diff --git a/.editorconfig b/.editorconfig index 8e84accde..2925ccbba 100644 --- a/.editorconfig +++ b/.editorconfig @@ -3,9 +3,14 @@ root = true [*] +# This also tells github.com how wide to render tabs indent_size = 2 indent_style = space end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true + +[{package.json,*.yml,dist-raw/**}] +# In case we switch to tabs above, these must still be spaces +indent_style = space diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..9b98cc127 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +raw/* linguist-vendored diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index e62997d71..d5649bd65 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,18 +1,18 @@ ---- -contact_links: - - +--- +contact_links: + - name: Question - about: "Please ask and answer usage questions on Stack Overflow." - url: "https://stackoverflow.com/questions/tagged/ts-node" - - + about: "Please ask and answer usage questions in our Discussion forum." + url: "https://github.com/TypeStrong/ts-node/discussions" + - name: Chat about: "Alternatively, you can use the TypeScript Community Discord." url: "https://discord.gg/typescript" - - + - name: "Help! My Types Are Missing!" about: "This is likely a configuration problem. Check our README" - url: "https://github.com/TypeStrong/ts-node/blob/master/README.md#help-my-types-are-missing" - - + url: "https://typestrong.org/ts-node/docs/types" + - name: "TSError or SyntaxError" about: "These errors come from TypeScript and node, respectively. Use StackOverflow or Discord for usage and configuration help." - url: "https://stackoverflow.com/questions/tagged/ts-node" + url: "https://typestrong.org/ts-node/docs/troubleshooting" diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 4c49393fd..e279668f4 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -3,7 +3,7 @@ on: # branches pushed by collaborators push: branches: - - master + - main # pull request from non-collaborators pull_request: {} # nightly @@ -17,14 +17,22 @@ jobs: # checkout code - uses: actions/checkout@v2 # install node - - name: Use Node.js 14 + - name: Use Node.js 16 uses: actions/setup-node@v1 with: - node-version: 14 + node-version: 16 + - run: | + npm config set cache "$( node -p "process.cwd()" )/temp/npm-cache" + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: temp/npm-cache + key: npm-cache-packaging-${{ hashFiles('package-lock.json') }} + restore-keys: npm-cache-packaging- # lint, build, test - - run: npm install + - run: npm ci - run: npm run lint - - run: npm run build + - run: npm run build-pack - name: Upload package artifact uses: actions/upload-artifact@v1 with: @@ -39,53 +47,71 @@ jobs: fail-fast: false matrix: os: [ubuntu, windows] - flavor: [1, 2, 3, 4, 5, 6, 7, 8, 9] + # Don't forget to add all new flavors to this list! + flavor: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] include: + # Node 12.15 + # TODO Add comments about why we test 12.15; I think git blame says it's because of an ESM behavioral change that happened at 12.16 - flavor: 1 - node: 10 - nodeFlag: 10 - typescript: latest - typescriptFlag: latest - - flavor: 2 node: 12.15 nodeFlag: 12_15 typescript: latest typescriptFlag: latest - - flavor: 3 + # Node 12.16 + # Earliest version that supports getFormat, etc hooks: https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V12.md#12.16.0 + - flavor: 2 node: 12.16 nodeFlag: 12_16 typescript: latest typescriptFlag: latest + # Node 12 + - flavor: 3 + node: 12 + nodeFlag: 12 + typescript: latest + typescriptFlag: latest + # Node 14.13.0 + # To test ESM builtin module resolution immediately before a node behavioral change: https://github.com/TypeStrong/ts-node/issues/1130 - flavor: 4 - node: 13 - nodeFlag: 13 + node: 14.13.0 + nodeFlag: 14_13_0 typescript: latest typescriptFlag: latest + # Node 14 - flavor: 5 - node: 13 - nodeFlag: 13 - typescript: 2.7 - typescriptFlag: 2_7 - - flavor: 6 - node: 13 - nodeFlag: 13 - typescript: next - typescriptFlag: next - - flavor: 7 node: 14 nodeFlag: 14 typescript: latest typescriptFlag: latest - - flavor: 8 + - flavor: 6 node: 14 nodeFlag: 14 typescript: 2.7 typescriptFlag: 2_7 - - flavor: 9 + - flavor: 7 node: 14 nodeFlag: 14 typescript: next typescriptFlag: next + # Node 16 + - flavor: 8 + node: 16 + nodeFlag: 16 + typescript: latest + typescriptFlag: latest + downgradeNpm: true + - flavor: 9 + node: 16 + nodeFlag: 16 + typescript: 2.7 + typescriptFlag: 2_7 + downgradeNpm: true + - flavor: 10 + node: 16 + nodeFlag: 16 + typescript: next + typescriptFlag: next + downgradeNpm: true steps: # checkout code - uses: actions/checkout@v2 @@ -95,8 +121,25 @@ jobs: with: node-version: ${{ matrix.node }} # lint, build, test - - run: npm install - - run: npm run build-nopack + # Downgrade from npm 7 to 6 because 7 still seems buggy to me + - if: ${{ matrix.downgradeNpm }} + run: npm install -g npm@6 + - run: | + npm config set cache "$( node -p "process.cwd()" )/temp/npm-cache" + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: temp/npm-cache + key: npm-cache-${{ matrix.os }}-${{ hashFiles('package-lock.json') }} + restore-keys: npm-cache-${{matrix.os }}- + - run: npm ci --ignore-scripts + - name: Upload npm logs + if: ${{ failure() }} + uses: actions/upload-artifact@v1 + with: + name: npm-logs + path: temp/npm-cache/_logs + - run: npm run build-tsc - name: Download package artifact uses: actions/download-artifact@v1 with: @@ -104,6 +147,12 @@ jobs: path: tests/ - run: npm install typescript@${{ matrix.typescript }} --force - run: npm run test-cov + - name: Upload npm logs + if: ${{ failure() }} + uses: actions/upload-artifact@v1 + with: + name: npm-logs-${{ matrix.os }}-node-${{ matrix.nodeFlag }}-typescript-${{ matrix.typescriptFlag }} + path: temp/npm-cache/_logs - run: npm run coverage-report if: ${{ always() }} - name: Codecov @@ -111,21 +160,3 @@ jobs: uses: codecov/codecov-action@v1 with: flags: ${{ matrix.os }},node_${{ matrix.nodeFlag }},typescript_${{ matrix.typescriptFlag }} - - run: npm run coverage-fix-paths - - run: npm run coverage-report - - name: Coveralls - if: ${{ always() }} - uses: coverallsapp/github-action@master - with: - github-token: ${{ secrets.github_token }} - parallel: true - finish: - needs: test - runs-on: ubuntu-latest - if: ${{ always() }} - steps: - - name: Coveralls Finished - uses: coverallsapp/github-action@master - with: - github-token: ${{ secrets.github_token }} - parallel-finished: true diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml new file mode 100644 index 000000000..6e907f718 --- /dev/null +++ b/.github/workflows/website.yml @@ -0,0 +1,32 @@ +name: Publish website +on: + # branches pushed by collaborators + push: + branches: + - docs +jobs: + build: + name: Build & Deploy + runs-on: ubuntu-20.04 + steps: + # checkout code + - uses: actions/checkout@v2 + # install node + - name: Use Node.js 14 + uses: actions/setup-node@v1 + with: + node-version: 14 + # Render typedoc + # Using custom branch to workaround: https://github.com/TypeStrong/typedoc/issues/1585 + - run: npm install && git clone --depth 1 https://github.com/cspotcode/typedoc --branch patch-2 && pushd typedoc && npm install && npm run build || true && popd && ./typedoc/bin/typedoc + # Render docusaurus and deploy website + - run: | + set -euo pipefail + git config --global user.name "GitHub Action" + git config --global user.email "github-action@users.noreply.github.com" + cd website + yarn + yarn deploy + env: + GIT_USER: ${{ github.actor }} + GIT_PASS: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 54fca00d2..f8e97ed5f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ -node_modules/ +/node_modules/ +/tests/node_modules/ .nyc_output/ coverage/ .DS_Store @@ -8,3 +9,6 @@ tsconfig.schema.json tsconfig.schemastore-schema.json .idea/ /.vscode/ +/website/static/api +/tsconfig.tsbuildinfo +/temp diff --git a/.mocharc.js b/.mocharc.js deleted file mode 100644 index 089a7cfd0..000000000 --- a/.mocharc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - spec: ['dist/**/*.spec.js'] -}; diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..4b463a062 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,12 @@ +/* +!/*.js +!/*.mjs +!/esm +!/register +!/scripts +!/src +!/tests +tests/main-realpath/symlink/tsconfig.json +tests/throw error.ts +tests/throw error react tsx.tsx +tests/esm/throw error.ts diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..a1f0363f9 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,65 @@ +*This guide is best-effort and will be improved as necessary.* + +## Features, bugfixes, and other code + +We use npm scripts for building, testing, and linting. Read the scripts to become familiar with our build process. The big ones are: + +``` +npm install +npm run build +npm run test-local +npm run lint-fix +``` + +`npm prepare` is maintained so that anyone can install `ts-node` from git, which is useful for testing experimental branches and unreleased features. + +Source lives in `src` and is compiled to `dist`. Some shim files live outside of `src` so that they can be imported at +certain paths. For example, to allow users to import `ts-node/register`, we have `register/index.js` which is a shim to +compiled code in `dist`. + +`dist-raw` is for larger chunks of code which are not compiled nor linted because they have been copy-pasted from `node`'s source code. + +## Documentation + +Documentation is written in markdown in `website/docs` and rendered into a website by Docusaurus. The README is also generated from these markdown files. + +To edit documentation, modify the markdown files in `./website/docs` and the sidebar declaration in `./website/sidebars.js` + +Docs for the latest stable release live in a `docs` branch. The "Edit this page" links on the website link to the `docs` +branch so that the website can be improved in parallel with new feature work. + +Docs changes for unreleased features are merged to `main` in the same PR which implements the feature, adds tests, etc. +When we release a new version, we merge `main` with `docs`, unifying the two. + +```shell +cd ./website +yarn +yarn start +# Will host live website locally + +yarn build-readme # will rebuild the README.md +``` + +This site was used to generate the favicon from a high-res PNG export of the SVG. https://realfavicongenerator.net/ + +## Release checklist + +We publish using `np`: https://npm.im/np + +1. Merge `docs` into `main` using a pull request, ensuring a consistent squash-merge +2. Rebuild the README (see instructions above, necessary because npmjs.com renders the readme) +3. (optional) Update the api-extractor report; check for unexpected changes. See below +4. Publish with `np` +5. Add changelog to the Github Release; match formatting from previous releases +6. Move `docs` branch to head of `main` + - this rebuilds the website + - `git push --force origin main:docs` + - avoids merge messiness due to earlier squash-merge from `docs` to `main` +7. If tsconfig schema has changed, send a pull request to schemastore. [Example](https://github.com/SchemaStore/schemastore/pull/1208) + +## APIExtractor + +`npm run api-extractor` will update an API report generated by [`api-extractor`](https://api-extractor.com/pages/overview/intro/) which may be useful +when generating release notes to detect (breaking) changes in our API surface. + +I configured it for my own convenience; it is not a necessary part of our development process. diff --git a/README.md b/README.md index 1c4f7f990..d50652f58 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,121 @@ + + # ![TypeScript Node](logo.svg?sanitize=true) -[![NPM version][npm-image]][npm-url] -[![NPM downloads][downloads-image]][downloads-url] -[![Build status][github-actions-image]][github-actions-url] -[![Test coverage][codecov-image]][codecov-url] +[![NPM version](https://img.shields.io/npm/v/ts-node.svg?style=flat)](https://npmjs.org/package/ts-node) +[![NPM downloads](https://img.shields.io/npm/dm/ts-node.svg?style=flat)](https://npmjs.org/package/ts-node) +[![Build status](https://img.shields.io/github/workflow/status/TypeStrong/ts-node/Continuous%20Integration)](https://github.com/TypeStrong/ts-node/actions?query=workflow%3A%22Continuous+Integration%22) +[![Test coverage](https://codecov.io/gh/TypeStrong/ts-node/branch/main/graph/badge.svg)](https://codecov.io/gh/TypeStrong/ts-node) > TypeScript execution and REPL for node.js, with source map support. **Works with `typescript@>=2.7`**. +The latest documentation can also be found on our website: + ### *Experimental ESM support* Native ESM support is currently experimental. For usage, limitations, and to provide feedback, see [#1007](https://github.com/TypeStrong/ts-node/issues/1007). -## Installation - -```sh +# Table of Contents + +* [Overview](#overview) + * [Features](#features) +* [Installation](#installation) +* [Usage](#usage) + * [Shell](#shell) + * [Shebang](#shebang) + * [Programmatic](#programmatic) + * [Developers](#developers) +* [Configuration](#configuration) + * [CLI flags](#cli-flags) + * [Via tsconfig.json (recommended)](#via-tsconfigjson-recommended) + * [@tsconfig/bases](#tsconfigbases) + * [Default config](#default-config) + * [`node` flags](#node-flags) +* [Options](#options) + * [Shell](#shell-1) + * [TSConfig](#tsconfig) + * [Typechecking](#typechecking) + * [Transpilation](#transpilation) + * [Diagnostics](#diagnostics) + * [Advanced](#advanced) + * [API](#api) +* [CommonJS vs native ECMAScript modules](#commonjs-vs-native-ecmascript-modules) + * [CommonJS](#commonjs) + * [Native ECMAScript modules](#native-ecmascript-modules) +* [Troubleshooting](#troubleshooting) + * [Understanding configuration](#understanding-configuration) + * [Understanding Errors](#understanding-errors) + * [`TSError`](#tserror) + * [`SyntaxError`](#syntaxerror) + * [Unsupported JavaScript syntax](#unsupported-javascript-syntax) +* [Make it fast](#make-it-fast) + * [Skip typechecking](#skip-typechecking) + * [With typechecking](#with-typechecking) +* [Advanced](#advanced-1) + * [How It Works](#how-it-works) + * [Skipping `node_modules`](#skipping-node_modules) + * [paths and baseUrl + ](#paths-and-baseurl) + * [Why is this not built-in to `ts-node`?](#why-is-this-not-built-in-to-ts-node) + * [Help! My Types Are Missing!](#help-my-types-are-missing) + * [Third-party compilers](#third-party-compilers) + * [Third-party transpilers](#third-party-transpilers) + * [Bundled `swc` integration](#bundled-swc-integration) + * [Writing your own integration](#writing-your-own-integration) + * [Module type overrides](#module-type-overrides) + * [Caveats](#caveats) +* [Recipes](#recipes) + * [Watching and Restarting](#watching-and-restarting) + * [AVA](#ava) + * [CommonJS](#commonjs-1) + * [Native ECMAScript modules](#native-ecmascript-modules-1) + * [Gulp](#gulp) + * [IntelliJ and Webstorm](#intellij-and-webstorm) + * [Mocha](#mocha) + * [Mocha 7 and newer](#mocha-7-and-newer) + * [Mocha <=6](#mocha-6) + * [Tape](#tape) + * [Visual Studio Code](#visual-studio-code) + * [Other](#other) +* [License](#license) + +# Overview + +`ts-node` is a TypeScript execution engine and REPL for Node.js. + +It JIT transforms TypeScript into JavaScript, enabling you to directly execute TypeScript on Node.js without precompiling. +This is accomplished by hooking node's module loading APIs, enabling it to be used seamlessly alongside other Node.js +tools and libraries. + +## Features + +* Automatic sourcemaps in stack traces +* Automatic `tsconfig.json` parsing +* Automatic defaults to match your node version +* Typechecking (optional) +* REPL +* Write standalone scripts +* Native ESM loader +* Use third-party transpilers +* Use custom transformers +* Integrate with test runners, debuggers, and CLI tools +* Compatible with pre-compilation for production + +![TypeScript REPL](website/static/img/screenshot.png) + +# Installation + +```shell # Locally in your project. npm install -D typescript npm install -D ts-node @@ -21,15 +123,18 @@ npm install -D ts-node # Or globally with TypeScript. npm install -g typescript npm install -g ts-node + +# Depending on configuration, you may also need these +npm install -D tslib @types/node ``` **Tip:** Installing modules locally allows you to control and share the versions through `package.json`. TS Node will always resolve the compiler from `cwd` before checking relative to its own installation. -## Usage +# Usage -### Shell +## Shell -```sh +```shell # Execute a script as `node` + `tsc`. ts-node script.ts @@ -45,200 +150,419 @@ ts-node -p -e '"Hello, world!"' # Pipe scripts to execute with TypeScript. echo 'console.log("Hello, world!")' | ts-node -# Equivalent to ts-node --script-mode -ts-node-script scripts.ts - # Equivalent to ts-node --transpile-only -ts-node-transpile-only scripts.ts -``` +ts-node-transpile-only script.ts -![TypeScript REPL](https://github.com/TypeStrong/ts-node/raw/master/screenshot.png) +# Equivalent to ts-node --cwd-mode +ts-node-cwd script.ts +``` -### Shebang +## Shebang ```typescript -#!/usr/bin/env ts-node-script +#!/usr/bin/env ts-node console.log("Hello, world!") ``` -`ts-node-script` is recommended because it enables `--script-mode`, discovering `tsconfig.json` relative to the script's location instead of `process.cwd()`. This makes scripts more portable. - Passing CLI arguments via shebang is allowed on Mac but not Linux. For example, the following will fail on Linux: -``` -#!/usr/bin/env ts-node --script-mode --transpile-only --files -// This shebang is not portable. It only works on Mac -``` + #!/usr/bin/env ts-node --files + // This shebang is not portable. It only works on Mac + +Instead, specify all `ts-node` options in your `tsconfig.json`. -### Programmatic +## Programmatic You can require `ts-node` and register the loader for future requires by using `require('ts-node').register({ /* options */ })`. You can also use file shortcuts - `node -r ts-node/register` or `node -r ts-node/register/transpile-only` - depending on your preferences. **Note:** If you need to use advanced node.js CLI arguments (e.g. `--inspect`), use them with `node -r ts-node/register` instead of the `ts-node` CLI. -#### Developers +### Developers -**TS Node** exports a `create()` function that can be used to initialize a TypeScript compiler that isn't registered to `require.extensions`, and it uses the same code as `register`. +`ts-node` exports a `create()` function that can be used to initialize a TypeScript compiler that isn't registered to `require.extensions`, and it uses the same code as `register`. -### Mocha +# Configuration -Mocha 6 +`ts-node` supports a variety of options which can be specified via `tsconfig.json`, as CLI flags, as environment variables, or programmatically. -```sh -mocha --require ts-node/register --watch-extensions ts,tsx "test/**/*.{ts,tsx}" [...args] -``` +For a complete list, see [Options](#options). -**Note:** `--watch-extensions` is only used in `--watch` mode. +## CLI flags -Mocha 7 +`ts-node` CLI flags must come *before* the entrypoint script. For example: -```sh -mocha --require ts-node/register --extensions ts,tsx --watch --watch-files src 'tests/**/*.{ts,tsx}' [...args] +```shell +$ ts-node --project tsconfig-dev.json say-hello.ts Ronald +Hello, Ronald! ``` -### Tape +## Via tsconfig.json (recommended) -```sh -ts-node node_modules/tape/bin/tape [...args] -``` +`ts-node` automatically finds and loads `tsconfig.json`. Most `ts-node` options can be specified in a `"ts-node"` object using their programmatic, camelCase names. We recommend this because it works even when you cannot pass CLI flags, such as `node --require ts-node/register` and when using shebangs. -### Gulp +Use `--skip-project` to skip loading the `tsconfig.json`. Use `--project` to explicitly specify the path to a `tsconfig.json`. -```sh -# Create a `gulpfile.ts` and run `gulp`. -gulp +When searching, it is resolved using [the same search behavior as `tsc`](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html). By default, this search is performed relative to the entrypoint script. In `--cwd-mode` or if no entrypoint is specified -- for example when using the REPL -- the search is performed relative to `--cwd` / `process.cwd()`. + +You can use this sample configuration as a starting point: + +```jsonc title="tsconfig.json" +{ + // This is an alias to @tsconfig/node12: https://github.com/tsconfig/bases + "extends": "ts-node/node12/tsconfig.json", + + // Most ts-node options can be specified here using their programmatic names. + "ts-node": { + // It is faster to skip typechecking. + // Remove if you want ts-node to do typechecking. + "transpileOnly": true, + + "files": true, + + "compilerOptions": { + // compilerOptions specified here will override those declared below, + // but *only* in ts-node. Useful if you want ts-node and tsc to use + // different options with a single tsconfig.json. + } + }, + "compilerOptions": { + // typescript options here + } +} ``` -### Visual Studio Code +Our bundled [JSON schema](https://unpkg.com/browse/ts-node@latest/tsconfig.schema.json) lists all compatible options. -Create a new node.js configuration, add `-r ts-node/register` to node args and move the `program` to the `args` list (so VS Code doesn't look for `outFiles`). +### @tsconfig/bases -```json +[@tsconfig/bases](https://github.com/tsconfig/bases) maintains recommended configurations for several node versions. +As a convenience, these are bundled with `ts-node`. + +```jsonc title="tsconfig.json" { - "type": "node", - "request": "launch", - "name": "Launch Program", - "runtimeArgs": [ - "-r", - "ts-node/register" - ], - "args": [ - "${workspaceFolder}/index.ts" - ] + "extends": "ts-node/node16/tsconfig.json", + + // Or install directly with `npm i -D @tsconfig/node16` + "extends": "@tsconfig/node16/tsconfig.json", } ``` -**Note:** If you are using the `--project ` command line argument as per the [Configuration Options](#configuration-options), and want to apply this same behavior when launching in VS Code, add an "env" key into the launch configuration: `"env": { "TS_NODE_PROJECT": "" }`. +### Default config -### IntelliJ (and WebStorm) +If no `tsconfig.json` is loaded from disk, `ts-node` will use the newest recommended defaults from +[@tsconfig/bases](https://github.com/tsconfig/bases/) compatible with your `node` and `typescript` versions. +With the latest `node` and `typescript`, this is [`@tsconfig/node16`](https://github.com/tsconfig/bases/blob/master/bases/node16.json). -Create a new Node.js configuration and add `-r ts-node/register` to "Node parameters." +Older versions of `typescript` are incompatible with `@tsconfig/node16`. In those cases we will use an older default configuration. -**Note:** If you are using the `--project ` command line argument as per the [Configuration Options](#configuration-options), and want to apply this same behavior when launching in IntelliJ, specify under "Environment Variables": `TS_NODE_PROJECT=`. +When in doubt, `ts-node --show-config` will log the configuration being used, and `ts-node -vv` will log `node` and `typescript` versions. -## How It Works +## `node` flags -**TypeScript Node** works by registering the TypeScript compiler for `.tsx?` and `.jsx?` (when `allowJs == true`) extensions. When node.js has an extension registered (via `require.extensions`), it will use the extension internally for module resolution. When an extension is unknown to node.js, it handles the file as `.js` (JavaScript). By default, **TypeScript Node** avoids compiling files in `/node_modules/` for three reasons: +[`node` flags](https://nodejs.org/api/cli.html) must be passed directly to `node`; they cannot be passed to the `ts-node` binary nor can they be specified in `tsconfig.json` -1. Modules should always be published in a format node.js can consume -2. Transpiling the entire dependency tree will make your project slower -3. Differing behaviours between TypeScript and node.js (e.g. ES2015 modules) can result in a project that works until you decide to support a feature natively from node.js +We recommend using the [`NODE_OPTIONS`](https://nodejs.org/api/cli.html#cli_node_options_options) environment variable to pass options to `node`. -**P.S.** This means if you don't register an extension, it is compiled as JavaScript. When `ts-node` is used with `allowJs`, JavaScript files are transpiled using the TypeScript compiler. +```shell +NODE_OPTIONS='--trace-deprecation --abort-on-uncaught-exception' ts-node ./index.ts +``` -## Loading `tsconfig.json` +Alternatively, you can invoke `node` directly and install `ts-node` via `--require`/`-r` -**Typescript Node** loads `tsconfig.json` automatically. Use `--skip-project` to skip loading the `tsconfig.json`. +```shell +node --trace-deprecation --abort-on-uncaught-exception -r ts-node/register ./index.ts +``` -It is resolved relative to `--dir` using [the same search behavior as `tsc`](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html). In `--script-mode`, this is the directory containing the script. Otherwise it is resolved relative to `process.cwd()`, which matches the behavior of `tsc`. +# Options -Use `--project` to specify the path to your `tsconfig.json`, ignoring `--dir`. +`ts-node` supports `--print` (`-p`), `--eval` (`-e`), `--require` (`-r`) and `--interactive` (`-i`) similar to the [node.js CLI options](https://nodejs.org/api/cli.html). -**Tip**: You can use `ts-node` together with [tsconfig-paths](https://www.npmjs.com/package/tsconfig-paths) to load modules according to the `paths` section in `tsconfig.json`. +*Environment variables, where available, are in `ALL_CAPS`* -## Configuration Options +## Shell -You can set options by passing them before the script path, via programmatic usage, via `tsconfig.json`, or via environment variables. +* `-h, --help` Prints the help text +* `-v, --version` Prints the version. `-vv` prints node and typescript compiler versions, too +* `-e, --eval` Evaluate code +* `-p, --print` Print result of `--eval` +* `-i, --interactive` Opens the REPL even if stdin does not appear to be a terminal -```sh -ts-node --compiler ntypescript --project src/tsconfig.json hello-world.ts -``` +## TSConfig -**Note:** [`ntypescript`](https://github.com/TypeStrong/ntypescript#readme) is an example of a TypeScript-compatible `compiler`. +* `-P, --project [path]` Path to TypeScript JSON project file
*Environment:* `TS_NODE_PROJECT` +* `--skip-project` Skip project config resolution and loading
*Default:* `false`
*Environment:* `TS_NODE_SKIP_PROJECT` +* `-c, --cwd-mode` Resolve config relative to the current directory instead of the directory of the entrypoint script +* `-O, --compiler-options [opts]` JSON object to merge with compiler options
*Environment:* `TS_NODE_COMPILER_OPTIONS` +* `--show-config` Print resolved `tsconfig.json`, including `ts-node` options, and exit -### CLI Options +## Typechecking -`ts-node` supports `--print` (`-p`), `--eval` (`-e`), `--require` (`-r`) and `--interactive` (`-i`) similar to the [node.js CLI options](https://nodejs.org/api/cli.html). +* `-T, --transpile-only` Use TypeScript's faster `transpileModule`
*Default:* `false`
*Environment:* `TS_NODE_TRANSPILE_ONLY` +* `--type-check` Opposite of `--transpile-only`
*Default:* `true`
*Environment:* `TS_NODE_TYPE_CHECK` +* `-H, --compiler-host` Use TypeScript's compiler host API
*Default:* `false`
*Environment:* `TS_NODE_COMPILER_HOST` +* `--files` Load `files`, `include` and `exclude` from `tsconfig.json` on startup
*Default:* `false`
*Environment:* `TS_NODE_FILES` +* `-D, --ignore-diagnostics [code]` Ignore TypeScript warnings by diagnostic code
*Environment:* `TS_NODE_IGNORE_DIAGNOSTICS` + +## Transpilation + +* `-I, --ignore [pattern]` Override the path patterns to skip compilation
*Default:* `/node_modules/`
*Environment:* `TS_NODE_IGNORE` +* `--skip-ignore` Skip ignore checks
*Default:* `false`
*Environment:* `TS_NODE_SKIP_IGNORE` +* `-C, --compiler [name]` Specify a custom TypeScript compiler
*Default:* `typescript`
*Environment:* `TS_NODE_COMPILER` +* `--transpiler [name]` Specify a third-party, non-typechecking transpiler +* `--prefer-ts-exts` Re-order file extensions so that TypeScript imports are preferred
*Default:* `false`
*Environment:* `TS_NODE_PREFER_TS_EXTS` -* `-h, --help` Prints the help text -* `-v, --version` Prints the version. `-vv` prints node and typescript compiler versions, too -* `-s, --script-mode` Resolve config relative to the directory of the passed script instead of the current directory. Changes default of `--dir` +## Diagnostics -### CLI and Programmatic Options +* `--log-error` Logs TypeScript errors to stderr instead of throwing exceptions
*Default:* `false`
*Environment:* `TS_NODE_LOG_ERROR` +* `--pretty` Use pretty diagnostic formatter
*Default:* `false`
*Environment:* `TS_NODE_PRETTY` +* `TS_NODE_DEBUG` Enable debug logging
-_The name of the environment variable and the option's default value are denoted in parentheses._ +## Advanced -* `-T, --transpile-only` Use TypeScript's faster `transpileModule` (`TS_NODE_TRANSPILE_ONLY`, default: `false`) -* `-H, --compiler-host` Use TypeScript's compiler host API (`TS_NODE_COMPILER_HOST`, default: `false`) -* `-I, --ignore [pattern]` Override the path patterns to skip compilation (`TS_NODE_IGNORE`, default: `/node_modules/`) -* `-P, --project [path]` Path to TypeScript JSON project file (`TS_NODE_PROJECT`) -* `-C, --compiler [name]` Specify a custom TypeScript compiler (`TS_NODE_COMPILER`, default: `typescript`) -* `-D, --ignore-diagnostics [code]` Ignore TypeScript warnings by diagnostic code (`TS_NODE_IGNORE_DIAGNOSTICS`) -* `-O, --compiler-options [opts]` JSON object to merge with compiler options (`TS_NODE_COMPILER_OPTIONS`) -* `--dir` Specify working directory for config resolution (`TS_NODE_CWD`, default: `process.cwd()`, or `dirname(scriptPath)` if `--script-mode`) -* `--scope` Scope compiler to files within `cwd` (`TS_NODE_SCOPE`, default: `false`) -* `--files` Load `files`, `include` and `exclude` from `tsconfig.json` on startup (`TS_NODE_FILES`, default: `false`) -* `--pretty` Use pretty diagnostic formatter (`TS_NODE_PRETTY`, default: `false`) -* `--skip-project` Skip project config resolution and loading (`TS_NODE_SKIP_PROJECT`, default: `false`) -* `--skip-ignore` Skip ignore checks (`TS_NODE_SKIP_IGNORE`, default: `false`) -* `--emit` Emit output files into `.ts-node` directory (`TS_NODE_EMIT`, default: `false`) -* `--prefer-ts-exts` Re-order file extensions so that TypeScript imports are preferred (`TS_NODE_PREFER_TS_EXTS`, default: `false`) -* `--log-error` Logs TypeScript errors to stderr instead of throwing exceptions (`TS_NODE_LOG_ERROR`, default: `false`) +* `-r, --require [path]` Require a node module before execution +* `--cwd` Behave as if invoked in this working directory
*Default:* `process.cwd()`
*Environment:* `TS_NODE_CWD` +* `--emit` Emit output files into `.ts-node` directory
*Default:* `false`
*Environment:* `TS_NODE_EMIT` +* `--scope` Scope compiler to files within `scopeDir`. Anything outside this directory is ignored.
\*Default: `false`
*Environment:* `TS_NODE_SCOPE` +* `--scopeDir` Directory within which compiler is limited when `scope` is enabled.
*Default:* First of: `tsconfig.json` "rootDir" if specified, directory containing `tsconfig.json`, or cwd if no `tsconfig.json` is loaded.
*Environment:* `TS_NODE_SCOPE_DIR` +* `moduleType` Override the module type of certain files, ignoring the `package.json` `"type"` field. See [Module type overrides](#module-type-overrides) for details.
*Default:* obeys `package.json` `"type"` and `tsconfig.json` `"module"`
*Can only be specified via `tsconfig.json` or API.* +* `TS_NODE_HISTORY` Path to history file for REPL
*Default:* `~/.ts_node_repl_history`
+* `--no-experimental-repl-await` Disable top-level await in REPL. Equivalent to node's [`--no-experimental-repl-await`](https://nodejs.org/api/cli.html#cli_no_experimental_repl_await)
*Default:* Enabled if TypeScript version is 3.8 or higher and target is ES2018 or higher.
*Environment:* `TS_NODE_EXPERIMENTAL_REPL_AWAIT` set `false` to disable -### Programmatic-only Options +## API -* `transformers` `_ts.CustomTransformers | ((p: _ts.Program) => _ts.CustomTransformers)`: An object with transformers or a function that accepts a program and returns an transformers object to pass to TypeScript. Function isn't available with `transpileOnly` flag -* `readFile`: Custom TypeScript-compatible file reading function -* `fileExists`: Custom TypeScript-compatible file existence function +The API includes [additional options](https://typestrong.org/ts-node/api/interfaces/RegisterOptions.html) not shown here. -### Options via tsconfig.json +# CommonJS vs native ECMAScript modules -Most options can be specified by a `"ts-node"` object in `tsconfig.json` using their programmatic, camelCase names. For example, to enable `--transpile-only`: +TypeScript is almost always written using modern `import` syntax, but you can choose to either transform to CommonJS or use node's native ESM support. Configuration is different for each. + +Here is a brief comparison of the two. + +| CommonJS | Native ECMAScript modules | +|---|---| +| Write native `import` syntax | Write native `import` syntax | +| Transforms `import` into `require()` | Does not transform `import` | +| Node executes scripts using the classic [CommonJS loader](https://nodejs.org/dist/latest-v16.x/docs/api/modules.html) | Node executes scripts using the new [ESM loader](https://nodejs.org/dist/latest-v16.x/docs/api/esm.html) | +| Use any of:
`ts-node` CLI
`node -r ts-node/register`
`NODE_OPTIONS="ts-node/register" node`
`require('ts-node').register({/* options */})` | Must use the ESM loader via:
`node --loader ts-node/esm`
`NODE_OPTIONS="--loader ts-node/esm" node` | + +## CommonJS + +Transforming to CommonJS is typically simpler and more widely supported because it is older. You must remove [`"type": "module"`](https://nodejs.org/api/packages.html#packages_type) from `package.json` and set [`"module": "CommonJS"`](https://www.typescriptlang.org/tsconfig/#module) in `tsconfig.json`. + +```jsonc title="package.json" +{ + // This can be omitted; commonjs is the default + "type": "commonjs" +} +``` -```json -// tsconfig.json +```jsonc title="tsconfig.json" { + "compilerOptions": { + "module": "CommonJS" + } +} +``` + +If you must keep `"module": "ESNext"` for `tsc`, webpack, or another build tool, you can set an override for `ts-node`. + +```jsonc title="tsconfig.json" +{ + "compilerOptions": { + "module": "ESNext" + }, "ts-node": { - "transpileOnly": true + "compilerOptions": { + "module": "CommonJS" + } + } +} +``` + +## Native ECMAScript modules + +[Node's ESM loader hooks](https://nodejs.org/api/esm.html#esm_experimental_loaders) are [**experimental**](https://nodejs.org/api/documentation.html#documentation_stability_index) and subject to change. `ts-node`'s ESM support is also experimental. They may have +breaking changes in minor and patch releases and are not recommended for production. + +For complete usage, limitations, and to provide feedback, see [#1007](https://github.com/TypeStrong/ts-node/issues/1007). + +You must set [`"type": "module"`](https://nodejs.org/api/packages.html#packages_type) in `package.json` and [`"module": "ESNext"`](https://www.typescriptlang.org/tsconfig/#module) in `tsconfig.json`. + +```jsonc title="package.json" +{ + "type": "module" +} +``` + +```jsonc title="tsconfig.json" +{ + "compilerOptions": { + "module": "ESNext" // or ES2015, ES2020 + } +} +``` + +# Troubleshooting + +## Understanding configuration + +`ts-node` uses sensible default configurations to reduce boilerplate while still respecting `tsconfig.json` if you +have one. If you are unsure which configuration is used, you can log it with `ts-node --show-config`. This is similar to +`tsc --showConfig` but includes `"ts-node"` options as well. + +`ts-node` also respects your locally-installed `typescript` version, but global installations fallback to the globally-installed +`typescript`. If you are unsure which versions are used, `ts-node -vv` will log them. + +```shell +$ ts-node -vv +ts-node v10.0.0 +node v16.1.0 +compiler v4.2.2 + +$ ts-node --show-config +{ + "compilerOptions": { + "target": "es6", + "lib": [ + "es6", + "dom" + ], + "rootDir": "./src", + "outDir": "./.ts-node", + "module": "commonjs", + "moduleResolution": "node", + "strict": true, + "declaration": false, + "sourceMap": true, + "inlineSources": true, + "types": [ + "node" + ], + "stripInternal": true, + "incremental": true, + "skipLibCheck": true, + "importsNotUsedAsValues": "error", + "inlineSourceMap": false, + "noEmit": false }, - "compilerOptions": {} + "ts-node": { + "cwd": "/d/project", + "projectSearchDir": "/d/project", + "require": [], + "project": "/d/project/tsconfig.json" + } } ``` -Our bundled [JSON schema](https://unpkg.com/browse/ts-node@8.8.2/tsconfig.schema.json) lists all compatible options. +## Understanding Errors + +It is important to differentiate between errors from `ts-node`, errors from the TypeScript compiler, and errors from `node`. It is also important to understand when errors are caused by a type error in your code, a bug in your code, or a flaw in your configuration. + +### `TSError` + +Type errors from the compiler are thrown as a `TSError`. These are the same as errors you get from `tsc`. + +### `SyntaxError` + +Any error that is not a `TSError` is from node.js (e.g. `SyntaxError`), and cannot be fixed by TypeScript or `ts-node`. These are bugs in your code or configuration. + +#### Unsupported JavaScript syntax + +Your version of `node` may not support all JavaScript syntax supported by TypeScript. The compiler must transform this syntax via "downleveling," which is controlled by +the [tsconfig `"target"` option](https://www.typescriptlang.org/tsconfig#target). Otherwise your code will compile fine, but node will throw a `SyntaxError`. + +For example, `node` 12 does not understand the `?.` optional chaining operator. If you use `"target": "esnext"`, then the following TypeScript syntax: + +```typescript +const bar: string | undefined = foo?.bar; +``` + +will compile into this JavaScript: + +```javascript +const a = foo?.bar; +``` -## SyntaxError +When you try to run this code, node 12 will throw a `SyntaxError`. To fix this, you must switch to `"target": "es2019"` or lower so TypeScript transforms `?.` into something `node` can understand. -Any error that is not a `TSError` is from node.js (e.g. `SyntaxError`), and cannot be fixed by TypeScript or `ts-node`. These are runtime issues with your code. +# Make it fast -### Import Statements +These tricks will make `ts-node` faster. -There are two options when using `import` statements: compile them to CommonJS or use node's native ESM support. +## Skip typechecking -To compile to CommonJS, you must set `"module": "CommonJS"` in your `tsconfig.json` or compiler options. +It is often better to use `tsc --noEmit` to typecheck once before your tests run or as a lint step. In these cases, `ts-node` can skip typechecking. -Node's native ESM support is currently experimental and so is `ts-node`'s ESM loader hook. For usage, limitations, and to provide feedback, see [#1007](https://github.com/TypeStrong/ts-node/issues/1007). +* Enable [`transpileOnly`](#options) to skip typechecking +* Use our [`swc` integration](#bundled-swc-integration) + * This is by far the fastest option + +## With typechecking + +* Avoid dynamic `require()` which may trigger repeated typechecking; prefer `import` +* Try with and without `--files`; one may be faster depending on your project +* Check `tsc --showConfig`; make sure all executed files are included +* Enable [`skipLibCheck`](https://www.typescriptlang.org/tsconfig#skipLibCheck) +* Set a [`types`](https://www.typescriptlang.org/tsconfig#types) array to avoid loading unnecessary `@types` + +# Advanced + +## How It Works + +`ts-node` works by registering hooks for `.ts`, `.tsx`, `.js`, and/or `.jsx` extensions. + +Vanilla `node` loads `.js` by reading code from disk and executing it. Our hook runs in the middle, transforming code from TypeScript to JavaScript and passing the result to `node` for execution. This transformation will respect your `tsconfig.json` as if you had compiled via `tsc`. + +`.js` and `.jsx` are only transformed when [`allowJs`](https://www.typescriptlang.org/docs/handbook/compiler-options.html#compiler-options) is enabled. + +`.tsx` and `.jsx` are only transformed when [`jsx`](https://www.typescriptlang.org/docs/handbook/jsx.html) is enabled. + +> **Warning:** if a file is ignored or its file extension is not registered, node will either fail to resolve the file or will attempt to execute it as JavaScript without any transformation. This may cause syntax errors or other failures, because node does not understand TypeScript type syntax nor bleeding-edge ECMAScript features. + +> **Warning:** When `ts-node` is used with `allowJs`, all non-ignored JavaScript files are transformed using the TypeScript compiler. + +### Skipping `node_modules` + +By default, **TypeScript Node** avoids compiling files in `/node_modules/` for three reasons: + +1. Modules should always be published in a format node.js can consume +2. Transpiling the entire dependency tree will make your project slower +3. Differing behaviours between TypeScript and node.js (e.g. ES2015 modules) can result in a project that works until you decide to support a feature natively from node.js + +## paths and baseUrl + +You can use `ts-node` together with [tsconfig-paths](https://www.npmjs.com/package/tsconfig-paths) to load modules according to the `paths` section in `tsconfig.json`. + +```jsonc title="tsconfig.json" +{ + "ts-node": { + // Do not forget to `npm i -D tsconfig-paths` + "require": ["tsconfig-paths/register"] + } +} +``` + +### Why is this not built-in to `ts-node`? + +The official TypeScript Handbook explains the intended purpose for `"paths"` in ["Additional module resolution flags"](https://www.typescriptlang.org/docs/handbook/module-resolution.html#additional-module-resolution-flags). + +> The TypeScript compiler has a set of additional flags to *inform* the compiler of transformations that are expected to happen to the sources to generate the final output. +> +> It is important to note that the compiler will not perform any of these transformations; it just uses these pieces of information to guide the process of resolving a module import to its definition file. + +This means `"paths"` are intended to describe mappings that the build tool or runtime *already* performs, not to tell the build tool or +runtime how to resolve modules. In other words, they intend us to write our imports in a way `node` already understands. For this reason, `ts-node` does not modify `node`'s module resolution behavior to implement `"paths"` mappings. ## Help! My Types Are Missing! -**TypeScript Node** does _not_ use `files`, `include` or `exclude`, by default. This is because a large majority projects do not use all of the files in a project directory (e.g. `Gulpfile.ts`, runtime vs tests) and parsing every file for types slows startup time. Instead, `ts-node` starts with the script file (e.g. `ts-node index.ts`) and TypeScript resolves dependencies based on imports and references. +**TypeScript Node** does *not* use `files`, `include` or `exclude`, by default. This is because a large majority projects do not use all of the files in a project directory (e.g. `Gulpfile.ts`, runtime vs tests) and parsing every file for types slows startup time. Instead, `ts-node` starts with the script file (e.g. `ts-node index.ts`) and TypeScript resolves dependencies based on imports and references. For global definitions, you can use the `typeRoots` compiler option. This requires that your type definitions be structured as type packages (not loose TypeScript definition files). More details on how this works can be found in the [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html#types-typeroots-and-types). Example `tsconfig.json`: -```json +```jsonc { "compilerOptions": { "typeRoots" : ["./node_modules/@types", "./typings"] @@ -266,7 +590,7 @@ declare module '' { For module definitions, you can use [`paths`](https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping): -```json +```jsonc { "compilerOptions": { "baseUrl": ".", @@ -284,23 +608,273 @@ An alternative approach for definitions of third-party libraries are [triple-sla import UntypedJsLib from "untyped_js_lib" ``` -**Tip:** If you _must_ use `files`, `include`, or `exclude`, enable `--files` flags or set `TS_NODE_FILES=true`. +**Tip:** If you *must* use `files`, `include`, or `exclude`, enable `--files` flags or set `TS_NODE_FILES=true`. + +## Third-party compilers + +Some projects require a patched typescript compiler which adds additional features. For example, [`ttypescript`](https://github.com/cevek/ttypescript/tree/master/packages/ttypescript) and [`ts-patch`](https://github.com/nonara/ts-patch#readme) +add the ability to configure custom transformers. These are drop-in replacements for the vanilla `typescript` module and +implement the same API. + +For example, to use `ttypescript` and `ts-transformer-keys`, add this to your `tsconfig.json`: + +```jsonc title="tsconfig.json" +{ + "ts-node": { + // This can be omitted when using ts-patch + "compiler": "ttypescript" + }, + "compilerOptions": { + // plugin configuration is the same for both ts-patch and ttypescript + "plugins": [ + { "transform": "ts-transformer-keys/transformer" } + ] + } +} +``` + +## Third-party transpilers + +In transpile-only mode, we skip typechecking to speed up execution time. You can go a step further and use a +third-party transpiler to transform TypeScript into JavaScript even faster. You will still benefit from +`ts-node`'s automatic `tsconfig.json` discovery, sourcemap support, and global `ts-node` CLI. Integrations +can automatically derive an appropriate configuration from your existing `tsconfig.json` which simplifies project +boilerplate. + +> **What is the difference between a compiler and a transpiler?** +> +> For our purposes, a compiler implements TypeScript's API and can perform typechecking. +> A third-party transpiler does not. Both transform TypeScript into JavaScript. + +### Bundled `swc` integration + +We have bundled an experimental `swc` integration. + +[`swc`](https://swc.rs) is a TypeScript-compatible transpiler implemented in Rust. This makes it an order of magnitude faster +than `transpileModule`. + +To use it, first install `@swc/core` or `@swc/wasm`. If using `importHelpers`, also install `@swc/helpers`. + +```shell +npm i -D @swc/core @swc/helpers +``` + +Then add the following to your `tsconfig.json`. + +```jsonc title="tsconfig.json" +{ + "ts-node": { + "transpileOnly": true, + "transpiler": "ts-node/transpilers/swc-experimental" + } +} +``` + +> `swc` uses `@swc/helpers` instead of `tslib`. If you have enabled `importHelpers`, you must also install `@swc/helpers`. + +### Writing your own integration + +To write your own transpiler integration, check our [API docs](https://typestrong.org/ts-node/api/interfaces/TranspilerModule.html). + +Integrations are `require()`d, so they can be published to npm. The module must export a `create` function matching the +[`TranspilerModule`](https://typestrong.org/ts-node/api/interfaces/TranspilerModule.html) interface. + +## Module type overrides + +When deciding between CommonJS and native ECMAScript modules, `ts-node` defaults to matching vanilla `node` and `tsc` +behavior. This means TypeScript files are transformed according to your `tsconfig.json` `"module"` option and executed +according to node's rules for the `package.json` `"type"` field. + +In some projects you may need to override this behavior for some files. For example, in a webpack +project, you may have `package.json` configured with `"type": "module"` and `tsconfig.json` with +`"module": "esnext"`. However, webpack uses our CommonJS hook to execute your `webpack.config.ts`, +so you need to force your webpack config and any supporting scripts to execute as CommonJS. + +In these situations, our `moduleTypes` option lets you override certain files, forcing execution as +CommonJS or ESM. Node supports similar overriding via `.cjs` and `.mjs` file extensions, but `.ts` files cannot use them. +`moduleTypes` achieves the same effect, and *also* overrides your `tsconfig.json` `"module"` config appropriately. + +The following example tells `ts-node` to execute a webpack config as CommonJS: + +```jsonc title=tsconfig.json +{ + "ts-node": { + "transpileOnly": true, + "moduleTypes": { + "webpack.config.ts": "cjs", + // Globs are also supported with the same behavior as tsconfig "include" + "webpack-config-scripts/**/*": "cjs" + } + }, + "compilerOptions": { + "module": "es2020", + "target": "es2020" + } +} +``` + +Each key is a glob pattern with the same syntax as tsconfig's `"include"` array. +When multiple patterns match the same file, the last pattern takes precedence. + +* `cjs` overrides matches files to compile and execute as CommonJS. +* `esm` overrides matches files to compile and execute as native ECMAScript modules. +* `package` resets either of the above to default behavior, which obeys `package.json` `"type"` and `tsconfig.json` `"module"` options. + +### Caveats + +Files with an overridden module type are transformed with the same limitations as [`isolatedModules`](https://www.typescriptlang.org/tsconfig#isolatedModules). This will only affect rare cases such as using `const enum`s with [`preserveConstEnums`](https://www.typescriptlang.org/tsconfig#preserveConstEnums) disabled. + +This feature is meant to faciliate scenarios where normal `compilerOptions` and `package.json` configuration is not possible. For example, a `webpack.config.ts` cannot be given its own `package.json` to override `"type"`. Wherever possible you should favor using traditional `package.json` and `tsconfig.json` configurations. + +# Recipes ## Watching and Restarting **TypeScript Node** compiles source code via `require()`, watching files and code reloads are out of scope for the project. If you want to restart the `ts-node` process on file change, existing node.js tools such as [nodemon](https://github.com/remy/nodemon), [onchange](https://github.com/Qard/onchange) and [node-dev](https://github.com/fgnass/node-dev) work. -There's also [`ts-node-dev`](https://github.com/whitecolor/ts-node-dev), a modified version of [`node-dev`](https://github.com/fgnass/node-dev) using `ts-node` for compilation and won't restart the process on file change. +There's also [`ts-node-dev`](https://github.com/whitecolor/ts-node-dev), a modified version of [`node-dev`](https://github.com/fgnass/node-dev) using `ts-node` for compilation that will restart the process on file change. + +## AVA + +Assuming you are configuring AVA via your `package.json`, add one of the following configurations. + +### CommonJS + +Use this configuration if your `package.json` does not have `"type": "module"`. + +```jsonc title"package.json" +{ + "ava": { + "extensions": [ + "ts" + ], + "require": [ + "ts-node/register" + ] + } +} +``` + +### Native ECMAScript modules + +This configuration is necessary if your `package.json` has `"type": "module"`. + +```jsonc title"package.json" +{ + "ava": { + "extensions": { + "ts": "module" + }, + "nonSemVerExperiments": { + "configurableModuleFormat": true + }, + "nodeArguments": [ + "--loader=ts-node/esm" + ] + } +} +``` + +## Gulp + +ts-node support is built-in to gulp. + +```sh +# Create a `gulpfile.ts` and run `gulp`. +gulp +``` + +See also: https://gulpjs.com/docs/en/getting-started/javascript-and-gulpfiles#transpilation + +## IntelliJ and Webstorm + +Create a new Node.js configuration and add `-r ts-node/register` to "Node parameters." + +**Note:** If you are using the `--project ` command line argument as per the [Configuration Options](#configuration), and want to apply this same behavior when launching in IntelliJ, specify under "Environment Variables": `TS_NODE_PROJECT=`. + +## Mocha + +### Mocha 7 and newer + +```shell +mocha --require ts-node/register --extensions ts,tsx --watch --watch-files src 'tests/**/*.{ts,tsx}' [...args] +``` + +Or specify options via your mocha config file. + +```jsonc title=".mocharc.json" +{ + // Specify "require" for CommonJS + "require": "ts-node/register", + // Specify "loader" for native ESM + "loader": "ts-node/esm", + "extensions": ["ts", "tsx"], + "spec": [ + "tests/**/*.spec.*" + ], + "watch-files": [ + "src" + ] +} +``` + +See also: https://mochajs.org/#configuring-mocha-nodejs + +### Mocha <=6 + +```shell +mocha --require ts-node/register --watch-extensions ts,tsx "test/**/*.{ts,tsx}" [...args] +``` + +**Note:** `--watch-extensions` is only used in `--watch` mode. + +## Tape + +```shell +ts-node node_modules/tape/bin/tape [...args] +``` + +## Visual Studio Code + +Create a new node.js configuration, add `-r ts-node/register` to node args and move the `program` to the `args` list (so VS Code doesn't look for `outFiles`). + +```jsonc +{ + "type": "node", + "request": "launch", + "name": "Launch Program", + "runtimeArgs": [ + "-r", + "ts-node/register" + ], + "args": [ + "${workspaceFolder}/index.ts" + ] +} +``` + +**Note:** If you are using the `--project ` command line argument as per the [Configuration Options](#configuration), and want to apply this same behavior when launching in VS Code, add an "env" key into the launch configuration: `"env": { "TS_NODE_PROJECT": "" }`. + +## Other + +In many cases, setting [`NODE_OPTIONS`](https://nodejs.org/api/cli.html#cli_node_options_options) will enable `ts-node` within other node tools, child processes, and worker threads. + +```shell +NODE_OPTIONS="-r ts-node/register" +``` + +Or, if you require native ESM support: + +```shell +NODE_OPTIONS="--loader ts-node/esm" +``` + +This tells any node processes which receive this environment variable to install `ts-node`'s hooks before executing other code. + +# License -## License +ts-node is licensed under the MIT license. [MIT](https://github.com/TypeStrong/ts-node/blob/main/LICENSE) -MIT +ts-node includes source code from Node.js which is licensed under the MIT license. [Node.js license information](https://raw.githubusercontent.com/nodejs/node/master/LICENSE) -[npm-image]: https://img.shields.io/npm/v/ts-node.svg?style=flat -[npm-url]: https://npmjs.org/package/ts-node -[downloads-image]: https://img.shields.io/npm/dm/ts-node.svg?style=flat -[downloads-url]: https://npmjs.org/package/ts-node -[github-actions-image]: https://img.shields.io/github/workflow/status/TypeStrong/ts-node/Continuous%20Integration -[github-actions-url]: https://github.com/TypeStrong/ts-node/actions?query=workflow%3A%22Continuous+Integration%22 -[codecov-image]: https://codecov.io/gh/TypeStrong/ts-node/branch/master/graph/badge.svg -[codecov-url]: https://codecov.io/gh/TypeStrong/ts-node +ts-node includes source code from the TypeScript compiler which is licensed under the Apache License 2.0. [TypeScript license information](https://github.com/microsoft/TypeScript/blob/master/LICENSE.txt) diff --git a/api-extractor.json b/api-extractor.json new file mode 100644 index 000000000..c1190c878 --- /dev/null +++ b/api-extractor.json @@ -0,0 +1,368 @@ +/** + * Config file for API Extractor. For more info, please visit: https://api-extractor.com + */ +{ + "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", + + /** + * Optionally specifies another JSON config file that this file extends from. This provides a way for + * standard settings to be shared across multiple projects. + * + * If the path starts with "./" or "../", the path is resolved relative to the folder of the file that contains + * the "extends" field. Otherwise, the first path segment is interpreted as an NPM package name, and will be + * resolved using NodeJS require(). + * + * SUPPORTED TOKENS: none + * DEFAULT VALUE: "" + */ + // "extends": "./shared/api-extractor-base.json" + // "extends": "my-package/include/api-extractor-base.json" + + /** + * Determines the "" token that can be used with other config file settings. The project folder + * typically contains the tsconfig.json and package.json config files, but the path is user-defined. + * + * The path is resolved relative to the folder of the config file that contains the setting. + * + * The default value for "projectFolder" is the token "", which means the folder is determined by traversing + * parent folders, starting from the folder containing api-extractor.json, and stopping at the first folder + * that contains a tsconfig.json file. If a tsconfig.json file cannot be found in this way, then an error + * will be reported. + * + * SUPPORTED TOKENS: + * DEFAULT VALUE: "" + */ + // "projectFolder": "..", + + /** + * (REQUIRED) Specifies the .d.ts file to be used as the starting point for analysis. API Extractor + * analyzes the symbols exported by this module. + * + * The file extension must be ".d.ts" and not ".ts". + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + */ + "mainEntryPointFilePath": "/dist/index.d.ts", + + /** + * A list of NPM package names whose exports should be treated as part of this package. + * + * For example, suppose that Webpack is used to generate a distributed bundle for the project "library1", + * and another NPM package "library2" is embedded in this bundle. Some types from library2 may become part + * of the exported API for library1, but by default API Extractor would generate a .d.ts rollup that explicitly + * imports library2. To avoid this, we can specify: + * + * "bundledPackages": [ "library2" ], + * + * This would direct API Extractor to embed those types directly in the .d.ts rollup, as if they had been + * local files for library1. + */ + "bundledPackages": [], + + /** + * Determines how the TypeScript compiler engine will be invoked by API Extractor. + */ + "compiler": { + /** + * Specifies the path to the tsconfig.json file to be used by API Extractor when analyzing the project. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * Note: This setting will be ignored if "overrideTsconfig" is used. + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "/tsconfig.json" + */ + // "tsconfigFilePath": "/tsconfig.json", + /** + * Provides a compiler configuration that will be used instead of reading the tsconfig.json file from disk. + * The object must conform to the TypeScript tsconfig schema: + * + * http://json.schemastore.org/tsconfig + * + * If omitted, then the tsconfig.json file will be read from the "projectFolder". + * + * DEFAULT VALUE: no overrideTsconfig section + */ + // "overrideTsconfig": { + // . . . + // } + /** + * This option causes the compiler to be invoked with the --skipLibCheck option. This option is not recommended + * and may cause API Extractor to produce incomplete or incorrect declarations, but it may be required when + * dependencies contain declarations that are incompatible with the TypeScript engine that API Extractor uses + * for its analysis. Where possible, the underlying issue should be fixed rather than relying on skipLibCheck. + * + * DEFAULT VALUE: false + */ + // "skipLibCheck": true, + }, + + /** + * Configures how the API report file (*.api.md) will be generated. + */ + "apiReport": { + /** + * (REQUIRED) Whether to generate an API report. + */ + "enabled": true, + + /** + * The filename for the API report files. It will be combined with "reportFolder" or "reportTempFolder" to produce + * a full file path. + * + * The file extension should be ".api.md", and the string should not contain a path separator such as "\" or "/". + * + * SUPPORTED TOKENS: , + * DEFAULT VALUE: ".api.md" + */ + "reportFileName": ".api.md", + + /** + * Specifies the folder where the API report file is written. The file name portion is determined by + * the "reportFileName" setting. + * + * The API report file is normally tracked by Git. Changes to it can be used to trigger a branch policy, + * e.g. for an API review. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "/etc/" + */ + "reportFolder": "/api-extractor/" + + /** + * Specifies the folder where the temporary report file is written. The file name portion is determined by + * the "reportFileName" setting. + * + * After the temporary file is written to disk, it is compared with the file in the "reportFolder". + * If they are different, a production build will fail. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "/temp/" + */ + // "reportTempFolder": "/temp/" + }, + + /** + * Configures how the doc model file (*.api.json) will be generated. + */ + "docModel": { + /** + * (REQUIRED) Whether to generate a doc model file. + */ + "enabled": false + + /** + * The output path for the doc model file. The file extension should be ".api.json". + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "/temp/.api.json" + */ + // "apiJsonFilePath": "/temp/.api.json" + }, + + /** + * Configures how the .d.ts rollup file will be generated. + */ + "dtsRollup": { + /** + * (REQUIRED) Whether to generate the .d.ts rollup file. + */ + "enabled": false + + /** + * Specifies the output path for a .d.ts rollup file to be generated without any trimming. + * This file will include all declarations that are exported by the main entry point. + * + * If the path is an empty string, then this file will not be written. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "/dist/.d.ts" + */ + // "untrimmedFilePath": "/dist/.d.ts", + + /** + * Specifies the output path for a .d.ts rollup file to be generated with trimming for a "beta" release. + * This file will include only declarations that are marked as "@public" or "@beta". + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "" + */ + // "betaTrimmedFilePath": "/dist/-beta.d.ts", + + /** + * Specifies the output path for a .d.ts rollup file to be generated with trimming for a "public" release. + * This file will include only declarations that are marked as "@public". + * + * If the path is an empty string, then this file will not be written. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "" + */ + // "publicTrimmedFilePath": "/dist/-public.d.ts", + + /** + * When a declaration is trimmed, by default it will be replaced by a code comment such as + * "Excluded from this release type: exampleMember". Set "omitTrimmingComments" to true to remove the + * declaration completely. + * + * DEFAULT VALUE: false + */ + // "omitTrimmingComments": true + }, + + /** + * Configures how the tsdoc-metadata.json file will be generated. + */ + "tsdocMetadata": { + /** + * Whether to generate the tsdoc-metadata.json file. + * + * DEFAULT VALUE: true + */ + "enabled": false + /** + * Specifies where the TSDoc metadata file should be written. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * The default value is "", which causes the path to be automatically inferred from the "tsdocMetadata", + * "typings" or "main" fields of the project's package.json. If none of these fields are set, the lookup + * falls back to "tsdoc-metadata.json" in the package folder. + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "" + */ + // "tsdocMetadataFilePath": "/dist/tsdoc-metadata.json" + }, + + /** + * Specifies what type of newlines API Extractor should use when writing output files. By default, the output files + * will be written with Windows-style newlines. To use POSIX-style newlines, specify "lf" instead. + * To use the OS's default newline kind, specify "os". + * + * DEFAULT VALUE: "crlf" + */ + "newlineKind": "lf", + + /** + * Configures how API Extractor reports error and warning messages produced during analysis. + * + * There are three sources of messages: compiler messages, API Extractor messages, and TSDoc messages. + */ + "messages": { + /** + * Configures handling of diagnostic messages reported by the TypeScript compiler engine while analyzing + * the input .d.ts files. + * + * TypeScript message identifiers start with "TS" followed by an integer. For example: "TS2551" + * + * DEFAULT VALUE: A single "default" entry with logLevel=warning. + */ + "compilerMessageReporting": { + /** + * Configures the default routing for messages that don't match an explicit rule in this table. + */ + "default": { + /** + * Specifies whether the message should be written to the the tool's output log. Note that + * the "addToApiReportFile" property may supersede this option. + * + * Possible values: "error", "warning", "none" + * + * Errors cause the build to fail and return a nonzero exit code. Warnings cause a production build fail + * and return a nonzero exit code. For a non-production build (e.g. when "api-extractor run" includes + * the "--local" option), the warning is displayed but the build will not fail. + * + * DEFAULT VALUE: "warning" + */ + "logLevel": "warning", + + /** + * When addToApiReportFile is true: If API Extractor is configured to write an API report file (.api.md), + * then the message will be written inside that file; otherwise, the message is instead logged according to + * the "logLevel" option. + * + * DEFAULT VALUE: false + */ + "addToApiReportFile": true + }, + + // "TS2551": { + // "logLevel": "warning", + // "addToApiReportFile": true + // }, + // + // . . . + }, + + /** + * Configures handling of messages reported by API Extractor during its analysis. + * + * API Extractor message identifiers start with "ae-". For example: "ae-extra-release-tag" + * + * DEFAULT VALUE: See api-extractor-defaults.json for the complete table of extractorMessageReporting mappings + */ + "extractorMessageReporting": { + "default": { + "logLevel": "warning", + "addToApiReportFile": true + }, + + "ae-missing-release-tag": { + "logLevel": "none" + } + + // "ae-extra-release-tag": { + // "logLevel": "warning", + // "addToApiReportFile": true + // }, + // + // . . . + }, + + /** + * Configures handling of messages reported by the TSDoc parser when analyzing code comments. + * + * TSDoc message identifiers start with "tsdoc-". For example: "tsdoc-link-tag-unescaped-text" + * + * DEFAULT VALUE: A single "default" entry with logLevel=warning. + */ + "tsdocMessageReporting": { + "default": { + "logLevel": "warning" + // "addToApiReportFile": false + } + + // "tsdoc-link-tag-unescaped-text": { + // "logLevel": "warning", + // "addToApiReportFile": true + // }, + // + // . . . + } + } +} diff --git a/api-extractor/ts-node.api.md b/api-extractor/ts-node.api.md new file mode 100644 index 000000000..8801e708d --- /dev/null +++ b/api-extractor/ts-node.api.md @@ -0,0 +1,244 @@ +## API Report File for "ts-node" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { BaseError } from 'make-error'; +import type * as _ts from 'typescript'; + +// @public +export function create(rawOptions?: CreateOptions): Service; + +// @public +export interface CreateOptions { + compiler?: string; + compilerHost?: boolean; + compilerOptions?: object; + cwd?: string; + // @deprecated + dir?: string; + emit?: boolean; + experimentalReplAwait?: boolean; + // (undocumented) + fileExists?: (path: string) => boolean; + files?: boolean; + ignore?: string[]; + ignoreDiagnostics?: Array; + logError?: boolean; + moduleTypes?: Record; + pretty?: boolean; + project?: string; + projectSearchDir?: string; + // (undocumented) + readFile?: (path: string) => string | undefined; + require?: Array; + scope?: boolean; + // (undocumented) + scopeDir?: string; + skipIgnore?: boolean; + skipProject?: boolean; + // (undocumented) + transformers?: _ts.CustomTransformers | ((p: _ts.Program) => _ts.CustomTransformers); + transpileOnly?: boolean; + transpiler?: string | [string, object]; + typeCheck?: boolean; +} + +// @public +export function createRepl(options?: CreateReplOptions): ReplService; + +// @public (undocumented) +export interface CreateReplOptions { + // (undocumented) + service?: Service; + // Warning: (ae-forgotten-export) The symbol "EvalState" needs to be exported by the entry point index.d.ts + // + // (undocumented) + state?: EvalState; + // (undocumented) + stderr?: NodeJS.WritableStream; + // (undocumented) + stdin?: NodeJS.ReadableStream; + // (undocumented) + stdout?: NodeJS.WritableStream; +} + +// @public (undocumented) +export interface CreateTranspilerOptions { + // (undocumented) + service: Pick; +} + +// @public +export type EvalAwarePartialHost = Pick; + +// @public @deprecated +export type Register = Service; + +// @public +export function register(opts?: RegisterOptions): Service; + +// @public +export const REGISTER_INSTANCE: unique symbol; + +// @public +export interface RegisterOptions extends CreateOptions { + preferTsExts?: boolean; +} + +// @public (undocumented) +export interface ReplService { + // (undocumented) + evalAwarePartialHost: EvalAwarePartialHost; + evalCode(code: string): any; + nodeEval(code: string, context: any, _filename: string, callback: (err: Error | null, result?: any) => any): void; + setService(service: Service): void; + start(): void; + // @deprecated + start(code: string): void; + // (undocumented) + readonly state: EvalState; +} + +// @public +export interface Service { + // (undocumented) + compile(code: string, fileName: string, lineOffset?: number): string; + // (undocumented) + config: _ts.ParsedCommandLine; + // (undocumented) + enabled(enabled?: boolean): boolean; + // (undocumented) + getTypeInfo(code: string, fileName: string, position: number): TypeInfo; + // (undocumented) + ignored(fileName: string): boolean; + // (undocumented) + options: RegisterOptions; + // (undocumented) + ts: TSCommon; +} + +// @public (undocumented) +export interface TranspileOptions { + // (undocumented) + fileName: string; +} + +// @public (undocumented) +export interface TranspileOutput { + // (undocumented) + diagnostics?: _ts.Diagnostic[]; + // (undocumented) + outputText: string; + // (undocumented) + sourceMapText?: string; +} + +// @public (undocumented) +export interface Transpiler { + // (undocumented) + transpile(input: string, options: TranspileOptions): TranspileOutput; +} + +// @public +export type TranspilerFactory = (options: CreateTranspilerOptions) => Transpiler; + +// @public +export interface TranspilerModule { + // (undocumented) + create: TranspilerFactory; +} + +// @public +export interface TSCommon { + // (undocumented) + createDocumentRegistry: typeof _ts.createDocumentRegistry; + // (undocumented) + createEmitAndSemanticDiagnosticsBuilderProgram: typeof _ts.createEmitAndSemanticDiagnosticsBuilderProgram; + // (undocumented) + createIncrementalCompilerHost: typeof _ts.createIncrementalCompilerHost; + // (undocumented) + createIncrementalProgram: typeof _ts.createIncrementalProgram; + // (undocumented) + createLanguageService: typeof _ts.createLanguageService; + // (undocumented) + createModuleResolutionCache: typeof _ts.createModuleResolutionCache; + // (undocumented) + createSourceFile: typeof _ts.createSourceFile; + // (undocumented) + displayPartsToString: typeof _ts.displayPartsToString; + // (undocumented) + Extension: typeof _ts.Extension; + // (undocumented) + findConfigFile: typeof _ts.findConfigFile; + // (undocumented) + flattenDiagnosticMessageText: typeof _ts.flattenDiagnosticMessageText; + // (undocumented) + formatDiagnostics: typeof _ts.formatDiagnostics; + // (undocumented) + formatDiagnosticsWithColorAndContext: typeof _ts.formatDiagnosticsWithColorAndContext; + // (undocumented) + getDefaultLibFileName: typeof _ts.getDefaultLibFileName; + // (undocumented) + getDefaultLibFilePath: typeof _ts.getDefaultLibFilePath; + // (undocumented) + getPreEmitDiagnostics: typeof _ts.getPreEmitDiagnostics; + // (undocumented) + JsxEmit: typeof _ts.JsxEmit; + // (undocumented) + ModuleKind: typeof _ts.ModuleKind; + // (undocumented) + ModuleResolutionKind: typeof _ts.ModuleResolutionKind; + // (undocumented) + parseJsonConfigFileContent: typeof _ts.parseJsonConfigFileContent; + // (undocumented) + readConfigFile: typeof _ts.readConfigFile; + // (undocumented) + resolveModuleName: typeof _ts.resolveModuleName; + // (undocumented) + resolveModuleNameFromCache: typeof _ts.resolveModuleNameFromCache; + // (undocumented) + resolveTypeReferenceDirective: typeof _ts.resolveTypeReferenceDirective; + // (undocumented) + ScriptSnapshot: typeof _ts.ScriptSnapshot; + // (undocumented) + ScriptTarget: typeof _ts.ScriptTarget; + // (undocumented) + sys: typeof _ts.sys; + // (undocumented) + transpileModule: typeof _ts.transpileModule; + // (undocumented) + version: typeof _ts.version; +} + +// @public +export interface TsConfigOptions extends Omit { +} + +// @public +export class TSError extends BaseError { + constructor(diagnosticText: string, diagnosticCodes: number[]); + // (undocumented) + diagnosticCodes: number[]; + // (undocumented) + diagnosticText: string; + // (undocumented) + name: string; +} + +// @public +export interface TypeInfo { + // (undocumented) + comment: string; + // (undocumented) + name: string; +} + +// @public +export const VERSION: any; + + +// (No @packageDocumentation comment for this package) + +``` diff --git a/codecov.yml b/codecov.yml index 28ca33092..4aaa7bb83 100644 --- a/codecov.yml +++ b/codecov.yml @@ -2,3 +2,17 @@ fixes: # Remap from npm-installed ts-node to root of project # This can take the place of ./scripts/rewrite-coverage-paths.js - "tests/node_modules/ts-node/::" + +coverage: + status: + patch: + default: + # Do not fail when `patch` coverage is low. When this fails, it is misleading and not necessarily bad. + # For example if a patch changes 2 lines, and only one is covered, then patch coverage is 50%. + target: 0% + project: + default: + threshold: 1% + +comment: + layout: "files" diff --git a/development-docs/repl-api.md b/development-docs/repl-api.md new file mode 100644 index 000000000..782a13dc2 --- /dev/null +++ b/development-docs/repl-api.md @@ -0,0 +1,27 @@ +## How to create your own ts-node powered REPL + +- Create ts-node REPL service which includes EvalState +- Create ts-node compiler service using EvalState-aware `readFile` and `fileExists` implementations from REPL +- Bind REPL service to compiler service (chicken-and-egg problem necessitates late binding) +- Either: + - call REPL method start() to start a REPL + - create your own node repl but pass it REPL service's nodeEval() function + +``` +import * as tsnode from 'ts-node'; +const repl = tsnode.createRepl(); +const service = tsnode.register({ + ... options, + ...repl.evalAwarePartialHost +}); +repl.setService(service); + +// Start it +repl.start(); + +// or +const nodeRepl = require('repl').start({ + ...options, + eval: repl.nodeEval +}); +``` diff --git a/dist-raw/node-cjs-helpers.d.ts b/dist-raw/node-cjs-helpers.d.ts new file mode 100644 index 000000000..a57c2f831 --- /dev/null +++ b/dist-raw/node-cjs-helpers.d.ts @@ -0,0 +1 @@ +export function addBuiltinLibsToObject(object: any): void; diff --git a/dist-raw/node-cjs-helpers.js b/dist-raw/node-cjs-helpers.js new file mode 100644 index 000000000..20bfb44f8 --- /dev/null +++ b/dist-raw/node-cjs-helpers.js @@ -0,0 +1,51 @@ +const {ArrayPrototypeForEach, StringPrototypeStartsWith, ObjectPrototypeHasOwnProperty, StringPrototypeIncludes, ObjectDefineProperty} = require('./node-primordials'); + +exports.addBuiltinLibsToObject = addBuiltinLibsToObject; + +// Copied from https://github.com/nodejs/node/blob/21f5a56914a3b24ad77535ef369b93c6b1c11d18/lib/internal/modules/cjs/helpers.js#L133-L178 +function addBuiltinLibsToObject(object) { + // Make built-in modules available directly (loaded lazily). + const { builtinModules } = require('module').Module; + ArrayPrototypeForEach(builtinModules, (name) => { + // Neither add underscored modules, nor ones that contain slashes (e.g., + // 'fs/promises') or ones that are already defined. + if (StringPrototypeStartsWith(name, '_') || + StringPrototypeIncludes(name, '/') || + ObjectPrototypeHasOwnProperty(object, name)) { + return; + } + // Goals of this mechanism are: + // - Lazy loading of built-in modules + // - Having all built-in modules available as non-enumerable properties + // - Allowing the user to re-assign these variables as if there were no + // pre-existing globals with the same name. + + const setReal = (val) => { + // Deleting the property before re-assigning it disables the + // getter/setter mechanism. + delete object[name]; + object[name] = val; + }; + + ObjectDefineProperty(object, name, { + get: () => { + const lib = require(name); + + // Disable the current getter/setter and set up a new + // non-enumerable property. + delete object[name]; + ObjectDefineProperty(object, name, { + get: () => lib, + set: setReal, + configurable: true, + enumerable: false + }); + + return lib; + }, + set: setReal, + configurable: true, + enumerable: false + }); + }); +} diff --git a/dist-raw/node-cjs-loader-utils.js b/dist-raw/node-cjs-loader-utils.js index 0c5fabf9c..b7ec0d531 100644 --- a/dist-raw/node-cjs-loader-utils.js +++ b/dist-raw/node-cjs-loader-utils.js @@ -3,18 +3,30 @@ // Each function and variable below must have a comment linking to the source in node's github repo. const path = require('path'); -const fs = require('fs'); +const packageJsonReader = require('./node-package-json-reader'); +const {JSONParse} = require('./node-primordials'); +const {normalizeSlashes} = require('../dist/util'); module.exports.assertScriptCanLoadAsCJSImpl = assertScriptCanLoadAsCJSImpl; -// copied from Module._extensions['.js'] -// https://github.com/nodejs/node/blob/2d5d77306f6dff9110c1f77fefab25f973415770/lib/internal/modules/cjs/loader.js#L1211-L1217 -function assertScriptCanLoadAsCJSImpl(filename) { +/** + * copied from Module._extensions['.js'] + * https://github.com/nodejs/node/blob/v15.3.0/lib/internal/modules/cjs/loader.js#L1113-L1120 + * @param {import('../src/index').Service} service + * @param {NodeJS.Module} module + * @param {string} filename + */ +function assertScriptCanLoadAsCJSImpl(service, module, filename) { const pkg = readPackageScope(filename); + + // ts-node modification: allow our configuration to override + const tsNodeClassification = service.moduleTypeClassifier.classifyModule(normalizeSlashes(filename)); + if(tsNodeClassification.moduleType === 'cjs') return; + // Function require shouldn't be used in ES modules. - if (pkg && pkg.data && pkg.data.type === 'module') { + if (tsNodeClassification.moduleType === 'esm' || (pkg && pkg.data && pkg.data.type === 'module')) { const parentPath = module.parent && module.parent.filename; - const packageJsonPath = path.resolve(pkg.path, 'package.json'); + const packageJsonPath = pkg ? path.resolve(pkg.path, 'package.json') : null; throw createErrRequireEsm(filename, parentPath, packageJsonPath); } } @@ -41,31 +53,27 @@ function readPackageScope(checkPath) { // Copied from https://github.com/nodejs/node/blob/2d5d77306f6dff9110c1f77fefab25f973415770/lib/internal/modules/cjs/loader.js#L249 const packageJsonCache = new Map(); -// Copied from https://github.com/nodejs/node/blob/2d5d77306f6dff9110c1f77fefab25f973415770/lib/internal/modules/cjs/loader.js#L251-L283 +// Copied from https://github.com/nodejs/node/blob/v15.3.0/lib/internal/modules/cjs/loader.js#L275-L304 function readPackage(requestPath) { const jsonPath = path.resolve(requestPath, 'package.json'); const existing = packageJsonCache.get(jsonPath); if (existing !== undefined) return existing; - const json = internalModuleReadJSON(path.toNamespacedPath(jsonPath)); + const result = packageJsonReader.read(jsonPath); + const json = result.containsKeys === false ? '{}' : result.string; if (json === undefined) { packageJsonCache.set(jsonPath, false); return false; } - // TODO Related to `--experimental-policy`? Disabling for now - // if (manifest) { - // const jsonURL = pathToFileURL(jsonPath); - // manifest.assertIntegrity(jsonURL, json); - // } - try { - const parsed = JSON.parse(json); + const parsed = JSONParse(json); const filtered = { name: parsed.name, main: parsed.main, exports: parsed.exports, + imports: parsed.imports, type: parsed.type }; packageJsonCache.set(jsonPath, filtered); @@ -77,17 +85,6 @@ function readPackage(requestPath) { } } -// In node's core, this is implemented in C -// https://github.com/nodejs/node/blob/e9f293750760d59243020d0376edf242c9a26b67/src/node_file.cc#L845-L939 -function internalModuleReadJSON(path) { - try { - return fs.readFileSync(path, 'utf8') - } catch (e) { - if (e.code === 'ENOENT') return undefined - throw e - } -} - // Native ERR_REQUIRE_ESM Error is declared here: // https://github.com/nodejs/node/blob/2d5d77306f6dff9110c1f77fefab25f973415770/lib/internal/errors.js#L1294-L1313 // Error class factory is implemented here: diff --git a/dist-raw/node-createrequire.js b/dist-raw/node-createrequire.js deleted file mode 100644 index 649deb10d..000000000 --- a/dist-raw/node-createrequire.js +++ /dev/null @@ -1,29 +0,0 @@ -// Extracted from https://github.com/nodejs/node/blob/ec2ffd6b9d255e19818b6949d2f7dc7ac70faee9/lib/internal/modules/cjs/loader.js -// then modified to suit our needs - -const path = require('path'); -const Module = require('module'); - -exports.createRequireFromPath = createRequireFromPath; - -function createRequireFromPath(filename) { - // Allow a directory to be passed as the filename - const trailingSlash = - filename.endsWith('/') || (isWindows && filename.endsWith('\\')); - - const proxyPath = trailingSlash ? - path.join(filename, 'noop.js') : - filename; - - const m = new Module(proxyPath); - m.filename = proxyPath; - - m.paths = Module._nodeModulePaths(m.path); - return makeRequireFunction(m, proxyPath); -} - -// This trick is much smaller than copy-pasting from https://github.com/nodejs/node/blob/ec2ffd6b9d255e19818b6949d2f7dc7ac70faee9/lib/internal/modules/cjs/helpers.js#L32-L101 -function makeRequireFunction(module, filename) { - module._compile('module.exports = require;', filename) - return mod.exports -} diff --git a/dist-raw/node-errors.js b/dist-raw/node-errors.js new file mode 100644 index 000000000..f7c6edcf8 --- /dev/null +++ b/dist-raw/node-errors.js @@ -0,0 +1,29 @@ +exports.codes = { + ERR_INPUT_TYPE_NOT_ALLOWED: createErrorCtor(joinArgs('ERR_INPUT_TYPE_NOT_ALLOWED')), + ERR_INVALID_ARG_VALUE: createErrorCtor(joinArgs('ERR_INVALID_ARG_VALUE')), + ERR_INVALID_MODULE_SPECIFIER: createErrorCtor(joinArgs('ERR_INVALID_MODULE_SPECIFIER')), + ERR_INVALID_PACKAGE_CONFIG: createErrorCtor(joinArgs('ERR_INVALID_PACKAGE_CONFIG')), + ERR_INVALID_PACKAGE_TARGET: createErrorCtor(joinArgs('ERR_INVALID_PACKAGE_TARGET')), + ERR_MANIFEST_DEPENDENCY_MISSING: createErrorCtor(joinArgs('ERR_MANIFEST_DEPENDENCY_MISSING')), + ERR_MODULE_NOT_FOUND: createErrorCtor((path, base, type = 'package') => { + return `Cannot find ${type} '${path}' imported from ${base}` + }), + ERR_PACKAGE_IMPORT_NOT_DEFINED: createErrorCtor(joinArgs('ERR_PACKAGE_IMPORT_NOT_DEFINED')), + ERR_PACKAGE_PATH_NOT_EXPORTED: createErrorCtor(joinArgs('ERR_PACKAGE_PATH_NOT_EXPORTED')), + ERR_UNSUPPORTED_DIR_IMPORT: createErrorCtor(joinArgs('ERR_UNSUPPORTED_DIR_IMPORT')), + ERR_UNSUPPORTED_ESM_URL_SCHEME: createErrorCtor(joinArgs('ERR_UNSUPPORTED_ESM_URL_SCHEME')), +} + +function joinArgs(name) { + return (...args) => { + return [name, ...args].join(' ') + } +} + +function createErrorCtor(errorMessageCreator) { + return class CustomError extends Error { + constructor(...args) { + super(errorMessageCreator(...args)) + } + } +} diff --git a/dist-raw/node-esm-resolve-implementation.js b/dist-raw/node-esm-resolve-implementation.js index a3da2f9a0..04ea84668 100644 --- a/dist-raw/node-esm-resolve-implementation.js +++ b/dist-raw/node-esm-resolve-implementation.js @@ -1,36 +1,53 @@ -// Copied from https://raw.githubusercontent.com/nodejs/node/v13.12.0/lib/internal/modules/esm/resolve.js +// Copied from https://raw.githubusercontent.com/nodejs/node/v15.3.0/lib/internal/modules/esm/resolve.js // Then modified to suite our needs. // Formatting is intentionally bad to keep the diff as small as possible, to make it easier to merge // upstream changes and understand our modifications. +// +// Github diff to easily view the changes: +// https://github.com/TypeStrong/ts-node/compare/esm-resolver-diff..main 'use strict'; +const [nodeMajor, nodeMinor, nodePatch] = process.versions.node.split('.').map(s => parseInt(s, 10)) +// Test for node >14.13.1 || (>=12.20.0 && <13) +const builtinModuleProtocol = nodeMajor > 14 || ( + nodeMajor === 14 && ( + nodeMinor > 13 || ( + nodeMinor === 13 && nodePatch > 0 + ) + ) + ) || ( + nodeMajor === 12 && ( + nodeMinor > 20 || ( + nodeMinor === 20 + ) + ) + ) + ? 'node:' + : 'nodejs:'; + const { ArrayIsArray, + ArrayPrototypeJoin, + ArrayPrototypeShift, JSONParse, JSONStringify, + ObjectFreeze, ObjectGetOwnPropertyNames, ObjectPrototypeHasOwnProperty, + // RegExp, + RegExpPrototypeTest, SafeMap, + SafeSet, + // String, StringPrototypeEndsWith, - StringPrototypeIncludes, StringPrototypeIndexOf, + StringPrototypeLastIndexOf, + StringPrototypeReplace, StringPrototypeSlice, + StringPrototypeSplit, StringPrototypeStartsWith, StringPrototypeSubstr, -} = { - ArrayIsArray: Array.isArray, - JSONParse: JSON.parse, - JSONStringify: JSON.stringify, - ObjectGetOwnPropertyNames: Object.getOwnPropertyNames, - ObjectPrototypeHasOwnProperty: (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop), - SafeMap: Map, - StringPrototypeEndsWith: (str, ...rest) => String.prototype.endsWith.apply(str, rest), - StringPrototypeIncludes: (str, ...rest) => String.prototype.includes.apply(str, rest), - StringPrototypeIndexOf: (str, ...rest) => String.prototype.indexOf.apply(str, rest), - StringPrototypeSlice: (str, ...rest) => String.prototype.slice.apply(str, rest), - StringPrototypeStartsWith: (str, ...rest) => String.prototype.startsWith.apply(str, rest), - StringPrototypeSubstr: (str, ...rest) => String.prototype.substr.apply(str, rest), -} // node pulls from `primordials` object +} = require('./node-primordials'); // const internalFS = require('internal/fs/utils'); // const { NativeModule } = require('internal/bootstrap/loaders'); @@ -41,18 +58,19 @@ const NativeModule = { } } const { - closeSync, - fstatSync, - openSync, - readFileSync, realpathSync, statSync, Stats, } = require('fs'); // const { getOptionValue } = require('internal/options'); const { getOptionValue } = require('./node-options'); -const { sep } = require('path'); - +// // Do not eagerly grab .manifest, it may be in TDZ +// const policy = getOptionValue('--experimental-policy') ? +// require('internal/process/policy') : +// null; +// disabled for now. I am not sure if/how we should support this +const policy = null; +const { sep, relative } = require('path'); const preserveSymlinks = getOptionValue('--preserve-symlinks'); const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main'); const typeFlag = getOptionValue('--input-type'); @@ -60,34 +78,75 @@ const typeFlag = getOptionValue('--input-type'); const { URL, pathToFileURL, fileURLToPath } = require('url'); const { ERR_INPUT_TYPE_NOT_ALLOWED, + ERR_INVALID_ARG_VALUE, ERR_INVALID_MODULE_SPECIFIER, ERR_INVALID_PACKAGE_CONFIG, ERR_INVALID_PACKAGE_TARGET, + ERR_MANIFEST_DEPENDENCY_MISSING, ERR_MODULE_NOT_FOUND, + ERR_PACKAGE_IMPORT_NOT_DEFINED, ERR_PACKAGE_PATH_NOT_EXPORTED, + ERR_UNSUPPORTED_DIR_IMPORT, ERR_UNSUPPORTED_ESM_URL_SCHEME, // } = require('internal/errors').codes; -} = { - ERR_INPUT_TYPE_NOT_ALLOWED: createErrorCtor('ERR_INPUT_TYPE_NOT_ALLOWED'), - ERR_INVALID_MODULE_SPECIFIER: createErrorCtor('ERR_INVALID_MODULE_SPECIFIER'), - ERR_INVALID_PACKAGE_CONFIG: createErrorCtor('ERR_INVALID_PACKAGE_CONFIG'), - ERR_INVALID_PACKAGE_TARGET: createErrorCtor('ERR_INVALID_PACKAGE_TARGET'), - ERR_MODULE_NOT_FOUND: createErrorCtor('ERR_MODULE_NOT_FOUND'), - ERR_PACKAGE_PATH_NOT_EXPORTED: createErrorCtor('ERR_PACKAGE_PATH_NOT_EXPORTED'), - ERR_UNSUPPORTED_ESM_URL_SCHEME: createErrorCtor('ERR_UNSUPPORTED_ESM_URL_SCHEME'), -} -function createErrorCtor(name) { - return class CustomError extends Error { - constructor(...args) { - super([name, ...args].join(' ')) - } - } -} +} = require('./node-errors').codes; + +// const { Module: CJSModule } = require('internal/modules/cjs/loader'); +const CJSModule = Module; + +// const packageJsonReader = require('internal/modules/package_json_reader'); +const packageJsonReader = require('./node-package-json-reader'); +const userConditions = getOptionValue('--conditions'); +const DEFAULT_CONDITIONS = ObjectFreeze(['node', 'import', ...userConditions]); +const DEFAULT_CONDITIONS_SET = new SafeSet(DEFAULT_CONDITIONS); + +const pendingDeprecation = getOptionValue('--pending-deprecation'); function createResolve(opts) { // TODO receive cached fs implementations here const {tsExtensions, jsExtensions, preferTsExts} = opts; +const emittedPackageWarnings = new SafeSet(); +function emitFolderMapDeprecation(match, pjsonUrl, isExports, base) { + const pjsonPath = fileURLToPath(pjsonUrl); + if (!pendingDeprecation) { + const nodeModulesIndex = StringPrototypeLastIndexOf(pjsonPath, + '/node_modules/'); + if (nodeModulesIndex !== -1) { + const afterNodeModulesPath = StringPrototypeSlice(pjsonPath, + nodeModulesIndex + 14, + -13); + try { + const { packageSubpath } = parsePackageName(afterNodeModulesPath); + if (packageSubpath === '.') + return; + } catch {} + } + } + if (emittedPackageWarnings.has(pjsonPath + '|' + match)) + return; + emittedPackageWarnings.add(pjsonPath + '|' + match); + process.emitWarning( + `Use of deprecated folder mapping "${match}" in the ${isExports ? + '"exports"' : '"imports"'} field module resolution of the package at ${ + pjsonPath}${base ? ` imported from ${fileURLToPath(base)}` : ''}.\n` + + `Update this package.json to use a subpath pattern like "${match}*".`, + 'DeprecationWarning', + 'DEP0148' + ); +} + +function getConditionsSet(conditions) { + if (conditions !== undefined && conditions !== DEFAULT_CONDITIONS) { + if (!ArrayIsArray(conditions)) { + throw new ERR_INVALID_ARG_VALUE('conditions', conditions, + 'expected an array'); + } + return new SafeSet(conditions); + } + return DEFAULT_CONDITIONS_SET; +} + const realpathCache = new SafeMap(); const packageJSONCache = new SafeMap(); /* string -> PackageConfig */ @@ -99,39 +158,21 @@ function tryStatSync(path) { } } -function readIfFile(path) { - let fd; - try { - fd = openSync(path, 'r'); - } catch { - return undefined; - } - try { - if (!fstatSync(fd).isFile()) return undefined; - return readFileSync(fd, 'utf8'); - } finally { - closeSync(fd); - } -} - -function getPackageConfig(path, base) { +function getPackageConfig(path, specifier, base) { const existing = packageJSONCache.get(path); if (existing !== undefined) { - if (!existing.isValid) { - throw new ERR_INVALID_PACKAGE_CONFIG(path, fileURLToPath(base), false); - } return existing; } - - const source = readIfFile(path); + const source = packageJsonReader.read(path).string; if (source === undefined) { const packageConfig = { + pjsonPath: path, exists: false, main: undefined, name: undefined, - isValid: true, type: 'none', - exports: undefined + exports: undefined, + imports: undefined, }; packageJSONCache.set(path, packageConfig); return packageConfig; @@ -140,45 +181,43 @@ function getPackageConfig(path, base) { let packageJSON; try { packageJSON = JSONParse(source); - } catch { - const packageConfig = { - exists: true, - main: undefined, - name: undefined, - isValid: false, - type: 'none', - exports: undefined - }; - packageJSONCache.set(path, packageConfig); - return packageConfig; + } catch (error) { + throw new ERR_INVALID_PACKAGE_CONFIG( + path, + (base ? `"${specifier}" from ` : '') + fileURLToPath(base || specifier), + error.message + ); } - let { main, name, type } = packageJSON; + let { imports, main, name, type } = packageJSON; const { exports } = packageJSON; + if (typeof imports !== 'object' || imports === null) imports = undefined; if (typeof main !== 'string') main = undefined; if (typeof name !== 'string') name = undefined; // Ignore unknown types for forwards compatibility if (type !== 'module' && type !== 'commonjs') type = 'none'; const packageConfig = { + pjsonPath: path, exists: true, main, name, - isValid: true, type, - exports + exports, + imports, }; packageJSONCache.set(path, packageConfig); return packageConfig; } -function getPackageScopeConfig(resolved, base) { +function getPackageScopeConfig(resolved) { let packageJSONUrl = new URL('./package.json', resolved); while (true) { const packageJSONPath = packageJSONUrl.pathname; if (StringPrototypeEndsWith(packageJSONPath, 'node_modules/package.json')) break; - const packageConfig = getPackageConfig(fileURLToPath(packageJSONUrl), base); + const packageConfig = getPackageConfig(fileURLToPath(packageJSONUrl), + resolved); if (packageConfig.exists) return packageConfig; const lastPackageJSONUrl = packageJSONUrl; @@ -188,15 +227,17 @@ function getPackageScopeConfig(resolved, base) { // (can't just check "/package.json" for Windows support). if (packageJSONUrl.pathname === lastPackageJSONUrl.pathname) break; } + const packageJSONPath = fileURLToPath(packageJSONUrl); const packageConfig = { + pjsonPath: packageJSONPath, exists: false, main: undefined, name: undefined, - isValid: true, type: 'none', - exports: undefined + exports: undefined, + imports: undefined, }; - packageJSONCache.set(fileURLToPath(packageJSONUrl), packageConfig); + packageJSONCache.set(packageJSONPath, packageConfig); return packageConfig; } @@ -212,7 +253,7 @@ function fileExists(url) { return tryStatSync(fileURLToPath(url)).isFile(); } -function legacyMainResolve(packageJSONUrl, packageConfig) { +function legacyMainResolve(packageJSONUrl, packageConfig, base) { let guess; if (packageConfig.main !== undefined) { // Note: fs check redundances will be handled by Descriptor cache here. @@ -257,7 +298,8 @@ function legacyMainResolve(packageJSONUrl, packageConfig) { return guess; } // Not found. - return undefined; + throw new ERR_MODULE_NOT_FOUND( + fileURLToPath(new URL('.', packageJSONUrl)), fileURLToPath(base)); } function resolveExtensionsWithTryExactName(search) { @@ -295,7 +337,8 @@ function resolveReplacementExtensions(search) { const pathnameWithoutExtension = search.pathname.slice(0, search.pathname.length - 3); for (let i = 0; i < replacementExtensions.length; i++) { const extension = replacementExtensions[i]; - const guess = new URL(`${pathnameWithoutExtension}${extension}`, search); + const guess = new URL(search.toString()); + guess.pathname = `${pathnameWithoutExtension}${extension}`; if (fileExists(guess)) return guess; } } @@ -306,119 +349,166 @@ function resolveIndex(search) { return resolveExtensions(new URL('index', search)); } +const encodedSepRegEx = /%2F|%2C/i; function finalizeResolution(resolved, base) { + if (RegExpPrototypeTest(encodedSepRegEx, resolved.pathname)) + throw new ERR_INVALID_MODULE_SPECIFIER( + resolved.pathname, 'must not include encoded "/" or "\\" characters', + fileURLToPath(base)); + if (getOptionValue('--experimental-specifier-resolution') === 'node') { + const path = fileURLToPath(resolved); let file = resolveExtensionsWithTryExactName(resolved); if (file !== undefined) return file; - if (!StringPrototypeEndsWith(resolved.pathname, '/')) { - file = resolveIndex(new URL(`${resolved.pathname}/`, base)); + if (!StringPrototypeEndsWith(path, '/')) { + file = resolveIndex(new URL(`${resolved}/`)); + if (file !== undefined) return file; } else { - file = resolveIndex(resolved); + return resolveIndex(resolved) || resolved; } - if (file !== undefined) return file; throw new ERR_MODULE_NOT_FOUND( resolved.pathname, fileURLToPath(base), 'module'); } - if (StringPrototypeEndsWith(resolved.pathname, '/')) return resolved; - const file = resolveReplacementExtensions(resolved) || resolved; - const path = fileURLToPath(file); - if (!tryStatSync(path).isFile()) { - throw new ERR_MODULE_NOT_FOUND( - path || resolved.pathname, fileURLToPath(base), 'module'); + const stats = tryStatSync(StringPrototypeEndsWith(path, '/') ? + StringPrototypeSlice(path, -1) : path); + if (stats.isDirectory()) { + const err = new ERR_UNSUPPORTED_DIR_IMPORT(path, fileURLToPath(base)); + err.url = String(resolved); + throw err; + } else if (!stats.isFile()) { + throw new ERR_MODULE_NOT_FOUND( + path || resolved.pathname, fileURLToPath(base), 'module'); } return file; } +function throwImportNotDefined(specifier, packageJSONUrl, base) { + throw new ERR_PACKAGE_IMPORT_NOT_DEFINED( + specifier, packageJSONUrl && fileURLToPath(new URL('.', packageJSONUrl)), + fileURLToPath(base)); +} + function throwExportsNotFound(subpath, packageJSONUrl, base) { throw new ERR_PACKAGE_PATH_NOT_EXPORTED( - fileURLToPath(packageJSONUrl), subpath, fileURLToPath(base)); + fileURLToPath(new URL('.', packageJSONUrl)), subpath, + base && fileURLToPath(base)); } -function throwSubpathInvalid(subpath, packageJSONUrl, base) { - throw new ERR_INVALID_MODULE_SPECIFIER( - fileURLToPath(packageJSONUrl), subpath, fileURLToPath(base)); +function throwInvalidSubpath(subpath, packageJSONUrl, internal, base) { + const reason = `request is not a valid subpath for the "${internal ? + 'imports' : 'exports'}" resolution of ${fileURLToPath(packageJSONUrl)}`; + throw new ERR_INVALID_MODULE_SPECIFIER(subpath, reason, + base && fileURLToPath(base)); } -function throwExportsInvalid( - subpath, target, packageJSONUrl, base) { +function throwInvalidPackageTarget( + subpath, target, packageJSONUrl, internal, base) { if (typeof target === 'object' && target !== null) { target = JSONStringify(target, null, ''); - } else if (ArrayIsArray(target)) { - target = `[${target}]`; } else { target = `${target}`; } throw new ERR_INVALID_PACKAGE_TARGET( - fileURLToPath(packageJSONUrl), null, subpath, target, fileURLToPath(base)); + fileURLToPath(new URL('.', packageJSONUrl)), subpath, target, + internal, base && fileURLToPath(base)); } -function resolveExportsTargetString( - target, subpath, match, packageJSONUrl, base) { - if (target[0] !== '.' || target[1] !== '/' || - (subpath !== '' && target[target.length - 1] !== '/')) { - throwExportsInvalid(match, target, packageJSONUrl, base); +const invalidSegmentRegEx = /(^|\\|\/)(\.\.?|node_modules)(\\|\/|$)/; +const patternRegEx = /\*/g; + +function resolvePackageTargetString( + target, subpath, match, packageJSONUrl, base, pattern, internal, conditions) { + if (subpath !== '' && !pattern && target[target.length - 1] !== '/') + throwInvalidPackageTarget(match, target, packageJSONUrl, internal, base); + + if (!StringPrototypeStartsWith(target, './')) { + if (internal && !StringPrototypeStartsWith(target, '../') && + !StringPrototypeStartsWith(target, '/')) { + let isURL = false; + try { + new URL(target); + isURL = true; + } catch {} + if (!isURL) { + const exportTarget = pattern ? + StringPrototypeReplace(target, patternRegEx, subpath) : + target + subpath; + return packageResolve(exportTarget, packageJSONUrl, conditions); + } + } + throwInvalidPackageTarget(match, target, packageJSONUrl, internal, base); } + if (RegExpPrototypeTest(invalidSegmentRegEx, StringPrototypeSlice(target, 2))) + throwInvalidPackageTarget(match, target, packageJSONUrl, internal, base); + const resolved = new URL(target, packageJSONUrl); const resolvedPath = resolved.pathname; const packagePath = new URL('.', packageJSONUrl).pathname; - if (!StringPrototypeStartsWith(resolvedPath, packagePath) || - StringPrototypeIncludes( - resolvedPath, '/node_modules/', packagePath.length - 1)) { - throwExportsInvalid(match, target, packageJSONUrl, base); - } + if (!StringPrototypeStartsWith(resolvedPath, packagePath)) + throwInvalidPackageTarget(match, target, packageJSONUrl, internal, base); if (subpath === '') return resolved; - const subpathResolved = new URL(subpath, resolved); - const subpathResolvedPath = subpathResolved.pathname; - if (!StringPrototypeStartsWith(subpathResolvedPath, resolvedPath) || - StringPrototypeIncludes(subpathResolvedPath, - '/node_modules/', packagePath.length - 1)) { - throwSubpathInvalid(match + subpath, packageJSONUrl, base); - } - return subpathResolved; + + if (RegExpPrototypeTest(invalidSegmentRegEx, subpath)) + throwInvalidSubpath(match + subpath, packageJSONUrl, internal, base); + + if (pattern) + return new URL(StringPrototypeReplace(resolved.href, patternRegEx, + subpath)); + return new URL(subpath, resolved); } -function isArrayIndex(key /* string */) { /* -> boolean */ +/** + * @param {string} key + * @returns {boolean} + */ +function isArrayIndex(key) { const keyNum = +key; if (`${keyNum}` !== key) return false; return keyNum >= 0 && keyNum < 0xFFFF_FFFF; } -function resolveExportsTarget( - packageJSONUrl, target, subpath, packageSubpath, base) { +function resolvePackageTarget(packageJSONUrl, target, subpath, packageSubpath, + base, pattern, internal, conditions) { if (typeof target === 'string') { - const resolved = resolveExportsTargetString( - target, subpath, packageSubpath, packageJSONUrl, base); - return finalizeResolution(resolved, base); + return resolvePackageTargetString( + target, subpath, packageSubpath, packageJSONUrl, base, pattern, internal, + conditions); } else if (ArrayIsArray(target)) { if (target.length === 0) - throwExportsInvalid(packageSubpath, target, packageJSONUrl, base); + return null; let lastException; for (let i = 0; i < target.length; i++) { const targetItem = target[i]; let resolved; try { - resolved = resolveExportsTarget( - packageJSONUrl, targetItem, subpath, packageSubpath, base); + resolved = resolvePackageTarget( + packageJSONUrl, targetItem, subpath, packageSubpath, base, pattern, + internal, conditions); } catch (e) { lastException = e; - if (e.code === 'ERR_PACKAGE_PATH_NOT_EXPORTED' || - e.code === 'ERR_INVALID_PACKAGE_TARGET') { + if (e.code === 'ERR_INVALID_PACKAGE_TARGET') continue; - } throw e; } - - return finalizeResolution(resolved, base); + if (resolved === undefined) + continue; + if (resolved === null) { + lastException = null; + continue; + } + return resolved; } + if (lastException === undefined || lastException === null) + return lastException; throw lastException; } else if (typeof target === 'object' && target !== null) { const keys = ObjectGetOwnPropertyNames(target); @@ -426,26 +516,28 @@ function resolveExportsTarget( const key = keys[i]; if (isArrayIndex(key)) { throw new ERR_INVALID_PACKAGE_CONFIG( - fileURLToPath(packageJSONUrl), - '"exports" cannot contain numeric property keys'); + fileURLToPath(packageJSONUrl), base, + '"exports" cannot contain numeric property keys.'); } } for (let i = 0; i < keys.length; i++) { const key = keys[i]; - if (key === 'node' || key === 'import' || key === 'default') { + if (key === 'default' || conditions.has(key)) { const conditionalTarget = target[key]; - try { - return resolveExportsTarget( - packageJSONUrl, conditionalTarget, subpath, packageSubpath, base); - } catch (e) { - if (e.code === 'ERR_PACKAGE_PATH_NOT_EXPORTED') continue; - throw e; - } + const resolved = resolvePackageTarget( + packageJSONUrl, conditionalTarget, subpath, packageSubpath, base, + pattern, internal, conditions); + if (resolved === undefined) + continue; + return resolved; } } - throwExportsNotFound(packageSubpath, packageJSONUrl, base); + return undefined; + } else if (target === null) { + return null; } - throwExportsInvalid(packageSubpath, target, packageJSONUrl, base); + throwInvalidPackageTarget(packageSubpath, target, packageJSONUrl, internal, + base); } function isConditionalExportsMainSugar(exports, packageJSONUrl, base) { @@ -462,7 +554,7 @@ function isConditionalExportsMainSugar(exports, packageJSONUrl, base) { isConditionalSugar = curIsConditionalSugar; } else if (isConditionalSugar !== curIsConditionalSugar) { throw new ERR_INVALID_PACKAGE_CONFIG( - fileURLToPath(packageJSONUrl), + fileURLToPath(packageJSONUrl), base, '"exports" cannot contain some keys starting with \'.\' and some not.' + ' The exports object must either be an object of package subpath keys' + ' or an object of main entry condition name keys only.'); @@ -471,89 +563,126 @@ function isConditionalExportsMainSugar(exports, packageJSONUrl, base) { return isConditionalSugar; } - -function packageMainResolve(packageJSONUrl, packageConfig, base) { - if (packageConfig.exists) { - const exports = packageConfig.exports; - if (exports !== undefined) { - if (isConditionalExportsMainSugar(exports, packageJSONUrl, base)) { - return resolveExportsTarget(packageJSONUrl, exports, '', '', base); - } else if (typeof exports === 'object' && exports !== null) { - const target = exports['.']; - if (target !== undefined) - return resolveExportsTarget(packageJSONUrl, target, '', '', base); - } - - throw new ERR_PACKAGE_PATH_NOT_EXPORTED(packageJSONUrl, '.'); - } - if (packageConfig.main !== undefined) { - const resolved = new URL(packageConfig.main, packageJSONUrl); - const path = fileURLToPath(resolved); - if (tryStatSync(path).isFile()) return resolved; - } - if (getOptionValue('--experimental-specifier-resolution') === 'node') { - if (packageConfig.main !== undefined) { - return finalizeResolution( - new URL(packageConfig.main, packageJSONUrl), base); - } else { - return finalizeResolution( - new URL('index', packageJSONUrl), base); - } - } - if (packageConfig.type !== 'module') { - return legacyMainResolve(packageJSONUrl, packageConfig); - } - } - - throw new ERR_MODULE_NOT_FOUND( - fileURLToPath(new URL('.', packageJSONUrl)), fileURLToPath(base)); -} - - +/** + * @param {URL} packageJSONUrl + * @param {string} packageSubpath + * @param {object} packageConfig + * @param {string} base + * @param {Set} conditions + * @returns {URL} + */ function packageExportsResolve( - packageJSONUrl, packageSubpath, packageConfig, base) /* -> URL */ { - const exports = packageConfig.exports; - if (exports === undefined || - isConditionalExportsMainSugar(exports, packageJSONUrl, base)) { - throwExportsNotFound(packageSubpath, packageJSONUrl, base); - } - + packageJSONUrl, packageSubpath, packageConfig, base, conditions) { + let exports = packageConfig.exports; + if (isConditionalExportsMainSugar(exports, packageJSONUrl, base)) + exports = { '.': exports }; if (ObjectPrototypeHasOwnProperty(exports, packageSubpath)) { const target = exports[packageSubpath]; - const resolved = resolveExportsTarget( - packageJSONUrl, target, '', packageSubpath, base); - return finalizeResolution(resolved, base); + const resolved = resolvePackageTarget( + packageJSONUrl, target, '', packageSubpath, base, false, false, conditions + ); + if (resolved === null || resolved === undefined) + throwExportsNotFound(packageSubpath, packageJSONUrl, base); + return { resolved, exact: true }; } let bestMatch = ''; const keys = ObjectGetOwnPropertyNames(exports); for (let i = 0; i < keys.length; i++) { const key = keys[i]; - if (key[key.length - 1] !== '/') continue; - if (StringPrototypeStartsWith(packageSubpath, key) && + if (key[key.length - 1] === '*' && + StringPrototypeStartsWith(packageSubpath, + StringPrototypeSlice(key, 0, -1)) && + packageSubpath.length >= key.length && key.length > bestMatch.length) { bestMatch = key; + } else if (key[key.length - 1] === '/' && + StringPrototypeStartsWith(packageSubpath, key) && + key.length > bestMatch.length) { + bestMatch = key; } } if (bestMatch) { const target = exports[bestMatch]; - const subpath = StringPrototypeSubstr(packageSubpath, bestMatch.length); - const resolved = resolveExportsTarget( - packageJSONUrl, target, subpath, packageSubpath, base); - return finalizeResolution(resolved, base); + const pattern = bestMatch[bestMatch.length - 1] === '*'; + const subpath = StringPrototypeSubstr(packageSubpath, bestMatch.length - + (pattern ? 1 : 0)); + const resolved = resolvePackageTarget(packageJSONUrl, target, subpath, + bestMatch, base, pattern, false, + conditions); + if (resolved === null || resolved === undefined) + throwExportsNotFound(packageSubpath, packageJSONUrl, base); + if (!pattern) + emitFolderMapDeprecation(bestMatch, packageJSONUrl, true, base); + return { resolved, exact: pattern }; } throwExportsNotFound(packageSubpath, packageJSONUrl, base); } +function packageImportsResolve(name, base, conditions) { + if (name === '#' || StringPrototypeStartsWith(name, '#/')) { + const reason = 'is not a valid internal imports specifier name'; + throw new ERR_INVALID_MODULE_SPECIFIER(name, reason, fileURLToPath(base)); + } + let packageJSONUrl; + const packageConfig = getPackageScopeConfig(base); + if (packageConfig.exists) { + packageJSONUrl = pathToFileURL(packageConfig.pjsonPath); + const imports = packageConfig.imports; + if (imports) { + if (ObjectPrototypeHasOwnProperty(imports, name)) { + const resolved = resolvePackageTarget( + packageJSONUrl, imports[name], '', name, base, false, true, conditions + ); + if (resolved !== null) + return { resolved, exact: true }; + } else { + let bestMatch = ''; + const keys = ObjectGetOwnPropertyNames(imports); + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + if (key[key.length - 1] === '*' && + StringPrototypeStartsWith(name, + StringPrototypeSlice(key, 0, -1)) && + name.length >= key.length && + key.length > bestMatch.length) { + bestMatch = key; + } else if (key[key.length - 1] === '/' && + StringPrototypeStartsWith(name, key) && + key.length > bestMatch.length) { + bestMatch = key; + } + } + + if (bestMatch) { + const target = imports[bestMatch]; + const pattern = bestMatch[bestMatch.length - 1] === '*'; + const subpath = StringPrototypeSubstr(name, bestMatch.length - + (pattern ? 1 : 0)); + const resolved = resolvePackageTarget( + packageJSONUrl, target, subpath, bestMatch, base, pattern, true, + conditions); + if (resolved !== null) { + if (!pattern) + emitFolderMapDeprecation(bestMatch, packageJSONUrl, false, base); + return { resolved, exact: pattern }; + } + } + } + } + } + throwImportNotDefined(name, packageJSONUrl, base); +} + function getPackageType(url) { - const packageConfig = getPackageScopeConfig(url, url); + const packageConfig = getPackageScopeConfig(url); return packageConfig.type; } -function packageResolve(specifier /* string */, base /* URL */) { /* -> URL */ +function parsePackageName(specifier, base) { let separatorIndex = StringPrototypeIndexOf(specifier, '/'); let validPackageName = true; let isScoped = false; @@ -581,35 +710,34 @@ function packageResolve(specifier /* string */, base /* URL */) { /* -> URL */ if (!validPackageName) { throw new ERR_INVALID_MODULE_SPECIFIER( - specifier, undefined, fileURLToPath(base)); + specifier, 'is not a valid package name', fileURLToPath(base)); } - const packageSubpath = separatorIndex === -1 ? - '' : '.' + StringPrototypeSlice(specifier, separatorIndex); + const packageSubpath = '.' + (separatorIndex === -1 ? '' : + StringPrototypeSlice(specifier, separatorIndex)); + + return { packageName, packageSubpath, isScoped }; +} + +/** + * @param {string} specifier + * @param {URL} base + * @param {Set} conditions + * @returns {URL} + */ +function packageResolve(specifier, base, conditions) { + const { packageName, packageSubpath, isScoped } = + parsePackageName(specifier, base); // ResolveSelf - const packageConfig = getPackageScopeConfig(base, base); + const packageConfig = getPackageScopeConfig(base); if (packageConfig.exists) { - // TODO(jkrems): Find a way to forward the pair/iterator already generated - // while executing GetPackageScopeConfig - let packageJSONUrl; - for (const [ filename, packageConfigCandidate ] of packageJSONCache) { - if (packageConfig === packageConfigCandidate) { - packageJSONUrl = pathToFileURL(filename); - break; - } - } - if (packageJSONUrl !== undefined && - packageConfig.name === packageName && - packageConfig.exports !== undefined) { - if (packageSubpath === './') { - return new URL('./', packageJSONUrl); - } else if (packageSubpath === '') { - return packageMainResolve(packageJSONUrl, packageConfig, base); - } else { - return packageExportsResolve( - packageJSONUrl, packageSubpath, packageConfig, base); - } + const packageJSONUrl = pathToFileURL(packageConfig.pjsonPath); + if (packageConfig.name === packageName && + packageConfig.exports !== undefined && packageConfig.exports !== null) { + return packageExportsResolve( + packageJSONUrl, packageSubpath, packageConfig, base, conditions + ).resolved; } } @@ -618,8 +746,8 @@ function packageResolve(specifier /* string */, base /* URL */) { /* -> URL */ let packageJSONPath = fileURLToPath(packageJSONUrl); let lastPath; do { - const stat = tryStatSync( - StringPrototypeSlice(packageJSONPath, 0, packageJSONPath.length - 13)); + const stat = tryStatSync(StringPrototypeSlice(packageJSONPath, 0, + packageJSONPath.length - 13)); if (!stat.isDirectory()) { lastPath = packageJSONPath; packageJSONUrl = new URL((isScoped ? @@ -630,18 +758,14 @@ function packageResolve(specifier /* string */, base /* URL */) { /* -> URL */ } // Package match. - const packageConfig = getPackageConfig(packageJSONPath, base); - if (packageSubpath === './') { - return new URL('./', packageJSONUrl); - } else if (packageSubpath === '') { - return packageMainResolve(packageJSONUrl, packageConfig, base); - } else if (packageConfig.exports !== undefined) { + const packageConfig = getPackageConfig(packageJSONPath, specifier, base); + if (packageConfig.exports !== undefined && packageConfig.exports !== null) return packageExportsResolve( - packageJSONUrl, packageSubpath, packageConfig, base); - } else { - return finalizeResolution( - new URL(packageSubpath, packageJSONUrl), base); - } + packageJSONUrl, packageSubpath, packageConfig, base, conditions + ).resolved; + if (packageSubpath === '.') + return legacyMainResolve(packageJSONUrl, packageConfig, base); + return new URL(packageSubpath, packageJSONUrl); // Cross-platform root check. } while (packageJSONPath.length !== lastPath.length); @@ -650,9 +774,11 @@ function packageResolve(specifier /* string */, base /* URL */) { /* -> URL */ throw new ERR_MODULE_NOT_FOUND(packageName, fileURLToPath(base)); } -function shouldBeTreatedAsRelativeOrAbsolutePath(specifier) { - if (specifier === '') return false; - if (specifier[0] === '/') return true; +function isBareSpecifier(specifier) { + return specifier[0] && specifier[0] !== '/' && specifier[0] !== '.'; +} + +function isRelativeSpecifier(specifier) { if (specifier[0] === '.') { if (specifier.length === 1 || specifier[1] === '/') return true; if (specifier[1] === '.') { @@ -662,23 +788,104 @@ function shouldBeTreatedAsRelativeOrAbsolutePath(specifier) { return false; } -function moduleResolve(specifier /* string */, base /* URL */) { /* -> URL */ +function shouldBeTreatedAsRelativeOrAbsolutePath(specifier) { + if (specifier === '') return false; + if (specifier[0] === '/') return true; + return isRelativeSpecifier(specifier); +} + +/** + * @param {string} specifier + * @param {URL} base + * @param {Set} conditions + * @returns {URL} + */ +function moduleResolve(specifier, base, conditions) { // Order swapped from spec for minor perf gain. // Ok since relative URLs cannot parse as URLs. let resolved; if (shouldBeTreatedAsRelativeOrAbsolutePath(specifier)) { resolved = new URL(specifier, base); + } else if (specifier[0] === '#') { + ({ resolved } = packageImportsResolve(specifier, base, conditions)); } else { try { resolved = new URL(specifier); } catch { - return packageResolve(specifier, base); + resolved = packageResolve(specifier, base, conditions); } } return finalizeResolution(resolved, base); } -function defaultResolve(specifier, { parentURL } = {}, defaultResolveUnused) { +/** + * Try to resolve an import as a CommonJS module + * @param {string} specifier + * @param {string} parentURL + * @returns {boolean|string} + */ +function resolveAsCommonJS(specifier, parentURL) { + try { + const parent = fileURLToPath(parentURL); + const tmpModule = new CJSModule(parent, null); + tmpModule.paths = CJSModule._nodeModulePaths(parent); + + let found = CJSModule._resolveFilename(specifier, tmpModule, false); + + // If it is a relative specifier return the relative path + // to the parent + if (isRelativeSpecifier(specifier)) { + found = relative(parent, found); + // Add '.separator if the path does not start with '..separator' + // This should be a safe assumption because when loading + // esm modules there should be always a file specified so + // there should not be a specifier like '..' or '.' + if (!StringPrototypeStartsWith(found, `..${sep}`)) { + found = `.${sep}${found}`; + } + } else if (isBareSpecifier(specifier)) { + // If it is a bare specifier return the relative path within the + // module + const pkg = StringPrototypeSplit(specifier, '/')[0]; + const index = StringPrototypeIndexOf(found, pkg); + if (index !== -1) { + found = StringPrototypeSlice(found, index); + } + } + // Normalize the path separator to give a valid suggestion + // on Windows + if (process.platform === 'win32') { + found = StringPrototypeReplace(found, new RegExp(`\\${sep}`, 'g'), '/'); + } + return found; + } catch { + return false; + } +} + +function defaultResolve(specifier, context = {}, defaultResolveUnused) { + let { parentURL, conditions } = context; + if (parentURL && policy != null && policy.manifest) { + const redirects = policy.manifest.getDependencyMapper(parentURL); + if (redirects) { + const { resolve, reaction } = redirects; + const destination = resolve(specifier, new SafeSet(conditions)); + let missing = true; + if (destination === true) { + missing = false; + } else if (destination) { + const href = destination.href; + return { url: href }; + } + if (missing) { + reaction(new ERR_MANIFEST_DEPENDENCY_MISSING( + parentURL, + specifier, + ArrayPrototypeJoin([...conditions], ', ')) + ); + } + } + } let parsed; try { parsed = new URL(specifier); @@ -688,13 +895,13 @@ function defaultResolve(specifier, { parentURL } = {}, defaultResolveUnused) { }; } } catch {} - if (parsed && parsed.protocol === 'nodejs:') + if (parsed && parsed.protocol === builtinModuleProtocol) return { url: specifier }; if (parsed && parsed.protocol !== 'file:' && parsed.protocol !== 'data:') - throw new ERR_UNSUPPORTED_ESM_URL_SCHEME(); + throw new ERR_UNSUPPORTED_ESM_URL_SCHEME(parsed); if (NativeModule.canBeRequiredByUsers(specifier)) { return { - url: 'nodejs:' + specifier + url: builtinModuleProtocol + specifier }; } if (parentURL && StringPrototypeStartsWith(parentURL, 'data:')) { @@ -716,7 +923,32 @@ function defaultResolve(specifier, { parentURL } = {}, defaultResolveUnused) { throw new ERR_INPUT_TYPE_NOT_ALLOWED(); } - let url = moduleResolve(specifier, new URL(parentURL)); + conditions = getConditionsSet(conditions); + let url; + try { + url = moduleResolve(specifier, parentURL, conditions); + } catch (error) { + // Try to give the user a hint of what would have been the + // resolved CommonJS module + if (error.code === 'ERR_MODULE_NOT_FOUND' || + error.code === 'ERR_UNSUPPORTED_DIR_IMPORT') { + if (StringPrototypeStartsWith(specifier, 'file://')) { + specifier = fileURLToPath(specifier); + } + const found = resolveAsCommonJS(specifier, parentURL); + if (found) { + // Modify the stack and message string to include the hint + const lines = StringPrototypeSplit(error.stack, '\n'); + const hint = `Did you mean to import ${found}?`; + error.stack = + ArrayPrototypeShift(lines) + '\n' + + hint + '\n' + + ArrayPrototypeJoin(lines, '\n'); + error.message += `\n${hint}`; + } + } + throw error; + } if (isMain ? !preserveSymlinksMain : !preserveSymlinks) { const urlPath = fileURLToPath(url); @@ -724,7 +956,8 @@ function defaultResolve(specifier, { parentURL } = {}, defaultResolveUnused) { // [internalFS.realpathCacheKey]: realpathCache }); const old = url; - url = pathToFileURL(real + (urlPath.endsWith(sep) ? '/' : '')); + url = pathToFileURL( + real + (StringPrototypeEndsWith(urlPath, sep) ? '/' : '')); url.search = old.search; url.hash = old.hash; } @@ -733,10 +966,14 @@ function defaultResolve(specifier, { parentURL } = {}, defaultResolveUnused) { } return { + DEFAULT_CONDITIONS, defaultResolve, - getPackageType + encodedSepRegEx, + getPackageType, + packageExportsResolve, + packageImportsResolve }; } module.exports = { createResolve -} +}; diff --git a/dist-raw/node-internal-fs.js b/dist-raw/node-internal-fs.js new file mode 100644 index 000000000..d9a2528dd --- /dev/null +++ b/dist-raw/node-internal-fs.js @@ -0,0 +1,22 @@ +const fs = require('fs'); + +// In node's core, this is implemented in C +// https://github.com/nodejs/node/blob/v15.3.0/src/node_file.cc#L891-L985 +function internalModuleReadJSON(path) { + let string + try { + string = fs.readFileSync(path, 'utf8') + } catch (e) { + if (e.code === 'ENOENT') return [] + throw e + } + // Node's implementation checks for the presence of relevant keys: main, name, type, exports, imports + // Node does this for performance to skip unnecessary parsing. + // This would slow us down and, based on our usage, we can skip it. + const containsKeys = true + return [string, containsKeys] +} + +module.exports = { + internalModuleReadJSON +}; diff --git a/dist-raw/node-options.js b/dist-raw/node-options.js index f27a44689..0602a4769 100644 --- a/dist-raw/node-options.js +++ b/dist-raw/node-options.js @@ -14,8 +14,12 @@ function parseOptions() { '--preserve-symlinks-main': false, '--input-type': undefined, '--experimental-specifier-resolution': 'explicit', + '--experimental-policy': undefined, + '--conditions': [], + '--pending-deprecation': false, ...parseArgv(getNodeOptionsEnvArgv()), - ...parseArgv(process.execArgv) + ...parseArgv(process.execArgv), + ...getOptionValuesFromOtherEnvVars() } } } @@ -25,7 +29,12 @@ function parseArgv(argv) { '--preserve-symlinks': Boolean, '--preserve-symlinks-main': Boolean, '--input-type': String, - '--experimental-specifier-resolution': String + '--experimental-specifier-resolution': String, + // Legacy alias for node versions prior to 12.16 + '--es-module-specifier-resolution': '--experimental-specifier-resolution', + '--experimental-policy': String, + '--conditions': [String], + '--pending-deprecation': Boolean }, { argv, permissive: true @@ -81,3 +90,12 @@ function ParseNodeOptionsEnvVar(node_options, errors) { } return env_argv; } + +// Get option values that can be specified via env vars besides NODE_OPTIONS +function getOptionValuesFromOtherEnvVars() { + const options = {}; + if(process.env.NODE_PENDING_DEPRECATION === '1') { + options['--pending-deprecation'] = true; + } + return options; +} diff --git a/dist-raw/node-package-json-reader.js b/dist-raw/node-package-json-reader.js new file mode 100644 index 000000000..1c36501cd --- /dev/null +++ b/dist-raw/node-package-json-reader.js @@ -0,0 +1,44 @@ +// copied from https://github.com/nodejs/node/blob/v15.3.0/lib/internal/modules/package_json_reader.js +'use strict'; + +const { SafeMap } = require('./node-primordials'); +const { internalModuleReadJSON } = require('./node-internal-fs'); +const { pathToFileURL } = require('url'); +const { toNamespacedPath } = require('path'); + +const cache = new SafeMap(); + +let manifest; + +/** + * @param {string} jsonPath + * @return {[string, boolean]} + */ +function read(jsonPath) { + if (cache.has(jsonPath)) { + return cache.get(jsonPath); + } + + const [string, containsKeys] = internalModuleReadJSON( + toNamespacedPath(jsonPath) + ); + const result = { string, containsKeys }; + const { getOptionValue } = require('./node-options'); + if (string !== undefined) { + if (manifest === undefined) { + // manifest = getOptionValue('--experimental-policy') ? + // require('internal/process/policy').manifest : + // null; + // disabled for now. I am not sure if/how we should support this + manifest = null; + } + if (manifest !== null) { + const jsonURL = pathToFileURL(jsonPath); + manifest.assertIntegrity(jsonURL, string); + } + } + cache.set(jsonPath, result); + return result; +} + +module.exports = { read }; diff --git a/dist-raw/node-primordials.js b/dist-raw/node-primordials.js new file mode 100644 index 000000000..ec8083460 --- /dev/null +++ b/dist-raw/node-primordials.js @@ -0,0 +1,34 @@ +module.exports = { + ArrayFrom: Array.from, + ArrayIsArray: Array.isArray, + ArrayPrototypeJoin: (obj, separator) => Array.prototype.join.call(obj, separator), + ArrayPrototypeShift: (obj) => Array.prototype.shift.call(obj), + ArrayPrototypeForEach: (arr, ...rest) => Array.prototype.forEach.apply(arr, rest), + ArrayPrototypeIncludes: (arr, ...rest) => Array.prototype.includes.apply(arr, rest), + ArrayPrototypeJoin: (arr, ...rest) => Array.prototype.join.apply(arr, rest), + ArrayPrototypePop: (arr, ...rest) => Array.prototype.pop.apply(arr, rest), + ArrayPrototypePush: (arr, ...rest) => Array.prototype.push.apply(arr, rest), + FunctionPrototype: Function.prototype, + JSONParse: JSON.parse, + JSONStringify: JSON.stringify, + ObjectFreeze: Object.freeze, + ObjectKeys: Object.keys, + ObjectGetOwnPropertyNames: Object.getOwnPropertyNames, + ObjectDefineProperty: Object.defineProperty, + ObjectPrototypeHasOwnProperty: (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop), + RegExpPrototypeTest: (obj, string) => RegExp.prototype.test.call(obj, string), + RegExpPrototypeSymbolReplace: (obj, ...rest) => RegExp.prototype[Symbol.replace].apply(obj, rest), + SafeMap: Map, + SafeSet: Set, + StringPrototypeEndsWith: (str, ...rest) => String.prototype.endsWith.apply(str, rest), + StringPrototypeIncludes: (str, ...rest) => String.prototype.includes.apply(str, rest), + StringPrototypeLastIndexOf: (str, ...rest) => String.prototype.lastIndexOf.apply(str, rest), + StringPrototypeIndexOf: (str, ...rest) => String.prototype.indexOf.apply(str, rest), + StringPrototypeRepeat: (str, ...rest) => String.prototype.repeat.apply(str, rest), + StringPrototypeReplace: (str, ...rest) => String.prototype.replace.apply(str, rest), + StringPrototypeSlice: (str, ...rest) => String.prototype.slice.apply(str, rest), + StringPrototypeSplit: (str, ...rest) => String.prototype.split.apply(str, rest), + StringPrototypeStartsWith: (str, ...rest) => String.prototype.startsWith.apply(str, rest), + StringPrototypeSubstr: (str, ...rest) => String.prototype.substr.apply(str, rest), + SyntaxError: SyntaxError +}; diff --git a/dist-raw/node-repl-await.js b/dist-raw/node-repl-await.js new file mode 100644 index 000000000..85bff2de1 --- /dev/null +++ b/dist-raw/node-repl-await.js @@ -0,0 +1,254 @@ +// copied from https://github.com/nodejs/node/blob/88799930794045795e8abac874730f9eba7e2300/lib/internal/repl/await.js +'use strict'; + +const { + ArrayFrom, + ArrayPrototypeForEach, + ArrayPrototypeIncludes, + ArrayPrototypeJoin, + ArrayPrototypePop, + ArrayPrototypePush, + FunctionPrototype, + ObjectKeys, + RegExpPrototypeSymbolReplace, + StringPrototypeEndsWith, + StringPrototypeIncludes, + StringPrototypeIndexOf, + StringPrototypeRepeat, + StringPrototypeSplit, + StringPrototypeStartsWith, + SyntaxError, +} = require('./node-primordials'); + +const parser = require('acorn').Parser; +const walk = require('acorn-walk'); +const { Recoverable } = require('repl'); + +function isTopLevelDeclaration(state) { + return state.ancestors[state.ancestors.length - 2] === state.body; +} + +const noop = FunctionPrototype; +const visitorsWithoutAncestors = { + ClassDeclaration(node, state, c) { + if (isTopLevelDeclaration(state)) { + state.prepend(node, `${node.id.name}=`); + ArrayPrototypePush( + state.hoistedDeclarationStatements, + `let ${node.id.name}; ` + ); + } + + walk.base.ClassDeclaration(node, state, c); + }, + ForOfStatement(node, state, c) { + if (node.await === true) { + state.containsAwait = true; + } + walk.base.ForOfStatement(node, state, c); + }, + FunctionDeclaration(node, state, c) { + state.prepend(node, `${node.id.name}=`); + ArrayPrototypePush( + state.hoistedDeclarationStatements, + `var ${node.id.name}; ` + ); + }, + FunctionExpression: noop, + ArrowFunctionExpression: noop, + MethodDefinition: noop, + AwaitExpression(node, state, c) { + state.containsAwait = true; + walk.base.AwaitExpression(node, state, c); + }, + ReturnStatement(node, state, c) { + state.containsReturn = true; + walk.base.ReturnStatement(node, state, c); + }, + VariableDeclaration(node, state, c) { + const variableKind = node.kind; + const isIterableForDeclaration = ArrayPrototypeIncludes( + ['ForOfStatement', 'ForInStatement'], + state.ancestors[state.ancestors.length - 2].type + ); + + if (variableKind === 'var' || isTopLevelDeclaration(state)) { + state.replace( + node.start, + node.start + variableKind.length + (isIterableForDeclaration ? 1 : 0), + variableKind === 'var' && isIterableForDeclaration ? + '' : + 'void' + (node.declarations.length === 1 ? '' : ' (') + ); + + if (!isIterableForDeclaration) { + ArrayPrototypeForEach(node.declarations, (decl) => { + state.prepend(decl, '('); + state.append(decl, decl.init ? ')' : '=undefined)'); + }); + + if (node.declarations.length !== 1) { + state.append(node.declarations[node.declarations.length - 1], ')'); + } + } + + const variableIdentifiersToHoist = [ + ['var', []], + ['let', []], + ]; + function registerVariableDeclarationIdentifiers(node) { + switch (node.type) { + case 'Identifier': + ArrayPrototypePush( + variableIdentifiersToHoist[variableKind === 'var' ? 0 : 1][1], + node.name + ); + break; + case 'ObjectPattern': + ArrayPrototypeForEach(node.properties, (property) => { + registerVariableDeclarationIdentifiers(property.value); + }); + break; + case 'ArrayPattern': + ArrayPrototypeForEach(node.elements, (element) => { + registerVariableDeclarationIdentifiers(element); + }); + break; + } + } + + ArrayPrototypeForEach(node.declarations, (decl) => { + registerVariableDeclarationIdentifiers(decl.id); + }); + + ArrayPrototypeForEach( + variableIdentifiersToHoist, + ({ 0: kind, 1: identifiers }) => { + if (identifiers.length > 0) { + ArrayPrototypePush( + state.hoistedDeclarationStatements, + `${kind} ${ArrayPrototypeJoin(identifiers, ', ')}; ` + ); + } + } + ); + } + + walk.base.VariableDeclaration(node, state, c); + } +}; + +const visitors = {}; +for (const nodeType of ObjectKeys(walk.base)) { + const callback = visitorsWithoutAncestors[nodeType] || walk.base[nodeType]; + visitors[nodeType] = (node, state, c) => { + const isNew = node !== state.ancestors[state.ancestors.length - 1]; + if (isNew) { + ArrayPrototypePush(state.ancestors, node); + } + callback(node, state, c); + if (isNew) { + ArrayPrototypePop(state.ancestors); + } + }; +} + +function processTopLevelAwait(src) { + const wrapPrefix = '(async () => { '; + const wrapped = `${wrapPrefix}${src} })()`; + const wrappedArray = ArrayFrom(wrapped); + let root; + try { + root = parser.parse(wrapped, { ecmaVersion: 'latest' }); + } catch (e) { + if (StringPrototypeStartsWith(e.message, 'Unterminated ')) + throw new Recoverable(e); + // If the parse error is before the first "await", then use the execution + // error. Otherwise we must emit this parse error, making it look like a + // proper syntax error. + const awaitPos = StringPrototypeIndexOf(src, 'await'); + const errPos = e.pos - wrapPrefix.length; + if (awaitPos > errPos) + return null; + // Convert keyword parse errors on await into their original errors when + // possible. + if (errPos === awaitPos + 6 && + StringPrototypeIncludes(e.message, 'Expecting Unicode escape sequence')) + return null; + if (errPos === awaitPos + 7 && + StringPrototypeIncludes(e.message, 'Unexpected token')) + return null; + const line = e.loc.line; + const column = line === 1 ? e.loc.column - wrapPrefix.length : e.loc.column; + let message = '\n' + StringPrototypeSplit(src, '\n')[line - 1] + '\n' + + StringPrototypeRepeat(' ', column) + + '^\n\n' + RegExpPrototypeSymbolReplace(/ \([^)]+\)/, e.message, ''); + // V8 unexpected token errors include the token string. + if (StringPrototypeEndsWith(message, 'Unexpected token')) + message += " '" + + // Wrapper end may cause acorn to report error position after the source + ((src.length - 1) >= (e.pos - wrapPrefix.length) + ? src[e.pos - wrapPrefix.length] + : src[src.length - 1]) + + "'"; + // eslint-disable-next-line no-restricted-syntax + throw new SyntaxError(message); + } + const body = root.body[0].expression.callee.body; + const state = { + body, + ancestors: [], + hoistedDeclarationStatements: [], + replace(from, to, str) { + for (let i = from; i < to; i++) { + wrappedArray[i] = ''; + } + if (from === to) str += wrappedArray[from]; + wrappedArray[from] = str; + }, + prepend(node, str) { + wrappedArray[node.start] = str + wrappedArray[node.start]; + }, + append(node, str) { + wrappedArray[node.end - 1] += str; + }, + containsAwait: false, + containsReturn: false + }; + + walk.recursive(body, state, visitors); + + // Do not transform if + // 1. False alarm: there isn't actually an await expression. + // 2. There is a top-level return, which is not allowed. + if (!state.containsAwait || state.containsReturn) { + return null; + } + + const last = body.body[body.body.length - 1]; + if (last.type === 'ExpressionStatement') { + // For an expression statement of the form + // ( expr ) ; + // ^^^^^^^^^^ // last + // ^^^^ // last.expression + // + // We do not want the left parenthesis before the `return` keyword; + // therefore we prepend the `return (` to `last`. + // + // On the other hand, we do not want the right parenthesis after the + // semicolon. Since there can only be more right parentheses between + // last.expression.end and the semicolon, appending one more to + // last.expression should be fine. + state.prepend(last, 'return ('); + state.append(last.expression, ')'); + } + + return ( + ArrayPrototypeJoin(state.hoistedDeclarationStatements, '') + + ArrayPrototypeJoin(wrappedArray, '') + ); +} + +module.exports = { + processTopLevelAwait +}; diff --git a/esm-usage-example/package.json b/esm-usage-example/package.json index e9974a780..ec1886ad7 100644 --- a/esm-usage-example/package.json +++ b/esm-usage-example/package.json @@ -1,7 +1,7 @@ { "type": "module", "dependencies": { - "ts-node": "github:TypeStrong/ts-node#ab/esm-support", + "ts-node": "github:TypeStrong/ts-node#main", "typescript": "^3.8.3" } } diff --git a/esm.mjs b/esm.mjs index 873ff9768..2a11ac36e 100644 --- a/esm.mjs +++ b/esm.mjs @@ -1,7 +1,11 @@ -import {fileURLToPath} from 'url' -import {createRequire} from 'module' -const require = createRequire(fileURLToPath(import.meta.url)) +import { fileURLToPath } from 'url'; +import { createRequire } from 'module'; +const require = createRequire(fileURLToPath(import.meta.url)); /** @type {import('./dist/esm')} */ -const esm = require('./dist/esm') -export const {resolve, getFormat, transformSource} = esm.registerAndCreateEsmHooks() +const esm = require('./dist/esm'); +export const { + resolve, + getFormat, + transformSource, +} = esm.registerAndCreateEsmHooks(); diff --git a/esm/transpile-only.mjs b/esm/transpile-only.mjs index 4823d5217..c19132284 100644 --- a/esm/transpile-only.mjs +++ b/esm/transpile-only.mjs @@ -1,7 +1,11 @@ -import {fileURLToPath} from 'url' -import {createRequire} from 'module' -const require = createRequire(fileURLToPath(import.meta.url)) +import { fileURLToPath } from 'url'; +import { createRequire } from 'module'; +const require = createRequire(fileURLToPath(import.meta.url)); /** @type {import('../dist/esm')} */ -const esm = require('../dist/esm') -export const {resolve, getFormat, transformSource} = esm.registerAndCreateEsmHooks({transpileOnly: true}) +const esm = require('../dist/esm'); +export const { + resolve, + getFormat, + transformSource, +} = esm.registerAndCreateEsmHooks({ transpileOnly: true }); diff --git a/logo-icon.svg b/logo-icon.svg new file mode 100644 index 000000000..8757b0806 --- /dev/null +++ b/logo-icon.svg @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/node10/tsconfig.json b/node10/tsconfig.json new file mode 100644 index 000000000..7079f3adb --- /dev/null +++ b/node10/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "@tsconfig/node10/tsconfig.json" +} diff --git a/node12/tsconfig.json b/node12/tsconfig.json new file mode 100644 index 000000000..76603f1cd --- /dev/null +++ b/node12/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "@tsconfig/node12/tsconfig.json", +} diff --git a/node14/tsconfig.json b/node14/tsconfig.json new file mode 100644 index 000000000..b08285106 --- /dev/null +++ b/node14/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "@tsconfig/node14/tsconfig.json" +} diff --git a/node16/tsconfig.json b/node16/tsconfig.json new file mode 100644 index 000000000..e9c0bafec --- /dev/null +++ b/node16/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "@tsconfig/node16/tsconfig.json" +} diff --git a/nyc.config.js b/nyc.config.js index 4a886a910..3f15fe94f 100644 --- a/nyc.config.js +++ b/nyc.config.js @@ -1,12 +1,7 @@ module.exports = { all: true, - include: [ - 'tests/node_modules/ts-node/**', - ], - exclude: [ - '**/*.d.ts', - 'tests/node_modules/ts-node/node_modules/**', - ], + include: ['tests/node_modules/ts-node/**'], + exclude: ['**/*.d.ts', 'tests/node_modules/ts-node/node_modules/**'], excludeNodeModules: false, - excludeAfterRemap: false + excludeAfterRemap: false, }; diff --git a/package-lock.json b/package-lock.json index 997c65b9a..9c01f18a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,24 +1,99 @@ { "name": "ts-node", - "version": "9.0.0", - "lockfileVersion": 1, + "version": "10.2.0", + "lockfileVersion": 2, "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha1-M+JZA9dIEYFTThLsCiXxa2/PQZ4=", + "packages": { + "": { + "name": "ts-node", + "version": "10.2.0", + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "0.6.1", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "devDependencies": { + "@microsoft/api-extractor": "^7.15.2", + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/chai": "^4.0.4", + "@types/diff": "^4.0.2", + "@types/lodash": "^4.14.151", + "@types/node": "13.13.5", + "@types/proxyquire": "^1.3.28", + "@types/react": "^16.0.2", + "@types/rimraf": "^3.0.0", + "@types/semver": "^7.1.0", + "@yarnpkg/fslib": "^2.4.0", + "ava": "^3.15.0", + "axios": "^0.21.1", + "chai": "^4.0.1", + "expect": "^27.0.2", + "get-stream": "^6.0.0", + "lodash": "^4.17.15", + "ntypescript": "^1.201507091536.1", + "nyc": "^15.0.1", + "prettier": "^2.2.1", + "proxyquire": "^2.0.0", + "react": "^16.14.0", + "rimraf": "^3.0.0", + "semver": "^7.1.3", + "throat": "^6.0.1", + "typedoc": "^0.20.28", + "typescript": "4.2.2", + "typescript-json-schema": "^0.42.0", + "util.promisify": "^1.0.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/@babel/code-frame": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", "dev": true, - "requires": { - "@babel/highlight": "^7.8.3" + "dependencies": { + "@babel/highlight": "^7.12.13" } }, - "@babel/core": { + "node_modules/@babel/core": { "version": "7.9.6", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.6.tgz", "integrity": "sha512-nD3deLvbsApbHAHttzIssYqgb883yU/d9roe4RZymBCDaZryMJDbptVpEpeQuRh4BJ+SYI8le9YGxKvFEvl1Wg==", "dev": true, - "requires": { + "dependencies": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.9.6", "@babel/helper-module-transforms": "^7.9.0", @@ -36,103 +111,111 @@ "semver": "^5.4.1", "source-map": "^0.5.0" }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } + "ms": "^2.1.1" } }, - "@babel/generator": { + "node_modules/@babel/core/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@babel/core/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/generator": { "version": "7.9.6", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.9.6", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } } }, - "@babel/helper-function-name": { + "node_modules/@babel/generator/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/helper-function-name": { "version": "7.9.5", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-get-function-arity": "^7.8.3", "@babel/template": "^7.8.3", "@babel/types": "^7.9.5" } }, - "@babel/helper-get-function-arity": { + "node_modules/@babel/helper-get-function-arity": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.8.3" } }, - "@babel/helper-member-expression-to-functions": { + "node_modules/@babel/helper-member-expression-to-functions": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.8.3" } }, - "@babel/helper-module-imports": { + "node_modules/@babel/helper-module-imports": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.8.3" } }, - "@babel/helper-module-transforms": { + "node_modules/@babel/helper-module-transforms": { "version": "7.9.0", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz", "integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-module-imports": "^7.8.3", "@babel/helper-replace-supers": "^7.8.6", "@babel/helper-simple-access": "^7.8.3", @@ -142,105 +225,138 @@ "lodash": "^4.17.13" } }, - "@babel/helper-optimise-call-expression": { + "node_modules/@babel/helper-optimise-call-expression": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.8.3" } }, - "@babel/helper-replace-supers": { + "node_modules/@babel/helper-replace-supers": { "version": "7.9.6", "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.9.6.tgz", "integrity": "sha512-qX+chbxkbArLyCImk3bWV+jB5gTNU/rsze+JlcF6Nf8tVTigPJSI1o1oBow/9Resa1yehUO9lIipsmu9oG4RzA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-member-expression-to-functions": "^7.8.3", "@babel/helper-optimise-call-expression": "^7.8.3", "@babel/traverse": "^7.9.6", "@babel/types": "^7.9.6" } }, - "@babel/helper-simple-access": { + "node_modules/@babel/helper-simple-access": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", "dev": true, - "requires": { + "dependencies": { "@babel/template": "^7.8.3", "@babel/types": "^7.8.3" } }, - "@babel/helper-split-export-declaration": { + "node_modules/@babel/helper-split-export-declaration": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.8.3" } }, - "@babel/helper-validator-identifier": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz", - "integrity": "sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==", + "node_modules/@babel/helper-validator-identifier": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", + "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", "dev": true }, - "@babel/helpers": { + "node_modules/@babel/helpers": { "version": "7.9.6", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.6.tgz", "integrity": "sha512-tI4bUbldloLcHWoRUMAj4g1bF313M/o6fBKhIsb3QnGVPwRm9JsNf/gqMkQ7zjqReABiffPV6RWj7hEglID5Iw==", "dev": true, - "requires": { + "dependencies": { "@babel/template": "^7.8.3", "@babel/traverse": "^7.9.6", "@babel/types": "^7.9.6" } }, - "@babel/highlight": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", - "integrity": "sha1-TptFzLgreWBycbKXmtgse2gWMHk=", + "node_modules/@babel/highlight": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", + "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.9.0", + "dependencies": { + "@babel/helper-validator-identifier": "^7.14.0", "chalk": "^2.0.0", "js-tokens": "^4.0.0" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "dependencies": { - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - } + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "@babel/parser": { + "node_modules/@babel/parser": { "version": "7.9.6", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", - "dev": true + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } }, - "@babel/template": { + "node_modules/@babel/template": { "version": "7.8.6", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", "dev": true, - "requires": { + "dependencies": { "@babel/code-frame": "^7.8.3", "@babel/parser": "^7.8.6", "@babel/types": "^7.8.6" } }, - "@babel/traverse": { + "node_modules/@babel/traverse": { "version": "7.9.6", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", "dev": true, - "requires": { + "dependencies": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.9.6", "@babel/helper-function-name": "^7.9.5", @@ -250,312 +366,7670 @@ "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" - }, + } + }, + "node_modules/@babel/traverse/node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } + "ms": "^2.1.1" } }, - "@babel/types": { + "node_modules/@babel/types": { "version": "7.9.6", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-validator-identifier": "^7.9.5", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" + } + }, + "node_modules/@concordance/react": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@concordance/react/-/react-2.0.0.tgz", + "integrity": "sha512-huLSkUuM2/P+U0uy2WwlKuixMsTODD8p4JVQBI4VKeopkiN0C7M3N9XYVawb4M+4spN5RrO/eLhk7KoQX6nsfA==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1" }, + "engines": { + "node": ">=6.12.3 <7 || >=8.9.4 <9 || >=10.0.0" + } + }, + "node_modules/@concordance/react/node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz", + "integrity": "sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg==", "dependencies": { - "@babel/helper-validator-identifier": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", - "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", - "dev": true - } + "@cspotcode/source-map-consumer": "0.8.0" + }, + "engines": { + "node": ">=12" } }, - "@istanbuljs/load-nyc-config": { + "node_modules/@istanbuljs/load-nyc-config": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz", "integrity": "sha512-ZR0rq/f/E4f4XcgnDvtMWXCUJpi8eO0rssVhmztsZqLIEFA9UUP9zmpE0VxlM+kv/E1ul2I876Fwil2ayptDVg==", "dev": true, - "requires": { + "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", "js-yaml": "^3.13.1", "resolve-from": "^5.0.0" }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - } + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "@istanbuljs/schema": { + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "@types/chai": { - "version": "4.0.10", + "node_modules/@jest/types": { + "version": "27.0.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz", + "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@microsoft/api-extractor": { + "version": "7.15.2", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.15.2.tgz", + "integrity": "sha512-/Y/n+QOc1vM6Vg3OAUByT/wXdZciE7jV3ay33+vxl3aKva5cNsuOauL14T7XQWUiLko3ilPwrcnFcEjzXpLsuA==", + "dev": true, + "dependencies": { + "@microsoft/api-extractor-model": "7.13.2", + "@microsoft/tsdoc": "0.13.2", + "@microsoft/tsdoc-config": "~0.15.2", + "@rushstack/node-core-library": "3.38.0", + "@rushstack/rig-package": "0.2.12", + "@rushstack/ts-command-line": "4.7.10", + "colors": "~1.2.1", + "lodash": "~4.17.15", + "resolve": "~1.17.0", + "semver": "~7.3.0", + "source-map": "~0.6.1", + "typescript": "~4.2.4" + }, + "bin": { + "api-extractor": "bin/api-extractor" + } + }, + "node_modules/@microsoft/api-extractor-model": { + "version": "7.13.2", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.13.2.tgz", + "integrity": "sha512-gA9Q8q5TPM2YYk7rLinAv9KqcodrmRC13BVmNzLswjtFxpz13lRh0BmrqD01/sddGpGMIuWFYlfUM4VSWxnggA==", + "dev": true, + "dependencies": { + "@microsoft/tsdoc": "0.13.2", + "@microsoft/tsdoc-config": "~0.15.2", + "@rushstack/node-core-library": "3.38.0" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/colors": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", + "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/typescript": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@microsoft/tsdoc": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.13.2.tgz", + "integrity": "sha512-WrHvO8PDL8wd8T2+zBGKrMwVL5IyzR3ryWUsl0PXgEV0QHup4mTLi0QcATefGI6Gx9Anu7vthPyyyLpY0EpiQg==", + "dev": true + }, + "node_modules/@microsoft/tsdoc-config": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.15.2.tgz", + "integrity": "sha512-mK19b2wJHSdNf8znXSMYVShAHktVr/ib0Ck2FA3lsVBSEhSI/TfXT7DJQkAYgcztTuwazGcg58ZjYdk0hTCVrA==", + "dev": true, + "dependencies": { + "@microsoft/tsdoc": "0.13.2", + "ajv": "~6.12.6", + "jju": "~1.4.0", + "resolve": "~1.19.0" + } + }, + "node_modules/@microsoft/tsdoc-config/node_modules/resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "dependencies": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + } + }, + "node_modules/@napi-rs/triples": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@napi-rs/triples/-/triples-1.0.2.tgz", + "integrity": "sha512-EL3SiX43m9poFSnhDx4d4fn9SSaqyO2rHsCNhETi9bWPmjXK3uPJ0QpPFtx39FEdHcz1vJmsiW41kqc0AgvtzQ==", + "dev": true + }, + "node_modules/@node-rs/helper": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@node-rs/helper/-/helper-1.1.0.tgz", + "integrity": "sha512-r43YnnrY5JNzDuXJdW3sBJrKzvejvFmFWbiItUEoBJsaPzOIWFMhXB7i5j4c9EMXcFfxveF4l7hT+rLmwtjrVQ==", + "dev": true, + "dependencies": { + "@napi-rs/triples": "^1.0.2", + "tslib": "^2.1.0" + } + }, + "node_modules/@node-rs/helper/node_modules/tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", + "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.4", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", + "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", + "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.4", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@rushstack/node-core-library": { + "version": "3.38.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.38.0.tgz", + "integrity": "sha512-cmvl0yQx8sSmbuXwiRYJi8TO+jpTtrLJQ8UmFHhKvgPVJAW8cV8dnpD1Xx/BvTGrJZ2XtRAIkAhBS9okBnap4w==", + "dev": true, + "dependencies": { + "@types/node": "10.17.13", + "colors": "~1.2.1", + "fs-extra": "~7.0.1", + "import-lazy": "~4.0.0", + "jju": "~1.4.0", + "resolve": "~1.17.0", + "semver": "~7.3.0", + "timsort": "~0.3.0", + "z-schema": "~3.18.3" + } + }, + "node_modules/@rushstack/node-core-library/node_modules/@types/node": { + "version": "10.17.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.13.tgz", + "integrity": "sha512-pMCcqU2zT4TjqYFrWtYHKal7Sl30Ims6ulZ4UFXxI4xbtQqK/qqKwkDoBFCfooRqqmRu9vY3xaJRwxSh673aYg==", + "dev": true + }, + "node_modules/@rushstack/node-core-library/node_modules/colors": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", + "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@rushstack/node-core-library/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@rushstack/node-core-library/node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@rushstack/node-core-library/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@rushstack/node-core-library/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@rushstack/node-core-library/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/@rushstack/node-core-library/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@rushstack/node-core-library/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/@rushstack/node-core-library/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@rushstack/rig-package": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.2.12.tgz", + "integrity": "sha512-nbePcvF8hQwv0ql9aeQxcaMPK/h1OLAC00W7fWCRWIvD2MchZOE8jumIIr66HGrfG2X1sw++m/ZYI4D+BM5ovQ==", + "dev": true, + "dependencies": { + "resolve": "~1.17.0", + "strip-json-comments": "~3.1.1" + } + }, + "node_modules/@rushstack/rig-package/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/@rushstack/rig-package/node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@rushstack/ts-command-line": { + "version": "4.7.10", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.7.10.tgz", + "integrity": "sha512-8t042g8eerypNOEcdpxwRA3uCmz0duMo21rG4Z2mdz7JxJeylDmzjlU3wDdef2t3P1Z61JCdZB6fbm1Mh0zi7w==", + "dev": true, + "dependencies": { + "@types/argparse": "1.0.38", + "argparse": "~1.0.9", + "colors": "~1.2.1", + "string-argv": "~0.3.1" + } + }, + "node_modules/@rushstack/ts-command-line/node_modules/colors": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", + "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@swc/core": { + "version": "1.2.58", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.2.58.tgz", + "integrity": "sha512-u/vaon34x4ISDDdgZLaxacPB4Ly8SqqmFkBKPp2VtUDbD12VqKzb6EoLDC3A5EULFQDgIdIMHuVlBB+mc8dq0w==", + "dev": true, + "dependencies": { + "@node-rs/helper": "^1.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-android-arm64": "^1.2.58", + "@swc/core-darwin-arm64": "^1.2.58", + "@swc/core-darwin-x64": "^1.2.58", + "@swc/core-linux-arm-gnueabihf": "^1.2.58", + "@swc/core-linux-arm64-gnu": "^1.2.58", + "@swc/core-linux-x64-gnu": "^1.2.58", + "@swc/core-linux-x64-musl": "^1.2.58", + "@swc/core-win32-ia32-msvc": "^1.2.58", + "@swc/core-win32-x64-msvc": "^1.2.58" + } + }, + "node_modules/@swc/core-android-arm64": { + "version": "1.2.58", + "resolved": "https://registry.npmjs.org/@swc/core-android-arm64/-/core-android-arm64-1.2.58.tgz", + "integrity": "sha512-eSNNt/KiAbseOZ/lbaHnXClWOOeEPBRJBjxIBDX6U4oXaHLBCwgwU+qhWziVV4Lq6gX0zqcw6JY7Pxz9r2Pxzw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.2.58", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.2.58.tgz", + "integrity": "sha512-PHZm9kYi4KjWgac86fhr1238elI7M1K8Zh634eDCJCZbU7LHWUWOyeTpT9G8dxOuAUTOUZDaCHNW/+63N5XWPA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.2.58", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.2.58.tgz", + "integrity": "sha512-jKJNNxBbt/ckp49QUP28P+YEGDS3baruCBRbVkgJQY5Nj5GKw5kay6prVf6ajhoegmtjLr+1p3By7S5XOgIc8g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.2.58", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.2.58.tgz", + "integrity": "sha512-dnZcurOjTEr2IkSdWakyoVlE6ay3QQSSTv/9IsBH3eI7CI2+W8m9AtQ+KyN5BKPBSK5NjswF59xA3gocbsUpng==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.2.58", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.2.58.tgz", + "integrity": "sha512-lSOd73EqFLx0I0f9UJq2wbwjQc+tbXbLznJp89tEZeLOljuMJkF3O22l2Nv6Vet6NBPbTQYiKy6ouibFvOqMag==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.2.58", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.2.58.tgz", + "integrity": "sha512-bDU2LiURs4MKXWNNUKxVU1KKCO6lp1ILszkLPYuRAHbbQCtoQUe5JCbFlCqniFOxZOm2NBtZF4a+z5bGFpb0QA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.2.58", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.2.58.tgz", + "integrity": "sha512-wdF8nHrlMI4PUL13PQFo4BMfCr9HL3kNWftiA8i+mJhfp8Z2xfyarOnVkeXmYmQYGPoqSDCsskui6n5PvBLePw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.2.58", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.2.58.tgz", + "integrity": "sha512-Qrox0Kz3KQSYnMwAH55DYXzOG+L0PPYQHaQnJCh5rywKDUx2n/Ar5zKkVkEhRf0ehPgKajt0h2BYHsTpqNA9/w==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.2.58", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.2.58.tgz", + "integrity": "sha512-HPmxovhC7DbNcXLJe5nUmo+4o6Ea2d7oFdli3IvTgDri0IynQaRlfVWIuNnZmEsN7Gl1kW7PUK5WZXPUosMn8A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/wasm": { + "version": "1.2.58", + "resolved": "https://registry.npmjs.org/@swc/wasm/-/wasm-1.2.58.tgz", + "integrity": "sha512-3PAMVT+clB2xZsaVtQK2WjgeCftCxDO/0q8JCwW5g3CrLL/WBOCHyCKME3CzGz7V9zfw84QZZMpZY26gohhF/w==", + "dev": true + }, + "node_modules/@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "dependencies": { + "defer-to-connect": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.7.tgz", + "integrity": "sha512-aBvUmXLQbayM4w3A8TrjwrXs4DZ8iduJnuJLLRGdkWlyakCf1q6uHZJBzXoRA/huAEknG5tcUyQxN3A+In5euQ==" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.7.tgz", + "integrity": "sha512-dgasobK/Y0wVMswcipr3k0HpevxFJLijN03A8mYfEPvWvOs14v0ZlYTR4kIgMx8g4+fTyTFv8/jLCIfRqLDJ4A==" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.0.tgz", + "integrity": "sha512-RKkL8eTdPv6t5EHgFKIVQgsDapugbuOptNd9OOunN/HAkzmmTnZELx1kNCK0rSdUYGmiFMM3rRQMAWiyp023LQ==" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==" + }, + "node_modules/@types/argparse": { + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", + "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==", + "dev": true + }, + "node_modules/@types/chai": { + "version": "4.0.10", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.0.10.tgz", "integrity": "sha512-Ejh1AXTY8lm+x91X/yar3G2z4x9RyKwdTVdyyu7Xj3dNB35fMNCnEWqTO9FgS3zjzlRNqk1MruYhgb8yhRN9rA==", "dev": true }, - "@types/color-name": { + "node_modules/@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, - "@types/diff": { + "node_modules/@types/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/diff/-/diff-4.0.2.tgz", "integrity": "sha1-Lpu4n5rMOrAQjw89xNvc8v/4qZw=", "dev": true }, - "@types/events": { + "node_modules/@types/emscripten": { + "version": "1.39.4", + "resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.39.4.tgz", + "integrity": "sha512-k3LLVMFrdNA9UCvMDPWMbFrGPNb+GcPyw29ktJTo1RCN7RmxFG5XzPZcPKRlnLuLT/FRm8wp4ohvDwNY7GlROQ==", + "dev": true + }, + "node_modules/@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", "dev": true }, - "@types/glob": { + "node_modules/@types/glob": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", "dev": true, - "requires": { + "dependencies": { "@types/events": "*", "@types/minimatch": "*", "@types/node": "*" } }, - "@types/json-schema": { + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/json-schema": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz", "integrity": "sha1-OP1z3f2bVaux4bLtV4y1W9e30zk=", "dev": true }, - "@types/lodash": { + "node_modules/@types/lodash": { "version": "4.14.151", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.151.tgz", "integrity": "sha512-Zst90IcBX5wnwSu7CAS0vvJkTjTELY4ssKbHiTnGcJgi170uiS8yQDdc3v6S77bRqYQIN1App5a1Pc2lceE5/g==", "dev": true }, - "@types/minimatch": { + "node_modules/@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", "dev": true }, - "@types/mocha": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", - "integrity": "sha1-MV1XDMtWxTRS/4Y4c432BybVtuo=", - "dev": true - }, - "@types/node": { + "node_modules/@types/node": { "version": "13.13.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.5.tgz", "integrity": "sha512-3ySmiBYJPqgjiHA7oEaIo2Rzz0HrOZ7yrNO5HWyaE5q0lQ3BppDZ3N53Miz8bw2I7gh1/zir2MGVZBvpb1zq9g==", "dev": true }, - "@types/proxyquire": { + "node_modules/@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "node_modules/@types/proxyquire": { "version": "1.3.28", "resolved": "https://registry.npmjs.org/@types/proxyquire/-/proxyquire-1.3.28.tgz", "integrity": "sha1-BaZHuw2P5I/I7cwZPkPMeTEPqn0=", "dev": true }, - "@types/react": { + "node_modules/@types/react": { "version": "16.0.31", "resolved": "https://registry.npmjs.org/@types/react/-/react-16.0.31.tgz", "integrity": "sha512-ft7OuDGUo39e+9LGwUewf2RyEaNBOjWbHUmD5bzjNuSuDabccE/1IuO7iR0dkzLjVUKxTMq69E+FmKfbgBcfbQ==", "dev": true }, - "@types/rimraf": { + "node_modules/@types/rimraf": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-3.0.0.tgz", "integrity": "sha512-7WhJ0MdpFgYQPXlF4Dx+DhgvlPCfz/x5mHaeDQAKhcenvQP1KCpLQ18JklAqeGMYSAT2PxLpzd0g2/HE7fj7hQ==", "dev": true, - "requires": { + "dependencies": { "@types/glob": "*", "@types/node": "*" } }, - "@types/semver": { + "node_modules/@types/semver": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.1.0.tgz", "integrity": "sha1-yMYw1MGM0ya+/3dASIdZb5ZAhAg=", "dev": true, - "requires": { + "dependencies": { "@types/node": "*" } }, - "@types/source-map-support": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@types/source-map-support/-/source-map-support-0.5.0.tgz", - "integrity": "sha512-OrnAz5K5dXDgMdeRRoXIjDAvkodQ9ESvVJCyzrhzUJKmCkXgmYx/KLUBcVFe5eS4FiohfcY7YPxsdkmSwJz9wA==", - "dev": true, - "requires": { - "@types/node": "*" - } + "node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true }, - "aggregate-error": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", - "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", + "node_modules/@types/yargs": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz", + "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==", "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" + "dependencies": { + "@types/yargs-parser": "*" } }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha1-V9NbhoboUeLMBMQD8cACA5dqGBM=", - "dev": true - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "node_modules/@types/yargs-parser": { + "version": "20.2.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", + "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==", "dev": true }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", + "node_modules/@yarnpkg/fslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/fslib/-/fslib-2.4.0.tgz", + "integrity": "sha512-CwffYY9owtl3uImNOn1K4jl5iIb/L16a9UZ9Q3lkBARk6tlUsPrNFX00eoUlFcLn49TTfd3zdN6higloGCyncw==", "dev": true, - "requires": { - "color-convert": "^1.9.0" + "dependencies": { + "@yarnpkg/libzip": "^2.2.1", + "tslib": "^1.13.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/@yarnpkg/libzip": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@yarnpkg/libzip/-/libzip-2.2.1.tgz", + "integrity": "sha512-AYDJXrkzayoDd3ZlVgFJ+LyDX+Zj/cki3vxIpcYxejtgkl3aquVWOxlC0DD9WboBWsJFIP1MjrUbchLyh++/7A==", + "dev": true, + "dependencies": { + "@types/emscripten": "^1.38.0", + "tslib": "^1.13.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", + "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", + "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "node_modules/ansi-align": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", + "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "dev": true, + "dependencies": { + "string-width": "^3.0.0" + } + }, + "node_modules/ansi-align/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-align/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "dependencies": { + "default-require-extensions": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, + "node_modules/arg": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", + "integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==" + }, + "node_modules/argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/arrgv": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arrgv/-/arrgv-1.0.2.tgz", + "integrity": "sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/assertion-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", + "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/ava": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/ava/-/ava-3.15.0.tgz", + "integrity": "sha512-HGAnk1SHPk4Sx6plFAUkzV/XC1j9+iQhOzt4vBly18/yo0AV8Oytx7mtJd/CR8igCJ5p160N/Oo/cNJi2uSeWA==", + "dev": true, + "dependencies": { + "@concordance/react": "^2.0.0", + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "ansi-styles": "^5.0.0", + "arrgv": "^1.0.2", + "arrify": "^2.0.1", + "callsites": "^3.1.0", + "chalk": "^4.1.0", + "chokidar": "^3.4.3", + "chunkd": "^2.0.1", + "ci-info": "^2.0.0", + "ci-parallel-vars": "^1.0.1", + "clean-yaml-object": "^0.1.0", + "cli-cursor": "^3.1.0", + "cli-truncate": "^2.1.0", + "code-excerpt": "^3.0.0", + "common-path-prefix": "^3.0.0", + "concordance": "^5.0.1", + "convert-source-map": "^1.7.0", + "currently-unhandled": "^0.4.1", + "debug": "^4.3.1", + "del": "^6.0.0", + "emittery": "^0.8.0", + "equal-length": "^1.0.0", + "figures": "^3.2.0", + "globby": "^11.0.1", + "ignore-by-default": "^2.0.0", + "import-local": "^3.0.2", + "indent-string": "^4.0.0", + "is-error": "^2.2.2", + "is-plain-object": "^5.0.0", + "is-promise": "^4.0.0", + "lodash": "^4.17.20", + "matcher": "^3.0.0", + "md5-hex": "^3.0.1", + "mem": "^8.0.0", + "ms": "^2.1.3", + "ora": "^5.2.0", + "p-event": "^4.2.0", + "p-map": "^4.0.0", + "picomatch": "^2.2.2", + "pkg-conf": "^3.1.0", + "plur": "^4.0.0", + "pretty-ms": "^7.0.1", + "read-pkg": "^5.2.0", + "resolve-cwd": "^3.0.0", + "slash": "^3.0.0", + "source-map-support": "^0.5.19", + "stack-utils": "^2.0.3", + "strip-ansi": "^6.0.0", + "supertap": "^2.0.0", + "temp-dir": "^2.0.0", + "trim-off-newlines": "^1.0.1", + "update-notifier": "^5.0.1", + "write-file-atomic": "^3.0.3", + "yargs": "^16.2.0" + }, + "bin": { + "ava": "cli.js" + }, + "engines": { + "node": ">=10.18.0 <11 || >=12.14.0 <12.17.0 || >=12.17.0 <13 || >=14.0.0 <15 || >=15" + } + }, + "node_modules/ava/node_modules/ansi-styles": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.1.0.tgz", + "integrity": "sha512-osxifZo3ar56+e8tdYreU6p8FZGciBHo5O0JoDAxMUqZuyNUb+yHEwYtJZ+Z32R459jEgtwVf1u8D7qYwU0l6w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ava/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/ava/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/ava/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/ava/node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ava/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/ava/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/ava/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ava/node_modules/lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "dev": true + }, + "node_modules/ava/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/ava/node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ava/node_modules/string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ava/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ava/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ava/node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ava/node_modules/y18n": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", + "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ava/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ava/node_modules/yargs-parser": { + "version": "20.2.5", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.5.tgz", + "integrity": "sha512-jYRGS3zWy20NtDtK2kBgo/TlAoy5YUuhD9/LZ7z7W4j1Fdw2cqD0xEEclf8fxc8xjD6X5Qr+qQQwCEsP8iRiYg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "dev": true, + "dependencies": { + "follow-redirects": "^1.10.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/blueimp-md5": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.18.0.tgz", + "integrity": "sha512-vE52okJvzsVWhcgUHOv+69OG3Mdg151xyn41aVQN/5W5S+S43qZhxECtYLAEHMSFWX6Mv5IZrzj3T5+JqXfj5Q==", + "dev": true + }, + "node_modules/boxen": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.0.0.tgz", + "integrity": "sha512-5bvsqw+hhgUi3oYGK0Vf4WpIkyemp60WBInn7+WNfoISzAqk/HX4L7WNROq38E6UR/y3YADpv6pEm4BfkeEAdA==", + "dev": true, + "dependencies": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.0", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/boxen/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/boxen/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/boxen/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/boxen/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/boxen/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/boxen/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha1-MnE7wCj3XAL9txDXx7zsHyxgcO8=", + "dev": true + }, + "node_modules/cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "dependencies": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha1-48mzFWnhBoEd8kL3FXJaH0xJQyA=", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chai": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", + "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", + "dev": true, + "dependencies": { + "assertion-error": "^1.0.1", + "check-error": "^1.0.1", + "deep-eql": "^3.0.0", + "get-func-name": "^2.0.0", + "pathval": "^1.0.0", + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/chalk/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/chalk/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.1" + } + }, + "node_modules/chunkd": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/chunkd/-/chunkd-2.0.1.tgz", + "integrity": "sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==", + "dev": true + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/ci-parallel-vars": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ci-parallel-vars/-/ci-parallel-vars-1.0.1.tgz", + "integrity": "sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg==", + "dev": true + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/clean-yaml-object": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz", + "integrity": "sha1-Y/sRDcLOGoTcIfbZM0h20BCui2g=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.5.0.tgz", + "integrity": "sha512-PC+AmIuK04E6aeSs/pUccSujsTzBhu4HzC2dL+CfJB/Jcc2qTRbEwZQDfIUpt2Xl8BodYBEq8w4fc0kU2I9DjQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/cli-truncate/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha1-3u/P2y6AB4SqNPRvoI4GhRx7u8U=", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha1-InZ74htirxCBV0MG9prFG2IgOWE=", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4=", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + } + }, + "node_modules/code-excerpt": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-3.0.0.tgz", + "integrity": "sha512-VHNTVhd7KsLGOqfX3SyeO8RyYPMp1GJOg194VITk04WMYCv4plV68YWe6TJZxd9MhobjtpMRnVky01gqZsalaw==", + "dev": true, + "dependencies": { + "convert-to-spaces": "^1.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "optional": true + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "dev": true + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/concordance": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/concordance/-/concordance-5.0.2.tgz", + "integrity": "sha512-hC63FKdGM9tBcd4VQIa+LQjmrgorrnxESb8B3J21Qe/FzL0blBv0pb8iNyymt+bmsvGSUqO0uhPi2ZSLgLtLdg==", + "dev": true, + "dependencies": { + "date-time": "^3.1.0", + "esutils": "^2.0.3", + "fast-diff": "^1.2.0", + "js-string-escape": "^1.0.1", + "lodash": "^4.17.15", + "md5-hex": "^3.0.1", + "semver": "^7.3.2", + "well-known-symbols": "^2.0.0" + }, + "engines": { + "node": ">=10.18.0 <11 || >=12.14.0 <13 || >=14" + } + }, + "node_modules/concordance/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/concordance/node_modules/semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/concordance/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "dependencies": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/convert-to-spaces": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-1.0.2.tgz", + "integrity": "sha1-fj5Iu+bZl7FBfdyihoIEtNPYVxU=", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/create-require": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.0.tgz", + "integrity": "sha512-yEFVS7dQjDXp5iOEtWisN4uFmL+pUTyIaEizKda9Eb77XX58p6pgFOLAPaBCP+IR6ZPZ1jgJLAuf+ABk0zXYBQ==" + }, + "node_modules/cross-spawn": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.2.tgz", + "integrity": "sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "dependencies": { + "array-find-index": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/date-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/date-time/-/date-time-3.1.0.tgz", + "integrity": "sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==", + "dev": true, + "dependencies": { + "time-zone": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha1-38lARACtHI/gI+faHfHBR8S0RN8=", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/default-require-extensions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", + "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", + "dev": true, + "dependencies": { + "strip-bom": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + } + }, + "node_modules/defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha1-z4jabL7ib+bbcJT2HYcMvYTO6fE=", + "dev": true, + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/del": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-6.0.0.tgz", + "integrity": "sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ==", + "dev": true, + "dependencies": { + "globby": "^11.0.1", + "graceful-fs": "^4.2.4", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.2", + "p-map": "^4.0.0", + "rimraf": "^3.0.2", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/del/node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/del/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/diff": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", + "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "27.0.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.1.tgz", + "integrity": "sha512-XPLijkfJUh/PIBnfkcSHgvD6tlYixmcMAn3osTk6jt+H0v/mgURto1XUiD9DKuGX5NDoVS6dSlA23gd9FUaCFg==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "node_modules/emittery": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha1-kzoEBShgyF6DwSJHnEdIqOTHIVY=", + "dev": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/equal-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/equal-length/-/equal-length-1.0.1.tgz", + "integrity": "sha1-IcoRLUirJLTh5//A5TOdMf38J0w=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", + "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "dev": true, + "dependencies": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha1-5VzUyc3BiLzvsDs2bHNjI/xciYo=", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expect": { + "version": "27.0.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.0.2.tgz", + "integrity": "sha512-YJFNJe2+P2DqH+ZrXy+ydRQYO87oxRUonZImpDodR1G7qo3NYd3pL+NQ9Keqpez3cehczYwZDBC3A7xk3n7M/w==", + "dev": true, + "dependencies": { + "@jest/types": "^27.0.2", + "ansi-styles": "^5.0.0", + "jest-get-type": "^27.0.1", + "jest-matcher-utils": "^27.0.2", + "jest-message-util": "^27.0.2", + "jest-regex-util": "^27.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/expect/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", + "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.10.1.tgz", + "integrity": "sha512-AWuv6Ery3pM+dY7LYS8YIaCiQvUaos9OB1RyNgaOWnaX+Tik7Onvcsf8x8c+YtDeT0maYLniBip2hox5KtEXXA==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fill-keys": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fill-keys/-/fill-keys-1.0.2.tgz", + "integrity": "sha1-mo+jb06K1jTjv2tPPIiCVRRS6yA=", + "dev": true, + "dependencies": { + "is-object": "~1.0.1", + "merge-descriptors": "~1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha1-SRafHXmTQwZG2mHsxa41XCHJe3M=", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/follow-redirects": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.1.tgz", + "integrity": "sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/fromentries": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.2.0.tgz", + "integrity": "sha512-33X7H/wdfO99GdRLLgkjUrD4geAFdq/Uv0kl3HD4da6HDixd2GUg8Mw7dahLCV9r/EARkmtYBB6Tch4EEokFTQ==", + "dev": true + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=", + "dev": true + }, + "node_modules/gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha1-T5RBKoLbMvNuOwuXQfipf+sDH34=", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz", + "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global-dirs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", + "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", + "dev": true, + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.2.tgz", + "integrity": "sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/got/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y=", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha1-n1IUdYpEGWxAbZvXbOv4HsLdMeg=", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hasha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.0.tgz", + "integrity": "sha512-2W+jKdQbAdSIrggA8Q35Br8qKadTrqCTC8+XZvBWepKDK6m9XkX6Iz1a2yh2KP01kzAR/dpuMeUnocoLYDcskw==", + "dev": true, + "dependencies": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/hasha/node_modules/is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + }, + "node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-by-default": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-2.0.0.tgz", + "integrity": "sha512-+mQSgMRiFD3L3AOxLYOCxjIq4OnAmo5CIuC+lj5ehCJcPtV++QacEV7FdpzvYxH6DaOySWzQU6RR0lPLy37ckA==", + "dev": true, + "engines": { + "node": ">=10 <11 || >=12 <13 || >=14" + } + }, + "node_modules/import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/irregular-plurals": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.2.0.tgz", + "integrity": "sha512-YqTdPLfwP7YFN0SsD3QUVCkm9ZG2VzOXv3DOrw5G5mkMbVwptTwVcFv7/C0vOpBmgTxAeTG19XpUs1E522LW9Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha1-9+RrWWiQRW23Tn9ul2yzJz0G+qs=", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + } + }, + "node_modules/is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha1-vac28s2P0G0yhE53Q7+nSUw7/X4=", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-error": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.2.tgz", + "integrity": "sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==", + "dev": true + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-npm": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", + "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", + "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=", + "dev": true + }, + "node_modules/is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", + "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "dev": true + }, + "node_modules/is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha1-OdWJo1i/GJZ/cmlnEguPwa7XTq4=", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha1-OOEBS55jKb4N6dJKQU/XRB7GGTc=", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "dependencies": { + "append-transform": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-processinfo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", + "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", + "dev": true, + "dependencies": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.0", + "istanbul-lib-coverage": "^3.0.0-alpha.1", + "make-dir": "^3.0.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^3.3.3" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff": { + "version": "27.0.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.2.tgz", + "integrity": "sha512-BFIdRb0LqfV1hBt8crQmw6gGQHVDhM87SpMIZ45FPYKReZYG5er1+5pIn2zKqvrJp6WNox0ylR8571Iwk2Dmgw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.0.1", + "jest-get-type": "^27.0.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "27.0.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz", + "integrity": "sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "27.0.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.0.2.tgz", + "integrity": "sha512-Qczi5xnTNjkhcIB0Yy75Txt+Ez51xdhOxsukN7awzq2auZQGPHcQrJ623PZj0ECDEMOk2soxWx05EXdXGd1CbA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.0.2", + "jest-get-type": "^27.0.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "27.0.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.0.2.tgz", + "integrity": "sha512-rTqWUX42ec2LdMkoUPOzrEd1Tcm+R1KfLOmFK+OVNo4MnLsEaxO5zPDb2BbdSmthdM/IfXxOZU60P/WbWF8BTw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.0.2", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.4", + "pretty-format": "^27.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-regex-util": { + "version": "27.0.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.1.tgz", + "integrity": "sha512-6nY6QVcpTgEKQy1L41P4pr3aOddneK17kn3HJw6SdwGiKfgCGTvH02hVXL0GU8GEKtPH83eD2DIDgxHXOxVohQ==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jju": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", + "integrity": "sha1-o6vicYryQaKykE+EpiWXDzia4yo=", + "dev": true + }, + "node_modules/js-string-escape": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", + "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "dependencies": { + "jsonify": "~0.0.0" + } + }, + "node_modules/json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "node_modules/jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "node_modules/keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.0" + } + }, + "node_modules/latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "dependencies": { + "package-json": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "node_modules/load-json-file": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", + "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.15", + "parse-json": "^4.0.0", + "pify": "^4.0.1", + "strip-bom": "^3.0.0", + "type-fest": "^0.3.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/load-json-file/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/type-fest": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha1-2+w7OrdZdYBxtY/ln8QYca8hQA4=", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "dev": true + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", + "dev": true + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/make-error": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.0.tgz", + "integrity": "sha1-Uq06M5zPEM5itAQLcI/nByRLi5Y=" + }, + "node_modules/map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "dependencies": { + "p-defer": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/marked": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-2.0.0.tgz", + "integrity": "sha512-NqRSh2+LlN2NInpqTQnS614Y/3NkVMFFU6sJlRFEpxJ/LHuK/qJECH7/fXZjk4VZstPW/Pevjil/VtSONsLc7Q==", + "dev": true, + "bin": { + "marked": "bin/marked" + }, + "engines": { + "node": ">= 8.16.2" + } + }, + "node_modules/matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/matcher/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/md5-hex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-3.0.1.tgz", + "integrity": "sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==", + "dev": true, + "dependencies": { + "blueimp-md5": "^2.10.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mem": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-8.0.0.tgz", + "integrity": "sha512-qrcJOe6uD+EW8Wrci1Vdiua/15Xw3n/QnaNXE7varnB6InxSk7nu3/i5jfy3S6kWxr8WYJ6R1o0afMUtvorTsA==", + "dev": true, + "dependencies": { + "map-age-cleaner": "^0.1.3", + "mimic-fn": "^3.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mem/node_modules/mimic-fn": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", + "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/module-not-found-error": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/module-not-found-error/-/module-not-found-error-1.0.1.tgz", + "integrity": "sha1-z4tP9PKWQGdNbN0CsOO8UjwrvcA=", + "dev": true + }, + "node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "dependencies": { + "process-on-spawn": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "dependencies": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ntypescript": { + "version": "1.201706190042.1", + "resolved": "https://registry.npmjs.org/ntypescript/-/ntypescript-1.201706190042.1.tgz", + "integrity": "sha1-hmrpzDZoixQWBhVu0LzDXN9TYnE=", + "dev": true, + "bin": { + "ntsc": "bin/tsc" + } + }, + "node_modules/nyc": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.0.1.tgz", + "integrity": "sha512-n0MBXYBYRqa67IVt62qW1r/d9UH/Qtr7SF1w/nQLJ9KxvWF6b2xCHImRAixHN9tnMMYHC2P14uo6KddNGwMgGg==", + "dev": true, + "dependencies": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "bin": { + "nyc": "bin/nyc.js" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/nyc/node_modules/ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "dependencies": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/nyc/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/nyc/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/nyc/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/nyc/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/nyc/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/yargs": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", + "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", + "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha1-9Pa9GBrXfwBrXs5gvQtvOY/3Smc=", + "dev": true + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha1-HEfyct8nfzsdrwYWd9nILiMixg4=", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha1-lovxEA15Vrs8oIbwBvhGs7xACNo=", + "dev": true, + "dependencies": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", + "integrity": "sha1-Npvx+VktiridcS3O1cuBx8U1Jkk=", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/onigasm": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/onigasm/-/onigasm-2.2.5.tgz", + "integrity": "sha512-F+th54mPc0l1lp1ZcFMyL/jTs2Tlq4SqIHKIXGZOR/VkHkF9A7Fr5rRr5+ZG/lWeRsyrClLYRq7s/yFQ/XhWCA==", + "dev": true, + "dependencies": { + "lru-cache": "^5.1.1" + } + }, + "node_modules/ora": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.3.0.tgz", + "integrity": "sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "log-symbols": "^4.0.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ora/node_modules/log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-event": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", + "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", + "dev": true, + "dependencies": { + "p-timeout": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", + "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha1-Mi1poFwCZLJZl9n0DNiokasAZKQ=", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dev": true, + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha1-yyhoVA4xPWHeWPr741zpAE1VQOY=", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "dependencies": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/package-json/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/parse-ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", + "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha1-1i27VnlAXXLEc37FhgDp3c8G0kw=", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-conf": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-3.1.0.tgz", + "integrity": "sha512-m0OTbR/5VPNPqO1ph6Fqbj7Hv6QU7gR/tQW40ZqrL1rjgCU85W6C1bJn0BItuJqnR98PWzw7Z8hHeChD1WrgdQ==", + "dev": true, + "dependencies": { + "find-up": "^3.0.0", + "load-json-file": "^5.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/plur": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/plur/-/plur-4.0.0.tgz", + "integrity": "sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg==", + "dev": true, + "dependencies": { + "irregular-plurals": "^3.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/pretty-format": { + "version": "27.0.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz", + "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==", + "dev": true, + "dependencies": { + "@jest/types": "^27.0.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pretty-format/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/pretty-ms": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", + "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", + "dev": true, + "dependencies": { + "parse-ms": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "dependencies": { + "fromentries": "^1.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "dev": true, + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "node_modules/proxyquire": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/proxyquire/-/proxyquire-2.0.0.tgz", + "integrity": "sha512-TO9TAIz0mpa+SKddXsgCFatoe/KmHvoNVj2jDMC1kXE6kKn7/4CRpxvQ+0wAK9sbMT2FVO89qItlvnZMcFbJ2Q==", + "dev": true, + "dependencies": { + "fill-keys": "^1.0.2", + "module-not-found-error": "^1.0.0", + "resolve": "~1.1.7" + } + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "dependencies": { + "escape-goat": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.2.tgz", + "integrity": "sha512-dB15eXv3p2jDlbOiNLyMabYg1/sXvppd8DP2J3EOCQ0AkuSXCW2tP7mnVouVLJKgUMY6yP0kcQDVpLCN13h4Xg==", + "dev": true + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/react": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", + "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", + "dev": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/registry-auth-token": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "dev": true, + "dependencies": { + "rc": "^1.2.8" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "dependencies": { + "rc": "^1.2.8" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "dev": true, + "dependencies": { + "es6-error": "^4.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha1-0LMp7MfMD2Fkn2IhW+aa9UqomJs=", + "dev": true + }, + "node_modules/resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "dependencies": { + "lowercase-keys": "^1.0.0" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz", + "integrity": "sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/semver": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.1.3.tgz", + "integrity": "sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "dependencies": { + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/semver-diff/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "dev": true, + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-error/node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shelljs": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", + "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", + "dev": true, + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/shiki": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.9.2.tgz", + "integrity": "sha512-BjUCxVbxMnvjs8jC4b+BQ808vwjJ9Q8NtLqPwXShZ307HdXiDFYP968ORSVfaTNNSWYDBYdMnVKJ0fYNsoZUBA==", + "dev": true, + "dependencies": { + "onigasm": "^2.2.5", + "vscode-textmate": "^5.2.0" + } + }, + "node_modules/signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "dependencies": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/spawn-wrap/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", + "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", + "dev": true + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "node_modules/string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/string.prototype.trimleft": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", + "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.trimright": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", + "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supertap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supertap/-/supertap-2.0.0.tgz", + "integrity": "sha512-jRzcXlCeDYvKoZGA5oRhYyR3jUIYu0enkSxtmAgHRlD7HwrovTpH4bDSi0py9FtuA8si9cW/fKommJHuaoDHJA==", + "dev": true, + "dependencies": { + "arrify": "^2.0.1", + "indent-string": "^4.0.0", + "js-yaml": "^3.14.0", + "serialize-error": "^7.0.1", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/supertap/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/supertap/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/throat": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", + "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", + "dev": true + }, + "node_modules/time-zone": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz", + "integrity": "sha1-mcW/VZWJZq9tBtg73zgA3IL67F0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/trim-off-newlines": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", + "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/type-detect": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.5.tgz", + "integrity": "sha512-N9IvkQslUGYGC24RkJk1ba99foK6TkwC2FHAEBlQFBP0RxQZS8ZpJuAZcwiY/w9ZJHFQb1aOXBI60OdxhTrwEQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typedoc": { + "version": "0.20.28", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.20.28.tgz", + "integrity": "sha512-8j0T8u9FuyDkoe+M/3cyoaGJSVgXCY9KwVoo7TLUnmQuzXwqH+wkScY530ZEdK6G39UZ2LFTYPIrL5eykWjx6A==", + "dev": true, + "dependencies": { + "colors": "^1.4.0", + "fs-extra": "^9.1.0", + "handlebars": "^4.7.7", + "lodash": "^4.17.21", + "lunr": "^2.3.9", + "marked": "^2.0.0", + "minimatch": "^3.0.0", + "progress": "^2.0.3", + "shelljs": "^0.8.4", + "shiki": "^0.9.2", + "typedoc-default-themes": "^0.12.7" + }, + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 10.8.0" + } + }, + "node_modules/typedoc-default-themes": { + "version": "0.12.7", + "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.12.7.tgz", + "integrity": "sha512-0XAuGEqID+gon1+fhi4LycOEFM+5Mvm2PjwaiVZNAzU7pn3G2DEpsoXnFOPlLDnHY6ZW0BY0nO7ur9fHOFkBLQ==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/typedoc/node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/typescript": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.2.tgz", + "integrity": "sha512-tbb+NVrLfnsJy3M59lsDgrzWIflR4d4TIUjz+heUnHZwdF7YsrMTKoRERiIvI2lvBG95dfpLxB21WZhys1bgaQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/typescript-json-schema": { + "version": "0.42.0", + "resolved": "https://registry.npmjs.org/typescript-json-schema/-/typescript-json-schema-0.42.0.tgz", + "integrity": "sha1-aV8hKnLZHUfAYFNx3Gl1l7eBfBs=", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.3", + "glob": "~7.1.4", + "json-stable-stringify": "^1.0.1", + "typescript": "^3.5.3", + "yargs": "^14.0.0" + }, + "bin": { + "typescript-json-schema": "bin/typescript-json-schema" + } + }, + "node_modules/typescript-json-schema/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/typescript-json-schema/node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha1-FB8zuBp8JJLhJVlDB0gMRmeSeKY=", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/typescript-json-schema/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha1-InZ74htirxCBV0MG9prFG2IgOWE=", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/typescript-json-schema/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4=", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/typescript-json-schema/node_modules/typescript": { + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", + "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/typescript-json-schema/node_modules/yargs": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", + "integrity": "sha1-Ghw+3O0a+yov6jNgS8bR2NaIpBQ=", + "dev": true, + "dependencies": { + "cliui": "^5.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^15.0.1" + } + }, + "node_modules/typescript-json-schema/node_modules/yargs-parser": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz", + "integrity": "sha1-VHhq9AuCDcsvuAJbEbTWWddjI7M=", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/uglify-js": { + "version": "3.12.8", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.12.8.tgz", + "integrity": "sha512-fvBeuXOsvqjecUtF/l1dwsrrf5y2BCUk9AOJGzGcm6tE7vegku5u/YvqjyDaAGr422PLoLnrxg3EnRvTqsdC1w==", + "dev": true, + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/update-notifier": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", + "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", + "dev": true, + "dependencies": { + "boxen": "^5.0.0", + "chalk": "^4.1.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.4.0", + "is-npm": "^5.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.1.0", + "pupa": "^2.1.1", + "semver": "^7.3.4", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/update-notifier/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/update-notifier/node_modules/semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/update-notifier/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "node_modules/util.promisify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.2", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" + } + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validator": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-8.2.0.tgz", + "integrity": "sha512-Yw5wW34fSv5spzTXNkokD6S6/Oq92d8q/t14TqsS3fAiA1RYnxSFSIZ+CY3n6PGGRCq5HhJTSepQvFUS2QUDxA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vscode-textmate": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz", + "integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==", + "dev": true + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/well-known-symbols": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz", + "integrity": "sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/widest-line/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/widest-line/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/widest-line/node_modules/string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/widest-line/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha1-H9H2cjXVttD+54EFYAG/tpTAOwk=", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha1-InZ74htirxCBV0MG9prFG2IgOWE=", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4=", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha1-le+U+F7MgdAHwmThkKEg8KPIVms=", + "dev": true + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha1-HodAGgnXZ8HV6rJqbkwYUYLS61A=", + "engines": { + "node": ">=6" + } + }, + "node_modules/z-schema": { + "version": "3.18.4", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-3.18.4.tgz", + "integrity": "sha512-DUOKC/IhbkdLKKiV89gw9DUauTV8U/8yJl1sjf6MtDmzevLKOF2duNJ495S3MFVjqZarr+qNGCPbkg4mu4PpLw==", + "dev": true, + "dependencies": { + "lodash.get": "^4.0.0", + "lodash.isequal": "^4.0.0", + "validator": "^8.0.0" + }, + "bin": { + "z-schema": "bin/z-schema" + }, + "optionalDependencies": { + "commander": "^2.7.1" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.12.13" + } + }, + "@babel/core": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.6.tgz", + "integrity": "sha512-nD3deLvbsApbHAHttzIssYqgb883yU/d9roe4RZymBCDaZryMJDbptVpEpeQuRh4BJ+SYI8le9YGxKvFEvl1Wg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.6", + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helpers": "^7.9.6", + "@babel/parser": "^7.9.6", + "@babel/template": "^7.8.6", + "@babel/traverse": "^7.9.6", + "@babel/types": "^7.9.6", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", + "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", + "dev": true, + "requires": { + "@babel/types": "^7.9.6", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", + "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-module-imports": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", + "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-module-transforms": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz", + "integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", + "@babel/helper-simple-access": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/template": "^7.8.6", + "@babel/types": "^7.9.0", + "lodash": "^4.17.13" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", + "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-replace-supers": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.9.6.tgz", + "integrity": "sha512-qX+chbxkbArLyCImk3bWV+jB5gTNU/rsze+JlcF6Nf8tVTigPJSI1o1oBow/9Resa1yehUO9lIipsmu9oG4RzA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/traverse": "^7.9.6", + "@babel/types": "^7.9.6" + } + }, + "@babel/helper-simple-access": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", + "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", + "dev": true, + "requires": { + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", + "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", + "dev": true + }, + "@babel/helpers": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.6.tgz", + "integrity": "sha512-tI4bUbldloLcHWoRUMAj4g1bF313M/o6fBKhIsb3QnGVPwRm9JsNf/gqMkQ7zjqReABiffPV6RWj7hEglID5Iw==", + "dev": true, + "requires": { + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.9.6", + "@babel/types": "^7.9.6" + } + }, + "@babel/highlight": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", + "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", + "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", + "dev": true + }, + "@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/traverse": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", + "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.6", + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "@babel/types": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", + "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "@concordance/react": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@concordance/react/-/react-2.0.0.tgz", + "integrity": "sha512-huLSkUuM2/P+U0uy2WwlKuixMsTODD8p4JVQBI4VKeopkiN0C7M3N9XYVawb4M+4spN5RrO/eLhk7KoQX6nsfA==", + "dev": true, + "requires": { + "arrify": "^1.0.1" + }, + "dependencies": { + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + } + } + }, + "@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==" + }, + "@cspotcode/source-map-support": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz", + "integrity": "sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg==", + "requires": { + "@cspotcode/source-map-consumer": "0.8.0" + } + }, + "@istanbuljs/load-nyc-config": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz", + "integrity": "sha512-ZR0rq/f/E4f4XcgnDvtMWXCUJpi8eO0rssVhmztsZqLIEFA9UUP9zmpE0VxlM+kv/E1ul2I876Fwil2ayptDVg==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "dev": true + }, + "@jest/types": { + "version": "27.0.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz", + "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@microsoft/api-extractor": { + "version": "7.15.2", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.15.2.tgz", + "integrity": "sha512-/Y/n+QOc1vM6Vg3OAUByT/wXdZciE7jV3ay33+vxl3aKva5cNsuOauL14T7XQWUiLko3ilPwrcnFcEjzXpLsuA==", + "dev": true, + "requires": { + "@microsoft/api-extractor-model": "7.13.2", + "@microsoft/tsdoc": "0.13.2", + "@microsoft/tsdoc-config": "~0.15.2", + "@rushstack/node-core-library": "3.38.0", + "@rushstack/rig-package": "0.2.12", + "@rushstack/ts-command-line": "4.7.10", + "colors": "~1.2.1", + "lodash": "~4.17.15", + "resolve": "~1.17.0", + "semver": "~7.3.0", + "source-map": "~0.6.1", + "typescript": "~4.2.4" + }, + "dependencies": { + "colors": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", + "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "typescript": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "@microsoft/api-extractor-model": { + "version": "7.13.2", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.13.2.tgz", + "integrity": "sha512-gA9Q8q5TPM2YYk7rLinAv9KqcodrmRC13BVmNzLswjtFxpz13lRh0BmrqD01/sddGpGMIuWFYlfUM4VSWxnggA==", + "dev": true, + "requires": { + "@microsoft/tsdoc": "0.13.2", + "@microsoft/tsdoc-config": "~0.15.2", + "@rushstack/node-core-library": "3.38.0" + } + }, + "@microsoft/tsdoc": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.13.2.tgz", + "integrity": "sha512-WrHvO8PDL8wd8T2+zBGKrMwVL5IyzR3ryWUsl0PXgEV0QHup4mTLi0QcATefGI6Gx9Anu7vthPyyyLpY0EpiQg==", + "dev": true + }, + "@microsoft/tsdoc-config": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.15.2.tgz", + "integrity": "sha512-mK19b2wJHSdNf8znXSMYVShAHktVr/ib0Ck2FA3lsVBSEhSI/TfXT7DJQkAYgcztTuwazGcg58ZjYdk0hTCVrA==", + "dev": true, + "requires": { + "@microsoft/tsdoc": "0.13.2", + "ajv": "~6.12.6", + "jju": "~1.4.0", + "resolve": "~1.19.0" + }, + "dependencies": { + "resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "requires": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + } + } + } + }, + "@napi-rs/triples": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@napi-rs/triples/-/triples-1.0.2.tgz", + "integrity": "sha512-EL3SiX43m9poFSnhDx4d4fn9SSaqyO2rHsCNhETi9bWPmjXK3uPJ0QpPFtx39FEdHcz1vJmsiW41kqc0AgvtzQ==", + "dev": true + }, + "@node-rs/helper": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@node-rs/helper/-/helper-1.1.0.tgz", + "integrity": "sha512-r43YnnrY5JNzDuXJdW3sBJrKzvejvFmFWbiItUEoBJsaPzOIWFMhXB7i5j4c9EMXcFfxveF4l7hT+rLmwtjrVQ==", + "dev": true, + "requires": { + "@napi-rs/triples": "^1.0.2", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", + "dev": true + } + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", + "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.4", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", + "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", + "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.4", + "fastq": "^1.6.0" + } + }, + "@rushstack/node-core-library": { + "version": "3.38.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.38.0.tgz", + "integrity": "sha512-cmvl0yQx8sSmbuXwiRYJi8TO+jpTtrLJQ8UmFHhKvgPVJAW8cV8dnpD1Xx/BvTGrJZ2XtRAIkAhBS9okBnap4w==", + "dev": true, + "requires": { + "@types/node": "10.17.13", + "colors": "~1.2.1", + "fs-extra": "~7.0.1", + "import-lazy": "~4.0.0", + "jju": "~1.4.0", + "resolve": "~1.17.0", + "semver": "~7.3.0", + "timsort": "~0.3.0", + "z-schema": "~3.18.3" + }, + "dependencies": { + "@types/node": { + "version": "10.17.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.13.tgz", + "integrity": "sha512-pMCcqU2zT4TjqYFrWtYHKal7Sl30Ims6ulZ4UFXxI4xbtQqK/qqKwkDoBFCfooRqqmRu9vY3xaJRwxSh673aYg==", + "dev": true + }, + "colors": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", + "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", + "dev": true + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "@rushstack/rig-package": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.2.12.tgz", + "integrity": "sha512-nbePcvF8hQwv0ql9aeQxcaMPK/h1OLAC00W7fWCRWIvD2MchZOE8jumIIr66HGrfG2X1sw++m/ZYI4D+BM5ovQ==", + "dev": true, + "requires": { + "resolve": "~1.17.0", + "strip-json-comments": "~3.1.1" + }, + "dependencies": { + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + } + } + }, + "@rushstack/ts-command-line": { + "version": "4.7.10", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.7.10.tgz", + "integrity": "sha512-8t042g8eerypNOEcdpxwRA3uCmz0duMo21rG4Z2mdz7JxJeylDmzjlU3wDdef2t3P1Z61JCdZB6fbm1Mh0zi7w==", + "dev": true, + "requires": { + "@types/argparse": "1.0.38", + "argparse": "~1.0.9", + "colors": "~1.2.1", + "string-argv": "~0.3.1" + }, + "dependencies": { + "colors": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", + "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", + "dev": true + } + } + }, + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, + "@swc/core": { + "version": "1.2.58", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.2.58.tgz", + "integrity": "sha512-u/vaon34x4ISDDdgZLaxacPB4Ly8SqqmFkBKPp2VtUDbD12VqKzb6EoLDC3A5EULFQDgIdIMHuVlBB+mc8dq0w==", + "dev": true, + "requires": { + "@node-rs/helper": "^1.0.0", + "@swc/core-android-arm64": "^1.2.58", + "@swc/core-darwin-arm64": "^1.2.58", + "@swc/core-darwin-x64": "^1.2.58", + "@swc/core-linux-arm-gnueabihf": "^1.2.58", + "@swc/core-linux-arm64-gnu": "^1.2.58", + "@swc/core-linux-x64-gnu": "^1.2.58", + "@swc/core-linux-x64-musl": "^1.2.58", + "@swc/core-win32-ia32-msvc": "^1.2.58", + "@swc/core-win32-x64-msvc": "^1.2.58" + } + }, + "@swc/core-android-arm64": { + "version": "1.2.58", + "resolved": "https://registry.npmjs.org/@swc/core-android-arm64/-/core-android-arm64-1.2.58.tgz", + "integrity": "sha512-eSNNt/KiAbseOZ/lbaHnXClWOOeEPBRJBjxIBDX6U4oXaHLBCwgwU+qhWziVV4Lq6gX0zqcw6JY7Pxz9r2Pxzw==", + "dev": true, + "optional": true + }, + "@swc/core-darwin-arm64": { + "version": "1.2.58", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.2.58.tgz", + "integrity": "sha512-PHZm9kYi4KjWgac86fhr1238elI7M1K8Zh634eDCJCZbU7LHWUWOyeTpT9G8dxOuAUTOUZDaCHNW/+63N5XWPA==", + "dev": true, + "optional": true + }, + "@swc/core-darwin-x64": { + "version": "1.2.58", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.2.58.tgz", + "integrity": "sha512-jKJNNxBbt/ckp49QUP28P+YEGDS3baruCBRbVkgJQY5Nj5GKw5kay6prVf6ajhoegmtjLr+1p3By7S5XOgIc8g==", + "dev": true, + "optional": true + }, + "@swc/core-linux-arm-gnueabihf": { + "version": "1.2.58", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.2.58.tgz", + "integrity": "sha512-dnZcurOjTEr2IkSdWakyoVlE6ay3QQSSTv/9IsBH3eI7CI2+W8m9AtQ+KyN5BKPBSK5NjswF59xA3gocbsUpng==", + "dev": true, + "optional": true + }, + "@swc/core-linux-arm64-gnu": { + "version": "1.2.58", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.2.58.tgz", + "integrity": "sha512-lSOd73EqFLx0I0f9UJq2wbwjQc+tbXbLznJp89tEZeLOljuMJkF3O22l2Nv6Vet6NBPbTQYiKy6ouibFvOqMag==", + "dev": true, + "optional": true + }, + "@swc/core-linux-x64-gnu": { + "version": "1.2.58", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.2.58.tgz", + "integrity": "sha512-bDU2LiURs4MKXWNNUKxVU1KKCO6lp1ILszkLPYuRAHbbQCtoQUe5JCbFlCqniFOxZOm2NBtZF4a+z5bGFpb0QA==", + "dev": true, + "optional": true + }, + "@swc/core-linux-x64-musl": { + "version": "1.2.58", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.2.58.tgz", + "integrity": "sha512-wdF8nHrlMI4PUL13PQFo4BMfCr9HL3kNWftiA8i+mJhfp8Z2xfyarOnVkeXmYmQYGPoqSDCsskui6n5PvBLePw==", + "dev": true, + "optional": true + }, + "@swc/core-win32-ia32-msvc": { + "version": "1.2.58", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.2.58.tgz", + "integrity": "sha512-Qrox0Kz3KQSYnMwAH55DYXzOG+L0PPYQHaQnJCh5rywKDUx2n/Ar5zKkVkEhRf0ehPgKajt0h2BYHsTpqNA9/w==", + "dev": true, + "optional": true + }, + "@swc/core-win32-x64-msvc": { + "version": "1.2.58", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.2.58.tgz", + "integrity": "sha512-HPmxovhC7DbNcXLJe5nUmo+4o6Ea2d7oFdli3IvTgDri0IynQaRlfVWIuNnZmEsN7Gl1kW7PUK5WZXPUosMn8A==", + "dev": true, + "optional": true + }, + "@swc/wasm": { + "version": "1.2.58", + "resolved": "https://registry.npmjs.org/@swc/wasm/-/wasm-1.2.58.tgz", + "integrity": "sha512-3PAMVT+clB2xZsaVtQK2WjgeCftCxDO/0q8JCwW5g3CrLL/WBOCHyCKME3CzGz7V9zfw84QZZMpZY26gohhF/w==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "@tsconfig/node10": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.7.tgz", + "integrity": "sha512-aBvUmXLQbayM4w3A8TrjwrXs4DZ8iduJnuJLLRGdkWlyakCf1q6uHZJBzXoRA/huAEknG5tcUyQxN3A+In5euQ==" + }, + "@tsconfig/node12": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.7.tgz", + "integrity": "sha512-dgasobK/Y0wVMswcipr3k0HpevxFJLijN03A8mYfEPvWvOs14v0ZlYTR4kIgMx8g4+fTyTFv8/jLCIfRqLDJ4A==" + }, + "@tsconfig/node14": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.0.tgz", + "integrity": "sha512-RKkL8eTdPv6t5EHgFKIVQgsDapugbuOptNd9OOunN/HAkzmmTnZELx1kNCK0rSdUYGmiFMM3rRQMAWiyp023LQ==" + }, + "@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==" + }, + "@types/argparse": { + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", + "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==", + "dev": true + }, + "@types/chai": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.0.10.tgz", + "integrity": "sha512-Ejh1AXTY8lm+x91X/yar3G2z4x9RyKwdTVdyyu7Xj3dNB35fMNCnEWqTO9FgS3zjzlRNqk1MruYhgb8yhRN9rA==", + "dev": true + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "@types/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/diff/-/diff-4.0.2.tgz", + "integrity": "sha1-Lpu4n5rMOrAQjw89xNvc8v/4qZw=", + "dev": true + }, + "@types/emscripten": { + "version": "1.39.4", + "resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.39.4.tgz", + "integrity": "sha512-k3LLVMFrdNA9UCvMDPWMbFrGPNb+GcPyw29ktJTo1RCN7RmxFG5XzPZcPKRlnLuLT/FRm8wp4ohvDwNY7GlROQ==", + "dev": true + }, + "@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", + "dev": true + }, + "@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "dev": true, + "requires": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "dev": true + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/json-schema": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz", + "integrity": "sha1-OP1z3f2bVaux4bLtV4y1W9e30zk=", + "dev": true + }, + "@types/lodash": { + "version": "4.14.151", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.151.tgz", + "integrity": "sha512-Zst90IcBX5wnwSu7CAS0vvJkTjTELY4ssKbHiTnGcJgi170uiS8yQDdc3v6S77bRqYQIN1App5a1Pc2lceE5/g==", + "dev": true + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "@types/node": { + "version": "13.13.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.5.tgz", + "integrity": "sha512-3ySmiBYJPqgjiHA7oEaIo2Rzz0HrOZ7yrNO5HWyaE5q0lQ3BppDZ3N53Miz8bw2I7gh1/zir2MGVZBvpb1zq9g==", + "dev": true + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "@types/proxyquire": { + "version": "1.3.28", + "resolved": "https://registry.npmjs.org/@types/proxyquire/-/proxyquire-1.3.28.tgz", + "integrity": "sha1-BaZHuw2P5I/I7cwZPkPMeTEPqn0=", + "dev": true + }, + "@types/react": { + "version": "16.0.31", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.0.31.tgz", + "integrity": "sha512-ft7OuDGUo39e+9LGwUewf2RyEaNBOjWbHUmD5bzjNuSuDabccE/1IuO7iR0dkzLjVUKxTMq69E+FmKfbgBcfbQ==", + "dev": true + }, + "@types/rimraf": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-3.0.0.tgz", + "integrity": "sha512-7WhJ0MdpFgYQPXlF4Dx+DhgvlPCfz/x5mHaeDQAKhcenvQP1KCpLQ18JklAqeGMYSAT2PxLpzd0g2/HE7fj7hQ==", + "dev": true, + "requires": { + "@types/glob": "*", + "@types/node": "*" + } + }, + "@types/semver": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.1.0.tgz", + "integrity": "sha1-yMYw1MGM0ya+/3dASIdZb5ZAhAg=", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, + "@types/yargs": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz", + "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "20.2.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", + "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==", + "dev": true + }, + "@yarnpkg/fslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/fslib/-/fslib-2.4.0.tgz", + "integrity": "sha512-CwffYY9owtl3uImNOn1K4jl5iIb/L16a9UZ9Q3lkBARk6tlUsPrNFX00eoUlFcLn49TTfd3zdN6higloGCyncw==", + "dev": true, + "requires": { + "@yarnpkg/libzip": "^2.2.1", + "tslib": "^1.13.0" + } + }, + "@yarnpkg/libzip": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@yarnpkg/libzip/-/libzip-2.2.1.tgz", + "integrity": "sha512-AYDJXrkzayoDd3ZlVgFJ+LyDX+Zj/cki3vxIpcYxejtgkl3aquVWOxlC0DD9WboBWsJFIP1MjrUbchLyh++/7A==", + "dev": true, + "requires": { + "@types/emscripten": "^1.38.0", + "tslib": "^1.13.0" + } + }, + "acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==" + }, + "acorn-walk": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", + "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==" + }, + "aggregate-error": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", + "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-align": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", + "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "dev": true, + "requires": { + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "requires": { + "default-require-extensions": "^3.0.0" + } + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, + "arg": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", + "integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==" + }, + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "arrgv": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arrgv/-/arrgv-1.0.2.tgz", + "integrity": "sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw==", + "dev": true + }, + "arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true + }, + "assertion-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", + "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=", + "dev": true + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true + }, + "ava": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/ava/-/ava-3.15.0.tgz", + "integrity": "sha512-HGAnk1SHPk4Sx6plFAUkzV/XC1j9+iQhOzt4vBly18/yo0AV8Oytx7mtJd/CR8igCJ5p160N/Oo/cNJi2uSeWA==", + "dev": true, + "requires": { + "@concordance/react": "^2.0.0", + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "ansi-styles": "^5.0.0", + "arrgv": "^1.0.2", + "arrify": "^2.0.1", + "callsites": "^3.1.0", + "chalk": "^4.1.0", + "chokidar": "^3.4.3", + "chunkd": "^2.0.1", + "ci-info": "^2.0.0", + "ci-parallel-vars": "^1.0.1", + "clean-yaml-object": "^0.1.0", + "cli-cursor": "^3.1.0", + "cli-truncate": "^2.1.0", + "code-excerpt": "^3.0.0", + "common-path-prefix": "^3.0.0", + "concordance": "^5.0.1", + "convert-source-map": "^1.7.0", + "currently-unhandled": "^0.4.1", + "debug": "^4.3.1", + "del": "^6.0.0", + "emittery": "^0.8.0", + "equal-length": "^1.0.0", + "figures": "^3.2.0", + "globby": "^11.0.1", + "ignore-by-default": "^2.0.0", + "import-local": "^3.0.2", + "indent-string": "^4.0.0", + "is-error": "^2.2.2", + "is-plain-object": "^5.0.0", + "is-promise": "^4.0.0", + "lodash": "^4.17.20", + "matcher": "^3.0.0", + "md5-hex": "^3.0.1", + "mem": "^8.0.0", + "ms": "^2.1.3", + "ora": "^5.2.0", + "p-event": "^4.2.0", + "p-map": "^4.0.0", + "picomatch": "^2.2.2", + "pkg-conf": "^3.1.0", + "plur": "^4.0.0", + "pretty-ms": "^7.0.1", + "read-pkg": "^5.2.0", + "resolve-cwd": "^3.0.0", + "slash": "^3.0.0", + "source-map-support": "^0.5.19", + "stack-utils": "^2.0.3", + "strip-ansi": "^6.0.0", + "supertap": "^2.0.0", + "temp-dir": "^2.0.0", + "trim-off-newlines": "^1.0.1", + "update-notifier": "^5.0.1", + "write-file-atomic": "^3.0.3", + "yargs": "^16.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.1.0.tgz", + "integrity": "sha512-osxifZo3ar56+e8tdYreU6p8FZGciBHo5O0JoDAxMUqZuyNUb+yHEwYtJZ+Z32R459jEgtwVf1u8D7qYwU0l6w==", + "dev": true + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "dev": true + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + } + } + }, + "y18n": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", + "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.5", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.5.tgz", + "integrity": "sha512-jYRGS3zWy20NtDtK2kBgo/TlAoy5YUuhD9/LZ7z7W4j1Fdw2cqD0xEEclf8fxc8xjD6X5Qr+qQQwCEsP8iRiYg==", + "dev": true + } + } + }, + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "dev": true, + "requires": { + "follow-redirects": "^1.10.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + } + } + }, + "blueimp-md5": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.18.0.tgz", + "integrity": "sha512-vE52okJvzsVWhcgUHOv+69OG3Mdg151xyn41aVQN/5W5S+S43qZhxECtYLAEHMSFWX6Mv5IZrzj3T5+JqXfj5Q==", + "dev": true + }, + "boxen": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.0.0.tgz", + "integrity": "sha512-5bvsqw+hhgUi3oYGK0Vf4WpIkyemp60WBInn7+WNfoISzAqk/HX4L7WNROq38E6UR/y3YADpv6pEm4BfkeEAdA==", + "dev": true, + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.0", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } } }, - "append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", "dev": true, "requires": { - "default-require-extensions": "^3.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, - "arg": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", - "integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==" - }, - "argparse": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { - "sprintf-js": "~1.0.2" + "fill-range": "^7.0.1" } }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "dev": true - }, - "assertion-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", - "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=", - "dev": true - }, - "axios": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz", - "integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==", + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "dev": true, "requires": { - "follow-redirects": "1.5.10", - "is-buffer": "^2.0.2" + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" } }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha1-MnE7wCj3XAL9txDXx7zsHyxgcO8=", "dev": true }, - "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", "dev": true, "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } } }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha1-uqVZ7hTO1zRSIputcyZGfGH6vWA=", - "dev": true - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha1-MnE7wCj3XAL9txDXx7zsHyxgcO8=" - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, "caching-transform": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", @@ -568,6 +8042,12 @@ "write-file-atomic": "^3.0.0" } }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -589,24 +8069,38 @@ } }, "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true } } }, @@ -616,12 +8110,117 @@ "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", "dev": true }, + "chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "chunkd": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/chunkd/-/chunkd-2.0.1.tgz", + "integrity": "sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==", + "dev": true + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "ci-parallel-vars": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ci-parallel-vars/-/ci-parallel-vars-1.0.1.tgz", + "integrity": "sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg==", + "dev": true + }, "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true }, + "clean-yaml-object": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz", + "integrity": "sha1-Y/sRDcLOGoTcIfbZM0h20BCui2g=", + "dev": true + }, + "cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-spinners": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.5.0.tgz", + "integrity": "sha512-PC+AmIuK04E6aeSs/pUccSujsTzBhu4HzC2dL+CfJB/Jcc2qTRbEwZQDfIUpt2Xl8BodYBEq8w4fc0kU2I9DjQ==", + "dev": true + }, + "cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", @@ -661,6 +8260,30 @@ } } }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "code-excerpt": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-3.0.0.tgz", + "integrity": "sha512-VHNTVhd7KsLGOqfX3SyeO8RyYPMp1GJOg194VITk04WMYCv4plV68YWe6TJZxd9MhobjtpMRnVky01gqZsalaw==", + "dev": true, + "requires": { + "convert-to-spaces": "^1.0.1" + } + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -676,10 +8299,23 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true + }, "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "optional": true + }, + "common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", "dev": true }, "commondir": { @@ -694,6 +8330,62 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "concordance": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/concordance/-/concordance-5.0.2.tgz", + "integrity": "sha512-hC63FKdGM9tBcd4VQIa+LQjmrgorrnxESb8B3J21Qe/FzL0blBv0pb8iNyymt+bmsvGSUqO0uhPi2ZSLgLtLdg==", + "dev": true, + "requires": { + "date-time": "^3.1.0", + "esutils": "^2.0.3", + "fast-diff": "^1.2.0", + "js-string-escape": "^1.0.1", + "lodash": "^4.17.15", + "md5-hex": "^3.0.1", + "semver": "^7.3.2", + "well-known-symbols": "^2.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + } + }, "convert-source-map": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", @@ -703,12 +8395,17 @@ "safe-buffer": "~5.1.1" } }, - "core-js": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", - "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=", + "convert-to-spaces": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-1.0.2.tgz", + "integrity": "sha1-fj5Iu+bZl7FBfdyihoIEtNPYVxU=", "dev": true }, + "create-require": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.0.tgz", + "integrity": "sha512-yEFVS7dQjDXp5iOEtWisN4uFmL+pUTyIaEizKda9Eb77XX58p6pgFOLAPaBCP+IR6ZPZ1jgJLAuf+ABk0zXYBQ==" + }, "cross-spawn": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.2.tgz", @@ -731,13 +8428,28 @@ } } }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", "dev": true, "requires": { - "ms": "^2.1.1" + "array-find-index": "^1.0.1" + } + }, + "date-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/date-time/-/date-time-3.1.0.tgz", + "integrity": "sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==", + "dev": true, + "requires": { + "time-zone": "^1.0.0" } }, "decamelize": { @@ -746,6 +8458,15 @@ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, "deep-eql": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", @@ -755,6 +8476,12 @@ "type-detect": "^4.0.0" } }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, "default-require-extensions": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", @@ -764,6 +8491,21 @@ "strip-bom": "^4.0.0" } }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "requires": { + "clone": "^1.0.2" + } + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -773,42 +8515,111 @@ "object-keys": "^1.0.12" } }, + "del": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-6.0.0.tgz", + "integrity": "sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ==", + "dev": true, + "requires": { + "globby": "^11.0.1", + "graceful-fs": "^4.2.4", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.2", + "p-map": "^4.0.0", + "rimraf": "^3.0.2", + "slash": "^3.0.0" + }, + "dependencies": { + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, "diff": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==" }, - "doctrine": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-0.7.2.tgz", - "integrity": "sha1-fLhgNZujvpDgQLJrcpzkv6ZUxSM=", + "diff-sequences": { + "version": "27.0.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.1.tgz", + "integrity": "sha512-XPLijkfJUh/PIBnfkcSHgvD6tlYixmcMAn3osTk6jt+H0v/mgURto1XUiD9DKuGX5NDoVS6dSlA23gd9FUaCFg==", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", "dev": true, "requires": { - "esutils": "^1.1.6", - "isarray": "0.0.1" - }, - "dependencies": { - "esutils": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz", - "integrity": "sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U=", - "dev": true - } + "is-obj": "^2.0.0" } }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "emittery": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "dev": true + }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", "integrity": "sha1-kzoEBShgyF6DwSJHnEdIqOTHIVY=", "dev": true }, - "encoding": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "equal-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/equal-length/-/equal-length-1.0.1.tgz", + "integrity": "sha1-IcoRLUirJLTh5//A5TOdMf38J0w=", + "dev": true + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "requires": { - "iconv-lite": "~0.4.13" + "is-arrayish": "^0.2.1" } }, "es-abstract": { @@ -847,25 +8658,106 @@ "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", "dev": true }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, - "fbjs": { - "version": "0.8.16", - "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz", - "integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=", + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "expect": { + "version": "27.0.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.0.2.tgz", + "integrity": "sha512-YJFNJe2+P2DqH+ZrXy+ydRQYO87oxRUonZImpDodR1G7qo3NYd3pL+NQ9Keqpez3cehczYwZDBC3A7xk3n7M/w==", + "dev": true, + "requires": { + "@jest/types": "^27.0.2", + "ansi-styles": "^5.0.0", + "jest-get-type": "^27.0.1", + "jest-matcher-utils": "^27.0.2", + "jest-message-util": "^27.0.2", + "jest-regex-util": "^27.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + } + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "fast-glob": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", + "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fastq": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.10.1.tgz", + "integrity": "sha512-AWuv6Ery3pM+dY7LYS8YIaCiQvUaos9OB1RyNgaOWnaX+Tik7Onvcsf8x8c+YtDeT0maYLniBip2hox5KtEXXA==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dev": true, "requires": { - "core-js": "^1.0.0", - "isomorphic-fetch": "^2.1.1", - "loose-envify": "^1.0.0", - "object-assign": "^4.1.0", - "promise": "^7.1.1", - "setimmediate": "^1.0.5", - "ua-parser-js": "^0.7.9" + "escape-string-regexp": "^1.0.5" } }, "fill-keys": { @@ -878,6 +8770,15 @@ "merge-descriptors": "~1.0.0" } }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, "find-cache-dir": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", @@ -898,40 +8799,11 @@ "locate-path": "^3.0.0" } }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha1-CQvsiwXjnLowl0fx1YjwTbr5jbI=", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - } - }, "follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha1-e3qfmuov3/NnhqlP9kPtB/T/Xio=", - "dev": true, - "requires": { - "debug": "=3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.1.tgz", + "integrity": "sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==", + "dev": true }, "foreground-child": { "version": "2.0.0", @@ -949,12 +8821,31 @@ "integrity": "sha512-33X7H/wdfO99GdRLLgkjUrD4geAFdq/Uv0kl3HD4da6HDixd2GUg8Mw7dahLCV9r/EARkmtYBB6Tch4EEokFTQ==", "dev": true }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -979,23 +8870,112 @@ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, + "get-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz", + "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==", + "dev": true + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "global-dirs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", + "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", + "dev": true, + "requires": { + "ini": "2.0.0" + } + }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, + "globby": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.2.tgz", + "integrity": "sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "dependencies": { + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + } + } + }, "graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha1-8nNdwig2dPpnR4sQGBBZNVw2nl4=", - "dev": true + "handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + } }, "has": { "version": "1.0.3", @@ -1007,9 +8987,9 @@ } }, "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "has-symbols": { @@ -1018,6 +8998,12 @@ "integrity": "sha1-n1IUdYpEGWxAbZvXbOv4HsLdMeg=", "dev": true }, + "has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true + }, "hasha": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.0.tgz", @@ -1036,10 +9022,10 @@ } } }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha1-hK5l+n6vsWX922FWauFLrwVmTw8=", + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", "dev": true }, "html-escaper": { @@ -1048,12 +9034,46 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, - "iconv-lite": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + }, + "ignore-by-default": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-2.0.0.tgz", + "integrity": "sha512-+mQSgMRiFD3L3AOxLYOCxjIq4OnAmo5CIuC+lj5ehCJcPtV++QacEV7FdpzvYxH6DaOySWzQU6RR0lPLy37ckA==", + "dev": true + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", "dev": true }, + "import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -1082,36 +9102,160 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha1-PlcvI8hBGlz9lVfISeNmXgspBiM=", + "ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true + }, + "irregular-plurals": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.2.0.tgz", + "integrity": "sha512-YqTdPLfwP7YFN0SsD3QUVCkm9ZG2VzOXv3DOrw5G5mkMbVwptTwVcFv7/C0vOpBmgTxAeTG19XpUs1E522LW9Q==", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, "is-callable": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", "integrity": "sha1-9+RrWWiQRW23Tn9ul2yzJz0G+qs=", "dev": true }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, "is-date-object": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", "integrity": "sha1-vac28s2P0G0yhE53Q7+nSUw7/X4=", "dev": true }, + "is-error": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.2.tgz", + "integrity": "sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "requires": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + } + }, + "is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true + }, + "is-npm": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", + "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, "is-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=", "dev": true }, + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", + "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", + "dev": true + }, + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true + }, + "is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "dev": true + }, "is-regex": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", @@ -1121,12 +9265,6 @@ "has": "^1.0.3" } }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, "is-symbol": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", @@ -1148,10 +9286,10 @@ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", "dev": true }, "isexe": { @@ -1160,16 +9298,6 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, - "isomorphic-fetch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", - "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", - "dev": true, - "requires": { - "node-fetch": "^1.0.1", - "whatwg-fetch": ">=0.10.0" - } - }, "istanbul-lib-coverage": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", @@ -1229,23 +9357,6 @@ "istanbul-lib-coverage": "^3.0.0", "make-dir": "^3.0.0", "supports-color": "^7.1.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } } }, "istanbul-lib-source-maps": { @@ -1280,36 +9391,107 @@ "istanbul-lib-report": "^3.0.0" } }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "jest-diff": { + "version": "27.0.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.2.tgz", + "integrity": "sha512-BFIdRb0LqfV1hBt8crQmw6gGQHVDhM87SpMIZ45FPYKReZYG5er1+5pIn2zKqvrJp6WNox0ylR8571Iwk2Dmgw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^27.0.1", + "jest-get-type": "^27.0.1", + "pretty-format": "^27.0.2" + } + }, + "jest-get-type": { + "version": "27.0.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz", + "integrity": "sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg==", "dev": true }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha1-r/FRswv9+o5J4F2iLnQV6d+jeEc=", + "jest-matcher-utils": { + "version": "27.0.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.0.2.tgz", + "integrity": "sha512-Qczi5xnTNjkhcIB0Yy75Txt+Ez51xdhOxsukN7awzq2auZQGPHcQrJ623PZj0ECDEMOk2soxWx05EXdXGd1CbA==", "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "dependencies": { - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha1-E7BM2z5sXRnfkatph6hpVhmwqnE=", - "dev": true - } + "chalk": "^4.0.0", + "jest-diff": "^27.0.2", + "jest-get-type": "^27.0.1", + "pretty-format": "^27.0.2" + } + }, + "jest-message-util": { + "version": "27.0.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.0.2.tgz", + "integrity": "sha512-rTqWUX42ec2LdMkoUPOzrEd1Tcm+R1KfLOmFK+OVNo4MnLsEaxO5zPDb2BbdSmthdM/IfXxOZU60P/WbWF8BTw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.0.2", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.4", + "pretty-format": "^27.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" } }, + "jest-regex-util": { + "version": "27.0.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.1.tgz", + "integrity": "sha512-6nY6QVcpTgEKQy1L41P4pr3aOddneK17kn3HJw6SdwGiKfgCGTvH02hVXL0GU8GEKtPH83eD2DIDgxHXOxVohQ==", + "dev": true + }, + "jju": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", + "integrity": "sha1-o6vicYryQaKykE+EpiWXDzia4yo=", + "dev": true + }, + "js-string-escape": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", + "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "json-stable-stringify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", @@ -1326,14 +9508,16 @@ "dev": true, "requires": { "minimist": "^1.2.5" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" } }, "jsonify": { @@ -1342,6 +9526,57 @@ "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", "dev": true }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "requires": { + "package-json": "^6.3.0" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "load-json-file": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", + "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "parse-json": "^4.0.0", + "pify": "^4.0.1", + "strip-bom": "^3.0.0", + "type-fest": "^0.3.0" + }, + "dependencies": { + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "type-fest": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", + "dev": true + } + } + }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", @@ -1364,24 +9599,48 @@ "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha1-V0Dhxdbw39pK2TI7UzIQfva0xAo=", + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dev": true, "requires": { - "chalk": "^2.0.1" + "js-tokens": "^3.0.0 || ^4.0.0" } }, - "loose-envify": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", - "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "requires": { - "js-tokens": "^3.0.0" + "yallist": "^3.0.2" } }, + "lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -1404,115 +9663,114 @@ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.0.tgz", "integrity": "sha1-Uq06M5zPEM5itAQLcI/nByRLi5Y=" }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "p-defer": "^1.0.0" } }, - "mkdirp": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz", - "integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==", + "marked": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-2.0.0.tgz", + "integrity": "sha512-NqRSh2+LlN2NInpqTQnS614Y/3NkVMFFU6sJlRFEpxJ/LHuK/qJECH7/fXZjk4VZstPW/Pevjil/VtSONsLc7Q==", + "dev": true + }, + "matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", "dev": true, "requires": { - "minimist": "^1.2.5" + "escape-string-regexp": "^4.0.0" }, "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true } } }, - "mocha": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.2.tgz", - "integrity": "sha512-FgDS9Re79yU1xz5d+C4rv1G7QagNGHZ+iXF81hO8zY35YZZcLEsJVfFolfsqKFWunATEvNzMK0r/CwWd/szO9A==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "2.2.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "ms": "2.1.1", - "node-environment-flags": "1.0.5", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.0", - "yargs-parser": "13.1.1", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha1-gAwN0eCov7yVg1wgKtIg/jF+WhI=", - "dev": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha1-OWCDLT8VdBCDQtr9OmezMsCWnfE=", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "md5-hex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-3.0.1.tgz", + "integrity": "sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==", + "dev": true, + "requires": { + "blueimp-md5": "^2.10.0" + } + }, + "mem": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-8.0.0.tgz", + "integrity": "sha512-qrcJOe6uD+EW8Wrci1Vdiua/15Xw3n/QnaNXE7varnB6InxSk7nu3/i5jfy3S6kWxr8WYJ6R1o0afMUtvorTsA==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.3", + "mimic-fn": "^3.1.0" + }, + "dependencies": { + "mimic-fn": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", + "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } } } }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, "module-not-found-error": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/module-not-found-error/-/module-not-found-error-1.0.1.tgz", @@ -1525,42 +9783,62 @@ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true }, - "node-environment-flags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", - "integrity": "sha1-+pMCdfW/Xa4YjWGSsktMi7rD12o=", + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "requires": { + "process-on-spawn": "^1.0.0" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" }, "dependencies": { + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } }, - "node-fetch": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", - "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", - "dev": true, - "requires": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" - } + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true }, - "node-preload": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", - "dev": true, - "requires": { - "process-on-spawn": "^1.0.0" - } + "normalize-url": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "dev": true }, "ntypescript": { "version": "1.201706190042.1", @@ -1602,12 +9880,6 @@ "yargs": "^15.0.2" }, "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -1815,6 +10087,87 @@ "wrappy": "1" } }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "onigasm": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/onigasm/-/onigasm-2.2.5.tgz", + "integrity": "sha512-F+th54mPc0l1lp1ZcFMyL/jTs2Tlq4SqIHKIXGZOR/VkHkF9A7Fr5rRr5+ZG/lWeRsyrClLYRq7s/yFQ/XhWCA==", + "dev": true, + "requires": { + "lru-cache": "^5.1.1" + } + }, + "ora": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.3.0.tgz", + "integrity": "sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==", + "dev": true, + "requires": { + "bl": "^4.0.3", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "log-symbols": "^4.0.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "dependencies": { + "log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "requires": { + "chalk": "^4.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, + "p-event": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", + "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", + "dev": true, + "requires": { + "p-timeout": "^3.1.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, "p-limit": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", @@ -1842,6 +10195,15 @@ "aggregate-error": "^3.0.0" } }, + "p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dev": true, + "requires": { + "p-finally": "^1.0.0" + } + }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -1860,6 +10222,42 @@ "release-zalgo": "^1.0.0" } }, + "package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "requires": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "parse-ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", + "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", + "dev": true + }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -1884,12 +10282,40 @@ "integrity": "sha1-1i27VnlAXXLEc37FhgDp3c8G0kw=", "dev": true }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, "pathval": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", "dev": true }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pkg-conf": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-3.1.0.tgz", + "integrity": "sha512-m0OTbR/5VPNPqO1ph6Fqbj7Hv6QU7gR/tQW40ZqrL1rjgCU85W6C1bJn0BItuJqnR98PWzw7Z8hHeChD1WrgdQ==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "load-json-file": "^5.2.0" + } + }, "pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -1935,6 +10361,62 @@ } } }, + "plur": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/plur/-/plur-4.0.0.tgz", + "integrity": "sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg==", + "dev": true, + "requires": { + "irregular-plurals": "^3.2.0" + } + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true + }, + "prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true + }, + "pretty-format": { + "version": "27.0.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz", + "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==", + "dev": true, + "requires": { + "@jest/types": "^27.0.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + } + } + }, + "pretty-ms": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", + "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", + "dev": true, + "requires": { + "parse-ms": "^2.1.0" + } + }, "process-on-spawn": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", @@ -1944,24 +10426,21 @@ "fromentries": "^1.2.0" } }, - "promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "dev": true, - "requires": { - "asap": "~2.0.3" - } + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true }, "prop-types": { - "version": "15.6.0", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz", - "integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=", + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", "dev": true, "requires": { - "fbjs": "^0.8.16", - "loose-envify": "^1.3.1", - "object-assign": "^4.1.1" + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" } }, "proxyquire": { @@ -1975,16 +10454,151 @@ "resolve": "~1.1.7" } }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "requires": { + "escape-goat": "^2.0.0" + } + }, + "queue-microtask": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.2.tgz", + "integrity": "sha512-dB15eXv3p2jDlbOiNLyMabYg1/sXvppd8DP2J3EOCQ0AkuSXCW2tP7mnVouVLJKgUMY6yP0kcQDVpLCN13h4Xg==", + "dev": true + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + } + } + }, "react": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.2.0.tgz", - "integrity": "sha512-ZmIomM7EE1DvPEnSFAHZn9Vs9zJl5A9H7el0EGTE6ZbW9FKe/14IYAlPbC8iH25YarEQxZL+E8VW7Mi7kfQrDQ==", + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", + "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", "dev": true, "requires": { - "fbjs": "^0.8.16", "loose-envify": "^1.1.0", "object-assign": "^4.1.1", - "prop-types": "^15.6.0" + "prop-types": "^15.6.2" + } + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "^1.1.6" + } + }, + "registry-auth-token": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "requires": { + "rc": "^1.2.8" } }, "release-zalgo": { @@ -2014,12 +10628,46 @@ "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", "dev": true }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + } + }, "resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, "rimraf": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz", @@ -2045,6 +10693,15 @@ } } }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -2057,18 +10714,46 @@ "integrity": "sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA==", "dev": true }, + "semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "requires": { + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "dev": true, + "requires": { + "type-fest": "^0.13.1" + }, + "dependencies": { + "type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true + } + } + }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -2084,21 +10769,93 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, + "shelljs": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", + "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", + "dev": true, + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "shiki": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.9.2.tgz", + "integrity": "sha512-BjUCxVbxMnvjs8jC4b+BQ808vwjJ9Q8NtLqPwXShZ307HdXiDFYP968ORSVfaTNNSWYDBYdMnVKJ0fYNsoZUBA==", + "dev": true, + "requires": { + "onigasm": "^2.2.5", + "vscode-textmate": "^5.2.0" + } + }, "signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + } + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=" + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", + "dev": true }, "source-map-support": { - "version": "0.5.17", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.17.tgz", - "integrity": "sha512-bwdKOBZ5L0gFRh4KOxNap/J/MpvX9Yxsq9lFDx65s3o7F/NiHy7JRaGIS8MwW6tZPAq9UXE207Il0cfcb5yu/Q==", + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -2129,22 +10886,84 @@ } } }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", + "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", + "dev": true + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", + "stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + } + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } } }, + "string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true + }, "string.prototype.trimleft": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", @@ -2165,36 +10984,67 @@ "function-bind": "^1.1.1" } }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supertap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supertap/-/supertap-2.0.0.tgz", + "integrity": "sha512-jRzcXlCeDYvKoZGA5oRhYyR3jUIYu0enkSxtmAgHRlD7HwrovTpH4bDSi0py9FtuA8si9cW/fKommJHuaoDHJA==", + "dev": true, + "requires": { + "arrify": "^2.0.1", + "indent-string": "^4.0.0", + "js-yaml": "^3.14.0", + "serialize-error": "^7.0.1", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "has-flag": "^4.0.0" } }, - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", "dev": true }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, "test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -2222,115 +11072,56 @@ } } }, + "throat": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", + "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", + "dev": true + }, + "time-zone": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz", + "integrity": "sha1-mcW/VZWJZq9tBtg73zgA3IL67F0=", + "dev": true + }, + "timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", + "dev": true + }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, - "tslib": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", - "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", "dev": true }, - "tslint": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.0.tgz", - "integrity": "sha512-fXjYd/61vU6da04E505OZQGb2VCN2Mq3doeWcOIryuG+eqdmFUXTYVwdhnbEu2k46LNLgUYt9bI5icQze/j0bQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^4.0.1", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.10.0", - "tsutils": "^2.29.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha1-FB8zuBp8JJLhJVlDB0gMRmeSeKY=", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "resolve": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", - "dev": true - } - } - }, - "tslint-config-standard": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/tslint-config-standard/-/tslint-config-standard-9.0.0.tgz", - "integrity": "sha1-NJqUgZ2T1fjYA+PHHLWO847/iOA=", + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "requires": { - "tslint-eslint-rules": "^5.3.1" + "is-number": "^7.0.0" } }, - "tslint-eslint-rules": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/tslint-eslint-rules/-/tslint-eslint-rules-5.4.0.tgz", - "integrity": "sha1-5IjMkYG/GT/lzXv8ohOnaV8XN7U=", - "dev": true, - "requires": { - "doctrine": "0.7.2", - "tslib": "1.9.0", - "tsutils": "^3.0.0" - }, - "dependencies": { - "tslib": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz", - "integrity": "sha1-43qG/ajLuvI6BX9HPJ9Nxk5fwug=", - "dev": true - }, - "tsutils": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", - "integrity": "sha1-7XGZF/EcoN7lhicrKsSeAVot11k=", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } + "trim-off-newlines": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", + "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", + "dev": true }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha1-MrSIUBRnrL7dS4VJhnOggSrKC5k=", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true }, "type-detect": { "version": "4.0.5", @@ -2353,10 +11144,43 @@ "is-typedarray": "^1.0.0" } }, + "typedoc": { + "version": "0.20.28", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.20.28.tgz", + "integrity": "sha512-8j0T8u9FuyDkoe+M/3cyoaGJSVgXCY9KwVoo7TLUnmQuzXwqH+wkScY530ZEdK6G39UZ2LFTYPIrL5eykWjx6A==", + "dev": true, + "requires": { + "colors": "^1.4.0", + "fs-extra": "^9.1.0", + "handlebars": "^4.7.7", + "lodash": "^4.17.21", + "lunr": "^2.3.9", + "marked": "^2.0.0", + "minimatch": "^3.0.0", + "progress": "^2.0.3", + "shelljs": "^0.8.4", + "shiki": "^0.9.2", + "typedoc-default-themes": "^0.12.7" + }, + "dependencies": { + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + } + } + }, + "typedoc-default-themes": { + "version": "0.12.7", + "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.12.7.tgz", + "integrity": "sha512-0XAuGEqID+gon1+fhi4LycOEFM+5Mvm2PjwaiVZNAzU7pn3G2DEpsoXnFOPlLDnHY6ZW0BY0nO7ur9fHOFkBLQ==", + "dev": true + }, "typescript": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz", - "integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.2.tgz", + "integrity": "sha512-tbb+NVrLfnsJy3M59lsDgrzWIflR4d4TIUjz+heUnHZwdF7YsrMTKoRERiIvI2lvBG95dfpLxB21WZhys1bgaQ==", "dev": true }, "typescript-json-schema": { @@ -2449,10 +11273,98 @@ } } }, - "ua-parser-js": { - "version": "0.7.17", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz", - "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g==", + "uglify-js": { + "version": "3.12.8", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.12.8.tgz", + "integrity": "sha512-fvBeuXOsvqjecUtF/l1dwsrrf5y2BCUk9AOJGzGcm6tE7vegku5u/YvqjyDaAGr422PLoLnrxg3EnRvTqsdC1w==", + "dev": true, + "optional": true + }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + }, + "update-notifier": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", + "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", + "dev": true, + "requires": { + "boxen": "^5.0.0", + "chalk": "^4.1.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.4.0", + "is-npm": "^5.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.1.0", + "pupa": "^2.1.1", + "semver": "^7.3.4", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, "util.promisify": { @@ -2473,10 +11385,41 @@ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true }, - "whatwg-fetch": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", - "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=", + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "validator": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-8.2.0.tgz", + "integrity": "sha512-Yw5wW34fSv5spzTXNkokD6S6/Oq92d8q/t14TqsS3fAiA1RYnxSFSIZ+CY3n6PGGRCq5HhJTSepQvFUS2QUDxA==", + "dev": true + }, + "vscode-textmate": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz", + "integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==", + "dev": true + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, + "well-known-symbols": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz", + "integrity": "sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==", "dev": true }, "which-module": { @@ -2485,15 +11428,55 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha1-rgdOa9wMFKQx6ATmJFScYzsABFc=", + "widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", "dev": true, "requires": { - "string-width": "^1.0.2 || 2" + "string-width": "^4.0.0" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } } }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, "wrap-ansi": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", @@ -2551,83 +11534,40 @@ "typedarray-to-buffer": "^3.1.5" } }, + "xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true + }, "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", "integrity": "sha1-le+U+F7MgdAHwmThkKEg8KPIVms=", "dev": true }, - "yargs": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", - "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.1" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha1-InZ74htirxCBV0MG9prFG2IgOWE=", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4=", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha1-7yXCx2n/a9CeSw+dfGBfsnhG6p8=", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true }, "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha1-HodAGgnXZ8HV6rJqbkwYUYLS61A=" + }, + "z-schema": { + "version": "3.18.4", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-3.18.4.tgz", + "integrity": "sha512-DUOKC/IhbkdLKKiV89gw9DUauTV8U/8yJl1sjf6MtDmzevLKOF2duNJ495S3MFVjqZarr+qNGCPbkg4mu4PpLw==", + "dev": true, + "requires": { + "commander": "^2.7.1", + "lodash.get": "^4.0.0", + "lodash.isequal": "^4.0.0", + "validator": "^8.0.0" + } } } } diff --git a/package.json b/package.json index 808cf56d9..e5b6ca0b6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ts-node", - "version": "9.0.0", + "version": "10.2.0", "description": "TypeScript execution environment and REPL for node.js, with source map support", "main": "dist/index.js", "exports": { @@ -13,6 +13,8 @@ "./dist/bin-transpile.js": "./dist/bin-transpile.js", "./dist/bin-script": "./dist/bin-script.js", "./dist/bin-script.js": "./dist/bin-script.js", + "./dist/bin-cwd": "./dist/bin-cwd.js", + "./dist/bin-cwd.js": "./dist/bin-cwd.js", "./register": "./register/index.js", "./register/files": "./register/files.js", "./register/transpile-only": "./register/transpile-only.js", @@ -20,43 +22,57 @@ "./esm": "./esm.mjs", "./esm.mjs": "./esm.mjs", "./esm/transpile-only": "./esm/transpile-only.mjs", - "./esm/transpile-only.mjs": "./esm/transpile-only.mjs" + "./esm/transpile-only.mjs": "./esm/transpile-only.mjs", + "./transpilers/swc-experimental": "./transpilers/swc-experimental.js", + "./node10/tsconfig.json": "./node10/tsconfig.json", + "./node12/tsconfig.json": "./node12/tsconfig.json", + "./node14/tsconfig.json": "./node14/tsconfig.json", + "./node16/tsconfig.json": "./node16/tsconfig.json" }, "types": "dist/index.d.ts", "bin": { "ts-node": "dist/bin.js", "ts-script": "dist/bin-script-deprecated.js", "ts-node-script": "dist/bin-script.js", + "ts-node-cwd": "dist/bin-cwd.js", "ts-node-transpile-only": "dist/bin-transpile.js" }, "files": [ - "dist/", - "dist-raw/", - "register/", - "esm/", - "esm.mjs", - "LICENSE", - "tsconfig.schema.json", - "tsconfig.schemastore-schema.json" + "/transpilers/", + "/dist/", + "!/dist/test", + "/dist-raw/**.js", + "/register/", + "/esm/", + "/esm.mjs", + "/LICENSE", + "/tsconfig.schema.json", + "/tsconfig.schemastore-schema.json", + "/node10/", + "/node12/", + "/node14/", + "/node16/" ], "scripts": { - "lint": "tslint \"src/**/*.ts\" --project tsconfig.json", - "lint-fix": "tslint \"src/**/*.ts\" --project tsconfig.json --fix", - "clean": "rimraf dist && rimraf tsconfig.schema.json && rimraf tsconfig.schemastore-schema.json && rimraf tests/ts-node-packed.tgz", + "lint": "prettier --check .", + "lint-fix": "prettier --write .", + "clean": "rimraf dist tsconfig.schema.json tsconfig.schemastore-schema.json tsconfig.tsbuildinfo tests/ts-node-packed.tgz", + "rebuild": "npm run clean && npm run build", "build": "npm run build-nopack && npm run build-pack", - "build-nopack": "npm run clean && npm run build-tsc && npm run build-configSchema", + "build-nopack": "npm run build-tsc && npm run build-configSchema", "build-tsc": "tsc", - "build-configSchema": "typescript-json-schema --topRef --refs --validationKeywords allOf --out tsconfig.schema.json tsconfig.json TsConfigSchema && node --require ./register ./scripts/create-merged-schema", + "build-configSchema": "typescript-json-schema --topRef --refs --validationKeywords allOf --out tsconfig.schema.json tsconfig.build-schema.json TsConfigSchema && node --require ./register ./scripts/create-merged-schema", "build-pack": "node ./scripts/build-pack.js", - "test-spec": "mocha dist/**/*.spec.js -R spec --bail", - "test-cov": "nyc mocha -- \"dist/**/*.spec.js\" -R spec --bail", - "test": "npm run build && npm run lint && npm run test-cov", - "coverage-fix-paths": "node ./scripts/rewrite-coverage-paths.js", + "test-spec": "ava", + "test-cov": "nyc ava", + "test": "npm run build && npm run lint && npm run test-cov --", + "test-local": "npm run lint-fix && npm run build-tsc && npm run build-pack && npm run test-spec --", "coverage-report": "nyc report --reporter=lcov", - "prepare": "npm run build-nopack" + "prepare": "npm run clean && npm run build-nopack", + "api-extractor": "api-extractor run --local --verbose" }, "engines": { - "node": ">=10.0.0" + "node": ">=12.0.0" }, "repository": { "type": "git", @@ -75,46 +91,86 @@ "email": "hello@blakeembrey.com", "url": "http://blakeembrey.me" }, + "contributors": [ + { + "name": "Andrew Bradley", + "email": "cspotcode@gmail.com", + "url": "https://github.com/cspotcode" + } + ], "license": "MIT", "bugs": { "url": "https://github.com/TypeStrong/ts-node/issues" }, - "homepage": "https://github.com/TypeStrong/ts-node", + "homepage": "https://typestrong.org/ts-node", + "ava": { + "files": [ + "dist/test/*.spec.js" + ], + "failWithoutAssertions": false, + "timeout": "300s" + }, "devDependencies": { + "@microsoft/api-extractor": "^7.15.2", + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", "@types/chai": "^4.0.4", "@types/diff": "^4.0.2", "@types/lodash": "^4.14.151", - "@types/mocha": "^5.2.7", "@types/node": "13.13.5", "@types/proxyquire": "^1.3.28", "@types/react": "^16.0.2", "@types/rimraf": "^3.0.0", "@types/semver": "^7.1.0", - "@types/source-map-support": "^0.5.0", - "axios": "^0.19.0", + "@yarnpkg/fslib": "^2.4.0", + "ava": "^3.15.0", + "axios": "^0.21.1", "chai": "^4.0.1", + "expect": "^27.0.2", + "get-stream": "^6.0.0", "lodash": "^4.17.15", - "mocha": "^6.2.2", "ntypescript": "^1.201507091536.1", "nyc": "^15.0.1", + "prettier": "^2.2.1", "proxyquire": "^2.0.0", - "react": "^16.0.0", + "react": "^16.14.0", "rimraf": "^3.0.0", "semver": "^7.1.3", - "tslint": "^6.1.0", - "tslint-config-standard": "^9.0.0", - "typescript": "4.0.2", + "throat": "^6.0.1", + "typedoc": "^0.20.28", + "typescript": "4.2.2", "typescript-json-schema": "^0.42.0", "util.promisify": "^1.0.1" }, "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", "typescript": ">=2.7" }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + }, "dependencies": { + "@cspotcode/source-map-support": "0.6.1", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", "arg": "^4.1.0", + "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", - "source-map-support": "^0.5.17", "yn": "3.1.1" + }, + "prettier": { + "singleQuote": true } } diff --git a/raw/node-esm-resolve-implementation.js b/raw/node-esm-resolve-implementation-v13.12.0.js similarity index 99% rename from raw/node-esm-resolve-implementation.js rename to raw/node-esm-resolve-implementation-v13.12.0.js index 730c815b8..1c2b8e67f 100644 --- a/raw/node-esm-resolve-implementation.js +++ b/raw/node-esm-resolve-implementation-v13.12.0.js @@ -661,3 +661,4 @@ module.exports = { defaultResolve, getPackageType }; + diff --git a/raw/node-esm-resolve-implementation-v15.3.0.js b/raw/node-esm-resolve-implementation-v15.3.0.js new file mode 100644 index 000000000..782b892a6 --- /dev/null +++ b/raw/node-esm-resolve-implementation-v15.3.0.js @@ -0,0 +1,900 @@ +'use strict'; + +const { + ArrayIsArray, + ArrayPrototypeJoin, + ArrayPrototypeShift, + JSONParse, + JSONStringify, + ObjectFreeze, + ObjectGetOwnPropertyNames, + ObjectPrototypeHasOwnProperty, + RegExp, + RegExpPrototypeTest, + SafeMap, + SafeSet, + String, + StringPrototypeEndsWith, + StringPrototypeIndexOf, + StringPrototypeLastIndexOf, + StringPrototypeReplace, + StringPrototypeSlice, + StringPrototypeSplit, + StringPrototypeStartsWith, + StringPrototypeSubstr, +} = primordials; +const internalFS = require('internal/fs/utils'); +const { NativeModule } = require('internal/bootstrap/loaders'); +const { + realpathSync, + statSync, + Stats, +} = require('fs'); +const { getOptionValue } = require('internal/options'); +// Do not eagerly grab .manifest, it may be in TDZ +const policy = getOptionValue('--experimental-policy') ? + require('internal/process/policy') : + null; +const { sep, relative } = require('path'); +const preserveSymlinks = getOptionValue('--preserve-symlinks'); +const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main'); +const typeFlag = getOptionValue('--input-type'); +const { URL, pathToFileURL, fileURLToPath } = require('internal/url'); +const { + ERR_INPUT_TYPE_NOT_ALLOWED, + ERR_INVALID_ARG_VALUE, + ERR_INVALID_MODULE_SPECIFIER, + ERR_INVALID_PACKAGE_CONFIG, + ERR_INVALID_PACKAGE_TARGET, + ERR_MANIFEST_DEPENDENCY_MISSING, + ERR_MODULE_NOT_FOUND, + ERR_PACKAGE_IMPORT_NOT_DEFINED, + ERR_PACKAGE_PATH_NOT_EXPORTED, + ERR_UNSUPPORTED_DIR_IMPORT, + ERR_UNSUPPORTED_ESM_URL_SCHEME, +} = require('internal/errors').codes; +const { Module: CJSModule } = require('internal/modules/cjs/loader'); + +const packageJsonReader = require('internal/modules/package_json_reader'); +const userConditions = getOptionValue('--conditions'); +const DEFAULT_CONDITIONS = ObjectFreeze(['node', 'import', ...userConditions]); +const DEFAULT_CONDITIONS_SET = new SafeSet(DEFAULT_CONDITIONS); + +const pendingDeprecation = getOptionValue('--pending-deprecation'); +const emittedPackageWarnings = new SafeSet(); +function emitFolderMapDeprecation(match, pjsonUrl, isExports, base) { + const pjsonPath = fileURLToPath(pjsonUrl); + if (!pendingDeprecation) { + const nodeModulesIndex = StringPrototypeLastIndexOf(pjsonPath, + '/node_modules/'); + if (nodeModulesIndex !== -1) { + const afterNodeModulesPath = StringPrototypeSlice(pjsonPath, + nodeModulesIndex + 14, + -13); + try { + const { packageSubpath } = parsePackageName(afterNodeModulesPath); + if (packageSubpath === '.') + return; + } catch {} + } + } + if (emittedPackageWarnings.has(pjsonPath + '|' + match)) + return; + emittedPackageWarnings.add(pjsonPath + '|' + match); + process.emitWarning( + `Use of deprecated folder mapping "${match}" in the ${isExports ? + '"exports"' : '"imports"'} field module resolution of the package at ${ + pjsonPath}${base ? ` imported from ${fileURLToPath(base)}` : ''}.\n` + + `Update this package.json to use a subpath pattern like "${match}*".`, + 'DeprecationWarning', + 'DEP0148' + ); +} + +function getConditionsSet(conditions) { + if (conditions !== undefined && conditions !== DEFAULT_CONDITIONS) { + if (!ArrayIsArray(conditions)) { + throw new ERR_INVALID_ARG_VALUE('conditions', conditions, + 'expected an array'); + } + return new SafeSet(conditions); + } + return DEFAULT_CONDITIONS_SET; +} + +const realpathCache = new SafeMap(); +const packageJSONCache = new SafeMap(); /* string -> PackageConfig */ + +function tryStatSync(path) { + try { + return statSync(path); + } catch { + return new Stats(); + } +} + +function getPackageConfig(path, specifier, base) { + const existing = packageJSONCache.get(path); + if (existing !== undefined) { + return existing; + } + const source = packageJsonReader.read(path).string; + if (source === undefined) { + const packageConfig = { + pjsonPath: path, + exists: false, + main: undefined, + name: undefined, + type: 'none', + exports: undefined, + imports: undefined, + }; + packageJSONCache.set(path, packageConfig); + return packageConfig; + } + + let packageJSON; + try { + packageJSON = JSONParse(source); + } catch (error) { + throw new ERR_INVALID_PACKAGE_CONFIG( + path, + (base ? `"${specifier}" from ` : '') + fileURLToPath(base || specifier), + error.message + ); + } + + let { imports, main, name, type } = packageJSON; + const { exports } = packageJSON; + if (typeof imports !== 'object' || imports === null) imports = undefined; + if (typeof main !== 'string') main = undefined; + if (typeof name !== 'string') name = undefined; + // Ignore unknown types for forwards compatibility + if (type !== 'module' && type !== 'commonjs') type = 'none'; + + const packageConfig = { + pjsonPath: path, + exists: true, + main, + name, + type, + exports, + imports, + }; + packageJSONCache.set(path, packageConfig); + return packageConfig; +} + +function getPackageScopeConfig(resolved) { + let packageJSONUrl = new URL('./package.json', resolved); + while (true) { + const packageJSONPath = packageJSONUrl.pathname; + if (StringPrototypeEndsWith(packageJSONPath, 'node_modules/package.json')) + break; + const packageConfig = getPackageConfig(fileURLToPath(packageJSONUrl), + resolved); + if (packageConfig.exists) return packageConfig; + + const lastPackageJSONUrl = packageJSONUrl; + packageJSONUrl = new URL('../package.json', packageJSONUrl); + + // Terminates at root where ../package.json equals ../../package.json + // (can't just check "/package.json" for Windows support). + if (packageJSONUrl.pathname === lastPackageJSONUrl.pathname) break; + } + const packageJSONPath = fileURLToPath(packageJSONUrl); + const packageConfig = { + pjsonPath: packageJSONPath, + exists: false, + main: undefined, + name: undefined, + type: 'none', + exports: undefined, + imports: undefined, + }; + packageJSONCache.set(packageJSONPath, packageConfig); + return packageConfig; +} + +/* + * Legacy CommonJS main resolution: + * 1. let M = pkg_url + (json main field) + * 2. TRY(M, M.js, M.json, M.node) + * 3. TRY(M/index.js, M/index.json, M/index.node) + * 4. TRY(pkg_url/index.js, pkg_url/index.json, pkg_url/index.node) + * 5. NOT_FOUND + */ +function fileExists(url) { + return tryStatSync(fileURLToPath(url)).isFile(); +} + +function legacyMainResolve(packageJSONUrl, packageConfig, base) { + let guess; + if (packageConfig.main !== undefined) { + // Note: fs check redundances will be handled by Descriptor cache here. + if (fileExists(guess = new URL(`./${packageConfig.main}`, + packageJSONUrl))) { + return guess; + } + if (fileExists(guess = new URL(`./${packageConfig.main}.js`, + packageJSONUrl))) { + return guess; + } + if (fileExists(guess = new URL(`./${packageConfig.main}.json`, + packageJSONUrl))) { + return guess; + } + if (fileExists(guess = new URL(`./${packageConfig.main}.node`, + packageJSONUrl))) { + return guess; + } + if (fileExists(guess = new URL(`./${packageConfig.main}/index.js`, + packageJSONUrl))) { + return guess; + } + if (fileExists(guess = new URL(`./${packageConfig.main}/index.json`, + packageJSONUrl))) { + return guess; + } + if (fileExists(guess = new URL(`./${packageConfig.main}/index.node`, + packageJSONUrl))) { + return guess; + } + // Fallthrough. + } + if (fileExists(guess = new URL('./index.js', packageJSONUrl))) { + return guess; + } + // So fs. + if (fileExists(guess = new URL('./index.json', packageJSONUrl))) { + return guess; + } + if (fileExists(guess = new URL('./index.node', packageJSONUrl))) { + return guess; + } + // Not found. + throw new ERR_MODULE_NOT_FOUND( + fileURLToPath(new URL('.', packageJSONUrl)), fileURLToPath(base)); +} + +function resolveExtensionsWithTryExactName(search) { + if (fileExists(search)) return search; + return resolveExtensions(search); +} + +const extensions = ['.js', '.json', '.node', '.mjs']; +function resolveExtensions(search) { + for (let i = 0; i < extensions.length; i++) { + const extension = extensions[i]; + const guess = new URL(`${search.pathname}${extension}`, search); + if (fileExists(guess)) return guess; + } + return undefined; +} + +function resolveIndex(search) { + return resolveExtensions(new URL('index', search)); +} + +const encodedSepRegEx = /%2F|%2C/i; +function finalizeResolution(resolved, base) { + if (RegExpPrototypeTest(encodedSepRegEx, resolved.pathname)) + throw new ERR_INVALID_MODULE_SPECIFIER( + resolved.pathname, 'must not include encoded "/" or "\\" characters', + fileURLToPath(base)); + + const path = fileURLToPath(resolved); + if (getOptionValue('--experimental-specifier-resolution') === 'node') { + let file = resolveExtensionsWithTryExactName(resolved); + if (file !== undefined) return file; + if (!StringPrototypeEndsWith(path, '/')) { + file = resolveIndex(new URL(`${resolved}/`)); + if (file !== undefined) return file; + } else { + return resolveIndex(resolved) || resolved; + } + throw new ERR_MODULE_NOT_FOUND( + resolved.pathname, fileURLToPath(base), 'module'); + } + + const stats = tryStatSync(StringPrototypeEndsWith(path, '/') ? + StringPrototypeSlice(path, -1) : path); + if (stats.isDirectory()) { + const err = new ERR_UNSUPPORTED_DIR_IMPORT(path, fileURLToPath(base)); + err.url = String(resolved); + throw err; + } else if (!stats.isFile()) { + throw new ERR_MODULE_NOT_FOUND( + path || resolved.pathname, base && fileURLToPath(base), 'module'); + } + + return resolved; +} + +function throwImportNotDefined(specifier, packageJSONUrl, base) { + throw new ERR_PACKAGE_IMPORT_NOT_DEFINED( + specifier, packageJSONUrl && fileURLToPath(new URL('.', packageJSONUrl)), + fileURLToPath(base)); +} + +function throwExportsNotFound(subpath, packageJSONUrl, base) { + throw new ERR_PACKAGE_PATH_NOT_EXPORTED( + fileURLToPath(new URL('.', packageJSONUrl)), subpath, + base && fileURLToPath(base)); +} + +function throwInvalidSubpath(subpath, packageJSONUrl, internal, base) { + const reason = `request is not a valid subpath for the "${internal ? + 'imports' : 'exports'}" resolution of ${fileURLToPath(packageJSONUrl)}`; + throw new ERR_INVALID_MODULE_SPECIFIER(subpath, reason, + base && fileURLToPath(base)); +} + +function throwInvalidPackageTarget( + subpath, target, packageJSONUrl, internal, base) { + if (typeof target === 'object' && target !== null) { + target = JSONStringify(target, null, ''); + } else { + target = `${target}`; + } + throw new ERR_INVALID_PACKAGE_TARGET( + fileURLToPath(new URL('.', packageJSONUrl)), subpath, target, + internal, base && fileURLToPath(base)); +} + +const invalidSegmentRegEx = /(^|\\|\/)(\.\.?|node_modules)(\\|\/|$)/; +const patternRegEx = /\*/g; + +function resolvePackageTargetString( + target, subpath, match, packageJSONUrl, base, pattern, internal, conditions) { + if (subpath !== '' && !pattern && target[target.length - 1] !== '/') + throwInvalidPackageTarget(match, target, packageJSONUrl, internal, base); + + if (!StringPrototypeStartsWith(target, './')) { + if (internal && !StringPrototypeStartsWith(target, '../') && + !StringPrototypeStartsWith(target, '/')) { + let isURL = false; + try { + new URL(target); + isURL = true; + } catch {} + if (!isURL) { + const exportTarget = pattern ? + StringPrototypeReplace(target, patternRegEx, subpath) : + target + subpath; + return packageResolve(exportTarget, packageJSONUrl, conditions); + } + } + throwInvalidPackageTarget(match, target, packageJSONUrl, internal, base); + } + + if (RegExpPrototypeTest(invalidSegmentRegEx, StringPrototypeSlice(target, 2))) + throwInvalidPackageTarget(match, target, packageJSONUrl, internal, base); + + const resolved = new URL(target, packageJSONUrl); + const resolvedPath = resolved.pathname; + const packagePath = new URL('.', packageJSONUrl).pathname; + + if (!StringPrototypeStartsWith(resolvedPath, packagePath)) + throwInvalidPackageTarget(match, target, packageJSONUrl, internal, base); + + if (subpath === '') return resolved; + + if (RegExpPrototypeTest(invalidSegmentRegEx, subpath)) + throwInvalidSubpath(match + subpath, packageJSONUrl, internal, base); + + if (pattern) + return new URL(StringPrototypeReplace(resolved.href, patternRegEx, + subpath)); + return new URL(subpath, resolved); +} + +/** + * @param {string} key + * @returns {boolean} + */ +function isArrayIndex(key) { + const keyNum = +key; + if (`${keyNum}` !== key) return false; + return keyNum >= 0 && keyNum < 0xFFFF_FFFF; +} + +function resolvePackageTarget(packageJSONUrl, target, subpath, packageSubpath, + base, pattern, internal, conditions) { + if (typeof target === 'string') { + return resolvePackageTargetString( + target, subpath, packageSubpath, packageJSONUrl, base, pattern, internal, + conditions); + } else if (ArrayIsArray(target)) { + if (target.length === 0) + return null; + + let lastException; + for (let i = 0; i < target.length; i++) { + const targetItem = target[i]; + let resolved; + try { + resolved = resolvePackageTarget( + packageJSONUrl, targetItem, subpath, packageSubpath, base, pattern, + internal, conditions); + } catch (e) { + lastException = e; + if (e.code === 'ERR_INVALID_PACKAGE_TARGET') + continue; + throw e; + } + if (resolved === undefined) + continue; + if (resolved === null) { + lastException = null; + continue; + } + return resolved; + } + if (lastException === undefined || lastException === null) + return lastException; + throw lastException; + } else if (typeof target === 'object' && target !== null) { + const keys = ObjectGetOwnPropertyNames(target); + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + if (isArrayIndex(key)) { + throw new ERR_INVALID_PACKAGE_CONFIG( + fileURLToPath(packageJSONUrl), base, + '"exports" cannot contain numeric property keys.'); + } + } + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + if (key === 'default' || conditions.has(key)) { + const conditionalTarget = target[key]; + const resolved = resolvePackageTarget( + packageJSONUrl, conditionalTarget, subpath, packageSubpath, base, + pattern, internal, conditions); + if (resolved === undefined) + continue; + return resolved; + } + } + return undefined; + } else if (target === null) { + return null; + } + throwInvalidPackageTarget(packageSubpath, target, packageJSONUrl, internal, + base); +} + +function isConditionalExportsMainSugar(exports, packageJSONUrl, base) { + if (typeof exports === 'string' || ArrayIsArray(exports)) return true; + if (typeof exports !== 'object' || exports === null) return false; + + const keys = ObjectGetOwnPropertyNames(exports); + let isConditionalSugar = false; + let i = 0; + for (let j = 0; j < keys.length; j++) { + const key = keys[j]; + const curIsConditionalSugar = key === '' || key[0] !== '.'; + if (i++ === 0) { + isConditionalSugar = curIsConditionalSugar; + } else if (isConditionalSugar !== curIsConditionalSugar) { + throw new ERR_INVALID_PACKAGE_CONFIG( + fileURLToPath(packageJSONUrl), base, + '"exports" cannot contain some keys starting with \'.\' and some not.' + + ' The exports object must either be an object of package subpath keys' + + ' or an object of main entry condition name keys only.'); + } + } + return isConditionalSugar; +} + +/** + * @param {URL} packageJSONUrl + * @param {string} packageSubpath + * @param {object} packageConfig + * @param {string} base + * @param {Set} conditions + * @returns {URL} + */ +function packageExportsResolve( + packageJSONUrl, packageSubpath, packageConfig, base, conditions) { + let exports = packageConfig.exports; + if (isConditionalExportsMainSugar(exports, packageJSONUrl, base)) + exports = { '.': exports }; + + if (ObjectPrototypeHasOwnProperty(exports, packageSubpath)) { + const target = exports[packageSubpath]; + const resolved = resolvePackageTarget( + packageJSONUrl, target, '', packageSubpath, base, false, false, conditions + ); + if (resolved === null || resolved === undefined) + throwExportsNotFound(packageSubpath, packageJSONUrl, base); + return { resolved, exact: true }; + } + + let bestMatch = ''; + const keys = ObjectGetOwnPropertyNames(exports); + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + if (key[key.length - 1] === '*' && + StringPrototypeStartsWith(packageSubpath, + StringPrototypeSlice(key, 0, -1)) && + packageSubpath.length >= key.length && + key.length > bestMatch.length) { + bestMatch = key; + } else if (key[key.length - 1] === '/' && + StringPrototypeStartsWith(packageSubpath, key) && + key.length > bestMatch.length) { + bestMatch = key; + } + } + + if (bestMatch) { + const target = exports[bestMatch]; + const pattern = bestMatch[bestMatch.length - 1] === '*'; + const subpath = StringPrototypeSubstr(packageSubpath, bestMatch.length - + (pattern ? 1 : 0)); + const resolved = resolvePackageTarget(packageJSONUrl, target, subpath, + bestMatch, base, pattern, false, + conditions); + if (resolved === null || resolved === undefined) + throwExportsNotFound(packageSubpath, packageJSONUrl, base); + if (!pattern) + emitFolderMapDeprecation(bestMatch, packageJSONUrl, true, base); + return { resolved, exact: pattern }; + } + + throwExportsNotFound(packageSubpath, packageJSONUrl, base); +} + +function packageImportsResolve(name, base, conditions) { + if (name === '#' || StringPrototypeStartsWith(name, '#/')) { + const reason = 'is not a valid internal imports specifier name'; + throw new ERR_INVALID_MODULE_SPECIFIER(name, reason, fileURLToPath(base)); + } + let packageJSONUrl; + const packageConfig = getPackageScopeConfig(base); + if (packageConfig.exists) { + packageJSONUrl = pathToFileURL(packageConfig.pjsonPath); + const imports = packageConfig.imports; + if (imports) { + if (ObjectPrototypeHasOwnProperty(imports, name)) { + const resolved = resolvePackageTarget( + packageJSONUrl, imports[name], '', name, base, false, true, conditions + ); + if (resolved !== null) + return { resolved, exact: true }; + } else { + let bestMatch = ''; + const keys = ObjectGetOwnPropertyNames(imports); + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + if (key[key.length - 1] === '*' && + StringPrototypeStartsWith(name, + StringPrototypeSlice(key, 0, -1)) && + name.length >= key.length && + key.length > bestMatch.length) { + bestMatch = key; + } else if (key[key.length - 1] === '/' && + StringPrototypeStartsWith(name, key) && + key.length > bestMatch.length) { + bestMatch = key; + } + } + + if (bestMatch) { + const target = imports[bestMatch]; + const pattern = bestMatch[bestMatch.length - 1] === '*'; + const subpath = StringPrototypeSubstr(name, bestMatch.length - + (pattern ? 1 : 0)); + const resolved = resolvePackageTarget( + packageJSONUrl, target, subpath, bestMatch, base, pattern, true, + conditions); + if (resolved !== null) { + if (!pattern) + emitFolderMapDeprecation(bestMatch, packageJSONUrl, false, base); + return { resolved, exact: pattern }; + } + } + } + } + } + throwImportNotDefined(name, packageJSONUrl, base); +} + +function getPackageType(url) { + const packageConfig = getPackageScopeConfig(url); + return packageConfig.type; +} + +function parsePackageName(specifier, base) { + let separatorIndex = StringPrototypeIndexOf(specifier, '/'); + let validPackageName = true; + let isScoped = false; + if (specifier[0] === '@') { + isScoped = true; + if (separatorIndex === -1 || specifier.length === 0) { + validPackageName = false; + } else { + separatorIndex = StringPrototypeIndexOf( + specifier, '/', separatorIndex + 1); + } + } + + const packageName = separatorIndex === -1 ? + specifier : StringPrototypeSlice(specifier, 0, separatorIndex); + + // Package name cannot have leading . and cannot have percent-encoding or + // separators. + for (let i = 0; i < packageName.length; i++) { + if (packageName[i] === '%' || packageName[i] === '\\') { + validPackageName = false; + break; + } + } + + if (!validPackageName) { + throw new ERR_INVALID_MODULE_SPECIFIER( + specifier, 'is not a valid package name', fileURLToPath(base)); + } + + const packageSubpath = '.' + (separatorIndex === -1 ? '' : + StringPrototypeSlice(specifier, separatorIndex)); + + return { packageName, packageSubpath, isScoped }; +} + +/** + * @param {string} specifier + * @param {URL} base + * @param {Set} conditions + * @returns {URL} + */ +function packageResolve(specifier, base, conditions) { + const { packageName, packageSubpath, isScoped } = + parsePackageName(specifier, base); + + // ResolveSelf + const packageConfig = getPackageScopeConfig(base); + if (packageConfig.exists) { + const packageJSONUrl = pathToFileURL(packageConfig.pjsonPath); + if (packageConfig.name === packageName && + packageConfig.exports !== undefined && packageConfig.exports !== null) { + return packageExportsResolve( + packageJSONUrl, packageSubpath, packageConfig, base, conditions + ).resolved; + } + } + + let packageJSONUrl = + new URL('./node_modules/' + packageName + '/package.json', base); + let packageJSONPath = fileURLToPath(packageJSONUrl); + let lastPath; + do { + const stat = tryStatSync(StringPrototypeSlice(packageJSONPath, 0, + packageJSONPath.length - 13)); + if (!stat.isDirectory()) { + lastPath = packageJSONPath; + packageJSONUrl = new URL((isScoped ? + '../../../../node_modules/' : '../../../node_modules/') + + packageName + '/package.json', packageJSONUrl); + packageJSONPath = fileURLToPath(packageJSONUrl); + continue; + } + + // Package match. + const packageConfig = getPackageConfig(packageJSONPath, specifier, base); + if (packageConfig.exports !== undefined && packageConfig.exports !== null) + return packageExportsResolve( + packageJSONUrl, packageSubpath, packageConfig, base, conditions + ).resolved; + if (packageSubpath === '.') + return legacyMainResolve(packageJSONUrl, packageConfig, base); + return new URL(packageSubpath, packageJSONUrl); + // Cross-platform root check. + } while (packageJSONPath.length !== lastPath.length); + + // eslint can't handle the above code. + // eslint-disable-next-line no-unreachable + throw new ERR_MODULE_NOT_FOUND(packageName, fileURLToPath(base)); +} + +function isBareSpecifier(specifier) { + return specifier[0] && specifier[0] !== '/' && specifier[0] !== '.'; +} + +function isRelativeSpecifier(specifier) { + if (specifier[0] === '.') { + if (specifier.length === 1 || specifier[1] === '/') return true; + if (specifier[1] === '.') { + if (specifier.length === 2 || specifier[2] === '/') return true; + } + } + return false; +} + +function shouldBeTreatedAsRelativeOrAbsolutePath(specifier) { + if (specifier === '') return false; + if (specifier[0] === '/') return true; + return isRelativeSpecifier(specifier); +} + +/** + * @param {string} specifier + * @param {URL} base + * @param {Set} conditions + * @returns {URL} + */ +function moduleResolve(specifier, base, conditions) { + // Order swapped from spec for minor perf gain. + // Ok since relative URLs cannot parse as URLs. + let resolved; + if (shouldBeTreatedAsRelativeOrAbsolutePath(specifier)) { + resolved = new URL(specifier, base); + } else if (specifier[0] === '#') { + ({ resolved } = packageImportsResolve(specifier, base, conditions)); + } else { + try { + resolved = new URL(specifier); + } catch { + resolved = packageResolve(specifier, base, conditions); + } + } + return finalizeResolution(resolved, base); +} + +/** + * Try to resolve an import as a CommonJS module + * @param {string} specifier + * @param {string} parentURL + * @returns {boolean|string} + */ +function resolveAsCommonJS(specifier, parentURL) { + try { + const parent = fileURLToPath(parentURL); + const tmpModule = new CJSModule(parent, null); + tmpModule.paths = CJSModule._nodeModulePaths(parent); + + let found = CJSModule._resolveFilename(specifier, tmpModule, false); + + // If it is a relative specifier return the relative path + // to the parent + if (isRelativeSpecifier(specifier)) { + found = relative(parent, found); + // Add '.separator if the path does not start with '..separator' + // This should be a safe assumption because when loading + // esm modules there should be always a file specified so + // there should not be a specifier like '..' or '.' + if (!StringPrototypeStartsWith(found, `..${sep}`)) { + found = `.${sep}${found}`; + } + } else if (isBareSpecifier(specifier)) { + // If it is a bare specifier return the relative path within the + // module + const pkg = StringPrototypeSplit(specifier, '/')[0]; + const index = StringPrototypeIndexOf(found, pkg); + if (index !== -1) { + found = StringPrototypeSlice(found, index); + } + } + // Normalize the path separator to give a valid suggestion + // on Windows + if (process.platform === 'win32') { + found = StringPrototypeReplace(found, new RegExp(`\\${sep}`, 'g'), '/'); + } + return found; + } catch { + return false; + } +} + +function defaultResolve(specifier, context = {}, defaultResolveUnused) { + let { parentURL, conditions } = context; + if (parentURL && policy?.manifest) { + const redirects = policy.manifest.getDependencyMapper(parentURL); + if (redirects) { + const { resolve, reaction } = redirects; + const destination = resolve(specifier, new SafeSet(conditions)); + let missing = true; + if (destination === true) { + missing = false; + } else if (destination) { + const href = destination.href; + return { url: href }; + } + if (missing) { + reaction(new ERR_MANIFEST_DEPENDENCY_MISSING( + parentURL, + specifier, + ArrayPrototypeJoin([...conditions], ', ')) + ); + } + } + } + let parsed; + try { + parsed = new URL(specifier); + if (parsed.protocol === 'data:') { + return { + url: specifier + }; + } + } catch {} + if (parsed && parsed.protocol === 'node:') + return { url: specifier }; + if (parsed && parsed.protocol !== 'file:' && parsed.protocol !== 'data:') + throw new ERR_UNSUPPORTED_ESM_URL_SCHEME(parsed); + if (NativeModule.canBeRequiredByUsers(specifier)) { + return { + url: 'node:' + specifier + }; + } + if (parentURL && StringPrototypeStartsWith(parentURL, 'data:')) { + // This is gonna blow up, we want the error + new URL(specifier, parentURL); + } + + const isMain = parentURL === undefined; + if (isMain) { + parentURL = pathToFileURL(`${process.cwd()}/`).href; + + // This is the initial entry point to the program, and --input-type has + // been passed as an option; but --input-type can only be used with + // --eval, --print or STDIN string input. It is not allowed with file + // input, to avoid user confusion over how expansive the effect of the + // flag should be (i.e. entry point only, package scope surrounding the + // entry point, etc.). + if (typeFlag) + throw new ERR_INPUT_TYPE_NOT_ALLOWED(); + } + + conditions = getConditionsSet(conditions); + let url; + try { + url = moduleResolve(specifier, parentURL, conditions); + } catch (error) { + // Try to give the user a hint of what would have been the + // resolved CommonJS module + if (error.code === 'ERR_MODULE_NOT_FOUND' || + error.code === 'ERR_UNSUPPORTED_DIR_IMPORT') { + if (StringPrototypeStartsWith(specifier, 'file://')) { + specifier = fileURLToPath(specifier); + } + const found = resolveAsCommonJS(specifier, parentURL); + if (found) { + // Modify the stack and message string to include the hint + const lines = StringPrototypeSplit(error.stack, '\n'); + const hint = `Did you mean to import ${found}?`; + error.stack = + ArrayPrototypeShift(lines) + '\n' + + hint + '\n' + + ArrayPrototypeJoin(lines, '\n'); + error.message += `\n${hint}`; + } + } + throw error; + } + + if (isMain ? !preserveSymlinksMain : !preserveSymlinks) { + const urlPath = fileURLToPath(url); + const real = realpathSync(urlPath, { + [internalFS.realpathCacheKey]: realpathCache + }); + const old = url; + url = pathToFileURL( + real + (StringPrototypeEndsWith(urlPath, sep) ? '/' : '')); + url.search = old.search; + url.hash = old.hash; + } + + return { url: `${url}` }; +} + +module.exports = { + DEFAULT_CONDITIONS, + defaultResolve, + encodedSepRegEx, + getPackageType, + packageExportsResolve, + packageImportsResolve +}; + diff --git a/raw/node-repl-await.js b/raw/node-repl-await.js new file mode 100644 index 000000000..b8b9153f4 --- /dev/null +++ b/raw/node-repl-await.js @@ -0,0 +1,252 @@ +// downloaded from https://github.com/nodejs/node/blob/88799930794045795e8abac874730f9eba7e2300/lib/internal/repl/await.js +'use strict'; + +const { + ArrayFrom, + ArrayPrototypeForEach, + ArrayPrototypeIncludes, + ArrayPrototypeJoin, + ArrayPrototypePop, + ArrayPrototypePush, + FunctionPrototype, + ObjectKeys, + RegExpPrototypeSymbolReplace, + StringPrototypeEndsWith, + StringPrototypeIncludes, + StringPrototypeIndexOf, + StringPrototypeRepeat, + StringPrototypeSplit, + StringPrototypeStartsWith, + SyntaxError, +} = primordials; + +const parser = require('internal/deps/acorn/acorn/dist/acorn').Parser; +const walk = require('internal/deps/acorn/acorn-walk/dist/walk'); +const { Recoverable } = require('internal/repl'); + +function isTopLevelDeclaration(state) { + return state.ancestors[state.ancestors.length - 2] === state.body; +} + +const noop = FunctionPrototype; +const visitorsWithoutAncestors = { + ClassDeclaration(node, state, c) { + if (isTopLevelDeclaration(state)) { + state.prepend(node, `${node.id.name}=`); + ArrayPrototypePush( + state.hoistedDeclarationStatements, + `let ${node.id.name}; ` + ); + } + + walk.base.ClassDeclaration(node, state, c); + }, + ForOfStatement(node, state, c) { + if (node.await === true) { + state.containsAwait = true; + } + walk.base.ForOfStatement(node, state, c); + }, + FunctionDeclaration(node, state, c) { + state.prepend(node, `${node.id.name}=`); + ArrayPrototypePush( + state.hoistedDeclarationStatements, + `var ${node.id.name}; ` + ); + }, + FunctionExpression: noop, + ArrowFunctionExpression: noop, + MethodDefinition: noop, + AwaitExpression(node, state, c) { + state.containsAwait = true; + walk.base.AwaitExpression(node, state, c); + }, + ReturnStatement(node, state, c) { + state.containsReturn = true; + walk.base.ReturnStatement(node, state, c); + }, + VariableDeclaration(node, state, c) { + const variableKind = node.kind; + const isIterableForDeclaration = ArrayPrototypeIncludes( + ['ForOfStatement', 'ForInStatement'], + state.ancestors[state.ancestors.length - 2].type + ); + + if (variableKind === 'var' || isTopLevelDeclaration(state)) { + state.replace( + node.start, + node.start + variableKind.length + (isIterableForDeclaration ? 1 : 0), + variableKind === 'var' && isIterableForDeclaration ? + '' : + 'void' + (node.declarations.length === 1 ? '' : ' (') + ); + + if (!isIterableForDeclaration) { + ArrayPrototypeForEach(node.declarations, (decl) => { + state.prepend(decl, '('); + state.append(decl, decl.init ? ')' : '=undefined)'); + }); + + if (node.declarations.length !== 1) { + state.append(node.declarations[node.declarations.length - 1], ')'); + } + } + + const variableIdentifiersToHoist = [ + ['var', []], + ['let', []], + ]; + function registerVariableDeclarationIdentifiers(node) { + switch (node.type) { + case 'Identifier': + ArrayPrototypePush( + variableIdentifiersToHoist[variableKind === 'var' ? 0 : 1][1], + node.name + ); + break; + case 'ObjectPattern': + ArrayPrototypeForEach(node.properties, (property) => { + registerVariableDeclarationIdentifiers(property.value); + }); + break; + case 'ArrayPattern': + ArrayPrototypeForEach(node.elements, (element) => { + registerVariableDeclarationIdentifiers(element); + }); + break; + } + } + + ArrayPrototypeForEach(node.declarations, (decl) => { + registerVariableDeclarationIdentifiers(decl.id); + }); + + ArrayPrototypeForEach( + variableIdentifiersToHoist, + ({ 0: kind, 1: identifiers }) => { + if (identifiers.length > 0) { + ArrayPrototypePush( + state.hoistedDeclarationStatements, + `${kind} ${ArrayPrototypeJoin(identifiers, ', ')}; ` + ); + } + } + ); + } + + walk.base.VariableDeclaration(node, state, c); + } +}; + +const visitors = {}; +for (const nodeType of ObjectKeys(walk.base)) { + const callback = visitorsWithoutAncestors[nodeType] || walk.base[nodeType]; + visitors[nodeType] = (node, state, c) => { + const isNew = node !== state.ancestors[state.ancestors.length - 1]; + if (isNew) { + ArrayPrototypePush(state.ancestors, node); + } + callback(node, state, c); + if (isNew) { + ArrayPrototypePop(state.ancestors); + } + }; +} + +function processTopLevelAwait(src) { + const wrapPrefix = '(async () => { '; + const wrapped = `${wrapPrefix}${src} })()`; + const wrappedArray = ArrayFrom(wrapped); + let root; + try { + root = parser.parse(wrapped, { ecmaVersion: 'latest' }); + } catch (e) { + if (StringPrototypeStartsWith(e.message, 'Unterminated ')) + throw new Recoverable(e); + // If the parse error is before the first "await", then use the execution + // error. Otherwise we must emit this parse error, making it look like a + // proper syntax error. + const awaitPos = StringPrototypeIndexOf(src, 'await'); + const errPos = e.pos - wrapPrefix.length; + if (awaitPos > errPos) + return null; + // Convert keyword parse errors on await into their original errors when + // possible. + if (errPos === awaitPos + 6 && + StringPrototypeIncludes(e.message, 'Expecting Unicode escape sequence')) + return null; + if (errPos === awaitPos + 7 && + StringPrototypeIncludes(e.message, 'Unexpected token')) + return null; + const line = e.loc.line; + const column = line === 1 ? e.loc.column - wrapPrefix.length : e.loc.column; + let message = '\n' + StringPrototypeSplit(src, '\n')[line - 1] + '\n' + + StringPrototypeRepeat(' ', column) + + '^\n\n' + RegExpPrototypeSymbolReplace(/ \([^)]+\)/, e.message, ''); + // V8 unexpected token errors include the token string. + if (StringPrototypeEndsWith(message, 'Unexpected token')) + message += " '" + + // Wrapper end may cause acorn to report error position after the source + (src[e.pos - wrapPrefix.length] ?? src[src.length - 1]) + + "'"; + // eslint-disable-next-line no-restricted-syntax + throw new SyntaxError(message); + } + const body = root.body[0].expression.callee.body; + const state = { + body, + ancestors: [], + hoistedDeclarationStatements: [], + replace(from, to, str) { + for (let i = from; i < to; i++) { + wrappedArray[i] = ''; + } + if (from === to) str += wrappedArray[from]; + wrappedArray[from] = str; + }, + prepend(node, str) { + wrappedArray[node.start] = str + wrappedArray[node.start]; + }, + append(node, str) { + wrappedArray[node.end - 1] += str; + }, + containsAwait: false, + containsReturn: false + }; + + walk.recursive(body, state, visitors); + + // Do not transform if + // 1. False alarm: there isn't actually an await expression. + // 2. There is a top-level return, which is not allowed. + if (!state.containsAwait || state.containsReturn) { + return null; + } + + const last = body.body[body.body.length - 1]; + if (last.type === 'ExpressionStatement') { + // For an expression statement of the form + // ( expr ) ; + // ^^^^^^^^^^ // last + // ^^^^ // last.expression + // + // We do not want the left parenthesis before the `return` keyword; + // therefore we prepend the `return (` to `last`. + // + // On the other hand, we do not want the right parenthesis after the + // semicolon. Since there can only be more right parentheses between + // last.expression.end and the semicolon, appending one more to + // last.expression should be fine. + state.prepend(last, 'return ('); + state.append(last.expression, ')'); + } + + return ( + ArrayPrototypeJoin(state.hoistedDeclarationStatements, '') + + ArrayPrototypeJoin(wrappedArray, '') + ); +} + +module.exports = { + processTopLevelAwait +}; diff --git a/register/files.js b/register/files.js index 93505b69a..9be5bf50d 100644 --- a/register/files.js +++ b/register/files.js @@ -1,3 +1,3 @@ require('../dist').register({ - files: true -}) + files: true, +}); diff --git a/register/index.js b/register/index.js index 63ec2ce5b..456911760 100644 --- a/register/index.js +++ b/register/index.js @@ -1 +1 @@ -require('../').register() +require('../').register(); diff --git a/register/transpile-only.js b/register/transpile-only.js index a42dc27a9..4c526989b 100644 --- a/register/transpile-only.js +++ b/register/transpile-only.js @@ -1,3 +1,3 @@ require('../').register({ - transpileOnly: true -}) + transpileOnly: true, +}); diff --git a/register/type-check.js b/register/type-check.js index 08b410281..3d3c60b5b 100644 --- a/register/type-check.js +++ b/register/type-check.js @@ -1,3 +1,3 @@ require('../').register({ - typeCheck: true -}) + typeCheck: true, +}); diff --git a/screenshot.png b/screenshot.png index cf35ed5fb..620447419 100644 Binary files a/screenshot.png and b/screenshot.png differ diff --git a/scripts/build-pack.js b/scripts/build-pack.js index 38811e99c..ac5e19768 100644 --- a/scripts/build-pack.js +++ b/scripts/build-pack.js @@ -1,20 +1,31 @@ // Written in JS to support Windows // Would otherwise be written as inline bash in package.json script -const { exec } = require('child_process') -const { mkdtempSync, writeFileSync, readFileSync, unlinkSync, rmdirSync, readdirSync } = require('fs') -const { join } = require('path') +const { exec } = require('child_process'); +const { + mkdtempSync, + writeFileSync, + readFileSync, + unlinkSync, + rmdirSync, + readdirSync, +} = require('fs'); +const { join } = require('path'); -const testDir = join(__dirname, '../tests') -const tarballPath = join(testDir, 'ts-node-packed.tgz') -const tempDir = mkdtempSync(join(testDir, 'tmp')) -exec(`npm pack "${join(__dirname, '..')}"`, { cwd: tempDir }, (err, stdout) => { - if (err) { - console.error(err) - process.exit(1) +const testDir = join(__dirname, '../tests'); +const tarballPath = join(testDir, 'ts-node-packed.tgz'); +const tempDir = mkdtempSync(join(testDir, 'tmp')); +exec( + `npm pack --ignore-scripts "${join(__dirname, '..')}"`, + { cwd: tempDir }, + (err, stdout) => { + if (err) { + console.error(err); + process.exit(1); + } + const tempTarballPath = join(tempDir, readdirSync(tempDir)[0]); + writeFileSync(tarballPath, readFileSync(tempTarballPath)); + unlinkSync(tempTarballPath); + rmdirSync(tempDir); } - const tempTarballPath = join(tempDir, readdirSync(tempDir)[0]) - writeFileSync(tarballPath, readFileSync(tempTarballPath)) - unlinkSync(tempTarballPath) - rmdirSync(tempDir) -}) +); diff --git a/scripts/create-merged-schema.ts b/scripts/create-merged-schema.ts index 16aa66fe9..4016fd339 100755 --- a/scripts/create-merged-schema.ts +++ b/scripts/create-merged-schema.ts @@ -7,8 +7,8 @@ */ import axios from 'axios'; -import {resolve} from 'path'; -import {writeFileSync} from 'fs'; +import { resolve } from 'path'; +import { writeFileSync } from 'fs'; async function main() { /** schemastore definition */ @@ -26,27 +26,34 @@ async function main() { properties: { 'ts-node': { ...typescriptNodeSchema.definitions.TsConfigOptions, - description: typescriptNodeSchema.definitions.TsConfigSchema.properties['ts-node'].description, + description: + typescriptNodeSchema.definitions.TsConfigSchema.properties[ + 'ts-node' + ].description, properties: { ...typescriptNodeSchema.definitions.TsConfigOptions.properties, compilerOptions: { - ...typescriptNodeSchema.definitions.TsConfigOptions.properties.compilerOptions, - allOf: [{ - $ref: '#/definitions/compilerOptionsDefinition/properties/compilerOptions' - }] - } - } - } - } + ...typescriptNodeSchema.definitions.TsConfigOptions.properties + .compilerOptions, + allOf: [ + { + $ref: + '#/definitions/compilerOptionsDefinition/properties/compilerOptions', + }, + ], + }, + }, + }, + }, }, }, allOf: [ // Splice into the allOf array at a spot that looks good. Does not affect // behavior of the schema, but looks nicer if we want to submit as a PR to schemastore. ...schemastoreSchema.allOf.slice(0, 4), - { "$ref": "#/definitions/tsNodeDefinition" }, + { $ref: '#/definitions/tsNodeDefinition' }, ...schemastoreSchema.allOf.slice(4), - ] + ], }; writeFileSync( resolve(__dirname, '../tsconfig.schemastore-schema.json'), @@ -55,9 +62,11 @@ async function main() { } export async function getSchemastoreSchema() { - const {data: schemastoreSchema} = await axios.get( + const { + data: schemastoreSchema, + } = await axios.get( 'https://schemastore.azurewebsites.net/schemas/json/tsconfig.json', - { responseType: "json" } + { responseType: 'json' } ); return schemastoreSchema; } diff --git a/scripts/rewrite-coverage-paths.js b/scripts/rewrite-coverage-paths.js deleted file mode 100644 index 8793839cc..000000000 --- a/scripts/rewrite-coverage-paths.js +++ /dev/null @@ -1,26 +0,0 @@ -const {readdirSync, readFileSync, writeFileSync, statSync} = require('fs') -const {resolve, sep} = require('path') -const {mapKeys, each} = require('lodash') - -const fromPrefix = resolve(__dirname, '../tests/node_modules/ts-node') + sep -const toPrefix = resolve(__dirname, '..') + sep - -function rewritePath(input) { - if(input.indexOf(fromPrefix) === 0) { - return toPrefix + input.slice(fromPrefix.length) - } - return input -} - -const nycOutputDir = resolve(__dirname, '../.nyc_output') -for(const filename of readdirSync(nycOutputDir)) { - const filePath = resolve(nycOutputDir, filename) - if(statSync(filePath).isDirectory()) continue - let json = JSON.parse(readFileSync(filePath, 'utf8')) - json = mapKeys(json, (_, key) => rewritePath(key)) - each(json, obj => { - if(obj.path) - obj.path = rewritePath(obj.path) - }) - writeFileSync(filePath, JSON.stringify(json)) -} diff --git a/scripts/update-schemastore-schema-with-compiler-options.ts b/scripts/update-schemastore-schema-with-compiler-options.ts index c4405f39b..25707df94 100644 --- a/scripts/update-schemastore-schema-with-compiler-options.ts +++ b/scripts/update-schemastore-schema-with-compiler-options.ts @@ -23,16 +23,18 @@ * in the TypeStrong org. */ -import {} from 'ts-expose-internals' -import * as ts from 'typescript' -import { getSchemastoreSchema } from './create-merged-schema' +import {} from 'ts-expose-internals'; +import * as ts from 'typescript'; +import { getSchemastoreSchema } from './create-merged-schema'; // Sometimes schemastore becomes out of date with the latest tsconfig options. // This script async function main() { const schemastoreSchema = await getSchemastoreSchema(); - const compilerOptions = schemastoreSchema.definitions.compilerOptionsDefinition.properties.compilerOptions.properties; + const compilerOptions = + schemastoreSchema.definitions.compilerOptionsDefinition.properties + .compilerOptions.properties; // These options are only available via CLI flags, not in a tsconfig file. const excludedOptions = [ @@ -48,10 +50,10 @@ async function main() { 'out', // <-- deprecated ]; - ts.optionDeclarations.forEach(v => { - if(excludedOptions.includes(v.name)) return; + ts.optionDeclarations.forEach((v) => { + if (excludedOptions.includes(v.name)) return; - if(!compilerOptions[v.name]) { + if (!compilerOptions[v.name]) { compilerOptions[v.name] = { description: v.description?.message, type: v.type, @@ -60,9 +62,7 @@ async function main() { }); // Don't write to a file; this is not part of our build process - console.log( - JSON.stringify(schemastoreSchema, null, 2) - ); + console.log(JSON.stringify(schemastoreSchema, null, 2)); } main(); diff --git a/src/bin-cwd.ts b/src/bin-cwd.ts new file mode 100644 index 000000000..bd2f4483c --- /dev/null +++ b/src/bin-cwd.ts @@ -0,0 +1,5 @@ +#!/usr/bin/env node + +import { main } from './bin'; + +main(undefined, { '--cwd-mode': true }); diff --git a/src/bin-script-deprecated.ts b/src/bin-script-deprecated.ts index 6c0dc6f82..07112d85b 100644 --- a/src/bin-script-deprecated.ts +++ b/src/bin-script-deprecated.ts @@ -1,10 +1,10 @@ #!/usr/bin/env node -import { main } from './bin' +import { main } from './bin'; console.warn( 'ts-script has been deprecated and will be removed in the next major release.', 'Please use ts-node-script instead' -) +); -main(['--script-mode', ...process.argv.slice(2)]) +main(undefined, { '--script-mode': true }); diff --git a/src/bin-script.ts b/src/bin-script.ts index 66e1113ee..78f9ab320 100644 --- a/src/bin-script.ts +++ b/src/bin-script.ts @@ -1,5 +1,5 @@ #!/usr/bin/env node -import { main } from './bin' +import { main } from './bin'; -main(['--script-mode', ...process.argv.slice(2)]) +main(undefined, { '--script-mode': true }); diff --git a/src/bin-transpile.ts b/src/bin-transpile.ts index 241c15f43..8eb818146 100644 --- a/src/bin-transpile.ts +++ b/src/bin-transpile.ts @@ -1,5 +1,5 @@ #!/usr/bin/env node -import { main } from './bin' +import { main } from './bin'; -main(['--transpile-only', ...process.argv.slice(2)]) +main(undefined, { '--transpile-only': true }); diff --git a/src/bin.ts b/src/bin.ts index 13c19c38a..43974b046 100644 --- a/src/bin.ts +++ b/src/bin.ts @@ -1,95 +1,108 @@ #!/usr/bin/env node -import { join, resolve, dirname } from 'path' -import { start, Recoverable } from 'repl' -import { inspect } from 'util' -import Module = require('module') -import arg = require('arg') -import { diffLines } from 'diff' -import { Script } from 'vm' -import { readFileSync, statSync, realpathSync } from 'fs' -import { homedir } from 'os' -import { VERSION, TSError, parse, Register, register } from './index' - -/** - * Eval filename for REPL/debug. - */ -const EVAL_FILENAME = `[eval].ts` - -/** - * Eval state management. - */ -class EvalState { - input = '' - output = '' - version = 0 - lines = 0 - - constructor (public path: string) {} -} +import { join, resolve, dirname, parse as parsePath } from 'path'; +import { inspect } from 'util'; +import Module = require('module'); +import arg = require('arg'); +import { parse, createRequire, hasOwnProperty } from './util'; +import { + EVAL_FILENAME, + EvalState, + createRepl, + ReplService, + setupContext, + STDIN_FILENAME, + EvalAwarePartialHost, + EVAL_NAME, + STDIN_NAME, + REPL_FILENAME, +} from './repl'; +import { VERSION, TSError, register } from './index'; +import type { TSInternal } from './ts-compiler-types'; +import { addBuiltinLibsToObject } from '../dist-raw/node-cjs-helpers'; /** * Main `bin` functionality. */ -export function main (argv: string[]) { - const args = arg({ - // Node.js-like options. - '--eval': String, - '--interactive': Boolean, - '--print': Boolean, - '--require': [String], - - // CLI options. - '--help': Boolean, - '--script-mode': Boolean, - '--version': arg.COUNT, - - // Project options. - '--dir': String, - '--files': Boolean, - '--compiler': String, - '--compiler-options': parse, - '--project': String, - '--ignore-diagnostics': [String], - '--ignore': [String], - '--transpile-only': Boolean, - '--type-check': Boolean, - '--compiler-host': Boolean, - '--pretty': Boolean, - '--skip-project': Boolean, - '--skip-ignore': Boolean, - '--prefer-ts-exts': Boolean, - '--log-error': Boolean, - '--emit': Boolean, - - // Aliases. - '-e': '--eval', - '-i': '--interactive', - '-p': '--print', - '-r': '--require', - '-h': '--help', - '-s': '--script-mode', - '-v': '--version', - '-T': '--transpile-only', - '-H': '--compiler-host', - '-I': '--ignore', - '-P': '--project', - '-C': '--compiler', - '-D': '--ignore-diagnostics', - '-O': '--compiler-options' - }, { - argv, - stopAtPositional: true - }) +export function main( + argv: string[] = process.argv.slice(2), + entrypointArgs: Record = {} +) { + const args = { + ...entrypointArgs, + ...arg( + { + // Node.js-like options. + '--eval': String, + '--interactive': Boolean, + '--print': Boolean, + '--require': [String], + + // CLI options. + '--help': Boolean, + '--cwd-mode': Boolean, + '--script-mode': Boolean, + '--version': arg.COUNT, + '--show-config': Boolean, + + // Project options. + '--cwd': String, + '--files': Boolean, + '--compiler': String, + '--compiler-options': parse, + '--project': String, + '--ignore-diagnostics': [String], + '--ignore': [String], + '--transpile-only': Boolean, + '--transpiler': String, + '--type-check': Boolean, + '--compiler-host': Boolean, + '--pretty': Boolean, + '--skip-project': Boolean, + '--skip-ignore': Boolean, + '--prefer-ts-exts': Boolean, + '--log-error': Boolean, + '--emit': Boolean, + '--scope': Boolean, + '--scope-dir': String, + '--no-experimental-repl-await': Boolean, + + // Aliases. + '-e': '--eval', + '-i': '--interactive', + '-p': '--print', + '-r': '--require', + '-h': '--help', + '-s': '--script-mode', + '-v': '--version', + '-T': '--transpile-only', + '-H': '--compiler-host', + '-I': '--ignore', + '-P': '--project', + '-C': '--compiler', + '-D': '--ignore-diagnostics', + '-O': '--compiler-options', + '--dir': '--cwd', + '--showConfig': '--show-config', + '--scopeDir': '--scope-dir', + }, + { + argv, + stopAtPositional: true, + } + ), + }; // Only setting defaults for CLI-specific flags // Anything passed to `register()` can be `undefined`; `create()` will apply // defaults. const { - '--dir': dir, + '--cwd': cwdArg, '--help': help = false, - '--script-mode': scriptMode = false, + '--script-mode': scriptMode, + '--cwd-mode': cwdMode, '--version': version = 0, + '--show-config': showConfig, '--require': argsRequire = [], '--eval': code = undefined, '--print': print = false, @@ -102,14 +115,18 @@ export function main (argv: string[]) { '--ignore': ignore, '--transpile-only': transpileOnly, '--type-check': typeCheck, + '--transpiler': transpiler, '--compiler-host': compilerHost, '--pretty': pretty, '--skip-project': skipProject, '--skip-ignore': skipIgnore, '--prefer-ts-exts': preferTsExts, '--log-error': logError, - '--emit': emit - } = args + '--emit': emit, + '--scope': scope = undefined, + '--scope-dir': scopeDir = undefined, + '--no-experimental-repl-await': noExperimentalReplAwait, + } = args; if (help) { console.log(` @@ -117,59 +134,132 @@ export function main (argv: string[]) { Options: - -e, --eval [code] Evaluate code - -p, --print Print result of \`--eval\` - -r, --require [path] Require a node module before execution - -i, --interactive Opens the REPL even if stdin does not appear to be a terminal - - -h, --help Print CLI usage - -v, --version Print module version information - -s, --script-mode Use cwd from instead of current directory - - -T, --transpile-only Use TypeScript's faster \`transpileModule\` - -H, --compiler-host Use TypeScript's compiler host API - -I, --ignore [pattern] Override the path patterns to skip compilation - -P, --project [path] Path to TypeScript JSON project file - -C, --compiler [name] Specify a custom TypeScript compiler + -e, --eval [code] Evaluate code + -p, --print Print result of \`--eval\` + -r, --require [path] Require a node module before execution + -i, --interactive Opens the REPL even if stdin does not appear to be a terminal + + -h, --help Print CLI usage + -v, --version Print module version information + --cwd-mode Use current directory instead of for config resolution + --show-config Print resolved configuration and exit + + -T, --transpile-only Use TypeScript's faster \`transpileModule\` or a third-party transpiler + -H, --compiler-host Use TypeScript's compiler host API + -I, --ignore [pattern] Override the path patterns to skip compilation + -P, --project [path] Path to TypeScript JSON project file + -C, --compiler [name] Specify a custom TypeScript compiler + --transpiler [name] Specify a third-party, non-typechecking transpiler -D, --ignore-diagnostics [code] Ignore TypeScript warnings by diagnostic code -O, --compiler-options [opts] JSON object to merge with compiler options - --dir Specify working directory for config resolution - --scope Scope compiler to files within \`cwd\` only - --files Load \`files\`, \`include\` and \`exclude\` from \`tsconfig.json\` on startup - --pretty Use pretty diagnostic formatter (usually enabled by default) - --skip-project Skip reading \`tsconfig.json\` - --skip-ignore Skip \`--ignore\` checks - --prefer-ts-exts Prefer importing TypeScript files over JavaScript files - --log-error Logs TypeScript errors to stderr instead of throwing exceptions - `) - - process.exit(0) + --cwd Behave as if invoked within this working directory. + --files Load \`files\`, \`include\` and \`exclude\` from \`tsconfig.json\` on startup + --pretty Use pretty diagnostic formatter (usually enabled by default) + --skip-project Skip reading \`tsconfig.json\` + --skip-ignore Skip \`--ignore\` checks + --scope Scope compiler to files within \`scopeDir\`. Anything outside this directory is ignored. + --scope-dir Directory for \`--scope\` + --prefer-ts-exts Prefer importing TypeScript files over JavaScript files + --log-error Logs TypeScript errors to stderr instead of throwing exceptions + --no-experimental-repl-await Disable top-level await in REPL. Equivalent to node's --no-experimental-repl-await + `); + + process.exit(0); } // Output project information. if (version === 1) { - console.log(`v${VERSION}`) - process.exit(0) + console.log(`v${VERSION}`); + process.exit(0); } - const cwd = dir || process.cwd() + // Figure out which we are executing: piped stdin, --eval, REPL, and/or entrypoint + // This is complicated because node's behavior is complicated + // `node -e code -i ./script.js` ignores -e + const executeEval = code != null && !(interactive && args._.length); + const executeEntrypoint = !executeEval && args._.length > 0; + const executeRepl = + !executeEntrypoint && + (interactive || (process.stdin.isTTY && !executeEval)); + const executeStdin = !executeEval && !executeRepl && !executeEntrypoint; + + const cwd = cwdArg || process.cwd(); /** Unresolved. May point to a symlink, not realpath. May be missing file extension */ - const scriptPath = args._.length ? resolve(cwd, args._[0]) : undefined - const state = new EvalState(scriptPath || join(cwd, EVAL_FILENAME)) + const scriptPath = executeEntrypoint ? resolve(cwd, args._[0]) : undefined; + + /** + * , [stdin], and [eval] are all essentially virtual files that do not exist on disc and are backed by a REPL + * service to handle eval-ing of code. + */ + interface VirtualFileState { + state: EvalState; + repl: ReplService; + module?: Module; + } + let evalStuff: VirtualFileState | undefined; + let replStuff: VirtualFileState | undefined; + let stdinStuff: VirtualFileState | undefined; + let evalAwarePartialHost: EvalAwarePartialHost | undefined = undefined; + if (executeEval) { + const state = new EvalState(join(cwd, EVAL_FILENAME)); + evalStuff = { + state, + repl: createRepl({ + state, + composeWithEvalAwarePartialHost: evalAwarePartialHost, + ignoreDiagnosticsThatAreAnnoyingInInteractiveRepl: false, + }), + }; + ({ evalAwarePartialHost } = evalStuff.repl); + // Create a local module instance based on `cwd`. + const module = (evalStuff.module = new Module(EVAL_NAME)); + module.filename = evalStuff.state.path; + module.paths = (Module as any)._nodeModulePaths(cwd); + } + if (executeStdin) { + const state = new EvalState(join(cwd, STDIN_FILENAME)); + stdinStuff = { + state, + repl: createRepl({ + state, + composeWithEvalAwarePartialHost: evalAwarePartialHost, + ignoreDiagnosticsThatAreAnnoyingInInteractiveRepl: false, + }), + }; + ({ evalAwarePartialHost } = stdinStuff.repl); + // Create a local module instance based on `cwd`. + const module = (stdinStuff.module = new Module(STDIN_NAME)); + module.filename = stdinStuff.state.path; + module.paths = (Module as any)._nodeModulePaths(cwd); + } + if (executeRepl) { + const state = new EvalState(join(cwd, REPL_FILENAME)); + replStuff = { + state, + repl: createRepl({ + state, + composeWithEvalAwarePartialHost: evalAwarePartialHost, + }), + }; + ({ evalAwarePartialHost } = replStuff.repl); + } // Register the TypeScript compiler instance. const service = register({ - dir: getCwd(dir, scriptMode, scriptPath), + cwd, emit, files, pretty, - transpileOnly, + transpileOnly: transpileOnly ?? transpiler != null ? true : undefined, + experimentalReplAwait: noExperimentalReplAwait ? false : undefined, typeCheck, + transpiler, compilerHost, ignore, preferTsExts, logError, + projectSearchDir: getProjectSearchDir(cwd, scriptMode, cwdMode, scriptPath), project, skipProject, skipIgnore, @@ -177,80 +267,124 @@ export function main (argv: string[]) { ignoreDiagnostics, compilerOptions, require: argsRequire, - readFile: code !== undefined - ? (path: string) => { - if (path === state.path) return state.input + readFile: evalAwarePartialHost?.readFile ?? undefined, + fileExists: evalAwarePartialHost?.fileExists ?? undefined, + scope, + scopeDir, + }); - try { - return readFileSync(path, 'utf8') - } catch (err) {/* Ignore. */} - } - : undefined, - fileExists: code !== undefined - ? (path: string) => { - if (path === state.path) return true - - try { - const stats = statSync(path) - return stats.isFile() || stats.isFIFO() - } catch (err) { - return false - } - } - : undefined - }) + // Bind REPL service to ts-node compiler service (chicken-and-egg problem) + replStuff?.repl.setService(service); + evalStuff?.repl.setService(service); + stdinStuff?.repl.setService(service); // Output project information. if (version >= 2) { - console.log(`ts-node v${VERSION}`) - console.log(`node ${process.version}`) - console.log(`compiler v${service.ts.version}`) - process.exit(0) + console.log(`ts-node v${VERSION}`); + console.log(`node ${process.version}`); + console.log(`compiler v${service.ts.version}`); + process.exit(0); } - // Create a local module instance based on `cwd`. - const module = new Module(state.path) - module.filename = state.path - module.paths = (Module as any)._nodeModulePaths(cwd) + if (showConfig) { + const ts = (service.ts as any) as TSInternal; + if (typeof ts.convertToTSConfig !== 'function') { + console.error( + 'Error: --show-config requires a typescript versions >=3.2 that support --showConfig' + ); + process.exit(1); + } + const json = { + ['ts-node']: { + ...service.options, + optionBasePaths: undefined, + experimentalEsmLoader: undefined, + compilerOptions: undefined, + project: service.configFilePath ?? service.options.project, + }, + ...ts.convertToTSConfig( + service.config, + service.configFilePath ?? join(cwd, 'ts-node-implicit-tsconfig.json'), + service.ts.sys + ), + }; + console.log( + // Assumes that all configuration options which can possibly be specified via the CLI are JSON-compatible. + // If, in the future, we must log functions, for example readFile and fileExists, then we can implement a JSON + // replacer function. + JSON.stringify(json, null, 2) + ); + process.exit(0); + } // Prepend `ts-node` arguments to CLI for child processes. - process.execArgv.unshift(__filename, ...process.argv.slice(2, process.argv.length - args._.length)) - process.argv = [process.argv[1]].concat(scriptPath || []).concat(args._.slice(1)) + process.execArgv.unshift( + __filename, + ...process.argv.slice(2, process.argv.length - args._.length) + ); + process.argv = [process.argv[1]] + .concat(executeEntrypoint ? ([scriptPath] as string[]) : []) + .concat(args._.slice(executeEntrypoint ? 1 : 0)); // Execute the main contents (either eval, script or piped). - if (code !== undefined && !interactive) { - evalAndExit(service, state, module, code, print) + if (executeEntrypoint) { + Module.runMain(); } else { - if (args._.length) { - Module.runMain() - } else { - // Piping of execution _only_ occurs when no other script is specified. - // --interactive flag forces REPL - if (interactive || process.stdin.isTTY) { - startRepl(service, state, code) - } else { - let buffer = code || '' - process.stdin.on('data', (chunk: Buffer) => buffer += chunk) - process.stdin.on('end', () => evalAndExit(service, state, module, buffer, print)) - } + // Note: eval and repl may both run, but never with stdin. + // If stdin runs, eval and repl will not. + if (executeEval) { + addBuiltinLibsToObject(global); + evalAndExitOnTsError( + evalStuff!.repl, + evalStuff!.module!, + code!, + print, + 'eval' + ); } - } -} -/** - * Get project path from args. - */ -function getCwd (dir?: string, scriptMode?: boolean, scriptPath?: string) { - // Validate `--script-mode` usage is correct. - if (scriptMode) { - if (!scriptPath) { - throw new TypeError('Script mode must be used with a script name, e.g. `ts-node -s `') + if (executeRepl) { + replStuff!.repl.start(); } - if (dir) { - throw new TypeError('Script mode cannot be combined with `--dir`') + if (executeStdin) { + let buffer = code || ''; + process.stdin.on('data', (chunk: Buffer) => (buffer += chunk)); + process.stdin.on('end', () => { + evalAndExitOnTsError( + stdinStuff!.repl, + stdinStuff!.module!, + buffer, + // `echo 123 | node -p` still prints 123 + print, + 'stdin' + ); + }); } + } +} +/** + * Get project search path from args. + */ +function getProjectSearchDir( + cwd?: string, + scriptMode?: boolean, + cwdMode?: boolean, + scriptPath?: string +) { + // Validate `--script-mode` / `--cwd-mode` / `--cwd` usage is correct. + if (scriptMode && cwdMode) { + throw new TypeError('--cwd-mode cannot be combined with --script-mode'); + } + if (scriptMode && !scriptPath) { + throw new TypeError( + '--script-mode must be used with a script name, e.g. `ts-node --script-mode `' + ); + } + const doScriptMode = + scriptMode === true ? true : cwdMode === true ? false : !!scriptPath; + if (doScriptMode) { // Use node's own resolution behavior to ensure we follow symlinks. // scriptPath may omit file extension or point to a directory with or without package.json. // This happens before we are registered, so we tell node's resolver to consider ts, tsx, and jsx files. @@ -258,256 +392,92 @@ function getCwd (dir?: string, scriptMode?: boolean, scriptPath?: string) { // because we do not yet know preferTsExts, jsx, nor allowJs. // See also, justification why this will not happen in real-world situations: // https://github.com/TypeStrong/ts-node/pull/1009#issuecomment-613017081 - const exts = ['.js', '.jsx', '.ts', '.tsx'] - const extsTemporarilyInstalled: string[] = [] + const exts = ['.js', '.jsx', '.ts', '.tsx']; + const extsTemporarilyInstalled: string[] = []; for (const ext of exts) { - if (!hasOwnProperty(require.extensions, ext)) { // tslint:disable-line - extsTemporarilyInstalled.push(ext) - require.extensions[ext] = function() {} // tslint:disable-line + if (!hasOwnProperty(require.extensions, ext)) { + extsTemporarilyInstalled.push(ext); + require.extensions[ext] = function () {}; } } try { - return dirname(require.resolve(scriptPath)) + return dirname(requireResolveNonCached(scriptPath!)); } finally { for (const ext of extsTemporarilyInstalled) { - delete require.extensions[ext] // tslint:disable-line + delete require.extensions[ext]; } } } - return dir + return cwd; } -/** - * Evaluate a script. - */ -function evalAndExit (service: Register, state: EvalState, module: Module, code: string, isPrinted: boolean) { - let result: any - - ;(global as any).__filename = module.filename - ;(global as any).__dirname = dirname(module.filename) - ;(global as any).exports = module.exports - ;(global as any).module = module - ;(global as any).require = module.require.bind(module) - - try { - result = _eval(service, state, code) - } catch (error) { - if (error instanceof TSError) { - console.error(error) - process.exit(1) - } - - throw error - } - - if (isPrinted) { - console.log(typeof result === 'string' ? result : inspect(result)) - } -} - -/** - * Evaluate the code snippet. - */ -function _eval (service: Register, state: EvalState, input: string) { - const lines = state.lines - const isCompletion = !/\n$/.test(input) - const undo = appendEval(state, input) - let output: string - - try { - output = service.compile(state.input, state.path, -lines) - } catch (err) { - undo() - throw err - } - - // Use `diff` to check for new JavaScript to execute. - const changes = diffLines(state.output, output) - - if (isCompletion) { - undo() - } else { - state.output = output - } - - return changes.reduce((result, change) => { - return change.added ? exec(change.value, state.path) : result - }, undefined) -} +const guaranteedNonexistentDirectoryPrefix = resolve(__dirname, 'doesnotexist'); +let guaranteedNonexistentDirectorySuffix = 0; /** - * Execute some code. + * require.resolve an absolute path, tricking node into *not* caching the results. + * Necessary so that we do not pollute require.resolve cache prior to installing require.extensions + * + * Is a terrible hack, because node does not expose the necessary cache invalidation APIs + * https://stackoverflow.com/questions/59865584/how-to-invalidate-cached-require-resolve-results */ -function exec (code: string, filename: string) { - const script = new Script(code, { filename: filename }) - - return script.runInThisContext() +function requireResolveNonCached(absoluteModuleSpecifier: string) { + // node 10 and 11 fallback: The trick below triggers a node 10 & 11 bug + // On those node versions, pollute the require cache instead. This is a deliberate + // ts-node limitation that will *rarely* manifest, and will not matter once node 10 + // is end-of-life'd on 2021-04-30 + const isSupportedNodeVersion = + parseInt(process.versions.node.split('.')[0], 10) >= 12; + if (!isSupportedNodeVersion) return require.resolve(absoluteModuleSpecifier); + + const { dir, base } = parsePath(absoluteModuleSpecifier); + const relativeModuleSpecifier = `./${base}`; + + const req = createRequire( + join(dir, 'imaginaryUncacheableRequireResolveScript') + ); + return req.resolve(relativeModuleSpecifier, { + paths: [ + `${guaranteedNonexistentDirectoryPrefix}${guaranteedNonexistentDirectorySuffix++}`, + ...(req.resolve.paths(relativeModuleSpecifier) || []), + ], + }); } /** - * Start a CLI REPL. + * Evaluate an [eval] or [stdin] script */ -function startRepl (service: Register, state: EvalState, code?: string) { - // Eval incoming code before the REPL starts. - if (code) { - try { - _eval(service, state, `${code}\n`) - } catch (err) { - console.error(err) - process.exit(1) - } - } - - const repl = start({ - prompt: '> ', - input: process.stdin, - output: process.stdout, - // Mimicking node's REPL implementation: https://github.com/nodejs/node/blob/168b22ba073ee1cbf8d0bcb4ded7ff3099335d04/lib/internal/repl.js#L28-L30 - terminal: process.stdout.isTTY && !parseInt(process.env.NODE_NO_READLINE!, 10), - eval: replEval, - useGlobal: true - }) - - /** - * Eval code from the REPL. - */ - function replEval (code: string, _context: any, _filename: string, callback: (err: Error | null, result?: any) => any) { - let err: Error | null = null - let result: any - - // TODO: Figure out how to handle completion here. - if (code === '.scope') { - callback(err) - return - } - - try { - result = _eval(service, state, code) - } catch (error) { - if (error instanceof TSError) { - // Support recoverable compilations using >= node 6. - if (Recoverable && isRecoverable(error)) { - err = new Recoverable(error) - } else { - console.error(error) - } - } else { - err = error - } - } - - return callback(err, result) - } - - // Bookmark the point where we should reset the REPL state. - const resetEval = appendEval(state, '') - - function reset () { - resetEval() - - // Hard fix for TypeScript forcing `Object.defineProperty(exports, ...)`. - exec('exports = module.exports', state.path) - } - - reset() - repl.on('reset', reset) - - repl.defineCommand('type', { - help: 'Check the type of a TypeScript identifier', - action: function (identifier: string) { - if (!identifier) { - repl.displayPrompt() - return - } - - const undo = appendEval(state, identifier) - const { name, comment } = service.getTypeInfo(state.input, state.path, state.input.length) - - undo() +function evalAndExitOnTsError( + replService: ReplService, + module: Module, + code: string, + isPrinted: boolean, + filenameAndDirname: 'eval' | 'stdin' +) { + let result: any; + setupContext(global, module, filenameAndDirname); - if (name) repl.outputStream.write(`${name}\n`) - if (comment) repl.outputStream.write(`${comment}\n`) - repl.displayPrompt() + try { + result = replService.evalCode(code); + } catch (error) { + if (error instanceof TSError) { + console.error(error); + process.exit(1); } - }) - - // Set up REPL history when available natively via node.js >= 11. - if (repl.setupHistory) { - const historyPath = process.env.TS_NODE_HISTORY || join(homedir(), '.ts_node_repl_history') - - repl.setupHistory(historyPath, err => { - if (!err) return - - console.error(err) - process.exit(1) - }) - } -} -/** - * Append to the eval instance and return an undo function. - */ -function appendEval (state: EvalState, input: string) { - const undoInput = state.input - const undoVersion = state.version - const undoOutput = state.output - const undoLines = state.lines - - // Handle ASI issues with TypeScript re-evaluation. - if (undoInput.charAt(undoInput.length - 1) === '\n' && /^\s*[\/\[(`-]/.test(input) && !/;\s*$/.test(undoInput)) { - state.input = `${state.input.slice(0, -1)};\n` + throw error; } - state.input += input - state.lines += lineCount(input) - state.version++ - - return function () { - state.input = undoInput - state.output = undoOutput - state.version = undoVersion - state.lines = undoLines - } -} - -/** - * Count the number of lines. - */ -function lineCount (value: string) { - let count = 0 - - for (const char of value) { - if (char === '\n') { - count++ - } + if (isPrinted) { + console.log( + typeof result === 'string' + ? result + : inspect(result, { colors: process.stdout.isTTY }) + ); } - - return count -} - -const RECOVERY_CODES: Set = new Set([ - 1003, // "Identifier expected." - 1005, // "')' expected." - 1109, // "Expression expected." - 1126, // "Unexpected end of text." - 1160, // "Unterminated template literal." - 1161, // "Unterminated regular expression literal." - 2355 // "A function whose declared type is neither 'void' nor 'any' must return a value." -]) - -/** - * Check if a function can recover gracefully. - */ -function isRecoverable (error: TSError) { - return error.diagnosticCodes.every(code => RECOVERY_CODES.has(code)) -} - -/** Safe `hasOwnProperty` */ -function hasOwnProperty (object: any, property: string): boolean { - return Object.prototype.hasOwnProperty.call(object, property) } if (require.main === module) { - main(process.argv.slice(2)) + main(); } diff --git a/src/configuration.ts b/src/configuration.ts new file mode 100644 index 000000000..6bc8e1113 --- /dev/null +++ b/src/configuration.ts @@ -0,0 +1,303 @@ +import { resolve, dirname } from 'path'; +import type * as _ts from 'typescript'; +import { + CreateOptions, + DEFAULTS, + OptionBasePaths, + TSCommon, + TsConfigOptions, +} from './index'; +import type { TSInternal } from './ts-compiler-types'; +import { createTsInternals } from './ts-internals'; +import { getDefaultTsconfigJsonForNodeVersion } from './tsconfigs'; +import { assign, createRequire, trace } from './util'; + +/** + * TypeScript compiler option values required by `ts-node` which cannot be overridden. + */ +const TS_NODE_COMPILER_OPTIONS = { + sourceMap: true, + inlineSourceMap: false, + inlineSources: true, + declaration: false, + noEmit: false, + outDir: '.ts-node', +}; + +/* + * Do post-processing on config options to support `ts-node`. + */ +function fixConfig(ts: TSCommon, config: _ts.ParsedCommandLine) { + // Delete options that *should not* be passed through. + delete config.options.out; + delete config.options.outFile; + delete config.options.composite; + delete config.options.declarationDir; + delete config.options.declarationMap; + delete config.options.emitDeclarationOnly; + + // Target ES5 output by default (instead of ES3). + if (config.options.target === undefined) { + config.options.target = ts.ScriptTarget.ES5; + } + + // Target CommonJS modules by default (instead of magically switching to ES6 when the target is ES6). + if (config.options.module === undefined) { + config.options.module = ts.ModuleKind.CommonJS; + } + + return config; +} + +/** + * Load TypeScript configuration. Returns the parsed TypeScript config and + * any `ts-node` options specified in the config file. + * + * Even when a tsconfig.json is not loaded, this function still handles merging + * compilerOptions from various sources: API, environment variables, etc. + * + * @internal + */ +export function readConfig( + cwd: string, + ts: TSCommon, + rawApiOptions: CreateOptions +): { + /** + * Path of tsconfig file if one was loaded + */ + configFilePath: string | undefined; + /** + * Parsed TypeScript configuration with compilerOptions merged from all other sources (env vars, etc) + */ + config: _ts.ParsedCommandLine; + /** + * ts-node options pulled from `tsconfig.json`, NOT merged with any other sources. Merging must happen outside + * this function. + */ + tsNodeOptionsFromTsconfig: TsConfigOptions; + optionBasePaths: OptionBasePaths; +} { + // Ordered [a, b, c] where config a extends b extends c + const configChain: Array<{ + config: any; + basePath: string; + configPath: string; + }> = []; + let config: any = { compilerOptions: {} }; + let basePath = cwd; + let configFilePath: string | undefined = undefined; + const projectSearchDir = resolve(cwd, rawApiOptions.projectSearchDir ?? cwd); + + const { + fileExists = ts.sys.fileExists, + readFile = ts.sys.readFile, + skipProject = DEFAULTS.skipProject, + project = DEFAULTS.project, + } = rawApiOptions; + + // Read project configuration when available. + if (!skipProject) { + configFilePath = project + ? resolve(cwd, project) + : ts.findConfigFile(projectSearchDir, fileExists); + + if (configFilePath) { + let pathToNextConfigInChain = configFilePath; + const tsInternals = createTsInternals(ts); + const errors: Array<_ts.Diagnostic> = []; + + // Follow chain of "extends" + while (true) { + const result = ts.readConfigFile(pathToNextConfigInChain, readFile); + + // Return diagnostics. + if (result.error) { + return { + configFilePath, + config: { errors: [result.error], fileNames: [], options: {} }, + tsNodeOptionsFromTsconfig: {}, + optionBasePaths: {}, + }; + } + + const c = result.config; + const bp = dirname(pathToNextConfigInChain); + configChain.push({ + config: c, + basePath: bp, + configPath: pathToNextConfigInChain, + }); + + if (c.extends == null) break; + const resolvedExtendedConfigPath = tsInternals.getExtendsConfigPath( + c.extends, + { + fileExists, + readDirectory: ts.sys.readDirectory, + readFile, + useCaseSensitiveFileNames: ts.sys.useCaseSensitiveFileNames, + trace, + }, + bp, + errors, + ((ts as unknown) as TSInternal).createCompilerDiagnostic + ); + if (errors.length) { + return { + configFilePath, + config: { errors, fileNames: [], options: {} }, + tsNodeOptionsFromTsconfig: {}, + optionBasePaths: {}, + }; + } + if (resolvedExtendedConfigPath == null) break; + pathToNextConfigInChain = resolvedExtendedConfigPath; + } + + ({ config, basePath } = configChain[0]); + } + } + + // Merge and fix ts-node options that come from tsconfig.json(s) + const tsNodeOptionsFromTsconfig: TsConfigOptions = {}; + const optionBasePaths: OptionBasePaths = {}; + for (let i = configChain.length - 1; i >= 0; i--) { + const { config, basePath, configPath } = configChain[i]; + const options = filterRecognizedTsConfigTsNodeOptions(config['ts-node']) + .recognized; + + // Some options are relative to the config file, so must be converted to absolute paths here + if (options.require) { + // Modules are found relative to the tsconfig file, not the `dir` option + const tsconfigRelativeRequire = createRequire(configPath); + options.require = options.require.map((path: string) => + tsconfigRelativeRequire.resolve(path) + ); + } + if (options.scopeDir) { + options.scopeDir = resolve(basePath, options.scopeDir!); + } + + // Downstream code uses the basePath; we do not do that here. + if (options.moduleTypes) { + optionBasePaths.moduleTypes = basePath; + } + + assign(tsNodeOptionsFromTsconfig, options); + } + + // Remove resolution of "files". + const files = + rawApiOptions.files ?? tsNodeOptionsFromTsconfig.files ?? DEFAULTS.files; + if (!files) { + config.files = []; + config.include = []; + } + + // Only if a config file is *not* loaded, load an implicit configuration from @tsconfig/bases + const skipDefaultCompilerOptions = configFilePath != null; + const defaultCompilerOptionsForNodeVersion = skipDefaultCompilerOptions + ? undefined + : { + ...getDefaultTsconfigJsonForNodeVersion(ts).compilerOptions, + types: ['node'], + }; + + // Merge compilerOptions from all sources + config.compilerOptions = Object.assign( + {}, + // automatically-applied options from @tsconfig/bases + defaultCompilerOptionsForNodeVersion, + // tsconfig.json "compilerOptions" + config.compilerOptions, + // from env var + DEFAULTS.compilerOptions, + // tsconfig.json "ts-node": "compilerOptions" + tsNodeOptionsFromTsconfig.compilerOptions, + // passed programmatically + rawApiOptions.compilerOptions, + // overrides required by ts-node, cannot be changed + TS_NODE_COMPILER_OPTIONS + ); + + const fixedConfig = fixConfig( + ts, + ts.parseJsonConfigFileContent( + config, + { + fileExists, + readFile, + readDirectory: ts.sys.readDirectory, + useCaseSensitiveFileNames: ts.sys.useCaseSensitiveFileNames, + }, + basePath, + undefined, + configFilePath + ) + ); + + return { + configFilePath, + config: fixedConfig, + tsNodeOptionsFromTsconfig, + optionBasePaths, + }; +} + +/** + * Given the raw "ts-node" sub-object from a tsconfig, return an object with only the properties + * recognized by "ts-node" + */ +function filterRecognizedTsConfigTsNodeOptions( + jsonObject: any +): { recognized: TsConfigOptions; unrecognized: any } { + if (jsonObject == null) return { recognized: {}, unrecognized: {} }; + const { + compiler, + compilerHost, + compilerOptions, + emit, + files, + ignore, + ignoreDiagnostics, + logError, + preferTsExts, + pretty, + require, + skipIgnore, + transpileOnly, + typeCheck, + transpiler, + scope, + scopeDir, + moduleTypes, + experimentalReplAwait, + ...unrecognized + } = jsonObject as TsConfigOptions; + const filteredTsConfigOptions = { + compiler, + compilerHost, + compilerOptions, + emit, + experimentalReplAwait, + files, + ignore, + ignoreDiagnostics, + logError, + preferTsExts, + pretty, + require, + skipIgnore, + transpileOnly, + typeCheck, + transpiler, + scope, + scopeDir, + moduleTypes, + }; + // Use the typechecker to make sure this implementation has the correct set of properties + const catchExtraneousProps: keyof TsConfigOptions = (null as any) as keyof typeof filteredTsConfigOptions; + const catchMissingProps: keyof typeof filteredTsConfigOptions = (null as any) as keyof TsConfigOptions; + return { recognized: filteredTsConfigOptions, unrecognized }; +} diff --git a/src/esm.ts b/src/esm.ts index a00b2110e..53e14fd71 100644 --- a/src/esm.ts +++ b/src/esm.ts @@ -1,103 +1,150 @@ -import { register, getExtensions, RegisterOptions } from './index' -import { parse as parseUrl, format as formatUrl, UrlWithStringQuery, fileURLToPath, pathToFileURL } from 'url' -import { extname } from 'path' -import * as assert from 'assert' -const { createResolve } = require('../dist-raw/node-esm-resolve-implementation') +import { register, getExtensions, RegisterOptions } from './index'; +import { + parse as parseUrl, + format as formatUrl, + UrlWithStringQuery, + fileURLToPath, + pathToFileURL, +} from 'url'; +import { extname } from 'path'; +import * as assert from 'assert'; +import { normalizeSlashes } from './util'; +const { + createResolve, +} = require('../dist-raw/node-esm-resolve-implementation'); // Note: On Windows, URLs look like this: file:///D:/dev/@TypeStrong/ts-node-examples/foo.ts -export function registerAndCreateEsmHooks (opts?: RegisterOptions) { +export function registerAndCreateEsmHooks(opts?: RegisterOptions) { // Automatically performs registration just like `-r ts-node/register` const tsNodeInstance = register({ ...opts, - experimentalEsmLoader: true - }) + experimentalEsmLoader: true, + }); // Custom implementation that considers additional file extensions and automatically adds file extensions const nodeResolveImplementation = createResolve({ ...getExtensions(tsNodeInstance.config), - preferTsExts: tsNodeInstance.options.preferTsExts - }) + preferTsExts: tsNodeInstance.options.preferTsExts, + }); - return { resolve, getFormat, transformSource } + return { resolve, getFormat, transformSource }; - function isFileUrlOrNodeStyleSpecifier (parsed: UrlWithStringQuery) { + function isFileUrlOrNodeStyleSpecifier(parsed: UrlWithStringQuery) { // We only understand file:// URLs, but in node, the specifier can be a node-style `./foo` or `foo` - const { protocol } = parsed - return protocol === null || protocol === 'file:' + const { protocol } = parsed; + return protocol === null || protocol === 'file:'; } - async function resolve (specifier: string, context: {parentURL: string}, defaultResolve: typeof resolve): Promise<{url: string}> { + async function resolve( + specifier: string, + context: { parentURL: string }, + defaultResolve: typeof resolve + ): Promise<{ url: string }> { const defer = async () => { - const r = await defaultResolve(specifier, context, defaultResolve) - return r - } + const r = await defaultResolve(specifier, context, defaultResolve); + return r; + }; - const parsed = parseUrl(specifier) - const { pathname, protocol, hostname } = parsed + const parsed = parseUrl(specifier); + const { pathname, protocol, hostname } = parsed; if (!isFileUrlOrNodeStyleSpecifier(parsed)) { - return defer() + return defer(); } if (protocol !== null && protocol !== 'file:') { - return defer() + return defer(); } // Malformed file:// URL? We should always see `null` or `''` if (hostname) { // TODO file://./foo sets `hostname` to `'.'`. Perhaps we should special-case this. - return defer() + return defer(); } // pathname is the path to be resolved - return nodeResolveImplementation.defaultResolve(specifier, context, defaultResolve) + return nodeResolveImplementation.defaultResolve( + specifier, + context, + defaultResolve + ); } - type Format = 'builtin' | 'commonjs' | 'dynamic' | 'json' | 'module' | 'wasm' - async function getFormat (url: string, context: {}, defaultGetFormat: typeof getFormat): Promise<{format: Format}> { - const defer = (overrideUrl: string = url) => defaultGetFormat(overrideUrl, context, defaultGetFormat) + type Format = 'builtin' | 'commonjs' | 'dynamic' | 'json' | 'module' | 'wasm'; + async function getFormat( + url: string, + context: {}, + defaultGetFormat: typeof getFormat + ): Promise<{ format: Format }> { + const defer = (overrideUrl: string = url) => + defaultGetFormat(overrideUrl, context, defaultGetFormat); - const parsed = parseUrl(url) + const parsed = parseUrl(url); if (!isFileUrlOrNodeStyleSpecifier(parsed)) { - return defer() + return defer(); } - const { pathname } = parsed - assert(pathname !== null, 'ESM getFormat() hook: URL should never have null pathname') + const { pathname } = parsed; + assert( + pathname !== null, + 'ESM getFormat() hook: URL should never have null pathname' + ); - const nativePath = fileURLToPath(url) + const nativePath = fileURLToPath(url); // If file has .ts, .tsx, or .jsx extension, then ask node how it would treat this file if it were .js - const ext = extname(nativePath) + const ext = extname(nativePath); + let nodeSays: { format: Format }; if (ext !== '.js' && !tsNodeInstance.ignored(nativePath)) { - return defer(formatUrl(pathToFileURL(nativePath + '.js'))) + nodeSays = await defer(formatUrl(pathToFileURL(nativePath + '.js'))); + } else { + nodeSays = await defer(); } - - return defer() + // For files compiled by ts-node that node believes are either CJS or ESM, check if we should override that classification + if ( + !tsNodeInstance.ignored(nativePath) && + (nodeSays.format === 'commonjs' || nodeSays.format === 'module') + ) { + const { moduleType } = tsNodeInstance.moduleTypeClassifier.classifyModule( + normalizeSlashes(nativePath) + ); + if (moduleType === 'cjs') { + return { format: 'commonjs' }; + } else if (moduleType === 'esm') { + return { format: 'module' }; + } + } + return nodeSays; } - async function transformSource (source: string | Buffer, context: {url: string, format: Format}, defaultTransformSource: typeof transformSource): Promise<{source: string | Buffer}> { - const defer = () => defaultTransformSource(source, context, defaultTransformSource) + async function transformSource( + source: string | Buffer, + context: { url: string; format: Format }, + defaultTransformSource: typeof transformSource + ): Promise<{ source: string | Buffer }> { + const defer = () => + defaultTransformSource(source, context, defaultTransformSource); - const sourceAsString = typeof source === 'string' ? source : source.toString('utf8') + const sourceAsString = + typeof source === 'string' ? source : source.toString('utf8'); - const { url } = context - const parsed = parseUrl(url) + const { url } = context; + const parsed = parseUrl(url); if (!isFileUrlOrNodeStyleSpecifier(parsed)) { - return defer() + return defer(); } - const nativePath = fileURLToPath(url) + const nativePath = fileURLToPath(url); if (tsNodeInstance.ignored(nativePath)) { - return defer() + return defer(); } - const emittedJs = tsNodeInstance.compile(sourceAsString, nativePath) + const emittedJs = tsNodeInstance.compile(sourceAsString, nativePath); - return { source: emittedJs } + return { source: emittedJs }; } } diff --git a/src/externs.d.ts b/src/externs.d.ts index d9257bd38..ebc98df01 100644 --- a/src/externs.d.ts +++ b/src/externs.d.ts @@ -1,4 +1,4 @@ declare module 'util.promisify' { - const _export: typeof import('util').promisify - export = _export + const _export: typeof import('util').promisify; + export = _export; } diff --git a/src/index.spec.ts b/src/index.spec.ts deleted file mode 100644 index 10e6aa376..000000000 --- a/src/index.spec.ts +++ /dev/null @@ -1,959 +0,0 @@ -import { expect } from 'chai' -import { exec } from 'child_process' -import { join } from 'path' -import semver = require('semver') -import ts = require('typescript') -import proxyquire = require('proxyquire') -import type * as tsNodeTypes from './index' -import { unlinkSync, existsSync, lstatSync } from 'fs' -import * as promisify from 'util.promisify' -import { sync as rimrafSync } from 'rimraf' -import { createRequire, createRequireFromPath } from 'module' -import { pathToFileURL } from 'url' -import Module = require('module') - -const execP = promisify(exec) - -const TEST_DIR = join(__dirname, '../tests') -const PROJECT = join(TEST_DIR, 'tsconfig.json') -const BIN_PATH = join(TEST_DIR, 'node_modules/.bin/ts-node') -const BIN_SCRIPT_PATH = join(TEST_DIR, 'node_modules/.bin/ts-node-script') - -const SOURCE_MAP_REGEXP = /\/\/# sourceMappingURL=data:application\/json;charset=utf\-8;base64,[\w\+]+=*$/ - -// `createRequire` does not exist on older node versions -const testsDirRequire = (createRequire || createRequireFromPath)(join(TEST_DIR, 'index.js')) // tslint:disable-line - -// Set after ts-node is installed locally -let { register, create, VERSION }: typeof tsNodeTypes = {} as any - -// Pack and install ts-node locally, necessary to test package "exports" -before(async function () { - this.timeout(5 * 60e3) - rimrafSync(join(TEST_DIR, 'node_modules')) - await execP(`npm install`, { cwd: TEST_DIR }) - const packageLockPath = join(TEST_DIR, 'package-lock.json') - existsSync(packageLockPath) && unlinkSync(packageLockPath) - ;({ register, create, VERSION } = testsDirRequire('ts-node')) -}) - -describe('ts-node', function () { - const cmd = `"${BIN_PATH}" --project "${PROJECT}"` - const cmdNoProject = `"${BIN_PATH}"` - - this.timeout(10000) - - it('should export the correct version', function () { - expect(VERSION).to.equal(require('../package.json').version) - }) - it('should export all CJS entrypoints', function () { - // Ensure our package.json "exports" declaration allows `require()`ing all our entrypoints - // https://github.com/TypeStrong/ts-node/pull/1026 - - testsDirRequire.resolve('ts-node') - - // only reliably way to ask node for the root path of a dependency is Path.resolve(require.resolve('ts-node/package'), '..') - testsDirRequire.resolve('ts-node/package') - testsDirRequire.resolve('ts-node/package.json') - - // All bin entrypoints for people who need to augment our CLI: `node -r otherstuff ./node_modules/ts-node/dist/bin` - testsDirRequire.resolve('ts-node/dist/bin') - testsDirRequire.resolve('ts-node/dist/bin.js') - testsDirRequire.resolve('ts-node/dist/bin-transpile') - testsDirRequire.resolve('ts-node/dist/bin-transpile.js') - testsDirRequire.resolve('ts-node/dist/bin-script') - testsDirRequire.resolve('ts-node/dist/bin-script.js') - - // Must be `require()`able obviously - testsDirRequire.resolve('ts-node/register') - testsDirRequire.resolve('ts-node/register/files') - testsDirRequire.resolve('ts-node/register/transpile-only') - testsDirRequire.resolve('ts-node/register/type-check') - - // `node --loader ts-node/esm` - testsDirRequire.resolve('ts-node/esm') - testsDirRequire.resolve('ts-node/esm.mjs') - testsDirRequire.resolve('ts-node/esm/transpile-only') - testsDirRequire.resolve('ts-node/esm/transpile-only.mjs') - }) - - describe('cli', function () { - this.slow(1000) - - it('should execute cli', function (done) { - exec(`${cmd} tests/hello-world`, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('Hello, world!\n') - - return done() - }) - }) - - it('shows usage via --help', function (done) { - exec(`${cmdNoProject} --help`, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.match(/Usage: ts-node /) - return done() - }) - }) - it('shows version via -v', function (done) { - exec(`${cmdNoProject} -v`, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout.trim()).to.equal('v' + testsDirRequire('ts-node/package').version) - return done() - }) - }) - it('shows version of compiler via -vv', function (done) { - exec(`${cmdNoProject} -vv`, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout.trim()).to.equal( - `ts-node v${ testsDirRequire('ts-node/package').version }\n` + - `node ${ process.version }\n` + - `compiler v${ testsDirRequire('typescript/package').version }` - ) - return done() - }) - }) - - it('should register via cli', function (done) { - exec(`node -r ts-node/register hello-world.ts`, { - cwd: TEST_DIR - }, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('Hello, world!\n') - - return done() - }) - }) - - it('should execute cli with absolute path', function (done) { - exec(`${cmd} "${join(TEST_DIR, 'hello-world')}"`, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('Hello, world!\n') - - return done() - }) - }) - - it('should print scripts', function (done) { - exec(`${cmd} -pe "import { example } from './tests/complex/index';example()"`, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('example\n') - - return done() - }) - }) - - it('should provide registered information globally', function (done) { - exec(`${cmd} tests/env`, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('object\n') - - return done() - }) - }) - - it('should provide registered information on register', function (done) { - exec(`node -r ts-node/register env.ts`, { - cwd: TEST_DIR - }, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('object\n') - - return done() - }) - }) - - if (semver.gte(ts.version, '1.8.0')) { - it('should allow js', function (done) { - exec( - [ - cmd, - '-O "{\\\"allowJs\\\":true}"', - '-pe "import { main } from \'./tests/allow-js/run\';main()"' - ].join(' '), - function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('hello world\n') - - return done() - } - ) - }) - - it('should include jsx when `allow-js` true', function (done) { - exec( - [ - cmd, - '-O "{\\\"allowJs\\\":true}"', - '-pe "import { Foo2 } from \'./tests/allow-js/with-jsx\'; Foo2.sayHi()"' - ].join(' '), - function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('hello world\n') - - return done() - } - ) - }) - } - - it('should eval code', function (done) { - exec( - `${cmd} -e "import * as m from './tests/module';console.log(m.example('test'))"`, - function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('TEST\n') - - return done() - } - ) - }) - - it('should import empty files', function (done) { - exec(`${cmd} -e "import './tests/empty'"`, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('') - - return done() - }) - }) - - it('should throw errors', function (done) { - exec(`${cmd} -e "import * as m from './tests/module';console.log(m.example(123))"`, function (err) { - if (err === null) { - return done('Command was expected to fail, but it succeeded.') - } - - expect(err.message).to.match(new RegExp( - 'TS2345: Argument of type \'(?:number|123)\' ' + - 'is not assignable to parameter of type \'string\'\\.' - )) - - return done() - }) - }) - - it('should be able to ignore diagnostic', function (done) { - exec( - `${cmd} --ignore-diagnostics 2345 -e "import * as m from './tests/module';console.log(m.example(123))"`, - function (err) { - if (err === null) { - return done('Command was expected to fail, but it succeeded.') - } - - expect(err.message).to.match( - /TypeError: (?:(?:undefined|foo\.toUpperCase) is not a function|.*has no method \'toUpperCase\')/ - ) - - return done() - } - ) - }) - - it('should work with source maps', function (done) { - exec(`${cmd} tests/throw`, function (err) { - if (err === null) { - return done('Command was expected to fail, but it succeeded.') - } - - expect(err.message).to.contain([ - `${join(__dirname, '../tests/throw.ts')}:100`, - ' bar () { throw new Error(\'this is a demo\') }', - ' ^', - 'Error: this is a demo' - ].join('\n')) - - return done() - }) - }) - - it('eval should work with source maps', function (done) { - exec(`${cmd} -pe "import './tests/throw'"`, function (err) { - if (err === null) { - return done('Command was expected to fail, but it succeeded.') - } - - expect(err.message).to.contain([ - `${join(__dirname, '../tests/throw.ts')}:100`, - ' bar () { throw new Error(\'this is a demo\') }', - ' ^' - ].join('\n')) - - return done() - }) - }) - - it('should support transpile only mode', function (done) { - exec(`${cmd} --transpile-only -pe "x"`, function (err) { - if (err === null) { - return done('Command was expected to fail, but it succeeded.') - } - - expect(err.message).to.contain('ReferenceError: x is not defined') - - return done() - }) - }) - - it('should throw error even in transpileOnly mode', function (done) { - exec(`${cmd} --transpile-only -pe "console."`, function (err) { - if (err === null) { - return done('Command was expected to fail, but it succeeded.') - } - - expect(err.message).to.contain('error TS1003: Identifier expected') - - return done() - }) - }) - - it('should pipe into `ts-node` and evaluate', function (done) { - const cp = exec(cmd, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('hello\n') - - return done() - }) - - cp.stdin!.end("console.log('hello')") - }) - - it('should pipe into `ts-node`', function (done) { - const cp = exec(`${cmd} -p`, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('true\n') - - return done() - }) - - cp.stdin!.end('true') - }) - - it('should pipe into an eval script', function (done) { - const cp = exec(`${cmd} --transpile-only -pe "process.stdin.isTTY"`, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('undefined\n') - - return done() - }) - - cp.stdin!.end('true') - }) - - it('should run REPL when --interactive passed and stdin is not a TTY', function (done) { - const cp = exec(`${cmd} --interactive`, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal( - '> 123\n' + - 'undefined\n' + - '> ' - ) - return done() - }) - - cp.stdin!.end('console.log("123")\n') - - }) - it('REPL has command to get type information', function (done) { - const cp = exec(`${cmd} --interactive`, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal( - '> undefined\n' + - '> undefined\n' + - '> const a: 123\n' + - '> ' - ) - return done() - }) - - cp.stdin!.end('\nconst a = 123\n.type a') - }) - - it('should support require flags', function (done) { - exec(`${cmd} -r ./tests/hello-world -pe "console.log('success')"`, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('Hello, world!\nsuccess\nundefined\n') - - return done() - }) - }) - - it('should support require from node modules', function (done) { - exec(`${cmd} -r typescript -e "console.log('success')"`, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('success\n') - - return done() - }) - }) - - it('should use source maps with react tsx', function (done) { - exec(`${cmd} tests/throw-react-tsx.tsx`, function (err, stdout) { - expect(err).not.to.equal(null) - expect(err!.message).to.contain([ - `${join(__dirname, '../tests/throw-react-tsx.tsx')}:100`, - ' bar () { throw new Error(\'this is a demo\') }', - ' ^', - 'Error: this is a demo' - ].join('\n')) - - return done() - }) - }) - - it('should allow custom typings', function (done) { - exec(`${cmd} tests/custom-types`, function (err, stdout) { - expect(err).to.match(/Error: Cannot find module 'does-not-exist'/) - - return done() - }) - }) - - it('should preserve `ts-node` context with child process', function (done) { - exec(`${cmd} tests/child-process`, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('Hello, world!\n') - - return done() - }) - }) - - it('should import js before ts by default', function (done) { - exec(`${cmd} tests/import-order/compiled`, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('Hello, JavaScript!\n') - - return done() - }) - }) - - it('should import ts before js when --prefer-ts-exts flag is present', function (done) { - exec(`${cmd} --prefer-ts-exts tests/import-order/compiled`, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('Hello, TypeScript!\n') - - return done() - }) - }) - - it('should import ts before js when TS_NODE_PREFER_TS_EXTS env is present', function (done) { - exec(`${cmd} tests/import-order/compiled`, { env: { ...process.env, TS_NODE_PREFER_TS_EXTS: 'true' } }, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('Hello, TypeScript!\n') - - return done() - }) - }) - - it('should ignore .d.ts files', function (done) { - exec(`${cmd} tests/import-order/importer`, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('Hello, World!\n') - - return done() - }) - }) - - describe('issue #884', function () { - it('should compile', function (done) { - // TODO disabled because it consistently fails on Windows on TS 2.7 - if (process.platform === 'win32' && semver.satisfies(ts.version, '2.7')) { - this.skip() - } else { - exec(`"${BIN_PATH}" --project tests/issue-884/tsconfig.json tests/issue-884`, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('') - - return done() - }) - } - }) - }) - - describe('issue #986', function () { - it('should not compile', function (done) { - exec(`"${BIN_PATH}" --project tests/issue-986/tsconfig.json tests/issue-986`, function (err, stdout, stderr) { - expect(err).not.to.equal(null) - expect(stderr).to.contain('Cannot find name \'TEST\'') // TypeScript error. - expect(stdout).to.equal('') - - return done() - }) - }) - - it('should compile with `--files`', function (done) { - exec(`"${BIN_PATH}" --files --project tests/issue-986/tsconfig.json tests/issue-986`, function (err, stdout, stderr) { - expect(err).not.to.equal(null) - expect(stderr).to.contain('ReferenceError: TEST is not defined') // Runtime error. - expect(stdout).to.equal('') - - return done() - }) - }) - }) - - if (semver.gte(ts.version, '2.7.0')) { - it('should support script mode', function (done) { - exec(`${BIN_SCRIPT_PATH} tests/scope/a/log`, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('.ts\n') - - return done() - }) - }) - it('should read tsconfig relative to realpath, not symlink, in scriptMode', function (done) { - if (lstatSync(join(TEST_DIR, 'main-realpath/symlink/symlink.tsx')).isSymbolicLink()) { - exec(`${BIN_SCRIPT_PATH} tests/main-realpath/symlink/symlink.tsx`, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('') - - return done() - }) - } else { - this.skip() - } - }) - } - - describe('should read ts-node options from tsconfig.json', function () { - const BIN_EXEC = `"${BIN_PATH}" --project tests/tsconfig-options/tsconfig.json` - - it('should override compiler options from env', function (done) { - exec(`${BIN_EXEC} tests/tsconfig-options/log-options1.js`, { - env: { - ...process.env, - TS_NODE_COMPILER_OPTIONS: '{"typeRoots": ["env-typeroots"]}' - } - }, function (err, stdout) { - expect(err).to.equal(null) - const { config } = JSON.parse(stdout) - expect(config.options.typeRoots).to.deep.equal([join(__dirname, '../tests/tsconfig-options/env-typeroots').replace(/\\/g, '/')]) - return done() - }) - }) - - it('should use options from `tsconfig.json`', function (done) { - exec(`${BIN_EXEC} tests/tsconfig-options/log-options1.js`, function (err, stdout) { - expect(err).to.equal(null) - const { options, config } = JSON.parse(stdout) - expect(config.options.typeRoots).to.deep.equal([join(__dirname, '../tests/tsconfig-options/tsconfig-typeroots').replace(/\\/g, '/')]) - expect(config.options.types).to.deep.equal(['tsconfig-tsnode-types']) - expect(options.pretty).to.equal(undefined) - expect(options.skipIgnore).to.equal(false) - expect(options.transpileOnly).to.equal(true) - expect(options.require).to.deep.equal([join(__dirname, '../tests/tsconfig-options/required1.js')]) - return done() - }) - }) - - it('should have flags override / merge with `tsconfig.json`', function (done) { - exec(`${BIN_EXEC} --skip-ignore --compiler-options "{\\"types\\":[\\"flags-types\\"]}" --require ./tests/tsconfig-options/required2.js tests/tsconfig-options/log-options2.js`, function (err, stdout) { - expect(err).to.equal(null) - const { options, config } = JSON.parse(stdout) - expect(config.options.typeRoots).to.deep.equal([join(__dirname, '../tests/tsconfig-options/tsconfig-typeroots').replace(/\\/g, '/')]) - expect(config.options.types).to.deep.equal(['flags-types']) - expect(options.pretty).to.equal(undefined) - expect(options.skipIgnore).to.equal(true) - expect(options.transpileOnly).to.equal(true) - expect(options.require).to.deep.equal([ - join(__dirname, '../tests/tsconfig-options/required1.js'), - './tests/tsconfig-options/required2.js' - ]) - return done() - }) - }) - - it('should have `tsconfig.json` override environment', function (done) { - exec(`${BIN_EXEC} tests/tsconfig-options/log-options1.js`, { - env: { - ...process.env, - TS_NODE_PRETTY: 'true', - TS_NODE_SKIP_IGNORE: 'true' - } - }, function (err, stdout) { - expect(err).to.equal(null) - const { options, config } = JSON.parse(stdout) - expect(config.options.typeRoots).to.deep.equal([join(__dirname, '../tests/tsconfig-options/tsconfig-typeroots').replace(/\\/g, '/')]) - expect(config.options.types).to.deep.equal(['tsconfig-tsnode-types']) - expect(options.pretty).to.equal(true) - expect(options.skipIgnore).to.equal(false) - expect(options.transpileOnly).to.equal(true) - expect(options.require).to.deep.equal([join(__dirname, '../tests/tsconfig-options/required1.js')]) - return done() - }) - }) - }) - - describe('compiler host', function () { - it('should execute cli', function (done) { - exec(`${cmd} --compiler-host tests/hello-world`, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('Hello, world!\n') - - return done() - }) - }) - }) - - it('should transpile files inside a node_modules directory when not ignored', function (done) { - exec(`${cmdNoProject} --script-mode tests/from-node-modules/from-node-modules`, function (err, stdout, stderr) { - if (err) return done(`Unexpected error: ${err}\nstdout:\n${stdout}\nstderr:\n${stderr}`) - expect(JSON.parse(stdout)).to.deep.equal({ - external: { - tsmri: { name: 'typescript-module-required-internally' }, - jsmri: { name: 'javascript-module-required-internally' }, - tsmii: { name: 'typescript-module-imported-internally' }, - jsmii: { name: 'javascript-module-imported-internally' } - }, - tsmie: { name: 'typescript-module-imported-externally' }, - jsmie: { name: 'javascript-module-imported-externally' }, - tsmre: { name: 'typescript-module-required-externally' }, - jsmre: { name: 'javascript-module-required-externally' } - }) - done() - }) - }) - - describe('should respect maxNodeModulesJsDepth', function () { - it('for unscoped modules', function (done) { - exec(`${cmdNoProject} --script-mode tests/maxnodemodulesjsdepth`, function (err, stdout, stderr) { - expect(err).to.not.equal(null) - expect(stderr.replace(/\r\n/g, '\n')).to.contain( - 'TSError: ⨯ Unable to compile TypeScript:\n' + - "other.ts(4,7): error TS2322: Type 'string' is not assignable to type 'boolean'.\n" + - '\n' - ) - done() - }) - }) - - it('for @scoped modules', function (done) { - exec(`${cmdNoProject} --script-mode tests/maxnodemodulesjsdepth-scoped`, function (err, stdout, stderr) { - expect(err).to.not.equal(null) - expect(stderr.replace(/\r\n/g, '\n')).to.contain( - 'TSError: ⨯ Unable to compile TypeScript:\n' + - "other.ts(7,7): error TS2322: Type 'string' is not assignable to type 'boolean'.\n" + - '\n' - ) - done() - }) - }) - }) - }) - - describe('register', function () { - let registered: tsNodeTypes.Register - let moduleTestPath: string - before(() => { - registered = register({ - project: PROJECT, - compilerOptions: { - jsx: 'preserve' - } - }) - moduleTestPath = require.resolve('../tests/module') - }) - - afterEach(() => { - // Re-enable project after every test. - registered.enabled(true) - }) - - it('should be able to require typescript', function () { - const m = require(moduleTestPath) - - expect(m.example('foo')).to.equal('FOO') - }) - - it('should support dynamically disabling', function () { - delete require.cache[moduleTestPath] - - expect(registered.enabled(false)).to.equal(false) - expect(() => require(moduleTestPath)).to.throw(/Unexpected token/) - - delete require.cache[moduleTestPath] - - expect(registered.enabled()).to.equal(false) - expect(() => require(moduleTestPath)).to.throw(/Unexpected token/) - - delete require.cache[moduleTestPath] - - expect(registered.enabled(true)).to.equal(true) - expect(() => require(moduleTestPath)).to.not.throw() - - delete require.cache[moduleTestPath] - - expect(registered.enabled()).to.equal(true) - expect(() => require(moduleTestPath)).to.not.throw() - }) - - if (semver.gte(ts.version, '2.7.0')) { - it('should support compiler scopes', function () { - const calls: string[] = [] - - registered.enabled(false) - - const compilers = [ - register({ dir: join(TEST_DIR, 'scope/a'), scope: true }), - register({ dir: join(TEST_DIR, 'scope/b'), scope: true }) - ] - - compilers.forEach(c => { - const old = c.compile - c.compile = (code, fileName, lineOffset) => { - calls.push(fileName) - - return old(code, fileName, lineOffset) - } - }) - - try { - expect(require('../tests/scope/a').ext).to.equal('.ts') - expect(require('../tests/scope/b').ext).to.equal('.ts') - } finally { - compilers.forEach(c => c.enabled(false)) - } - - expect(calls).to.deep.equal([ - join(TEST_DIR, 'scope/a/index.ts'), - join(TEST_DIR, 'scope/b/index.ts') - ]) - - delete require.cache[moduleTestPath] - - expect(() => require(moduleTestPath)).to.throw() - }) - } - - it('should compile through js and ts', function () { - const m = require('../tests/complex') - - expect(m.example()).to.equal('example') - }) - - it('should work with proxyquire', function () { - const m = proxyquire('../tests/complex', { - './example': 'hello' - }) - - expect(m.example()).to.equal('hello') - }) - - it('should work with `require.cache`', function () { - const { example1, example2 } = require('../tests/require-cache') - - expect(example1).to.not.equal(example2) - }) - - it('should use source maps', function (done) { - try { - require('../tests/throw') - } catch (error) { - expect(error.stack).to.contain([ - 'Error: this is a demo', - ` at Foo.bar (${join(__dirname, '../tests/throw.ts')}:100:18)` - ].join('\n')) - - done() - } - }) - - describe('JSX preserve', () => { - let old: (m: Module, filename: string) => any - let compiled: string - - before(function () { - old = require.extensions['.tsx']! // tslint:disable-line - require.extensions['.tsx'] = (m: any, fileName) => { // tslint:disable-line - const _compile = m._compile - - m._compile = (code: string, fileName: string) => { - compiled = code - return _compile.call(this, code, fileName) - } - - return old(m, fileName) - } - }) - - after(function () { - require.extensions['.tsx'] = old // tslint:disable-line - }) - - it('should use source maps', function (done) { - try { - require('../tests/with-jsx.tsx') - } catch (error) { - expect(error.stack).to.contain('SyntaxError: Unexpected token') - } - - expect(compiled).to.match(SOURCE_MAP_REGEXP) - - done() - }) - }) - }) - - describe('create', () => { - let service: tsNodeTypes.Register - before(() => { - service = create({ compilerOptions: { target: 'es5' }, skipProject: true }) - }) - - it('should create generic compiler instances', () => { - const output = service.compile('const x = 10', 'test.ts') - expect(output).to.contain('var x = 10;') - }) - - describe('should get type information', () => { - it('given position of identifier', () => { - expect(service.getTypeInfo('/**jsdoc here*/const x = 10', 'test.ts', 21)).to.deep.equal({ - comment: 'jsdoc here', - name: 'const x: 10' - }) - }) - it('given position that does not point to an identifier', () => { - expect(service.getTypeInfo('/**jsdoc here*/const x = 10', 'test.ts', 0)).to.deep.equal({ - comment: '', - name: '' - }) - }) - }) - }) - - describe('issue #1098', () => { - function testIgnored (ignored: tsNodeTypes.Register['ignored'], allowed: string[], disallowed: string[]) { - for (const ext of allowed) { - expect(ignored(join(__dirname, `index${ext}`))).equal(false, `should accept ${ext} files`) - } - for (const ext of disallowed) { - expect(ignored(join(__dirname, `index${ext}`))).equal(true, `should ignore ${ext} files`) - } - } - - it('correctly filters file extensions from the compiler when allowJs=false and jsx=false', () => { - const { ignored } = create({ compilerOptions: { }, skipProject: true }) - testIgnored(ignored, ['.ts', '.d.ts'], ['.js', '.tsx', '.jsx', '.mjs', '.cjs', '.xyz', '']) - }) - it('correctly filters file extensions from the compiler when allowJs=true and jsx=false', () => { - const { ignored } = create({ compilerOptions: { allowJs: true }, skipProject: true }) - testIgnored(ignored, ['.ts', '.js', '.d.ts'], ['.tsx', '.jsx', '.mjs', '.cjs', '.xyz', '']) - }) - it('correctly filters file extensions from the compiler when allowJs=false and jsx=true', () => { - const { ignored } = create({ compilerOptions: { allowJs: false, jsx: 'preserve' }, skipProject: true }) - testIgnored(ignored, ['.ts', '.tsx', '.d.ts'], ['.js', '.jsx', '.mjs', '.cjs', '.xyz', '']) - }) - it('correctly filters file extensions from the compiler when allowJs=true and jsx=true', () => { - const { ignored } = create({ compilerOptions: { allowJs: true, jsx: 'preserve' }, skipProject: true }) - testIgnored(ignored, ['.ts', '.tsx', '.js', '.jsx', '.d.ts'], ['.mjs', '.cjs', '.xyz', '']) - }) - }) - - describe('esm', () => { - this.slow(1000) - - const cmd = `node --loader ts-node/esm` - - if (semver.gte(process.version, '13.0.0')) { - it('should compile and execute as ESM', (done) => { - exec(`${cmd} index.ts`, { cwd: join(__dirname, '../tests/esm') }, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('foo bar baz biff\n') - - return done() - }) - }) - it('should use source maps', function (done) { - exec(`${cmd} throw.ts`, { cwd: join(__dirname, '../tests/esm') }, function (err, stdout) { - expect(err).not.to.equal(null) - expect(err!.message).to.contain([ - `${pathToFileURL(join(__dirname, '../tests/esm/throw.ts'))}:100`, - ' bar () { throw new Error(\'this is a demo\') }', - ' ^', - 'Error: this is a demo' - ].join('\n')) - - return done() - }) - }) - - describe('supports experimental-specifier-resolution=node', () => { - it('via --experimental-specifier-resolution', (done) => { - exec(`${cmd} --experimental-specifier-resolution=node index.ts`, { cwd: join(__dirname, '../tests/esm-node-resolver') }, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('foo bar baz biff\n') - - return done() - }) - }) - it('via NODE_OPTIONS', (done) => { - exec(`${cmd} index.ts`, { - cwd: join(__dirname, '../tests/esm-node-resolver'), - env: { - ...process.env, - NODE_OPTIONS: '--experimental-specifier-resolution=node' - } - }, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('foo bar baz biff\n') - - return done() - }) - }) - }) - - it('throws ERR_REQUIRE_ESM when attempting to require() an ESM script while ESM loader is enabled', function (done) { - exec(`${cmd} ./index.js`, { cwd: join(__dirname, '../tests/esm-err-require-esm') }, function (err, stdout, stderr) { - expect(err).to.not.equal(null) - expect(stderr).to.contain('Error [ERR_REQUIRE_ESM]: Must use import to load ES Module:') - - return done() - }) - }) - - it('defers to fallback loaders when URL should not be handled by ts-node', function (done) { - exec(`${cmd} index.mjs`, { - cwd: join(__dirname, '../tests/esm-import-http-url') - }, function (err, stdout, stderr) { - expect(err).to.not.equal(null) - // expect error from node's default resolver - expect(stderr).to.match(/Error \[ERR_UNSUPPORTED_ESM_URL_SCHEME\]:.*\n *at defaultResolve/) - return done() - }) - }) - - it('should support transpile only mode via dedicated loader entrypoint', (done) => { - exec(`${cmd}/transpile-only index.ts`, { cwd: join(__dirname, '../tests/esm-transpile-only') }, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('') - - return done() - }) - }) - it('should throw type errors without transpile-only enabled', (done) => { - exec(`${cmd} index.ts`, { cwd: join(__dirname, '../tests/esm-transpile-only') }, function (err, stdout) { - if (err === null) { - return done('Command was expected to fail, but it succeeded.') - } - - expect(err.message).to.contain('Unable to compile TypeScript') - expect(err.message).to.match(new RegExp('TS2345: Argument of type \'(?:number|1101)\' is not assignable to parameter of type \'string\'\\.')) - expect(err.message).to.match(new RegExp('TS2322: Type \'(?:"hello world"|string)\' is not assignable to type \'number\'\\.')) - expect(stdout).to.equal('') - - return done() - }) - }) - } - - it('executes ESM as CJS, ignoring package.json "types" field (for backwards compatibility; should be changed in next major release to throw ERR_REQUIRE_ESM)', function (done) { - exec(`${BIN_PATH} ./tests/esm-err-require-esm/index.js`, function (err, stdout) { - expect(err).to.equal(null) - expect(stdout).to.equal('CommonJS\n') - - return done() - }) - }) - }) -}) diff --git a/src/index.ts b/src/index.ts index e2b759afc..165c14354 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,35 +1,87 @@ -import { relative, basename, extname, resolve, dirname, join, isAbsolute } from 'path' -import sourceMapSupport = require('source-map-support') -import * as ynModule from 'yn' -import { BaseError } from 'make-error' -import * as util from 'util' -import { fileURLToPath } from 'url' -import type * as _ts from 'typescript' -import * as Module from 'module' +import { relative, basename, extname, resolve, dirname, join } from 'path'; +import { Module } from 'module'; +import * as util from 'util'; +import { fileURLToPath } from 'url'; + +import sourceMapSupport = require('@cspotcode/source-map-support'); +import { BaseError } from 'make-error'; +import type * as _ts from 'typescript'; + +import type { Transpiler, TranspilerFactory } from './transpilers/types'; +import { + assign, + cachedLookup, + normalizeSlashes, + parse, + split, + yn, +} from './util'; +import { readConfig } from './configuration'; +import type { TSCommon, TSInternal } from './ts-compiler-types'; +import { + createModuleTypeClassifier, + ModuleTypeClassifier, +} from './module-type-classifier'; +import { createResolverFunctions } from './resolver-functions'; +import { ScriptTarget } from 'typescript'; + +export { TSCommon }; +export { + createRepl, + CreateReplOptions, + ReplService, + EvalAwarePartialHost, +} from './repl'; +export type { + TranspilerModule, + TranspilerFactory, + CreateTranspilerOptions, + TranspileOutput, + TranspileOptions, + Transpiler, +} from './transpilers/types'; /** * Does this version of node obey the package.json "type" field * and throw ERR_REQUIRE_ESM when attempting to require() an ESM modules. */ -const engineSupportsPackageTypeField = parseInt(process.versions.node.split('.')[0], 10) >= 12 - -// Loaded conditionally so we don't need to support older node versions -let assertScriptCanLoadAsCJSImpl: ((filename: string) => void) | undefined +const engineSupportsPackageTypeField = + parseInt(process.versions.node.split('.')[0], 10) >= 12; + +function versionGte(version: string, requirement: string) { + const [major, minor, patch, extra] = version + .split(/[\.-]/) + .map((s) => parseInt(s, 10)); + const [reqMajor, reqMinor, reqPatch] = requirement + .split('.') + .map((s) => parseInt(s, 10)); + return ( + major > reqMajor || + (major === reqMajor && + (minor > reqMinor || (minor === reqMinor && patch >= reqPatch))) + ); +} /** * Assert that script can be loaded as CommonJS when we attempt to require it. * If it should be loaded as ESM, throw ERR_REQUIRE_ESM like node does. + * + * Loaded conditionally so we don't need to support older node versions */ -function assertScriptCanLoadAsCJS (filename: string) { - if (!engineSupportsPackageTypeField) return - if (!assertScriptCanLoadAsCJSImpl) assertScriptCanLoadAsCJSImpl = require('../dist-raw/node-cjs-loader-utils').assertScriptCanLoadAsCJSImpl - assertScriptCanLoadAsCJSImpl!(filename) -} +let assertScriptCanLoadAsCJS: ( + service: Service, + module: NodeJS.Module, + filename: string +) => void = engineSupportsPackageTypeField + ? require('../dist-raw/node-cjs-loader-utils').assertScriptCanLoadAsCJSImpl + : () => { + /* noop */ + }; /** * Registered `ts-node` instance information. */ -export const REGISTER_INSTANCE = Symbol.for('ts-node.register.instance') +export const REGISTER_INSTANCE = Symbol.for('ts-node.register.instance'); /** * Expose `REGISTER_INSTANCE` information on node.js `process`. @@ -37,196 +89,257 @@ export const REGISTER_INSTANCE = Symbol.for('ts-node.register.instance') declare global { namespace NodeJS { interface Process { - [REGISTER_INSTANCE]?: Register + [REGISTER_INSTANCE]?: Service; } } } +/** @internal */ +export const env = process.env as ProcessEnv; /** + * Declare all env vars, to aid discoverability. + * If an env var affects ts-node's behavior, it should not be buried somewhere in our codebase. * @internal */ -export const INSPECT_CUSTOM = util.inspect.custom || 'inspect' +export interface ProcessEnv { + TS_NODE_DEBUG?: string; + TS_NODE_CWD?: string; + /** @deprecated */ + TS_NODE_DIR?: string; + TS_NODE_EMIT?: string; + TS_NODE_SCOPE?: string; + TS_NODE_SCOPE_DIR?: string; + TS_NODE_FILES?: string; + TS_NODE_PRETTY?: string; + TS_NODE_COMPILER?: string; + TS_NODE_COMPILER_OPTIONS?: string; + TS_NODE_IGNORE?: string; + TS_NODE_PROJECT?: string; + TS_NODE_SKIP_PROJECT?: string; + TS_NODE_SKIP_IGNORE?: string; + TS_NODE_PREFER_TS_EXTS?: string; + TS_NODE_IGNORE_DIAGNOSTICS?: string; + TS_NODE_TRANSPILE_ONLY?: string; + TS_NODE_TYPE_CHECK?: string; + TS_NODE_COMPILER_HOST?: string; + TS_NODE_LOG_ERROR?: string; + TS_NODE_HISTORY?: string; + TS_NODE_EXPERIMENTAL_REPL_AWAIT?: string; + + NODE_NO_READLINE?: string; +} /** - * Wrapper around yn module that returns `undefined` instead of `null`. - * This is implemented by yn v4, but we're staying on v3 to avoid v4's node 10 requirement. + * @internal */ -function yn (value: string | undefined) { - return ynModule(value) ?? undefined -} +export const INSPECT_CUSTOM = util.inspect.custom || 'inspect'; /** * Debugging `ts-node`. */ -const shouldDebug = yn(process.env.TS_NODE_DEBUG) +const shouldDebug = yn(env.TS_NODE_DEBUG); /** @internal */ -export const debug = shouldDebug ? - (...args: any) => console.log(`[ts-node ${new Date().toISOString()}]`, ...args) - : () => undefined -const debugFn = shouldDebug ? - (key: string, fn: (arg: T) => U) => { - let i = 0 - return (x: T) => { - debug(key, x, ++i) - return fn(x) +export const debug = shouldDebug + ? (...args: any) => + console.log(`[ts-node ${new Date().toISOString()}]`, ...args) + : () => undefined; +const debugFn = shouldDebug + ? (key: string, fn: (arg: T) => U) => { + let i = 0; + return (x: T) => { + debug(key, x, ++i); + return fn(x); + }; } - } : - (_: string, fn: (arg: T) => U) => fn - -/** - * Common TypeScript interfaces between versions. - */ -export interface TSCommon { - version: typeof _ts.version - sys: typeof _ts.sys - ScriptSnapshot: typeof _ts.ScriptSnapshot - displayPartsToString: typeof _ts.displayPartsToString - createLanguageService: typeof _ts.createLanguageService - getDefaultLibFilePath: typeof _ts.getDefaultLibFilePath - getPreEmitDiagnostics: typeof _ts.getPreEmitDiagnostics - flattenDiagnosticMessageText: typeof _ts.flattenDiagnosticMessageText - transpileModule: typeof _ts.transpileModule - ModuleKind: typeof _ts.ModuleKind - ScriptTarget: typeof _ts.ScriptTarget - findConfigFile: typeof _ts.findConfigFile - readConfigFile: typeof _ts.readConfigFile - parseJsonConfigFileContent: typeof _ts.parseJsonConfigFileContent - formatDiagnostics: typeof _ts.formatDiagnostics - formatDiagnosticsWithColorAndContext: typeof _ts.formatDiagnosticsWithColorAndContext -} - -/** - * Compiler APIs we use that are marked internal and not included in TypeScript's public API declarations - */ -interface TSInternal { - // https://github.com/microsoft/TypeScript/blob/4a34294908bed6701dcba2456ca7ac5eafe0ddff/src/compiler/core.ts#L1906-L1909 - createGetCanonicalFileName (useCaseSensitiveFileNames: boolean): TSInternal.GetCanonicalFileName -} -namespace TSInternal { - // https://github.com/microsoft/TypeScript/blob/4a34294908bed6701dcba2456ca7ac5eafe0ddff/src/compiler/core.ts#L1906 - export type GetCanonicalFileName = (fileName: string) => string -} + : (_: string, fn: (arg: T) => U) => fn; /** * Export the current version. */ -export const VERSION = require('../package.json').version +export const VERSION = require('../package.json').version; /** * Options for creating a new TypeScript compiler instance. */ export interface CreateOptions { /** - * Specify working directory for config resolution. + * Behave as if invoked within this working directory. Roughly equivalent to `cd $dir && ts-node ...` * * @default process.cwd() */ - dir?: string + cwd?: string; + /** + * Legacy alias for `cwd` + * + * @deprecated use `projectSearchDir` or `cwd` + */ + dir?: string; /** * Emit output files into `.ts-node` directory. * * @default false */ - emit?: boolean + emit?: boolean; /** - * Scope compiler to files within `cwd`. + * Scope compiler to files within `scopeDir`. * * @default false */ - scope?: boolean + scope?: boolean; + /** + * @default First of: `tsconfig.json` "rootDir" if specified, directory containing `tsconfig.json`, or cwd if no `tsconfig.json` is loaded. + */ + scopeDir?: string; /** * Use pretty diagnostic formatter. * * @default false */ - pretty?: boolean + pretty?: boolean; /** * Use TypeScript's faster `transpileModule`. * * @default false */ - transpileOnly?: boolean + transpileOnly?: boolean; /** * **DEPRECATED** Specify type-check is enabled (e.g. `transpileOnly == false`). * * @default true */ - typeCheck?: boolean + typeCheck?: boolean; /** - * Use TypeScript's compiler host API. + * Use TypeScript's compiler host API instead of the language service API. * * @default false */ - compilerHost?: boolean + compilerHost?: boolean; /** * Logs TypeScript errors to stderr instead of throwing exceptions. * * @default false */ - logError?: boolean + logError?: boolean; /** - * Load files from `tsconfig.json` on startup. + * Load "files" and "include" from `tsconfig.json` on startup. + * + * Default is to override `tsconfig.json` "files" and "include" to only include the entrypoint script. * * @default false */ - files?: boolean + files?: boolean; /** * Specify a custom TypeScript compiler. * * @default "typescript" */ - compiler?: string + compiler?: string; + /** + * Specify a custom transpiler for use with transpileOnly + */ + transpiler?: string | [string, object]; /** - * Override the path patterns to skip compilation. + * Paths which should not be compiled. + * + * Each string in the array is converted to a regular expression via `new RegExp()` and tested against source paths prior to compilation. + * + * Source paths are normalized to posix-style separators, relative to the directory containing `tsconfig.json` or to cwd if no `tsconfig.json` is loaded. * - * @default /node_modules/ - * @docsDefault "/node_modules/" + * Default is to ignore all node_modules subdirectories. + * + * @default ["(?:^|/)node_modules/"] + */ + ignore?: string[]; + /** + * Path to TypeScript config file or directory containing a `tsconfig.json`. + * Similar to the `tsc --project` flag: https://www.typescriptlang.org/docs/handbook/compiler-options.html */ - ignore?: string[] + project?: string; /** - * Path to TypeScript JSON project file. + * Search for TypeScript config file (`tsconfig.json`) in this or parent directories. */ - project?: string + projectSearchDir?: string; /** * Skip project config resolution and loading. * * @default false */ - skipProject?: boolean + skipProject?: boolean; /** - * Skip ignore check. + * Skip ignore check, so that compilation will be attempted for all files with matching extensions. * * @default false */ - skipIgnore?: boolean + skipIgnore?: boolean; /** - * JSON object to merge with compiler options. + * JSON object to merge with TypeScript `compilerOptions`. * * @allOf [{"$ref": "https://schemastore.azurewebsites.net/schemas/json/tsconfig.json#definitions/compilerOptionsDefinition/properties/compilerOptions"}] */ - compilerOptions?: object + compilerOptions?: object; /** * Ignore TypeScript warnings by diagnostic code. */ - ignoreDiagnostics?: Array + ignoreDiagnostics?: Array; /** * Modules to require, like node's `--require` flag. * - * If specified in tsconfig.json, the modules will be resolved relative to the tsconfig.json file. + * If specified in `tsconfig.json`, the modules will be resolved relative to the `tsconfig.json` file. * * If specified programmatically, each input string should be pre-resolved to an absolute path for * best results. */ - require?: Array - readFile?: (path: string) => string | undefined - fileExists?: (path: string) => boolean - transformers?: _ts.CustomTransformers | ((p: _ts.Program) => _ts.CustomTransformers) + require?: Array; + readFile?: (path: string) => string | undefined; + fileExists?: (path: string) => boolean; + transformers?: + | _ts.CustomTransformers + | ((p: _ts.Program) => _ts.CustomTransformers); /** * True if require() hooks should interop with experimental ESM loader. * Enabled explicitly via a flag since it is a breaking change. * @internal */ - experimentalEsmLoader?: boolean + experimentalEsmLoader?: boolean; + /** + * Allows the usage of top level await in REPL. + * + * Uses node's implementation which accomplishes this with an AST syntax transformation. + * + * Enabled by default when tsconfig target is es2018 or above. Set to false to disable. + * + * **Note**: setting to `true` when tsconfig target is too low will throw an Error. Leave as `undefined` + * to get default, automatic behavior. + */ + experimentalReplAwait?: boolean; + /** + * Override certain paths to be compiled and executed as CommonJS or ECMAScript modules. + * When overridden, the tsconfig "module" and package.json "type" fields are overridden. + * This is useful because TypeScript files cannot use the .cjs nor .mjs file extensions; + * it achieves the same effect. + * + * Each key is a glob pattern following the same rules as tsconfig's "include" array. + * When multiple patterns match the same file, the last pattern takes precedence. + * + * `cjs` overrides matches files to compile and execute as CommonJS. + * `esm` overrides matches files to compile and execute as native ECMAScript modules. + * `package` overrides either of the above to default behavior, which obeys package.json "type" and + * tsconfig.json "module" options. + */ + moduleTypes?: Record; + /** + * @internal + * Set by our configuration loader whenever a config file contains options that + * are relative to the config file they came from, *and* when other logic needs + * to know this. Some options can be eagerly resolved to absolute paths by + * the configuration loader, so it is *not* necessary for their source to be set here. + */ + optionBasePaths?: OptionBasePaths; +} + +/** @internal */ +export interface OptionBasePaths { + moduleTypes?: string; } /** @@ -236,607 +349,667 @@ export interface RegisterOptions extends CreateOptions { /** * Re-order file extensions so that TypeScript imports are preferred. * + * For example, when both `index.js` and `index.ts` exist, enabling this option causes `require('./index')` to resolve to `index.ts` instead of `index.js` + * * @default false */ - preferTsExts?: boolean + preferTsExts?: boolean; } /** * Must be an interface to support `typescript-json-schema`. */ -export interface TsConfigOptions extends Omit {} -/** - * Like `Object.assign`, but ignores `undefined` properties. - */ -function assign (initialValue: T, ...sources: Array): T { - for (const source of sources) { - for (const key of Object.keys(source)) { - const value = (source as any)[key] - if (value !== undefined) (initialValue as any)[key] = value - } - } - return initialValue -} - /** * Information retrieved from type info check. */ export interface TypeInfo { - name: string - comment: string + name: string; + comment: string; } /** * Default register options, including values specified via environment * variables. + * @internal */ export const DEFAULTS: RegisterOptions = { - dir: process.env.TS_NODE_DIR, - emit: yn(process.env.TS_NODE_EMIT), - scope: yn(process.env.TS_NODE_SCOPE), - files: yn(process.env.TS_NODE_FILES), - pretty: yn(process.env.TS_NODE_PRETTY), - compiler: process.env.TS_NODE_COMPILER, - compilerOptions: parse(process.env.TS_NODE_COMPILER_OPTIONS), - ignore: split(process.env.TS_NODE_IGNORE), - project: process.env.TS_NODE_PROJECT, - skipProject: yn(process.env.TS_NODE_SKIP_PROJECT), - skipIgnore: yn(process.env.TS_NODE_SKIP_IGNORE), - preferTsExts: yn(process.env.TS_NODE_PREFER_TS_EXTS), - ignoreDiagnostics: split(process.env.TS_NODE_IGNORE_DIAGNOSTICS), - transpileOnly: yn(process.env.TS_NODE_TRANSPILE_ONLY), - typeCheck: yn(process.env.TS_NODE_TYPE_CHECK), - compilerHost: yn(process.env.TS_NODE_COMPILER_HOST), - logError: yn(process.env.TS_NODE_LOG_ERROR), - experimentalEsmLoader: false -} - -/** - * Default TypeScript compiler options required by `ts-node`. - */ -const TS_NODE_COMPILER_OPTIONS = { - sourceMap: true, - inlineSourceMap: false, - inlineSources: true, - declaration: false, - noEmit: false, - outDir: '.ts-node' -} - -/** - * Split a string array of values. - */ -export function split (value: string | undefined) { - return typeof value === 'string' ? value.split(/ *, */g) : undefined -} - -/** - * Parse a string as JSON. - */ -export function parse (value: string | undefined): object | undefined { - return typeof value === 'string' ? JSON.parse(value) : undefined -} - -/** - * Replace backslashes with forward slashes. - */ -export function normalizeSlashes (value: string): string { - return value.replace(/\\/g, '/') -} + cwd: env.TS_NODE_CWD ?? env.TS_NODE_DIR, + emit: yn(env.TS_NODE_EMIT), + scope: yn(env.TS_NODE_SCOPE), + scopeDir: env.TS_NODE_SCOPE_DIR, + files: yn(env.TS_NODE_FILES), + pretty: yn(env.TS_NODE_PRETTY), + compiler: env.TS_NODE_COMPILER, + compilerOptions: parse(env.TS_NODE_COMPILER_OPTIONS), + ignore: split(env.TS_NODE_IGNORE), + project: env.TS_NODE_PROJECT, + skipProject: yn(env.TS_NODE_SKIP_PROJECT), + skipIgnore: yn(env.TS_NODE_SKIP_IGNORE), + preferTsExts: yn(env.TS_NODE_PREFER_TS_EXTS), + ignoreDiagnostics: split(env.TS_NODE_IGNORE_DIAGNOSTICS), + transpileOnly: yn(env.TS_NODE_TRANSPILE_ONLY), + typeCheck: yn(env.TS_NODE_TYPE_CHECK), + compilerHost: yn(env.TS_NODE_COMPILER_HOST), + logError: yn(env.TS_NODE_LOG_ERROR), + experimentalEsmLoader: false, + experimentalReplAwait: yn(env.TS_NODE_EXPERIMENTAL_REPL_AWAIT) ?? undefined, +}; /** * TypeScript diagnostics error. */ export class TSError extends BaseError { - name = 'TSError' + name = 'TSError'; - constructor (public diagnosticText: string, public diagnosticCodes: number[]) { - super(`⨯ Unable to compile TypeScript:\n${diagnosticText}`) + constructor(public diagnosticText: string, public diagnosticCodes: number[]) { + super(`⨯ Unable to compile TypeScript:\n${diagnosticText}`); } /** * @internal */ - [INSPECT_CUSTOM] () { - return this.diagnosticText + [INSPECT_CUSTOM]() { + return this.diagnosticText; } } /** - * Return type for registering `ts-node`. + * Primary ts-node service, which wraps the TypeScript API and can compile TypeScript to JavaScript */ -export interface Register { - ts: TSCommon - config: _ts.ParsedCommandLine - options: RegisterOptions - enabled (enabled?: boolean): boolean - ignored (fileName: string): boolean - compile (code: string, fileName: string, lineOffset?: number): string - getTypeInfo (code: string, fileName: string, position: number): TypeInfo +export interface Service { + ts: TSCommon; + config: _ts.ParsedCommandLine; + options: RegisterOptions; + enabled(enabled?: boolean): boolean; + ignored(fileName: string): boolean; + compile(code: string, fileName: string, lineOffset?: number): string; + getTypeInfo(code: string, fileName: string, position: number): TypeInfo; + /** @internal */ + configFilePath: string | undefined; + /** @internal */ + moduleTypeClassifier: ModuleTypeClassifier; + /** @internal */ + readonly shouldReplAwait: boolean; + /** @internal */ + addDiagnosticFilter(filter: DiagnosticFilter): void; } /** - * Cached fs operation wrapper. + * Re-export of `Service` interface for backwards-compatibility + * @deprecated use `Service` instead + * @see {Service} */ -function cachedLookup (fn: (arg: string) => T): (arg: string) => T { - const cache = new Map() - - return (arg: string): T => { - if (!cache.has(arg)) { - cache.set(arg, fn(arg)) - } +export type Register = Service; - return cache.get(arg)! - } +/** @internal */ +export interface DiagnosticFilter { + /** if true, filter applies to all files */ + appliesToAllFiles: boolean; + /** Filter applies onto to these filenames. Only used if appliesToAllFiles is false */ + filenamesAbsolute: string[]; + /** these diagnostic codes are ignored */ + diagnosticsIgnored: number[]; } /** @internal */ -export function getExtensions (config: _ts.ParsedCommandLine) { - const tsExtensions = ['.ts'] - const jsExtensions = [] +export function getExtensions(config: _ts.ParsedCommandLine) { + const tsExtensions = ['.ts']; + const jsExtensions = []; // Enable additional extensions when JSX or `allowJs` is enabled. - if (config.options.jsx) tsExtensions.push('.tsx') - if (config.options.allowJs) jsExtensions.push('.js') - if (config.options.jsx && config.options.allowJs) jsExtensions.push('.jsx') - return { tsExtensions, jsExtensions } + if (config.options.jsx) tsExtensions.push('.tsx'); + if (config.options.allowJs) jsExtensions.push('.js'); + if (config.options.jsx && config.options.allowJs) jsExtensions.push('.jsx'); + return { tsExtensions, jsExtensions }; } /** * Register TypeScript compiler instance onto node.js */ -export function register (opts: RegisterOptions = {}): Register { - const originalJsHandler = require.extensions['.js'] // tslint:disable-line - const service = create(opts) - const { tsExtensions, jsExtensions } = getExtensions(service.config) - const extensions = [...tsExtensions, ...jsExtensions] +export function register(opts: RegisterOptions = {}): Service { + const originalJsHandler = require.extensions['.js']; + const service = create(opts); + const { tsExtensions, jsExtensions } = getExtensions(service.config); + const extensions = [...tsExtensions, ...jsExtensions]; // Expose registered instance globally. - process[REGISTER_INSTANCE] = service + process[REGISTER_INSTANCE] = service; // Register the extensions. - registerExtensions(service.options.preferTsExts, extensions, service, originalJsHandler) + registerExtensions( + service.options.preferTsExts, + extensions, + service, + originalJsHandler + ); // Require specified modules before start-up. - ;(Module as any)._preloadModules(service.options.require) + (Module as any)._preloadModules(service.options.require); - return service + return service; } /** * Create TypeScript compiler instance. */ -export function create (rawOptions: CreateOptions = {}): Register { - const dir = rawOptions.dir ?? DEFAULTS.dir - const compilerName = rawOptions.compiler ?? DEFAULTS.compiler - const cwd = dir ? resolve(dir) : process.cwd() +export function create(rawOptions: CreateOptions = {}): Service { + const cwd = resolve( + rawOptions.cwd ?? rawOptions.dir ?? DEFAULTS.cwd ?? process.cwd() + ); + const compilerName = rawOptions.compiler ?? DEFAULTS.compiler; /** * Load the typescript compiler. It is required to load the tsconfig but might - * be changed by the tsconfig, so we sometimes have to do this twice. + * be changed by the tsconfig, so we have to do this twice. */ - function loadCompiler (name: string | undefined) { - const compiler = require.resolve(name || 'typescript', { paths: [cwd, __dirname] }) - const ts: typeof _ts = require(compiler) - return { compiler, ts } + function loadCompiler(name: string | undefined, relativeToPath: string) { + const compiler = require.resolve(name || 'typescript', { + paths: [relativeToPath, __dirname], + }); + const ts: typeof _ts = require(compiler); + return { compiler, ts }; } // Compute minimum options to read the config file. - let { compiler, ts } = loadCompiler(compilerName) + let { compiler, ts } = loadCompiler( + compilerName, + rawOptions.projectSearchDir ?? rawOptions.project ?? cwd + ); // Read config file and merge new options between env and CLI options. - const { config, options: tsconfigOptions } = readConfig(cwd, ts, rawOptions) - const options = assign({}, DEFAULTS, tsconfigOptions || {}, rawOptions) + const { + configFilePath, + config, + tsNodeOptionsFromTsconfig, + optionBasePaths, + } = readConfig(cwd, ts, rawOptions); + const options = assign( + {}, + DEFAULTS, + tsNodeOptionsFromTsconfig || {}, + { optionBasePaths }, + rawOptions + ); options.require = [ - ...tsconfigOptions.require || [], - ...rawOptions.require || [] - ] + ...(tsNodeOptionsFromTsconfig.require || []), + ...(rawOptions.require || []), + ]; + + // Experimental REPL await is not compatible targets lower than ES2018 + const targetSupportsTla = config.options.target! >= ScriptTarget.ES2018; + if (options.experimentalReplAwait === true && !targetSupportsTla) { + throw new Error( + 'Experimental REPL await is not compatible with targets lower than ES2018' + ); + } + // Top-level await was added in TS 3.8 + const tsVersionSupportsTla = versionGte(ts.version, '3.8.0'); + if (options.experimentalReplAwait === true && !tsVersionSupportsTla) { + throw new Error( + 'Experimental REPL await is not compatible with TypeScript versions older than 3.8' + ); + } - // If `compiler` option changed based on tsconfig, re-load the compiler. - if (options.compiler !== compilerName) { - ({ compiler, ts } = loadCompiler(options.compiler)) + const shouldReplAwait = + options.experimentalReplAwait !== false && + tsVersionSupportsTla && + targetSupportsTla; + + // Re-load the compiler in case it has changed. + // Compiler is loaded relative to tsconfig.json, so tsconfig discovery may cause us to load a + // different compiler than we did above, even if the name has not changed. + if (configFilePath) { + ({ compiler, ts } = loadCompiler(options.compiler, configFilePath)); } - const readFile = options.readFile || ts.sys.readFile - const fileExists = options.fileExists || ts.sys.fileExists - const transpileOnly = options.transpileOnly === true || options.typeCheck === false - const transformers = options.transformers || undefined - const ignoreDiagnostics = [ - 6059, // "'rootDir' is expected to contain all source files." - 18002, // "The 'files' list in config file is empty." - 18003, // "No inputs were found in config file." - ...(options.ignoreDiagnostics || []) - ].map(Number) - - const configDiagnosticList = filterDiagnostics(config.errors, ignoreDiagnostics) - const outputCache = new Map() - - const isScoped = options.scope ? (relname: string) => relname.charAt(0) !== '.' : () => true - const shouldIgnore = createIgnore(options.skipIgnore ? [] : ( - options.ignore || ['(?:^|/)node_modules/'] - ).map(str => new RegExp(str))) + const readFile = options.readFile || ts.sys.readFile; + const fileExists = options.fileExists || ts.sys.fileExists; + // typeCheck can override transpileOnly, useful for CLI flag to override config file + const transpileOnly = + options.transpileOnly === true && options.typeCheck !== true; + const transformers = options.transformers || undefined; + const diagnosticFilters: Array = [ + { + appliesToAllFiles: true, + filenamesAbsolute: [], + diagnosticsIgnored: [ + 6059, // "'rootDir' is expected to contain all source files." + 18002, // "The 'files' list in config file is empty." + 18003, // "No inputs were found in config file." + ...(options.ignoreDiagnostics || []), + ].map(Number), + }, + ]; + + const configDiagnosticList = filterDiagnostics( + config.errors, + diagnosticFilters + ); + const outputCache = new Map< + string, + { + content: string; + } + >(); + + const configFileDirname = configFilePath ? dirname(configFilePath) : null; + const scopeDir = + options.scopeDir ?? config.options.rootDir ?? configFileDirname ?? cwd; + const ignoreBaseDir = configFileDirname ?? cwd; + const isScoped = options.scope + ? (fileName: string) => relative(scopeDir, fileName).charAt(0) !== '.' + : () => true; + const shouldIgnore = createIgnore( + ignoreBaseDir, + options.skipIgnore + ? [] + : (options.ignore || ['(?:^|/)node_modules/']).map( + (str) => new RegExp(str) + ) + ); const diagnosticHost: _ts.FormatDiagnosticsHost = { getNewLine: () => ts.sys.newLine, getCurrentDirectory: () => cwd, - getCanonicalFileName: ts.sys.useCaseSensitiveFileNames ? x => x : x => x.toLowerCase() + getCanonicalFileName: ts.sys.useCaseSensitiveFileNames + ? (x) => x + : (x) => x.toLowerCase(), + }; + + if (options.transpileOnly && typeof transformers === 'function') { + throw new TypeError( + 'Transformers function is unavailable in "--transpile-only"' + ); + } + let customTranspiler: Transpiler | undefined = undefined; + if (options.transpiler) { + if (!transpileOnly) + throw new Error( + 'Custom transpiler can only be used when transpileOnly is enabled.' + ); + const transpilerName = + typeof options.transpiler === 'string' + ? options.transpiler + : options.transpiler[0]; + const transpilerOptions = + typeof options.transpiler === 'string' ? {} : options.transpiler[1] ?? {}; + // TODO mimic fixed resolution logic from loadCompiler main + // TODO refactor into a more generic "resolve dep relative to project" helper + const transpilerPath = require.resolve(transpilerName, { + paths: [cwd, __dirname], + }); + const transpilerFactory: TranspilerFactory = require(transpilerPath).create; + customTranspiler = transpilerFactory({ + service: { options, config }, + ...transpilerOptions, + }); } // Install source map support and read from memory cache. sourceMapSupport.install({ environment: 'node', - retrieveFile (pathOrUrl: string) { - let path = pathOrUrl + retrieveFile(pathOrUrl: string) { + let path = pathOrUrl; // If it's a file URL, convert to local path // Note: fileURLToPath does not exist on early node v10 // I could not find a way to handle non-URLs except to swallow an error if (options.experimentalEsmLoader && path.startsWith('file://')) { try { - path = fileURLToPath(path) - } catch (e) {/* swallow error */} + path = fileURLToPath(path); + } catch (e) { + /* swallow error */ + } } - path = normalizeSlashes(path) - return outputCache.get(path)?.content || '' - } - }) - - const formatDiagnostics = process.stdout.isTTY || options.pretty - ? (ts.formatDiagnosticsWithColorAndContext || ts.formatDiagnostics) - : ts.formatDiagnostics - - function createTSError (diagnostics: ReadonlyArray<_ts.Diagnostic>) { - const diagnosticText = formatDiagnostics(diagnostics, diagnosticHost) - const diagnosticCodes = diagnostics.map(x => x.code) - return new TSError(diagnosticText, diagnosticCodes) + path = normalizeSlashes(path); + return outputCache.get(path)?.content || ''; + }, + }); + + const shouldHavePrettyErrors = + options.pretty === undefined ? process.stdout.isTTY : options.pretty; + + const formatDiagnostics = shouldHavePrettyErrors + ? ts.formatDiagnosticsWithColorAndContext || ts.formatDiagnostics + : ts.formatDiagnostics; + + function createTSError(diagnostics: ReadonlyArray<_ts.Diagnostic>) { + const diagnosticText = formatDiagnostics(diagnostics, diagnosticHost); + const diagnosticCodes = diagnostics.map((x) => x.code); + return new TSError(diagnosticText, diagnosticCodes); } - function reportTSError (configDiagnosticList: _ts.Diagnostic[]) { - const error = createTSError(configDiagnosticList) + function reportTSError(configDiagnosticList: _ts.Diagnostic[]) { + const error = createTSError(configDiagnosticList); if (options.logError) { // Print error in red color and continue execution. - console.error('\x1b[31m%s\x1b[0m', error) + console.error('\x1b[31m%s\x1b[0m', error); } else { // Throw error and exit the script. - throw error + throw error; } } // Render the configuration errors. - if (configDiagnosticList.length) reportTSError(configDiagnosticList) + if (configDiagnosticList.length) reportTSError(configDiagnosticList); /** * Get the extension for a transpiled file. */ - const getExtension = config.options.jsx === ts.JsxEmit.Preserve ? - ((path: string) => /\.[tj]sx$/.test(path) ? '.jsx' : '.js') : - ((_: string) => '.js') + const getExtension = + config.options.jsx === ts.JsxEmit.Preserve + ? (path: string) => (/\.[tj]sx$/.test(path) ? '.jsx' : '.js') + : (_: string) => '.js'; + type GetOutputFunction = (code: string, fileName: string) => SourceOutput; /** * Create the basic required function using transpile mode. */ - let getOutput: (code: string, fileName: string) => SourceOutput - let getTypeInfo: (_code: string, _fileName: string, _position: number) => TypeInfo - - const getCanonicalFileName = (ts as unknown as TSInternal).createGetCanonicalFileName(ts.sys.useCaseSensitiveFileNames) - - // In a factory because these are shared across both CompilerHost and LanguageService codepaths - function createResolverFunctions (serviceHost: _ts.ModuleResolutionHost) { - const moduleResolutionCache = ts.createModuleResolutionCache(cwd, getCanonicalFileName, config.options) - const knownInternalFilenames = new Set() - /** "Buckets" (module directories) whose contents should be marked "internal" */ - const internalBuckets = new Set() - - // Get bucket for a source filename. Bucket is the containing `./node_modules/*/` directory - // For '/project/node_modules/foo/node_modules/bar/lib/index.js' bucket is '/project/node_modules/foo/node_modules/bar/' - // For '/project/node_modules/foo/node_modules/@scope/bar/lib/index.js' bucket is '/project/node_modules/foo/node_modules/@scope/bar/' - const moduleBucketRe = /.*\/node_modules\/(?:@[^\/]+\/)?[^\/]+\// - function getModuleBucket (filename: string) { - const find = moduleBucketRe.exec(filename) - if (find) return find[0] - return '' - } - - // Mark that this file and all siblings in its bucket should be "internal" - function markBucketOfFilenameInternal (filename: string) { - internalBuckets.add(getModuleBucket(filename)) - } - - function isFileInInternalBucket (filename: string) { - return internalBuckets.has(getModuleBucket(filename)) - } - - function isFileKnownToBeInternal (filename: string) { - return knownInternalFilenames.has(filename) - } - - /** - * If we need to emit JS for a file, force TS to consider it non-external - */ - const fixupResolvedModule = (resolvedModule: _ts.ResolvedModule | _ts.ResolvedTypeReferenceDirective) => { - const { resolvedFileName } = resolvedModule - if (resolvedFileName === undefined) return - // .ts is always switched to internal - // .js is switched on-demand - if ( - resolvedModule.isExternalLibraryImport && ( - (resolvedFileName.endsWith('.ts') && !resolvedFileName.endsWith('.d.ts')) || - isFileKnownToBeInternal(resolvedFileName) || - isFileInInternalBucket(resolvedFileName) - ) - ) { - resolvedModule.isExternalLibraryImport = false - } - if (!resolvedModule.isExternalLibraryImport) { - knownInternalFilenames.add(resolvedFileName) - } - } - /* - * NOTE: - * Older ts versions do not pass `redirectedReference` nor `options`. - * We must pass `redirectedReference` to newer ts versions, but cannot rely on `options`, hence the weird argument name - */ - const resolveModuleNames: _ts.LanguageServiceHost['resolveModuleNames'] = (moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference: _ts.ResolvedProjectReference | undefined, optionsOnlyWithNewerTsVersions: _ts.CompilerOptions): (_ts.ResolvedModule | undefined)[] => { - return moduleNames.map(moduleName => { - const { resolvedModule } = ts.resolveModuleName(moduleName, containingFile, config.options, serviceHost, moduleResolutionCache, redirectedReference) - if (resolvedModule) { - fixupResolvedModule(resolvedModule) - } - return resolvedModule - }) - } - - // language service never calls this, but TS docs recommend that we implement it - const getResolvedModuleWithFailedLookupLocationsFromCache: _ts.LanguageServiceHost['getResolvedModuleWithFailedLookupLocationsFromCache'] = (moduleName, containingFile): _ts.ResolvedModuleWithFailedLookupLocations | undefined => { - const ret = ts.resolveModuleNameFromCache(moduleName, containingFile, moduleResolutionCache) - if (ret && ret.resolvedModule) { - fixupResolvedModule(ret.resolvedModule) - } - return ret - } - - const resolveTypeReferenceDirectives: _ts.LanguageServiceHost['resolveTypeReferenceDirectives'] = (typeDirectiveNames: string[], containingFile: string, redirectedReference: _ts.ResolvedProjectReference | undefined, options: _ts.CompilerOptions): (_ts.ResolvedTypeReferenceDirective | undefined)[] => { - // Note: seems to be called with empty typeDirectiveNames array for all files. - return typeDirectiveNames.map(typeDirectiveName => { - const { resolvedTypeReferenceDirective } = ts.resolveTypeReferenceDirective(typeDirectiveName, containingFile, config.options, serviceHost, redirectedReference) - if (resolvedTypeReferenceDirective) { - fixupResolvedModule(resolvedTypeReferenceDirective) - } - return resolvedTypeReferenceDirective - }) - } - - return { - resolveModuleNames, - getResolvedModuleWithFailedLookupLocationsFromCache, - resolveTypeReferenceDirectives, - isFileKnownToBeInternal, - markBucketOfFilenameInternal - } - } + let getOutput: GetOutputFunction; + let getTypeInfo: ( + _code: string, + _fileName: string, + _position: number + ) => TypeInfo; + + const getCanonicalFileName = ((ts as unknown) as TSInternal).createGetCanonicalFileName( + ts.sys.useCaseSensitiveFileNames + ); + + const moduleTypeClassifier = createModuleTypeClassifier({ + basePath: options.optionBasePaths?.moduleTypes, + patterns: options.moduleTypes, + }); // Use full language services when the fast option is disabled. if (!transpileOnly) { - const fileContents = new Map() - const rootFileNames = new Set(config.fileNames) - const cachedReadFile = cachedLookup(debugFn('readFile', readFile)) + const fileContents = new Map(); + const rootFileNames = new Set(config.fileNames); + const cachedReadFile = cachedLookup(debugFn('readFile', readFile)); // Use language services by default (TODO: invert next major version). if (!options.compilerHost) { - let projectVersion = 1 - const fileVersions = new Map(Array.from(rootFileNames).map(fileName => [fileName, 0])) + let projectVersion = 1; + const fileVersions = new Map( + Array.from(rootFileNames).map((fileName) => [fileName, 0]) + ); const getCustomTransformers = () => { if (typeof transformers === 'function') { - const program = service.getProgram() - return program ? transformers(program) : undefined + const program = service.getProgram(); + return program ? transformers(program) : undefined; } - return transformers - } + return transformers; + }; // Create the compiler host for type checking. - const serviceHost: _ts.LanguageServiceHost & Required> = { + const serviceHost: _ts.LanguageServiceHost & + Required> = { getProjectVersion: () => String(projectVersion), getScriptFileNames: () => Array.from(rootFileNames), getScriptVersion: (fileName: string) => { - const version = fileVersions.get(fileName) - return version ? version.toString() : '' + const version = fileVersions.get(fileName); + return version ? version.toString() : ''; }, - getScriptSnapshot (fileName: string) { + getScriptSnapshot(fileName: string) { // TODO ordering of this with getScriptVersion? Should they sync up? - let contents = fileContents.get(fileName) + let contents = fileContents.get(fileName); // Read contents into TypeScript memory cache. if (contents === undefined) { - contents = cachedReadFile(fileName) - if (contents === undefined) return + contents = cachedReadFile(fileName); + if (contents === undefined) return; - fileVersions.set(fileName, 1) - fileContents.set(fileName, contents) - projectVersion++ + fileVersions.set(fileName, 1); + fileContents.set(fileName, contents); + projectVersion++; } - return ts.ScriptSnapshot.fromString(contents) + return ts.ScriptSnapshot.fromString(contents); }, readFile: cachedReadFile, readDirectory: ts.sys.readDirectory, - getDirectories: cachedLookup(debugFn('getDirectories', ts.sys.getDirectories)), + getDirectories: cachedLookup( + debugFn('getDirectories', ts.sys.getDirectories) + ), fileExists: cachedLookup(debugFn('fileExists', fileExists)), - directoryExists: cachedLookup(debugFn('directoryExists', ts.sys.directoryExists)), - realpath: ts.sys.realpath ? cachedLookup(debugFn('realpath', ts.sys.realpath)) : undefined, + directoryExists: cachedLookup( + debugFn('directoryExists', ts.sys.directoryExists) + ), + realpath: ts.sys.realpath + ? cachedLookup(debugFn('realpath', ts.sys.realpath)) + : undefined, getNewLine: () => ts.sys.newLine, useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames, getCurrentDirectory: () => cwd, getCompilationSettings: () => config.options, getDefaultLibFileName: () => ts.getDefaultLibFilePath(config.options), - getCustomTransformers: getCustomTransformers - } - const { resolveModuleNames, getResolvedModuleWithFailedLookupLocationsFromCache, resolveTypeReferenceDirectives, isFileKnownToBeInternal, markBucketOfFilenameInternal } = createResolverFunctions(serviceHost) - serviceHost.resolveModuleNames = resolveModuleNames - serviceHost.getResolvedModuleWithFailedLookupLocationsFromCache = getResolvedModuleWithFailedLookupLocationsFromCache - serviceHost.resolveTypeReferenceDirectives = resolveTypeReferenceDirectives - - const registry = ts.createDocumentRegistry(ts.sys.useCaseSensitiveFileNames, cwd) - const service = ts.createLanguageService(serviceHost, registry) + getCustomTransformers: getCustomTransformers, + }; + const { + resolveModuleNames, + getResolvedModuleWithFailedLookupLocationsFromCache, + resolveTypeReferenceDirectives, + isFileKnownToBeInternal, + markBucketOfFilenameInternal, + } = createResolverFunctions({ + serviceHost, + getCanonicalFileName, + ts, + cwd, + config, + configFilePath, + }); + serviceHost.resolveModuleNames = resolveModuleNames; + serviceHost.getResolvedModuleWithFailedLookupLocationsFromCache = getResolvedModuleWithFailedLookupLocationsFromCache; + serviceHost.resolveTypeReferenceDirectives = resolveTypeReferenceDirectives; + + const registry = ts.createDocumentRegistry( + ts.sys.useCaseSensitiveFileNames, + cwd + ); + const service = ts.createLanguageService(serviceHost, registry); const updateMemoryCache = (contents: string, fileName: string) => { // Add to `rootFiles` as necessary, either to make TS include a file it has not seen, // or to trigger a re-classification of files from external to internal. - if (!rootFileNames.has(fileName) && !isFileKnownToBeInternal(fileName)) { - markBucketOfFilenameInternal(fileName) - rootFileNames.add(fileName) + if ( + !rootFileNames.has(fileName) && + !isFileKnownToBeInternal(fileName) + ) { + markBucketOfFilenameInternal(fileName); + rootFileNames.add(fileName); // Increment project version for every change to rootFileNames. - projectVersion++ + projectVersion++; } - const previousVersion = fileVersions.get(fileName) || 0 - const previousContents = fileContents.get(fileName) + const previousVersion = fileVersions.get(fileName) || 0; + const previousContents = fileContents.get(fileName); // Avoid incrementing cache when nothing has changed. if (contents !== previousContents) { - fileVersions.set(fileName, previousVersion + 1) - fileContents.set(fileName, contents) + fileVersions.set(fileName, previousVersion + 1); + fileContents.set(fileName, contents); // Increment project version for every file change. - projectVersion++ + projectVersion++; } - } + }; - let previousProgram: _ts.Program | undefined = undefined + let previousProgram: _ts.Program | undefined = undefined; getOutput = (code: string, fileName: string) => { - updateMemoryCache(code, fileName) + updateMemoryCache(code, fileName); - const programBefore = service.getProgram() + const programBefore = service.getProgram(); if (programBefore !== previousProgram) { - debug(`compiler rebuilt Program instance when getting output for ${fileName}`) + debug( + `compiler rebuilt Program instance when getting output for ${fileName}` + ); } - const output = service.getEmitOutput(fileName) + const output = service.getEmitOutput(fileName); // Get the relevant diagnostics - this is 3x faster than `getPreEmitDiagnostics`. - const diagnostics = service.getSemanticDiagnostics(fileName) - .concat(service.getSyntacticDiagnostics(fileName)) + const diagnostics = service + .getSemanticDiagnostics(fileName) + .concat(service.getSyntacticDiagnostics(fileName)); - const programAfter = service.getProgram() + const programAfter = service.getProgram(); debug( 'invariant: Is service.getProject() identical before and after getting emit output and diagnostics? (should always be true) ', programBefore === programAfter - ) + ); - previousProgram = programAfter + previousProgram = programAfter; - const diagnosticList = filterDiagnostics(diagnostics, ignoreDiagnostics) - if (diagnosticList.length) reportTSError(diagnosticList) + const diagnosticList = filterDiagnostics( + diagnostics, + diagnosticFilters + ); + if (diagnosticList.length) reportTSError(diagnosticList); if (output.emitSkipped) { - throw new TypeError(`${relative(cwd, fileName)}: Emit skipped`) + throw new TypeError(`${relative(cwd, fileName)}: Emit skipped`); } // Throw an error when requiring `.d.ts` files. if (output.outputFiles.length === 0) { throw new TypeError( `Unable to require file: ${relative(cwd, fileName)}\n` + - 'This is usually the result of a faulty configuration or import. ' + - 'Make sure there is a `.js`, `.json` or other executable extension with ' + - 'loader attached before `ts-node` available.' - ) + 'This is usually the result of a faulty configuration or import. ' + + 'Make sure there is a `.js`, `.json` or other executable extension with ' + + 'loader attached before `ts-node` available.' + ); } - return [output.outputFiles[1].text, output.outputFiles[0].text] - } + return [output.outputFiles[1].text, output.outputFiles[0].text]; + }; getTypeInfo = (code: string, fileName: string, position: number) => { - updateMemoryCache(code, fileName) + updateMemoryCache(code, fileName); - const info = service.getQuickInfoAtPosition(fileName, position) - const name = ts.displayPartsToString(info ? info.displayParts : []) - const comment = ts.displayPartsToString(info ? info.documentation : []) + const info = service.getQuickInfoAtPosition(fileName, position); + const name = ts.displayPartsToString(info ? info.displayParts : []); + const comment = ts.displayPartsToString(info ? info.documentation : []); - return { name, comment } - } + return { name, comment }; + }; } else { const sys: _ts.System & _ts.FormatDiagnosticsHost = { ...ts.sys, ...diagnosticHost, readFile: (fileName: string) => { - const cacheContents = fileContents.get(fileName) - if (cacheContents !== undefined) return cacheContents - const contents = cachedReadFile(fileName) - if (contents) fileContents.set(fileName, contents) - return contents + const cacheContents = fileContents.get(fileName); + if (cacheContents !== undefined) return cacheContents; + const contents = cachedReadFile(fileName); + if (contents) fileContents.set(fileName, contents); + return contents; }, readDirectory: ts.sys.readDirectory, - getDirectories: cachedLookup(debugFn('getDirectories', ts.sys.getDirectories)), + getDirectories: cachedLookup( + debugFn('getDirectories', ts.sys.getDirectories) + ), fileExists: cachedLookup(debugFn('fileExists', fileExists)), - directoryExists: cachedLookup(debugFn('directoryExists', ts.sys.directoryExists)), + directoryExists: cachedLookup( + debugFn('directoryExists', ts.sys.directoryExists) + ), resolvePath: cachedLookup(debugFn('resolvePath', ts.sys.resolvePath)), - realpath: ts.sys.realpath ? cachedLookup(debugFn('realpath', ts.sys.realpath)) : undefined - } + realpath: ts.sys.realpath + ? cachedLookup(debugFn('realpath', ts.sys.realpath)) + : undefined, + }; const host: _ts.CompilerHost = ts.createIncrementalCompilerHost ? ts.createIncrementalCompilerHost(config.options, sys) : { - ...sys, - getSourceFile: (fileName, languageVersion) => { - const contents = sys.readFile(fileName) - if (contents === undefined) return - return ts.createSourceFile(fileName, contents, languageVersion) - }, - getDefaultLibLocation: () => normalizeSlashes(dirname(compiler)), - getDefaultLibFileName: () => normalizeSlashes(join(dirname(compiler), ts.getDefaultLibFileName(config.options))), - useCaseSensitiveFileNames: () => sys.useCaseSensitiveFileNames - } - const { resolveModuleNames, resolveTypeReferenceDirectives, isFileKnownToBeInternal, markBucketOfFilenameInternal } = createResolverFunctions(host) - host.resolveModuleNames = resolveModuleNames - host.resolveTypeReferenceDirectives = resolveTypeReferenceDirectives + ...sys, + getSourceFile: (fileName, languageVersion) => { + const contents = sys.readFile(fileName); + if (contents === undefined) return; + return ts.createSourceFile(fileName, contents, languageVersion); + }, + getDefaultLibLocation: () => normalizeSlashes(dirname(compiler)), + getDefaultLibFileName: () => + normalizeSlashes( + join( + dirname(compiler), + ts.getDefaultLibFileName(config.options) + ) + ), + useCaseSensitiveFileNames: () => sys.useCaseSensitiveFileNames, + }; + const { + resolveModuleNames, + resolveTypeReferenceDirectives, + isFileKnownToBeInternal, + markBucketOfFilenameInternal, + } = createResolverFunctions({ + serviceHost: host, + cwd, + configFilePath, + config, + ts, + getCanonicalFileName, + }); + host.resolveModuleNames = resolveModuleNames; + host.resolveTypeReferenceDirectives = resolveTypeReferenceDirectives; // Fallback for older TypeScript releases without incremental API. let builderProgram = ts.createIncrementalProgram ? ts.createIncrementalProgram({ - rootNames: Array.from(rootFileNames), - options: config.options, - host: host, - configFileParsingDiagnostics: config.errors, - projectReferences: config.projectReferences - }) + rootNames: Array.from(rootFileNames), + options: config.options, + host: host, + configFileParsingDiagnostics: config.errors, + projectReferences: config.projectReferences, + }) : ts.createEmitAndSemanticDiagnosticsBuilderProgram( - Array.from(rootFileNames), - config.options, - host, - undefined, - config.errors, - config.projectReferences - ) + Array.from(rootFileNames), + config.options, + host, + undefined, + config.errors, + config.projectReferences + ); // Read and cache custom transformers. - const customTransformers = typeof transformers === 'function' - ? transformers(builderProgram.getProgram()) - : transformers + const customTransformers = + typeof transformers === 'function' + ? transformers(builderProgram.getProgram()) + : transformers; // Set the file contents into cache manually. const updateMemoryCache = (contents: string, fileName: string) => { - const previousContents = fileContents.get(fileName) - const contentsChanged = previousContents !== contents + const previousContents = fileContents.get(fileName); + const contentsChanged = previousContents !== contents; if (contentsChanged) { - fileContents.set(fileName, contents) + fileContents.set(fileName, contents); } // Add to `rootFiles` when discovered by compiler for the first time. - let addedToRootFileNames = false - if (!rootFileNames.has(fileName) && !isFileKnownToBeInternal(fileName)) { - markBucketOfFilenameInternal(fileName) - rootFileNames.add(fileName) - addedToRootFileNames = true + let addedToRootFileNames = false; + if ( + !rootFileNames.has(fileName) && + !isFileKnownToBeInternal(fileName) + ) { + markBucketOfFilenameInternal(fileName); + rootFileNames.add(fileName); + addedToRootFileNames = true; } // Update program when file changes. @@ -848,141 +1021,235 @@ export function create (rawOptions: CreateOptions = {}): Register { builderProgram, config.errors, config.projectReferences - ) + ); } - } + }; getOutput = (code: string, fileName: string) => { - const output: [string, string] = ['', ''] - - updateMemoryCache(code, fileName) - - const sourceFile = builderProgram.getSourceFile(fileName) - if (!sourceFile) throw new TypeError(`Unable to read file: ${fileName}`) - - const program = builderProgram.getProgram() - const diagnostics = ts.getPreEmitDiagnostics(program, sourceFile) - const diagnosticList = filterDiagnostics(diagnostics, ignoreDiagnostics) - if (diagnosticList.length) reportTSError(diagnosticList) - - const result = builderProgram.emit(sourceFile, (path, file, writeByteOrderMark) => { - if (path.endsWith('.map')) { - output[1] = file - } else { - output[0] = file - } - - if (options.emit) sys.writeFile(path, file, writeByteOrderMark) - }, undefined, undefined, customTransformers) + const output: [string, string] = ['', '']; + + updateMemoryCache(code, fileName); + + const sourceFile = builderProgram.getSourceFile(fileName); + if (!sourceFile) + throw new TypeError(`Unable to read file: ${fileName}`); + + const program = builderProgram.getProgram(); + const diagnostics = ts.getPreEmitDiagnostics(program, sourceFile); + const diagnosticList = filterDiagnostics( + diagnostics, + diagnosticFilters + ); + if (diagnosticList.length) reportTSError(diagnosticList); + + const result = builderProgram.emit( + sourceFile, + (path, file, writeByteOrderMark) => { + if (path.endsWith('.map')) { + output[1] = file; + } else { + output[0] = file; + } + + if (options.emit) sys.writeFile(path, file, writeByteOrderMark); + }, + undefined, + undefined, + customTransformers + ); if (result.emitSkipped) { - throw new TypeError(`${relative(cwd, fileName)}: Emit skipped`) + throw new TypeError(`${relative(cwd, fileName)}: Emit skipped`); } // Throw an error when requiring files that cannot be compiled. if (output[0] === '') { if (program.isSourceFileFromExternalLibrary(sourceFile)) { - throw new TypeError(`Unable to compile file from external library: ${relative(cwd, fileName)}`) + throw new TypeError( + `Unable to compile file from external library: ${relative( + cwd, + fileName + )}` + ); } throw new TypeError( `Unable to require file: ${relative(cwd, fileName)}\n` + - 'This is usually the result of a faulty configuration or import. ' + - 'Make sure there is a `.js`, `.json` or other executable extension with ' + - 'loader attached before `ts-node` available.' - ) + 'This is usually the result of a faulty configuration or import. ' + + 'Make sure there is a `.js`, `.json` or other executable extension with ' + + 'loader attached before `ts-node` available.' + ); } - return output - } + return output; + }; getTypeInfo = (code: string, fileName: string, position: number) => { - updateMemoryCache(code, fileName) + updateMemoryCache(code, fileName); - const sourceFile = builderProgram.getSourceFile(fileName) - if (!sourceFile) throw new TypeError(`Unable to read file: ${fileName}`) + const sourceFile = builderProgram.getSourceFile(fileName); + if (!sourceFile) + throw new TypeError(`Unable to read file: ${fileName}`); - const node = getTokenAtPosition(ts, sourceFile, position) - const checker = builderProgram.getProgram().getTypeChecker() - const symbol = checker.getSymbolAtLocation(node) + const node = getTokenAtPosition(ts, sourceFile, position); + const checker = builderProgram.getProgram().getTypeChecker(); + const symbol = checker.getSymbolAtLocation(node); - if (!symbol) return { name: '', comment: '' } + if (!symbol) return { name: '', comment: '' }; - const type = checker.getTypeOfSymbolAtLocation(symbol, node) - const signatures = [...type.getConstructSignatures(), ...type.getCallSignatures()] + const type = checker.getTypeOfSymbolAtLocation(symbol, node); + const signatures = [ + ...type.getConstructSignatures(), + ...type.getCallSignatures(), + ]; return { - name: signatures.length ? signatures.map(x => checker.signatureToString(x)).join('\n') : checker.typeToString(type), - comment: ts.displayPartsToString(symbol ? symbol.getDocumentationComment(checker) : []) - } - } + name: signatures.length + ? signatures.map((x) => checker.signatureToString(x)).join('\n') + : checker.typeToString(type), + comment: ts.displayPartsToString( + symbol ? symbol.getDocumentationComment(checker) : [] + ), + }; + }; // Write `.tsbuildinfo` when `--build` is enabled. if (options.emit && config.options.incremental) { process.on('exit', () => { // Emits `.tsbuildinfo` to filesystem. - (builderProgram.getProgram() as any).emitBuildInfo() - }) + (builderProgram.getProgram() as any).emitBuildInfo(); + }); } } } else { - if (typeof transformers === 'function') { - throw new TypeError('Transformers function is unavailable in "--transpile-only"') - } + getOutput = createTranspileOnlyGetOutputFunction(); - getOutput = (code: string, fileName: string): SourceOutput => { - const result = ts.transpileModule(code, { - fileName, - compilerOptions: config.options, - reportDiagnostics: true, - transformers: transformers - }) + getTypeInfo = () => { + throw new TypeError( + 'Type information is unavailable in "--transpile-only"' + ); + }; + } - const diagnosticList = filterDiagnostics(result.diagnostics || [], ignoreDiagnostics) - if (diagnosticList.length) reportTSError(diagnosticList) + function createTranspileOnlyGetOutputFunction( + overrideModuleType?: _ts.ModuleKind + ): GetOutputFunction { + const compilerOptions = { ...config.options }; + if (overrideModuleType !== undefined) + compilerOptions.module = overrideModuleType; + return (code: string, fileName: string): SourceOutput => { + let result: _ts.TranspileOutput; + if (customTranspiler) { + result = customTranspiler.transpile(code, { + fileName, + }); + } else { + result = ts.transpileModule(code, { + fileName, + compilerOptions, + reportDiagnostics: true, + transformers: transformers as _ts.CustomTransformers | undefined, + }); + } - return [result.outputText, result.sourceMapText as string] - } + const diagnosticList = filterDiagnostics( + result.diagnostics || [], + diagnosticFilters + ); + if (diagnosticList.length) reportTSError(diagnosticList); - getTypeInfo = () => { - throw new TypeError('Type information is unavailable in "--transpile-only"') - } + return [result.outputText, result.sourceMapText as string]; + }; } + // When either is undefined, it means normal `getOutput` should be used + const getOutputForceCommonJS = + config.options.module === ts.ModuleKind.CommonJS + ? undefined + : createTranspileOnlyGetOutputFunction(ts.ModuleKind.CommonJS); + const getOutputForceESM = + config.options.module === ts.ModuleKind.ES2015 || + config.options.module === ts.ModuleKind.ES2020 || + config.options.module === ts.ModuleKind.ESNext + ? undefined + : createTranspileOnlyGetOutputFunction( + ts.ModuleKind.ES2020 || ts.ModuleKind.ES2015 + ); + // Create a simple TypeScript compiler proxy. - function compile (code: string, fileName: string, lineOffset = 0) { - const normalizedFileName = normalizeSlashes(fileName) - const [value, sourceMap] = getOutput(code, normalizedFileName) - const output = updateOutput(value, normalizedFileName, sourceMap, getExtension) - outputCache.set(normalizedFileName, { content: output }) - return output + function compile(code: string, fileName: string, lineOffset = 0) { + const normalizedFileName = normalizeSlashes(fileName); + const classification = moduleTypeClassifier.classifyModule( + normalizedFileName + ); + // Must always call normal getOutput to throw typechecking errors + let [value, sourceMap] = getOutput(code, normalizedFileName); + // If module classification contradicts the above, call the relevant transpiler + if (classification.moduleType === 'cjs' && getOutputForceCommonJS) { + [value, sourceMap] = getOutputForceCommonJS(code, normalizedFileName); + } else if (classification.moduleType === 'esm' && getOutputForceESM) { + [value, sourceMap] = getOutputForceESM(code, normalizedFileName); + } + const output = updateOutput( + value, + normalizedFileName, + sourceMap, + getExtension + ); + outputCache.set(normalizedFileName, { content: output }); + return output; } - let active = true - const enabled = (enabled?: boolean) => enabled === undefined ? active : (active = !!enabled) - const extensions = getExtensions(config) + let active = true; + const enabled = (enabled?: boolean) => + enabled === undefined ? active : (active = !!enabled); + const extensions = getExtensions(config); const ignored = (fileName: string) => { - if (!active) return true - const ext = extname(fileName) - if (extensions.tsExtensions.includes(ext) || extensions.jsExtensions.includes(ext)) { - const relname = relative(cwd, fileName) - return !isScoped(relname) || shouldIgnore(relname) + if (!active) return true; + const ext = extname(fileName); + if ( + extensions.tsExtensions.includes(ext) || + extensions.jsExtensions.includes(ext) + ) { + return !isScoped(fileName) || shouldIgnore(fileName); } - return true + return true; + }; + + function addDiagnosticFilter(filter: DiagnosticFilter) { + diagnosticFilters.push({ + ...filter, + filenamesAbsolute: filter.filenamesAbsolute.map((f) => + normalizeSlashes(f) + ), + }); } - return { ts, config, compile, getTypeInfo, ignored, enabled, options } + return { + ts, + config, + compile, + getTypeInfo, + ignored, + enabled, + options, + configFilePath, + moduleTypeClassifier, + shouldReplAwait, + addDiagnosticFilter, + }; } /** * Check if the filename should be ignored. */ -function createIgnore (ignore: RegExp[]) { - return (relname: string) => { - const path = normalizeSlashes(relname) +function createIgnore(ignoreBaseDir: string, ignore: RegExp[]) { + return (fileName: string) => { + const relname = relative(ignoreBaseDir, fileName); + const path = normalizeSlashes(relname); - return ignore.some(x => x.test(path)) - } + return ignore.some((x) => x.test(path)); + }; } /** @@ -990,205 +1257,151 @@ function createIgnore (ignore: RegExp[]) { * * @param {string} ext */ -function reorderRequireExtension (ext: string) { - const old = require.extensions[ext] // tslint:disable-line - delete require.extensions[ext] // tslint:disable-line - require.extensions[ext] = old // tslint:disable-line +function reorderRequireExtension(ext: string) { + const old = require.extensions[ext]; + delete require.extensions[ext]; + require.extensions[ext] = old; } /** * Register the extensions to support when importing files. */ -function registerExtensions ( +function registerExtensions( preferTsExts: boolean | null | undefined, extensions: string[], - register: Register, + service: Service, originalJsHandler: (m: NodeModule, filename: string) => any ) { // Register new extensions. for (const ext of extensions) { - registerExtension(ext, register, originalJsHandler) + registerExtension(ext, service, originalJsHandler); } if (preferTsExts) { - // tslint:disable-next-line - const preferredExtensions = new Set([...extensions, ...Object.keys(require.extensions)]) + const preferredExtensions = new Set([ + ...extensions, + ...Object.keys(require.extensions), + ]); - for (const ext of preferredExtensions) reorderRequireExtension(ext) + for (const ext of preferredExtensions) reorderRequireExtension(ext); } } /** * Register the extension for node. */ -function registerExtension ( +function registerExtension( ext: string, - register: Register, + service: Service, originalHandler: (m: NodeModule, filename: string) => any ) { - const old = require.extensions[ext] || originalHandler // tslint:disable-line + const old = require.extensions[ext] || originalHandler; - require.extensions[ext] = function (m: any, filename) { // tslint:disable-line - if (register.ignored(filename)) return old(m, filename) + require.extensions[ext] = function (m: any, filename) { + if (service.ignored(filename)) return old(m, filename); - if (register.options.experimentalEsmLoader) { - assertScriptCanLoadAsCJS(filename) - } + assertScriptCanLoadAsCJS(service, m, filename); - const _compile = m._compile + const _compile = m._compile; m._compile = function (code: string, fileName: string) { - debug('module._compile', fileName) - - return _compile.call(this, register.compile(code, fileName), fileName) - } - - return old(m, filename) - } -} - -/** - * Do post-processing on config options to support `ts-node`. - */ -function fixConfig (ts: TSCommon, config: _ts.ParsedCommandLine) { - // Delete options that *should not* be passed through. - delete config.options.out - delete config.options.outFile - delete config.options.composite - delete config.options.declarationDir - delete config.options.declarationMap - delete config.options.emitDeclarationOnly - - // Target ES5 output by default (instead of ES3). - if (config.options.target === undefined) { - config.options.target = ts.ScriptTarget.ES5 - } + debug('module._compile', fileName); - // Target CommonJS modules by default (instead of magically switching to ES6 when the target is ES6). - if (config.options.module === undefined) { - config.options.module = ts.ModuleKind.CommonJS - } + const result = service.compile(code, fileName); + return _compile.call(this, result, fileName); + }; - return config -} - -/** - * Load TypeScript configuration. Returns the parsed TypeScript config and - * any `ts-node` options specified in the config file. - */ -function readConfig ( - cwd: string, - ts: TSCommon, - rawOptions: CreateOptions -): { - // Parsed TypeScript configuration. - config: _ts.ParsedCommandLine - // Options pulled from `tsconfig.json`. - options: TsConfigOptions -} { - let config: any = { compilerOptions: {} } - let basePath = cwd - let configFileName: string | undefined = undefined - - const { - fileExists = ts.sys.fileExists, - readFile = ts.sys.readFile, - skipProject = DEFAULTS.skipProject, - project = DEFAULTS.project - } = rawOptions - - // Read project configuration when available. - if (!skipProject) { - configFileName = project - ? resolve(cwd, project) - : ts.findConfigFile(cwd, fileExists) - - if (configFileName) { - const result = ts.readConfigFile(configFileName, readFile) - - // Return diagnostics. - if (result.error) { - return { - config: { errors: [result.error], fileNames: [], options: {} }, - options: {} - } - } - - config = result.config - basePath = dirname(configFileName) - } - } - - // Fix ts-node options that come from tsconfig.json - const tsconfigOptions: TsConfigOptions = Object.assign({}, config['ts-node']) - - // Remove resolution of "files". - const files = rawOptions.files ?? tsconfigOptions.files ?? DEFAULTS.files - if (!files) { - config.files = [] - config.include = [] - } - - // Override default configuration options `ts-node` requires. - config.compilerOptions = Object.assign( - {}, - config.compilerOptions, - DEFAULTS.compilerOptions, - tsconfigOptions.compilerOptions, - rawOptions.compilerOptions, - TS_NODE_COMPILER_OPTIONS - ) - - const fixedConfig = fixConfig(ts, ts.parseJsonConfigFileContent(config, { - fileExists, - readFile, - readDirectory: ts.sys.readDirectory, - useCaseSensitiveFileNames: ts.sys.useCaseSensitiveFileNames - }, basePath, undefined, configFileName)) - - if (tsconfigOptions.require) { - // Modules are found relative to the tsconfig file, not the `dir` option - const tsconfigRelativeRequire = createRequire(configFileName!) - tsconfigOptions.require = tsconfigOptions.require.map((path: string) => { - return tsconfigRelativeRequire.resolve(path) - }) - } - - return { config: fixedConfig, options: tsconfigOptions } + return old(m, filename); + }; } /** * Internal source output. */ -type SourceOutput = [string, string] +type SourceOutput = [string, string]; /** * Update the output remapping the source map. */ -function updateOutput (outputText: string, fileName: string, sourceMap: string, getExtension: (fileName: string) => string) { - const base64Map = Buffer.from(updateSourceMap(sourceMap, fileName), 'utf8').toString('base64') - const sourceMapContent = `data:application/json;charset=utf-8;base64,${base64Map}` - const sourceMapLength = `${basename(fileName)}.map`.length + (getExtension(fileName).length - extname(fileName).length) +function updateOutput( + outputText: string, + fileName: string, + sourceMap: string, + getExtension: (fileName: string) => string +) { + const base64Map = Buffer.from( + updateSourceMap(sourceMap, fileName), + 'utf8' + ).toString('base64'); + const sourceMapContent = `//# sourceMappingURL=data:application/json;charset=utf-8;base64,${base64Map}`; + // Expected form: `//# sourceMappingURL=foo bar.js.map` or `//# sourceMappingURL=foo%20bar.js.map` for input file "foo bar.tsx" + // Percent-encoding behavior added in TS 4.1.1: https://github.com/microsoft/TypeScript/issues/40951 + const prefix = '//# sourceMappingURL='; + const prefixLength = prefix.length; + const baseName = /*foo.tsx*/ basename(fileName); + const extName = /*.tsx*/ extname(fileName); + const extension = /*.js*/ getExtension(fileName); + const sourcemapFilename = + baseName.slice(0, -extName.length) + extension + '.map'; + const sourceMapLengthWithoutPercentEncoding = + prefixLength + sourcemapFilename.length; + /* + * Only rewrite if existing directive exists at the location we expect, to support: + * a) compilers that do not append a sourcemap directive + * b) situations where we did the math wrong + * Not ideal, but appending our sourcemap *after* a pre-existing sourcemap still overrides, so the end-user is happy. + */ + if ( + outputText.substr(-sourceMapLengthWithoutPercentEncoding, prefixLength) === + prefix + ) { + return ( + outputText.slice(0, -sourceMapLengthWithoutPercentEncoding) + + sourceMapContent + ); + } + // If anyone asks why we're not using URL, the URL equivalent is: `u = new URL('http://d'); u.pathname = "/" + sourcemapFilename; return u.pathname.slice(1); + const sourceMapLengthWithPercentEncoding = + prefixLength + encodeURI(sourcemapFilename).length; + if ( + outputText.substr(-sourceMapLengthWithPercentEncoding, prefixLength) === + prefix + ) { + return ( + outputText.slice(0, -sourceMapLengthWithPercentEncoding) + + sourceMapContent + ); + } - return outputText.slice(0, -sourceMapLength) + sourceMapContent + return `${outputText}\n${sourceMapContent}`; } /** * Update the source map contents for improved output. */ -function updateSourceMap (sourceMapText: string, fileName: string) { - const sourceMap = JSON.parse(sourceMapText) - sourceMap.file = fileName - sourceMap.sources = [fileName] - delete sourceMap.sourceRoot - return JSON.stringify(sourceMap) +function updateSourceMap(sourceMapText: string, fileName: string) { + const sourceMap = JSON.parse(sourceMapText); + sourceMap.file = fileName; + sourceMap.sources = [fileName]; + delete sourceMap.sourceRoot; + return JSON.stringify(sourceMap); } /** * Filter diagnostics. */ -function filterDiagnostics (diagnostics: readonly _ts.Diagnostic[], ignore: number[]) { - return diagnostics.filter(x => ignore.indexOf(x.code) === -1) +function filterDiagnostics( + diagnostics: readonly _ts.Diagnostic[], + filters: DiagnosticFilter[] +) { + return diagnostics.filter((d) => + filters.every( + (f) => + (!f.appliesToAllFiles && + f.filenamesAbsolute.indexOf(d.file?.fileName!) === -1) || + f.diagnosticsIgnored.indexOf(d.code) === -1 + ) + ); } /** @@ -1196,30 +1409,25 @@ function filterDiagnostics (diagnostics: readonly _ts.Diagnostic[], ignore: numb * * Reference: https://github.com/microsoft/TypeScript/blob/fcd9334f57d85b73dd66ad2d21c02e84822f4841/src/services/utilities.ts#L705-L731 */ -function getTokenAtPosition (ts: typeof _ts, sourceFile: _ts.SourceFile, position: number): _ts.Node { - let current: _ts.Node = sourceFile +function getTokenAtPosition( + ts: TSCommon, + sourceFile: _ts.SourceFile, + position: number +): _ts.Node { + let current: _ts.Node = sourceFile; outer: while (true) { for (const child of current.getChildren(sourceFile)) { - const start = child.getFullStart() - if (start > position) break + const start = child.getFullStart(); + if (start > position) break; - const end = child.getEnd() + const end = child.getEnd(); if (position <= end) { - current = child - continue outer + current = child; + continue outer; } } - return current - } -} - -let nodeCreateRequire: (path: string) => NodeRequire -function createRequire (filename: string) { - if (!nodeCreateRequire) { - // tslint:disable-next-line - nodeCreateRequire = Module.createRequire || Module.createRequireFromPath || require('../dist-raw/node-createrequire').createRequireFromPath + return current; } - return nodeCreateRequire(filename) } diff --git a/src/module-type-classifier.ts b/src/module-type-classifier.ts new file mode 100644 index 000000000..dfe153289 --- /dev/null +++ b/src/module-type-classifier.ts @@ -0,0 +1,96 @@ +import { dirname } from 'path'; +import { getPatternFromSpec } from './ts-internals'; +import { cachedLookup, normalizeSlashes } from './util'; + +// Logic to support out `moduleTypes` option, which allows overriding node's default ESM / CJS +// classification of `.js` files based on package.json `type` field. + +/** @internal */ +export type ModuleType = 'cjs' | 'esm' | 'package'; +/** @internal */ +export interface ModuleTypeClassification { + moduleType: ModuleType; +} +/** @internal */ +export interface ModuleTypeClassifierOptions { + basePath?: string; + patterns?: Record; +} +/** @internal */ +export type ModuleTypeClassifier = ReturnType< + typeof createModuleTypeClassifier +>; +/** + * @internal + * May receive non-normalized options -- basePath and patterns -- and will normalize them + * internally. + * However, calls to `classifyModule` must pass pre-normalized paths! + */ +export function createModuleTypeClassifier( + options: ModuleTypeClassifierOptions +) { + const { patterns, basePath: _basePath } = options; + const basePath = + _basePath !== undefined + ? normalizeSlashes(_basePath).replace(/\/$/, '') + : undefined; + + const patternTypePairs = Object.entries(patterns ?? []).map( + ([_pattern, type]) => { + const pattern = normalizeSlashes(_pattern); + return { pattern: parsePattern(basePath!, pattern), type }; + } + ); + + const classifications: Record = { + package: { + moduleType: 'package', + }, + cjs: { + moduleType: 'cjs', + }, + esm: { + moduleType: 'esm', + }, + }; + const auto = classifications.package; + + // Passed path must be normalized! + function classifyModuleNonCached(path: string): ModuleTypeClassification { + const matched = matchPatterns(patternTypePairs, (_) => _.pattern, path); + if (matched) return classifications[matched.type]; + return auto; + } + + const classifyModule = cachedLookup(classifyModuleNonCached); + + function classifyModuleAuto(path: String) { + return auto; + } + + return { + classifyModule: patternTypePairs.length + ? classifyModule + : classifyModuleAuto, + }; +} + +function parsePattern(basePath: string, patternString: string): RegExp { + const pattern = getPatternFromSpec(patternString, basePath); + return pattern !== undefined ? new RegExp(pattern) : /(?:)/; +} + +function matchPatterns( + objects: T[], + getPattern: (t: T) => RegExp, + candidate: string +): T | undefined { + for (let i = objects.length - 1; i >= 0; i--) { + const object = objects[i]; + const pattern = getPattern(object); + + if (pattern?.test(candidate)) { + return object; + } + } +} diff --git a/src/repl.ts b/src/repl.ts new file mode 100644 index 000000000..8ead036ac --- /dev/null +++ b/src/repl.ts @@ -0,0 +1,674 @@ +import { diffLines } from 'diff'; +import { homedir } from 'os'; +import { join } from 'path'; +import { + Recoverable, + ReplOptions, + REPLServer, + start as nodeReplStart, +} from 'repl'; +import { Context, createContext, Script } from 'vm'; +import { Service, CreateOptions, TSError, env } from './index'; +import { readFileSync, statSync } from 'fs'; +import { Console } from 'console'; +import * as assert from 'assert'; +import type * as tty from 'tty'; +import type * as Module from 'module'; + +// Lazy-loaded. +let _processTopLevelAwait: (src: string) => string | null; +function getProcessTopLevelAwait() { + if (_processTopLevelAwait === undefined) { + ({ + processTopLevelAwait: _processTopLevelAwait, + } = require('../dist-raw/node-repl-await')); + } + return _processTopLevelAwait; +} + +/** @internal */ +export const EVAL_FILENAME = `[eval].ts`; +/** @internal */ +export const EVAL_NAME = `[eval]`; +/** @internal */ +export const STDIN_FILENAME = `[stdin].ts`; +/** @internal */ +export const STDIN_NAME = `[stdin]`; +/** @internal */ +export const REPL_FILENAME = '.ts'; +/** @internal */ +export const REPL_NAME = ''; + +export interface ReplService { + readonly state: EvalState; + /** + * Bind this REPL to a ts-node compiler service. A compiler service must be bound before `eval`-ing code or starting the REPL + */ + setService(service: Service): void; + /** + * Append code to the virtual source file, compile it to JavaScript, throw semantic errors if the typechecker is enabled, + * and execute it. + * + * Note: typically, you will want to call `start()` instead of using this method. + * + * @param code string of TypeScript. + */ + evalCode(code: string): any; + /** @internal */ + evalCodeInternal(opts: { + code: string; + enableTopLevelAwait?: boolean; + context?: Context; + }): + | { + containsTopLevelAwait: true; + valuePromise: Promise; + } + | { + containsTopLevelAwait: false; + value: any; + }; + /** + * `eval` implementation compatible with node's REPL API + * + * Can be used in advanced scenarios if you want to manually create your own + * node REPL instance and delegate eval to this `ReplService`. + * + * Example: + * + * import {start} from 'repl'; + * const replService: tsNode.ReplService = ...; // assuming you have already created a ts-node ReplService + * const nodeRepl = start({eval: replService.eval}); + */ + nodeEval( + code: string, + // TODO change to `Context` in a future release? Technically a breaking change + context: any, + _filename: string, + callback: (err: Error | null, result?: any) => any + ): void; + evalAwarePartialHost: EvalAwarePartialHost; + /** Start a node REPL */ + start(): void; + /** + * Start a node REPL, evaling a string of TypeScript before it starts. + * @deprecated + */ + start(code: string): void; + /** @internal */ + startInternal(opts?: ReplOptions): REPLServer; + /** @internal */ + readonly stdin: NodeJS.ReadableStream; + /** @internal */ + readonly stdout: NodeJS.WritableStream; + /** @internal */ + readonly stderr: NodeJS.WritableStream; + /** @internal */ + readonly console: Console; +} + +export interface CreateReplOptions { + service?: Service; + state?: EvalState; + stdin?: NodeJS.ReadableStream; + stdout?: NodeJS.WritableStream; + stderr?: NodeJS.WritableStream; + /** @internal */ + composeWithEvalAwarePartialHost?: EvalAwarePartialHost; + // TODO collapse both of the following two flags into a single `isInteractive` or `isLineByLine` flag. + /** + * @internal + * Ignore diagnostics that are annoying when interactively entering input line-by-line. + */ + ignoreDiagnosticsThatAreAnnoyingInInteractiveRepl?: boolean; +} + +/** + * Create a ts-node REPL instance. + * + * Pay close attention to the example below. Today, the API requires a few lines + * of boilerplate to correctly bind the `ReplService` to the ts-node `Service` and + * vice-versa. + * + * Usage example: + * + * const repl = tsNode.createRepl(); + * const service = tsNode.create({...repl.evalAwarePartialHost}); + * repl.setService(service); + * repl.start(); + */ +export function createRepl(options: CreateReplOptions = {}) { + const { ignoreDiagnosticsThatAreAnnoyingInInteractiveRepl = true } = options; + let service = options.service; + let nodeReplServer: REPLServer; + // If `useGlobal` is not true, then REPL creates a context when started. + // This stores a reference to it or to `global`, whichever is used, after REPL has started. + let context: Context | undefined; + const state = + options.state ?? new EvalState(join(process.cwd(), REPL_FILENAME)); + const evalAwarePartialHost = createEvalAwarePartialHost( + state, + options.composeWithEvalAwarePartialHost + ); + const stdin = options.stdin ?? process.stdin; + const stdout = options.stdout ?? process.stdout; + const stderr = options.stderr ?? process.stderr; + const _console = + stdout === process.stdout && stderr === process.stderr + ? console + : new Console(stdout, stderr); + + const replService: ReplService = { + state: options.state ?? new EvalState(join(process.cwd(), EVAL_FILENAME)), + setService, + evalCode, + evalCodeInternal, + nodeEval, + evalAwarePartialHost, + start, + startInternal, + stdin, + stdout, + stderr, + console: _console, + }; + + return replService; + + function setService(_service: Service) { + service = _service; + if (ignoreDiagnosticsThatAreAnnoyingInInteractiveRepl) { + service.addDiagnosticFilter({ + appliesToAllFiles: false, + filenamesAbsolute: [state.path], + diagnosticsIgnored: [ + 2393, // Duplicate function implementation: https://github.com/TypeStrong/ts-node/issues/729 + 6133, // is declared but its value is never read. https://github.com/TypeStrong/ts-node/issues/850 + 7027, // Unreachable code detected. https://github.com/TypeStrong/ts-node/issues/469 + ...(service.shouldReplAwait ? topLevelAwaitDiagnosticCodes : []), + ], + }); + } + } + + function evalCode(code: string) { + const result = appendCompileAndEvalInput({ + service: service!, + state, + input: code, + context, + }); + assert(result.containsTopLevelAwait === false); + return result.value; + } + + function evalCodeInternal(options: { + code: string; + enableTopLevelAwait?: boolean; + context: Context; + }) { + const { code, enableTopLevelAwait, context } = options; + return appendCompileAndEvalInput({ + service: service!, + state, + input: code, + enableTopLevelAwait, + context, + }); + } + + function nodeEval( + code: string, + context: any, + _filename: string, + callback: (err: Error | null, result?: any) => any + ) { + // TODO: Figure out how to handle completion here. + if (code === '.scope') { + callback(null); + return; + } + + try { + const evalResult = evalCodeInternal({ + code, + enableTopLevelAwait: true, + context, + }); + + if (evalResult.containsTopLevelAwait) { + (async () => { + try { + callback(null, await evalResult.valuePromise); + } catch (promiseError) { + handleError(promiseError); + } + })(); + } else { + callback(null, evalResult.value); + } + } catch (error) { + handleError(error); + } + + // Log TSErrors, check if they're recoverable, log helpful hints for certain + // well-known errors, and invoke `callback()` + // TODO should evalCode API get the same error-handling benefits? + function handleError(error: unknown) { + // Don't show TLA hint if the user explicitly disabled repl top level await + const canLogTopLevelAwaitHint = + service!.options.experimentalReplAwait !== false && + !service!.shouldReplAwait; + if (error instanceof TSError) { + // Support recoverable compilations using >= node 6. + if (Recoverable && isRecoverable(error)) { + callback(new Recoverable(error)); + return; + } else { + _console.error(error); + + if ( + canLogTopLevelAwaitHint && + error.diagnosticCodes.some((dC) => + topLevelAwaitDiagnosticCodes.includes(dC) + ) + ) { + _console.error(getTopLevelAwaitHint()); + } + callback(null); + } + } else { + let _error = error as Error | undefined; + if ( + canLogTopLevelAwaitHint && + _error instanceof SyntaxError && + _error.message?.includes('await is only valid') + ) { + try { + // Only way I know to make our hint appear after the error + _error.message += `\n\n${getTopLevelAwaitHint()}`; + _error.stack = _error.stack?.replace( + /(SyntaxError:.*)/, + (_, $1) => `${$1}\n\n${getTopLevelAwaitHint()}` + ); + } catch {} + } + callback(_error as Error); + } + } + function getTopLevelAwaitHint() { + return `Hint: REPL top-level await requires TypeScript version 3.8 or higher and target ES2018 or higher. You are using TypeScript ${ + service!.ts.version + } and target ${ + service!.ts.ScriptTarget[service!.config.options.target!] + }.`; + } + } + + // Note: `code` argument is deprecated + function start(code?: string) { + startInternal({ code }); + } + + // Note: `code` argument is deprecated + function startInternal( + options?: ReplOptions & { code?: string; forceToBeModule?: boolean } + ) { + const { code, forceToBeModule = true, ...optionsOverride } = options ?? {}; + // TODO assert that `service` is set; remove all `service!` non-null assertions + + // Eval incoming code before the REPL starts. + // Note: deprecated + if (code) { + try { + evalCode(`${code}\n`); + } catch (err) { + _console.error(err); + // Note: should not be killing the process here, but this codepath is deprecated anyway + process.exit(1); + } + } + + const repl = nodeReplStart({ + prompt: '> ', + input: replService.stdin, + output: replService.stdout, + // Mimicking node's REPL implementation: https://github.com/nodejs/node/blob/168b22ba073ee1cbf8d0bcb4ded7ff3099335d04/lib/internal/repl.js#L28-L30 + terminal: + (stdout as tty.WriteStream).isTTY && + !parseInt(env.NODE_NO_READLINE!, 10), + eval: nodeEval, + useGlobal: true, + ...optionsOverride, + }); + + nodeReplServer = repl; + context = repl.context; + + // Bookmark the point where we should reset the REPL state. + const resetEval = appendToEvalState(state, ''); + + function reset() { + resetEval(); + + // Hard fix for TypeScript forcing `Object.defineProperty(exports, ...)`. + runInContext('exports = module.exports', state.path, context); + if (forceToBeModule) { + state.input += 'export {};void 0;\n'; + } + } + + reset(); + repl.on('reset', reset); + + repl.defineCommand('type', { + help: 'Check the type of a TypeScript identifier', + action: function (identifier: string) { + if (!identifier) { + repl.displayPrompt(); + return; + } + + const undo = appendToEvalState(state, identifier); + const { name, comment } = service!.getTypeInfo( + state.input, + state.path, + state.input.length + ); + + undo(); + + if (name) repl.outputStream.write(`${name}\n`); + if (comment) repl.outputStream.write(`${comment}\n`); + repl.displayPrompt(); + }, + }); + + // Set up REPL history when available natively via node.js >= 11. + if (repl.setupHistory) { + const historyPath = + env.TS_NODE_HISTORY || join(homedir(), '.ts_node_repl_history'); + + repl.setupHistory(historyPath, (err) => { + if (!err) return; + + _console.error(err); + process.exit(1); + }); + } + + return repl; + } +} + +/** + * Eval state management. Stores virtual `[eval].ts` file + */ +export class EvalState { + /** @internal */ + input = ''; + /** @internal */ + output = ''; + /** @internal */ + version = 0; + /** @internal */ + lines = 0; + + __tsNodeEvalStateBrand: unknown; + + constructor(public path: string) {} +} + +/** + * Filesystem host functions which are aware of the "virtual" `[eval].ts`, ``, or `[stdin].ts` file used to compile REPL inputs. + * Must be passed to `create()` to create a ts-node compiler service which can compile REPL inputs. + */ +export type EvalAwarePartialHost = Pick< + CreateOptions, + 'readFile' | 'fileExists' +>; + +export function createEvalAwarePartialHost( + state: EvalState, + composeWith?: EvalAwarePartialHost +): EvalAwarePartialHost { + function readFile(path: string) { + if (path === state.path) return state.input; + + if (composeWith?.readFile) return composeWith.readFile(path); + + try { + return readFileSync(path, 'utf8'); + } catch (err) { + /* Ignore. */ + } + } + function fileExists(path: string) { + if (path === state.path) return true; + + if (composeWith?.fileExists) return composeWith.fileExists(path); + + try { + const stats = statSync(path); + return stats.isFile() || stats.isFIFO(); + } catch (err) { + return false; + } + } + return { readFile, fileExists }; +} + +type AppendCompileAndEvalInputResult = + | { containsTopLevelAwait: true; valuePromise: Promise } + | { containsTopLevelAwait: false; value: any }; +/** + * Evaluate the code snippet. + * + * Append it to virtual .ts file, compile, handle compiler errors, compute a diff of the JS, and eval any code that + * appears as "added" in the diff. + */ +function appendCompileAndEvalInput(options: { + service: Service; + state: EvalState; + input: string; + /** Enable top-level await but only if the TSNode service allows it. */ + enableTopLevelAwait?: boolean; + context: Context | undefined; +}): AppendCompileAndEvalInputResult { + const { + service, + state, + input, + enableTopLevelAwait = false, + context, + } = options; + const lines = state.lines; + const isCompletion = !/\n$/.test(input); + const undo = appendToEvalState(state, input); + let output: string; + + // Based on https://github.com/nodejs/node/blob/92573721c7cff104ccb82b6ed3e8aa69c4b27510/lib/repl.js#L457-L461 + function adjustUseStrict(code: string) { + // "void 0" keeps the repl from returning "use strict" as the result + // value for statements and declarations that don't return a value. + return code.replace(/^"use strict";/, '"use strict"; void 0;'); + } + + try { + output = service.compile(state.input, state.path, -lines); + } catch (err) { + undo(); + throw err; + } + + output = adjustUseStrict(output); + + // Use `diff` to check for new JavaScript to execute. + const changes = diffLines(state.output, output); + + if (isCompletion) { + undo(); + } else { + state.output = output; + } + + let commands: Array<{ mustAwait?: true; execCommand: () => any }> = []; + let containsTopLevelAwait = false; + + // Build a list of "commands": bits of JS code in the diff that must be executed. + for (const change of changes) { + if (change.added) { + if ( + enableTopLevelAwait && + service.shouldReplAwait && + change.value.indexOf('await') > -1 + ) { + const processTopLevelAwait = getProcessTopLevelAwait(); + + // Newline prevents comments to mess with wrapper + const wrappedResult = processTopLevelAwait(change.value + '\n'); + if (wrappedResult !== null) { + containsTopLevelAwait = true; + commands.push({ + mustAwait: true, + execCommand: () => runInContext(wrappedResult, state.path, context), + }); + continue; + } + } + commands.push({ + execCommand: () => runInContext(change.value, state.path, context), + }); + } + } + + // Execute all commands asynchronously if necessary, returning the result or a + // promise of the result. + if (containsTopLevelAwait) { + return { + containsTopLevelAwait, + valuePromise: (async () => { + let value; + for (const command of commands) { + const r = command.execCommand(); + value = command.mustAwait ? await r : r; + } + return value; + })(), + }; + } else { + return { + containsTopLevelAwait: false, + value: commands.reduce((_, c) => c.execCommand(), undefined), + }; + } +} + +/** + * Low-level execution of JS code in context + */ +function runInContext(code: string, filename: string, context?: Context) { + const script = new Script(code, { filename }); + + if (context === undefined || context === global) { + return script.runInThisContext(); + } else { + return script.runInContext(context); + } +} + +/** + * Append to the eval instance and return an undo function. + */ +function appendToEvalState(state: EvalState, input: string) { + const undoInput = state.input; + const undoVersion = state.version; + const undoOutput = state.output; + const undoLines = state.lines; + + // Handle ASI issues with TypeScript re-evaluation. + if ( + undoInput.charAt(undoInput.length - 1) === '\n' && + /^\s*[\/\[(`-]/.test(input) && + !/;\s*$/.test(undoInput) + ) { + state.input = `${state.input.slice(0, -1)};\n`; + } + + state.input += input; + state.lines += lineCount(input); + state.version++; + + return function () { + state.input = undoInput; + state.output = undoOutput; + state.version = undoVersion; + state.lines = undoLines; + }; +} + +/** + * Count the number of lines. + */ +function lineCount(value: string) { + let count = 0; + + for (const char of value) { + if (char === '\n') { + count++; + } + } + + return count; +} + +/** + * TS diagnostic codes which are recoverable, meaning that the user likely entered and incomplete line of code + * and should be prompted for the next. For example, starting a multi-line for() loop and not finishing it. + */ +const RECOVERY_CODES: Set = new Set([ + 1003, // "Identifier expected." + 1005, // "')' expected." + 1109, // "Expression expected." + 1126, // "Unexpected end of text." + 1160, // "Unterminated template literal." + 1161, // "Unterminated regular expression literal." + 2355, // "A function whose declared type is neither 'void' nor 'any' must return a value." +]); + +/** + * Diagnostic codes raised when using top-level await. + * These are suppressed when top-level await is enabled. + * When it is *not* enabled, these trigger a helpful hint about enabling top-level await. + */ +const topLevelAwaitDiagnosticCodes = [ + 1375, // 'await' expressions are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module. + 1378, // Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher. + 1431, // 'for await' loops are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module. + 1432, // Top-level 'for await' loops are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher. +]; + +/** + * Check if a function can recover gracefully. + */ +function isRecoverable(error: TSError) { + return error.diagnosticCodes.every((code) => RECOVERY_CODES.has(code)); +} + +/** + * @internal + * Set properties on `context` before eval-ing [stdin] or [eval] input. + */ +export function setupContext( + context: any, + module: Module, + filenameAndDirname: 'eval' | 'stdin' | null +) { + if (filenameAndDirname) { + context.__dirname = '.'; + context.__filename = `[${filenameAndDirname}]`; + } + context.module = module; + context.exports = module.exports; + context.require = module.require.bind(module); +} diff --git a/src/resolver-functions.ts b/src/resolver-functions.ts new file mode 100644 index 000000000..e76528155 --- /dev/null +++ b/src/resolver-functions.ts @@ -0,0 +1,179 @@ +import { resolve } from 'path'; +import type * as _ts from 'typescript'; + +/** + * @internal + * In a factory because these are shared across both CompilerHost and LanguageService codepaths + */ +export function createResolverFunctions(kwargs: { + ts: typeof _ts; + serviceHost: _ts.ModuleResolutionHost; + cwd: string; + getCanonicalFileName: (filename: string) => string; + config: _ts.ParsedCommandLine; + configFilePath: string | undefined; +}) { + const { + serviceHost, + ts, + config, + cwd, + getCanonicalFileName, + configFilePath, + } = kwargs; + const moduleResolutionCache = ts.createModuleResolutionCache( + cwd, + getCanonicalFileName, + config.options + ); + const knownInternalFilenames = new Set(); + /** "Buckets" (module directories) whose contents should be marked "internal" */ + const internalBuckets = new Set(); + + // Get bucket for a source filename. Bucket is the containing `./node_modules/*/` directory + // For '/project/node_modules/foo/node_modules/bar/lib/index.js' bucket is '/project/node_modules/foo/node_modules/bar/' + // For '/project/node_modules/foo/node_modules/@scope/bar/lib/index.js' bucket is '/project/node_modules/foo/node_modules/@scope/bar/' + const moduleBucketRe = /.*\/node_modules\/(?:@[^\/]+\/)?[^\/]+\//; + function getModuleBucket(filename: string) { + const find = moduleBucketRe.exec(filename); + if (find) return find[0]; + return ''; + } + + // Mark that this file and all siblings in its bucket should be "internal" + function markBucketOfFilenameInternal(filename: string) { + internalBuckets.add(getModuleBucket(filename)); + } + + function isFileInInternalBucket(filename: string) { + return internalBuckets.has(getModuleBucket(filename)); + } + + function isFileKnownToBeInternal(filename: string) { + return knownInternalFilenames.has(filename); + } + + /** + * If we need to emit JS for a file, force TS to consider it non-external + */ + const fixupResolvedModule = ( + resolvedModule: _ts.ResolvedModule | _ts.ResolvedTypeReferenceDirective + ) => { + const { resolvedFileName } = resolvedModule; + if (resolvedFileName === undefined) return; + // .ts is always switched to internal + // .js is switched on-demand + if ( + resolvedModule.isExternalLibraryImport && + ((resolvedFileName.endsWith('.ts') && + !resolvedFileName.endsWith('.d.ts')) || + isFileKnownToBeInternal(resolvedFileName) || + isFileInInternalBucket(resolvedFileName)) + ) { + resolvedModule.isExternalLibraryImport = false; + } + if (!resolvedModule.isExternalLibraryImport) { + knownInternalFilenames.add(resolvedFileName); + } + }; + /* + * NOTE: + * Older ts versions do not pass `redirectedReference` nor `options`. + * We must pass `redirectedReference` to newer ts versions, but cannot rely on `options`, hence the weird argument name + */ + const resolveModuleNames: _ts.LanguageServiceHost['resolveModuleNames'] = ( + moduleNames: string[], + containingFile: string, + reusedNames: string[] | undefined, + redirectedReference: _ts.ResolvedProjectReference | undefined, + optionsOnlyWithNewerTsVersions: _ts.CompilerOptions + ): (_ts.ResolvedModule | undefined)[] => { + return moduleNames.map((moduleName) => { + const { resolvedModule } = ts.resolveModuleName( + moduleName, + containingFile, + config.options, + serviceHost, + moduleResolutionCache, + redirectedReference + ); + if (resolvedModule) { + fixupResolvedModule(resolvedModule); + } + return resolvedModule; + }); + }; + + // language service never calls this, but TS docs recommend that we implement it + const getResolvedModuleWithFailedLookupLocationsFromCache: _ts.LanguageServiceHost['getResolvedModuleWithFailedLookupLocationsFromCache'] = ( + moduleName, + containingFile + ): _ts.ResolvedModuleWithFailedLookupLocations | undefined => { + const ret = ts.resolveModuleNameFromCache( + moduleName, + containingFile, + moduleResolutionCache + ); + if (ret && ret.resolvedModule) { + fixupResolvedModule(ret.resolvedModule); + } + return ret; + }; + + const resolveTypeReferenceDirectives: _ts.LanguageServiceHost['resolveTypeReferenceDirectives'] = ( + typeDirectiveNames: string[], + containingFile: string, + redirectedReference: _ts.ResolvedProjectReference | undefined, + options: _ts.CompilerOptions + ): (_ts.ResolvedTypeReferenceDirective | undefined)[] => { + // Note: seems to be called with empty typeDirectiveNames array for all files. + return typeDirectiveNames.map((typeDirectiveName) => { + let { resolvedTypeReferenceDirective } = ts.resolveTypeReferenceDirective( + typeDirectiveName, + containingFile, + config.options, + serviceHost, + redirectedReference + ); + if (typeDirectiveName === 'node' && !resolvedTypeReferenceDirective) { + // Resolve @types/node relative to project first, then __dirname (copy logic from elsewhere / refactor into reusable function) + let typesNodePackageJsonPath: string | undefined; + try { + typesNodePackageJsonPath = require.resolve( + '@types/node/package.json', + { + paths: [configFilePath ?? cwd, __dirname], + } + ); + } catch {} // gracefully do nothing when @types/node is not installed for any reason + if (typesNodePackageJsonPath) { + const typeRoots = [resolve(typesNodePackageJsonPath, '../..')]; + ({ + resolvedTypeReferenceDirective, + } = ts.resolveTypeReferenceDirective( + typeDirectiveName, + containingFile, + { + ...config.options, + typeRoots, + }, + serviceHost, + redirectedReference + )); + } + } + if (resolvedTypeReferenceDirective) { + fixupResolvedModule(resolvedTypeReferenceDirective); + } + return resolvedTypeReferenceDirective; + }); + }; + + return { + resolveModuleNames, + getResolvedModuleWithFailedLookupLocationsFromCache, + resolveTypeReferenceDirectives, + isFileKnownToBeInternal, + markBucketOfFilenameInternal, + }; +} diff --git a/src/test/index.spec.ts b/src/test/index.spec.ts new file mode 100644 index 000000000..6b3c337eb --- /dev/null +++ b/src/test/index.spec.ts @@ -0,0 +1,2207 @@ +import { test } from './testlib'; +import { expect } from 'chai'; +import * as exp from 'expect'; +import { + ChildProcess, + exec as childProcessExec, + ExecException, + ExecOptions, +} from 'child_process'; +import { dirname, join, resolve, sep as pathSep } from 'path'; +import { homedir, tmpdir } from 'os'; +import semver = require('semver'); +import ts = require('typescript'); +import proxyquire = require('proxyquire'); +import type * as tsNodeTypes from '../index'; +import * as fs from 'fs'; +import { unlinkSync, existsSync, lstatSync, mkdtempSync } from 'fs'; +import { NodeFS, npath } from '@yarnpkg/fslib'; +import * as promisify from 'util.promisify'; +import { sync as rimrafSync } from 'rimraf'; +import type _createRequire from 'create-require'; +const createRequire: typeof _createRequire = require('create-require'); +import { pathToFileURL } from 'url'; +import type * as Module from 'module'; +import { PassThrough } from 'stream'; +import * as getStream from 'get-stream'; +import { once } from 'lodash'; +import { upstreamTopLevelAwaitTests } from './node-repl-tla'; +import { createMacrosAndHelpers, ExecMacroAssertionCallback } from './macros'; + +const xfs = new NodeFS(fs); + +async function settled(fn: () => Promise | T) { + try { + return { + status: 'fulfilled', + value: await fn(), + }; + } catch (reason) { + return { + status: 'rejected', + reason, + }; + } +} + +interface CreateReplViaApiOptions { + createReplOpts?: Partial; + createServiceOpts?: Partial; +} +function createReplViaApi({ + createReplOpts, + createServiceOpts, +}: CreateReplViaApiOptions = {}) { + const stdin = new PassThrough(); + const stdout = new PassThrough(); + const stderr = new PassThrough(); + const replService = createRepl({ + stdin, + stdout, + stderr, + ...createReplOpts, + }); + const service = create({ + ...replService.evalAwarePartialHost, + project: `${TEST_DIR}/tsconfig.json`, + ...createServiceOpts, + }); + replService.setService(service); + return { stdin, stdout, stderr, replService, service }; +} + +// Todo combine with replApiMacro +async function executeInRepl( + input: string, + { + waitMs = 1e3, + startOptions, + ...rest + }: CreateReplViaApiOptions & { + waitMs?: number; + startOptions?: Parameters[0]; + } = {} +) { + const { stdin, stdout, stderr, replService } = createReplViaApi(rest); + + replService.startInternal(startOptions); + + stdin.write(input); + stdin.end(); + await promisify(setTimeout)(waitMs); + stdout.end(); + stderr.end(); + + return { + stdin, + stdout: await getStream(stdout), + stderr: await getStream(stderr), + }; +} + +const ROOT_DIR = resolve(__dirname, '../..'); +const DIST_DIR = resolve(__dirname, '..'); +const TEST_DIR = join(__dirname, '../../tests'); +const PROJECT = join(TEST_DIR, 'tsconfig.json'); +const BIN_PATH = join(TEST_DIR, 'node_modules/.bin/ts-node'); +const BIN_SCRIPT_PATH = join(TEST_DIR, 'node_modules/.bin/ts-node-script'); +const BIN_CWD_PATH = join(TEST_DIR, 'node_modules/.bin/ts-node-cwd'); + +const SOURCE_MAP_REGEXP = /\/\/# sourceMappingURL=data:application\/json;charset=utf\-8;base64,[\w\+]+=*$/; + +// `createRequire` does not exist on older node versions +const testsDirRequire = createRequire(join(TEST_DIR, 'index.js')); + +// Set after ts-node is installed locally +let { register, create, VERSION, createRepl }: typeof tsNodeTypes = {} as any; + +const { exec, createExecMacro } = createMacrosAndHelpers({ + test, + defaultCwd: TEST_DIR, +}); + +// Pack and install ts-node locally, necessary to test package "exports" +test.beforeAll(async () => { + const totalTries = process.platform === 'win32' ? 5 : 1; + let tries = 0; + while (true) { + try { + rimrafSync(join(TEST_DIR, 'node_modules')); + await promisify(childProcessExec)(`npm install`, { cwd: TEST_DIR }); + const packageLockPath = join(TEST_DIR, 'package-lock.json'); + existsSync(packageLockPath) && unlinkSync(packageLockPath); + break; + } catch (e) { + tries++; + if (tries >= totalTries) throw e; + } + } + ({ register, create, VERSION, createRepl } = testsDirRequire('ts-node')); +}); + +test.suite('ts-node', (test) => { + /** Default `ts-node --project` invocation */ + const cmd = `"${BIN_PATH}" --project "${PROJECT}"`; + /** Default `ts-node` invocation without `--project` */ + const cmdNoProject = `"${BIN_PATH}"`; + const experimentalModulesFlag = semver.gte(process.version, '12.17.0') + ? '' + : '--experimental-modules'; + const cmdEsmLoaderNoProject = `node ${experimentalModulesFlag} --loader ts-node/esm`; + + test('should export the correct version', () => { + expect(VERSION).to.equal(require('../../package.json').version); + }); + test('should export all CJS entrypoints', () => { + // Ensure our package.json "exports" declaration allows `require()`ing all our entrypoints + // https://github.com/TypeStrong/ts-node/pull/1026 + + testsDirRequire.resolve('ts-node'); + + // only reliably way to ask node for the root path of a dependency is Path.resolve(require.resolve('ts-node/package'), '..') + testsDirRequire.resolve('ts-node/package'); + testsDirRequire.resolve('ts-node/package.json'); + + // All bin entrypoints for people who need to augment our CLI: `node -r otherstuff ./node_modules/ts-node/dist/bin` + testsDirRequire.resolve('ts-node/dist/bin'); + testsDirRequire.resolve('ts-node/dist/bin.js'); + testsDirRequire.resolve('ts-node/dist/bin-transpile'); + testsDirRequire.resolve('ts-node/dist/bin-transpile.js'); + testsDirRequire.resolve('ts-node/dist/bin-script'); + testsDirRequire.resolve('ts-node/dist/bin-script.js'); + testsDirRequire.resolve('ts-node/dist/bin-cwd'); + testsDirRequire.resolve('ts-node/dist/bin-cwd.js'); + + // Must be `require()`able obviously + testsDirRequire.resolve('ts-node/register'); + testsDirRequire.resolve('ts-node/register/files'); + testsDirRequire.resolve('ts-node/register/transpile-only'); + testsDirRequire.resolve('ts-node/register/type-check'); + + // `node --loader ts-node/esm` + testsDirRequire.resolve('ts-node/esm'); + testsDirRequire.resolve('ts-node/esm.mjs'); + testsDirRequire.resolve('ts-node/esm/transpile-only'); + testsDirRequire.resolve('ts-node/esm/transpile-only.mjs'); + + testsDirRequire.resolve('ts-node/transpilers/swc-experimental'); + + testsDirRequire.resolve('ts-node/node10/tsconfig.json'); + testsDirRequire.resolve('ts-node/node12/tsconfig.json'); + testsDirRequire.resolve('ts-node/node14/tsconfig.json'); + testsDirRequire.resolve('ts-node/node16/tsconfig.json'); + }); + + test.suite('cli', (test) => { + test('should execute cli', async () => { + const { err, stdout } = await exec(`${cmd} hello-world`); + expect(err).to.equal(null); + expect(stdout).to.equal('Hello, world!\n'); + }); + + test('shows usage via --help', async () => { + const { err, stdout } = await exec(`${cmdNoProject} --help`); + expect(err).to.equal(null); + expect(stdout).to.match(/Usage: ts-node /); + }); + test('shows version via -v', async () => { + const { err, stdout } = await exec(`${cmdNoProject} -v`); + expect(err).to.equal(null); + expect(stdout.trim()).to.equal( + 'v' + testsDirRequire('ts-node/package').version + ); + }); + test('shows version of compiler via -vv', async () => { + const { err, stdout } = await exec(`${cmdNoProject} -vv`); + expect(err).to.equal(null); + expect(stdout.trim()).to.equal( + `ts-node v${testsDirRequire('ts-node/package').version}\n` + + `node ${process.version}\n` + + `compiler v${testsDirRequire('typescript/package').version}` + ); + }); + + test('should register via cli', async () => { + const { err, stdout } = await exec( + `node -r ts-node/register hello-world.ts`, + { + cwd: TEST_DIR, + } + ); + expect(err).to.equal(null); + expect(stdout).to.equal('Hello, world!\n'); + }); + + test('should execute cli with absolute path', async () => { + const { err, stdout } = await exec( + `${cmd} "${join(TEST_DIR, 'hello-world')}"` + ); + expect(err).to.equal(null); + expect(stdout).to.equal('Hello, world!\n'); + }); + + test('should print scripts', async () => { + const { err, stdout } = await exec( + `${cmd} -pe "import { example } from './complex/index';example()"` + ); + expect(err).to.equal(null); + expect(stdout).to.equal('example\n'); + }); + + test('should provide registered information globally', async () => { + const { err, stdout } = await exec(`${cmd} env`); + expect(err).to.equal(null); + expect(stdout).to.equal('object\n'); + }); + + test('should provide registered information on register', async () => { + const { err, stdout } = await exec(`node -r ts-node/register env.ts`, { + cwd: TEST_DIR, + }); + expect(err).to.equal(null); + expect(stdout).to.equal('object\n'); + }); + + if (semver.gte(ts.version, '1.8.0')) { + test('should allow js', async () => { + const { err, stdout } = await exec( + [ + cmd, + '-O "{\\"allowJs\\":true}"', + '-pe "import { main } from \'./allow-js/run\';main()"', + ].join(' ') + ); + expect(err).to.equal(null); + expect(stdout).to.equal('hello world\n'); + }); + + test('should include jsx when `allow-js` true', async () => { + const { err, stdout } = await exec( + [ + cmd, + '-O "{\\"allowJs\\":true}"', + '-pe "import { Foo2 } from \'./allow-js/with-jsx\'; Foo2.sayHi()"', + ].join(' ') + ); + expect(err).to.equal(null); + expect(stdout).to.equal('hello world\n'); + }); + } + + test('should eval code', async () => { + const { err, stdout } = await exec( + `${cmd} -e "import * as m from './module';console.log(m.example('test'))"` + ); + expect(err).to.equal(null); + expect(stdout).to.equal('TEST\n'); + }); + + test('should import empty files', async () => { + const { err, stdout } = await exec(`${cmd} -e "import './empty'"`); + expect(err).to.equal(null); + expect(stdout).to.equal(''); + }); + + test('should throw errors', async () => { + const { err } = await exec( + `${cmd} -e "import * as m from './module';console.log(m.example(123))"` + ); + if (err === null) { + throw new Error('Command was expected to fail, but it succeeded.'); + } + + expect(err.message).to.match( + new RegExp( + "TS2345: Argument of type '(?:number|123)' " + + "is not assignable to parameter of type 'string'\\." + ) + ); + }); + + test('should be able to ignore diagnostic', async () => { + const { err } = await exec( + `${cmd} --ignore-diagnostics 2345 -e "import * as m from './module';console.log(m.example(123))"` + ); + if (err === null) { + throw new Error('Command was expected to fail, but it succeeded.'); + } + + expect(err.message).to.match( + /TypeError: (?:(?:undefined|foo\.toUpperCase) is not a function|.*has no method \'toUpperCase\')/ + ); + }); + + test('should work with source maps', async () => { + const { err } = await exec(`${cmd} "throw error"`); + if (err === null) { + throw new Error('Command was expected to fail, but it succeeded.'); + } + + expect(err.message).to.contain( + [ + `${join(TEST_DIR, 'throw error.ts')}:100`, + " bar() { throw new Error('this is a demo'); }", + ' ^', + 'Error: this is a demo', + ].join('\n') + ); + }); + + test('should work with source maps in --transpile-only mode', async () => { + const { err } = await exec(`${cmd} --transpile-only "throw error"`); + if (err === null) { + throw new Error('Command was expected to fail, but it succeeded.'); + } + + expect(err.message).to.contain( + [ + `${join(TEST_DIR, 'throw error.ts')}:100`, + " bar() { throw new Error('this is a demo'); }", + ' ^', + 'Error: this is a demo', + ].join('\n') + ); + }); + + test('eval should work with source maps', async () => { + const { err } = await exec(`${cmd} -pe "import './throw error'"`); + if (err === null) { + throw new Error('Command was expected to fail, but it succeeded.'); + } + + expect(err.message).to.contain( + [ + `${join(TEST_DIR, 'throw error.ts')}:100`, + " bar() { throw new Error('this is a demo'); }", + ' ^', + ].join('\n') + ); + }); + + test('should support transpile only mode', async () => { + const { err } = await exec(`${cmd} --transpile-only -pe "x"`); + if (err === null) { + throw new Error('Command was expected to fail, but it succeeded.'); + } + + expect(err.message).to.contain('ReferenceError: x is not defined'); + }); + + test('should throw error even in transpileOnly mode', async () => { + const { err } = await exec(`${cmd} --transpile-only -pe "console."`); + if (err === null) { + throw new Error('Command was expected to fail, but it succeeded.'); + } + + expect(err.message).to.contain('error TS1003: Identifier expected'); + }); + + test('should support third-party transpilers via --transpiler', async () => { + const { err, stdout } = await exec( + `${cmdNoProject} --transpiler ts-node/transpilers/swc-experimental transpile-only-swc` + ); + expect(err).to.equal(null); + expect(stdout).to.contain('Hello World!'); + }); + + test('should support third-party transpilers via tsconfig', async () => { + const { err, stdout } = await exec( + `${cmdNoProject} transpile-only-swc-via-tsconfig` + ); + expect(err).to.equal(null); + expect(stdout).to.contain('Hello World!'); + }); + + if (semver.gte(process.version, '12.16.0')) { + test('swc transpiler supports native ESM emit', async () => { + const { err, stdout } = await exec( + `${cmdEsmLoaderNoProject} ./index.ts`, + { + cwd: resolve(TEST_DIR, 'transpile-only-swc-native-esm'), + } + ); + expect(err).to.equal(null); + expect(stdout).to.contain('Hello file://'); + }); + } + + test('should pipe into `ts-node` and evaluate', async () => { + const execPromise = exec(cmd); + execPromise.child.stdin!.end("console.log('hello')"); + const { err, stdout } = await execPromise; + expect(err).to.equal(null); + expect(stdout).to.equal('hello\n'); + }); + + test('should pipe into `ts-node`', async () => { + const execPromise = exec(`${cmd} -p`); + execPromise.child.stdin!.end('true'); + const { err, stdout } = await execPromise; + expect(err).to.equal(null); + expect(stdout).to.equal('true\n'); + }); + + test('should pipe into an eval script', async () => { + const execPromise = exec( + `${cmd} --transpile-only -pe "process.stdin.isTTY"` + ); + execPromise.child.stdin!.end('true'); + const { err, stdout } = await execPromise; + expect(err).to.equal(null); + expect(stdout).to.equal('undefined\n'); + }); + + test('should run REPL when --interactive passed and stdin is not a TTY', async () => { + const execPromise = exec(`${cmd} --interactive`); + execPromise.child.stdin!.end('console.log("123")\n'); + const { err, stdout } = await execPromise; + expect(err).to.equal(null); + expect(stdout).to.equal('> 123\n' + 'undefined\n' + '> '); + }); + + test('REPL has command to get type information', async () => { + const execPromise = exec(`${cmd} --interactive`); + execPromise.child.stdin!.end('\nconst a = 123\n.type a'); + const { err, stdout } = await execPromise; + expect(err).to.equal(null); + expect(stdout).to.equal( + '> undefined\n' + '> undefined\n' + '> const a: 123\n' + '> ' + ); + }); + + const execMacro = createExecMacro({ + cmd, + cwd: TEST_DIR, + }); + + type ReplApiMacroAssertions = ( + stdout: string, + stderr: string + ) => Promise; + + const replApiMacro = test.macro( + (opts: { input: string }, assertions: ReplApiMacroAssertions) => async ( + t + ) => { + const { input } = opts; + const { stdin, stdout, stderr, replService } = createReplViaApi(); + replService.start(); + stdin.write(input); + stdin.end(); + await promisify(setTimeout)(1e3); + stdout.end(); + stderr.end(); + const stderrString = await getStream(stderr); + const stdoutString = await getStream(stdout); + await assertions(stdoutString, stderrString); + } + ); + + // Serial because it's timing-sensitive + test.serial( + 'REPL can be created via API', + replApiMacro, + { + input: '\nconst a = 123\n.type a\n', + }, + async (stdout, stderr) => { + expect(stderr).to.equal(''); + expect(stdout).to.equal( + '> undefined\n' + '> undefined\n' + '> const a: 123\n' + '> ' + ); + } + ); + + // Serial because it's timing-sensitive + test.serial('REPL can be configured on `start`', async () => { + const prompt = '#> '; + + const { stdout, stderr } = await executeInRepl('const x = 3', { + startOptions: { + prompt, + ignoreUndefined: true, + }, + }); + + expect(stderr).to.equal(''); + expect(stdout).to.equal(`${prompt}${prompt}`); + }); + + // Serial because it's timing-sensitive + test.serial( + 'REPL uses a different context when `useGlobal` is false', + async () => { + const { stdout, stderr } = await executeInRepl( + // No error when re-declaring x + 'const x = 3\n' + + // console.log ouput will end up in the stream and not in test output + 'console.log(1)\n', + { + startOptions: { + useGlobal: false, + }, + } + ); + + expect(stderr).to.equal(''); + expect(stdout).to.equal(`> undefined\n> 1\nundefined\n> `); + } + ); + + test.suite( + '[eval], , and [stdin] execute with correct globals', + (test) => { + interface GlobalInRepl extends NodeJS.Global { + testReport: any; + replReport: any; + stdinReport: any; + evalReport: any; + module: any; + exports: any; + fs: any; + __filename: any; + __dirname: any; + } + const globalInRepl = global as GlobalInRepl; + const programmaticTest = test.macro( + ( + { + evalCodeBefore, + stdinCode, + }: { + evalCodeBefore: string | null; + stdinCode: string; + }, + assertions: (stdout: string) => Promise | void + ) => async (t) => { + delete globalInRepl.testReport; + delete globalInRepl.replReport; + delete globalInRepl.stdinReport; + delete globalInRepl.evalReport; + delete globalInRepl.module; + delete globalInRepl.exports; + delete globalInRepl.fs; + delete globalInRepl.__filename; + delete globalInRepl.__dirname; + const { stdin, stderr, stdout, replService } = createReplViaApi(); + if (typeof evalCodeBefore === 'string') { + replService.evalCode(evalCodeBefore); + } + replService.start(); + stdin.write(stdinCode); + stdin.end(); + await promisify(setTimeout)(1e3); + stdout.end(); + stderr.end(); + expect(await getStream(stderr)).to.equal(''); + await assertions(await getStream(stdout)); + } + ); + + const declareGlobals = `declare var replReport: any, stdinReport: any, evalReport: any, restReport: any, global: any, __filename: any, __dirname: any, module: any, exports: any, fs: any;`; + function setReportGlobal(type: 'repl' | 'stdin' | 'eval') { + return ` + ${declareGlobals} + global.${type}Report = { + __filename: typeof __filename !== 'undefined' && __filename, + __dirname: typeof __dirname !== 'undefined' && __dirname, + moduleId: typeof module !== 'undefined' && module.id, + modulePath: typeof module !== 'undefined' && module.path, + moduleFilename: typeof module !== 'undefined' && module.filename, + modulePaths: typeof module !== 'undefined' && [...module.paths], + exportsTest: typeof exports !== 'undefined' ? module.exports === exports : null, + stackTest: new Error().stack!.split('\\n')[1], + moduleAccessorsTest: typeof fs === 'undefined' ? null : fs === require('fs'), + argv: [...process.argv] + }; + `.replace(/\n/g, ''); + } + const reportsObject = ` + { + stdinReport: typeof stdinReport !== 'undefined' && stdinReport, + evalReport: typeof evalReport !== 'undefined' && evalReport, + replReport: typeof replReport !== 'undefined' && replReport + } + `; + const printReports = ` + ${declareGlobals} + console.log(JSON.stringify(${reportsObject})); + `.replace(/\n/g, ''); + const saveReportsAsGlobal = ` + ${declareGlobals} + global.testReport = ${reportsObject}; + `.replace(/\n/g, ''); + + function parseStdoutStripReplPrompt(stdout: string) { + // Strip node's welcome header, only uncomment if running these tests manually against vanilla node + // stdout = stdout.replace(/^Welcome to.*\nType "\.help" .*\n/, ''); + expect(stdout.slice(0, 2)).to.equal('> '); + expect(stdout.slice(-12)).to.equal('undefined\n> '); + return parseStdout(stdout.slice(2, -12)); + } + function parseStdout(stdout: string) { + return JSON.parse(stdout); + } + + /** Every possible ./node_modules directory ascending upwards starting with ./tests/node_modules */ + const modulePaths = createModulePaths(TEST_DIR); + const rootModulePaths = createModulePaths(ROOT_DIR); + function createModulePaths(dir: string) { + const modulePaths: string[] = []; + for (let path = dir; ; path = dirname(path)) { + modulePaths.push(join(path, 'node_modules')); + if (dirname(path) === path) break; + } + return modulePaths; + } + + // Executable is `ts-node` on Posix, `bin.js` on Windows due to Windows shimming limitations (this is determined by package manager) + const tsNodeExe = exp.stringMatching(/\b(ts-node|bin.js)$/); + + test( + 'stdin', + execMacro, + { + stdin: `${setReportGlobal('stdin')};${printReports}`, + flags: '', + }, + (stdout) => { + const report = parseStdout(stdout); + exp(report).toMatchObject({ + stdinReport: { + __filename: '[stdin]', + __dirname: '.', + moduleId: '[stdin]', + modulePath: '.', + // Note: vanilla node does does not have file extension + moduleFilename: join(TEST_DIR, `[stdin].ts`), + modulePaths, + exportsTest: true, + // Note: vanilla node uses different name. See #1360 + stackTest: exp.stringContaining( + ` at ${join(TEST_DIR, `[stdin].ts`)}:1:` + ), + moduleAccessorsTest: null, + argv: [tsNodeExe], + }, + evalReport: false, + replReport: false, + }); + } + ); + test( + 'repl', + execMacro, + { + stdin: `${setReportGlobal('repl')};${printReports}`, + flags: '-i', + }, + (stdout) => { + const report = parseStdoutStripReplPrompt(stdout); + exp(report).toMatchObject({ + stdinReport: false, + evalReport: false, + replReport: { + __filename: false, + __dirname: false, + moduleId: '', + modulePath: '.', + moduleFilename: null, + modulePaths: exp.objectContaining({ + ...[join(TEST_DIR, `repl/node_modules`), ...modulePaths], + }), + // Note: vanilla node REPL does not set exports + exportsTest: true, + // Note: vanilla node uses different name. See #1360 + stackTest: exp.stringContaining( + ` at ${join(TEST_DIR, '.ts')}:2:` + ), + moduleAccessorsTest: true, + argv: [tsNodeExe], + }, + }); + // Prior to these, nyc adds another entry on Windows; we need to ignore it + exp(report.replReport.modulePaths.slice(-3)).toMatchObject([ + join(homedir(), `.node_modules`), + join(homedir(), `.node_libraries`), + // additional entry goes to node's install path + exp.any(String), + ]); + } + ); + + // Should ignore -i and run the entrypoint + test( + '-i w/entrypoint ignores -i', + execMacro, + { + stdin: `${setReportGlobal('repl')};${printReports}`, + flags: '-i ./repl/script.js', + }, + (stdout) => { + const report = parseStdout(stdout); + exp(report).toMatchObject({ + stdinReport: false, + evalReport: false, + replReport: false, + }); + } + ); + + // Should not execute stdin + // Should not interpret positional arg as an entrypoint script + test( + '-e', + execMacro, + { + stdin: `throw new Error()`, + flags: `-e "${setReportGlobal('eval')};${printReports}"`, + }, + (stdout) => { + const report = parseStdout(stdout); + exp(report).toMatchObject({ + stdinReport: false, + evalReport: { + __filename: '[eval]', + __dirname: '.', + moduleId: '[eval]', + modulePath: '.', + // Note: vanilla node does does not have file extension + moduleFilename: join(TEST_DIR, `[eval].ts`), + modulePaths: [...modulePaths], + exportsTest: true, + // Note: vanilla node uses different name. See #1360 + stackTest: exp.stringContaining( + ` at ${join(TEST_DIR, `[eval].ts`)}:1:` + ), + moduleAccessorsTest: true, + argv: [tsNodeExe], + }, + replReport: false, + }); + } + ); + test( + '-e w/entrypoint arg does not execute entrypoint', + execMacro, + { + stdin: `throw new Error()`, + flags: `-e "${setReportGlobal( + 'eval' + )};${printReports}" ./repl/script.js`, + }, + (stdout) => { + const report = parseStdout(stdout); + exp(report).toMatchObject({ + stdinReport: false, + evalReport: { + __filename: '[eval]', + __dirname: '.', + moduleId: '[eval]', + modulePath: '.', + // Note: vanilla node does does not have file extension + moduleFilename: join(TEST_DIR, `[eval].ts`), + modulePaths, + exportsTest: true, + // Note: vanilla node uses different name. See #1360 + stackTest: exp.stringContaining( + ` at ${join(TEST_DIR, `[eval].ts`)}:1:` + ), + moduleAccessorsTest: true, + argv: [tsNodeExe, './repl/script.js'], + }, + replReport: false, + }); + } + ); + test( + '-e w/non-path arg', + execMacro, + { + stdin: `throw new Error()`, + flags: `-e "${setReportGlobal( + 'eval' + )};${printReports}" ./does-not-exist.js`, + }, + (stdout) => { + const report = parseStdout(stdout); + exp(report).toMatchObject({ + stdinReport: false, + evalReport: { + __filename: '[eval]', + __dirname: '.', + moduleId: '[eval]', + modulePath: '.', + // Note: vanilla node does does not have file extension + moduleFilename: join(TEST_DIR, `[eval].ts`), + modulePaths, + exportsTest: true, + // Note: vanilla node uses different name. See #1360 + stackTest: exp.stringContaining( + ` at ${join(TEST_DIR, `[eval].ts`)}:1:` + ), + moduleAccessorsTest: true, + argv: [tsNodeExe, './does-not-exist.js'], + }, + replReport: false, + }); + } + ); + test( + '-e -i', + execMacro, + { + stdin: `${setReportGlobal('repl')};${printReports}`, + flags: `-e "${setReportGlobal('eval')}" -i`, + }, + (stdout) => { + const report = parseStdoutStripReplPrompt(stdout); + exp(report).toMatchObject({ + stdinReport: false, + evalReport: { + __filename: '[eval]', + __dirname: '.', + moduleId: '[eval]', + modulePath: '.', + // Note: vanilla node does does not have file extension + moduleFilename: join(TEST_DIR, `[eval].ts`), + modulePaths, + exportsTest: true, + // Note: vanilla node uses different name. See #1360 + stackTest: exp.stringContaining( + ` at ${join(TEST_DIR, `[eval].ts`)}:1:` + ), + moduleAccessorsTest: true, + argv: [tsNodeExe], + }, + replReport: { + __filename: '[eval]', + __dirname: '.', + moduleId: '', + modulePath: '.', + moduleFilename: null, + modulePaths: exp.objectContaining({ + ...[join(TEST_DIR, `repl/node_modules`), ...modulePaths], + }), + // Note: vanilla node REPL does not set exports, so this would be false + exportsTest: true, + // Note: vanilla node uses different name. See #1360 + stackTest: exp.stringContaining( + ` at ${join(TEST_DIR, '.ts')}:2:` + ), + moduleAccessorsTest: true, + argv: [tsNodeExe], + }, + }); + // Prior to these, nyc adds another entry on Windows; we need to ignore it + exp(report.replReport.modulePaths.slice(-3)).toMatchObject([ + join(homedir(), `.node_modules`), + join(homedir(), `.node_libraries`), + // additional entry goes to node's install path + exp.any(String), + ]); + } + ); + + test( + '-e -i w/entrypoint ignores -e and -i, runs entrypoint', + execMacro, + { + stdin: `throw new Error()`, + flags: '-e "throw new Error()" -i ./repl/script.js', + }, + (stdout) => { + const report = parseStdout(stdout); + exp(report).toMatchObject({ + stdinReport: false, + evalReport: false, + replReport: false, + }); + } + ); + + test( + '-e -i when -e throws error, -i does not run', + execMacro, + { + stdin: `console.log('hello')`, + flags: `-e "throw new Error('error from -e')" -i`, + expectError: true, + }, + (stdout, stderr, err) => { + exp(err).toBeDefined(); + exp(stdout).toBe(''); + exp(stderr).toContain('error from -e'); + } + ); + + // Serial because it's timing-sensitive + test.serial( + 'programmatically, eval-ing before starting REPL', + programmaticTest, + { + evalCodeBefore: `${setReportGlobal('repl')};${saveReportsAsGlobal}`, + stdinCode: '', + }, + (stdout) => { + exp(globalInRepl.testReport).toMatchObject({ + stdinReport: false, + evalReport: false, + replReport: { + __filename: false, + __dirname: false, + + // Due to limitations in node's REPL API, we can't really expose + // the `module` prior to calling repl.start() which also sends + // output to stdout. + // For now, leaving this as unsupported / undefined behavior. + + // moduleId: '', + // modulePath: '.', + // moduleFilename: null, + // modulePaths: [ + // join(ROOT_DIR, `repl/node_modules`), + // ...rootModulePaths, + // join(homedir(), `.node_modules`), + // join(homedir(), `.node_libraries`), + // // additional entry goes to node's install path + // exp.any(String), + // ], + // // Note: vanilla node REPL does not set exports + // exportsTest: true, + // moduleAccessorsTest: true, + + // Note: vanilla node uses different name. See #1360 + stackTest: exp.stringContaining( + ` at ${join(ROOT_DIR, '.ts')}:1:` + ), + }, + }); + } + ); + test.serial( + 'programmatically, passing code to stdin after starting REPL', + programmaticTest, + { + evalCodeBefore: null, + stdinCode: `${setReportGlobal('repl')};${saveReportsAsGlobal}`, + }, + (stdout) => { + exp(globalInRepl.testReport).toMatchObject({ + stdinReport: false, + evalReport: false, + replReport: { + __filename: false, + __dirname: false, + moduleId: '', + modulePath: '.', + moduleFilename: null, + modulePaths: exp.objectContaining({ + ...[join(ROOT_DIR, `repl/node_modules`), ...rootModulePaths], + }), + // Note: vanilla node REPL does not set exports + exportsTest: true, + // Note: vanilla node uses different name. See #1360 + stackTest: exp.stringContaining( + ` at ${join(ROOT_DIR, '.ts')}:1:` + ), + moduleAccessorsTest: true, + }, + }); + // Prior to these, nyc adds another entry on Windows; we need to ignore it + exp( + globalInRepl.testReport.replReport.modulePaths.slice(-3) + ).toMatchObject([ + join(homedir(), `.node_modules`), + join(homedir(), `.node_libraries`), + // additional entry goes to node's install path + exp.any(String), + ]); + } + ); + } + ); + + test.suite( + 'REPL ignores diagnostics that are annoying in interactive sessions', + (test) => { + const code = `function foo() {};\nfunction foo() {return 123};\nconsole.log(foo());\n`; + const diagnosticMessage = `Duplicate function implementation`; + test( + 'interactive repl should ignore them', + execMacro, + { + flags: '-i', + stdin: code, + }, + async (stdout, stderr) => { + exp(stdout).not.toContain(diagnosticMessage); + } + ); + test( + 'interactive repl should not ignore them if they occur in other files', + execMacro, + { + flags: '-i', + stdin: `import './repl-ignored-diagnostics/index.ts';\n`, + }, + async (stdout, stderr) => { + exp(stderr).toContain(diagnosticMessage); + } + ); + test( + '[stdin] should not ignore them', + execMacro, + { + stdin: code, + expectError: true, + }, + async (stdout, stderr) => { + exp(stderr).toContain(diagnosticMessage); + } + ); + test( + '[eval] should not ignore them', + execMacro, + { + flags: `-e "${code.replace(/\n/g, '')}"`, + expectError: true, + }, + async (stdout, stderr) => { + exp(stderr).toContain(diagnosticMessage); + } + ); + } + ); + + test('should support require flags', async () => { + const { err, stdout } = await exec( + `${cmd} -r ./hello-world -pe "console.log('success')"` + ); + expect(err).to.equal(null); + expect(stdout).to.equal('Hello, world!\nsuccess\nundefined\n'); + }); + + test('should support require from node modules', async () => { + const { err, stdout } = await exec( + `${cmd} -r typescript -e "console.log('success')"` + ); + expect(err).to.equal(null); + expect(stdout).to.equal('success\n'); + }); + + test('should use source maps with react tsx', async () => { + const { err, stdout } = await exec(`${cmd} "throw error react tsx.tsx"`); + expect(err).not.to.equal(null); + expect(err!.message).to.contain( + [ + `${join(TEST_DIR, './throw error react tsx.tsx')}:100`, + " bar() { throw new Error('this is a demo'); }", + ' ^', + 'Error: this is a demo', + ].join('\n') + ); + }); + + test('should use source maps with react tsx in --transpile-only mode', async () => { + const { err, stdout } = await exec( + `${cmd} --transpile-only "throw error react tsx.tsx"` + ); + expect(err).not.to.equal(null); + expect(err!.message).to.contain( + [ + `${join(TEST_DIR, './throw error react tsx.tsx')}:100`, + " bar() { throw new Error('this is a demo'); }", + ' ^', + 'Error: this is a demo', + ].join('\n') + ); + }); + + test('should allow custom typings', async () => { + const { err, stdout } = await exec(`${cmd} custom-types`); + expect(err).to.match(/Error: Cannot find module 'does-not-exist'/); + }); + + test('should preserve `ts-node` context with child process', async () => { + const { err, stdout } = await exec(`${cmd} child-process`); + expect(err).to.equal(null); + expect(stdout).to.equal('Hello, world!\n'); + }); + + test('should import js before ts by default', async () => { + const { err, stdout } = await exec(`${cmd} import-order/compiled`); + expect(err).to.equal(null); + expect(stdout).to.equal('Hello, JavaScript!\n'); + }); + + const preferTsExtsEntrypoint = semver.gte(process.version, '12.0.0') + ? 'import-order/compiled' + : 'import-order/require-compiled'; + test('should import ts before js when --prefer-ts-exts flag is present', async () => { + const { err, stdout } = await exec( + `${cmd} --prefer-ts-exts ${preferTsExtsEntrypoint}` + ); + expect(err).to.equal(null); + expect(stdout).to.equal('Hello, TypeScript!\n'); + }); + + test('should import ts before js when TS_NODE_PREFER_TS_EXTS env is present', async () => { + const { err, stdout } = await exec(`${cmd} ${preferTsExtsEntrypoint}`, { + env: { ...process.env, TS_NODE_PREFER_TS_EXTS: 'true' }, + }); + expect(err).to.equal(null); + expect(stdout).to.equal('Hello, TypeScript!\n'); + }); + + test('should ignore .d.ts files', async () => { + const { err, stdout } = await exec(`${cmd} import-order/importer`); + expect(err).to.equal(null); + expect(stdout).to.equal('Hello, World!\n'); + }); + + test.suite('issue #884', (test) => { + test('should compile', async (t) => { + // TODO disabled because it consistently fails on Windows on TS 2.7 + if ( + process.platform === 'win32' && + semver.satisfies(ts.version, '2.7') + ) { + t.log('Skipping'); + return; + } else { + const { err, stdout } = await exec( + `"${BIN_PATH}" --project issue-884/tsconfig.json issue-884` + ); + expect(err).to.equal(null); + expect(stdout).to.equal(''); + } + }); + }); + + test.suite('issue #986', (test) => { + test('should not compile', async () => { + const { err, stdout, stderr } = await exec( + `"${BIN_PATH}" --project issue-986/tsconfig.json issue-986` + ); + expect(err).not.to.equal(null); + expect(stderr).to.contain("Cannot find name 'TEST'"); // TypeScript error. + expect(stdout).to.equal(''); + }); + + test('should compile with `--files`', async () => { + const { err, stdout, stderr } = await exec( + `"${BIN_PATH}" --files --project issue-986/tsconfig.json issue-986` + ); + expect(err).not.to.equal(null); + expect(stderr).to.contain('ReferenceError: TEST is not defined'); // Runtime error. + expect(stdout).to.equal(''); + }); + }); + + if (semver.gte(ts.version, '2.7.0')) { + test('should locate tsconfig relative to entry-point by default', async () => { + const { err, stdout } = await exec(`${BIN_PATH} ../a/index`, { + cwd: join(TEST_DIR, 'cwd-and-script-mode/b'), + }); + expect(err).to.equal(null); + expect(stdout).to.match(/plugin-a/); + }); + test('should locate tsconfig relative to entry-point via ts-node-script', async () => { + const { err, stdout } = await exec(`${BIN_SCRIPT_PATH} ../a/index`, { + cwd: join(TEST_DIR, 'cwd-and-script-mode/b'), + }); + expect(err).to.equal(null); + expect(stdout).to.match(/plugin-a/); + }); + test('should locate tsconfig relative to entry-point with --script-mode', async () => { + const { err, stdout } = await exec( + `${BIN_PATH} --script-mode ../a/index`, + { + cwd: join(TEST_DIR, 'cwd-and-script-mode/b'), + } + ); + expect(err).to.equal(null); + expect(stdout).to.match(/plugin-a/); + }); + test('should locate tsconfig relative to cwd via ts-node-cwd', async () => { + const { err, stdout } = await exec(`${BIN_CWD_PATH} ../a/index`, { + cwd: join(TEST_DIR, 'cwd-and-script-mode/b'), + }); + expect(err).to.equal(null); + expect(stdout).to.match(/plugin-b/); + }); + test('should locate tsconfig relative to cwd in --cwd-mode', async () => { + const { err, stdout } = await exec( + `${BIN_PATH} --cwd-mode ../a/index`, + { cwd: join(TEST_DIR, 'cwd-and-script-mode/b') } + ); + expect(err).to.equal(null); + expect(stdout).to.match(/plugin-b/); + }); + test('should locate tsconfig relative to realpath, not symlink, when entrypoint is a symlink', async (t) => { + if ( + lstatSync( + join(TEST_DIR, 'main-realpath/symlink/symlink.tsx') + ).isSymbolicLink() + ) { + const { err, stdout } = await exec( + `${BIN_PATH} main-realpath/symlink/symlink.tsx` + ); + expect(err).to.equal(null); + expect(stdout).to.equal(''); + } else { + t.log('Skipping'); + return; + } + }); + } + + test.suite('should read ts-node options from tsconfig.json', (test) => { + const BIN_EXEC = `"${BIN_PATH}" --project tsconfig-options/tsconfig.json`; + + test('should override compiler options from env', async () => { + const { err, stdout } = await exec( + `${BIN_EXEC} tsconfig-options/log-options1.js`, + { + env: { + ...process.env, + TS_NODE_COMPILER_OPTIONS: '{"typeRoots": ["env-typeroots"]}', + }, + } + ); + expect(err).to.equal(null); + const { config } = JSON.parse(stdout); + expect(config.options.typeRoots).to.deep.equal([ + join(TEST_DIR, './tsconfig-options/env-typeroots').replace( + /\\/g, + '/' + ), + ]); + }); + + test('should use options from `tsconfig.json`', async () => { + const { err, stdout } = await exec( + `${BIN_EXEC} tsconfig-options/log-options1.js` + ); + expect(err).to.equal(null); + const { options, config } = JSON.parse(stdout); + expect(config.options.typeRoots).to.deep.equal([ + join(TEST_DIR, './tsconfig-options/tsconfig-typeroots').replace( + /\\/g, + '/' + ), + ]); + expect(config.options.types).to.deep.equal(['tsconfig-tsnode-types']); + expect(options.pretty).to.equal(undefined); + expect(options.skipIgnore).to.equal(false); + expect(options.transpileOnly).to.equal(true); + expect(options.require).to.deep.equal([ + join(TEST_DIR, './tsconfig-options/required1.js'), + ]); + }); + + test('should have flags override / merge with `tsconfig.json`', async () => { + const { err, stdout } = await exec( + `${BIN_EXEC} --skip-ignore --compiler-options "{\\"types\\":[\\"flags-types\\"]}" --require ./tsconfig-options/required2.js tsconfig-options/log-options2.js` + ); + expect(err).to.equal(null); + const { options, config } = JSON.parse(stdout); + expect(config.options.typeRoots).to.deep.equal([ + join(TEST_DIR, './tsconfig-options/tsconfig-typeroots').replace( + /\\/g, + '/' + ), + ]); + expect(config.options.types).to.deep.equal(['flags-types']); + expect(options.pretty).to.equal(undefined); + expect(options.skipIgnore).to.equal(true); + expect(options.transpileOnly).to.equal(true); + expect(options.require).to.deep.equal([ + join(TEST_DIR, './tsconfig-options/required1.js'), + './tsconfig-options/required2.js', + ]); + }); + + test('should have `tsconfig.json` override environment', async () => { + const { err, stdout } = await exec( + `${BIN_EXEC} tsconfig-options/log-options1.js`, + { + env: { + ...process.env, + TS_NODE_PRETTY: 'true', + TS_NODE_SKIP_IGNORE: 'true', + }, + } + ); + expect(err).to.equal(null); + const { options, config } = JSON.parse(stdout); + expect(config.options.typeRoots).to.deep.equal([ + join(TEST_DIR, './tsconfig-options/tsconfig-typeroots').replace( + /\\/g, + '/' + ), + ]); + expect(config.options.types).to.deep.equal(['tsconfig-tsnode-types']); + expect(options.pretty).to.equal(true); + expect(options.skipIgnore).to.equal(false); + expect(options.transpileOnly).to.equal(true); + expect(options.require).to.deep.equal([ + join(TEST_DIR, './tsconfig-options/required1.js'), + ]); + }); + + if (semver.gte(ts.version, '3.2.0')) { + test('should pull ts-node options from extended `tsconfig.json`', async () => { + const { err, stdout } = await exec( + `${BIN_PATH} --show-config --project ./tsconfig-extends/tsconfig.json` + ); + expect(err).to.equal(null); + const config = JSON.parse(stdout); + expect(config['ts-node'].require).to.deep.equal([ + resolve(TEST_DIR, 'tsconfig-extends/other/require-hook.js'), + ]); + expect(config['ts-node'].scopeDir).to.equal( + resolve(TEST_DIR, 'tsconfig-extends/other/scopedir') + ); + expect(config['ts-node'].preferTsExts).to.equal(true); + }); + } + }); + + test.suite( + 'should use implicit @tsconfig/bases config when one is not loaded from disk', + (_test) => { + const test = _test.context(async (t) => ({ + tempDir: mkdtempSync(join(tmpdir(), 'ts-node-spec')), + })); + if ( + semver.gte(ts.version, '3.5.0') && + semver.gte(process.versions.node, '14.0.0') + ) { + const libAndTarget = semver.gte(process.versions.node, '16.0.0') + ? 'es2021' + : 'es2020'; + test('implicitly uses @tsconfig/node14 or @tsconfig/node16 compilerOptions when both TS and node versions support it', async (t) => { + // node14 and node16 configs are identical, hence the "or" + const { + context: { tempDir }, + } = t; + const { + err: err1, + stdout: stdout1, + stderr: stderr1, + } = await exec(`${BIN_PATH} --showConfig`, { cwd: tempDir }); + expect(err1).to.equal(null); + t.like(JSON.parse(stdout1), { + compilerOptions: { + target: libAndTarget, + lib: [libAndTarget], + }, + }); + const { + err: err2, + stdout: stdout2, + stderr: stderr2, + } = await exec(`${BIN_PATH} -pe 10n`, { cwd: tempDir }); + expect(err2).to.equal(null); + expect(stdout2).to.equal('10n\n'); + }); + } else { + test('implicitly uses @tsconfig/* lower than node14 (node12) when either TS or node versions do not support @tsconfig/node14', async ({ + context: { tempDir }, + }) => { + const { err, stdout, stderr } = await exec(`${BIN_PATH} -pe 10n`, { + cwd: tempDir, + }); + expect(err).to.not.equal(null); + expect(stderr).to.match( + /BigInt literals are not available when targeting lower than|error TS2304: Cannot find name 'n'/ + ); + }); + } + test('implicitly loads @types/node even when not installed within local directory', async ({ + context: { tempDir }, + }) => { + const { err, stdout, stderr } = await exec( + `${BIN_PATH} -pe process.env.foo`, + { + cwd: tempDir, + env: { ...process.env, foo: 'hello world' }, + } + ); + expect(err).to.equal(null); + expect(stdout).to.equal('hello world\n'); + }); + test('implicitly loads local @types/node', async ({ + context: { tempDir }, + }) => { + await xfs.copyPromise( + npath.toPortablePath(tempDir), + npath.toPortablePath(join(TEST_DIR, 'local-types-node')) + ); + const { err, stdout, stderr } = await exec( + `${BIN_PATH} -pe process.env.foo`, + { + cwd: tempDir, + env: { ...process.env, foo: 'hello world' }, + } + ); + expect(err).to.not.equal(null); + expect(stderr).to.contain( + "Property 'env' does not exist on type 'LocalNodeTypes_Process'" + ); + }); + } + ); + + if (semver.gte(ts.version, '3.2.0')) { + test.suite( + 'should bundle @tsconfig/bases to be used in your own tsconfigs', + (test) => { + const macro = test.macro((nodeVersion: string) => async (t) => { + const config = require(`@tsconfig/${nodeVersion}/tsconfig.json`); + const { err, stdout, stderr } = await exec( + `${BIN_PATH} --showConfig -e 10n`, + { + cwd: join(TEST_DIR, 'tsconfig-bases', nodeVersion), + } + ); + expect(err).to.equal(null); + t.like(JSON.parse(stdout), { + compilerOptions: { + target: config.compilerOptions.target, + lib: config.compilerOptions.lib, + }, + }); + }); + test(`ts-node/node10/tsconfig.json`, macro, 'node10'); + test(`ts-node/node12/tsconfig.json`, macro, 'node12'); + test(`ts-node/node14/tsconfig.json`, macro, 'node14'); + test(`ts-node/node16/tsconfig.json`, macro, 'node16'); + } + ); + } + + test.suite('compiler host', (test) => { + test('should execute cli', async () => { + const { err, stdout } = await exec( + `${cmd} --compiler-host hello-world` + ); + expect(err).to.equal(null); + expect(stdout).to.equal('Hello, world!\n'); + }); + }); + + test('should transpile files inside a node_modules directory when not ignored', async () => { + const { err, stdout, stderr } = await exec( + `${cmdNoProject} from-node-modules/from-node-modules` + ); + if (err) + throw new Error( + `Unexpected error: ${err}\nstdout:\n${stdout}\nstderr:\n${stderr}` + ); + expect(JSON.parse(stdout)).to.deep.equal({ + external: { + tsmri: { name: 'typescript-module-required-internally' }, + jsmri: { name: 'javascript-module-required-internally' }, + tsmii: { name: 'typescript-module-imported-internally' }, + jsmii: { name: 'javascript-module-imported-internally' }, + }, + tsmie: { name: 'typescript-module-imported-externally' }, + jsmie: { name: 'javascript-module-imported-externally' }, + tsmre: { name: 'typescript-module-required-externally' }, + jsmre: { name: 'javascript-module-required-externally' }, + }); + }); + + test.suite('should respect maxNodeModulesJsDepth', (test) => { + test('for unscoped modules', async () => { + const { err, stdout, stderr } = await exec( + `${cmdNoProject} maxnodemodulesjsdepth` + ); + expect(err).to.not.equal(null); + expect(stderr.replace(/\r\n/g, '\n')).to.contain( + 'TSError: ⨯ Unable to compile TypeScript:\n' + + "maxnodemodulesjsdepth/other.ts(4,7): error TS2322: Type 'string' is not assignable to type 'boolean'.\n" + + '\n' + ); + }); + + test('for @scoped modules', async () => { + const { err, stdout, stderr } = await exec( + `${cmdNoProject} maxnodemodulesjsdepth-scoped` + ); + expect(err).to.not.equal(null); + expect(stderr.replace(/\r\n/g, '\n')).to.contain( + 'TSError: ⨯ Unable to compile TypeScript:\n' + + "maxnodemodulesjsdepth-scoped/other.ts(7,7): error TS2322: Type 'string' is not assignable to type 'boolean'.\n" + + '\n' + ); + }); + }); + + if (semver.gte(ts.version, '3.2.0')) { + test('--show-config should log resolved configuration', async (t) => { + function native(path: string) { + return path.replace(/\/|\\/g, pathSep); + } + function posix(path: string) { + return path.replace(/\/|\\/g, '/'); + } + const { err, stdout } = await exec(`${cmd} --showConfig`); + expect(err).to.equal(null); + t.is( + stdout, + JSON.stringify( + { + 'ts-node': { + cwd: native(`${ROOT_DIR}/tests`), + projectSearchDir: native(`${ROOT_DIR}/tests`), + project: native(`${ROOT_DIR}/tests/tsconfig.json`), + require: [], + }, + compilerOptions: { + target: 'es6', + jsx: 'react', + noEmit: false, + strict: true, + typeRoots: [ + posix(`${ROOT_DIR}/tests/typings`), + posix(`${ROOT_DIR}/node_modules/@types`), + ], + sourceMap: true, + inlineSourceMap: false, + inlineSources: true, + declaration: false, + outDir: './.ts-node', + module: 'commonjs', + }, + }, + null, + 2 + ) + '\n' + ); + }); + } else { + test('--show-config should log error message when used with old typescript versions', async (t) => { + const { err, stderr } = await exec(`${cmd} --showConfig`); + expect(err).to.not.equal(null); + expect(stderr).to.contain('Error: --show-config requires'); + }); + } + + test('should support compiler scope specified via tsconfig.json', async (t) => { + const { err, stderr, stdout } = await exec( + `${cmdNoProject} --project ./scope/c/config/tsconfig.json ./scope/c/index.js` + ); + expect(err).to.equal(null); + expect(stdout).to.equal(`value\nFailures: 0\n`); + }); + }); + + test.suite('register', (_test) => { + const test = _test.context( + once(async () => { + return { + registered: register({ + project: PROJECT, + compilerOptions: { + jsx: 'preserve', + }, + }), + moduleTestPath: require.resolve('../../tests/module'), + }; + }) + ); + test.beforeEach(async ({ context: { registered } }) => { + // Re-enable project for every test. + registered.enabled(true); + }); + test.runSerially(); + + test('should be able to require typescript', ({ + context: { moduleTestPath }, + }) => { + const m = require(moduleTestPath); + + expect(m.example('foo')).to.equal('FOO'); + }); + + test('should support dynamically disabling', ({ + context: { registered, moduleTestPath }, + }) => { + delete require.cache[moduleTestPath]; + + expect(registered.enabled(false)).to.equal(false); + expect(() => require(moduleTestPath)).to.throw(/Unexpected token/); + + delete require.cache[moduleTestPath]; + + expect(registered.enabled()).to.equal(false); + expect(() => require(moduleTestPath)).to.throw(/Unexpected token/); + + delete require.cache[moduleTestPath]; + + expect(registered.enabled(true)).to.equal(true); + expect(() => require(moduleTestPath)).to.not.throw(); + + delete require.cache[moduleTestPath]; + + expect(registered.enabled()).to.equal(true); + expect(() => require(moduleTestPath)).to.not.throw(); + }); + + test('should support compiler scopes', ({ + context: { registered, moduleTestPath }, + }) => { + const calls: string[] = []; + + registered.enabled(false); + + const compilers = [ + register({ + projectSearchDir: join(TEST_DIR, 'scope/a'), + scopeDir: join(TEST_DIR, 'scope/a'), + scope: true, + }), + register({ + projectSearchDir: join(TEST_DIR, 'scope/a'), + scopeDir: join(TEST_DIR, 'scope/b'), + scope: true, + }), + ]; + + compilers.forEach((c) => { + const old = c.compile; + c.compile = (code, fileName, lineOffset) => { + calls.push(fileName); + + return old(code, fileName, lineOffset); + }; + }); + + try { + expect(require('../../tests/scope/a').ext).to.equal('.ts'); + expect(require('../../tests/scope/b').ext).to.equal('.ts'); + } finally { + compilers.forEach((c) => c.enabled(false)); + } + + expect(calls).to.deep.equal([ + join(TEST_DIR, 'scope/a/index.ts'), + join(TEST_DIR, 'scope/b/index.ts'), + ]); + + delete require.cache[moduleTestPath]; + + expect(() => require(moduleTestPath)).to.throw(); + }); + + test('should compile through js and ts', () => { + const m = require('../../tests/complex'); + + expect(m.example()).to.equal('example'); + }); + + test('should work with proxyquire', () => { + const m = proxyquire('../../tests/complex', { + './example': 'hello', + }); + + expect(m.example()).to.equal('hello'); + }); + + test('should work with `require.cache`', () => { + const { example1, example2 } = require('../../tests/require-cache'); + + expect(example1).to.not.equal(example2); + }); + + test('should use source maps', async () => { + try { + require('../../tests/throw error'); + } catch (error) { + expect(error.stack).to.contain( + [ + 'Error: this is a demo', + ` at Foo.bar (${join(TEST_DIR, './throw error.ts')}:100:17)`, + ].join('\n') + ); + } + }); + + test.suite('JSX preserve', (test) => { + let old: (m: Module, filename: string) => any; + let compiled: string; + + test.runSerially(); + test.beforeAll(async () => { + old = require.extensions['.tsx']!; + require.extensions['.tsx'] = (m: any, fileName) => { + const _compile = m._compile; + + m._compile = function (code: string, fileName: string) { + compiled = code; + return _compile.call(this, code, fileName); + }; + + return old(m, fileName); + }; + }); + + test('should use source maps', async (t) => { + t.teardown(() => { + require.extensions['.tsx'] = old; + }); + try { + require('../../tests/with-jsx.tsx'); + } catch (error) { + expect(error.stack).to.contain('SyntaxError: Unexpected token'); + } + + expect(compiled).to.match(SOURCE_MAP_REGEXP); + }); + }); + }); + + test.suite('create', (_test) => { + const test = _test.context(async (t) => { + return { + service: create({ + compilerOptions: { target: 'es5' }, + skipProject: true, + }), + }; + }); + + test('should create generic compiler instances', ({ + context: { service }, + }) => { + const output = service.compile('const x = 10', 'test.ts'); + expect(output).to.contain('var x = 10;'); + }); + + test.suite('should get type information', (test) => { + test('given position of identifier', ({ context: { service } }) => { + expect( + service.getTypeInfo('/**jsdoc here*/const x = 10', 'test.ts', 21) + ).to.deep.equal({ + comment: 'jsdoc here', + name: 'const x: 10', + }); + }); + test('given position that does not point to an identifier', ({ + context: { service }, + }) => { + expect( + service.getTypeInfo('/**jsdoc here*/const x = 10', 'test.ts', 0) + ).to.deep.equal({ + comment: '', + name: '', + }); + }); + }); + }); + + test.suite('issue #1098', (test) => { + function testIgnored( + ignored: tsNodeTypes.Service['ignored'], + allowed: string[], + disallowed: string[] + ) { + for (const ext of allowed) { + expect(ignored(join(DIST_DIR, `index${ext}`))).equal( + false, + `should accept ${ext} files` + ); + } + for (const ext of disallowed) { + expect(ignored(join(DIST_DIR, `index${ext}`))).equal( + true, + `should ignore ${ext} files` + ); + } + } + + test('correctly filters file extensions from the compiler when allowJs=false and jsx=false', () => { + const { ignored } = create({ compilerOptions: {}, skipProject: true }); + testIgnored( + ignored, + ['.ts', '.d.ts'], + ['.js', '.tsx', '.jsx', '.mjs', '.cjs', '.xyz', ''] + ); + }); + test('correctly filters file extensions from the compiler when allowJs=true and jsx=false', () => { + const { ignored } = create({ + compilerOptions: { allowJs: true }, + skipProject: true, + }); + testIgnored( + ignored, + ['.ts', '.js', '.d.ts'], + ['.tsx', '.jsx', '.mjs', '.cjs', '.xyz', ''] + ); + }); + test('correctly filters file extensions from the compiler when allowJs=false and jsx=true', () => { + const { ignored } = create({ + compilerOptions: { allowJs: false, jsx: 'preserve' }, + skipProject: true, + }); + testIgnored( + ignored, + ['.ts', '.tsx', '.d.ts'], + ['.js', '.jsx', '.mjs', '.cjs', '.xyz', ''] + ); + }); + test('correctly filters file extensions from the compiler when allowJs=true and jsx=true', () => { + const { ignored } = create({ + compilerOptions: { allowJs: true, jsx: 'preserve' }, + skipProject: true, + }); + testIgnored( + ignored, + ['.ts', '.tsx', '.js', '.jsx', '.d.ts'], + ['.mjs', '.cjs', '.xyz', ''] + ); + }); + }); + + test.suite('esm', (test) => { + if (semver.gte(process.version, '12.16.0')) { + test('should compile and execute as ESM', async () => { + const { err, stdout } = await exec( + `${cmdEsmLoaderNoProject} index.ts`, + { + cwd: join(TEST_DIR, './esm'), + } + ); + expect(err).to.equal(null); + expect(stdout).to.equal('foo bar baz biff libfoo\n'); + }); + test('should use source maps', async () => { + const { err, stdout } = await exec( + `${cmdEsmLoaderNoProject} "throw error.ts"`, + { + cwd: join(TEST_DIR, './esm'), + } + ); + expect(err).not.to.equal(null); + expect(err!.message).to.contain( + [ + `${pathToFileURL(join(TEST_DIR, './esm/throw error.ts')) + .toString() + .replace(/%20/g, ' ')}:100`, + " bar() { throw new Error('this is a demo'); }", + ' ^', + 'Error: this is a demo', + ].join('\n') + ); + }); + + test.suite('supports experimental-specifier-resolution=node', (test) => { + test('via --experimental-specifier-resolution', async () => { + const { + err, + stdout, + } = await exec( + `${cmdEsmLoaderNoProject} --experimental-specifier-resolution=node index.ts`, + { cwd: join(TEST_DIR, './esm-node-resolver') } + ); + expect(err).to.equal(null); + expect(stdout).to.equal('foo bar baz biff libfoo\n'); + }); + test('via --es-module-specifier-resolution alias', async () => { + const { + err, + stdout, + } = await exec( + `${cmdEsmLoaderNoProject} --experimental-modules --es-module-specifier-resolution=node index.ts`, + { cwd: join(TEST_DIR, './esm-node-resolver') } + ); + expect(err).to.equal(null); + expect(stdout).to.equal('foo bar baz biff libfoo\n'); + }); + test('via NODE_OPTIONS', async () => { + const { err, stdout } = await exec( + `${cmdEsmLoaderNoProject} index.ts`, + { + cwd: join(TEST_DIR, './esm-node-resolver'), + env: { + ...process.env, + NODE_OPTIONS: `${experimentalModulesFlag} --experimental-specifier-resolution=node`, + }, + } + ); + expect(err).to.equal(null); + expect(stdout).to.equal('foo bar baz biff libfoo\n'); + }); + }); + + test('throws ERR_REQUIRE_ESM when attempting to require() an ESM script when ESM loader is enabled', async () => { + const { err, stderr } = await exec( + `${cmdEsmLoaderNoProject} ./index.js`, + { + cwd: join(TEST_DIR, './esm-err-require-esm'), + } + ); + expect(err).to.not.equal(null); + expect(stderr).to.contain( + 'Error [ERR_REQUIRE_ESM]: Must use import to load ES Module:' + ); + }); + + test('defers to fallback loaders when URL should not be handled by ts-node', async () => { + const { err, stdout, stderr } = await exec( + `${cmdEsmLoaderNoProject} index.mjs`, + { + cwd: join(TEST_DIR, './esm-import-http-url'), + } + ); + expect(err).to.not.equal(null); + // expect error from node's default resolver + expect(stderr).to.match( + /Error \[ERR_UNSUPPORTED_ESM_URL_SCHEME\]:.*(?:\n.*){0,1}\n *at defaultResolve/ + ); + }); + + test('should bypass import cache when changing search params', async () => { + const { err, stdout } = await exec( + `${cmdEsmLoaderNoProject} index.ts`, + { + cwd: join(TEST_DIR, './esm-import-cache'), + } + ); + expect(err).to.equal(null); + expect(stdout).to.equal('log1\nlog2\nlog2\n'); + }); + + test('should support transpile only mode via dedicated loader entrypoint', async () => { + const { err, stdout } = await exec( + `${cmdEsmLoaderNoProject}/transpile-only index.ts`, + { + cwd: join(TEST_DIR, './esm-transpile-only'), + } + ); + expect(err).to.equal(null); + expect(stdout).to.equal(''); + }); + test('should throw type errors without transpile-only enabled', async () => { + const { err, stdout } = await exec( + `${cmdEsmLoaderNoProject} index.ts`, + { + cwd: join(TEST_DIR, './esm-transpile-only'), + } + ); + if (err === null) { + throw new Error('Command was expected to fail, but it succeeded.'); + } + + expect(err.message).to.contain('Unable to compile TypeScript'); + expect(err.message).to.match( + new RegExp( + "TS2345: Argument of type '(?:number|1101)' is not assignable to parameter of type 'string'\\." + ) + ); + expect(err.message).to.match( + new RegExp( + "TS2322: Type '(?:\"hello world\"|string)' is not assignable to type 'number'\\." + ) + ); + expect(stdout).to.equal(''); + }); + + async function runModuleTypeTest(project: string, ext: string) { + const { err, stderr, stdout } = await exec( + `${cmdEsmLoaderNoProject} ./module-types/${project}/test.${ext}`, + { + env: { + ...process.env, + TS_NODE_PROJECT: `./module-types/${project}/tsconfig.json`, + }, + } + ); + expect(err).to.equal(null); + expect(stdout).to.equal(`Failures: 0\n`); + } + + test('moduleTypes should allow importing CJS in an otherwise ESM project', async (t) => { + // A notable case where you can use ts-node's CommonJS loader, not the ESM loader, in an ESM project: + // when loading a webpack.config.ts or similar config + const { err, stderr, stdout } = await exec( + `${cmdNoProject} --project ./module-types/override-to-cjs/tsconfig.json ./module-types/override-to-cjs/test-webpack-config.cjs` + ); + expect(err).to.equal(null); + expect(stdout).to.equal(``); + + await runModuleTypeTest('override-to-cjs', 'cjs'); + if (semver.gte(process.version, '14.13.1')) + await runModuleTypeTest('override-to-cjs', 'mjs'); + }); + + test('moduleTypes should allow importing ESM in an otherwise CJS project', async (t) => { + await runModuleTypeTest('override-to-esm', 'cjs'); + // Node 14.13.0 has a bug(?) where it checks for ESM-only syntax *before* we transform the code. + if (semver.gte(process.version, '14.13.1')) + await runModuleTypeTest('override-to-esm', 'mjs'); + }); + } + + if (semver.gte(process.version, '12.0.0')) { + test('throws ERR_REQUIRE_ESM when attempting to require() an ESM script when ESM loader is *not* enabled and node version is >= 12', async () => { + // Node versions >= 12 support package.json "type" field and so will throw an error when attempting to load ESM as CJS + const { err, stderr } = await exec(`${BIN_PATH} ./index.js`, { + cwd: join(TEST_DIR, './esm-err-require-esm'), + }); + expect(err).to.not.equal(null); + expect(stderr).to.contain( + 'Error [ERR_REQUIRE_ESM]: Must use import to load ES Module:' + ); + }); + } else { + test('Loads as CommonJS when attempting to require() an ESM script when ESM loader is *not* enabled and node version is < 12', async () => { + // Node versions less than 12 do not support package.json "type" field and so will load ESM as CommonJS + const { err, stdout } = await exec(`${BIN_PATH} ./index.js`, { + cwd: join(TEST_DIR, './esm-err-require-esm'), + }); + expect(err).to.equal(null); + expect(stdout).to.contain('CommonJS'); + }); + } + }); + + test.suite('top level await', (test) => { + const compilerOptions = { + target: 'es2018', + }; + function executeInTlaRepl(input: string, waitMs = 1000) { + return executeInRepl( + input + .split('\n') + .map((line) => line.trim()) + // Restore newline once https://github.com/nodejs/node/pull/39392 is merged + .join(''), + { + waitMs, + createServiceOpts: { + experimentalReplAwait: true, + compilerOptions, + }, + startOptions: { useGlobal: false }, + } + ); + } + + if (semver.gte(ts.version, '3.8.0')) { + // Serial because it's timing-sensitive + test.serial('should allow evaluating top level await', async () => { + const script = ` + const x: number = await new Promise((r) => r(1)); + for await (const x of [1,2,3]) { console.log(x) }; + for (const x of ['a', 'b']) { await x; console.log(x) }; + class Foo {}; await 1; + function Bar() {}; await 2; + const {y} = await ({y: 2}); + const [z] = await [3]; + x + y + z; + `; + + const { stdout, stderr } = await executeInTlaRepl(script); + expect(stderr).to.equal(''); + expect(stdout).to.equal('> 1\n2\n3\na\nb\n6\n> '); + }); + + // Serial because it's timing-sensitive + test.serial( + 'should wait until promise is settled when awaiting at top level', + async () => { + const awaitMs = 500; + const script = ` + const startTime = new Date().getTime(); + await new Promise((r) => setTimeout(() => r(1), ${awaitMs})); + const endTime = new Date().getTime(); + endTime - startTime; + `; + const { stdout, stderr } = await executeInTlaRepl(script, 6000); + + expect(stderr).to.equal(''); + + const elapsedTime = Number( + stdout.split('\n')[0].replace('> ', '').trim() + ); + expect(elapsedTime).to.be.gte(awaitMs - 50); + expect(elapsedTime).to.be.lte(awaitMs + 100); + } + ); + + // Serial because it's timing-sensitive + test.serial( + 'should not wait until promise is settled when not using await at top level', + async () => { + const script = ` + const startTime = new Date().getTime(); + (async () => await new Promise((r) => setTimeout(() => r(1), ${1000})))(); + const endTime = new Date().getTime(); + endTime - startTime; + `; + const { stdout, stderr } = await executeInTlaRepl(script); + + expect(stderr).to.equal(''); + + const ellapsedTime = Number( + stdout.split('\n')[0].replace('> ', '').trim() + ); + expect(ellapsedTime).to.be.gte(0); + expect(ellapsedTime).to.be.lte(10); + } + ); + + // Serial because it's timing-sensitive + test.serial( + 'should error with typing information when awaited result has type mismatch', + async () => { + const { stdout, stderr } = await executeInTlaRepl( + 'const x: string = await 1' + ); + + expect(stdout).to.equal('> > '); + expect(stderr.replace(/\r\n/g, '\n')).to.equal( + '.ts(2,7): error TS2322: ' + + (semver.gte(ts.version, '4.0.0') + ? `Type 'number' is not assignable to type 'string'.\n` + : `Type '1' is not assignable to type 'string'.\n`) + + '\n' + ); + } + ); + + // Serial because it's timing-sensitive + test.serial( + 'should error with typing information when importing a file with type errors', + async () => { + const { stdout, stderr } = await executeInTlaRepl( + `const {foo} = await import('./tests/repl/tla-import');` + ); + + expect(stdout).to.equal('> > '); + expect(stderr.replace(/\r\n/g, '\n')).to.equal( + 'tests/repl/tla-import.ts(1,14): error TS2322: ' + + (semver.gte(ts.version, '4.0.0') + ? `Type 'number' is not assignable to type 'string'.\n` + : `Type '1' is not assignable to type 'string'.\n`) + + '\n' + ); + } + ); + + test('should pass upstream test cases', async () => + upstreamTopLevelAwaitTests({ TEST_DIR, create, createRepl })); + } else { + test('should throw error when attempting to use top level await on TS < 3.8', async () => { + exp(executeInTlaRepl('', 1000)).rejects.toThrow( + 'Experimental REPL await is not compatible with TypeScript versions older than 3.8' + ); + }); + } + }); +}); diff --git a/src/test/macros.ts b/src/test/macros.ts new file mode 100644 index 000000000..4e076ae30 --- /dev/null +++ b/src/test/macros.ts @@ -0,0 +1,108 @@ +import type { ChildProcess, ExecException, ExecOptions } from 'child_process'; +import { exec as childProcessExec } from 'child_process'; +import type { TestInterface } from './testlib'; +import { expect } from 'chai'; +import * as exp from 'expect'; + +export type ExecReturn = Promise & { child: ChildProcess }; +export interface ExecResult { + stdout: string; + stderr: string; + err: null | ExecException; + child: ChildProcess; +} + +export interface ExecMacroOptions { + titlePrefix?: string; + cmd: string; + flags?: string; + cwd?: string; + env?: Record; + stdin?: string; + expectError?: boolean; +} +export type ExecMacroAssertionCallback = ( + stdout: string, + stderr: string, + err: ExecException | null +) => Promise | void; + +export interface createMacrosAndHelpersOptions { + test: TestInterface; + defaultCwd: string; +} +export function createMacrosAndHelpers(opts: createMacrosAndHelpersOptions) { + const { test, defaultCwd } = opts; + + /** + * Helper to exec a child process. + * Returns a Promise and a reference to the child process to suite multiple situations. + * Promise resolves with the process's stdout, stderr, and error. + */ + function exec(cmd: string, opts: ExecOptions = {}): ExecReturn { + let child!: ChildProcess; + return Object.assign( + new Promise((resolve, reject) => { + child = childProcessExec( + cmd, + { + cwd: defaultCwd, + ...opts, + }, + (err, stdout, stderr) => { + resolve({ err, stdout, stderr, child }); + } + ); + }), + { + child, + } + ); + } + + /** + * Create a macro that launches a CLI command, optionally pipes stdin, optionally sets env vars, + * and allows assertions against the output. + */ + function createExecMacro>( + preBoundOptions: T + ) { + return test.macro( + ( + options: Pick< + ExecMacroOptions, + Exclude + > & + Partial>, + assertions: ExecMacroAssertionCallback + ) => [ + (title) => `${options.titlePrefix ?? ''}${title}`, + async (t) => { + const { cmd, flags = '', stdin, expectError = false, cwd, env } = { + ...preBoundOptions, + ...options, + }; + const execPromise = exec(`${cmd} ${flags}`, { + cwd, + env: { ...process.env, ...env }, + }); + if (stdin !== undefined) { + execPromise.child.stdin!.end(stdin); + } + const { err, stdout, stderr } = await execPromise; + if (expectError) { + exp(err).toBeDefined(); + } else { + exp(err).toBeNull(); + } + await assertions(stdout, stderr, err); + }, + ] + ); + } + + return { + exec, + createExecMacro, + }; +} diff --git a/src/test/node-repl-tla.ts b/src/test/node-repl-tla.ts new file mode 100644 index 000000000..c981892d1 --- /dev/null +++ b/src/test/node-repl-tla.ts @@ -0,0 +1,336 @@ +import { expect } from 'chai'; +import type { Key } from 'readline'; +import { Stream } from 'stream'; +import type * as tsNodeTypes from '../index'; +import semver = require('semver'); +import ts = require('typescript'); + +interface SharedObjects + extends Pick { + TEST_DIR: string; +} + +// Based on https://github.com/nodejs/node/blob/88799930794045795e8abac874730f9eba7e2300/test/parallel/test-repl-top-level-await.js +export async function upstreamTopLevelAwaitTests({ + TEST_DIR, + create, + createRepl, +}: SharedObjects) { + const PROMPT = 'await repl > '; + + const putIn = new REPLStream(); + const replService = createRepl({ + // @ts-ignore + stdin: putIn, + // @ts-ignore + stdout: putIn, + // @ts-ignore + stderr: putIn, + }); + const service = create({ + ...replService.evalAwarePartialHost, + project: `${TEST_DIR}/tsconfig.json`, + experimentalReplAwait: true, + transpileOnly: true, + compilerOptions: { + target: semver.gte(ts.version, '3.0.1') + ? 'es2018' + : // TS 2.7 is using polyfill for async interator even though they + // were added in es2018 + 'esnext', + }, + }); + replService.setService(service); + (replService.stdout as NodeJS.WritableStream & { + isTTY: boolean; + }).isTTY = true; + const replServer = replService.startInternal({ + prompt: PROMPT, + terminal: true, + useColors: true, + useGlobal: false, + }); + + function runAndWait(cmds: Array) { + const promise = putIn.wait(); + for (const cmd of cmds) { + if (typeof cmd === 'string') { + putIn.run([cmd]); + } else { + replServer.write('', cmd); + } + } + return promise; + } + + runAndWait([ + 'function foo(x) { return x; }', + 'function koo() { return Promise.resolve(4); }', + ]); + + const testCases = [ + ['await Promise.resolve(0)', '0'], + + // issue: { a: await Promise.resolve(1) } is being interpreted as a block + // remove surrounding parenthesis once issue is fixed + ['({ a: await Promise.resolve(1) })', '{ a: 1 }'], + + ['_', '{ a: 1 }'], + ['let { aa, bb } = await Promise.resolve({ aa: 1, bb: 2 }), f = 5;'], + ['aa', '1'], + ['bb', '2'], + ['f', '5'], + ['let cc = await Promise.resolve(2)'], + ['cc', '2'], + ['let dd;'], + ['dd'], + ['let [ii, { abc: { kk } }] = [0, { abc: { kk: 1 } }];'], + ['ii', '0'], + ['kk', '1'], + ['var ll = await Promise.resolve(2);'], + ['ll', '2'], + ['foo(await koo())', '4'], + ['_', '4'], + ['const m = foo(await koo());'], + ['m', '4'], + + // issue: REPL doesn't recognize end of input + // compile is returning TS1005 after second line even though + // it's valid syntax + // [ + // 'const n = foo(await\nkoo());', + // ['const n = foo(await\r', '... koo());\r', 'undefined'], + // ], + + [ + '`status: ${(await Promise.resolve({ status: 200 })).status}`', + "'status: 200'", + ], + ['for (let i = 0; i < 2; ++i) await i'], + ['for (let i = 0; i < 2; ++i) { await i }'], + ['await 0', '0'], + ['await 0; function foo() {}'], + ['foo', '[Function: foo]'], + ['class Foo {}; await 1;', '1'], + + [ + 'Foo', + // Adjusted since ts-node supports older versions of node + semver.gte(process.version, '12.18.0') + ? '[class Foo]' + : '[Function: Foo]', + ], + ['if (await true) { function fooz() {}; }'], + ['fooz', '[Function: fooz]'], + ['if (await true) { class Bar {}; }'], + + [ + 'Bar', + // Adjusted since ts-node supports older versions of node + semver.gte(process.version, '12.16.0') + ? 'Uncaught ReferenceError: Bar is not defined' + : 'ReferenceError: Bar is not defined', + // Line increased due to TS added lines + { + line: semver.gte(process.version, '12.16.0') ? 4 : 5, + }, + ], + + ['await 0; function* gen(){}'], + ['for (var i = 0; i < 10; ++i) { await i; }'], + ['i', '10'], + ['for (let j = 0; j < 5; ++j) { await j; }'], + + [ + 'j', + // Adjusted since ts-node supports older versions of node + semver.gte(process.version, '12.16.0') + ? 'Uncaught ReferenceError: j is not defined' + : 'ReferenceError: j is not defined', + // Line increased due to TS added lines + { + line: semver.gte(process.version, '12.16.0') ? 4 : 5, + }, + ], + + ['gen', '[GeneratorFunction: gen]'], + + [ + 'return 42; await 5;', + // Adjusted since ts-node supports older versions of node + semver.gte(process.version, '12.16.0') + ? 'Uncaught SyntaxError: Illegal return statement' + : 'SyntaxError: Illegal return statement', + // Line increased due to TS added lines + { + line: semver.gte(process.version, '12.16.0') ? 4 : 5, + }, + ], + + ['let o = await 1, p'], + ['p'], + ['let q = 1, s = await 2'], + ['s', '2'], + [ + 'for await (let i of [1,2,3]) console.log(i)', + [ + 'for await (let i of [1,2,3]) console.log(i)\r', + '1', + '2', + '3', + 'undefined', + ], + ], + + // issue: REPL is expecting more input to finish execution + // compiler is returning TS1003 error + // [ + // 'await Promise..resolve()', + // [ + // 'await Promise..resolve()\r', + // 'Uncaught SyntaxError: ', + // 'await Promise..resolve()', + // ' ^', + // '', + // "Unexpected token '.'", + // ], + // ], + + [ + 'for (const x of [1,2,3]) {\nawait x\n}', + ['for (const x of [1,2,3]) {\r', '... await x\r', '... }\r', 'undefined'], + ], + [ + 'for (const x of [1,2,3]) {\nawait x;\n}', + [ + 'for (const x of [1,2,3]) {\r', + '... await x;\r', + '... }\r', + 'undefined', + ], + ], + [ + 'for await (const x of [1,2,3]) {\nconsole.log(x)\n}', + [ + 'for await (const x of [1,2,3]) {\r', + '... console.log(x)\r', + '... }\r', + '1', + '2', + '3', + 'undefined', + ], + ], + [ + 'for await (const x of [1,2,3]) {\nconsole.log(x);\n}', + [ + 'for await (const x of [1,2,3]) {\r', + '... console.log(x);\r', + '... }\r', + '1', + '2', + '3', + 'undefined', + ], + ], + ] as const; + + for (const [ + input, + expected = [`${input}\r`], + options = {} as { line?: number }, + ] of testCases) { + const toBeRun = input.split('\n'); + const lines = await runAndWait(toBeRun); + if (Array.isArray(expected)) { + if (expected.length === 1) expected.push('undefined'); + if (lines[0] === input) lines.shift(); + expect(lines).to.eqls([...expected, PROMPT]); + } else if ('line' in options) { + expect(lines[toBeRun.length + options.line!]).to.eqls(expected); + } else { + const echoed = toBeRun.map((a, i) => `${i > 0 ? '... ' : ''}${a}\r`); + expect(lines).to.eqls([...echoed, expected, PROMPT]); + } + } +} + +// copied from https://github.com/nodejs/node/blob/88799930794045795e8abac874730f9eba7e2300/lib/internal/util/inspect.js#L220-L227 +// Regex used for ansi escape code splitting +// Adopted from https://github.com/chalk/ansi-regex/blob/HEAD/index.js +// License: MIT, authors: @sindresorhus, Qix-, arjunmehta and LitoMore +// Matches all ansi escape code sequences in a string +const ansiPattern = + '[\\u001B\\u009B][[\\]()#;?]*' + + '(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)' + + '|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))'; +const ansi = new RegExp(ansiPattern, 'g'); + +// copied from https://github.com/nodejs/node/blob/88799930794045795e8abac874730f9eba7e2300/lib/internal/util/inspect.js#L2112-L2117 +/** + * Remove all VT control characters. Use to estimate displayed string width. + */ +function stripVTControlCharacters(str: string) { + return str.replace(ansi, ''); +} + +// copied from https://github.com/nodejs/node/blob/88799930794045795e8abac874730f9eba7e2300/test/parallel/test-repl-top-level-await.js +class ArrayStream extends Stream { + readable = true; + writable = true; + + run(data: string[]) { + data.forEach((line) => { + this.emit('data', `${line}\n`); + }); + } + + pause() {} + resume() {} + write(_chunk: Buffer | string, _encoding: string, _callback: () => {}) {} +} + +export class REPLStream extends ArrayStream { + waitingForResponse = false; + lines = ['']; + + constructor() { + super(); + } + + write(chunk: Buffer | string, encoding: string, callback: () => void) { + if (Buffer.isBuffer(chunk)) { + chunk = chunk.toString(encoding); + } + const chunkLines = stripVTControlCharacters(chunk).split('\n'); + this.lines[this.lines.length - 1] += chunkLines[0]; + if (chunkLines.length > 1) { + this.lines.push(...chunkLines.slice(1)); + } + this.emit('line'); + if (callback) callback(); + return true; + } + + wait(): Promise { + if (this.waitingForResponse) { + throw new Error('Currently waiting for response to another command'); + } + this.lines = ['']; + return new Promise((resolve, reject) => { + const onError = (err: any) => { + this.removeListener('line', onLine); + reject(err); + }; + const onLine = () => { + if (this.lines[this.lines.length - 1].includes('> ')) { + this.removeListener('error', onError); + this.removeListener('line', onLine); + resolve(this.lines); + } + }; + this.once('error', onError); + this.on('line', onLine); + }); + } +} diff --git a/src/test/testlib.ts b/src/test/testlib.ts new file mode 100644 index 000000000..d48af9ddb --- /dev/null +++ b/src/test/testlib.ts @@ -0,0 +1,240 @@ +/* + * Extensions to ava, for declaring and running test cases and suites + * Utilities specific to testing ts-node, for example handling streams and exec-ing processes, + * should go in a separate module. + */ + +import avaTest, { + ExecutionContext, + Implementation, + OneOrMoreMacros, +} from 'ava'; +import * as assert from 'assert'; +import throat from 'throat'; + +const concurrencyLimiter = throat(8); + +function once(func: T): T { + let run = false; + let ret: any = undefined; + return (function (...args: any[]) { + if (run) return ret; + run = true; + ret = func(...args); + return ret; + } as any) as T; +} + +export const test = createTestInterface({ + beforeEachFunctions: [], + mustDoSerial: false, + automaticallyDoSerial: false, + separator: ' > ', + titlePrefix: undefined, +}); +export interface TestInterface< + Context +> /*extends Omit, 'before' | 'beforeEach' | 'after' | 'afterEach' | 'failing' | 'serial'>*/ { + //#region copy-pasted from ava's .d.ts + /** Declare a concurrent test. */ + (title: string, implementation: Implementation): void; + /** Declare a concurrent test that uses one or more macros. Additional arguments are passed to the macro. */ + ( + title: string, + macros: OneOrMoreMacros, + ...rest: T + ): void; + /** Declare a concurrent test that uses one or more macros. The macro is responsible for generating a unique test title. */ + (macros: OneOrMoreMacros, ...rest: T): void; + //#endregion + + serial(title: string, implementation: Implementation): void; + /** Declare a concurrent test that uses one or more macros. Additional arguments are passed to the macro. */ + serial( + title: string, + macros: OneOrMoreMacros, + ...rest: T + ): void; + /** Declare a concurrent test that uses one or more macros. The macro is responsible for generating a unique test title. */ + serial( + macros: OneOrMoreMacros, + ...rest: T + ): void; + + macro( + cb: ( + ...args: Args + ) => + | [ + (title: string | undefined) => string | undefined, + (t: ExecutionContext) => Promise + ] + | ((t: ExecutionContext) => Promise) + ): ( + test: ExecutionContext, + ...args: Args + ) => Promise & { + title(givenTitle: string | undefined, ...args: Args): string; + }; + + beforeAll(cb: (t: ExecutionContext) => Promise): void; + beforeEach(cb: (t: ExecutionContext) => Promise): void; + context( + cb: (t: ExecutionContext) => Promise + ): TestInterface; + suite(title: string, cb: (test: TestInterface) => void): void; + + runSerially(): void; + + // TODO add teardownEach +} +function createTestInterface(opts: { + titlePrefix: string | undefined; + separator: string | undefined; + mustDoSerial: boolean; + automaticallyDoSerial: boolean; + beforeEachFunctions: Function[]; +}): TestInterface { + const { titlePrefix, separator = ' > ' } = opts; + const beforeEachFunctions = [...(opts.beforeEachFunctions ?? [])]; + let { mustDoSerial, automaticallyDoSerial } = opts; + let hookDeclared = false; + let suiteOrTestDeclared = false; + function computeTitle(title: string | undefined) { + assert(title); + // return `${ titlePrefix }${ separator }${ title }`; + if (titlePrefix != null && title != null) { + return `${titlePrefix}${separator}${title}`; + } + if (titlePrefix == null && title != null) { + return title; + } + } + function parseArgs(args: any[]) { + const title = + typeof args[0] === 'string' ? (args.shift() as string) : undefined; + const macros = + typeof args[0] === 'function' + ? [args.shift() as Function] + : Array.isArray(args[0]) + ? (args.shift() as Function[]) + : []; + return { title, macros, args }; + } + function assertOrderingForDeclaringTest() { + suiteOrTestDeclared = true; + } + function assertOrderingForDeclaringHook() { + if (suiteOrTestDeclared) { + throw new Error( + 'Hooks must be declared before declaring sub-suites or tests' + ); + } + hookDeclared = true; + } + /** + * @param avaDeclareFunction either test or test.serial + */ + function declareTest( + title: string | undefined, + macros: Function[], + avaDeclareFunction: Function, + args: any[] + ) { + const wrappedMacros = macros.map((macro) => { + return async function (t: ExecutionContext, ...args: any[]) { + return concurrencyLimiter(async () => { + let i = 0; + for (const func of beforeEachFunctions) { + await func(t); + i++; + } + return macro(t, ...args); + }); + }; + }); + const computedTitle = computeTitle(title); + avaDeclareFunction(computedTitle, wrappedMacros, ...args); + } + function test(...inputArgs: any[]) { + assertOrderingForDeclaringTest(); + // TODO is this safe to disable? + // X parallel tests will each invoke the beforeAll hook, but once()ification means each invocation will return the same promise, and tests cannot + // start till it finishes. + // HOWEVER if it returns a single shared state, can tests concurrently use this shared state? + // if(!automaticallyDoSerial && mustDoSerial) throw new Error('Cannot declare non-serial tests because you have declared a beforeAll() hook for this test suite.'); + const { args, macros, title } = parseArgs(inputArgs); + return declareTest( + title, + macros, + automaticallyDoSerial ? avaTest.serial : avaTest, + args + ); + } + test.serial = function (...inputArgs: any[]) { + assertOrderingForDeclaringTest(); + const { args, macros, title } = parseArgs(inputArgs); + return declareTest(title, macros, avaTest.serial, args); + }; + test.beforeEach = function ( + cb: (test: ExecutionContext) => Promise + ) { + assertOrderingForDeclaringHook(); + beforeEachFunctions.push(cb); + }; + test.context = function ( + cb: (test: ExecutionContext) => Promise + ) { + assertOrderingForDeclaringHook(); + beforeEachFunctions.push(async (t: ExecutionContext) => { + const addedContextFields = await cb(t); + Object.assign(t.context, addedContextFields); + }); + return test; + }; + test.beforeAll = function ( + cb: (test: ExecutionContext) => Promise + ) { + assertOrderingForDeclaringHook(); + mustDoSerial = true; + beforeEachFunctions.push(once(cb)); + }; + test.macro = function ( + cb: ( + ...args: Args + ) => + | [ + (title: string | undefined) => string, + (t: ExecutionContext) => Promise + ] + | ((t: ExecutionContext) => Promise) + ) { + function macro(testInterface: ExecutionContext, ...args: Args) { + const ret = cb(...args); + const macroFunction = Array.isArray(ret) ? ret[1] : ret; + return macroFunction(testInterface); + } + macro.title = function (givenTitle: string | undefined, ...args: Args) { + const ret = cb(...args); + return Array.isArray(ret) ? ret[0](givenTitle) : givenTitle; + }; + return macro; + }; + test.suite = function ( + title: string, + cb: (test: TestInterface) => void + ) { + const newApi = createTestInterface({ + mustDoSerial, + automaticallyDoSerial, + separator, + titlePrefix: computeTitle(title), + beforeEachFunctions, + }); + cb(newApi); + }; + test.runSerially = function () { + automaticallyDoSerial = true; + }; + return test as any; +} diff --git a/src/transpilers/swc.ts b/src/transpilers/swc.ts new file mode 100644 index 000000000..9b7361a08 --- /dev/null +++ b/src/transpilers/swc.ts @@ -0,0 +1,142 @@ +import type * as ts from 'typescript'; +import type * as swcWasm from '@swc/wasm'; +import type * as swcTypes from '@swc/core'; +import type { CreateTranspilerOptions, Transpiler } from './types'; + +export interface SwcTranspilerOptions extends CreateTranspilerOptions { + /** + * swc compiler to use for compilation + * Set to '@swc/wasm' to use swc's WASM compiler + * Default: '@swc/core', falling back to '@swc/wasm' + */ + swc?: string | typeof swcWasm; +} + +export function create(createOptions: SwcTranspilerOptions): Transpiler { + const { + swc, + service: { config }, + } = createOptions; + + // Load swc compiler + let swcInstance: typeof swcWasm; + if (typeof swc === 'string') { + swcInstance = require(swc) as typeof swcWasm; + } else if (swc == null) { + let swcResolved; + try { + swcResolved = require.resolve('@swc/core'); + } catch (e) { + try { + swcResolved = require.resolve('@swc/wasm'); + } catch (e) { + throw new Error( + 'swc compiler requires either @swc/core or @swc/wasm to be installed as dependencies' + ); + } + } + swcInstance = require(swcResolved) as typeof swcWasm; + } else { + swcInstance = swc; + } + + // Prepare SWC options derived from typescript compiler options + const compilerOptions = config.options; + const { + esModuleInterop, + sourceMap, + importHelpers, + experimentalDecorators, + emitDecoratorMetadata, + target, + module, + jsxFactory, + jsxFragmentFactory, + } = compilerOptions; + const nonTsxOptions = createSwcOptions(false); + const tsxOptions = createSwcOptions(true); + function createSwcOptions(isTsx: boolean): swcTypes.Options { + const swcTarget = targetMapping.get(target!) ?? 'es3'; + const keepClassNames = target! >= /* ts.ScriptTarget.ES2016 */ 3; + const moduleType = + module === ModuleKind.CommonJS + ? 'commonjs' + : module === ModuleKind.AMD + ? 'amd' + : module === ModuleKind.UMD + ? 'umd' + : undefined; + return { + sourceMaps: sourceMap, + // isModule: true, + module: moduleType + ? ({ + noInterop: !esModuleInterop, + type: moduleType, + } as swcTypes.ModuleConfig) + : undefined, + swcrc: false, + jsc: { + externalHelpers: importHelpers, + parser: { + syntax: 'typescript', + tsx: isTsx, + decorators: experimentalDecorators, + dynamicImport: true, + }, + target: swcTarget, + transform: { + decoratorMetadata: emitDecoratorMetadata, + legacyDecorator: true, + react: { + throwIfNamespace: false, + development: false, + useBuiltins: false, + pragma: jsxFactory!, + pragmaFrag: jsxFragmentFactory!, + } as swcTypes.ReactConfig, + }, + keepClassNames, + } as swcTypes.JscConfig, + }; + } + + const transpile: Transpiler['transpile'] = (input, transpileOptions) => { + const { fileName } = transpileOptions; + const swcOptions = + fileName.endsWith('.tsx') || fileName.endsWith('.jsx') + ? tsxOptions + : nonTsxOptions; + const { code, map } = swcInstance.transformSync(input, { + ...swcOptions, + filename: fileName, + }); + return { outputText: code, sourceMapText: map }; + }; + + return { + transpile, + }; +} + +const targetMapping = new Map(); +targetMapping.set(/* ts.ScriptTarget.ES3 */ 0, 'es3'); +targetMapping.set(/* ts.ScriptTarget.ES5 */ 1, 'es5'); +targetMapping.set(/* ts.ScriptTarget.ES2015 */ 2, 'es2015'); +targetMapping.set(/* ts.ScriptTarget.ES2016 */ 3, 'es2016'); +targetMapping.set(/* ts.ScriptTarget.ES2017 */ 4, 'es2017'); +targetMapping.set(/* ts.ScriptTarget.ES2018 */ 5, 'es2018'); +targetMapping.set(/* ts.ScriptTarget.ES2019 */ 6, 'es2019'); +targetMapping.set(/* ts.ScriptTarget.ES2020 */ 7, 'es2019'); +targetMapping.set(/* ts.ScriptTarget.ESNext */ 99, 'es2019'); + +const ModuleKind = { + None: 0, + CommonJS: 1, + AMD: 2, + UMD: 3, + System: 4, + ES2015: 5, + ES2020: 6, + ESNext: 99, +} as const; diff --git a/src/transpilers/types.ts b/src/transpilers/types.ts new file mode 100644 index 000000000..3c1e7afc3 --- /dev/null +++ b/src/transpilers/types.ts @@ -0,0 +1,34 @@ +import type * as ts from 'typescript'; +import type { Service } from '../index'; + +/** + * Third-party transpilers are implemented as a CommonJS module with a + * named export "create" + */ +export interface TranspilerModule { + create: TranspilerFactory; +} +/** + * Called by ts-node to create a custom transpiler. + */ +export type TranspilerFactory = ( + options: CreateTranspilerOptions +) => Transpiler; +export interface CreateTranspilerOptions { + // TODO this is confusing because its only a partial Service. Rename? + service: Pick; +} +export interface Transpiler { + // TODOs + // Create spec for returning diagnostics? Currently transpilers are allowed to + // throw an error but that's it. + transpile(input: string, options: TranspileOptions): TranspileOutput; +} +export interface TranspileOptions { + fileName: string; +} +export interface TranspileOutput { + outputText: string; + diagnostics?: ts.Diagnostic[]; + sourceMapText?: string; +} diff --git a/src/ts-compiler-types.ts b/src/ts-compiler-types.ts new file mode 100644 index 000000000..b17111c3a --- /dev/null +++ b/src/ts-compiler-types.ts @@ -0,0 +1,82 @@ +import type * as _ts from 'typescript'; + +/** + * Common TypeScript interfaces between versions. + */ +export interface TSCommon { + version: typeof _ts.version; + sys: typeof _ts.sys; + ScriptSnapshot: typeof _ts.ScriptSnapshot; + displayPartsToString: typeof _ts.displayPartsToString; + createLanguageService: typeof _ts.createLanguageService; + getDefaultLibFilePath: typeof _ts.getDefaultLibFilePath; + getPreEmitDiagnostics: typeof _ts.getPreEmitDiagnostics; + flattenDiagnosticMessageText: typeof _ts.flattenDiagnosticMessageText; + transpileModule: typeof _ts.transpileModule; + ModuleKind: typeof _ts.ModuleKind; + ScriptTarget: typeof _ts.ScriptTarget; + findConfigFile: typeof _ts.findConfigFile; + readConfigFile: typeof _ts.readConfigFile; + parseJsonConfigFileContent: typeof _ts.parseJsonConfigFileContent; + formatDiagnostics: typeof _ts.formatDiagnostics; + formatDiagnosticsWithColorAndContext: typeof _ts.formatDiagnosticsWithColorAndContext; + + createDocumentRegistry: typeof _ts.createDocumentRegistry; + JsxEmit: typeof _ts.JsxEmit; + createModuleResolutionCache: typeof _ts.createModuleResolutionCache; + resolveModuleName: typeof _ts.resolveModuleName; + resolveModuleNameFromCache: typeof _ts.resolveModuleNameFromCache; + resolveTypeReferenceDirective: typeof _ts.resolveTypeReferenceDirective; + createIncrementalCompilerHost: typeof _ts.createIncrementalCompilerHost; + createSourceFile: typeof _ts.createSourceFile; + getDefaultLibFileName: typeof _ts.getDefaultLibFileName; + createIncrementalProgram: typeof _ts.createIncrementalProgram; + createEmitAndSemanticDiagnosticsBuilderProgram: typeof _ts.createEmitAndSemanticDiagnosticsBuilderProgram; + + Extension: typeof _ts.Extension; + ModuleResolutionKind: typeof _ts.ModuleResolutionKind; +} + +/** + * Compiler APIs we use that are marked internal and not included in TypeScript's public API declarations + * @internal + */ +export interface TSInternal { + // https://github.com/microsoft/TypeScript/blob/4a34294908bed6701dcba2456ca7ac5eafe0ddff/src/compiler/core.ts#L1906-L1909 + createGetCanonicalFileName( + useCaseSensitiveFileNames: boolean + ): TSInternal.GetCanonicalFileName; + // https://github.com/microsoft/TypeScript/blob/c117c266e09c80e8a06b24a6e94b9d018f5fae6b/src/compiler/commandLineParser.ts#L2054 + convertToTSConfig( + configParseResult: _ts.ParsedCommandLine, + configFileName: string, + host: TSInternal.ConvertToTSConfigHost + ): any; + libs?: string[]; + Diagnostics: { + File_0_not_found: _ts.DiagnosticMessage; + }; + createCompilerDiagnostic( + message: _ts.DiagnosticMessage, + ...args: (string | number | undefined)[] + ): _ts.Diagnostic; + nodeModuleNameResolver( + moduleName: string, + containingFile: string, + compilerOptions: _ts.CompilerOptions, + host: _ts.ModuleResolutionHost, + cache?: _ts.ModuleResolutionCache, + redirectedReference?: _ts.ResolvedProjectReference, + lookupConfig?: boolean + ): _ts.ResolvedModuleWithFailedLookupLocations; +} +/** @internal */ +export namespace TSInternal { + // https://github.com/microsoft/TypeScript/blob/4a34294908bed6701dcba2456ca7ac5eafe0ddff/src/compiler/core.ts#L1906 + export type GetCanonicalFileName = (fileName: string) => string; + // https://github.com/microsoft/TypeScript/blob/c117c266e09c80e8a06b24a6e94b9d018f5fae6b/src/compiler/commandLineParser.ts#L2041 + export interface ConvertToTSConfigHost { + getCurrentDirectory(): string; + useCaseSensitiveFileNames: boolean; + } +} diff --git a/src/ts-internals.ts b/src/ts-internals.ts new file mode 100644 index 000000000..e438c812c --- /dev/null +++ b/src/ts-internals.ts @@ -0,0 +1,399 @@ +import { isAbsolute, resolve } from 'path'; +import { cachedLookup, normalizeSlashes } from './util'; +import type * as _ts from 'typescript'; +import type { TSCommon, TSInternal } from './ts-compiler-types'; + +/** @internal */ +export const createTsInternals = cachedLookup(createTsInternalsUncached); +/** + * Given a reference to the TS compiler, return some TS internal functions that we + * could not or did not want to grab off the `ts` object. + * These have been copy-pasted from TS's source and tweaked as necessary. + * + * NOTE: This factory returns *only* functions which need a reference to the TS + * compiler. Other functions do not need a reference to the TS compiler so are + * exported directly from this file. + */ +function createTsInternalsUncached(_ts: TSCommon) { + const ts = _ts as TSCommon & TSInternal; + /** + * Copied from: + * https://github.com/microsoft/TypeScript/blob/v4.3.2/src/compiler/commandLineParser.ts#L2821-L2846 + */ + function getExtendsConfigPath( + extendedConfig: string, + host: _ts.ParseConfigHost, + basePath: string, + errors: _ts.Push<_ts.Diagnostic>, + createDiagnostic: ( + message: _ts.DiagnosticMessage, + arg1?: string + ) => _ts.Diagnostic + ) { + extendedConfig = normalizeSlashes(extendedConfig); + if ( + isRootedDiskPath(extendedConfig) || + startsWith(extendedConfig, './') || + startsWith(extendedConfig, '../') + ) { + let extendedConfigPath = getNormalizedAbsolutePath( + extendedConfig, + basePath + ); + if ( + !host.fileExists(extendedConfigPath) && + !endsWith(extendedConfigPath, ts.Extension.Json) + ) { + extendedConfigPath = `${extendedConfigPath}.json`; + if (!host.fileExists(extendedConfigPath)) { + errors.push( + createDiagnostic(ts.Diagnostics.File_0_not_found, extendedConfig) + ); + return undefined; + } + } + return extendedConfigPath; + } + // If the path isn't a rooted or relative path, resolve like a module + const resolved = ts.nodeModuleNameResolver( + extendedConfig, + combinePaths(basePath, 'tsconfig.json'), + { moduleResolution: ts.ModuleResolutionKind.NodeJs }, + host, + /*cache*/ undefined, + /*projectRefs*/ undefined, + /*lookupConfig*/ true + ); + if (resolved.resolvedModule) { + return resolved.resolvedModule.resolvedFileName; + } + errors.push( + createDiagnostic(ts.Diagnostics.File_0_not_found, extendedConfig) + ); + return undefined; + } + + return { getExtendsConfigPath }; +} + +// These functions have alternative implementation to avoid copying too much from TS +function isRootedDiskPath(path: string) { + return isAbsolute(path); +} +function combinePaths(path: string, ...paths: (string | undefined)[]): string { + return normalizeSlashes( + resolve(path, ...(paths.filter((path) => path) as string[])) + ); +} +function getNormalizedAbsolutePath( + fileName: string, + currentDirectory: string | undefined +) { + return normalizeSlashes( + currentDirectory != null + ? resolve(currentDirectory!, fileName) + : resolve(fileName) + ); +} + +function startsWith(str: string, prefix: string): boolean { + return str.lastIndexOf(prefix, 0) === 0; +} + +function endsWith(str: string, suffix: string): boolean { + const expectedPos = str.length - suffix.length; + return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos; +} +// Reserved characters, forces escaping of any non-word (or digit), non-whitespace character. +// It may be inefficient (we could just match (/[-[\]{}()*+?.,\\^$|#\s]/g), but this is future +// proof. +const reservedCharacterPattern = /[^\w\s\/]/g; + +/** + * @internal + * See also: getRegularExpressionForWildcard, which seems to do almost the same thing + */ +export function getPatternFromSpec(spec: string, basePath: string) { + const pattern = spec && getSubPatternFromSpec(spec, basePath, excludeMatcher); + return pattern && `^(${pattern})${'($|/)'}`; +} +function getSubPatternFromSpec( + spec: string, + basePath: string, + { + singleAsteriskRegexFragment, + doubleAsteriskRegexFragment, + replaceWildcardCharacter, + }: WildcardMatcher +): string { + let subpattern = ''; + let hasWrittenComponent = false; + const components = getNormalizedPathComponents(spec, basePath); + const lastComponent = last(components); + + // getNormalizedPathComponents includes the separator for the root component. + // We need to remove to create our regex correctly. + components[0] = removeTrailingDirectorySeparator(components[0]); + + if (isImplicitGlob(lastComponent)) { + components.push('**', '*'); + } + + let optionalCount = 0; + for (let component of components) { + if (component === '**') { + subpattern += doubleAsteriskRegexFragment; + } else { + if (hasWrittenComponent) { + subpattern += directorySeparator; + } + subpattern += component.replace( + reservedCharacterPattern, + replaceWildcardCharacter + ); + } + + hasWrittenComponent = true; + } + + while (optionalCount > 0) { + subpattern += ')?'; + optionalCount--; + } + + return subpattern; +} +interface WildcardMatcher { + singleAsteriskRegexFragment: string; + doubleAsteriskRegexFragment: string; + replaceWildcardCharacter: (match: string) => string; +} +const directoriesMatcher: WildcardMatcher = { + singleAsteriskRegexFragment: '[^/]*', + /** + * Regex for the ** wildcard. Matches any num of subdirectories. When used for including + * files or directories, does not match subdirectories that start with a . character + */ + doubleAsteriskRegexFragment: `(/[^/.][^/]*)*?`, + replaceWildcardCharacter: (match) => + replaceWildcardCharacter( + match, + directoriesMatcher.singleAsteriskRegexFragment + ), +}; +const excludeMatcher: WildcardMatcher = { + singleAsteriskRegexFragment: '[^/]*', + doubleAsteriskRegexFragment: '(/.+?)?', + replaceWildcardCharacter: (match) => + replaceWildcardCharacter(match, excludeMatcher.singleAsteriskRegexFragment), +}; +function getNormalizedPathComponents( + path: string, + currentDirectory: string | undefined +) { + return reducePathComponents(getPathComponents(path, currentDirectory)); +} +function getPathComponents(path: string, currentDirectory = '') { + path = combinePaths(currentDirectory, path); + return pathComponents(path, getRootLength(path)); +} +function reducePathComponents(components: readonly string[]) { + if (!some(components)) return []; + const reduced = [components[0]]; + for (let i = 1; i < components.length; i++) { + const component = components[i]; + if (!component) continue; + if (component === '.') continue; + if (component === '..') { + if (reduced.length > 1) { + if (reduced[reduced.length - 1] !== '..') { + reduced.pop(); + continue; + } + } else if (reduced[0]) continue; + } + reduced.push(component); + } + return reduced; +} +function getRootLength(path: string) { + const rootLength = getEncodedRootLength(path); + return rootLength < 0 ? ~rootLength : rootLength; +} +function getEncodedRootLength(path: string): number { + if (!path) return 0; + const ch0 = path.charCodeAt(0); + + // POSIX or UNC + if (ch0 === CharacterCodes.slash || ch0 === CharacterCodes.backslash) { + if (path.charCodeAt(1) !== ch0) return 1; // POSIX: "/" (or non-normalized "\") + + const p1 = path.indexOf( + ch0 === CharacterCodes.slash ? directorySeparator : altDirectorySeparator, + 2 + ); + if (p1 < 0) return path.length; // UNC: "//server" or "\\server" + + return p1 + 1; // UNC: "//server/" or "\\server\" + } + + // DOS + if (isVolumeCharacter(ch0) && path.charCodeAt(1) === CharacterCodes.colon) { + const ch2 = path.charCodeAt(2); + if (ch2 === CharacterCodes.slash || ch2 === CharacterCodes.backslash) + return 3; // DOS: "c:/" or "c:\" + if (path.length === 2) return 2; // DOS: "c:" (but not "c:d") + } + + // URL + const schemeEnd = path.indexOf(urlSchemeSeparator); + if (schemeEnd !== -1) { + const authorityStart = schemeEnd + urlSchemeSeparator.length; + const authorityEnd = path.indexOf(directorySeparator, authorityStart); + if (authorityEnd !== -1) { + // URL: "file:///", "file://server/", "file://server/path" + // For local "file" URLs, include the leading DOS volume (if present). + // Per https://www.ietf.org/rfc/rfc1738.txt, a host of "" or "localhost" is a + // special case interpreted as "the machine from which the URL is being interpreted". + const scheme = path.slice(0, schemeEnd); + const authority = path.slice(authorityStart, authorityEnd); + if ( + scheme === 'file' && + (authority === '' || authority === 'localhost') && + isVolumeCharacter(path.charCodeAt(authorityEnd + 1)) + ) { + const volumeSeparatorEnd = getFileUrlVolumeSeparatorEnd( + path, + authorityEnd + 2 + ); + if (volumeSeparatorEnd !== -1) { + if (path.charCodeAt(volumeSeparatorEnd) === CharacterCodes.slash) { + // URL: "file:///c:/", "file://localhost/c:/", "file:///c%3a/", "file://localhost/c%3a/" + return ~(volumeSeparatorEnd + 1); + } + if (volumeSeparatorEnd === path.length) { + // URL: "file:///c:", "file://localhost/c:", "file:///c$3a", "file://localhost/c%3a" + // but not "file:///c:d" or "file:///c%3ad" + return ~volumeSeparatorEnd; + } + } + } + return ~(authorityEnd + 1); // URL: "file://server/", "http://server/" + } + return ~path.length; // URL: "file://server", "http://server" + } + + // relative + return 0; +} +function ensureTrailingDirectorySeparator(path: string) { + if (!hasTrailingDirectorySeparator(path)) { + return path + directorySeparator; + } + + return path; +} +function hasTrailingDirectorySeparator(path: string) { + return ( + path.length > 0 && isAnyDirectorySeparator(path.charCodeAt(path.length - 1)) + ); +} +function isAnyDirectorySeparator(charCode: number): boolean { + return ( + charCode === CharacterCodes.slash || charCode === CharacterCodes.backslash + ); +} +function removeTrailingDirectorySeparator(path: string) { + if (hasTrailingDirectorySeparator(path)) { + return path.substr(0, path.length - 1); + } + + return path; +} +const directorySeparator = '/'; +const altDirectorySeparator = '\\'; +const urlSchemeSeparator = '://'; +function isVolumeCharacter(charCode: number) { + return ( + (charCode >= CharacterCodes.a && charCode <= CharacterCodes.z) || + (charCode >= CharacterCodes.A && charCode <= CharacterCodes.Z) + ); +} +function getFileUrlVolumeSeparatorEnd(url: string, start: number) { + const ch0 = url.charCodeAt(start); + if (ch0 === CharacterCodes.colon) return start + 1; + if ( + ch0 === CharacterCodes.percent && + url.charCodeAt(start + 1) === CharacterCodes._3 + ) { + const ch2 = url.charCodeAt(start + 2); + if (ch2 === CharacterCodes.a || ch2 === CharacterCodes.A) return start + 3; + } + return -1; +} +function some(array: readonly T[] | undefined): array is readonly T[]; +function some( + array: readonly T[] | undefined, + predicate: (value: T) => boolean +): boolean; +function some( + array: readonly T[] | undefined, + predicate?: (value: T) => boolean +): boolean { + if (array) { + if (predicate) { + for (const v of array) { + if (predicate(v)) { + return true; + } + } + } else { + return array.length > 0; + } + } + return false; +} +/* @internal */ +const enum CharacterCodes { + _3 = 0x33, + a = 0x61, + z = 0x7a, + A = 0x41, + Z = 0x5a, + asterisk = 0x2a, // * + backslash = 0x5c, // \ + colon = 0x3a, // : + percent = 0x25, // % + question = 0x3f, // ? + slash = 0x2f, // / +} +function pathComponents(path: string, rootLength: number) { + const root = path.substring(0, rootLength); + const rest = path.substring(rootLength).split(directorySeparator); + if (rest.length && !lastOrUndefined(rest)) rest.pop(); + return [root, ...rest]; +} +function lastOrUndefined(array: readonly T[]): T | undefined { + return array.length === 0 ? undefined : array[array.length - 1]; +} +function last(array: readonly T[]): T { + // Debug.assert(array.length !== 0); + return array[array.length - 1]; +} +function replaceWildcardCharacter( + match: string, + singleAsteriskRegexFragment: string +) { + return match === '*' + ? singleAsteriskRegexFragment + : match === '?' + ? '[^/]' + : '\\' + match; +} +/** + * An "includes" path "foo" is implicitly a glob "foo/** /*" (without the space) if its last component has no extension, + * and does not contain any glob characters itself. + */ +function isImplicitGlob(lastPathComponent: string): boolean { + return !/[.*?]/.test(lastPathComponent); +} diff --git a/src/tsconfig-schema.ts b/src/tsconfig-schema.ts index d25b3025b..f20818e5a 100644 --- a/src/tsconfig-schema.ts +++ b/src/tsconfig-schema.ts @@ -1,4 +1,4 @@ -import { TsConfigOptions } from '.' +import type { TsConfigOptions } from './index'; /* * This interface exists solely for generating a JSON schema for tsconfig.json. @@ -12,9 +12,9 @@ import { TsConfigOptions } from '.' */ export interface TsConfigSchema { /** - * ts-node options. See also: https://github.com/TypeStrong/ts-node#configuration-options + * ts-node options. See also: https://typestrong.org/ts-node/docs/configuration * * ts-node offers TypeScript execution and REPL for node.js, with source map support. */ - 'ts-node': TsConfigOptions + 'ts-node': TsConfigOptions; } diff --git a/src/tsconfigs.ts b/src/tsconfigs.ts new file mode 100644 index 000000000..74a927449 --- /dev/null +++ b/src/tsconfigs.ts @@ -0,0 +1,40 @@ +import type { TSCommon, TSInternal } from './ts-compiler-types'; + +const nodeMajor = parseInt(process.versions.node.split('.')[0], 10); +/** + * return parsed JSON of the bundled @tsconfig/bases config appropriate for the + * running version of nodejs + * @internal + */ +export function getDefaultTsconfigJsonForNodeVersion(ts: TSCommon): any { + const tsInternal = (ts as any) as TSInternal; + if (nodeMajor >= 16) { + const config = require('@tsconfig/node16/tsconfig.json'); + if (configCompatible(config)) return config; + } + if (nodeMajor >= 14) { + const config = require('@tsconfig/node14/tsconfig.json'); + if (configCompatible(config)) return config; + } + if (nodeMajor >= 12) { + const config = require('@tsconfig/node12/tsconfig.json'); + if (configCompatible(config)) return config; + } + return require('@tsconfig/node10/tsconfig.json'); + + // Verify that tsconfig target and lib options are compatible with TypeScript compiler + function configCompatible(config: { + compilerOptions: { + lib: string[]; + target: string; + }; + }) { + return ( + typeof (ts.ScriptTarget as any)[ + config.compilerOptions.target.toUpperCase() + ] === 'number' && + tsInternal.libs && + config.compilerOptions.lib.every((lib) => tsInternal.libs!.includes(lib)) + ); + } +} diff --git a/src/util.ts b/src/util.ts new file mode 100644 index 000000000..9ea98a66d --- /dev/null +++ b/src/util.ts @@ -0,0 +1,95 @@ +import { + createRequire as nodeCreateRequire, + createRequireFromPath as nodeCreateRequireFromPath, +} from 'module'; +import type _createRequire from 'create-require'; +import * as ynModule from 'yn'; + +/** @internal */ +export const createRequire = + nodeCreateRequire ?? + nodeCreateRequireFromPath ?? + (require('create-require') as typeof _createRequire); + +/** + * Wrapper around yn module that returns `undefined` instead of `null`. + * This is implemented by yn v4, but we're staying on v3 to avoid v4's node 10 requirement. + * @internal + */ +export function yn(value: string | undefined) { + return ynModule(value) ?? undefined; +} + +/** + * Like `Object.assign`, but ignores `undefined` properties. + * + * @internal + */ +export function assign( + initialValue: T, + ...sources: Array +): T { + for (const source of sources) { + for (const key of Object.keys(source)) { + const value = (source as any)[key]; + if (value !== undefined) (initialValue as any)[key] = value; + } + } + return initialValue; +} + +/** + * Split a string array of values. + * @internal + */ +export function split(value: string | undefined) { + return typeof value === 'string' ? value.split(/ *, */g) : undefined; +} + +/** + * Parse a string as JSON. + * @internal + */ +export function parse(value: string | undefined): object | undefined { + return typeof value === 'string' ? JSON.parse(value) : undefined; +} + +const directorySeparator = '/'; +const backslashRegExp = /\\/g; +/** + * Replace backslashes with forward slashes. + * @internal + */ +export function normalizeSlashes(value: string): string { + return value.replace(backslashRegExp, directorySeparator); +} + +/** + * Safe `hasOwnProperty` + * @internal + */ +export function hasOwnProperty(object: any, property: string): boolean { + return Object.prototype.hasOwnProperty.call(object, property); +} + +/** + * Cached fs operation wrapper. + */ +export function cachedLookup(fn: (arg: T) => R): (arg: T) => R { + const cache = new Map(); + + return (arg: T): R => { + if (!cache.has(arg)) { + const v = fn(arg); + cache.set(arg, v); + return v; + } + return cache.get(arg)!; + }; +} + +/** + * We do not support ts's `trace` option yet. In the meantime, rather than omit + * `trace` options in hosts, I am using this placeholder. + */ +export function trace(s: string): void {} diff --git a/tests/allow-js/run.js b/tests/allow-js/run.js index dd3f91cd0..9001625ad 100644 --- a/tests/allow-js/run.js +++ b/tests/allow-js/run.js @@ -1,3 +1,3 @@ -export function main () { - return 'hello world' +export function main() { + return 'hello world'; } diff --git a/tests/allow-js/with-jsx.jsx b/tests/allow-js/with-jsx.jsx index d182b4b5d..a48e85a92 100644 --- a/tests/allow-js/with-jsx.jsx +++ b/tests/allow-js/with-jsx.jsx @@ -1,11 +1,9 @@ export class Foo2 { - - static sayHi () { - return 'hello world' + static sayHi() { + return 'hello world'; } - render () { - return
+ render() { + return
; } - } diff --git a/tests/child-process.ts b/tests/child-process.ts index 05050fec5..c0e9d4b94 100644 --- a/tests/child-process.ts +++ b/tests/child-process.ts @@ -1,4 +1,4 @@ -import { join } from 'path' -import { fork } from 'child_process' +import { join } from 'path'; +import { fork } from 'child_process'; -fork(join(__dirname, 'hello-world.ts')) +fork(join(__dirname, 'hello-world.ts')); diff --git a/tests/compiler-error.ts b/tests/compiler-error.ts index 05800dd5b..ced966e24 100644 --- a/tests/compiler-error.ts +++ b/tests/compiler-error.ts @@ -1,5 +1,5 @@ -function upper (str: string) { - return str.toUpperCase() +function upper(str: string) { + return str.toUpperCase(); } -upper(10) +upper(10); diff --git a/tests/complex/example.js b/tests/complex/example.js index 3971310d0..466e7df08 100644 --- a/tests/complex/example.js +++ b/tests/complex/example.js @@ -1 +1 @@ -module.exports = require('./foo').text +module.exports = require('./foo').text; diff --git a/tests/complex/foo.ts b/tests/complex/foo.ts index 93fb156db..bafb472a7 100644 --- a/tests/complex/foo.ts +++ b/tests/complex/foo.ts @@ -1 +1 @@ -export const text = 'example' +export const text = 'example'; diff --git a/tests/complex/index.ts b/tests/complex/index.ts index e87008576..7ac5a99d2 100644 --- a/tests/complex/index.ts +++ b/tests/complex/index.ts @@ -1,5 +1,5 @@ -declare function require (module: string): any +declare function require(module: string): any; -export function example () { - return require('./example') +export function example() { + return require('./example'); } diff --git a/tests/custom-types.ts b/tests/custom-types.ts index dc3da6ebe..fcd1fbdef 100644 --- a/tests/custom-types.ts +++ b/tests/custom-types.ts @@ -1,3 +1,3 @@ -import { foobar } from 'does-not-exist' +import { foobar } from 'does-not-exist'; -console.log(foobar) +console.log(foobar); diff --git a/tests/cwd-and-script-mode/a/index.ts b/tests/cwd-and-script-mode/a/index.ts new file mode 100644 index 000000000..230f5ea09 --- /dev/null +++ b/tests/cwd-and-script-mode/a/index.ts @@ -0,0 +1,9 @@ +export {}; +// Type assertion to please TS 2.7 +const register = process[(Symbol as any).for('ts-node.register.instance')]; +console.log( + JSON.stringify({ + options: register.options, + config: register.config, + }) +); diff --git a/tests/cwd-and-script-mode/a/tsconfig.json b/tests/cwd-and-script-mode/a/tsconfig.json new file mode 100644 index 000000000..196e2b444 --- /dev/null +++ b/tests/cwd-and-script-mode/a/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "plugins": [ + { + "name": "plugin-a" + } + ] + } +} diff --git a/tests/cwd-and-script-mode/b/index.ts b/tests/cwd-and-script-mode/b/index.ts new file mode 100644 index 000000000..230f5ea09 --- /dev/null +++ b/tests/cwd-and-script-mode/b/index.ts @@ -0,0 +1,9 @@ +export {}; +// Type assertion to please TS 2.7 +const register = process[(Symbol as any).for('ts-node.register.instance')]; +console.log( + JSON.stringify({ + options: register.options, + config: register.config, + }) +); diff --git a/tests/cwd-and-script-mode/b/tsconfig.json b/tests/cwd-and-script-mode/b/tsconfig.json new file mode 100644 index 000000000..3b22d468d --- /dev/null +++ b/tests/cwd-and-script-mode/b/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "plugins": [ + { + "name": "plugin-b" + } + ] + } +} diff --git a/tests/emit-compiled.ts b/tests/emit-compiled.ts index 7708b8551..0b1738d5e 100644 --- a/tests/emit-compiled.ts +++ b/tests/emit-compiled.ts @@ -1,16 +1,16 @@ -const extensions = ['.tsx'] +const extensions = ['.tsx']; -extensions.forEach(ext => { - const old = require.extensions[ext] +extensions.forEach((ext) => { + const old = require.extensions[ext]; require.extensions[ext] = (m, path) => { - const _compile = (m as any)._compile + const _compile = (m as any)._compile; - ;(m as any)._compile = (code, path) => { - console.error(code) - return _compile.call(this, code, path) - } + (m as any)._compile = (code, path) => { + console.error(code); + return _compile.call(this, code, path); + }; - return old(m, path) - } -}) + return old(m, path); + }; +}); diff --git a/tests/env.ts b/tests/env.ts index 8a3b78aba..94510e045 100644 --- a/tests/env.ts +++ b/tests/env.ts @@ -1 +1 @@ -console.log(typeof process[Symbol.for('ts-node.register.instance')]) +console.log(typeof (process as any)[Symbol.for('ts-node.register.instance')]); diff --git a/tests/esm-err-require-esm/esm-package/loaded-as.ts b/tests/esm-err-require-esm/esm-package/loaded-as.ts index df054c0bc..1e9f32136 100644 --- a/tests/esm-err-require-esm/esm-package/loaded-as.ts +++ b/tests/esm-err-require-esm/esm-package/loaded-as.ts @@ -1,5 +1,3 @@ // Log if this file is loaded as ESM or CommonJS -if(typeof module !== 'undefined') - console.log('CommonJS') -else - console.log('ESM') +if (typeof module !== 'undefined') console.log('CommonJS'); +else console.log('ESM'); diff --git a/tests/esm-err-require-esm/index.js b/tests/esm-err-require-esm/index.js index b2bf5a5fc..902779786 100644 --- a/tests/esm-err-require-esm/index.js +++ b/tests/esm-err-require-esm/index.js @@ -1 +1 @@ -require('./esm-package/loaded-as') +require('./esm-package/loaded-as'); diff --git a/tests/esm-import-cache/index.ts b/tests/esm-import-cache/index.ts new file mode 100644 index 000000000..684e08e60 --- /dev/null +++ b/tests/esm-import-cache/index.ts @@ -0,0 +1,4 @@ +import './log1.js'; +import './log1.js'; +import './log2.js'; +import './log2.js?bust'; diff --git a/tests/esm-import-cache/log1.ts b/tests/esm-import-cache/log1.ts new file mode 100644 index 000000000..886dfba9d --- /dev/null +++ b/tests/esm-import-cache/log1.ts @@ -0,0 +1 @@ +console.log('log1'); diff --git a/tests/esm-import-cache/log2.ts b/tests/esm-import-cache/log2.ts new file mode 100644 index 000000000..f4922a4f6 --- /dev/null +++ b/tests/esm-import-cache/log2.ts @@ -0,0 +1 @@ +console.log('log2'); diff --git a/tests/esm-import-cache/package.json b/tests/esm-import-cache/package.json new file mode 100644 index 000000000..3dbc1ca59 --- /dev/null +++ b/tests/esm-import-cache/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/tests/esm-import-cache/tsconfig.json b/tests/esm-import-cache/tsconfig.json new file mode 100644 index 000000000..c5272e687 --- /dev/null +++ b/tests/esm-import-cache/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "module": "ESNext", + "allowJs": true, + "moduleResolution": "node" + } +} diff --git a/tests/esm-import-http-url/index.mjs b/tests/esm-import-http-url/index.mjs index 35e59a6c6..5342c08ed 100644 --- a/tests/esm-import-http-url/index.mjs +++ b/tests/esm-import-http-url/index.mjs @@ -1 +1 @@ -import 'http://example.com/this-url-should-be-ignored-by-our-esm-loader.js' +import 'http://example.com/this-url-should-be-ignored-by-our-esm-loader.js'; diff --git a/tests/esm-node-resolver/bar/index.ts b/tests/esm-node-resolver/bar/index.ts index 4bfad1a30..4bc22c6f7 100644 --- a/tests/esm-node-resolver/bar/index.ts +++ b/tests/esm-node-resolver/bar/index.ts @@ -1,3 +1,4 @@ -export const bar: string = 'bar' +export const bar: string = 'bar'; -if(typeof module !== 'undefined') throw new Error('module should not exist in ESM') +if (typeof module !== 'undefined') + throw new Error('module should not exist in ESM'); diff --git a/tests/esm-node-resolver/baz.js b/tests/esm-node-resolver/baz.js index 51474b54f..6363a2880 100644 --- a/tests/esm-node-resolver/baz.js +++ b/tests/esm-node-resolver/baz.js @@ -1,3 +1,4 @@ -export const baz = 'baz' +export const baz = 'baz'; -if(typeof module !== 'undefined') throw new Error('module should not exist in ESM') +if (typeof module !== 'undefined') + throw new Error('module should not exist in ESM'); diff --git a/tests/esm-node-resolver/biff.jsx b/tests/esm-node-resolver/biff.jsx index e397d5217..7ac508317 100644 --- a/tests/esm-node-resolver/biff.jsx +++ b/tests/esm-node-resolver/biff.jsx @@ -1,8 +1,9 @@ -export const biff = 'biff' +export const biff = 'biff'; const React = { - createElement() {} -} -const div =
+ createElement() {}, +}; +const div =
; -if(typeof module !== 'undefined') throw new Error('module should not exist in ESM') +if (typeof module !== 'undefined') + throw new Error('module should not exist in ESM'); diff --git a/tests/esm-node-resolver/foo.ts b/tests/esm-node-resolver/foo.ts index 501c0021d..c6b5e44c8 100644 --- a/tests/esm-node-resolver/foo.ts +++ b/tests/esm-node-resolver/foo.ts @@ -1,3 +1,4 @@ -export const foo: string = 'foo' +export const foo: string = 'foo'; -if(typeof module !== 'undefined') throw new Error('module should not exist in ESM') +if (typeof module !== 'undefined') + throw new Error('module should not exist in ESM'); diff --git a/tests/esm-node-resolver/index.ts b/tests/esm-node-resolver/index.ts index 88b9bc868..419f16664 100644 --- a/tests/esm-node-resolver/index.ts +++ b/tests/esm-node-resolver/index.ts @@ -1,8 +1,15 @@ -import {foo} from './foo' -import {bar} from './bar' -import {baz} from './baz' -import {biff} from './biff' +import { foo } from './foo'; +import { bar } from './bar'; +import { baz } from './baz'; +import { biff } from './biff'; +import { libfoo } from 'libfoo'; -if(typeof module !== 'undefined') throw new Error('module should not exist in ESM') +// Test import builtin modules +import { readFileSync } from 'fs'; +if (typeof readFileSync !== 'function') + throw new Error('failed to import builtin module'); -console.log(`${foo} ${bar} ${baz} ${biff}`) +if (typeof module !== 'undefined') + throw new Error('module should not exist in ESM'); + +console.log(`${foo} ${bar} ${baz} ${biff} ${libfoo}`); diff --git a/tests/esm-node-resolver/node_modules/libfoo/entrypoint.js b/tests/esm-node-resolver/node_modules/libfoo/entrypoint.js new file mode 100644 index 000000000..97ec5ba03 --- /dev/null +++ b/tests/esm-node-resolver/node_modules/libfoo/entrypoint.js @@ -0,0 +1 @@ +export const libfoo = 'libfoo' diff --git a/tests/esm-node-resolver/node_modules/libfoo/index.d.ts b/tests/esm-node-resolver/node_modules/libfoo/index.d.ts new file mode 100644 index 000000000..dc2a05001 --- /dev/null +++ b/tests/esm-node-resolver/node_modules/libfoo/index.d.ts @@ -0,0 +1,2 @@ +// TypeScript does not yet support package.json "exports" +export const libfoo: string diff --git a/tests/esm-node-resolver/node_modules/libfoo/package.json b/tests/esm-node-resolver/node_modules/libfoo/package.json new file mode 100644 index 000000000..bda92d96b --- /dev/null +++ b/tests/esm-node-resolver/node_modules/libfoo/package.json @@ -0,0 +1,6 @@ +{ + "type": "module", + "exports": { + "import": "./entrypoint.js" + } +} diff --git a/tests/esm-transpile-only/index.ts b/tests/esm-transpile-only/index.ts index e99da7cfd..189ad05ca 100644 --- a/tests/esm-transpile-only/index.ts +++ b/tests/esm-transpile-only/index.ts @@ -1,5 +1,6 @@ -if (typeof module !== 'undefined') throw new Error('module should not exist in ESM') +if (typeof module !== 'undefined') + throw new Error('module should not exist in ESM'); // intentional type errors to check transpile-only ESM loader skips type checking -parseInt(1101, 2) -const x: number = 'hello world' +parseInt(1101, 2); +const x: number = 'hello world'; diff --git a/tests/esm/bar.ts b/tests/esm/bar.ts index 4bfad1a30..4bc22c6f7 100644 --- a/tests/esm/bar.ts +++ b/tests/esm/bar.ts @@ -1,3 +1,4 @@ -export const bar: string = 'bar' +export const bar: string = 'bar'; -if(typeof module !== 'undefined') throw new Error('module should not exist in ESM') +if (typeof module !== 'undefined') + throw new Error('module should not exist in ESM'); diff --git a/tests/esm/baz.js b/tests/esm/baz.js index 51474b54f..6363a2880 100644 --- a/tests/esm/baz.js +++ b/tests/esm/baz.js @@ -1,3 +1,4 @@ -export const baz = 'baz' +export const baz = 'baz'; -if(typeof module !== 'undefined') throw new Error('module should not exist in ESM') +if (typeof module !== 'undefined') + throw new Error('module should not exist in ESM'); diff --git a/tests/esm/biff.jsx b/tests/esm/biff.jsx index e397d5217..7ac508317 100644 --- a/tests/esm/biff.jsx +++ b/tests/esm/biff.jsx @@ -1,8 +1,9 @@ -export const biff = 'biff' +export const biff = 'biff'; const React = { - createElement() {} -} -const div =
+ createElement() {}, +}; +const div =
; -if(typeof module !== 'undefined') throw new Error('module should not exist in ESM') +if (typeof module !== 'undefined') + throw new Error('module should not exist in ESM'); diff --git a/tests/esm/foo.ts b/tests/esm/foo.ts index 501c0021d..c6b5e44c8 100644 --- a/tests/esm/foo.ts +++ b/tests/esm/foo.ts @@ -1,3 +1,4 @@ -export const foo: string = 'foo' +export const foo: string = 'foo'; -if(typeof module !== 'undefined') throw new Error('module should not exist in ESM') +if (typeof module !== 'undefined') + throw new Error('module should not exist in ESM'); diff --git a/tests/esm/index.ts b/tests/esm/index.ts index 3b955e28b..fd9538f11 100644 --- a/tests/esm/index.ts +++ b/tests/esm/index.ts @@ -1,8 +1,15 @@ -import {foo} from './foo.js' -import {bar} from './bar.js' -import {baz} from './baz.js' -import {biff} from './biff.js' +import { foo } from './foo.js'; +import { bar } from './bar.js'; +import { baz } from './baz.js'; +import { biff } from './biff.js'; +import { libfoo } from 'libfoo'; -if(typeof module !== 'undefined') throw new Error('module should not exist in ESM') +// Test import builtin modules +import { readFileSync } from 'fs'; +if (typeof readFileSync !== 'function') + throw new Error('failed to import builtin module'); -console.log(`${foo} ${bar} ${baz} ${biff}`) +if (typeof module !== 'undefined') + throw new Error('module should not exist in ESM'); + +console.log(`${foo} ${bar} ${baz} ${biff} ${libfoo}`); diff --git a/tests/esm/node_modules/libfoo/entrypoint.js b/tests/esm/node_modules/libfoo/entrypoint.js new file mode 100644 index 000000000..97ec5ba03 --- /dev/null +++ b/tests/esm/node_modules/libfoo/entrypoint.js @@ -0,0 +1 @@ +export const libfoo = 'libfoo' diff --git a/tests/esm/node_modules/libfoo/index.d.ts b/tests/esm/node_modules/libfoo/index.d.ts new file mode 100644 index 000000000..dc2a05001 --- /dev/null +++ b/tests/esm/node_modules/libfoo/index.d.ts @@ -0,0 +1,2 @@ +// TypeScript does not yet support package.json "exports" +export const libfoo: string diff --git a/tests/esm/node_modules/libfoo/package.json b/tests/esm/node_modules/libfoo/package.json new file mode 100644 index 000000000..bda92d96b --- /dev/null +++ b/tests/esm/node_modules/libfoo/package.json @@ -0,0 +1,6 @@ +{ + "type": "module", + "exports": { + "import": "./entrypoint.js" + } +} diff --git a/tests/throw-react-tsx.tsx b/tests/esm/throw error.ts similarity index 59% rename from tests/throw-react-tsx.tsx rename to tests/esm/throw error.ts index 88886824f..d52a5690a 100644 --- a/tests/throw-react-tsx.tsx +++ b/tests/esm/throw error.ts @@ -1,9 +1,7 @@ // intentional whitespace to prove that sourcemaps are working. Throw should happen on line 100. // 100 lines is meant to be far more space than the helper functions would take. -const React = {createElement: (...args: any[]) => null} -class Foo { - +// Space in filename is intentional to ensure we handle this correctly when providing sourcemaps @@ -95,12 +93,11 @@ class Foo { - - constructor () { this.bar() } - bar () { throw new Error('this is a demo') } - someJsx() { - return
+class Foo { + constructor() { + this.bar(); } + bar() { throw new Error('this is a demo'); } } -new Foo() -export {} +new Foo(); +export {}; diff --git a/tests/esm/tsconfig.json b/tests/esm/tsconfig.json index 03e0c3c5d..635b5b872 100644 --- a/tests/esm/tsconfig.json +++ b/tests/esm/tsconfig.json @@ -2,6 +2,7 @@ "compilerOptions": { "module": "ESNext", "allowJs": true, - "jsx": "react" + "jsx": "react", + "moduleResolution": "node" } } diff --git a/tests/from-node-modules/from-node-modules.ts b/tests/from-node-modules/from-node-modules.ts index 8a4ed4a37..0f343de39 100644 --- a/tests/from-node-modules/from-node-modules.ts +++ b/tests/from-node-modules/from-node-modules.ts @@ -1,10 +1,10 @@ // These files are resolved by the typechecker -import * as tsmie from 'external/typescript-module-imported-externally' -import * as jsmie from 'external/javascript-module-imported-externally' +import * as tsmie from 'external/typescript-module-imported-externally'; +import * as jsmie from 'external/javascript-module-imported-externally'; // These files are unknown to the compiler until required. -const tsmre = require('external/typescript-module-required-externally') -const jsmre = require('external/javascript-module-required-externally') +const tsmre = require('external/typescript-module-required-externally'); +const jsmre = require('external/javascript-module-required-externally'); -import * as external from 'external' +import * as external from 'external'; -console.log(JSON.stringify({external, tsmie, jsmie, tsmre, jsmre}, null, 2)) +console.log(JSON.stringify({ external, tsmie, jsmie, tsmre, jsmre }, null, 2)); diff --git a/tests/hello-world.ts b/tests/hello-world.ts index 19dfa14da..e9fe0090d 100644 --- a/tests/hello-world.ts +++ b/tests/hello-world.ts @@ -1 +1 @@ -console.log('Hello, world!') +console.log('Hello, world!'); diff --git a/tests/import-order/compiled.ts b/tests/import-order/compiled.ts index 2a508d1c4..fe9e058ef 100644 --- a/tests/import-order/compiled.ts +++ b/tests/import-order/compiled.ts @@ -1 +1 @@ -console.log('Hello, TypeScript!') +console.log('Hello, TypeScript!'); diff --git a/tests/import-order/defined.d.ts b/tests/import-order/defined.d.ts index 3bdda61f2..a40a0188d 100644 --- a/tests/import-order/defined.d.ts +++ b/tests/import-order/defined.d.ts @@ -1,3 +1,3 @@ -declare const v = 'Hello, World!' +declare const v = 'Hello, World!'; -export default v +export default v; diff --git a/tests/import-order/importer.ts b/tests/import-order/importer.ts index f20693337..446f0c501 100644 --- a/tests/import-order/importer.ts +++ b/tests/import-order/importer.ts @@ -1,3 +1,3 @@ -const v = require('./defined') +const v = require('./defined'); -console.log(v) +console.log(v); diff --git a/tests/import-order/require-compiled.js b/tests/import-order/require-compiled.js new file mode 100644 index 000000000..b73d5a376 --- /dev/null +++ b/tests/import-order/require-compiled.js @@ -0,0 +1,2 @@ +// indirectly load ./compiled in node < 12 (soon to be end-of-life'd) +require('./compiled'); diff --git a/tests/issue-986/index.ts b/tests/issue-986/index.ts index fb8e23051..dd81fe7ed 100644 --- a/tests/issue-986/index.ts +++ b/tests/issue-986/index.ts @@ -1 +1 @@ -console.log(TEST) +console.log(TEST); diff --git a/tests/issue-986/types.ts b/tests/issue-986/types.ts index 88473dfa4..8f3818960 100644 --- a/tests/issue-986/types.ts +++ b/tests/issue-986/types.ts @@ -1 +1 @@ -declare const TEST: string +declare const TEST: string; diff --git a/tests/jsx-react.tsx b/tests/jsx-react.tsx index 82d3094f4..0fb0d7e85 100644 --- a/tests/jsx-react.tsx +++ b/tests/jsx-react.tsx @@ -1,7 +1,7 @@ -import * as React from 'react' +import * as React from 'react'; -const Component = props => { - return
-} +const Component = (props) => { + return
; +}; -export default Component +export default Component; diff --git a/tests/local-types-node/node_modules/@types/node/index.d.ts b/tests/local-types-node/node_modules/@types/node/index.d.ts new file mode 100644 index 000000000..acc6b1da5 --- /dev/null +++ b/tests/local-types-node/node_modules/@types/node/index.d.ts @@ -0,0 +1,4 @@ +declare const process: LocalNodeTypes_Process; +declare interface LocalNodeTypes_Process { + /* empty */ +} diff --git a/tests/local-types-node/node_modules/@types/node/package.json b/tests/local-types-node/node_modules/@types/node/package.json new file mode 100644 index 000000000..b6d8ad997 --- /dev/null +++ b/tests/local-types-node/node_modules/@types/node/package.json @@ -0,0 +1,3 @@ +{ + "name": "@types/node" +} diff --git a/tests/main-realpath/target/target.tsx b/tests/main-realpath/target/target.tsx index 1a206f56d..2a03b0ac6 100644 --- a/tests/main-realpath/target/target.tsx +++ b/tests/main-realpath/target/target.tsx @@ -1,4 +1,4 @@ // Will throw a compiler error unless ./tsconfig.json is parsed, which enables JSX function foo() { -
+
; } diff --git a/tests/maxnodemodulesjsdepth-scoped/index.ts b/tests/maxnodemodulesjsdepth-scoped/index.ts index 434f70cba..a4d00ea96 100644 --- a/tests/maxnodemodulesjsdepth-scoped/index.ts +++ b/tests/maxnodemodulesjsdepth-scoped/index.ts @@ -1,10 +1,10 @@ // Import as values, forcing internal classification. All files are typechecked -import {foo as a_foo, bar as a_bar} from '@scoped/a' +import { foo as a_foo, bar as a_bar } from '@scoped/a'; // Values are not used, so classification remains external. Obeys maxNodeModulesJsDepth -import {foo as b_foo, bar as b_bar} from '@scoped/b' +import { foo as b_foo, bar as b_bar } from '@scoped/b'; // We must have two .ts files, one without type errors. // Otherwise, type errors would prevent imports from executing, so external modules would not be reclassified as internal. -a_foo +a_foo; -import './other' +import './other'; diff --git a/tests/maxnodemodulesjsdepth-scoped/other.ts b/tests/maxnodemodulesjsdepth-scoped/other.ts index 319936b5e..f8ed3a02d 100644 --- a/tests/maxnodemodulesjsdepth-scoped/other.ts +++ b/tests/maxnodemodulesjsdepth-scoped/other.ts @@ -1,10 +1,10 @@ // Import as values, forcing internal classification. All files are typechecked -import {foo as a_foo, bar as a_bar} from '@scoped/a' +import { foo as a_foo, bar as a_bar } from '@scoped/a'; // Values are not used, so classification remains external. Obeys maxNodeModulesJsDepth -import {foo as b_foo, bar as b_bar} from '@scoped/b' +import { foo as b_foo, bar as b_bar } from '@scoped/b'; // `a_bar` has type information because it has been reclassified as internal -const shouldBeBoolean2: boolean = a_bar +const shouldBeBoolean2: boolean = a_bar; // `b_bar` is missing type information, so this is not an error -const shouldBeBoolean4: boolean = null as typeof b_bar +const shouldBeBoolean4: boolean = null as typeof b_bar; diff --git a/tests/maxnodemodulesjsdepth/index.ts b/tests/maxnodemodulesjsdepth/index.ts index 7c5c75990..81442b776 100644 --- a/tests/maxnodemodulesjsdepth/index.ts +++ b/tests/maxnodemodulesjsdepth/index.ts @@ -1,2 +1,2 @@ -import {foo, bar} from 'external' -import './other' +import { foo, bar } from 'external'; +import './other'; diff --git a/tests/maxnodemodulesjsdepth/other.ts b/tests/maxnodemodulesjsdepth/other.ts index 897e4a8c0..12737b62f 100644 --- a/tests/maxnodemodulesjsdepth/other.ts +++ b/tests/maxnodemodulesjsdepth/other.ts @@ -1,7 +1,7 @@ -import {foo, bar} from 'external' +import { foo, bar } from 'external'; // `foo` has type information so this is an error -const shouldBeBoolean: boolean = foo +const shouldBeBoolean: boolean = foo; // `bar` is missing type information, so this is not an error -const shouldBeBoolean2: boolean = bar +const shouldBeBoolean2: boolean = bar; diff --git a/tests/module-types/override-to-cjs/package.json b/tests/module-types/override-to-cjs/package.json new file mode 100644 index 000000000..3dbc1ca59 --- /dev/null +++ b/tests/module-types/override-to-cjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/tests/module-types/override-to-cjs/src/cjs-subdir/esm-exception.ts b/tests/module-types/override-to-cjs/src/cjs-subdir/esm-exception.ts new file mode 100644 index 000000000..f93bf43df --- /dev/null +++ b/tests/module-types/override-to-cjs/src/cjs-subdir/esm-exception.ts @@ -0,0 +1,2 @@ +declare const require: any; +export const requireType = typeof require; diff --git a/tests/module-types/override-to-cjs/src/cjs-subdir/index.ts b/tests/module-types/override-to-cjs/src/cjs-subdir/index.ts new file mode 100644 index 000000000..f93bf43df --- /dev/null +++ b/tests/module-types/override-to-cjs/src/cjs-subdir/index.ts @@ -0,0 +1,2 @@ +declare const require: any; +export const requireType = typeof require; diff --git a/tests/module-types/override-to-cjs/src/should-be-esm.ts b/tests/module-types/override-to-cjs/src/should-be-esm.ts new file mode 100644 index 000000000..866503d04 --- /dev/null +++ b/tests/module-types/override-to-cjs/src/should-be-esm.ts @@ -0,0 +1,3 @@ +export const a: string = 'b'; +declare const require: any; +export const requireType = typeof require; diff --git a/tests/module-types/override-to-cjs/test-webpack-config.cjs b/tests/module-types/override-to-cjs/test-webpack-config.cjs new file mode 100644 index 000000000..b14389f1c --- /dev/null +++ b/tests/module-types/override-to-cjs/test-webpack-config.cjs @@ -0,0 +1,3 @@ +const assert = require('assert'); + +assert(require('./webpack.config').hello === 'world'); diff --git a/tests/module-types/override-to-cjs/test.cjs b/tests/module-types/override-to-cjs/test.cjs new file mode 100644 index 000000000..d8c2328a4 --- /dev/null +++ b/tests/module-types/override-to-cjs/test.cjs @@ -0,0 +1,25 @@ +const assert = require('assert'); + +const wpc = require('./webpack.config.ts'); +assert(wpc.hello === 'world'); + +let failures = 0; + +try { + require('./src/should-be-esm.ts'); + failures++; +} catch (e) { + // good +} + +const cjsSubdir = require('./src/cjs-subdir'); +assert(cjsSubdir.requireType === 'function'); + +try { + require('./src/cjs-subdir/esm-exception.ts'); + failures++; +} catch (e) { + // good +} + +console.log(`Failures: ${failures}`); diff --git a/tests/module-types/override-to-cjs/test.mjs b/tests/module-types/override-to-cjs/test.mjs new file mode 100644 index 000000000..b5183df06 --- /dev/null +++ b/tests/module-types/override-to-cjs/test.mjs @@ -0,0 +1,13 @@ +import assert from 'assert'; + +import webpackConfig from './webpack.config.ts'; +import * as shouldBeEsm from './src/should-be-esm.ts'; +import subdirCjs from './src/cjs-subdir/index.ts'; +import * as subdirEsm from './src/cjs-subdir/esm-exception.ts'; + +assert(webpackConfig.hello === 'world'); +assert(shouldBeEsm.requireType === 'undefined'); +assert(subdirCjs.requireType === 'function'); +assert(subdirEsm.requireType === 'undefined'); + +console.log(`Failures: 0`); diff --git a/tests/module-types/override-to-cjs/tsconfig.json b/tests/module-types/override-to-cjs/tsconfig.json new file mode 100644 index 000000000..f8d81b073 --- /dev/null +++ b/tests/module-types/override-to-cjs/tsconfig.json @@ -0,0 +1,14 @@ +{ + "ts-node": { + "moduleTypes": { + "webpack.config.ts": "cjs", + // Test that subsequent patterns override earlier ones + "src/cjs-subdir/**/*": "esm", + "src/cjs-subdir": "cjs", + "src/cjs-subdir/esm-exception.ts": "esm" + } + }, + "compilerOptions": { + "module": "ES2015" + } +} diff --git a/tests/module-types/override-to-cjs/webpack.config.ts b/tests/module-types/override-to-cjs/webpack.config.ts new file mode 100644 index 000000000..afa980a1c --- /dev/null +++ b/tests/module-types/override-to-cjs/webpack.config.ts @@ -0,0 +1 @@ +export const hello: string = 'world'; diff --git a/tests/module-types/override-to-esm/package.json b/tests/module-types/override-to-esm/package.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/tests/module-types/override-to-esm/package.json @@ -0,0 +1 @@ +{} diff --git a/tests/module-types/override-to-esm/src/esm-subdir/cjs-exception.ts b/tests/module-types/override-to-esm/src/esm-subdir/cjs-exception.ts new file mode 100644 index 000000000..f93bf43df --- /dev/null +++ b/tests/module-types/override-to-esm/src/esm-subdir/cjs-exception.ts @@ -0,0 +1,2 @@ +declare const require: any; +export const requireType = typeof require; diff --git a/tests/module-types/override-to-esm/src/esm-subdir/index.ts b/tests/module-types/override-to-esm/src/esm-subdir/index.ts new file mode 100644 index 000000000..f93bf43df --- /dev/null +++ b/tests/module-types/override-to-esm/src/esm-subdir/index.ts @@ -0,0 +1,2 @@ +declare const require: any; +export const requireType = typeof require; diff --git a/tests/module-types/override-to-esm/src/should-be-cjs.ts b/tests/module-types/override-to-esm/src/should-be-cjs.ts new file mode 100644 index 000000000..866503d04 --- /dev/null +++ b/tests/module-types/override-to-esm/src/should-be-cjs.ts @@ -0,0 +1,3 @@ +export const a: string = 'b'; +declare const require: any; +export const requireType = typeof require; diff --git a/tests/module-types/override-to-esm/test.cjs b/tests/module-types/override-to-esm/test.cjs new file mode 100644 index 000000000..aa321d258 --- /dev/null +++ b/tests/module-types/override-to-esm/test.cjs @@ -0,0 +1,18 @@ +const assert = require('assert'); + +let failures = 0; + +const shouldBeCjs = require('./src/should-be-cjs.ts'); +assert(shouldBeCjs.requireType === 'function'); + +try { + require('./src/esm-subdir'); + failures++; +} catch (e) { + // good +} + +const cjsException = require('./src/esm-subdir/cjs-exception.ts'); +assert(cjsException.requireType === 'function'); + +console.log(`Failures: ${failures}`); diff --git a/tests/module-types/override-to-esm/test.mjs b/tests/module-types/override-to-esm/test.mjs new file mode 100644 index 000000000..c1773964d --- /dev/null +++ b/tests/module-types/override-to-esm/test.mjs @@ -0,0 +1,11 @@ +import assert from 'assert'; + +import shouldBeCjs from './src/should-be-cjs.ts'; +import * as subdirEsm from './src/esm-subdir/index.ts'; +import subdirCjs from './src/esm-subdir/cjs-exception.ts'; + +assert(shouldBeCjs.requireType === 'function'); +assert(subdirEsm.requireType === 'undefined'); +assert(subdirCjs.requireType === 'function'); + +console.log(`Failures: 0`); diff --git a/tests/module-types/override-to-esm/tsconfig.json b/tests/module-types/override-to-esm/tsconfig.json new file mode 100644 index 000000000..ae239f1f8 --- /dev/null +++ b/tests/module-types/override-to-esm/tsconfig.json @@ -0,0 +1,13 @@ +{ + "ts-node": { + "moduleTypes": { + // Test that subsequent patterns override earlier ones + "src/esm-subdir/**/*": "cjs", + "src/esm-subdir": "esm", + "src/esm-subdir/cjs-exception.ts": "cjs" + } + }, + "compilerOptions": { + "module": "CommonJS" + } +} diff --git a/tests/module.ts b/tests/module.ts index b0ec363cd..fe33f0801 100644 --- a/tests/module.ts +++ b/tests/module.ts @@ -1,3 +1,3 @@ -export function example (foo: string) { - return foo.toUpperCase() +export function example(foo: string) { + return foo.toUpperCase(); } diff --git a/tests/package.json b/tests/package.json index 26351d2b8..1b91c8b50 100644 --- a/tests/package.json +++ b/tests/package.json @@ -1,5 +1,6 @@ { "dependencies": { + "@swc/core": "latest", "ts-node": "file:ts-node-packed.tgz" } } diff --git a/tests/repl-ignored-diagnostics/index.ts b/tests/repl-ignored-diagnostics/index.ts new file mode 100644 index 000000000..77f8fe380 --- /dev/null +++ b/tests/repl-ignored-diagnostics/index.ts @@ -0,0 +1,6 @@ +// This script triggers a diagnostic that is ignored in the virtual file but +// *not* in files such as this one. +// When this file is required by the REPL, the diagnostic *should* be logged. +export {}; +function foo() {} +function foo() {} diff --git a/tests/repl/script.js b/tests/repl/script.js new file mode 100644 index 000000000..468972685 --- /dev/null +++ b/tests/repl/script.js @@ -0,0 +1,7 @@ +console.log( + JSON.stringify({ + stdinReport: typeof stdinReport !== 'undefined' && stdinReport, + evalReport: typeof evalReport !== 'undefined' && evalReport, + replReport: typeof replReport !== 'undefined' && replReport, + }) +); diff --git a/tests/repl/tla-import.ts b/tests/repl/tla-import.ts new file mode 100644 index 000000000..b40ce69cc --- /dev/null +++ b/tests/repl/tla-import.ts @@ -0,0 +1 @@ +export const foo: string = 1; diff --git a/tests/require-cache.ts b/tests/require-cache.ts index 4fbdd5047..79a6f98f8 100644 --- a/tests/require-cache.ts +++ b/tests/require-cache.ts @@ -1,7 +1,7 @@ -const moduleName = require.resolve('./module') +const moduleName = require.resolve('./module'); -const { example: example1 } = require(moduleName) -delete require.cache[moduleName] -const { example: example2 } = require(moduleName) +const { example: example1 } = require(moduleName); +delete require.cache[moduleName]; +const { example: example2 } = require(moduleName); -export { example1, example2 } +export { example1, example2 }; diff --git a/tests/scope/a/index.ts b/tests/scope/a/index.ts index af2b0fed2..12797e9c6 100644 --- a/tests/scope/a/index.ts +++ b/tests/scope/a/index.ts @@ -1,3 +1,3 @@ -import path from 'path' +import path from 'path'; -export const ext = path.extname(__filename) +export const ext = path.extname(__filename); diff --git a/tests/scope/a/log.ts b/tests/scope/a/log.ts index bf20f0de2..35ff402ef 100644 --- a/tests/scope/a/log.ts +++ b/tests/scope/a/log.ts @@ -1,3 +1,3 @@ -import { ext } from './index' +import { ext } from './index'; -console.log(ext) +console.log(ext); diff --git a/tests/scope/b/index.ts b/tests/scope/b/index.ts index af2b0fed2..12797e9c6 100644 --- a/tests/scope/b/index.ts +++ b/tests/scope/b/index.ts @@ -1,3 +1,3 @@ -import path from 'path' +import path from 'path'; -export const ext = path.extname(__filename) +export const ext = path.extname(__filename); diff --git a/tests/scope/c/config/index.ts b/tests/scope/c/config/index.ts new file mode 100644 index 000000000..7a4ee038d --- /dev/null +++ b/tests/scope/c/config/index.ts @@ -0,0 +1 @@ +export const a: string = 'value'; diff --git a/tests/scope/c/config/scopedir/index.ts b/tests/scope/c/config/scopedir/index.ts new file mode 100644 index 000000000..7a4ee038d --- /dev/null +++ b/tests/scope/c/config/scopedir/index.ts @@ -0,0 +1 @@ +export const a: string = 'value'; diff --git a/tests/scope/c/config/tsconfig.json b/tests/scope/c/config/tsconfig.json new file mode 100644 index 000000000..f4adf0744 --- /dev/null +++ b/tests/scope/c/config/tsconfig.json @@ -0,0 +1,6 @@ +{ + "ts-node": { + "scope": true, + "scopeDir": "./scopedir" + } +} diff --git a/tests/scope/c/index.js b/tests/scope/c/index.js new file mode 100644 index 000000000..a84053dec --- /dev/null +++ b/tests/scope/c/index.js @@ -0,0 +1,26 @@ +let failures = 0; +try { + // This should fail with an error because it is outside scopedir + require('./scopedir/index'); + failures++; +} catch (e) { + // good +} + +try { + // This should fail with an error because it is outside scopedir + require('./config/index'); + failures++; +} catch (e) { + // good +} + +try { + // this should succeed + console.log(require('./config/scopedir/index').a); +} catch (e) { + // bad + failures++; +} + +console.log(`Failures: ${failures}`); diff --git a/tests/scope/c/scopedir/index.ts b/tests/scope/c/scopedir/index.ts new file mode 100644 index 000000000..7a4ee038d --- /dev/null +++ b/tests/scope/c/scopedir/index.ts @@ -0,0 +1 @@ +export const a: string = 'value'; diff --git a/tests/signals.ts b/tests/signals.ts index 0a0ebc6e7..665235754 100644 --- a/tests/signals.ts +++ b/tests/signals.ts @@ -1,12 +1,12 @@ process.on('SIGINT', () => { - process.stdout.write('exited') + process.stdout.write('exited'); setTimeout(() => { - process.stdout.write(' fine') + process.stdout.write(' fine'); // Needed to make sure what we wrote has time // to be written - process.nextTick(() => process.exit()) - }, 500) -}) + process.nextTick(() => process.exit()); + }, 500); +}); -setInterval(() => console.log('should not be reached'), 3000) +setInterval(() => console.log('should not be reached'), 3000); diff --git a/tests/throw error react tsx.tsx b/tests/throw error react tsx.tsx new file mode 100644 index 000000000..c1cd9688e --- /dev/null +++ b/tests/throw error react tsx.tsx @@ -0,0 +1,106 @@ +// intentional whitespace to prove that sourcemaps are working. Throw should happen on line 100. +// 100 lines is meant to be far more space than the helper functions would take. + +// Space in filename is intentional to ensure we handle this correctly when providing sourcemaps + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +const React = { createElement: (...args: any[]) => null }; +class Foo { + constructor() { + this.bar(); + } + bar() { throw new Error('this is a demo'); } + someJsx() { + return
; + } +} +new Foo(); +export {}; diff --git a/tests/esm/throw.ts b/tests/throw error.ts similarity index 58% rename from tests/esm/throw.ts rename to tests/throw error.ts index 85ba6da48..d52a5690a 100644 --- a/tests/esm/throw.ts +++ b/tests/throw error.ts @@ -1,9 +1,7 @@ // intentional whitespace to prove that sourcemaps are working. Throw should happen on line 100. // 100 lines is meant to be far more space than the helper functions would take. -class Foo { - - +// Space in filename is intentional to ensure we handle this correctly when providing sourcemaps @@ -95,9 +93,11 @@ class Foo { - - constructor () { this.bar() } - bar () { throw new Error('this is a demo') } +class Foo { + constructor() { + this.bar(); + } + bar() { throw new Error('this is a demo'); } } -new Foo() -export {} +new Foo(); +export {}; diff --git a/tests/throw.ts b/tests/throw.ts deleted file mode 100644 index 85ba6da48..000000000 --- a/tests/throw.ts +++ /dev/null @@ -1,103 +0,0 @@ -// intentional whitespace to prove that sourcemaps are working. Throw should happen on line 100. -// 100 lines is meant to be far more space than the helper functions would take. -class Foo { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - constructor () { this.bar() } - bar () { throw new Error('this is a demo') } -} -new Foo() -export {} diff --git a/tests/transpile-only-swc-native-esm/index.ts b/tests/transpile-only-swc-native-esm/index.ts new file mode 100644 index 000000000..8c6d0f5aa --- /dev/null +++ b/tests/transpile-only-swc-native-esm/index.ts @@ -0,0 +1,2 @@ +const x: number = `Hello ${import.meta.url.slice(0, 7)}!`; +console.log(x); diff --git a/tests/transpile-only-swc-native-esm/package.json b/tests/transpile-only-swc-native-esm/package.json new file mode 100644 index 000000000..3dbc1ca59 --- /dev/null +++ b/tests/transpile-only-swc-native-esm/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/tests/transpile-only-swc-native-esm/tsconfig.json b/tests/transpile-only-swc-native-esm/tsconfig.json new file mode 100644 index 000000000..e0e3c9a90 --- /dev/null +++ b/tests/transpile-only-swc-native-esm/tsconfig.json @@ -0,0 +1,13 @@ +{ + "ts-node": { + "transpileOnly": true, + "transpiler": "ts-node/transpilers/swc-experimental" + }, + "compilerOptions": { + "target": "ES2018", + "module": "ESNext", + "allowJs": true, + "jsx": "react", + "experimentalDecorators": true + } +} diff --git a/tests/transpile-only-swc-via-tsconfig/index.ts b/tests/transpile-only-swc-via-tsconfig/index.ts new file mode 100644 index 000000000..b7dfa09cd --- /dev/null +++ b/tests/transpile-only-swc-via-tsconfig/index.ts @@ -0,0 +1,13 @@ +// Test for #1343 +const Decorator = function () {}; +@Decorator +class World {} + +// intentional type errors to check transpile-only ESM loader skips type checking +parseInt(1101, 2); +const x: number = `Hello ${World.name}!`; +console.log(x); + +// test module type emit +import { readFileSync } from 'fs'; +readFileSync; diff --git a/tests/transpile-only-swc-via-tsconfig/tsconfig.json b/tests/transpile-only-swc-via-tsconfig/tsconfig.json new file mode 100644 index 000000000..5097d63ac --- /dev/null +++ b/tests/transpile-only-swc-via-tsconfig/tsconfig.json @@ -0,0 +1,13 @@ +{ + "ts-node": { + "transpileOnly": true, + "transpiler": "ts-node/transpilers/swc-experimental" + }, + "compilerOptions": { + "target": "ES2018", + "module": "CommonJS", + "allowJs": true, + "jsx": "react", + "experimentalDecorators": true + } +} diff --git a/tests/transpile-only-swc/index.ts b/tests/transpile-only-swc/index.ts new file mode 100644 index 000000000..b7dfa09cd --- /dev/null +++ b/tests/transpile-only-swc/index.ts @@ -0,0 +1,13 @@ +// Test for #1343 +const Decorator = function () {}; +@Decorator +class World {} + +// intentional type errors to check transpile-only ESM loader skips type checking +parseInt(1101, 2); +const x: number = `Hello ${World.name}!`; +console.log(x); + +// test module type emit +import { readFileSync } from 'fs'; +readFileSync; diff --git a/tests/transpile-only-swc/tsconfig.json b/tests/transpile-only-swc/tsconfig.json new file mode 100644 index 000000000..78c35a9ca --- /dev/null +++ b/tests/transpile-only-swc/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "target": "ES2018", + "module": "CommonJS", + "allowJs": true, + "jsx": "react", + "experimentalDecorators": true + } +} diff --git a/tests/tsconfig-bases/node10/tsconfig.json b/tests/tsconfig-bases/node10/tsconfig.json new file mode 100644 index 000000000..f8b881e4c --- /dev/null +++ b/tests/tsconfig-bases/node10/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "ts-node/node10/tsconfig.json" +} diff --git a/tests/tsconfig-bases/node12/tsconfig.json b/tests/tsconfig-bases/node12/tsconfig.json new file mode 100644 index 000000000..eda168e10 --- /dev/null +++ b/tests/tsconfig-bases/node12/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "ts-node/node12/tsconfig.json" +} diff --git a/tests/tsconfig-bases/node14/tsconfig.json b/tests/tsconfig-bases/node14/tsconfig.json new file mode 100644 index 000000000..8a496b8a8 --- /dev/null +++ b/tests/tsconfig-bases/node14/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "ts-node/node14/tsconfig.json" +} diff --git a/tests/tsconfig-bases/node16/tsconfig.json b/tests/tsconfig-bases/node16/tsconfig.json new file mode 100644 index 000000000..96b21f735 --- /dev/null +++ b/tests/tsconfig-bases/node16/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "ts-node/node16/tsconfig.json" +} diff --git a/tests/tsconfig-extends/other/require-hook.js b/tests/tsconfig-extends/other/require-hook.js new file mode 100644 index 000000000..e69de29bb diff --git a/tests/tsconfig-extends/other/tsconfig.json b/tests/tsconfig-extends/other/tsconfig.json new file mode 100644 index 000000000..14c5e0cec --- /dev/null +++ b/tests/tsconfig-extends/other/tsconfig.json @@ -0,0 +1,6 @@ +{ + "ts-node": { + "require": ["./require-hook"], + "scopeDir": "./scopedir" + } +} diff --git a/tests/tsconfig-extends/tsconfig.json b/tests/tsconfig-extends/tsconfig.json new file mode 100644 index 000000000..6ffbeefb6 --- /dev/null +++ b/tests/tsconfig-extends/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "./other/tsconfig.json", + "ts-node": { + "preferTsExts": true + } +} diff --git a/tests/tsconfig-options/log-options1.js b/tests/tsconfig-options/log-options1.js index 59bc33323..2c248faf7 100644 --- a/tests/tsconfig-options/log-options1.js +++ b/tests/tsconfig-options/log-options1.js @@ -1,7 +1,9 @@ -const assert = require('assert') -assert(process.required1) -const register = process[Symbol.for('ts-node.register.instance')] -console.log(JSON.stringify({ - options: register.options, - config: register.config -})) +const assert = require('assert'); +assert(process.required1); +const register = process[Symbol.for('ts-node.register.instance')]; +console.log( + JSON.stringify({ + options: register.options, + config: register.config, + }) +); diff --git a/tests/tsconfig-options/log-options2.js b/tests/tsconfig-options/log-options2.js index 30f402d16..c2d4c891a 100644 --- a/tests/tsconfig-options/log-options2.js +++ b/tests/tsconfig-options/log-options2.js @@ -1,3 +1,3 @@ -const assert = require('assert') -require('./log-options1') -assert(process.required2) +const assert = require('assert'); +require('./log-options1'); +assert(process.required2); diff --git a/tests/tsconfig-options/required1.js b/tests/tsconfig-options/required1.js index 8f3ac408f..33f6996f1 100644 --- a/tests/tsconfig-options/required1.js +++ b/tests/tsconfig-options/required1.js @@ -1 +1 @@ -process.required1 = true +process.required1 = true; diff --git a/tests/tsconfig-options/required2.js b/tests/tsconfig-options/required2.js index 69a3ba618..f6d7b77bd 100644 --- a/tests/tsconfig-options/required2.js +++ b/tests/tsconfig-options/required2.js @@ -1,2 +1,2 @@ -require('assert')(process.required1) -process.required2 = true +require('assert')(process.required1); +process.required2 = true; diff --git a/tests/tsconfig.json b/tests/tsconfig.json index 561005005..00dbc5efd 100644 --- a/tests/tsconfig.json +++ b/tests/tsconfig.json @@ -3,10 +3,8 @@ "target": "es2015", "jsx": "react", "noEmit": true, + "strict": true, // Global type definitions. - "typeRoots": [ - "./typings", - "../node_modules/@types", - ], + "typeRoots": ["./typings", "../node_modules/@types"] } } diff --git a/tests/typings/does-not-exist/index.d.ts b/tests/typings/does-not-exist/index.d.ts index 877673cad..7ed392e4f 100644 --- a/tests/typings/does-not-exist/index.d.ts +++ b/tests/typings/does-not-exist/index.d.ts @@ -1,3 +1,3 @@ -declare module "does-not-exist" { - export const foobar = 'test' +declare module 'does-not-exist' { + export const foobar = 'test'; } diff --git a/tests/with-jsx.tsx b/tests/with-jsx.tsx index 5c7864807..94ce0b184 100644 --- a/tests/with-jsx.tsx +++ b/tests/with-jsx.tsx @@ -1,3 +1,5 @@ class Foo2 { - render () { return
} + render() { + return
; + } } diff --git a/transpilers/swc-experimental.js b/transpilers/swc-experimental.js new file mode 100644 index 000000000..7cf79b13c --- /dev/null +++ b/transpilers/swc-experimental.js @@ -0,0 +1 @@ +module.exports = require('../dist/transpilers/swc') diff --git a/tsconfig.build-schema.json b/tsconfig.build-schema.json new file mode 100644 index 000000000..adf48b4c9 --- /dev/null +++ b/tsconfig.build-schema.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "incremental": false + } +} diff --git a/tsconfig.json b/tsconfig.json index 465293630..bf59b8f83 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,7 @@ "$schema": "./tsconfig.schemastore-schema.json", "compilerOptions": { "target": "es2015", - "lib": ["es2015"], + "lib": ["es2015", "dom"], "rootDir": "src", "outDir": "dist", "module": "commonjs", @@ -11,10 +11,18 @@ "declaration": true, "sourceMap": true, "inlineSources": true, - "types": ["node", "mocha"], - "stripInternal": true + "types": ["node"], + "stripInternal": true, + "incremental": true, + "skipLibCheck": true, + "importsNotUsedAsValues": "error" }, "include": [ "src/**/*" - ] + ], + "typedocOptions": { + "entryPoints": ["./src/index.ts"], + "readme": "none", + "out": "website/static/api" + } } diff --git a/tsdoc.json b/tsdoc.json new file mode 100644 index 000000000..78b2de6d2 --- /dev/null +++ b/tsdoc.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", + + "supportForTags": { + // Indicate that the custom tag is supported by your tooling. (Without this, warnings may + // be reported saying that the tag is unsupported.) + "@default": true, + "@allOf": true, + "@see": true, + "@deprecated": true + }, + + "tagDefinitions": [ + { + "tagName": "@default", + "syntaxKind": "block", + "allowMultiple": false + }, + { + "tagName": "@allOf", + "syntaxKind": "block", + "allowMultiple": false + } + ] +} diff --git a/tslint.json b/tslint.json deleted file mode 100644 index 888779856..000000000 --- a/tslint.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "tslint-config-standard" -} diff --git a/website/.gitignore b/website/.gitignore new file mode 100644 index 000000000..b2d6de306 --- /dev/null +++ b/website/.gitignore @@ -0,0 +1,20 @@ +# Dependencies +/node_modules + +# Production +/build + +# Generated files +.docusaurus +.cache-loader + +# Misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/website/README.md b/website/README.md new file mode 100644 index 000000000..8960fa2af --- /dev/null +++ b/website/README.md @@ -0,0 +1,33 @@ +# Website + +This website is built using [Docusaurus 2](https://v2.docusaurus.io/), a modern static website generator. + +## Installation + +```console +yarn install +``` + +## Local Development + +```console +yarn start +``` + +This command starts a local development server and open up a browser window. Most changes are reflected live without having to restart the server. + +## Build + +```console +yarn build +``` + +This command generates static content into the `build` directory and can be served using any static contents hosting service. + +## Deployment + +```console +GIT_USER= USE_SSH=true yarn deploy +``` + +If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. diff --git a/website/babel.config.js b/website/babel.config.js new file mode 100644 index 000000000..e00595dae --- /dev/null +++ b/website/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: [require.resolve('@docusaurus/core/lib/babel/preset')], +}; diff --git a/website/docs/compilers.md b/website/docs/compilers.md new file mode 100644 index 000000000..e51348fa9 --- /dev/null +++ b/website/docs/compilers.md @@ -0,0 +1,24 @@ +--- +title: Third-party compilers +--- + +Some projects require a patched typescript compiler which adds additional features. For example, [`ttypescript`](https://github.com/cevek/ttypescript/tree/master/packages/ttypescript) and [`ts-patch`](https://github.com/nonara/ts-patch#readme) +add the ability to configure custom transformers. These are drop-in replacements for the vanilla `typescript` module and +implement the same API. + +For example, to use `ttypescript` and `ts-transformer-keys`, add this to your `tsconfig.json`: + +```json title="tsconfig.json" +{ + "ts-node": { + // This can be omitted when using ts-patch + "compiler": "ttypescript" + }, + "compilerOptions": { + // plugin configuration is the same for both ts-patch and ttypescript + "plugins": [ + { "transform": "ts-transformer-keys/transformer" } + ] + } +} +``` diff --git a/website/docs/configuration.md b/website/docs/configuration.md new file mode 100644 index 000000000..ad9998328 --- /dev/null +++ b/website/docs/configuration.md @@ -0,0 +1,93 @@ +--- +title: Configuration +--- + +`ts-node` supports a variety of options which can be specified via `tsconfig.json`, as CLI flags, as environment variables, or programmatically. + +For a complete list, see [Options](./options.md). + +## CLI flags + +`ts-node` CLI flags must come *before* the entrypoint script. For example: + +```shell +$ ts-node --project tsconfig-dev.json say-hello.ts Ronald +Hello, Ronald! +``` + +## Via tsconfig.json (recommended) + +`ts-node` automatically finds and loads `tsconfig.json`. Most `ts-node` options can be specified in a `"ts-node"` object using their programmatic, camelCase names. We recommend this because it works even when you cannot pass CLI flags, such as `node --require ts-node/register` and when using shebangs. + +Use `--skip-project` to skip loading the `tsconfig.json`. Use `--project` to explicitly specify the path to a `tsconfig.json`. + +When searching, it is resolved using [the same search behavior as `tsc`](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html). By default, this search is performed relative to the entrypoint script. In `--cwd-mode` or if no entrypoint is specified -- for example when using the REPL -- the search is performed relative to `--cwd` / `process.cwd()`. + +You can use this sample configuration as a starting point: + +```json title="tsconfig.json" +{ + // This is an alias to @tsconfig/node12: https://github.com/tsconfig/bases + "extends": "ts-node/node12/tsconfig.json", + + // Most ts-node options can be specified here using their programmatic names. + "ts-node": { + // It is faster to skip typechecking. + // Remove if you want ts-node to do typechecking. + "transpileOnly": true, + + "files": true, + + "compilerOptions": { + // compilerOptions specified here will override those declared below, + // but *only* in ts-node. Useful if you want ts-node and tsc to use + // different options with a single tsconfig.json. + } + }, + "compilerOptions": { + // typescript options here + } +} +``` + +Our bundled [JSON schema](https://unpkg.com/browse/ts-node@latest/tsconfig.schema.json) lists all compatible options. + +### @tsconfig/bases + +[@tsconfig/bases](https://github.com/tsconfig/bases) maintains recommended configurations for several node versions. +As a convenience, these are bundled with `ts-node`. + +```json title="tsconfig.json" +{ + "extends": "ts-node/node16/tsconfig.json", + + // Or install directly with `npm i -D @tsconfig/node16` + "extends": "@tsconfig/node16/tsconfig.json", +} +``` + +### Default config + +If no `tsconfig.json` is loaded from disk, `ts-node` will use the newest recommended defaults from +[@tsconfig/bases](https://github.com/tsconfig/bases/) compatible with your `node` and `typescript` versions. +With the latest `node` and `typescript`, this is [`@tsconfig/node16`](https://github.com/tsconfig/bases/blob/master/bases/node16.json). + +Older versions of `typescript` are incompatible with `@tsconfig/node16`. In those cases we will use an older default configuration. + +When in doubt, `ts-node --show-config` will log the configuration being used, and `ts-node -vv` will log `node` and `typescript` versions. + +## `node` flags + +[`node` flags](https://nodejs.org/api/cli.html) must be passed directly to `node`; they cannot be passed to the `ts-node` binary nor can they be specified in `tsconfig.json` + +We recommend using the [`NODE_OPTIONS`](https://nodejs.org/api/cli.html#cli_node_options_options) environment variable to pass options to `node`. + +```shell +NODE_OPTIONS='--trace-deprecation --abort-on-uncaught-exception' ts-node ./index.ts +``` + +Alternatively, you can invoke `node` directly and install `ts-node` via `--require`/`-r` + +```shell +node --trace-deprecation --abort-on-uncaught-exception -r ts-node/register ./index.ts +``` diff --git a/website/docs/how-it-works.md b/website/docs/how-it-works.md new file mode 100644 index 000000000..28dec08aa --- /dev/null +++ b/website/docs/how-it-works.md @@ -0,0 +1,24 @@ +--- +title: How It Works +--- + +`ts-node` works by registering hooks for `.ts`, `.tsx`, `.js`, and/or `.jsx` extensions. + +Vanilla `node` loads `.js` by reading code from disk and executing it. Our hook runs in the middle, transforming code from TypeScript to JavaScript and passing the result to `node` for execution. This transformation will respect your `tsconfig.json` as if you had compiled via `tsc`. + +`.js` and `.jsx` are only transformed when [`allowJs`](https://www.typescriptlang.org/docs/handbook/compiler-options.html#compiler-options) is enabled. + +`.tsx` and `.jsx` are only transformed when [`jsx`](https://www.typescriptlang.org/docs/handbook/jsx.html) is enabled. + +> **Warning:** if a file is ignored or its file extension is not registered, node will either fail to resolve the file or will attempt to execute it as JavaScript without any transformation. This may cause syntax errors or other failures, because node does not understand TypeScript type syntax nor bleeding-edge ECMAScript features. + +> **Warning:** When `ts-node` is used with `allowJs`, all non-ignored JavaScript files are transformed using the TypeScript compiler. + +## Skipping `node_modules` + +By default, **TypeScript Node** avoids compiling files in `/node_modules/` for three reasons: + +1. Modules should always be published in a format node.js can consume +2. Transpiling the entire dependency tree will make your project slower +3. Differing behaviours between TypeScript and node.js (e.g. ES2015 modules) can result in a project that works until you decide to support a feature natively from node.js + diff --git a/website/docs/imports.md b/website/docs/imports.md new file mode 100644 index 000000000..9f759d207 --- /dev/null +++ b/website/docs/imports.md @@ -0,0 +1,71 @@ +--- +title: "CommonJS vs native ECMAScript modules" +--- + +TypeScript is almost always written using modern `import` syntax, but you can choose to either transform to CommonJS or use node's native ESM support. Configuration is different for each. + +Here is a brief comparison of the two. + +| CommonJS | Native ECMAScript modules | +|---|---| +| Write native `import` syntax | Write native `import` syntax | +| Transforms `import` into `require()` | Does not transform `import` | +| Node executes scripts using the classic [CommonJS loader](https://nodejs.org/dist/latest-v16.x/docs/api/modules.html) | Node executes scripts using the new [ESM loader](https://nodejs.org/dist/latest-v16.x/docs/api/esm.html) | +| Use any of:
`ts-node` CLI
`node -r ts-node/register`
`NODE_OPTIONS="ts-node/register" node`
`require('ts-node').register({/* options */})` | Must use the ESM loader via:
`node --loader ts-node/esm`
`NODE_OPTIONS="--loader ts-node/esm" node` | + +## CommonJS + +Transforming to CommonJS is typically simpler and more widely supported because it is older. You must remove [`"type": "module"`](https://nodejs.org/api/packages.html#packages_type) from `package.json` and set [`"module": "CommonJS"`](https://www.typescriptlang.org/tsconfig/#module) in `tsconfig.json`. + +```json title="package.json" +{ + // This can be omitted; commonjs is the default + "type": "commonjs" +} +``` + +```json title="tsconfig.json" +{ + "compilerOptions": { + "module": "CommonJS" + } +} +``` + +If you must keep `"module": "ESNext"` for `tsc`, webpack, or another build tool, you can set an override for `ts-node`. + +```json title="tsconfig.json" +{ + "compilerOptions": { + "module": "ESNext" + }, + "ts-node": { + "compilerOptions": { + "module": "CommonJS" + } + } +} +``` + +## Native ECMAScript modules + +[Node's ESM loader hooks](https://nodejs.org/api/esm.html#esm_experimental_loaders) are [**experimental**](https://nodejs.org/api/documentation.html#documentation_stability_index) and subject to change. `ts-node`'s ESM support is also experimental. They may have +breaking changes in minor and patch releases and are not recommended for production. + +For complete usage, limitations, and to provide feedback, see [#1007](https://github.com/TypeStrong/ts-node/issues/1007). + +You must set [`"type": "module"`](https://nodejs.org/api/packages.html#packages_type) in `package.json` and [`"module": "ESNext"`](https://www.typescriptlang.org/tsconfig/#module) in `tsconfig.json`. + +```json title="package.json" +{ + "type": "module" +} +``` + +```json title="tsconfig.json" +{ + "compilerOptions": { + "module": "ESNext" // or ES2015, ES2020 + } +} +``` diff --git a/website/docs/installation.md b/website/docs/installation.md new file mode 100644 index 000000000..4b22d54d3 --- /dev/null +++ b/website/docs/installation.md @@ -0,0 +1,18 @@ +--- +title: Installation +--- + +```shell +# Locally in your project. +npm install -D typescript +npm install -D ts-node + +# Or globally with TypeScript. +npm install -g typescript +npm install -g ts-node + +# Depending on configuration, you may also need these +npm install -D tslib @types/node +``` + +**Tip:** Installing modules locally allows you to control and share the versions through `package.json`. TS Node will always resolve the compiler from `cwd` before checking relative to its own installation. diff --git a/website/docs/module-type-overrides.md b/website/docs/module-type-overrides.md new file mode 100644 index 000000000..0cfd8e6a5 --- /dev/null +++ b/website/docs/module-type-overrides.md @@ -0,0 +1,48 @@ +--- +title: Module type overrides +--- + +When deciding between CommonJS and native ECMAScript modules, `ts-node` defaults to matching vanilla `node` and `tsc` +behavior. This means TypeScript files are transformed according to your `tsconfig.json` `"module"` option and executed +according to node's rules for the `package.json` `"type"` field. + +In some projects you may need to override this behavior for some files. For example, in a webpack +project, you may have `package.json` configured with `"type": "module"` and `tsconfig.json` with +`"module": "esnext"`. However, webpack uses our CommonJS hook to execute your `webpack.config.ts`, +so you need to force your webpack config and any supporting scripts to execute as CommonJS. + +In these situations, our `moduleTypes` option lets you override certain files, forcing execution as +CommonJS or ESM. Node supports similar overriding via `.cjs` and `.mjs` file extensions, but `.ts` files cannot use them. +`moduleTypes` achieves the same effect, and *also* overrides your `tsconfig.json` `"module"` config appropriately. + +The following example tells `ts-node` to execute a webpack config as CommonJS: + +```json title=tsconfig.json +{ + "ts-node": { + "transpileOnly": true, + "moduleTypes": { + "webpack.config.ts": "cjs", + // Globs are also supported with the same behavior as tsconfig "include" + "webpack-config-scripts/**/*": "cjs" + } + }, + "compilerOptions": { + "module": "es2020", + "target": "es2020" + } +} +``` + +Each key is a glob pattern with the same syntax as tsconfig's `"include"` array. +When multiple patterns match the same file, the last pattern takes precedence. + +* `cjs` overrides matches files to compile and execute as CommonJS. +* `esm` overrides matches files to compile and execute as native ECMAScript modules. +* `package` resets either of the above to default behavior, which obeys `package.json` `"type"` and `tsconfig.json` `"module"` options. + +## Caveats + +Files with an overridden module type are transformed with the same limitations as [`isolatedModules`](https://www.typescriptlang.org/tsconfig#isolatedModules). This will only affect rare cases such as using `const enum`s with [`preserveConstEnums`](https://www.typescriptlang.org/tsconfig#preserveConstEnums) disabled. + +This feature is meant to faciliate scenarios where normal `compilerOptions` and `package.json` configuration is not possible. For example, a `webpack.config.ts` cannot be given its own `package.json` to override `"type"`. Wherever possible you should favor using traditional `package.json` and `tsconfig.json` configurations. diff --git a/website/docs/options-table.md b/website/docs/options-table.md new file mode 100644 index 000000000..287da82dc --- /dev/null +++ b/website/docs/options-table.md @@ -0,0 +1,196 @@ +--- +title: Options +--- + + + +`ts-node` supports `--print` (`-p`), `--eval` (`-e`), `--require` (`-r`) and `--interactive` (`-i`) similar to the [node.js CLI options](https://nodejs.org/api/cli.html). + + + +The API includes [additional options](https://typestrong.org/ts-node/api/interfaces/RegisterOptions.html) not shown below. + +_Environment variables, where available, are in `ALL_CAPS`_ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CLITSConfigDescription
Shell
-h, --help Prints the help text
-v, --version Prints the version. -vv prints node and typescript compiler versions, too
-e, --eval Evaluate code
-p, --print Print result of --eval
-i, --interactive Opens the REPL even if stdin does not appear to be a terminal
TSConfig
-P, --project [path] Path to TypeScript JSON project file
Env: TS_NODE_PROJECT
--skip-project Skip project config resolution and loading
Default: false
Env: TS_NODE_SKIP_PROJECT
-c, --cwd-mode Resolve config relative to the current directory instead of the directory of the entrypoint script
-O, --compiler-options [opts] compilerOptions JSON object to merge with compiler options
Env: TS_NODE_COMPILER_OPTIONS
--show-config Print resolved tsconfig.json, including ts-node options, and exit
Typechecking
-T, --transpile-only transpileOnly Use TypeScript's faster transpileModule
Default: false
Env: TS_NODE_TRANSPILE_ONLY
--type-check Opposite of --transpile-only
Default: true
Env: TS_NODE_TYPE_CHECK
-H, --compiler-host compilerHost Use TypeScript's compiler host API
Default: false
Env: TS_NODE_COMPILER_HOST
--files files Load files, include and exclude from tsconfig.json on startup
Default: false
Env: TS_NODE_FILES
-D, --ignore-diagnostics [code] ignoreDiagnostics Ignore TypeScript warnings by diagnostic code
Env: TS_NODE_IGNORE_DIAGNOSTICS
Transpilation
-I, --ignore [pattern] ignore Override the path patterns to skip compilation
Default: /node_modules/
Env: TS_NODE_IGNORE
--skip-ignore skipIgnore Skip ignore checks
Default: false
Env: TS_NODE_SKIP_IGNORE
-C, --compiler [name] compiler Specify a custom TypeScript compiler
Default: typescript
Env: TS_NODE_COMPILER
--transpiler [name] transpiler Specify a third-party, non-typechecking transpiler
--prefer-ts-exts preferTsExts Re-order file extensions so that TypeScript imports are preferred
Default: false
Env: TS_NODE_PREFER_TS_EXTS
Diagnostics
--log-error logError Logs TypeScript errors to stderr instead of throwing exceptions
Default: false
Env: TS_NODE_LOG_ERROR
--pretty pretty Use pretty diagnostic formatter
Default: false
Env: TS_NODE_PRETTY
Enable debug logging
Env: TS_NODE_DEBUG
Advanced
-r, --require [path] require Require a node module before execution
--cwd Behave as if invoked in this working directory
Default: process.cwd()
Env: TS_NODE_CWD
--emit emit Emit output files into .ts-node directory
Default: false
Env: TS_NODE_EMIT
Path to history file for REPL
Default: ~/.ts_node_repl_history
Env: TS_NODE_HISTORY
diff --git a/website/docs/options.md b/website/docs/options.md new file mode 100644 index 000000000..9139ea85c --- /dev/null +++ b/website/docs/options.md @@ -0,0 +1,60 @@ +--- +title: Options +--- + +`ts-node` supports `--print` (`-p`), `--eval` (`-e`), `--require` (`-r`) and `--interactive` (`-i`) similar to the [node.js CLI options](https://nodejs.org/api/cli.html). + +_Environment variables, where available, are in `ALL_CAPS`_ + +## Shell + +- `-h, --help` Prints the help text +- `-v, --version` Prints the version. `-vv` prints node and typescript compiler versions, too +- `-e, --eval` Evaluate code +- `-p, --print` Print result of `--eval` +- `-i, --interactive` Opens the REPL even if stdin does not appear to be a terminal + +## TSConfig + +- `-P, --project [path]` Path to TypeScript JSON project file
*Environment:* `TS_NODE_PROJECT` +- `--skip-project` Skip project config resolution and loading
*Default:* `false`
*Environment:* `TS_NODE_SKIP_PROJECT` +- `-c, --cwd-mode` Resolve config relative to the current directory instead of the directory of the entrypoint script +- `-O, --compiler-options [opts]` JSON object to merge with compiler options
*Environment:* `TS_NODE_COMPILER_OPTIONS` +- `--show-config` Print resolved `tsconfig.json`, including `ts-node` options, and exit + +## Typechecking + +- `-T, --transpile-only` Use TypeScript's faster `transpileModule`
*Default:* `false`
*Environment:* `TS_NODE_TRANSPILE_ONLY` +- `--type-check` Opposite of `--transpile-only`
*Default:* `true`
*Environment:* `TS_NODE_TYPE_CHECK` +- `-H, --compiler-host` Use TypeScript's compiler host API
*Default:* `false`
*Environment:* `TS_NODE_COMPILER_HOST` +- `--files` Load `files`, `include` and `exclude` from `tsconfig.json` on startup
*Default:* `false`
*Environment:* `TS_NODE_FILES` +- `-D, --ignore-diagnostics [code]` Ignore TypeScript warnings by diagnostic code
*Environment:* `TS_NODE_IGNORE_DIAGNOSTICS` + +## Transpilation + +- `-I, --ignore [pattern]` Override the path patterns to skip compilation
*Default:* `/node_modules/`
*Environment:* `TS_NODE_IGNORE` +- `--skip-ignore` Skip ignore checks
*Default:* `false`
*Environment:* `TS_NODE_SKIP_IGNORE` +- `-C, --compiler [name]` Specify a custom TypeScript compiler
*Default:* `typescript`
*Environment:* `TS_NODE_COMPILER` +- `--transpiler [name]` Specify a third-party, non-typechecking transpiler +- `--prefer-ts-exts` Re-order file extensions so that TypeScript imports are preferred
*Default:* `false`
*Environment:* `TS_NODE_PREFER_TS_EXTS` + +## Diagnostics + +- `--log-error` Logs TypeScript errors to stderr instead of throwing exceptions
*Default:* `false`
*Environment:* `TS_NODE_LOG_ERROR` +- `--pretty` Use pretty diagnostic formatter
*Default:* `false`
*Environment:* `TS_NODE_PRETTY` +- `TS_NODE_DEBUG` Enable debug logging
+ +## Advanced + +- `-r, --require [path]` Require a node module before execution +- `--cwd` Behave as if invoked in this working directory
*Default:* `process.cwd()`
*Environment:* `TS_NODE_CWD` +- `--emit` Emit output files into `.ts-node` directory
*Default:* `false`
*Environment:* `TS_NODE_EMIT` +- `--scope` Scope compiler to files within `scopeDir`. Anything outside this directory is ignored.
*Default: `false`
*Environment:* `TS_NODE_SCOPE` +- `--scopeDir` Directory within which compiler is limited when `scope` is enabled.
*Default:* First of: `tsconfig.json` "rootDir" if specified, directory containing `tsconfig.json`, or cwd if no `tsconfig.json` is loaded.
*Environment:* `TS_NODE_SCOPE_DIR` +- `moduleType` Override the module type of certain files, ignoring the `package.json` `"type"` field. See [Module type overrides](./module-type-overrides.md) for details.
*Default:* obeys `package.json` `"type"` and `tsconfig.json` `"module"`
*Can only be specified via `tsconfig.json` or API.* +- `TS_NODE_HISTORY` Path to history file for REPL
*Default:* `~/.ts_node_repl_history`
+- `--no-experimental-repl-await` Disable top-level await in REPL. Equivalent to node's [`--no-experimental-repl-await`](https://nodejs.org/api/cli.html#cli_no_experimental_repl_await)
*Default:* Enabled if TypeScript version is 3.8 or higher and target is ES2018 or higher.
*Environment:* `TS_NODE_EXPERIMENTAL_REPL_AWAIT` set `false` to disable + +## API + +The API includes [additional options](https://typestrong.org/ts-node/api/interfaces/RegisterOptions.html) not shown here. diff --git a/website/docs/overview.md b/website/docs/overview.md new file mode 100644 index 000000000..9835306f9 --- /dev/null +++ b/website/docs/overview.md @@ -0,0 +1,26 @@ +--- +title: Overview +slug: / +--- + +`ts-node` is a TypeScript execution engine and REPL for Node.js. + +It JIT transforms TypeScript into JavaScript, enabling you to directly execute TypeScript on Node.js without precompiling. +This is accomplished by hooking node's module loading APIs, enabling it to be used seamlessly alongside other Node.js +tools and libraries. + +## Features + +* Automatic sourcemaps in stack traces +* Automatic `tsconfig.json` parsing +* Automatic defaults to match your node version +* Typechecking (optional) +* REPL +* Write standalone scripts +* Native ESM loader +* Use third-party transpilers +* Use custom transformers +* Integrate with test runners, debuggers, and CLI tools +* Compatible with pre-compilation for production + +![TypeScript REPL](/img/screenshot.png) diff --git a/website/docs/paths.md b/website/docs/paths.md new file mode 100644 index 000000000..6bc60fecc --- /dev/null +++ b/website/docs/paths.md @@ -0,0 +1,26 @@ +--- +title: | + paths and baseUrl +--- + +You can use `ts-node` together with [tsconfig-paths](https://www.npmjs.com/package/tsconfig-paths) to load modules according to the `paths` section in `tsconfig.json`. + +```json title="tsconfig.json" +{ + "ts-node": { + // Do not forget to `npm i -D tsconfig-paths` + "require": ["tsconfig-paths/register"] + } +} +``` + +## Why is this not built-in to `ts-node`? + +The official TypeScript Handbook explains the intended purpose for `"paths"` in ["Additional module resolution flags"](https://www.typescriptlang.org/docs/handbook/module-resolution.html#additional-module-resolution-flags). + +> The TypeScript compiler has a set of additional flags to *inform* the compiler of transformations that are expected to happen to the sources to generate the final output. +> +> It is important to note that the compiler will not perform any of these transformations; it just uses these pieces of information to guide the process of resolving a module import to its definition file. + +This means `"paths"` are intended to describe mappings that the build tool or runtime *already* performs, not to tell the build tool or +runtime how to resolve modules. In other words, they intend us to write our imports in a way `node` already understands. For this reason, `ts-node` does not modify `node`'s module resolution behavior to implement `"paths"` mappings. diff --git a/website/docs/performance.md b/website/docs/performance.md new file mode 100644 index 000000000..625e1cd96 --- /dev/null +++ b/website/docs/performance.md @@ -0,0 +1,21 @@ +--- +title: Make it fast +--- + +These tricks will make `ts-node` faster. + +## Skip typechecking + +It is often better to use `tsc --noEmit` to typecheck once before your tests run or as a lint step. In these cases, `ts-node` can skip typechecking. + +* Enable [`transpileOnly`](./options.md) to skip typechecking +* Use our [`swc` integration](./transpilers.md#bundled-swc-integration) + * This is by far the fastest option + +## With typechecking + +* Avoid dynamic `require()` which may trigger repeated typechecking; prefer `import` +* Try with and without `--files`; one may be faster depending on your project +* Check `tsc --showConfig`; make sure all executed files are included +* Enable [`skipLibCheck`](https://www.typescriptlang.org/tsconfig#skipLibCheck) +* Set a [`types`](https://www.typescriptlang.org/tsconfig#types) array to avoid loading unnecessary `@types` diff --git a/website/docs/recipes/ava.md b/website/docs/recipes/ava.md new file mode 100644 index 000000000..945008ec0 --- /dev/null +++ b/website/docs/recipes/ava.md @@ -0,0 +1,42 @@ +--- +title: AVA +--- + +Assuming you are configuring AVA via your `package.json`, add one of the following configurations. + +## CommonJS + +Use this configuration if your `package.json` does not have `"type": "module"`. + +```json title"package.json" +{ + "ava": { + "extensions": [ + "ts" + ], + "require": [ + "ts-node/register" + ] + } +} +``` + +## Native ECMAScript modules + +This configuration is necessary if your `package.json` has `"type": "module"`. + +```json title"package.json" +{ + "ava": { + "extensions": { + "ts": "module" + }, + "nonSemVerExperiments": { + "configurableModuleFormat": true + }, + "nodeArguments": [ + "--loader=ts-node/esm" + ] + } +} +``` diff --git a/website/docs/recipes/gulp.md b/website/docs/recipes/gulp.md new file mode 100644 index 000000000..31f1b5805 --- /dev/null +++ b/website/docs/recipes/gulp.md @@ -0,0 +1,12 @@ +--- +title: Gulp +--- + +ts-node support is built-in to gulp. + +```sh +# Create a `gulpfile.ts` and run `gulp`. +gulp +``` + +See also: https://gulpjs.com/docs/en/getting-started/javascript-and-gulpfiles#transpilation diff --git a/website/docs/recipes/intellij.md b/website/docs/recipes/intellij.md new file mode 100644 index 000000000..1a8879db2 --- /dev/null +++ b/website/docs/recipes/intellij.md @@ -0,0 +1,7 @@ +--- +title: "IntelliJ and Webstorm" +--- + +Create a new Node.js configuration and add `-r ts-node/register` to "Node parameters." + +**Note:** If you are using the `--project ` command line argument as per the [Configuration Options](../configuration.md), and want to apply this same behavior when launching in IntelliJ, specify under "Environment Variables": `TS_NODE_PROJECT=`. diff --git a/website/docs/recipes/mocha.md b/website/docs/recipes/mocha.md new file mode 100644 index 000000000..9f9c71827 --- /dev/null +++ b/website/docs/recipes/mocha.md @@ -0,0 +1,37 @@ +--- +title: Mocha +--- + +## Mocha 7 and newer + +```shell +mocha --require ts-node/register --extensions ts,tsx --watch --watch-files src 'tests/**/*.{ts,tsx}' [...args] +``` + +Or specify options via your mocha config file. + +```json title=".mocharc.json" +{ + // Specify "require" for CommonJS + "require": "ts-node/register", + // Specify "loader" for native ESM + "loader": "ts-node/esm", + "extensions": ["ts", "tsx"], + "spec": [ + "tests/**/*.spec.*" + ], + "watch-files": [ + "src" + ] +} +``` + +See also: https://mochajs.org/#configuring-mocha-nodejs + +## Mocha <=6 + +```shell +mocha --require ts-node/register --watch-extensions ts,tsx "test/**/*.{ts,tsx}" [...args] +``` + +**Note:** `--watch-extensions` is only used in `--watch` mode. diff --git a/website/docs/recipes/other.md b/website/docs/recipes/other.md new file mode 100644 index 000000000..2f93f853c --- /dev/null +++ b/website/docs/recipes/other.md @@ -0,0 +1,17 @@ +--- +title: Other +--- + +In many cases, setting [`NODE_OPTIONS`](https://nodejs.org/api/cli.html#cli_node_options_options) will enable `ts-node` within other node tools, child processes, and worker threads. + +```shell +NODE_OPTIONS="-r ts-node/register" +``` + +Or, if you require native ESM support: + +```shell +NODE_OPTIONS="--loader ts-node/esm" +``` + +This tells any node processes which receive this environment variable to install `ts-node`'s hooks before executing other code. diff --git a/website/docs/recipes/tape.md b/website/docs/recipes/tape.md new file mode 100644 index 000000000..7280d9dc8 --- /dev/null +++ b/website/docs/recipes/tape.md @@ -0,0 +1,7 @@ +--- +title: Tape +--- + +```shell +ts-node node_modules/tape/bin/tape [...args] +``` diff --git a/website/docs/recipes/visual-studio-code.md b/website/docs/recipes/visual-studio-code.md new file mode 100644 index 000000000..1d8d44b7f --- /dev/null +++ b/website/docs/recipes/visual-studio-code.md @@ -0,0 +1,22 @@ +--- +title: Visual Studio Code +--- + +Create a new node.js configuration, add `-r ts-node/register` to node args and move the `program` to the `args` list (so VS Code doesn't look for `outFiles`). + +```json +{ + "type": "node", + "request": "launch", + "name": "Launch Program", + "runtimeArgs": [ + "-r", + "ts-node/register" + ], + "args": [ + "${workspaceFolder}/index.ts" + ] +} +``` + +**Note:** If you are using the `--project ` command line argument as per the [Configuration Options](../configuration.md), and want to apply this same behavior when launching in VS Code, add an "env" key into the launch configuration: `"env": { "TS_NODE_PROJECT": "" }`. diff --git a/website/docs/recipes/watching-and-restarting.md b/website/docs/recipes/watching-and-restarting.md new file mode 100644 index 000000000..82f0d909e --- /dev/null +++ b/website/docs/recipes/watching-and-restarting.md @@ -0,0 +1,7 @@ +--- +title: Watching and Restarting +--- + +**TypeScript Node** compiles source code via `require()`, watching files and code reloads are out of scope for the project. If you want to restart the `ts-node` process on file change, existing node.js tools such as [nodemon](https://github.com/remy/nodemon), [onchange](https://github.com/Qard/onchange) and [node-dev](https://github.com/fgnass/node-dev) work. + +There's also [`ts-node-dev`](https://github.com/whitecolor/ts-node-dev), a modified version of [`node-dev`](https://github.com/fgnass/node-dev) using `ts-node` for compilation that will restart the process on file change. diff --git a/website/docs/transpilers.md b/website/docs/transpilers.md new file mode 100644 index 000000000..2df5fa2e8 --- /dev/null +++ b/website/docs/transpilers.md @@ -0,0 +1,47 @@ +--- +title: Third-party transpilers +--- + +In transpile-only mode, we skip typechecking to speed up execution time. You can go a step further and use a +third-party transpiler to transform TypeScript into JavaScript even faster. You will still benefit from +`ts-node`'s automatic `tsconfig.json` discovery, sourcemap support, and global `ts-node` CLI. Integrations +can automatically derive an appropriate configuration from your existing `tsconfig.json` which simplifies project +boilerplate. + +> **What is the difference between a compiler and a transpiler?** +> +> For our purposes, a compiler implements TypeScript's API and can perform typechecking. +> A third-party transpiler does not. Both transform TypeScript into JavaScript. + +## Bundled `swc` integration + +We have bundled an experimental `swc` integration. + +[`swc`](https://swc.rs) is a TypeScript-compatible transpiler implemented in Rust. This makes it an order of magnitude faster +than `transpileModule`. + +To use it, first install `@swc/core` or `@swc/wasm`. If using `importHelpers`, also install `@swc/helpers`. + +```shell +npm i -D @swc/core @swc/helpers +``` + +Then add the following to your `tsconfig.json`. + +```json title="tsconfig.json" +{ + "ts-node": { + "transpileOnly": true, + "transpiler": "ts-node/transpilers/swc-experimental" + } +} +``` + +> `swc` uses `@swc/helpers` instead of `tslib`. If you have enabled `importHelpers`, you must also install `@swc/helpers`. + +## Writing your own integration + +To write your own transpiler integration, check our [API docs](https://typestrong.org/ts-node/api/interfaces/TranspilerModule.html). + +Integrations are `require()`d, so they can be published to npm. The module must export a `create` function matching the +[`TranspilerModule`](https://typestrong.org/ts-node/api/interfaces/TranspilerModule.html) interface. diff --git a/website/docs/troubleshooting.md b/website/docs/troubleshooting.md new file mode 100644 index 000000000..4ddac6910 --- /dev/null +++ b/website/docs/troubleshooting.md @@ -0,0 +1,84 @@ +--- +title: Troubleshooting +--- + +## Understanding configuration + +`ts-node` uses sensible default configurations to reduce boilerplate while still respecting `tsconfig.json` if you +have one. If you are unsure which configuration is used, you can log it with `ts-node --show-config`. This is similar to +`tsc --showConfig` but includes `"ts-node"` options as well. + +`ts-node` also respects your locally-installed `typescript` version, but global installations fallback to the globally-installed +`typescript`. If you are unsure which versions are used, `ts-node -vv` will log them. + +```shell +$ ts-node -vv +ts-node v10.0.0 +node v16.1.0 +compiler v4.2.2 + +$ ts-node --show-config +{ + "compilerOptions": { + "target": "es6", + "lib": [ + "es6", + "dom" + ], + "rootDir": "./src", + "outDir": "./.ts-node", + "module": "commonjs", + "moduleResolution": "node", + "strict": true, + "declaration": false, + "sourceMap": true, + "inlineSources": true, + "types": [ + "node" + ], + "stripInternal": true, + "incremental": true, + "skipLibCheck": true, + "importsNotUsedAsValues": "error", + "inlineSourceMap": false, + "noEmit": false + }, + "ts-node": { + "cwd": "/d/project", + "projectSearchDir": "/d/project", + "require": [], + "project": "/d/project/tsconfig.json" + } +} +``` + +## Understanding Errors + +It is important to differentiate between errors from `ts-node`, errors from the TypeScript compiler, and errors from `node`. It is also important to understand when errors are caused by a type error in your code, a bug in your code, or a flaw in your configuration. + +### `TSError` + +Type errors from the compiler are thrown as a `TSError`. These are the same as errors you get from `tsc`. + +### `SyntaxError` + +Any error that is not a `TSError` is from node.js (e.g. `SyntaxError`), and cannot be fixed by TypeScript or `ts-node`. These are bugs in your code or configuration. + +#### Unsupported JavaScript syntax + +Your version of `node` may not support all JavaScript syntax supported by TypeScript. The compiler must transform this syntax via "downleveling," which is controlled by +the [tsconfig `"target"` option](https://www.typescriptlang.org/tsconfig#target). Otherwise your code will compile fine, but node will throw a `SyntaxError`. + +For example, `node` 12 does not understand the `?.` optional chaining operator. If you use `"target": "esnext"`, then the following TypeScript syntax: + +```typescript +const bar: string | undefined = foo?.bar; +``` + +will compile into this JavaScript: + +```javascript +const a = foo?.bar; +``` + +When you try to run this code, node 12 will throw a `SyntaxError`. To fix this, you must switch to `"target": "es2019"` or lower so TypeScript transforms `?.` into something `node` can understand. diff --git a/website/docs/types.md b/website/docs/types.md new file mode 100644 index 000000000..168c5c6a7 --- /dev/null +++ b/website/docs/types.md @@ -0,0 +1,57 @@ +--- +title: "Help! My Types Are Missing!" +--- + +**TypeScript Node** does _not_ use `files`, `include` or `exclude`, by default. This is because a large majority projects do not use all of the files in a project directory (e.g. `Gulpfile.ts`, runtime vs tests) and parsing every file for types slows startup time. Instead, `ts-node` starts with the script file (e.g. `ts-node index.ts`) and TypeScript resolves dependencies based on imports and references. + +For global definitions, you can use the `typeRoots` compiler option. This requires that your type definitions be structured as type packages (not loose TypeScript definition files). More details on how this works can be found in the [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html#types-typeroots-and-types). + +Example `tsconfig.json`: + +```json +{ + "compilerOptions": { + "typeRoots" : ["./node_modules/@types", "./typings"] + } +} +``` + +Example project structure: + +```text +/ +-- tsconfig.json +-- typings/ + -- / + -- index.d.ts +``` + +Example module declaration file: + +```typescript +declare module '' { + // module definitions go here +} +``` + +For module definitions, you can use [`paths`](https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping): + +```json +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "custom-module-type": ["types/custom-module-type"] + } + } +} +``` + +An alternative approach for definitions of third-party libraries are [triple-slash directives](https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html). This may be helpful if you prefer not to change your TypeScript `compilerOptions` or structure your custom type definitions when using `typeRoots`. Below is an example of the triple-slash directive as a relative path within your project: + +```typescript +/// +import UntypedJsLib from "untyped_js_lib" +``` + +**Tip:** If you _must_ use `files`, `include`, or `exclude`, enable `--files` flags or set `TS_NODE_FILES=true`. diff --git a/website/docs/usage.md b/website/docs/usage.md new file mode 100644 index 000000000..76048706c --- /dev/null +++ b/website/docs/usage.md @@ -0,0 +1,55 @@ +--- +title: Usage +--- + +## Shell + +```shell +# Execute a script as `node` + `tsc`. +ts-node script.ts + +# Starts a TypeScript REPL. +ts-node + +# Execute code with TypeScript. +ts-node -e 'console.log("Hello, world!")' + +# Execute, and print, code with TypeScript. +ts-node -p -e '"Hello, world!"' + +# Pipe scripts to execute with TypeScript. +echo 'console.log("Hello, world!")' | ts-node + +# Equivalent to ts-node --transpile-only +ts-node-transpile-only script.ts + +# Equivalent to ts-node --cwd-mode +ts-node-cwd script.ts +``` + +## Shebang + +```typescript +#!/usr/bin/env ts-node + +console.log("Hello, world!") +``` + +Passing CLI arguments via shebang is allowed on Mac but not Linux. For example, the following will fail on Linux: + +``` +#!/usr/bin/env ts-node --files +// This shebang is not portable. It only works on Mac +``` + +Instead, specify all `ts-node` options in your `tsconfig.json`. + +## Programmatic + +You can require `ts-node` and register the loader for future requires by using `require('ts-node').register({ /* options */ })`. You can also use file shortcuts - `node -r ts-node/register` or `node -r ts-node/register/transpile-only` - depending on your preferences. + +**Note:** If you need to use advanced node.js CLI arguments (e.g. `--inspect`), use them with `node -r ts-node/register` instead of the `ts-node` CLI. + +### Developers + +`ts-node` exports a `create()` function that can be used to initialize a TypeScript compiler that isn't registered to `require.extensions`, and it uses the same code as `register`. diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js new file mode 100644 index 000000000..109116d2c --- /dev/null +++ b/website/docusaurus.config.js @@ -0,0 +1,142 @@ +module.exports = { + title: 'ts-node', + tagline: 'TypeScript execution and REPL for node.js', + url: 'https://typestrong.org', + baseUrl: '/ts-node/', + onBrokenLinks: 'throw', + onBrokenMarkdownLinks: 'warn', + favicon: 'img/favicon/favicon.ico', + organizationName: 'TypeStrong', // Usually your GitHub org/user name. + projectName: 'ts-node', // Usually your repo name. + themeConfig: { + image: 'img/opengraph.png', + // announcementBar: { + // id: 'website_wip', // Any value that will identify this message. + // content: + // 'This website is still under construction. It describes the latest, unreleased changes from our main branch. Until it is ready, official documentation lives in our README', + // //backgroundColor: '#fafbfc', // Defaults to `#fff`. + // //textColor: '#091E42', // Defaults to `#000`. + // //isCloseable: false, // Defaults to `true`. + // }, + colorMode: { + respectPrefersColorScheme: true + }, + navbar: { + title: 'ts-node', + logo: { + alt: 'ts-node logo', + src: 'img/logo-icon.svg', + }, + items: [ + { + to: 'docs/', + activeBasePath: 'docs', + label: 'Docs', + position: 'right', + }, + { + href: 'https://typestrong.org/ts-node/api/', + label: 'API', + position: 'right', + }, + { + href: 'https://github.com/TypeStrong/ts-node/releases', + label: 'Release Notes', + position: 'right', + }, + { + href: 'https://github.com/TypeStrong/ts-node/discussions', + label: 'Discuss', + position: 'right', + }, + { + href: 'https://discord.gg/typescript', + label: 'Chat', + position: 'right', + }, + { + href: 'https://github.com/TypeStrong/ts-node', + label: 'GitHub', + position: 'right', + }, + ], + }, + // footer: { + // style: 'dark', + // links: [ + // // { + // // title: 'Docs', + // // items: [ + // // { + // // label: 'Docs', + // // to: 'docs/', + // // } + // // ], + // // }, + // // { + // // title: 'Community', + // // items: [ + // // { + // // label: 'Discord', + // // href: 'https://discord.gg/typescript' + // // }, + // // { + // // label: 'Github Discussions', + // // href: 'https://github.com/TypeStrong/ts-node/discussions' + // // }, + // // ], + // // }, + // // { + // // title: 'More', + // // items: [ + // // { + // // label: 'GitHub', + // // href: 'https://github.com/TypeStrong/ts-node', + // // }, + // // ], + // // }, + // ], + // // copyright: `Copyright © ${new Date().getFullYear()} My Project, Inc. Built with Docusaurus.`, + // }, + prism: { + // for syntax highlighting + // additionalLanguages: ['powershell'], + }, + algolia: { + apiKey: 'c882a0a136ef4e15aa99db604280caa6', + indexName: 'ts-node', + + // Optional: see doc section below + // contextualSearch: true, + + // Optional: see doc section below + // appId: 'YOUR_APP_ID', + + // Optional: Algolia search parameters + // searchParameters: {}, + + //... other Algolia params + }, + }, + presets: [ + [ + '@docusaurus/preset-classic', + { + docs: { + sidebarPath: require.resolve('./sidebars.js'), + editUrl: + 'https://github.com/TypeStrong/ts-node/edit/docs/website/', + }, + // blog: { + // showReadingTime: true, + // // Please change this to your repo. + // editUrl: + // 'https://github.com/facebook/docusaurus/edit/master/website/blog/', + // }, + theme: { + customCss: require.resolve('./src/css/custom.css'), + }, + }, + ], + ], +}; diff --git a/website/package.json b/website/package.json new file mode 100644 index 000000000..6c3851cd3 --- /dev/null +++ b/website/package.json @@ -0,0 +1,46 @@ +{ + "name": "@ts-node/website", + "version": "0.0.0", + "private": true, + "scripts": { + "docusaurus": "docusaurus", + "start": "docusaurus start", + "build": "docusaurus build", + "swizzle": "docusaurus swizzle", + "deploy": "docusaurus deploy", + "serve": "docusaurus serve", + "clear": "docusaurus clear", + "build-readme": "./scripts/build-readme.mjs" + }, + "dependencies": { + "@docusaurus/core": "2.0.0-alpha.75", + "@docusaurus/preset-classic": "2.0.0-alpha.75", + "@docusaurus/theme-search-algolia": "^2.0.0-alpha.75", + "@mdx-js/react": "^1.6.21", + "@types/js-yaml": "^4.0.0", + "clsx": "^1.1.1", + "js-yaml": "^4.0.0", + "react": "^16.8.4", + "react-dom": "^16.8.4", + "remark": "^13.0.0", + "remark-behead": "^2.3.3", + "remark-frontmatter": "^3.0.0", + "remark-preset-lint-recommended": "^5.0.0", + "remark-toc": "^7.2.0", + "remark-validate-links": "^10.0.4", + "vfile": "^4.2.1", + "vfile-reporter": "^6.0.2" + }, + "browserslist": { + "production": [ + ">0.5%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + } +} diff --git a/website/readme-sources/license.md b/website/readme-sources/license.md new file mode 100644 index 000000000..276f399ea --- /dev/null +++ b/website/readme-sources/license.md @@ -0,0 +1,9 @@ +--- +title: License +--- + +ts-node is licensed under the MIT license. [MIT](https://github.com/TypeStrong/ts-node/blob/main/LICENSE) + +ts-node includes source code from Node.js which is licensed under the MIT license. [Node.js license information](https://raw.githubusercontent.com/nodejs/node/master/LICENSE) + +ts-node includes source code from the TypeScript compiler which is licensed under the Apache License 2.0. [TypeScript license information](https://github.com/microsoft/TypeScript/blob/master/LICENSE.txt) diff --git a/website/readme-sources/prefix.md b/website/readme-sources/prefix.md new file mode 100644 index 000000000..2b5fe41ab --- /dev/null +++ b/website/readme-sources/prefix.md @@ -0,0 +1,32 @@ +--- +omitHeaderOnMerge: true +--- + + + +# ![TypeScript Node](logo.svg?sanitize=true) + +[![NPM version](https://img.shields.io/npm/v/ts-node.svg?style=flat)](https://npmjs.org/package/ts-node) +[![NPM downloads](https://img.shields.io/npm/dm/ts-node.svg?style=flat)](https://npmjs.org/package/ts-node) +[![Build status](https://img.shields.io/github/workflow/status/TypeStrong/ts-node/Continuous%20Integration)](https://github.com/TypeStrong/ts-node/actions?query=workflow%3A%22Continuous+Integration%22) +[![Test coverage](https://codecov.io/gh/TypeStrong/ts-node/branch/main/graph/badge.svg)](https://codecov.io/gh/TypeStrong/ts-node) + +> TypeScript execution and REPL for node.js, with source map support. **Works with `typescript@>=2.7`**. + +The latest documentation can also be found on our website: [https://typestrong.org/ts-node](https://typestrong.org/ts-node) + +### *Experimental ESM support* + +Native ESM support is currently experimental. For usage, limitations, and to provide feedback, see [#1007](https://github.com/TypeStrong/ts-node/issues/1007). + +# Table of Contents diff --git a/website/scripts/build-readme.mjs b/website/scripts/build-readme.mjs new file mode 100755 index 000000000..b7cb22c48 --- /dev/null +++ b/website/scripts/build-readme.mjs @@ -0,0 +1,156 @@ +#!/usr/bin/env node +/* + * Render README by merging website's `.md` pages. + */ + +import fs from 'fs'; +import { fileURLToPath } from 'url'; +import Path from 'path'; + +import _ from 'lodash'; +import remark from 'remark'; +import remarkFrontmatter from 'remark-frontmatter'; +import remarkRecommended from 'remark-preset-lint-recommended'; +import remarkToc from 'remark-toc'; +import remarkBehead from 'remark-behead'; +import remarkValidateLinks from 'remark-validate-links'; +import visit from 'unist-util-visit'; +import vfile from 'vfile'; +import vfileReporter from 'vfile-reporter'; +import jsYaml from 'js-yaml'; + +const __websiteRoot = Path.resolve(fileURLToPath(import.meta.url), '../..'); +const __root = Path.resolve(__websiteRoot, '..'); +const readmePath = Path.resolve(__root, 'README.md'); +const generateReadmeHeadersForCategories = { + General: false, + Advanced: true, + Recipes: true +}; + +import sidebars from '../sidebars.js'; + +async function main() { + const readmeNodes = []; + + await appendMarkdownFileToReadmeAst({ + path: 'readme-sources/prefix.md', + headerLevel: 1 + }); + + const sidebar = sidebars.primarySidebar; + for(const category of sidebar) { + const generateReadmeHeader = generateReadmeHeadersForCategories[category.label]; + if(generateReadmeHeader) { + readmeNodes.push(headerNode(1, category.label)); + } else if(generateReadmeHeader == null) { + throw new Error(`Update ${ import.meta.url } to include all sidebar categories`); + } + for(const page of category.items) { + await appendMarkdownFileToReadmeAst({ + path: `docs/${ page }.md`, + headerLevel: 1 + !!generateReadmeHeader + }); + } + } + + appendMarkdownFileToReadmeAst({ + path: 'readme-sources/license.md', + headerLevel: 1 + }); + + async function appendMarkdownFileToReadmeAst({path, headerLevel}) { + const absPath = Path.resolve(__websiteRoot, path); + console.log(`Appending ${ path } at header level ${ headerLevel }`); + const markdownSource = fs.readFileSync(absPath, 'utf8'); + await remark() + .use(remarkFrontmatter, ['yaml']) + .use(parseFrontmatter) + .use(remarkBehead, { after: '', depth: headerLevel - 1 }) + .use(() => (ast) => { + const {frontmatter} = ast; + if(frontmatter && !frontmatter.omitHeaderOnMerge) { + readmeNodes.push(headerNode(headerLevel, frontmatter && frontmatter.title || Path.basename(absPath))); + } + readmeNodes.push(...ast.children); + }) + .process(markdownSource); + } + + const renderedReadme = await remark() + .use(() => (ast) => { + ast.children.push(...readmeNodes); + }) + .use(codeLanguageJsonToJsonc) + .use(rewritePageLinksToAnchorLinks) + .use(rewriteImgTargets) + .use(remarkToc, {tight: true}) + .process(vfile({ + path: readmePath, + contents: '' + })); + console.error(vfileReporter(renderedReadme)); + if(renderedReadme.messages.length) throw new Error('Aborting on diagnostics.'); + const lintResults = await remark() + .use(remarkValidateLinks) + .use(remarkRecommended) + .process(renderedReadme); + console.error(vfileReporter(lintResults)); + if(lintResults.messages.length) throw new Error('Aborting on diagnostics.'); + + fs.writeFileSync(readmePath, renderedReadme.contents); +} + +function parseFrontmatter() { + return (ast) => { + if(ast.children[0].type === 'yaml') { + ast.frontmatter = jsYaml.load(ast.children[0].value); + ast.children.splice(0, 1); + } + } +} + +function codeLanguageJsonToJsonc() { + return (ast) => { + visit(ast, 'code', node => { + if(node.lang === 'json') node.lang = 'jsonc'; + }) + } +} +function rewritePageLinksToAnchorLinks() { + return (ast) => { + visit(ast, 'link', node => { + if(node.url?.match?.(/^https?\:\/\//)) return; + // TODO take page title into account + node.url = node.url.replace(/^[\.\/]*(?:([^#]+)|.*#(.*))$/, '#$1$2'); + node.url = node.url.replace(/\.md$/, ''); + }); + } +} + +function rewriteImgTargets() { + return (ast) => { + visit(ast, 'image', node => { + node.url = node.url.replace(/^\//, 'website/static/'); + }); + } +} + +function headerNode(depth, value) { + return { + type: 'heading', + depth, + children: [{ + type: 'text', + value, + children: [] + }] + }; +} + +try { + await main(); +} catch(e) { + console.error(e.message); + process.exitCode = 1; +} diff --git a/website/sidebars.js b/website/sidebars.js new file mode 100644 index 000000000..4f1d70e01 --- /dev/null +++ b/website/sidebars.js @@ -0,0 +1,51 @@ +module.exports = { + primarySidebar: [{ + type: 'category', + label: 'General', + collapsed: false, + items: [ + 'overview', + 'installation', + 'usage', + 'configuration', + 'options', + 'imports', + 'troubleshooting', + 'performance', + ] + }, { + type: 'category', + label: 'Advanced', + collapsed: false, + items: [ + 'how-it-works', + 'paths', + 'types', + 'compilers', + 'transpilers', + 'module-type-overrides' + ], + }, { + type: 'category', + label: 'Recipes', + collapsed: false, + items: [ + 'recipes/watching-and-restarting', + 'recipes/ava', + 'recipes/gulp', + 'recipes/intellij', + 'recipes/mocha', + 'recipes/tape', + 'recipes/visual-studio-code', + 'recipes/other' + ] + }], + hiddenSidebar: [{ + type: 'category', + label: 'Hidden pages', + collapsed: false, + items: [ + 'options-table', + ] + }], +}; diff --git a/website/src/css/custom.css b/website/src/css/custom.css new file mode 100644 index 000000000..9b7e4d80f --- /dev/null +++ b/website/src/css/custom.css @@ -0,0 +1,35 @@ +/* stylelint-disable docusaurus/copyright-header */ +/** + * Any CSS included here will be global. The classic template + * bundles Infima by default. Infima is a CSS framework designed to + * work well for content-centric websites. + */ + +/* You can override the default Infima variables here. */ +:root { + /* Generating by pasting #3178C6, the shade of blue from typescriptlang.org's navbar, into the palette generator at https://v2.docusaurus.io/docs/styling-layout/ */ + --ifm-color-primary: #3178c6; + --ifm-color-primary-dark: #2c6cb2; + --ifm-color-primary-darker: #2a66a8; + --ifm-color-primary-darkest: #22548b; + --ifm-color-primary-light: #4084d0; + --ifm-color-primary-lighter: #4a8bd2; + --ifm-color-primary-lightest: #689eda; + + /* Docusaurus defaults */ + /* --ifm-color-primary: #25c2a0; + --ifm-color-primary-dark: rgb(33, 175, 144); + --ifm-color-primary-darker: rgb(31, 165, 136); + --ifm-color-primary-darkest: rgb(26, 136, 112); + --ifm-color-primary-light: rgb(70, 203, 174); + --ifm-color-primary-lighter: rgb(102, 212, 189); + --ifm-color-primary-lightest: rgb(146, 224, 208); + --ifm-code-font-size: 95%; */ +} + +.docusaurus-highlight-code-line { + background-color: rgb(72, 77, 91); + display: block; + margin: 0 calc(-1 * var(--ifm-pre-padding)); + padding: 0 var(--ifm-pre-padding); +} diff --git a/website/src/pages/index.js b/website/src/pages/index.js new file mode 100644 index 000000000..9a50c6e39 --- /dev/null +++ b/website/src/pages/index.js @@ -0,0 +1,79 @@ +import React from 'react'; +import clsx from 'clsx'; +import Layout from '@theme/Layout'; +import Link from '@docusaurus/Link'; +import Head from '@docusaurus/Head'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import useBaseUrl from '@docusaurus/useBaseUrl'; +import styles from './styles.module.css'; + +function Feature({imageUrl, title, description}) { + const imgUrl = useBaseUrl(imageUrl); + return ( +
+ {imgUrl && ( +
+ {title} +
+ )} +
+ ); +} + +function Home() { + const context = useDocusaurusContext(); + const {siteConfig = {}} = context; + return ( + + + + + + + + + + + + +
+
+

{siteConfig.title}

+

{siteConfig.tagline}

+
+ + Get Started + +