From 5cfc2979d73add5a63999ab390cc8256199f54db Mon Sep 17 00:00:00 2001 From: Orta Date: Tue, 8 Jun 2021 10:42:11 +0100 Subject: [PATCH] Adds support for _not_ using JS at all --- jest.config.js | 10 +- package.json | 9 +- .../package.json | 2 +- .../test/fixtures.test.ts | 21 + .../test/fixtures/generics.md | 18 + .../test/results/codefenceHighlight.html | 23 +- .../test/results/exporting.html | 23 +- .../test/results/generics.html | 68 ++ .../test/results/generics.json | 112 ++ .../test/results/highlight.html | 21 +- .../test/results/importNodeTypes.html | 27 +- .../test/results/inline-angle-brackets.html | 23 +- .../test/results/large-chopped.html | 23 +- .../test/results/one.html | 21 +- .../test/results/simple-interface.html | 21 +- .../test/results/simple.html | 23 +- .../test/results/twoliner.html | 21 +- packages/hexo-shiki-twoslash/README.md | 2 +- packages/hexo-shiki-twoslash/package.json | 2 +- packages/markdown-it-shiki-twoslash/README.md | 2 +- .../markdown-it-shiki-twoslash/package.json | 2 +- packages/remark-shiki-twoslash/CHANGELOG.md | 8 + packages/remark-shiki-twoslash/README.md | 492 ++++----- packages/remark-shiki-twoslash/package.json | 4 +- packages/shiki-twoslash/README.md | 26 +- packages/shiki-twoslash/package.json | 4 +- packages/shiki-twoslash/src/index.ts | 9 +- .../shiki-twoslash/src/renderers/twoslash.ts | 19 +- packages/shiki-twoslash/src/utils.ts | 16 +- packages/shiki-twoslash/style.css | 242 +++++ .../test/createHighlightedString.test.ts | 36 + .../test/twoslash-renderer.test.ts | 10 +- pnpm-lock.yaml | 959 ++++++++++++------ site/pages/index.tsx | 4 - site/styles/globals.css | 23 +- 35 files changed, 1713 insertions(+), 613 deletions(-) create mode 100644 packages/gatsby-remark-shiki-twoslash/test/fixtures/generics.md create mode 100644 packages/gatsby-remark-shiki-twoslash/test/results/generics.html create mode 100644 packages/gatsby-remark-shiki-twoslash/test/results/generics.json create mode 100644 packages/remark-shiki-twoslash/CHANGELOG.md create mode 100644 packages/shiki-twoslash/style.css create mode 100644 packages/shiki-twoslash/test/createHighlightedString.test.ts diff --git a/jest.config.js b/jest.config.js index b913063..b92598d 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,6 +1,14 @@ module.exports = { testEnvironment: 'node', "transform": { - "^.+\\.tsx?$": "esbuild-jest" + "^.+\\.tsx?$": [ + "esbuild-jest", + { + sourcemap: true, + loaders: { + '.spec.ts': 'tsx' + } + } + ] } }; \ No newline at end of file diff --git a/package.json b/package.json index c477df4..5bae191 100644 --- a/package.json +++ b/package.json @@ -7,15 +7,16 @@ ], "scripts": { "test": "jest", - "bootstrap": "pnpm build -r --workspace-concurrency 1", + "bootstrap": "pnpm build -r --workspace-concurrency 1 && md-magic --path 'packages/*/README.md'", "build": "pnpm run build -r" }, "devDependencies": { "@types/jest": "^25.2.3", - "esbuild": "^0.12.3", + "esbuild": "^0.12.6", "esbuild-jest": "^0.5.0", - "jest": "^27.0.1", + "jest": "^27.0.4", "pleb": "^3.4.3", - "typescript": "^4.2.4" + "typescript": "^4.3.2", + "markdown-magic": "^2.0.0" } } diff --git a/packages/docusaurus-preset-shiki-twoslash/package.json b/packages/docusaurus-preset-shiki-twoslash/package.json index be002e2..710a507 100644 --- a/packages/docusaurus-preset-shiki-twoslash/package.json +++ b/packages/docusaurus-preset-shiki-twoslash/package.json @@ -1,6 +1,6 @@ { "name": "docusaurus-preset-shiki-twoslash", - "version": "1.0.3", + "version": "1.0.4", "license": "MIT", "homepage": "https://github.com/shikijs/twoslash", "repository": { diff --git a/packages/gatsby-remark-shiki-twoslash/test/fixtures.test.ts b/packages/gatsby-remark-shiki-twoslash/test/fixtures.test.ts index 78171ef..893e765 100644 --- a/packages/gatsby-remark-shiki-twoslash/test/fixtures.test.ts +++ b/packages/gatsby-remark-shiki-twoslash/test/fixtures.test.ts @@ -57,6 +57,8 @@ describe("with fixtures", () => { vfsRoot: join(__dirname, "..", "..", ".."), }) + console.log(results.html) + const htmlString = format(results.html + style, { parser: "html" }) expect(cleanFixture(htmlString)).toMatchFile(resultHTMLPath) @@ -105,6 +107,25 @@ color: #ffeeee; .query { color: white; } + +/* To get them all hovering OOTB: .twoslash data-lsp::before { */ + +.twoslash data-lsp:hover::before { + content: attr(lsp); + position: absolute; + transform: translate(0, 1rem); + + background-color: #3f3f3f; + color: #fff; + text-align: left; + padding: 5px 8px; + border-radius: 2px; + font-family: "JetBrains Mono", Menlo, Monaco, Consolas, Courier New, monospace; + font-size: 14px; + white-space: pre-wrap; + z-index: 100; +} + ` diff --git a/packages/gatsby-remark-shiki-twoslash/test/fixtures/generics.md b/packages/gatsby-remark-shiki-twoslash/test/fixtures/generics.md new file mode 100644 index 0000000..e7d9a83 --- /dev/null +++ b/packages/gatsby-remark-shiki-twoslash/test/fixtures/generics.md @@ -0,0 +1,18 @@ +## Generics in the LSP + +```ts twoslash +type A = { + str: string + b: B +} +``` + +## String union in the Generics in the LSP + +```ts twoslash + +type A = { + str: "one" | "two" + b: B +} +``` diff --git a/packages/gatsby-remark-shiki-twoslash/test/results/codefenceHighlight.html b/packages/gatsby-remark-shiki-twoslash/test/results/codefenceHighlight.html index 8eb30f2..18bbfa7 100644 --- a/packages/gatsby-remark-shiki-twoslash/test/results/codefenceHighlight.html +++ b/packages/gatsby-remark-shiki-twoslash/test/results/codefenceHighlight.html @@ -3,12 +3,12 @@

Relative imports

class="shiki twoslash lsp" style="background-color: #ffffff; color: #000000" >
function greet(person: string, date: Date) {
console.log(`Hello ${person}, today is ${date.toDateString()}!`)
}
-
greet("Maddison", new Date())
Try
+
greet("Maddison", new Date())

Hello

const b = 2
const c = 3 // highlighted (0 based)
Try
+>
const b = 2
const c = 3 // highlighted (0 based)
diff --git a/packages/gatsby-remark-shiki-twoslash/test/results/exporting.html b/packages/gatsby-remark-shiki-twoslash/test/results/exporting.html index 9788a9a..fd69a5a 100644 --- a/packages/gatsby-remark-shiki-twoslash/test/results/exporting.html +++ b/packages/gatsby-remark-shiki-twoslash/test/results/exporting.html @@ -2,8 +2,8 @@

Relative imports

// @filename: utilFunctions.js
const getStringLength = str => str.length
module.exports = {
getStringLength,
}
-
// @filename: index.ts
import utils from './utilFunctions'
const count = utils.getStringLength('Check JS')
Try
+>
// @filename: utilFunctions.js
const getStringLength = str => str.length
module.exports = {
getStringLength,
}
+
// @filename: index.ts
import utils from './utilFunctions'
const count = utils.getStringLength('Check JS')

Hello

diff --git a/packages/gatsby-remark-shiki-twoslash/test/results/generics.html b/packages/gatsby-remark-shiki-twoslash/test/results/generics.html new file mode 100644 index 0000000..107baf1 --- /dev/null +++ b/packages/gatsby-remark-shiki-twoslash/test/results/generics.html @@ -0,0 +1,68 @@ +

Generics in the LSP

+
type A<B> = {
str: string
b: B
}
+

String union in the Generics in the LSP

+
type A<B> = {
str: "one" | "two"
b: B
}
+ + diff --git a/packages/gatsby-remark-shiki-twoslash/test/results/generics.json b/packages/gatsby-remark-shiki-twoslash/test/results/generics.json new file mode 100644 index 0000000..703bd4e --- /dev/null +++ b/packages/gatsby-remark-shiki-twoslash/test/results/generics.json @@ -0,0 +1,112 @@ +[ + { + "code": "type A = { \n str: string\n b: B\n}", + "extension": "ts", + "highlights": [], + "queries": [], + "staticQuickInfos": [ + { + "text": "type A = {\n str: string;\n b: B;\n}", + "docs": "", + "start": 5, + "length": 1, + "line": 0, + "character": 5, + "targetString": "A" + }, + { + "text": "(type parameter) B in type A", + "docs": "", + "start": 7, + "length": 1, + "line": 0, + "character": 7, + "targetString": "B" + }, + { + "text": "(property) str: string", + "docs": "", + "start": 19, + "length": 3, + "line": 1, + "character": 4, + "targetString": "str" + }, + { + "text": "(property) b: B", + "docs": "", + "start": 35, + "length": 1, + "line": 2, + "character": 4, + "targetString": "b" + }, + { + "text": "(type parameter) B in type A", + "docs": "", + "start": 38, + "length": 1, + "line": 2, + "character": 7, + "targetString": "B" + } + ], + "errors": [], + "playgroundURL": "https://www.typescriptlang.org/play/#code/C4TwDgpgBAggPAIQHxQLxQN5QFBT1AZ2ACcAuQkgSwDsBzXfAI3IWwF8g" + }, + { + "code": "\ntype A = { \n str: \"one\" | \"two\"\n b: B\n}", + "extension": "ts", + "highlights": [], + "queries": [], + "staticQuickInfos": [ + { + "text": "type A = {\n str: \"one\" | \"two\";\n b: B;\n}", + "docs": "", + "start": 6, + "length": 1, + "line": 1, + "character": 5, + "targetString": "A" + }, + { + "text": "(type parameter) B in type A", + "docs": "", + "start": 8, + "length": 1, + "line": 1, + "character": 7, + "targetString": "B" + }, + { + "text": "(property) str: \"one\" | \"two\"", + "docs": "", + "start": 20, + "length": 3, + "line": 2, + "character": 4, + "targetString": "str" + }, + { + "text": "(property) b: B", + "docs": "", + "start": 43, + "length": 1, + "line": 3, + "character": 4, + "targetString": "b" + }, + { + "text": "(type parameter) B in type A", + "docs": "", + "start": 46, + "length": 1, + "line": 3, + "character": 7, + "targetString": "B" + } + ], + "errors": [], + "playgroundURL": "https://www.typescriptlang.org/play/#code/FAFwngDgpgBAggHgEID4YF4YG8bBvmAZxACcAuGAIgHsA7KSmAHypAHdrK8CAjCpYAF8gA" + } +] diff --git a/packages/gatsby-remark-shiki-twoslash/test/results/highlight.html b/packages/gatsby-remark-shiki-twoslash/test/results/highlight.html index be1884d..4fa3e7d 100644 --- a/packages/gatsby-remark-shiki-twoslash/test/results/highlight.html +++ b/packages/gatsby-remark-shiki-twoslash/test/results/highlight.html @@ -2,7 +2,7 @@

Hello

let helloWorld = 'Hello World'
let helloWorld: string
Try
+>
let helloWorld = 'Hello World'
let helloWorld: string
diff --git a/packages/gatsby-remark-shiki-twoslash/test/results/importNodeTypes.html b/packages/gatsby-remark-shiki-twoslash/test/results/importNodeTypes.html index 7e3a900..dec0ad6 100644 --- a/packages/gatsby-remark-shiki-twoslash/test/results/importNodeTypes.html +++ b/packages/gatsby-remark-shiki-twoslash/test/results/importNodeTypes.html @@ -4,11 +4,11 @@

Imports node's type defs

class="shiki twoslash lsp" style="background-color: #ffffff; color: #000000" >
/// <reference types="node" />
-
// @ts-check
import fs from "fs"
import { execSync } from "child_process"
-
const fileToEdit = process.env.HUSKY_GIT_PARAMS!.split(" ")[0]
const files = execSync("git status --porcelain", { encoding: "utf8" })
+
// @ts-check
import fs from "fs"
import { execSync } from "child_process"
+
const fileToEdit = process.env.HUSKY_GIT_PARAMS!.split(" ")[0]
const files = execSync("git status --porcelain", { encoding: "utf8" })
const maps: any = {
"spelltower/": "SPTWR",
"typeshift/": "TPSFT",
}
-
const prefixes = new Set()
files.split("\n").forEach(f => {
const found = Object.keys(maps).find(prefix => f.includes(prefix))
if (found) prefixes.add(maps[found])
})
-
if (prefixes.size) {
const prefix = [...prefixes.values()].sort().join(", ")
const msg = fs.readFileSync(fileToEdit, "utf8")
if (!msg.includes(prefix)) {
fs.writeFileSync(fileToEdit, `[${prefix}] ${msg}`)
}
}
Try
+
const prefixes = new Set()
files.split("\n").forEach(f => {
const found = Object.keys(maps).find(prefix => f.includes(prefix))
if (found) prefixes.add(maps[found])
})
+
if (prefixes.size) {
const prefix = [...prefixes.values()].sort().join(", ")
const msg = fs.readFileSync(fileToEdit, "utf8")
if (!msg.includes(prefix)) {
fs.writeFileSync(fileToEdit, `[${prefix}] ${msg}`)
}
}
diff --git a/packages/gatsby-remark-shiki-twoslash/test/results/inline-angle-brackets.html b/packages/gatsby-remark-shiki-twoslash/test/results/inline-angle-brackets.html index 80d9bf3..cb20114 100644 --- a/packages/gatsby-remark-shiki-twoslash/test/results/inline-angle-brackets.html +++ b/packages/gatsby-remark-shiki-twoslash/test/results/inline-angle-brackets.html @@ -3,13 +3,13 @@ class="shiki twoslash lsp" style="background-color: #ffffff; color: #000000" >
let someValue: any = "this is a string"
-
let strLength: number = (<string>someValue).length
Try
+
let strLength: number = (<string>someValue).length

And the other is the as-syntax:

let someValue: any = "this is a string"
-
let strLength: number = (someValue as string).length
Try
+
let strLength: number = (someValue as string).length

The two samples are equivalent. Using one over the other is mostly a choice of preference; however, when using TypeScript with JSX, only @@ -53,4 +53,23 @@ .query { color: white; } + + /* To get them all hovering OOTB: .twoslash data-lsp::before { */ + + .twoslash data-lsp:hover::before { + content: attr(lsp); + position: absolute; + transform: translate(0, 1rem); + + background-color: #3f3f3f; + color: #fff; + text-align: left; + padding: 5px 8px; + border-radius: 2px; + font-family: "JetBrains Mono", Menlo, Monaco, Consolas, Courier New, + monospace; + font-size: 14px; + white-space: pre-wrap; + z-index: 100; + } diff --git a/packages/gatsby-remark-shiki-twoslash/test/results/large-chopped.html b/packages/gatsby-remark-shiki-twoslash/test/results/large-chopped.html index 1c7d4f2..f3ac6d8 100644 --- a/packages/gatsby-remark-shiki-twoslash/test/results/large-chopped.html +++ b/packages/gatsby-remark-shiki-twoslash/test/results/large-chopped.html @@ -5,12 +5,12 @@

type NetworkState = NetworkLoadingState | NetworkFailedState | NetworkSuccessState
+>
type NetworkState = NetworkLoadingState | NetworkFailedState | NetworkSuccessState
function networkStatus(state: NetworkState): string {
// Right now TypeScript does not know which of the three
// potential types state could be.
// Trying to access a property which isn't shared
// across all types will raise an error
state.code
Property 'code' does not exist on type 'NetworkState'. Property 'code' does not exist on type 'NetworkLoadingState'.2339Property 'code' does not exist on type 'NetworkState'. Property 'code' does not exist on type 'NetworkLoadingState'. -
// By switching on state, TypeScript can narrow the union
// down in code flow analysis
switch (state.state) {
case 'loading':
return 'Downloading...'
case 'failed':
// The type must be NetworkFailedState here,
// so accessing the `code` field is safe
return `Error ${state.code} downloading`
case 'success':
return `Downloaded ${state.response.title} - ${state.response.summary}`
}
}
Try
+
// By switching on state, TypeScript can narrow the union
// down in code flow analysis
switch (state.state) {
case 'loading':
return 'Downloading...'
case 'failed':
// The type must be NetworkFailedState here,
// so accessing the `code` field is safe
return `Error ${state.code} downloading`
case 'success':
return `Downloaded ${state.response.title} - ${state.response.summary}`
}
}

Intersection Types

Intersection types are closely related to union types, but they are used very @@ -54,4 +54,23 @@

Intersection Types

.query { color: white; } + + /* To get them all hovering OOTB: .twoslash data-lsp::before { */ + + .twoslash data-lsp:hover::before { + content: attr(lsp); + position: absolute; + transform: translate(0, 1rem); + + background-color: #3f3f3f; + color: #fff; + text-align: left; + padding: 5px 8px; + border-radius: 2px; + font-family: "JetBrains Mono", Menlo, Monaco, Consolas, Courier New, + monospace; + font-size: 14px; + white-space: pre-wrap; + z-index: 100; + } diff --git a/packages/gatsby-remark-shiki-twoslash/test/results/one.html b/packages/gatsby-remark-shiki-twoslash/test/results/one.html index 7741b32..7756f08 100644 --- a/packages/gatsby-remark-shiki-twoslash/test/results/one.html +++ b/packages/gatsby-remark-shiki-twoslash/test/results/one.html @@ -2,7 +2,7 @@

One liner with multiple IDs

const getStringLength = (str: string) => str.length
Try
+>
const getStringLength = (str: string) => str.length
diff --git a/packages/gatsby-remark-shiki-twoslash/test/results/simple-interface.html b/packages/gatsby-remark-shiki-twoslash/test/results/simple-interface.html index a4683fb..3ac82d9 100644 --- a/packages/gatsby-remark-shiki-twoslash/test/results/simple-interface.html +++ b/packages/gatsby-remark-shiki-twoslash/test/results/simple-interface.html @@ -2,7 +2,7 @@

The { should not dissapear

interface User {
name: string
id: number
}
Try
+>
interface User {
name: string
id: number
}
diff --git a/packages/gatsby-remark-shiki-twoslash/test/results/simple.html b/packages/gatsby-remark-shiki-twoslash/test/results/simple.html index 23cae94..b74e886 100644 --- a/packages/gatsby-remark-shiki-twoslash/test/results/simple.html +++ b/packages/gatsby-remark-shiki-twoslash/test/results/simple.html @@ -2,8 +2,8 @@

A simple example with some identifiers

const a = {
b: '1234',
}
-
a
Try
+>
const a = {
b: '1234',
}
+
a
diff --git a/packages/gatsby-remark-shiki-twoslash/test/results/twoliner.html b/packages/gatsby-remark-shiki-twoslash/test/results/twoliner.html index 73253c2..e791fd6 100644 --- a/packages/gatsby-remark-shiki-twoslash/test/results/twoliner.html +++ b/packages/gatsby-remark-shiki-twoslash/test/results/twoliner.html @@ -2,7 +2,7 @@

Two liner with multiple IDs

// @filename: getStringLength.ts
export const getStringLength = (str: string) => str.length
// @filename: index.ts
import { getStringLength } from './getStringLength'
const b = getStringLength('string')
Try
+>
// @filename: getStringLength.ts
export const getStringLength = (str: string) => str.length
// @filename: index.ts
import { getStringLength } from './getStringLength'
const b = getStringLength('string')
diff --git a/packages/hexo-shiki-twoslash/README.md b/packages/hexo-shiki-twoslash/README.md index 4246b98..0a70690 100644 --- a/packages/hexo-shiki-twoslash/README.md +++ b/packages/hexo-shiki-twoslash/README.md @@ -21,5 +21,5 @@ syntax highlighting mixed with the twoslash JavaScript tooling from the TypeScri theme: "nord" ``` -1. **Follow the steps in [npmjs.com/package/remark-shiki-twoslash](https://www.npmjs.com/package/remark-shiki-twoslash)** to add the CSS and JS requirements. +1. **Follow the steps in [npmjs.com/package/remark-shiki-twoslash](https://www.npmjs.com/package/remark-shiki-twoslash)** to add the CSS requirements. 1. **Learn in [npmjs.com/package/remark-shiki-twoslash](https://www.npmjs.com/package/remark-shiki-twoslash)** to see what is available, this package leaves all the heavy work to that module. diff --git a/packages/hexo-shiki-twoslash/package.json b/packages/hexo-shiki-twoslash/package.json index 4c35bad..168cb6d 100644 --- a/packages/hexo-shiki-twoslash/package.json +++ b/packages/hexo-shiki-twoslash/package.json @@ -1,6 +1,6 @@ { "name": "hexo-shiki-twoslash", - "version": "1.0.1", + "version": "1.0.2", "license": "MIT", "homepage": "https://github.com/shikijs/twoslash", "repository": { diff --git a/packages/markdown-it-shiki-twoslash/README.md b/packages/markdown-it-shiki-twoslash/README.md index 2969bc1..11c4596 100644 --- a/packages/markdown-it-shiki-twoslash/README.md +++ b/packages/markdown-it-shiki-twoslash/README.md @@ -36,5 +36,5 @@ syntax highlighting mixed with the twoslash JavaScript tooling from the TypeScri Because shiki uses WASM to handle the syntax highlighting, _it has to be async code_, this clashes with the markdown-it API which enforces synchronous code. In the first code sample, the plugin uses [`deasync`](https://www.npmjs.com/package/deasync) to convert that async work to sync. It's safe to say that you _probably don't want deasync'd code in critical systems_. -1. **Follow the steps in [npmjs.com/package/remark-shiki-twoslash](https://www.npmjs.com/package/remark-shiki-twoslash)** to add the CSS and JS requirements. +1. **Follow the steps in [npmjs.com/package/remark-shiki-twoslash](https://www.npmjs.com/package/remark-shiki-twoslash)** to add the CSS requirements. 1. **Follow the instructions on [npmjs.com/package/remark-shiki-twoslash](https://www.npmjs.com/package/remark-shiki-twoslash)**, this module leaves all the heavy lifting to that module. diff --git a/packages/markdown-it-shiki-twoslash/package.json b/packages/markdown-it-shiki-twoslash/package.json index 2ac0e5b..df6e73c 100644 --- a/packages/markdown-it-shiki-twoslash/package.json +++ b/packages/markdown-it-shiki-twoslash/package.json @@ -1,6 +1,6 @@ { "name": "markdown-it-shiki-twoslash", - "version": "1.0.1", + "version": "1.0.2", "license": "MIT", "homepage": "https://github.com/shikijs/twoslash", "repository": { diff --git a/packages/remark-shiki-twoslash/CHANGELOG.md b/packages/remark-shiki-twoslash/CHANGELOG.md new file mode 100644 index 0000000..b687818 --- /dev/null +++ b/packages/remark-shiki-twoslash/CHANGELOG.md @@ -0,0 +1,8 @@ +### 1.4.0 + +- Removed the need to use JS at all, thanks to T6 - https://github.com/shikijs/twoslash/issues/7 +- Turned off the 'try' link by default, it's now an option enable it + +### 1.3.0 + +Ancient history \ No newline at end of file diff --git a/packages/remark-shiki-twoslash/README.md b/packages/remark-shiki-twoslash/README.md index a96e5a9..e53fc15 100644 --- a/packages/remark-shiki-twoslash/README.md +++ b/packages/remark-shiki-twoslash/README.md @@ -1,11 +1,13 @@ ### remark-shiki-twoslash -Sets up markdown code blocks to run through [shiki](https://shiki.matsu.io) which means it gets the VS Code quality +[You might first want to read the user docs.](https://shikijs.github.io/twoslash/). + +This module sets up markdown code blocks to run through [shiki](https://shiki.matsu.io) which means it gets the VS Code quality syntax highlighting, with optional inline TypeScript compiler-backed tooling. Why Shiki? Shiki uses the same syntax highlighter engine as VS Code, which means no matter how complex your code is - it will syntax highlight correctly. -In addition to all the languages shiki handles ([it's a lot](https://github.com/octref/shiki/blob/master/packages/languages/README.md#literal-values)), this module adds opt-in [@typescript/twoslash](https://github.com/microsoft/TypeScript-Website/tree/v2/packages/ts-twoslasher) rendering for TypeScript code blocks and tsconfig JSON files. +In addition to all the languages shiki handles (and [it's a lot](https://github.com/octref/shiki/blob/master/packages/languages/README.md#literal-values)), this module adds opt-in [@typescript/twoslash](https://github.com/microsoft/TypeScript-Website/tree/v2/packages/ts-twoslasher) rendering for TypeScript code blocks and tsconfig JSON files. This module powers the code samples on the TypeScript website. @@ -31,249 +33,257 @@ With Shiki Twoslash, you can explain complicated code in a way that lets people 1. **Add the CSS** - This CSS comes from the [TypeScript website's scss](https://github.com/microsoft/TypeScript-website/blob/v2/packages/typescriptlang-org/src/templates/markdown-twoslash.scss) + This CSS is based on from the [TypeScript website's scss](https://github.com/microsoft/TypeScript-website/blob/v2/packages/typescriptlang-org/src/templates/markdown-twoslash.scss) You should consider it a base to work from, rather than a perfect for every project reference. - ```css - /* Code blocks look like: -
-    
+
- -
[the code as a series of spans]
-
+ [the code as a series of spans] + Try (optional)
-
- */ - pre { - /* Give the text some space to breathe */ - padding: 12px; - /* All code samples get a grey border, twoslash ones get a different color */ - border-left: 1px solid #999; - border-bottom: 1px solid #999; - margin-bottom: 3rem; - /* Important to allow the code to move horizontally; - */ - overflow: auto; - /* So that folks know you can highlight */ - position: relative; - } - pre.shiki { - overflow: initial; - } - pre.shiki:hover .dim { - opacity: 1; - } - pre.shiki div.dim { - opacity: 0.5; - } - pre.shiki div.dim, - pre.shiki div.highlight { - margin: 0; - padding: 0; - } - pre.shiki div.highlight { - opacity: 1; - background-color: #f1f8ff; - } - pre.shiki div.line { - min-height: 1rem; - } - pre.twoslash { - border-color: #719af4; - } - pre .code-container { - overflow: auto; - } - pre .code-container > a { - position: absolute; - right: 8px; - bottom: 8px; - border-radius: 4px; - border: 1px solid #719af4; - padding: 0 8px; - color: #719af4; - text-decoration: none; - opacity: 0; - transition-timing-function: ease; - transition: opacity 0.3s; - } - @media (prefers-reduced-motion: reduce) { - pre .code-container > a { - transition: none; - } - } - pre .code-container > a:hover { - color: white; - background-color: #719af4; - } - pre .code-container:hover a { - opacity: 1; - } - pre code { - /** Style setup */ - font-size: 15px; - font-family: var(--code-font); - white-space: pre; - -webkit-overflow-scrolling: touch; - } - pre code a { - text-decoration: none; - } - pre data-err { - background: url("data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%206%203'%20enable-background%3D'new%200%200%206%203'%20height%3D'3'%20width%3D'6'%3E%3Cg%20fill%3D'%23c94824'%3E%3Cpolygon%20points%3D'5.5%2C0%202.5%2C3%201.1%2C3%204.1%2C0'%2F%3E%3Cpolygon%20points%3D'4%2C0%206%2C2%206%2C0.6%205.4%2C0'%2F%3E%3Cpolygon%20points%3D'0%2C2%201%2C3%202.4%2C3%200%2C0.6'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E") - repeat-x bottom left; - padding-bottom: 3px; - } - pre .query { - margin-bottom: 10px; - color: #137998; - display: inline-block; - } - pre .error, - pre .error-behind { - margin-left: -14px; - margin-top: 8px; - margin-bottom: 4px; - padding: 6px; - padding-left: 14px; - width: calc(100% - 19px); - white-space: pre-wrap; - display: block; - } - pre .error { - position: absolute; - background-color: #fee; - border-left: 2px solid #bf1818; - /* Give the space to the error code */ - display: flex; - align-items: center; - color: black; - } - pre .error .code { - display: none; - } - pre .error-behind { - user-select: none; - color: #fee; - } - pre .arrow { - /* Transparent background */ - background-color: #eee; - position: relative; - top: -7px; - margin-left: 0.1rem; - /* Edges */ - border-left: 1px solid #eee; - border-top: 1px solid #eee; - transform: translateY(25%) rotate(45deg); - /* Size */ - height: 8px; - width: 8px; - } - pre .popover { - margin-bottom: 10px; - background-color: #eee; - display: inline-block; - padding: 0 0.5rem 0.3rem; - margin-top: 10px; - border-radius: 3px; - } - pre .inline-completions ul.dropdown { - display: inline-block; - position: absolute; - width: 240px; - background-color: gainsboro; - color: grey; - padding-top: 4px; - font-family: "JetBrains Mono", Menlo, Monaco, Consolas, Courier New, monospace; - font-size: 0.8rem; - margin: 0; - padding: 0; - border-left: 4px solid #4b9edd; - } - pre .inline-completions ul.dropdown::before { - background-color: #4b9edd; - width: 2px; - position: absolute; - top: -1.2rem; - left: -3px; - content: " "; - } - pre .inline-completions ul.dropdown li { - overflow-x: hidden; - padding-left: 4px; - margin-bottom: 4px; - } - pre .inline-completions ul.dropdown li.deprecated { - text-decoration: line-through; - } - pre .inline-completions ul.dropdown li span.result-found { - color: #4b9edd; - } - pre .inline-completions ul.dropdown li span.result { - width: 100px; - color: black; - display: inline-block; - } - .dark-theme .markdown pre { - background-color: #d8d8d8; - border-color: #ddd; - filter: invert(98%) hue-rotate(180deg); - } - data-lsp { - /* Ensures there's no 1px jump when the hover happens above */ - border-bottom: 1px dotted transparent; - /* Fades in unobtrusively */ - transition-timing-function: ease; - transition: border-color 0.3s; - /* Respect people's wishes to not have animations */ - } - @media (prefers-reduced-motion: reduce) { - data-lsp { - transition: none; - } - } - /** When you mouse over the pre, show the underlines */ - pre:hover data-lsp { - border-color: #747474; - } - /** The tooltip-like which provides the LSP response */ - #twoslash-mouse-hover-info { - background-color: #3f3f3f; - color: #fff; - text-align: left; - padding: 5px 8px; - border-radius: 2px; - font-family: "Cascadia Mono-SemiLight", "JetBrains Mono", Menlo, Monaco, Consolas, Courier New, monospace; - font-size: 14px; - white-space: pre-wrap; - border-radius: 2px; - z-index: 100; - pointer-events: none; - } - ``` + +*/ -1. **Add the JS** for hover info to your component: - In a React codebase: +pre { + /* In theory shiki will overwrite these, but this is to make sure there are defaults regardless */ + background-color: white; + color: black; - ```jsx - import React, { useEffect } from "react" - import { setupTwoslashHovers } from "shiki-twoslash/dist/dom"; + /* Give it some space to breathe */ + padding: 12px; - export default () => { - // Add a the hovers - useEffect(setupTwoslashHovers, []) + /* All code samples get a grey border, twoslash ones get a different color */ + border-left: 1px solid #999; + border-bottom: 1px solid #999; - // Normal JSX for your component - return - } - ``` + margin-bottom: 3rem; + + /* Important to allow the code to move horizontally; */ + overflow-x: auto; + position: relative; +} + pre.shiki { + overflow-x: auto; +} + pre.shiki:hover .dim { + opacity: 1; +} + pre.shiki div.dim { + opacity: 0.5; +} + pre.shiki div.dim, pre.shiki div.highlight { + margin: 0; + padding: 0; +} + pre.shiki div.highlight { + opacity: 1; + background-color: #f1f8ff; +} + pre.shiki div.line { + min-height: 1rem; +} + +/* Visually differentiates twoslash code samples */ + pre.twoslash { + border-color: #719af4; +} + +/** When you mouse over the pre, show the underlines */ +pre.twoslash:hover data-lsp { + border-color: #747474; +} + +/** The tooltip-like which provides the LSP response */ +pre.twoslash data-lsp:hover::before { + content: attr(lsp); + position: absolute; + transform: translate(0, 1rem); + + background-color: #3f3f3f; + color: #fff; + text-align: left; + padding: 5px 8px; + border-radius: 2px; + font-family: "JetBrains Mono", Menlo, Monaco, Consolas, Courier New, monospace; + font-size: 14px; + white-space: pre-wrap; +} + +pre .code-container { + overflow: auto; +} +/* The try button */ + pre .code-container > a { + position: absolute; + right: 8px; + bottom: 8px; + border-radius: 4px; + border: 1px solid #719af4; + padding: 0 8px; + color: #719af4; + text-decoration: none; + opacity: 0; + transition-timing-function: ease; + transition: opacity 0.3s; +} +/* Respect no animations */ +@media (prefers-reduced-motion: reduce) { + pre .code-container > a { + transition: none; + } +} + pre .code-container > a:hover { + color: white; + background-color: #719af4; +} + pre .code-container:hover a { + opacity: 1; +} + + pre code { + font-size: 15px; + font-family: "JetBrains Mono", Menlo, Monaco, Consolas, Courier New, monospace;; + white-space: pre; + -webkit-overflow-scrolling: touch; +} + pre code a { + text-decoration: none; +} + pre data-err { + /* Extracted from VS Code */ + background: url("data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%206%203'%20enable-background%3D'new%200%200%206%203'%20height%3D'3'%20width%3D'6'%3E%3Cg%20fill%3D'%23c94824'%3E%3Cpolygon%20points%3D'5.5%2C0%202.5%2C3%201.1%2C3%204.1%2C0'%2F%3E%3Cpolygon%20points%3D'4%2C0%206%2C2%206%2C0.6%205.4%2C0'%2F%3E%3Cpolygon%20points%3D'0%2C2%201%2C3%202.4%2C3%200%2C0.6'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E") repeat-x bottom left; + padding-bottom: 3px; +} + pre .query { + margin-bottom: 10px; + color: #137998; + display: inline-block; +} + + /* In order to have the 'popped out' style design and to not break the layout + /* we need to place a fake and un-selectable copy of the error which _isn't_ broken out + /* behind the actual error message. + + /* This sections keeps both of those two in in sync */ + + pre .error, pre .error-behind { + margin-left: -14px; + margin-top: 8px; + margin-bottom: 4px; + padding: 6px; + padding-left: 14px; + width: calc(100% - 19px); + white-space: pre-wrap; + display: block; +} + pre .error { + position: absolute; + background-color: #fee; + border-left: 2px solid #bf1818; + /* Give the space to the error code */ + display: flex; + align-items: center; + color: black; +} + pre .error .code { + display: none; +} + pre .error-behind { + user-select: none; + color: #fee; +} +/* Queries */ + pre .arrow { + /* Transparent background */ + background-color: #eee; + position: relative; + top: -7px; + margin-left: 0.1rem; + /* Edges */ + border-left: 1px solid #eee; + border-top: 1px solid #eee; + transform: translateY(25%) rotate(45deg); + /* Size */ + height: 8px; + width: 8px; +} + pre .popover { + margin-bottom: 10px; + background-color: #eee; + display: inline-block; + padding: 0 0.5rem 0.3rem; + margin-top: 10px; + border-radius: 3px; +} +/* Completion */ + pre .inline-completions ul.dropdown { + display: inline-block; + position: absolute; + width: 240px; + background-color: gainsboro; + color: grey; + padding-top: 4px; + font-family: var(--code-font); + font-size: 0.8rem; + margin: 0; + padding: 0; + border-left: 4px solid #4b9edd; +} + pre .inline-completions ul.dropdown::before { + background-color: #4b9edd; + width: 2px; + position: absolute; + top: -1.2rem; + left: -3px; + content: " "; +} + pre .inline-completions ul.dropdown li { + overflow-x: hidden; + padding-left: 4px; + margin-bottom: 4px; +} + pre .inline-completions ul.dropdown li.deprecated { + text-decoration: line-through; +} + pre .inline-completions ul.dropdown li span.result-found { + color: #4b9edd; +} + pre .inline-completions ul.dropdown li span.result { + width: 100px; + color: black; + display: inline-block; +} + .dark-theme .markdown pre { + background-color: #d8d8d8; + border-color: #ddd; + filter: invert(98%) hue-rotate(180deg); +} + data-lsp { + /* Ensures there's no 1px jump when the hover happens */ + border-bottom: 1px dotted transparent; + /* Fades in unobtrusively */ + transition-timing-function: ease; + transition: border-color 0.3s; +} +/* Respect people's wishes to not have animations */ + @media (prefers-reduced-motion: reduce) { + data-lsp { + transition: none; + } +} +``` + - In a non-React codebase, you can still call `setupTwoslashHovers` via a bundler or module import, it will set up all - of the hovers on the page, this will need to be _after_ the HTML is set up. ### Verify @@ -318,7 +328,11 @@ Then it worked, and you should be able to hover over `createLabel` to see it's t ### Plugin Config This plugin passes the config options directly to Shiki and Twoslash. You probably will want to -[set `theme`](https://github.com/octref/shiki/blob/master/packages/themes/README.md#shiki-themes), then also the [TwoslashOptions here](https://www.npmjs.com/package/@typescript/twoslash#api-1). +[set `theme`](https://github.com/octref/shiki/blob/master/packages/themes/README.md#shiki-themes). The full reference for the plugin options [is available here](https://github.com/shikijs/twoslash/blob/main/packages/shiki-twoslash/README.md#user-settings). + +### Learning Twoslash + +The TypeScript website has a learning environment for twoslash in the [Bug Workbench](https://www.typescriptlang.org/dev/bug-workbench/). ### Light / Dark Modes @@ -399,3 +413,11 @@ Finally here is `c`: c.toString() ``` ```` + +### Editor Experience + +See [VSCode Twoslash](https://marketplace.visualstudio.com/items?itemName=Orta.vscode-twoslash) to get auto-complete for twoslash markup and quick links to the Twoslash online REPL. + +### CLI Tooling + +See [twoslash-cli](https://www.npmjs.com/package/twoslash-cli) to have a CI which verifies your code samples. \ No newline at end of file diff --git a/packages/remark-shiki-twoslash/package.json b/packages/remark-shiki-twoslash/package.json index a71f329..2d2b4e4 100644 --- a/packages/remark-shiki-twoslash/package.json +++ b/packages/remark-shiki-twoslash/package.json @@ -1,6 +1,6 @@ { "name": "remark-shiki-twoslash", - "version": "1.3.0", + "version": "1.4.0", "license": "MIT", "homepage": "https://github.com/shikijs/twoslash", "repository": { @@ -11,7 +11,7 @@ "bugs": { "url": "https://github.com/shikijs/twoslash/issues" }, - "description": "A remark plugin which adds twoslash code samples for TypeScript", + "description": "A remark plugin which renders code samples for all languages via Shiki, but has some real cool features for TS/JS code", "author": "Orta Therox", "main": "./dist/index.js", "module": "./dist/remark-shiki-twoslash.esm.js", diff --git a/packages/shiki-twoslash/README.md b/packages/shiki-twoslash/README.md index 3330e04..539a7d2 100644 --- a/packages/shiki-twoslash/README.md +++ b/packages/shiki-twoslash/README.md @@ -52,9 +52,6 @@ interface HighlighterOptions { theme?: IThemeRegistration langs?: (Lang | ILanguageRegistration)[] themes?: IThemeRegistration[] - /** - * Paths for loading themes and langs. Relative to the package's root. - */ paths?: IHighlighterPaths } ``` @@ -83,18 +80,28 @@ export interface TwoSlashOptions { } ``` -Most people will want to set a `theme`, and _maybe_ `vfsRoot` if they want to do twoslash with custom libraries in a monorepo: +And one extra for good luck: + +```ts +export interface TwoslashShikiOptions { + /** A way to turn on the try buttons seen on the TS website */ + addTryButton?: true +} +``` + +That said, most people will just want to set a `theme`: ```ts { resolve: "gatsby-remark-shiki-twoslash", options: { - theme: "github-light", - vfsRoot: path.join(__dirname, "..", "..") + theme: "github-light" }, } ``` +You can find all [built-in themes here](https://github.com/shikijs/shiki/tree/master/packages/shiki/themes) and all [built-in languages here](https://github.com/shikijs/shiki/tree/master/packages/shiki/languages). + ### Common Use Case ##### Node Types in a Code Sample @@ -114,7 +121,7 @@ This applies to other projects which use globals, like Jest etc. If you think th ### API -The user-exposed parts of the API is a single file, you might find it easier to just read that: [`src/index.ts`](https://github.com/microsoft/TypeScript-website/blob/v2/packages/shiki-twoslash/src/index.ts). +The user-exposed parts of the API is a well documented single file, you might find it easier to just read that: [`src/index.ts`](https://github.com/shikijs/twoslash/blob/main/packages/shiki-twoslash/src/index.ts). ##### `createShikiHighlighter` @@ -197,8 +204,3 @@ if (node.meta && node.meta.includes("twoslash")) { node.twoslash = results } ``` - -### Used in: - -- [gatsby-remark-shiki-twoslash](https://www.npmjs.com/package/gatsby-remark-shiki-twoslash) -- [remark-shiki-twoslash](https://www.npmjs.com/package/remark-shiki-twoslash) diff --git a/packages/shiki-twoslash/package.json b/packages/shiki-twoslash/package.json index 0792dbb..bdd1f9b 100644 --- a/packages/shiki-twoslash/package.json +++ b/packages/shiki-twoslash/package.json @@ -1,6 +1,6 @@ { "name": "shiki-twoslash", - "version": "1.3.3", + "version": "1.4.0", "license": "MIT", "homepage": "https://github.com/shikijs/twoslash", "repository": { @@ -23,7 +23,7 @@ "start": "tsdx watch", "prepublishOnly": "npm run ", "update": "node scripts/generateTSConfigOneliners.js", - "build": "tsdx build && npx tsc src/dom.ts --outDir dist", + "build": "tsdx build", "test": "tsdx test", "lint": "tsdx lint" }, diff --git a/packages/shiki-twoslash/src/index.ts b/packages/shiki-twoslash/src/index.ts index 4eb7e60..abd0664 100755 --- a/packages/shiki-twoslash/src/index.ts +++ b/packages/shiki-twoslash/src/index.ts @@ -6,8 +6,13 @@ import { defaultShikiRenderer } from "./renderers/shiki" import { tsconfigJSONRenderer } from "./renderers/tsconfig" import { parseCodeFenceInfo } from "./parseCodeFenceInfo" -/** The possible user config, a combination of all shiki and twoslash options */ -export type UserConfigSettings = HighlighterOptions & TwoSlashOptions +export interface TwoslashShikiOptions { + /** A way too turn on the try buttons seen on the TS website */ + addTryButton?: true +} + +/** The possible user config, a combination of all shiki, twoslash and twoslash-shiki options */ +export type UserConfigSettings = HighlighterOptions & TwoSlashOptions & TwoslashShikiOptions /** * This gets filled in by the promise below, then should diff --git a/packages/shiki-twoslash/src/renderers/twoslash.ts b/packages/shiki-twoslash/src/renderers/twoslash.ts index 600380c..ba84cfc 100644 --- a/packages/shiki-twoslash/src/renderers/twoslash.ts +++ b/packages/shiki-twoslash/src/renderers/twoslash.ts @@ -1,8 +1,9 @@ type Lines = import("shiki").IThemedToken[][] type TwoSlash = import("@typescript/twoslash").TwoSlashReturn +import { TwoslashShikiOptions } from ".." import { shouldBeHighlightable, shouldHighlightLine } from "../parseCodeFenceInfo" -import { stripHTML, createHighlightedString2, subTripleArrow, replaceTripleArrowEncoded, escapeHtml } from "../utils" +import { createHighlightedString, subTripleArrow, replaceTripleArrowEncoded, escapeHtml } from "../utils" import { HtmlRendererOptions, preOpenerFromRenderingOptsWithExtras } from "./plain" // OK, so - this is just straight up complex code. @@ -22,7 +23,7 @@ import { HtmlRendererOptions, preOpenerFromRenderingOptsWithExtras } from "./pla // - the DOM requires a flattened graph of html elements (e.g. spans can' be interspersed) // -export function twoslashRenderer(lines: Lines, options: HtmlRendererOptions, twoslash: TwoSlash, codefenceMeta: any) { +export function twoslashRenderer(lines: Lines, options: HtmlRendererOptions & TwoslashShikiOptions, twoslash: TwoSlash, codefenceMeta: any) { let html = "" const hasHighlight = shouldBeHighlightable(codefenceMeta) @@ -113,12 +114,12 @@ export function twoslashRenderer(lines: Lines, options: HtmlRendererOptions, two if ("kind" in token) range.classes = token.kind if ("targetString" in token) { range.classes = "lsp" - range["lsp"] = stripHTML(token.text) + range["lsp"] = token.text } return range }) - tokenContent += createHighlightedString2(ranges, token.content, targetedQueryWord?.text) + tokenContent += createHighlightedString(ranges, token.content, targetedQueryWord?.text) } else { tokenContent += subTripleArrow(token.content) } @@ -184,9 +185,15 @@ export function twoslashRenderer(lines: Lines, options: HtmlRendererOptions, two } }) html = replaceTripleArrowEncoded(html.replace(/\n*$/, "")) // Get rid of final new lines - const playgroundLink = `Try` - html += `${playgroundLink}` + + if (options.addTryButton) { + const playgroundLink = `Try` + html += `${playgroundLink}` + } else { + html += `` + } + html += `` return html } diff --git a/packages/shiki-twoslash/src/utils.ts b/packages/shiki-twoslash/src/utils.ts index 5bf3d75..0faa3e6 100644 --- a/packages/shiki-twoslash/src/utils.ts +++ b/packages/shiki-twoslash/src/utils.ts @@ -15,7 +15,7 @@ const splice = (str: string, idx: number, rem: number, newString: string) => * We're given the text which lives inside the token, and this function will * annotate it with twoslash metadata */ -export function createHighlightedString2(ranges: Range[], text: string, targetedWord: string = "") { +export function createHighlightedString(ranges: Range[], text: string, targetedWord: string = "") { const actions = [] as { text: string; index: number }[] let hasErrors = false @@ -27,9 +27,12 @@ export function createHighlightedString2(ranges: Range[], text: string, targeted ranges.forEach(r => { if (r.classes === "lsp") { + // console.log(ranges, text, targetedWord) + // The LSP response lives inside a dom attribute, which _can_ have < inside it, so switch them ahead of time. + const lsp = htmlAttrReplacer(r.lsp || "") const underLineTargetedWord = r.lsp === targetedWord ? "style=⇯border-bottom: solid 2px lightgrey;⇯" : "" actions.push({ text: "⇍/data-lsp⇏", index: r.end }) - actions.push({ text: `⇍data-lsp lsp=⇯${r.lsp || ""}⇯ ${underLineTargetedWord}⇏`, index: r.begin }) + actions.push({ text: `⇍data-lsp lsp=¿${lsp}¿ ${underLineTargetedWord}⇏`, index: r.begin }) } else if (r.classes === "err") { hasErrors = true } else if (r.classes === "query") { @@ -49,11 +52,16 @@ export function createHighlightedString2(ranges: Range[], text: string, targeted if (hasErrors) html = `⇍data-err⇏${html}⇍/data-err⇏` - return replaceTripleArrow(stripHTML(html)) + return htmlAttrUnReplacer(replaceTripleArrow(stripHTML(html))) } +// HTML attributes have different rules, +const htmlAttrReplacer = (str: string) => str.replace(/"/g, "⃟") +const htmlAttrUnReplacer = (str: string) => str.replace(/⃟/g, '"') + +// Inline strings which are shown at HTML level export const subTripleArrow = (str: string) => str.replace(//g, "⇏").replace(/'/g, "⇯") -export const replaceTripleArrow = (str: string) => str.replace(/⇍/g, "<").replace(/⇏/g, ">").replace(/⇯/g, "'") +export const replaceTripleArrow = (str: string) => str.replace(/⇍/g, "<").replace(/⇏/g, ">").replace(/⇯/g, "'").replace(/¿/g, "'") export const replaceTripleArrowEncoded = (str: string) => str.replace(/⇍/g, "<").replace(/⇏/g, ">").replace(/⇯/g, "'") diff --git a/packages/shiki-twoslash/style.css b/packages/shiki-twoslash/style.css new file mode 100644 index 0000000..6518bd2 --- /dev/null +++ b/packages/shiki-twoslash/style.css @@ -0,0 +1,242 @@ +/* Start of Shiki Twoslash CSS + +Code blocks look like: + +
+  
+ [the code as a series of spans] + Try (optional) +
+
+*/ + + +pre { + /* In theory shiki will overwrite these, but this is to make sure there are defaults regardless */ + background-color: white; + color: black; + + /* Give it some space to breathe */ + padding: 12px; + + /* All code samples get a grey border, twoslash ones get a different color */ + border-left: 1px solid #999; + border-bottom: 1px solid #999; + + margin-bottom: 3rem; + + /* Important to allow the code to move horizontally; */ + overflow-x: auto; + position: relative; +} + pre.shiki { + overflow-x: auto; +} + pre.shiki:hover .dim { + opacity: 1; +} + pre.shiki div.dim { + opacity: 0.5; +} + pre.shiki div.dim, pre.shiki div.highlight { + margin: 0; + padding: 0; +} + pre.shiki div.highlight { + opacity: 1; + background-color: #f1f8ff; +} + pre.shiki div.line { + min-height: 1rem; +} + +/* Visually differentiates twoslash code samples */ + pre.twoslash { + border-color: #719af4; +} + +/** When you mouse over the pre, show the underlines */ +pre.twoslash:hover data-lsp { + border-color: #747474; +} + +/** The tooltip-like which provides the LSP response */ +pre.twoslash data-lsp:hover::before { + content: attr(lsp); + position: absolute; + transform: translate(0, 1rem); + + background-color: #3f3f3f; + color: #fff; + text-align: left; + padding: 5px 8px; + border-radius: 2px; + font-family: "JetBrains Mono", Menlo, Monaco, Consolas, Courier New, monospace; + font-size: 14px; + white-space: pre-wrap; +} + +pre .code-container { + overflow: auto; +} +/* The try button */ + pre .code-container > a { + position: absolute; + right: 8px; + bottom: 8px; + border-radius: 4px; + border: 1px solid #719af4; + padding: 0 8px; + color: #719af4; + text-decoration: none; + opacity: 0; + transition-timing-function: ease; + transition: opacity 0.3s; +} +/* Respect no animations */ +@media (prefers-reduced-motion: reduce) { + pre .code-container > a { + transition: none; + } +} + pre .code-container > a:hover { + color: white; + background-color: #719af4; +} + pre .code-container:hover a { + opacity: 1; +} + + pre code { + font-size: 15px; + font-family: "JetBrains Mono", Menlo, Monaco, Consolas, Courier New, monospace;; + white-space: pre; + -webkit-overflow-scrolling: touch; +} + pre code a { + text-decoration: none; +} + pre data-err { + /* Extracted from VS Code */ + background: url("data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%206%203'%20enable-background%3D'new%200%200%206%203'%20height%3D'3'%20width%3D'6'%3E%3Cg%20fill%3D'%23c94824'%3E%3Cpolygon%20points%3D'5.5%2C0%202.5%2C3%201.1%2C3%204.1%2C0'%2F%3E%3Cpolygon%20points%3D'4%2C0%206%2C2%206%2C0.6%205.4%2C0'%2F%3E%3Cpolygon%20points%3D'0%2C2%201%2C3%202.4%2C3%200%2C0.6'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E") repeat-x bottom left; + padding-bottom: 3px; +} + pre .query { + margin-bottom: 10px; + color: #137998; + display: inline-block; +} + + /* In order to have the 'popped out' style design and to not break the layout + /* we need to place a fake and un-selectable copy of the error which _isn't_ broken out + /* behind the actual error message. + + /* This sections keeps both of those two in in sync */ + + pre .error, pre .error-behind { + margin-left: -14px; + margin-top: 8px; + margin-bottom: 4px; + padding: 6px; + padding-left: 14px; + width: calc(100% - 19px); + white-space: pre-wrap; + display: block; +} + pre .error { + position: absolute; + background-color: #fee; + border-left: 2px solid #bf1818; + /* Give the space to the error code */ + display: flex; + align-items: center; + color: black; +} + pre .error .code { + display: none; +} + pre .error-behind { + user-select: none; + color: #fee; +} +/* Queries */ + pre .arrow { + /* Transparent background */ + background-color: #eee; + position: relative; + top: -7px; + margin-left: 0.1rem; + /* Edges */ + border-left: 1px solid #eee; + border-top: 1px solid #eee; + transform: translateY(25%) rotate(45deg); + /* Size */ + height: 8px; + width: 8px; +} + pre .popover { + margin-bottom: 10px; + background-color: #eee; + display: inline-block; + padding: 0 0.5rem 0.3rem; + margin-top: 10px; + border-radius: 3px; +} +/* Completion */ + pre .inline-completions ul.dropdown { + display: inline-block; + position: absolute; + width: 240px; + background-color: gainsboro; + color: grey; + padding-top: 4px; + font-family: var(--code-font); + font-size: 0.8rem; + margin: 0; + padding: 0; + border-left: 4px solid #4b9edd; +} + pre .inline-completions ul.dropdown::before { + background-color: #4b9edd; + width: 2px; + position: absolute; + top: -1.2rem; + left: -3px; + content: " "; +} + pre .inline-completions ul.dropdown li { + overflow-x: hidden; + padding-left: 4px; + margin-bottom: 4px; +} + pre .inline-completions ul.dropdown li.deprecated { + text-decoration: line-through; +} + pre .inline-completions ul.dropdown li span.result-found { + color: #4b9edd; +} + pre .inline-completions ul.dropdown li span.result { + width: 100px; + color: black; + display: inline-block; +} + .dark-theme .markdown pre { + background-color: #d8d8d8; + border-color: #ddd; + filter: invert(98%) hue-rotate(180deg); +} + data-lsp { + /* Ensures there's no 1px jump when the hover happens */ + border-bottom: 1px dotted transparent; + /* Fades in unobtrusively */ + transition-timing-function: ease; + transition: border-color 0.3s; +} +/* Respect people's wishes to not have animations */ + @media (prefers-reduced-motion: reduce) { + data-lsp { + transition: none; + } +} + diff --git a/packages/shiki-twoslash/test/createHighlightedString.test.ts b/packages/shiki-twoslash/test/createHighlightedString.test.ts new file mode 100644 index 0000000..f8f0fe0 --- /dev/null +++ b/packages/shiki-twoslash/test/createHighlightedString.test.ts @@ -0,0 +1,36 @@ +import { createHighlightedString } from "../src/utils" + +describe(createHighlightedString, () => { + it("handles passing the LSP info through in a way that the CSS renderer can understand", () => { + const result = createHighlightedString( + [ + { + begin: 0, + end: 7, + classes: "lsp", + lsp: "function longest(a: number[], b: number[]): number[]", + }, + ], + "longest" + ) + + expect(result).toMatchInlineSnapshot( + `"longest"` + ) + }) + + it("doesn't accidentally close through a string union", () => { + const result = createHighlightedString( + [ + { + begin: 0, + end: 5, + classes: "lsp", + lsp: 'const hello: "alice" | "bob"', + }, + ], + "hello" + ) + expect(result).toMatchInlineSnapshot(`"hello"`) + }) +}) diff --git a/packages/shiki-twoslash/test/twoslash-renderer.test.ts b/packages/shiki-twoslash/test/twoslash-renderer.test.ts index fb268c1..c24e41a 100644 --- a/packages/shiki-twoslash/test/twoslash-renderer.test.ts +++ b/packages/shiki-twoslash/test/twoslash-renderer.test.ts @@ -138,12 +138,10 @@ it("handles multi-line queries with comments", async () => { const twoslash = runTwoSlash(file, "ts", {}) const html = renderCodeToHTML(twoslash.code, "ts", ["twoslash"], {}, highlighter, twoslash) - expect(html).toMatchInlineSnapshot(` - "
function f() {
return { x: 10, y: 3 };
}
type P = ReturnType<typeof f>;
type P = { - x: number; - y: number; - }
Try
" - `) + expect(html).toContain(`type P = { + x: number; + y: number; +}`) }) it("it has the right ", async () => { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d4f45fe..9a940b0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,16 +5,18 @@ importers: .: specifiers: '@types/jest': ^25.2.3 - esbuild: ^0.12.3 + esbuild: ^0.12.6 esbuild-jest: ^0.5.0 - jest: ^27.0.1 + jest: ^27.0.4 + markdown-magic: ^2.0.0 pleb: ^3.4.3 - typescript: ^4.2.4 + typescript: ^4.3.2 devDependencies: '@types/jest': 25.2.3 - esbuild: 0.12.5 - esbuild-jest: 0.5.0_esbuild@0.12.5 - jest: 27.0.1 + esbuild: 0.12.6 + esbuild-jest: 0.5.0_esbuild@0.12.6 + jest: 27.0.4 + markdown-magic: 2.0.0 pleb: 3.4.3 typescript: 4.3.2 @@ -1472,15 +1474,15 @@ packages: slash: 3.0.0 dev: true - /@jest/console/27.0.1: - resolution: {integrity: sha512-50E6nN2F5cAXn1lDljn0gE9F0WFXHYz/u0EeR7sOt4nbRPNli34ckbl6CUDaDABJbHt62DYnyQAIB3KgdzwKDw==} + /@jest/console/27.0.2: + resolution: {integrity: sha512-/zYigssuHLImGeMAACkjI4VLAiiJznHgAl3xnFT19iWyct2LhrH3KXOjHRmxBGTkiPLZKKAJAgaPpiU9EZ9K+w==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@jest/types': 27.0.1 - '@types/node': 15.6.1 + '@jest/types': 27.0.2 + '@types/node': 15.12.2 chalk: 4.1.1 - jest-message-util: 27.0.1 - jest-util: 27.0.1 + jest-message-util: 27.0.2 + jest-util: 27.0.2 slash: 3.0.0 dev: true @@ -1523,8 +1525,8 @@ packages: - utf-8-validate dev: true - /@jest/core/27.0.1: - resolution: {integrity: sha512-PiCbKSMf6t8PEfY3MAd0Ldn3aJAt5T+UcaFkAfMZ1VZgas35+fXk5uHIjAQHQLNIHZWX19TLv0wWNT03yvrw6w==} + /@jest/core/27.0.4: + resolution: {integrity: sha512-+dsmV8VUs1h/Szb+rEWk8xBM1fp1I///uFy9nk3wXGvRsF2lBp8EVPmtWc+QFRb3MY2b7u2HbkGF1fzoDzQTLA==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 @@ -1532,30 +1534,30 @@ packages: node-notifier: optional: true dependencies: - '@jest/console': 27.0.1 - '@jest/reporters': 27.0.1 - '@jest/test-result': 27.0.1 - '@jest/transform': 27.0.1 - '@jest/types': 27.0.1 - '@types/node': 15.6.1 + '@jest/console': 27.0.2 + '@jest/reporters': 27.0.4 + '@jest/test-result': 27.0.2 + '@jest/transform': 27.0.2 + '@jest/types': 27.0.2 + '@types/node': 15.12.2 ansi-escapes: 4.3.2 chalk: 4.1.1 emittery: 0.8.1 exit: 0.1.2 graceful-fs: 4.2.6 - jest-changed-files: 27.0.1 - jest-config: 27.0.1 - jest-haste-map: 27.0.1 - jest-message-util: 27.0.1 + jest-changed-files: 27.0.2 + jest-config: 27.0.4 + jest-haste-map: 27.0.2 + jest-message-util: 27.0.2 jest-regex-util: 27.0.1 - jest-resolve: 27.0.1 - jest-resolve-dependencies: 27.0.1 - jest-runner: 27.0.1 - jest-runtime: 27.0.1 - jest-snapshot: 27.0.1 - jest-util: 27.0.1 - jest-validate: 27.0.1 - jest-watcher: 27.0.1 + jest-resolve: 27.0.4 + jest-resolve-dependencies: 27.0.4 + jest-runner: 27.0.4 + jest-runtime: 27.0.4 + jest-snapshot: 27.0.4 + jest-util: 27.0.2 + jest-validate: 27.0.2 + jest-watcher: 27.0.2 micromatch: 4.0.4 p-each-series: 2.2.0 rimraf: 3.0.2 @@ -1578,14 +1580,14 @@ packages: jest-mock: 25.5.0 dev: true - /@jest/environment/27.0.1: - resolution: {integrity: sha512-nG+r3uSs2pOTsdhgt6lUm4ZGJLRcTc6HZIkrFsVpPcdSqEpJehEny9r9y2Bmhkn8fKXWdGCYJKF3i4nKO0HSmA==} + /@jest/environment/27.0.3: + resolution: {integrity: sha512-pN9m7fbKsop5vc3FOfH8NF7CKKdRbEZzcxfIo1n2TT6ucKWLFq0P6gCJH0GpnQp036++yY9utHOxpeT1WnkWTA==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@jest/fake-timers': 27.0.1 - '@jest/types': 27.0.1 - '@types/node': 15.6.1 - jest-mock: 27.0.1 + '@jest/fake-timers': 27.0.3 + '@jest/types': 27.0.2 + '@types/node': 15.12.2 + jest-mock: 27.0.3 dev: true /@jest/fake-timers/25.5.0: @@ -1599,16 +1601,16 @@ packages: lolex: 5.1.2 dev: true - /@jest/fake-timers/27.0.1: - resolution: {integrity: sha512-3CyLJQnHzKI4TCJSCo+I9TzIHjSK4RrNEk93jFM6Q9+9WlSJ3mpMq/p2YuKMe0SiHKbmZOd5G/Ll5ofF9Xkw9g==} + /@jest/fake-timers/27.0.3: + resolution: {integrity: sha512-fQ+UCKRIYKvTCEOyKPnaPnomLATIhMnHC/xPZ7yT1Uldp7yMgMxoYIFidDbpSTgB79+/U+FgfoD30c6wg3IUjA==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@jest/types': 27.0.1 + '@jest/types': 27.0.2 '@sinonjs/fake-timers': 7.1.2 - '@types/node': 15.6.1 - jest-message-util: 27.0.1 - jest-mock: 27.0.1 - jest-util: 27.0.1 + '@types/node': 15.12.2 + jest-message-util: 27.0.2 + jest-mock: 27.0.3 + jest-util: 27.0.2 dev: true /@jest/globals/25.5.2: @@ -1620,13 +1622,13 @@ packages: expect: 25.5.0 dev: true - /@jest/globals/27.0.1: - resolution: {integrity: sha512-80ZCzgopysKdpp5EOglgjApKxiNDR96PG4PwngB4fTwZ4qqqSKo0EwGwQIhl16szQ1M2xCVYmr9J6KelvnABNQ==} + /@jest/globals/27.0.3: + resolution: {integrity: sha512-OzsIuf7uf+QalqAGbjClyezzEcLQkdZ+7PejUrZgDs+okdAK8GwRCGcYCirHvhMBBQh60Jr3NlIGbn/KBPQLEQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@jest/environment': 27.0.1 - '@jest/types': 27.0.1 - expect: 27.0.1 + '@jest/environment': 27.0.3 + '@jest/types': 27.0.2 + expect: 27.0.2 dev: true /@jest/reporters/25.5.1: @@ -1663,8 +1665,8 @@ packages: - supports-color dev: true - /@jest/reporters/27.0.1: - resolution: {integrity: sha512-lZbJWuS1h/ytKERfu1D6tEQ4PuQ7+15S4+HrSzHR0i7AGVT1WRo49h4fZqxASOp7AQCupUVtPJNZDkaG9ZXy0g==} + /@jest/reporters/27.0.4: + resolution: {integrity: sha512-Xa90Nm3JnV0xCe4M6A10M9WuN9krb+WFKxV1A98Y4ePCw40n++r7uxFUNU7DT1i9Behj7fjrAIju9oU0t1QtCg==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 @@ -1673,10 +1675,10 @@ packages: optional: true dependencies: '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 27.0.1 - '@jest/test-result': 27.0.1 - '@jest/transform': 27.0.1 - '@jest/types': 27.0.1 + '@jest/console': 27.0.2 + '@jest/test-result': 27.0.2 + '@jest/transform': 27.0.2 + '@jest/types': 27.0.2 chalk: 4.1.1 collect-v8-coverage: 1.0.1 exit: 0.1.2 @@ -1687,10 +1689,10 @@ packages: istanbul-lib-report: 3.0.0 istanbul-lib-source-maps: 4.0.0 istanbul-reports: 3.0.2 - jest-haste-map: 27.0.1 - jest-resolve: 27.0.1 - jest-util: 27.0.1 - jest-worker: 27.0.1 + jest-haste-map: 27.0.2 + jest-resolve: 27.0.4 + jest-util: 27.0.2 + jest-worker: 27.0.2 slash: 3.0.0 source-map: 0.6.1 string-length: 4.0.2 @@ -1728,12 +1730,12 @@ packages: collect-v8-coverage: 1.0.1 dev: true - /@jest/test-result/27.0.1: - resolution: {integrity: sha512-5aa+ibX2dsGSDLKaQMZb453MqjJU/CRVumebXfaJmuzuGE4qf87yQ2QZ6PEpEtBwVUEgrJCzi3jLCRaUbksSuw==} + /@jest/test-result/27.0.2: + resolution: {integrity: sha512-gcdWwL3yP5VaIadzwQtbZyZMgpmes8ryBAJp70tuxghiA8qL4imJyZex+i+USQH2H4jeLVVszhwntgdQ97fccA==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@jest/console': 27.0.1 - '@jest/types': 27.0.1 + '@jest/console': 27.0.2 + '@jest/types': 27.0.2 '@types/istanbul-lib-coverage': 2.0.3 collect-v8-coverage: 1.0.1 dev: true @@ -1754,21 +1756,16 @@ packages: - utf-8-validate dev: true - /@jest/test-sequencer/27.0.1: - resolution: {integrity: sha512-yK2c2iruJ35WgH4KH8whS72uH+FASJUrzwxzNKTzLAEWmNpWKNEPOsSEKsHynvz78bLHafrTg4adN7RrYNbEOA==} + /@jest/test-sequencer/27.0.4: + resolution: {integrity: sha512-6UFEVwdmxYdyNffBxVVZxmXEdBE4riSddXYSnFNH0ELFQFk/bvagizim8WfgJTqF4EKd+j1yFxvhb8BMHfOjSQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@jest/test-result': 27.0.1 + '@jest/test-result': 27.0.2 graceful-fs: 4.2.6 - jest-haste-map: 27.0.1 - jest-runner: 27.0.1 - jest-runtime: 27.0.1 + jest-haste-map: 27.0.2 + jest-runtime: 27.0.4 transitivePeerDependencies: - - bufferutil - - canvas - supports-color - - ts-node - - utf-8-validate dev: true /@jest/transform/25.5.1: @@ -1818,20 +1815,20 @@ packages: - supports-color dev: true - /@jest/transform/27.0.1: - resolution: {integrity: sha512-LC95VpT6wMnQ96dRJDlUiAnW/90zyh4+jS30szI/5AsfS0qwSlr/O4TPcGoD2WVaVMfo6KvR+brvOtGyMHaNhA==} + /@jest/transform/27.0.2: + resolution: {integrity: sha512-H8sqKlgtDfVog/s9I4GG2XMbi4Ar7RBxjsKQDUhn2XHAi3NG+GoQwWMER+YfantzExbjNqQvqBHzo/G2pfTiPw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: '@babel/core': 7.14.3 - '@jest/types': 27.0.1 + '@jest/types': 27.0.2 babel-plugin-istanbul: 6.0.0 chalk: 4.1.1 convert-source-map: 1.7.0 fast-json-stable-stringify: 2.1.0 graceful-fs: 4.2.6 - jest-haste-map: 27.0.1 + jest-haste-map: 27.0.2 jest-regex-util: 27.0.1 - jest-util: 27.0.1 + jest-util: 27.0.2 micromatch: 4.0.4 pirates: 4.0.1 slash: 3.0.0 @@ -1856,19 +1853,19 @@ packages: engines: {node: '>= 10.14.2'} dependencies: '@types/istanbul-lib-coverage': 2.0.3 - '@types/istanbul-reports': 3.0.0 - '@types/node': 15.6.1 + '@types/istanbul-reports': 3.0.1 + '@types/node': 15.12.2 '@types/yargs': 15.0.13 chalk: 4.1.1 dev: true - /@jest/types/27.0.1: - resolution: {integrity: sha512-8A25RRV4twZutsx2D+7WphnDsp7If9Yu6ko0Gxwrwv8BiWESFzka34+Aa2kC8w9xewt7SDuCUSZ6IiAFVj3PRg==} + /@jest/types/27.0.2: + resolution: {integrity: sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: '@types/istanbul-lib-coverage': 2.0.3 - '@types/istanbul-reports': 3.0.0 - '@types/node': 15.6.1 + '@types/istanbul-reports': 3.0.1 + '@types/node': 15.12.2 '@types/yargs': 16.0.3 chalk: 4.1.1 dev: true @@ -2047,7 +2044,7 @@ packages: /@types/graceful-fs/4.1.5: resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==} dependencies: - '@types/node': 15.6.1 + '@types/node': 15.12.2 dev: true /@types/hast/2.3.1: @@ -2077,8 +2074,8 @@ packages: '@types/istanbul-lib-report': 3.0.0 dev: true - /@types/istanbul-reports/3.0.0: - resolution: {integrity: sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==} + /@types/istanbul-reports/3.0.1: + resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} dependencies: '@types/istanbul-lib-report': 3.0.0 dev: true @@ -2123,6 +2120,10 @@ packages: resolution: {integrity: sha512-/tpUyFD7meeooTRwl3sYlihx2BrJE7q9XF71EguPFIySj9B7qgnRtHsHTho+0AUm4m1SvWGm6uSncrR94q6Vtw==} dev: true + /@types/node/15.12.2: + resolution: {integrity: sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww==} + dev: true + /@types/node/15.6.1: resolution: {integrity: sha512-7EIraBEyRHEe7CH+Fm1XvgqU6uwZN8Q7jppJGcqjROMT29qhAuuOxYB1uEY5UMYQKEmA5D+5tBnhdaPXSsLONA==} dev: true @@ -2325,8 +2326,8 @@ packages: hasBin: true dev: true - /acorn/8.2.4: - resolution: {integrity: sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg==} + /acorn/8.3.0: + resolution: {integrity: sha512-tqPKHZ5CaBJw0Xmy0ZZvLs1qTV+BNFSyvn77ASXkpBNfIRk8ev26fKrD9iLGwGA9zedPao52GSHzq8lyZG0NUw==} engines: {node: '>=0.4.0'} hasBin: true dev: true @@ -2366,6 +2367,13 @@ packages: type-fest: 0.21.3 dev: true + /ansi-red/0.1.1: + resolution: {integrity: sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=} + engines: {node: '>=0.10.0'} + dependencies: + ansi-wrap: 0.1.0 + dev: true + /ansi-regex/3.0.0: resolution: {integrity: sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=} engines: {node: '>=4'} @@ -2400,6 +2408,11 @@ packages: engines: {node: '>=10'} dev: true + /ansi-wrap/0.1.0: + resolution: {integrity: sha1-qCJQ3bABXponyoLoLqYDu/pF768=} + engines: {node: '>=0.10.0'} + dev: true + /anymatch/2.0.0: resolution: {integrity: sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==} dependencies: @@ -2463,6 +2476,18 @@ packages: is-string: 1.0.6 dev: true + /array-union/1.0.2: + resolution: {integrity: sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=} + engines: {node: '>=0.10.0'} + dependencies: + array-uniq: 1.0.3 + dev: true + + /array-uniq/1.0.3: + resolution: {integrity: sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=} + engines: {node: '>=0.10.0'} + dev: true + /array-unique/0.3.2: resolution: {integrity: sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=} engines: {node: '>=0.10.0'} @@ -2487,6 +2512,10 @@ packages: function-bind: 1.1.1 dev: true + /asap/2.0.6: + resolution: {integrity: sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=} + dev: true + /asn1/0.2.4: resolution: {integrity: sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==} dependencies: @@ -2531,6 +2560,12 @@ packages: hasBin: true dev: true + /autolinker/0.28.1: + resolution: {integrity: sha1-BlK0kYgYefB3XazgzcoyM5QqTkc=} + dependencies: + gulp-header: 1.8.12 + dev: true + /aws-sign2/0.7.0: resolution: {integrity: sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=} dev: true @@ -2622,15 +2657,15 @@ packages: - supports-color dev: true - /babel-jest/27.0.1_@babel+core@7.14.3: - resolution: {integrity: sha512-aWFD7OGQjk3Y8MdZKf1XePlQvHnjMVJQjIq9WKrlAjz9by703kJ45Jxhp26JwnovoW71YYz5etuqRl8wMcIv0w==} + /babel-jest/27.0.2_@babel+core@7.14.3: + resolution: {integrity: sha512-9OThPl3/IQbo4Yul2vMz4FYwILPQak8XelX4YGowygfHaOl5R5gfjm4iVx4d8aUugkW683t8aq0A74E7b5DU1Q==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} peerDependencies: '@babel/core': ^7.8.0 dependencies: '@babel/core': 7.14.3 - '@jest/transform': 27.0.1 - '@jest/types': 27.0.1 + '@jest/transform': 27.0.2 + '@jest/types': 27.0.2 '@types/babel__core': 7.1.14 babel-plugin-istanbul: 6.0.0 babel-preset-jest: 27.0.1_@babel+core@7.14.3 @@ -2958,11 +2993,11 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001230 + caniuse-lite: 1.0.30001235 colorette: 1.2.2 - electron-to-chromium: 1.3.742 + electron-to-chromium: 1.3.749 escalade: 3.1.1 - node-releases: 1.1.72 + node-releases: 1.1.73 dev: true /bs-logger/0.2.6: @@ -3029,8 +3064,8 @@ packages: engines: {node: '>=10'} dev: true - /caniuse-lite/1.0.30001230: - resolution: {integrity: sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==} + /caniuse-lite/1.0.30001235: + resolution: {integrity: sha512-zWEwIVqnzPkSAXOUlQnPW2oKoYb2aLQ4Q5ejdjBcnH63rfypaW34CxaeBn1VMya2XaEU3P/R2qHpWyj+l0BT1A==} dev: true /capture-exit/2.0.0: @@ -3040,6 +3075,10 @@ packages: rsvp: 4.8.5 dev: true + /caseless/0.11.0: + resolution: {integrity: sha1-cVuW6phBWTzDMGeSP17GDr2k99c=} + dev: true + /caseless/0.12.0: resolution: {integrity: sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=} dev: true @@ -3170,6 +3209,13 @@ packages: engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} dev: true + /coffee-script/1.12.7: + resolution: {integrity: sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==} + engines: {node: '>=0.8.0'} + deprecated: CoffeeScript on NPM has moved to "coffeescript" (no hyphen) + hasBin: true + dev: true + /collapse-white-space/1.0.6: resolution: {integrity: sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==} dev: true @@ -3241,6 +3287,22 @@ packages: resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} dev: true + /concat-stream/1.6.2: + resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} + engines: {'0': node >= 0.8} + dependencies: + buffer-from: 1.1.1 + inherits: 2.0.4 + readable-stream: 2.3.7 + typedarray: 0.0.6 + dev: true + + /concat-with-sourcemaps/1.1.0: + resolution: {integrity: sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==} + dependencies: + source-map: 0.6.1 + dev: true + /confusing-browser-globals/1.0.10: resolution: {integrity: sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA==} dev: true @@ -3468,6 +3530,11 @@ packages: engines: {node: '>=8'} dev: true + /diacritics-map/0.1.0: + resolution: {integrity: sha1-bfwP+dAQAKLt8oZTccrDFulJd68=} + engines: {node: '>=0.8.0'} + dev: true + /diff-sequences/25.2.6: resolution: {integrity: sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==} engines: {node: '>= 8.3'} @@ -3517,8 +3584,8 @@ packages: safer-buffer: 2.1.2 dev: true - /electron-to-chromium/1.3.742: - resolution: {integrity: sha512-ihL14knI9FikJmH2XUIDdZFWJxvr14rPSdOhJ7PpS27xbz8qmaRwCwyg/bmFwjWKmWK9QyamiCZVCvXm5CH//Q==} + /electron-to-chromium/1.3.749: + resolution: {integrity: sha512-F+v2zxZgw/fMwPz/VUGIggG4ZndDsYy0vlpthi3tjmDZlcfbhN5mYW0evXUsBr2sUtuDANFtle410A9u/sd/4A==} dev: true /emittery/0.8.1: @@ -3592,7 +3659,7 @@ packages: is-symbol: 1.0.4 dev: true - /esbuild-jest/0.5.0_esbuild@0.12.5: + /esbuild-jest/0.5.0_esbuild@0.12.6: resolution: {integrity: sha512-AMZZCdEpXfNVOIDvURlqYyHwC8qC1/BFjgsrOiSL1eyiIArVtHL8YAC83Shhn16cYYoAWEW17yZn0W/RJKJKHQ==} peerDependencies: esbuild: '>=0.8.50' @@ -3600,13 +3667,13 @@ packages: '@babel/core': 7.14.3 '@babel/plugin-transform-modules-commonjs': 7.14.0_@babel+core@7.14.3 babel-jest: 26.6.3_@babel+core@7.14.3 - esbuild: 0.12.5 + esbuild: 0.12.6 transitivePeerDependencies: - supports-color dev: true - /esbuild/0.12.5: - resolution: {integrity: sha512-vcuP53pA5XiwUU4FnlXM+2PnVjTfHGthM7uP1gtp+9yfheGvFFbq/KyuESThmtoHPUrfZH5JpxGVJIFDVD1Egw==} + /esbuild/0.12.6: + resolution: {integrity: sha512-RDvVLvAjsq/kIZJoneMiUOH7EE7t2QaW7T3Q7EdQij14+bZbDq5sndb0tTanmHIFSqZVMBMMyqzVHkS3dJobeA==} hasBin: true requiresBuild: true dev: true @@ -3980,8 +4047,8 @@ packages: strip-final-newline: 2.0.0 dev: true - /execa/5.0.0: - resolution: {integrity: sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==} + /execa/5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} dependencies: cross-spawn: 7.0.3 @@ -4013,6 +4080,13 @@ packages: to-regex: 3.0.2 dev: true + /expand-range/1.8.2: + resolution: {integrity: sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=} + engines: {node: '>=0.10.0'} + dependencies: + fill-range: 2.2.4 + dev: true + /expect/25.5.0: resolution: {integrity: sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA==} engines: {node: '>= 8.3'} @@ -4025,15 +4099,15 @@ packages: jest-regex-util: 25.2.6 dev: true - /expect/27.0.1: - resolution: {integrity: sha512-hjKwLeAvKUiq0Plha1dmzOH1FGEwJC9njbT993cq4PK9r58/+3NM+WDqFVGcPuRH7XTjmbIeHQBzp2faDrPhjQ==} + /expect/27.0.2: + resolution: {integrity: sha512-YJFNJe2+P2DqH+ZrXy+ydRQYO87oxRUonZImpDodR1G7qo3NYd3pL+NQ9Keqpez3cehczYwZDBC3A7xk3n7M/w==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@jest/types': 27.0.1 + '@jest/types': 27.0.2 ansi-styles: 5.2.0 jest-get-type: 27.0.1 - jest-matcher-utils: 27.0.1 - jest-message-util: 27.0.1 + jest-matcher-utils: 27.0.2 + jest-message-util: 27.0.2 jest-regex-util: 27.0.1 dev: true @@ -4137,6 +4211,17 @@ packages: trim-repeated: 1.0.0 dev: true + /fill-range/2.2.4: + resolution: {integrity: sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==} + engines: {node: '>=0.10.0'} + dependencies: + is-number: 2.1.0 + isobject: 2.1.0 + randomatic: 3.1.1 + repeat-element: 1.1.4 + repeat-string: 1.6.1 + dev: true + /fill-range/4.0.0: resolution: {integrity: sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=} engines: {node: '>=0.10.0'} @@ -4223,7 +4308,7 @@ packages: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 - mime-types: 2.1.30 + mime-types: 2.1.31 dev: true /fragment-cache/0.2.1: @@ -4363,6 +4448,17 @@ packages: resolution: {integrity: sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==} dev: true + /globby/6.1.0: + resolution: {integrity: sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=} + engines: {node: '>=0.10.0'} + dependencies: + array-union: 1.0.2 + glob: 7.1.7 + object-assign: 4.1.1 + pify: 2.3.0 + pinkie-promise: 2.0.1 + dev: true + /globrex/0.1.2: resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} dev: true @@ -4371,6 +4467,17 @@ packages: resolution: {integrity: sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==} dev: true + /gray-matter/2.1.1: + resolution: {integrity: sha1-MELZrewqHe1qdwep7SOA+KF6Qw4=} + engines: {node: '>=0.10.0'} + dependencies: + ansi-red: 0.1.1 + coffee-script: 1.12.7 + extend-shallow: 2.0.1 + js-yaml: 3.14.1 + toml: 2.3.6 + dev: true + /gray-matter/4.0.3: resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} engines: {node: '>=6.0'} @@ -4386,6 +4493,15 @@ packages: dev: true optional: true + /gulp-header/1.8.12: + resolution: {integrity: sha512-lh9HLdb53sC7XIZOYzTXM4lFuXElv3EVkSDhsd7DoJBj7hm+Ni7D3qYbb+Rr8DuM8nRanBvkVO9d7askreXGnQ==} + deprecated: Removed event-stream from gulp-header + dependencies: + concat-with-sourcemaps: 1.1.0 + lodash.template: 4.5.0 + through2: 2.0.5 + dev: true + /har-schema/2.0.0: resolution: {integrity: sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=} engines: {node: '>=4'} @@ -4579,6 +4695,14 @@ packages: /html-void-elements/1.0.5: resolution: {integrity: sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==} + /http-basic/2.5.1: + resolution: {integrity: sha1-jORHvbW2xXf4pj4/p4BW7Eu02/s=} + dependencies: + caseless: 0.11.0 + concat-stream: 1.6.2 + http-response-object: 1.1.0 + dev: true + /http-proxy-agent/4.0.1: resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==} engines: {node: '>= 6'} @@ -4590,6 +4714,10 @@ packages: - supports-color dev: true + /http-response-object/1.1.0: + resolution: {integrity: sha1-p8TnWq6C87tJBOT0P2FWc7TVGMM=} + dev: true + /http-signature/1.2.0: resolution: {integrity: sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=} engines: {node: '>=0.8', npm: '>=1.3.7'} @@ -4875,6 +5003,10 @@ packages: engines: {node: '>=8'} dev: true + /is-local-path/0.1.6: + resolution: {integrity: sha1-gV0USxTVac7L6tTVaTCX8Aqb9sU=} + dev: true + /is-module/1.0.0: resolution: {integrity: sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=} dev: true @@ -4889,6 +5021,13 @@ packages: engines: {node: '>= 0.4'} dev: true + /is-number/2.1.0: + resolution: {integrity: sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 3.2.2 + dev: true + /is-number/3.0.0: resolution: {integrity: sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=} engines: {node: '>=0.10.0'} @@ -4896,6 +5035,11 @@ packages: kind-of: 3.2.2 dev: true + /is-number/4.0.0: + resolution: {integrity: sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==} + engines: {node: '>=0.10.0'} + dev: true + /is-number/7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -5055,44 +5199,40 @@ packages: throat: 5.0.0 dev: true - /jest-changed-files/27.0.1: - resolution: {integrity: sha512-Y/4AnqYNcUX/vVgfkmvSA3t7rcg+t8m3CsSGlU+ra8kjlVW5ZqXcBZY/NUew2Mo8M+dn0ApKl+FmGGT1JV5dVA==} + /jest-changed-files/27.0.2: + resolution: {integrity: sha512-eMeb1Pn7w7x3wue5/vF73LPCJ7DKQuC9wQUR5ebP9hDPpk5hzcT/3Hmz3Q5BOFpR3tgbmaWhJcMTVgC8Z1NuMw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@jest/types': 27.0.1 - execa: 5.0.0 + '@jest/types': 27.0.2 + execa: 5.1.1 throat: 6.0.1 dev: true - /jest-circus/27.0.1: - resolution: {integrity: sha512-Tz3ytmrsgxWlTwSyPYb8StF9J2IMjLlbBMKAjhL2UU9/0ZpYb2JiEGjXaAhnGauQRbbpyFbSH3yj5HIbdurmwQ==} + /jest-circus/27.0.4: + resolution: {integrity: sha512-QD+eblDiRphta630WRKewuASLs/oY1Zki2G4bccntRvrTHQ63ljwFR5TLduuK4Zg0ZPzW0+8o6AP7KRd1yKOjw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@jest/environment': 27.0.1 - '@jest/test-result': 27.0.1 - '@jest/types': 27.0.1 - '@types/node': 15.6.1 + '@jest/environment': 27.0.3 + '@jest/test-result': 27.0.2 + '@jest/types': 27.0.2 + '@types/node': 15.12.2 chalk: 4.1.1 co: 4.6.0 dedent: 0.7.0 - expect: 27.0.1 + expect: 27.0.2 is-generator-fn: 2.1.0 - jest-each: 27.0.1 - jest-matcher-utils: 27.0.1 - jest-message-util: 27.0.1 - jest-runner: 27.0.1 - jest-runtime: 27.0.1 - jest-snapshot: 27.0.1 - jest-util: 27.0.1 - pretty-format: 27.0.1 + jest-each: 27.0.2 + jest-matcher-utils: 27.0.2 + jest-message-util: 27.0.2 + jest-runtime: 27.0.4 + jest-snapshot: 27.0.4 + jest-util: 27.0.2 + pretty-format: 27.0.2 + slash: 3.0.0 stack-utils: 2.0.3 throat: 6.0.1 transitivePeerDependencies: - - bufferutil - - canvas - supports-color - - ts-node - - utf-8-validate dev: true /jest-cli/25.5.4: @@ -5121,8 +5261,8 @@ packages: - utf-8-validate dev: true - /jest-cli/27.0.1: - resolution: {integrity: sha512-plDsQQwpkKK1SZ5L5xqMa7v/sTwB5LTIeSJqb+cV+4EMlThdUQfg8jwMfHX8jHuUc9TPGLcdoZeBuZcGGn3Rlg==} + /jest-cli/27.0.4: + resolution: {integrity: sha512-E0T+/i2lxsWAzV7LKYd0SB7HUAvePqaeIh5vX43/G5jXLhv1VzjYzJAGEkTfvxV774ll9cyE2ljcL73PVMEOXQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} hasBin: true peerDependencies: @@ -5131,16 +5271,16 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 27.0.1 - '@jest/test-result': 27.0.1 - '@jest/types': 27.0.1 + '@jest/core': 27.0.4 + '@jest/test-result': 27.0.2 + '@jest/types': 27.0.2 chalk: 4.1.1 exit: 0.1.2 graceful-fs: 4.2.6 import-local: 3.0.2 - jest-config: 27.0.1 - jest-util: 27.0.1 - jest-validate: 27.0.1 + jest-config: 27.0.4 + jest-util: 27.0.2 + jest-validate: 27.0.2 prompts: 2.4.1 yargs: 16.2.0 transitivePeerDependencies: @@ -5181,8 +5321,8 @@ packages: - utf-8-validate dev: true - /jest-config/27.0.1: - resolution: {integrity: sha512-V8O6+CZjGF0OMq4kxVR29ztV/LQqlAAcJLw7a94RndfRXkha4U84n50yZCXiPWtAHHTmb3g1y52US6rGPxA+3w==} + /jest-config/27.0.4: + resolution: {integrity: sha512-VkQFAHWnPQefdvHU9A+G3H/Z3NrrTKqWpvxgQz3nkUdkDTWeKJE6e//BL+R7z79dXOMVksYgM/z6ndtN0hfChg==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} peerDependencies: ts-node: '>=9.0.0' @@ -5191,25 +5331,26 @@ packages: optional: true dependencies: '@babel/core': 7.14.3 - '@jest/test-sequencer': 27.0.1 - '@jest/types': 27.0.1 - babel-jest: 27.0.1_@babel+core@7.14.3 + '@jest/test-sequencer': 27.0.4 + '@jest/types': 27.0.2 + babel-jest: 27.0.2_@babel+core@7.14.3 chalk: 4.1.1 deepmerge: 4.2.2 glob: 7.1.7 graceful-fs: 4.2.6 is-ci: 3.0.0 - jest-circus: 27.0.1 - jest-environment-jsdom: 27.0.1 - jest-environment-node: 27.0.1 + jest-circus: 27.0.4 + jest-environment-jsdom: 27.0.3 + jest-environment-node: 27.0.3 jest-get-type: 27.0.1 - jest-jasmine2: 27.0.1 + jest-jasmine2: 27.0.4 jest-regex-util: 27.0.1 - jest-resolve: 27.0.1 - jest-util: 27.0.1 - jest-validate: 27.0.1 + jest-resolve: 27.0.4 + jest-runner: 27.0.4 + jest-util: 27.0.2 + jest-validate: 27.0.2 micromatch: 4.0.4 - pretty-format: 27.0.1 + pretty-format: 27.0.2 transitivePeerDependencies: - bufferutil - canvas @@ -5237,14 +5378,14 @@ packages: pretty-format: 26.6.2 dev: true - /jest-diff/27.0.1: - resolution: {integrity: sha512-DQ3OgfJgoGWVTYo4qnYW/Jg5mpYFS2QW9BLxA8bs12ZRN1K8QPZtWeYvUPohQFs3CHX3JLTndGg3jyxdL5THFQ==} + /jest-diff/27.0.2: + resolution: {integrity: sha512-BFIdRb0LqfV1hBt8crQmw6gGQHVDhM87SpMIZ45FPYKReZYG5er1+5pIn2zKqvrJp6WNox0ylR8571Iwk2Dmgw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: chalk: 4.1.1 diff-sequences: 27.0.1 jest-get-type: 27.0.1 - pretty-format: 27.0.1 + pretty-format: 27.0.2 dev: true /jest-docblock/25.3.0: @@ -5272,15 +5413,15 @@ packages: pretty-format: 25.5.0 dev: true - /jest-each/27.0.1: - resolution: {integrity: sha512-uJTK/aZ05HsdKkfXucAT5+/1DIURnTRv34OSxn1HWHrD+xu9eDX5Xgds09QSvg/mU01VS5upuHTDKG3W+r0rQA==} + /jest-each/27.0.2: + resolution: {integrity: sha512-OLMBZBZ6JkoXgUenDtseFRWA43wVl2BwmZYIWQws7eS7pqsIvePqj/jJmEnfq91ALk3LNphgwNK/PRFBYi7ITQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@jest/types': 27.0.1 + '@jest/types': 27.0.2 chalk: 4.1.1 jest-get-type: 27.0.1 - jest-util: 27.0.1 - pretty-format: 27.0.1 + jest-util: 27.0.2 + pretty-format: 27.0.2 dev: true /jest-environment-jsdom/25.5.0: @@ -5299,16 +5440,16 @@ packages: - utf-8-validate dev: true - /jest-environment-jsdom/27.0.1: - resolution: {integrity: sha512-lesU8T9zkjgLaLpUFmFDgchu6/2OCoXm52nN6UumR063Hb+1TJdI7ihgM86+G01Ay86Lyr+K/FAR6yIIOviH3Q==} + /jest-environment-jsdom/27.0.3: + resolution: {integrity: sha512-5KLmgv1bhiimpSA8oGTnZYk6g4fsNyZiA/6gI2tAZUgrufd7heRUSVh4gRokzZVEj8zlwAQYT0Zs6tuJSW/ECA==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@jest/environment': 27.0.1 - '@jest/fake-timers': 27.0.1 - '@jest/types': 27.0.1 - '@types/node': 15.6.1 - jest-mock: 27.0.1 - jest-util: 27.0.1 + '@jest/environment': 27.0.3 + '@jest/fake-timers': 27.0.3 + '@jest/types': 27.0.2 + '@types/node': 15.12.2 + jest-mock: 27.0.3 + jest-util: 27.0.2 jsdom: 16.6.0 transitivePeerDependencies: - bufferutil @@ -5329,16 +5470,16 @@ packages: semver: 6.3.0 dev: true - /jest-environment-node/27.0.1: - resolution: {integrity: sha512-/p94lo0hx+hbKUw1opnRFUPPsjncRBEUU+2Dh7BuxX8Nr4rRiTivLYgXzo79FhaeMYV0uiV5WAbHBq6xC11JJg==} + /jest-environment-node/27.0.3: + resolution: {integrity: sha512-co2/IVnIFL3cItpFULCvXFg9us4gvWXgs7mutAMPCbFhcqh56QAOdKhNzC2+RycsC/k4mbMj1VF+9F/NzA0ROg==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@jest/environment': 27.0.1 - '@jest/fake-timers': 27.0.1 - '@jest/types': 27.0.1 - '@types/node': 15.6.1 - jest-mock: 27.0.1 - jest-util: 27.0.1 + '@jest/environment': 27.0.3 + '@jest/fake-timers': 27.0.3 + '@jest/types': 27.0.2 + '@types/node': 15.12.2 + jest-mock: 27.0.3 + jest-util: 27.0.2 dev: true /jest-file-snapshot/0.5.0: @@ -5391,7 +5532,7 @@ packages: dependencies: '@jest/types': 26.6.2 '@types/graceful-fs': 4.1.5 - '@types/node': 15.6.1 + '@types/node': 15.12.2 anymatch: 3.1.2 fb-watchman: 2.0.1 graceful-fs: 4.2.6 @@ -5406,20 +5547,20 @@ packages: fsevents: 2.3.2 dev: true - /jest-haste-map/27.0.1: - resolution: {integrity: sha512-ioCuobr4z90H1Pz8+apz2vfz63387apzAoawm/9IIOndarDfRkjLURdLOe//AI5jUQmjVRg+WiL92339kqlCmA==} + /jest-haste-map/27.0.2: + resolution: {integrity: sha512-37gYfrYjjhEfk37C4bCMWAC0oPBxDpG0qpl8lYg8BT//wf353YT/fzgA7+Dq0EtM7rPFS3JEcMsxdtDwNMi2cA==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@jest/types': 27.0.1 + '@jest/types': 27.0.2 '@types/graceful-fs': 4.1.5 - '@types/node': 15.6.1 + '@types/node': 15.12.2 anymatch: 3.1.2 fb-watchman: 2.0.1 graceful-fs: 4.2.6 jest-regex-util: 27.0.1 jest-serializer: 27.0.1 - jest-util: 27.0.1 - jest-worker: 27.0.1 + jest-util: 27.0.2 + jest-worker: 27.0.2 micromatch: 4.0.4 walker: 1.0.7 optionalDependencies: @@ -5454,27 +5595,27 @@ packages: - utf-8-validate dev: true - /jest-jasmine2/27.0.1: - resolution: {integrity: sha512-o8Ist0o970QDDm/R2o9UDbvNxq8A0++FTFQ0z9OnieJwS1nDH6H7WBDYAGPTdmnla7kbW41oLFPvhmjJE4mekg==} + /jest-jasmine2/27.0.4: + resolution: {integrity: sha512-yj3WrjjquZwkJw+eA4c9yucHw4/+EHndHWSqgHbHGQfT94ihaaQsa009j1a0puU8CNxPDk0c1oAPeOpdJUElwA==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: '@babel/traverse': 7.14.2 - '@jest/environment': 27.0.1 + '@jest/environment': 27.0.3 '@jest/source-map': 27.0.1 - '@jest/test-result': 27.0.1 - '@jest/types': 27.0.1 - '@types/node': 15.6.1 + '@jest/test-result': 27.0.2 + '@jest/types': 27.0.2 + '@types/node': 15.12.2 chalk: 4.1.1 co: 4.6.0 - expect: 27.0.1 + expect: 27.0.2 is-generator-fn: 2.1.0 - jest-each: 27.0.1 - jest-matcher-utils: 27.0.1 - jest-message-util: 27.0.1 - jest-runtime: 27.0.1 - jest-snapshot: 27.0.1 - jest-util: 27.0.1 - pretty-format: 27.0.1 + jest-each: 27.0.2 + jest-matcher-utils: 27.0.2 + jest-message-util: 27.0.2 + jest-runtime: 27.0.4 + jest-snapshot: 27.0.4 + jest-util: 27.0.2 + pretty-format: 27.0.2 throat: 6.0.1 transitivePeerDependencies: - supports-color @@ -5488,12 +5629,12 @@ packages: pretty-format: 25.5.0 dev: true - /jest-leak-detector/27.0.1: - resolution: {integrity: sha512-SQ/lRhfmnV3UuiaKIjwNXCaW2yh1rTMAL4n4Cl4I4gU0X2LoIc6Ogxe4UKM/J6Ld2uzc4gDGVYc5lSdpf6WjYw==} + /jest-leak-detector/27.0.2: + resolution: {integrity: sha512-TZA3DmCOfe8YZFIMD1GxFqXUkQnIoOGQyy4hFCA2mlHtnAaf+FeOMxi0fZmfB41ZL+QbFG6BVaZF5IeFIVy53Q==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: jest-get-type: 27.0.1 - pretty-format: 27.0.1 + pretty-format: 27.0.2 dev: true /jest-matcher-utils/25.5.0: @@ -5506,14 +5647,14 @@ packages: pretty-format: 25.5.0 dev: true - /jest-matcher-utils/27.0.1: - resolution: {integrity: sha512-NauNU+olKhPzLlsRnTOYFGk/MK5QFYl9ZzkrtfsY4eCq4SB3Bcl03UL44VdnlN5S/uFn4H2jwvRY1y6nSDTX3g==} + /jest-matcher-utils/27.0.2: + resolution: {integrity: sha512-Qczi5xnTNjkhcIB0Yy75Txt+Ez51xdhOxsukN7awzq2auZQGPHcQrJ623PZj0ECDEMOk2soxWx05EXdXGd1CbA==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: chalk: 4.1.1 - jest-diff: 27.0.1 + jest-diff: 27.0.2 jest-get-type: 27.0.1 - pretty-format: 27.0.1 + pretty-format: 27.0.2 dev: true /jest-message-util/25.5.0: @@ -5530,17 +5671,17 @@ packages: stack-utils: 1.0.5 dev: true - /jest-message-util/27.0.1: - resolution: {integrity: sha512-w8BfON2GwWORkos8BsxcwwQrLkV2s1ENxSRXK43+6yuquDE2hVxES/jrFqOArpP1ETVqqMmktU6iGkG8ncVzeA==} + /jest-message-util/27.0.2: + resolution: {integrity: sha512-rTqWUX42ec2LdMkoUPOzrEd1Tcm+R1KfLOmFK+OVNo4MnLsEaxO5zPDb2BbdSmthdM/IfXxOZU60P/WbWF8BTw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: '@babel/code-frame': 7.12.13 - '@jest/types': 27.0.1 + '@jest/types': 27.0.2 '@types/stack-utils': 2.0.0 chalk: 4.1.1 graceful-fs: 4.2.6 micromatch: 4.0.4 - pretty-format: 27.0.1 + pretty-format: 27.0.2 slash: 3.0.0 stack-utils: 2.0.3 dev: true @@ -5552,12 +5693,12 @@ packages: '@jest/types': 25.5.0 dev: true - /jest-mock/27.0.1: - resolution: {integrity: sha512-fXCSZQDT5hUcAUy8OBnB018x7JFOMQnz4XfpSKEbfpWzL6o5qaLRhgf2Qg2NPuVKmC/fgOf33Edj8wjF4I24CQ==} + /jest-mock/27.0.3: + resolution: {integrity: sha512-O5FZn5XDzEp+Xg28mUz4ovVcdwBBPfAhW9+zJLO0Efn2qNbYcDaJvSlRiQ6BCZUCVOJjALicuJQI9mRFjv1o9Q==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@jest/types': 27.0.1 - '@types/node': 15.6.1 + '@jest/types': 27.0.2 + '@types/node': 15.12.2 dev: true /jest-pnp-resolver/1.2.2_jest-resolve@25.5.1: @@ -5572,7 +5713,7 @@ packages: jest-resolve: 25.5.1 dev: true - /jest-pnp-resolver/1.2.2_jest-resolve@27.0.1: + /jest-pnp-resolver/1.2.2_jest-resolve@27.0.4: resolution: {integrity: sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==} engines: {node: '>=6'} peerDependencies: @@ -5581,7 +5722,7 @@ packages: jest-resolve: optional: true dependencies: - jest-resolve: 27.0.1 + jest-resolve: 27.0.4 dev: true /jest-regex-util/25.2.6: @@ -5608,13 +5749,13 @@ packages: jest-snapshot: 25.5.1 dev: true - /jest-resolve-dependencies/27.0.1: - resolution: {integrity: sha512-ly1x5mEf21f3IVWbUNwIz/ePLtv4QdhYuQIVSVDqxx7yzAwhhdu0DJo7UNiEYKQY7Im48wfbNdOUpo7euFUXBQ==} + /jest-resolve-dependencies/27.0.4: + resolution: {integrity: sha512-F33UPfw1YGWCV2uxJl7wD6TvcQn5IC0LtguwY3r4L7R6H4twpLkp5Q2ZfzRx9A2I3G8feiy0O0sqcn/Qoym71A==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@jest/types': 27.0.1 + '@jest/types': 27.0.2 jest-regex-util: 27.0.1 - jest-snapshot: 27.0.1 + jest-snapshot: 27.0.4 transitivePeerDependencies: - supports-color dev: true @@ -5634,16 +5775,17 @@ packages: slash: 3.0.0 dev: true - /jest-resolve/27.0.1: - resolution: {integrity: sha512-Q7QQ0OZ7z6D5Dul0MrsexlKalU8ZwexBfHLSu1qYPgphvUm6WO1b/xUnipU3e+uW1riDzMcJeJVYbdQ37hBHeg==} + /jest-resolve/27.0.4: + resolution: {integrity: sha512-BcfyK2i3cG79PDb/6gB6zFeFQlcqLsQjGBqznFCpA0L/3l1L/oOsltdUjs5eISAWA9HS9qtj8v2PSZr/yWxONQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@jest/types': 27.0.1 + '@jest/types': 27.0.2 chalk: 4.1.1 escalade: 3.1.1 graceful-fs: 4.2.6 - jest-pnp-resolver: 1.2.2_jest-resolve@27.0.1 - jest-util: 27.0.1 + jest-pnp-resolver: 1.2.2_jest-resolve@27.0.4 + jest-util: 27.0.2 + jest-validate: 27.0.2 resolve: 1.20.0 slash: 3.0.0 dev: true @@ -5678,36 +5820,36 @@ packages: - utf-8-validate dev: true - /jest-runner/27.0.1: - resolution: {integrity: sha512-DUNizlD2D7J80G3VOrwfbtb7KYxiftMng82HNcKwTW0W3AwwNuBeq+1exoCnLO7Mxh7NP+k/1XQBlzLpjr/CnA==} + /jest-runner/27.0.4: + resolution: {integrity: sha512-NfmvSYLCsCJk2AG8Ar2NAh4PhsJJpO+/r+g4bKR5L/5jFzx/indUpnVBdrfDvuqhGLLAvrKJ9FM/Nt8o1dsqxg==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@jest/console': 27.0.1 - '@jest/environment': 27.0.1 - '@jest/test-result': 27.0.1 - '@jest/transform': 27.0.1 - '@jest/types': 27.0.1 - '@types/node': 15.6.1 + '@jest/console': 27.0.2 + '@jest/environment': 27.0.3 + '@jest/test-result': 27.0.2 + '@jest/transform': 27.0.2 + '@jest/types': 27.0.2 + '@types/node': 15.12.2 chalk: 4.1.1 emittery: 0.8.1 exit: 0.1.2 graceful-fs: 4.2.6 - jest-config: 27.0.1 jest-docblock: 27.0.1 - jest-haste-map: 27.0.1 - jest-leak-detector: 27.0.1 - jest-message-util: 27.0.1 - jest-resolve: 27.0.1 - jest-runtime: 27.0.1 - jest-util: 27.0.1 - jest-worker: 27.0.1 + jest-environment-jsdom: 27.0.3 + jest-environment-node: 27.0.3 + jest-haste-map: 27.0.2 + jest-leak-detector: 27.0.2 + jest-message-util: 27.0.2 + jest-resolve: 27.0.4 + jest-runtime: 27.0.4 + jest-util: 27.0.2 + jest-worker: 27.0.2 source-map-support: 0.5.19 throat: 6.0.1 transitivePeerDependencies: - bufferutil - canvas - supports-color - - ts-node - utf-8-validate dev: true @@ -5749,18 +5891,18 @@ packages: - utf-8-validate dev: true - /jest-runtime/27.0.1: - resolution: {integrity: sha512-ImcrbQtpCUp8X9Rm4ky3j1GG9cqIKZJvXGZyB5cHEapGPTmg7wvvNooLmKragEe61/p/bhw1qO68Y0/9BSsBBg==} + /jest-runtime/27.0.4: + resolution: {integrity: sha512-voJB4xbAjS/qYPboV+e+gmg3jfvHJJY4CagFWBOM9dQKtlaiTjcpD2tWwla84Z7PtXSQPeIpXY0qksA9Dum29A==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@jest/console': 27.0.1 - '@jest/environment': 27.0.1 - '@jest/fake-timers': 27.0.1 - '@jest/globals': 27.0.1 + '@jest/console': 27.0.2 + '@jest/environment': 27.0.3 + '@jest/fake-timers': 27.0.3 + '@jest/globals': 27.0.3 '@jest/source-map': 27.0.1 - '@jest/test-result': 27.0.1 - '@jest/transform': 27.0.1 - '@jest/types': 27.0.1 + '@jest/test-result': 27.0.2 + '@jest/transform': 27.0.2 + '@jest/types': 27.0.2 '@types/yargs': 16.0.3 chalk: 4.1.1 cjs-module-lexer: 1.2.1 @@ -5768,14 +5910,14 @@ packages: exit: 0.1.2 glob: 7.1.7 graceful-fs: 4.2.6 - jest-haste-map: 27.0.1 - jest-message-util: 27.0.1 - jest-mock: 27.0.1 + jest-haste-map: 27.0.2 + jest-message-util: 27.0.2 + jest-mock: 27.0.3 jest-regex-util: 27.0.1 - jest-resolve: 27.0.1 - jest-snapshot: 27.0.1 - jest-util: 27.0.1 - jest-validate: 27.0.1 + jest-resolve: 27.0.4 + jest-snapshot: 27.0.4 + jest-util: 27.0.2 + jest-validate: 27.0.2 slash: 3.0.0 strip-bom: 4.0.0 yargs: 16.2.0 @@ -5794,7 +5936,7 @@ packages: resolution: {integrity: sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==} engines: {node: '>= 10.14.2'} dependencies: - '@types/node': 15.6.1 + '@types/node': 15.12.2 graceful-fs: 4.2.6 dev: true @@ -5802,7 +5944,7 @@ packages: resolution: {integrity: sha512-svy//5IH6bfQvAbkAEg1s7xhhgHTtXu0li0I2fdKHDsLP2P2MOiscPQIENQep8oU2g2B3jqLyxKKzotZOz4CwQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@types/node': 15.6.1 + '@types/node': 15.12.2 graceful-fs: 4.2.6 dev: true @@ -5827,8 +5969,8 @@ packages: semver: 6.3.0 dev: true - /jest-snapshot/27.0.1: - resolution: {integrity: sha512-HgKmSebDB3rswugREeh+nKrxJEVZE12K7lZ2MuwfFZT6YmiH0TlofsL2YmiLsCsG5KH5ZcLYYpF5bDrvtVx/Xg==} + /jest-snapshot/27.0.4: + resolution: {integrity: sha512-hnjrvpKGdSMvKfbHyaG5Kul7pDJGZvjVy0CKpzhu28MmAssDXS6GpynhXzgst1wBQoKD8c9b2VS2a5yhDLQRCA==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: '@babel/core': 7.14.3 @@ -5837,23 +5979,23 @@ packages: '@babel/plugin-syntax-typescript': 7.12.13_@babel+core@7.14.3 '@babel/traverse': 7.14.2 '@babel/types': 7.14.4 - '@jest/transform': 27.0.1 - '@jest/types': 27.0.1 + '@jest/transform': 27.0.2 + '@jest/types': 27.0.2 '@types/babel__traverse': 7.11.1 '@types/prettier': 2.2.3 babel-preset-current-node-syntax: 1.0.1_@babel+core@7.14.3 chalk: 4.1.1 - expect: 27.0.1 + expect: 27.0.2 graceful-fs: 4.2.6 - jest-diff: 27.0.1 + jest-diff: 27.0.2 jest-get-type: 27.0.1 - jest-haste-map: 27.0.1 - jest-matcher-utils: 27.0.1 - jest-message-util: 27.0.1 - jest-resolve: 27.0.1 - jest-util: 27.0.1 + jest-haste-map: 27.0.2 + jest-matcher-utils: 27.0.2 + jest-message-util: 27.0.2 + jest-resolve: 27.0.4 + jest-util: 27.0.2 natural-compare: 1.4.0 - pretty-format: 27.0.1 + pretty-format: 27.0.2 semver: 7.3.5 transitivePeerDependencies: - supports-color @@ -5875,19 +6017,19 @@ packages: engines: {node: '>= 10.14.2'} dependencies: '@jest/types': 26.6.2 - '@types/node': 15.6.1 + '@types/node': 15.12.2 chalk: 4.1.1 graceful-fs: 4.2.6 is-ci: 2.0.0 micromatch: 4.0.4 dev: true - /jest-util/27.0.1: - resolution: {integrity: sha512-lEw3waSmEOO4ZkwkUlFSvg4es1+8+LIkSGxp/kF60K0+vMR3Dv3O2HMZhcln9NHqSQzpVbsDT6OeMzUPW7DfRg==} + /jest-util/27.0.2: + resolution: {integrity: sha512-1d9uH3a00OFGGWSibpNYr+jojZ6AckOMCXV2Z4K3YXDnzpkAaXQyIpY14FOJPiUmil7CD+A6Qs+lnnh6ctRbIA==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@jest/types': 27.0.1 - '@types/node': 15.6.1 + '@jest/types': 27.0.2 + '@types/node': 15.12.2 chalk: 4.1.1 graceful-fs: 4.2.6 is-ci: 3.0.0 @@ -5906,16 +6048,16 @@ packages: pretty-format: 25.5.0 dev: true - /jest-validate/27.0.1: - resolution: {integrity: sha512-zvmPRcfTkqTZuHveIKAI2nbkUc3SDXjWVJULknPLGF5bdxOGSeGZg7f/Uw0MUVOkCOaspcHnsPCgZG0pqmg71g==} + /jest-validate/27.0.2: + resolution: {integrity: sha512-UgBF6/oVu1ofd1XbaSotXKihi8nZhg0Prm8twQ9uCuAfo59vlxCXMPI/RKmrZEVgi3Nd9dS0I8A0wzWU48pOvg==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@jest/types': 27.0.1 + '@jest/types': 27.0.2 camelcase: 6.2.0 chalk: 4.1.1 jest-get-type: 27.0.1 leven: 3.1.0 - pretty-format: 27.0.1 + pretty-format: 27.0.2 dev: true /jest-watch-typeahead/0.5.0: @@ -5942,16 +6084,16 @@ packages: string-length: 3.1.0 dev: true - /jest-watcher/27.0.1: - resolution: {integrity: sha512-Chp9c02BN0IgEbtGreyAhGqIsOrn9a0XnzbuXOxdW1+cW0Tjh12hMzHDIdLFHpYP/TqaMTmPHaJ5KWvpCCrNFw==} + /jest-watcher/27.0.2: + resolution: {integrity: sha512-8nuf0PGuTxWj/Ytfw5fyvNn/R80iXY8QhIT0ofyImUvdnoaBdT6kob0GmhXR+wO+ALYVnh8bQxN4Tjfez0JgkA==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@jest/test-result': 27.0.1 - '@jest/types': 27.0.1 - '@types/node': 15.6.1 + '@jest/test-result': 27.0.2 + '@jest/types': 27.0.2 + '@types/node': 15.12.2 ansi-escapes: 4.3.2 chalk: 4.1.1 - jest-util: 27.0.1 + jest-util: 27.0.2 string-length: 4.0.2 dev: true @@ -5975,16 +6117,16 @@ packages: resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 15.6.1 + '@types/node': 15.12.2 merge-stream: 2.0.0 supports-color: 7.2.0 dev: true - /jest-worker/27.0.1: - resolution: {integrity: sha512-NhHqClI3owOjmS8dBhQMKHZ2rrT0sBTpqGitp9nMX5AAjVXd+15o4v96uBEMhoywaLKN+5opcKBlXwAoADZolA==} - engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + /jest-worker/27.0.2: + resolution: {integrity: sha512-EoBdilOTTyOgmHXtw/cPc+ZrCA0KJMrkXzkrPGNwLmnvvlN1nj7MPrxpT7m+otSv2e1TLaVffzDnE/LB14zJMg==} + engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 15.6.1 + '@types/node': 15.12.2 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true @@ -6004,8 +6146,8 @@ packages: - utf-8-validate dev: true - /jest/27.0.1: - resolution: {integrity: sha512-lFEoUdXjbGAIxk/gZhcv98xOaH1hjqG5R/PQHs5GBfIK5iL3tnXCjHQf4HQLVZZ2rcXML3oeVg9+XrRZbooBdQ==} + /jest/27.0.4: + resolution: {integrity: sha512-Px1iKFooXgGSkk1H8dJxxBIrM3tsc5SIuI4kfKYK2J+4rvCvPGr/cXktxh0e9zIPQ5g09kOMNfHQEmusBUf/ZA==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} hasBin: true peerDependencies: @@ -6014,9 +6156,9 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 27.0.1 + '@jest/core': 27.0.4 import-local: 3.0.2 - jest-cli: 27.0.1 + jest-cli: 27.0.4 transitivePeerDependencies: - bufferutil - canvas @@ -6095,7 +6237,7 @@ packages: optional: true dependencies: abab: 2.0.5 - acorn: 8.2.4 + acorn: 8.3.0 acorn-globals: 6.0.0 cssom: 0.4.4 cssstyle: 2.3.0 @@ -6248,6 +6390,13 @@ packages: language-subtag-registry: 0.3.21 dev: true + /lazy-cache/2.0.2: + resolution: {integrity: sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=} + engines: {node: '>=0.10.0'} + dependencies: + set-getter: 0.1.0 + dev: true + /leven/3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} engines: {node: '>=6'} @@ -6271,6 +6420,16 @@ packages: uc.micro: 1.0.6 dev: true + /list-item/1.1.1: + resolution: {integrity: sha1-DGXQDih8tmPMs8s4Sad+iewmilY=} + engines: {node: '>=0.10.0'} + dependencies: + expand-range: 1.8.2 + extend-shallow: 2.0.1 + is-number: 2.1.0 + repeat-string: 1.6.1 + dev: true + /load-json-file/4.0.0: resolution: {integrity: sha1-L19Fq5HjMhYjT9U62rZo607AmTs=} engines: {node: '>=4'} @@ -6303,6 +6462,10 @@ packages: p-locate: 5.0.0 dev: true + /lodash._reinterpolate/3.0.0: + resolution: {integrity: sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=} + dev: true + /lodash.debounce/4.0.8: resolution: {integrity: sha1-gteb/zCmfEAF/9XiUVMArZyk168=} dev: true @@ -6319,6 +6482,19 @@ packages: resolution: {integrity: sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=} dev: true + /lodash.template/4.5.0: + resolution: {integrity: sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==} + dependencies: + lodash._reinterpolate: 3.0.0 + lodash.templatesettings: 4.2.0 + dev: true + + /lodash.templatesettings/4.2.0: + resolution: {integrity: sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==} + dependencies: + lodash._reinterpolate: 3.0.0 + dev: true + /lodash.uniq/4.5.0: resolution: {integrity: sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=} dev: true @@ -6442,6 +6618,48 @@ packages: uc.micro: 1.0.6 dev: true + /markdown-link/0.1.1: + resolution: {integrity: sha1-MsXGUZmmRXMWMi0eQinRNAfIx88=} + engines: {node: '>=0.10.0'} + dev: true + + /markdown-magic/2.0.0: + resolution: {integrity: sha512-DoXAcSvpqpGBbv/pCZ74XvHJ7/et8RZMuEhgvjBfbqlK9XOnGaZRrbHSJKelegP4SFK0WWPEFirA01ej+RJcEw==} + hasBin: true + dependencies: + commander: 2.20.3 + deepmerge: 4.2.2 + find-up: 2.1.0 + globby: 6.1.0 + is-local-path: 0.1.6 + markdown-toc: 1.2.0 + mkdirp: 1.0.4 + sync-request: 3.0.1 + dev: true + + /markdown-toc/1.2.0: + resolution: {integrity: sha512-eOsq7EGd3asV0oBfmyqngeEIhrbkc7XVP63OwcJBIhH2EpG2PzFcbZdhy1jutXSlRBBVMNXHvMtSr5LAxSUvUg==} + engines: {node: '>=0.10.0'} + hasBin: true + dependencies: + concat-stream: 1.6.2 + diacritics-map: 0.1.0 + gray-matter: 2.1.1 + lazy-cache: 2.0.2 + list-item: 1.1.1 + markdown-link: 0.1.1 + minimist: 1.2.5 + mixin-deep: 1.3.2 + object.pick: 1.3.0 + remarkable: 1.7.4 + repeat-string: 1.6.1 + strip-color: 0.1.0 + dev: true + + /math-random/1.0.4: + resolution: {integrity: sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==} + dev: true + /mdast-squeeze-paragraphs/4.0.0: resolution: {integrity: sha512-zxdPn69hkQ1rm4J+2Cs2j6wDEv7O17TfXTJ33tl/+JPIoEmtV9t2ZzBM5LPHE8QlHsmVD8t3vPKCyY3oH+H8MQ==} dependencies: @@ -6536,6 +6754,11 @@ packages: engines: {node: '>= 0.6'} dev: true + /mime-db/1.48.0: + resolution: {integrity: sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==} + engines: {node: '>= 0.6'} + dev: true + /mime-types/2.1.30: resolution: {integrity: sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==} engines: {node: '>= 0.6'} @@ -6543,6 +6766,13 @@ packages: mime-db: 1.47.0 dev: true + /mime-types/2.1.31: + resolution: {integrity: sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.48.0 + dev: true + /mimic-fn/1.2.0: resolution: {integrity: sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==} engines: {node: '>=4'} @@ -6656,8 +6886,8 @@ packages: dev: true optional: true - /node-releases/1.1.72: - resolution: {integrity: sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==} + /node-releases/1.1.73: + resolution: {integrity: sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==} dev: true /normalize-package-data/2.5.0: @@ -7021,11 +7251,28 @@ packages: engines: {node: '>=8.6'} dev: true + /pify/2.3.0: + resolution: {integrity: sha1-7RQaasBDqEnqWISY59yosVMw6Qw=} + engines: {node: '>=0.10.0'} + dev: true + /pify/3.0.0: resolution: {integrity: sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=} engines: {node: '>=4'} dev: true + /pinkie-promise/2.0.1: + resolution: {integrity: sha1-ITXW36ejWMBprJsXh3YogihFD/o=} + engines: {node: '>=0.10.0'} + dependencies: + pinkie: 2.0.4 + dev: true + + /pinkie/2.0.4: + resolution: {integrity: sha1-clVrgM+g1IqXToDnckjoDtT3+HA=} + engines: {node: '>=0.10.0'} + dev: true + /pirates/4.0.1: resolution: {integrity: sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==} engines: {node: '>= 6'} @@ -7067,7 +7314,7 @@ packages: promise-assist: 1.3.0 semver: 7.3.5 tslib: 2.2.0 - type-fest: 1.1.3 + type-fest: 1.2.0 dev: true /pn/1.1.0: @@ -7123,16 +7370,20 @@ packages: react-is: 17.0.2 dev: true - /pretty-format/27.0.1: - resolution: {integrity: sha512-qE+0J6c/gd+R6XTcQgPJMc5hMJNsxzSF5p8iZSbMZ7GQzYGlSLNkh2P80Wa2dbF4gEVUsJEgcrBY+1L2/j265w==} + /pretty-format/27.0.2: + resolution: {integrity: sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@jest/types': 27.0.1 + '@jest/types': 27.0.2 ansi-regex: 5.0.0 ansi-styles: 5.2.0 react-is: 17.0.2 dev: true + /process-nextick-args/2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + dev: true + /progress-estimator/0.2.2: resolution: {integrity: sha512-GF76Ac02MTJD6o2nMNtmtOFjwWCnHcvXyn5HOWPQnEMO8OTLw7LAvNmrwe8LmdsB+eZhwUu9fX/c9iQnBxWaFA==} dependencies: @@ -7152,6 +7403,12 @@ packages: engines: {node: '>=8'} dev: true + /promise/7.3.1: + resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==} + dependencies: + asap: 2.0.6 + dev: true + /prompts/2.4.1: resolution: {integrity: sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==} engines: {node: '>= 6'} @@ -7194,6 +7451,15 @@ packages: engines: {node: '>=0.6'} dev: true + /randomatic/3.1.1: + resolution: {integrity: sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==} + engines: {node: '>= 0.10.0'} + dependencies: + is-number: 4.0.0 + kind-of: 6.0.3 + math-random: 1.0.4 + dev: true + /randombytes/2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} dependencies: @@ -7244,6 +7510,18 @@ packages: type-fest: 0.6.0 dev: true + /readable-stream/2.3.7: + resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==} + dependencies: + core-util-is: 1.0.2 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + dev: true + /realpath-native/2.0.0: resolution: {integrity: sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==} engines: {node: '>=8'} @@ -7399,6 +7677,15 @@ packages: transitivePeerDependencies: - supports-color + /remarkable/1.7.4: + resolution: {integrity: sha512-e6NKUXgX95whv7IgddywbeN/ItCkWbISmc2DiqHJb0wTrqZIexqdco5b8Z3XZoo/48IdNVKM9ZCvTPJ4F5uvhg==} + engines: {node: '>= 0.10.0'} + hasBin: true + dependencies: + argparse: 1.0.10 + autolinker: 0.28.1 + dev: true + /remove-trailing-separator/1.1.0: resolution: {integrity: sha1-wkvOKig62tW8P1jg1IJJuSN52O8=} dev: true @@ -7719,6 +8006,13 @@ packages: resolution: {integrity: sha1-BF+XgtARrppoA93TgrJDkrPYkPc=} dev: true + /set-getter/0.1.0: + resolution: {integrity: sha1-12nBgsnVpR9AkUXy+6guXoboA3Y=} + engines: {node: '>=0.10.0'} + dependencies: + to-object-path: 0.3.0 + dev: true + /set-value/2.0.1: resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} engines: {node: '>=0.10.0'} @@ -8033,6 +8327,12 @@ packages: define-properties: 1.1.3 dev: true + /string_decoder/1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + dependencies: + safe-buffer: 5.1.2 + dev: true + /stringify-entities/2.0.0: resolution: {integrity: sha512-fqqhZzXyAM6pGD9lky/GOPq6V4X0SeTAFBl0iXb/BzOegl40gpf/bV3QQP7zULNYvjr6+Dx8SCaDULjVoOru0A==} dependencies: @@ -8087,6 +8387,11 @@ packages: engines: {node: '>=8'} dev: true + /strip-color/0.1.0: + resolution: {integrity: sha1-EG9l09PmotlAHKwOsM6LinArT3s=} + engines: {node: '>=0.10.0'} + dev: true + /strip-eof/1.0.0: resolution: {integrity: sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=} engines: {node: '>=0.10.0'} @@ -8155,6 +8460,14 @@ packages: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} dev: true + /sync-request/3.0.1: + resolution: {integrity: sha1-yqEjWq+Im6UBB2oYNMQ2gwqC+3M=} + dependencies: + concat-stream: 1.6.2 + http-response-object: 1.1.0 + then-request: 2.2.0 + dev: true + /table/5.4.6: resolution: {integrity: sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==} engines: {node: '>=6.0.0'} @@ -8196,6 +8509,17 @@ packages: resolution: {integrity: sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=} dev: true + /then-request/2.2.0: + resolution: {integrity: sha1-ZnizL6DKIY/laZgbvYhxtZQGDYE=} + dependencies: + caseless: 0.11.0 + concat-stream: 1.6.2 + http-basic: 2.5.1 + http-response-object: 1.1.0 + promise: 7.3.1 + qs: 6.5.2 + dev: true + /throat/5.0.0: resolution: {integrity: sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==} dev: true @@ -8208,6 +8532,13 @@ packages: resolution: {integrity: sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=} dev: true + /through2/2.0.5: + resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} + dependencies: + readable-stream: 2.3.7 + xtend: 4.0.2 + dev: true + /tiny-glob/0.2.9: resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==} dependencies: @@ -8263,6 +8594,10 @@ packages: safe-regex: 1.1.0 dev: true + /toml/2.3.6: + resolution: {integrity: sha512-gVweAectJU3ebq//Ferr2JUY4WKSDe5N+z0FvjDncLGyHmIDoxgY/2Ie4qfEIDm4IS7OA6Rmdm7pdEEdMcV/xQ==} + dev: true + /tough-cookie/2.5.0: resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} engines: {node: '>=0.8'} @@ -8484,8 +8819,8 @@ packages: engines: {node: '>=8'} dev: true - /type-fest/1.1.3: - resolution: {integrity: sha512-CsiQeFMR1jZEq8R+H59qe+bBevnjoV5N2WZTTdlyqxeoODQOOepN2+msQOywcieDq5sBjabKzTn3U+sfHZlMdw==} + /type-fest/1.2.0: + resolution: {integrity: sha512-++0N6KyAj0t2webXst0PE0xuXb4Dv3z1Z+4SGzK+j/epeWBZCfkQbkW/ezscZwpinmBQ5wu/l4TqagKSVcAGCA==} engines: {node: '>=10'} dev: true @@ -8495,6 +8830,10 @@ packages: is-typedarray: 1.0.0 dev: true + /typedarray/0.0.6: + resolution: {integrity: sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=} + dev: true + /typescript/3.9.9: resolution: {integrity: sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==} engines: {node: '>=4.2.0'} @@ -8678,6 +9017,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /util-deprecate/1.0.2: + resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=} + dev: true + /uuid/3.4.0: resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. diff --git a/site/pages/index.tsx b/site/pages/index.tsx index a18362b..33a2681 100644 --- a/site/pages/index.tsx +++ b/site/pages/index.tsx @@ -1,10 +1,6 @@ import Head from "next/head"; -import { useEffect } from "react"; -import { setupTwoslashHovers } from "shiki-twoslash/dist/dom"; export default function Home(props: ReturnType["props"]) { - useEffect(setupTwoslashHovers, []); - return ( <> diff --git a/site/styles/globals.css b/site/styles/globals.css index 5f0a013..b1b61c5 100644 --- a/site/styles/globals.css +++ b/site/styles/globals.css @@ -1,11 +1,11 @@ @font-face { font-family: "caslon"; - src: url("/twoslash/CaslonOS-Regular.otf") format("woff2"); + src: url("/twoslash/CaslonOS-Regular.otf") format("woff2"); } @font-face { font-family: "euclid"; - src:url("/twoslash/EuclidInitialsnormal.woff2") format("woff2"); + src: url("/twoslash/EuclidInitialsnormal.woff2") format("woff2"); } @font-face { @@ -499,8 +499,8 @@ pre .inline-completions ul.dropdown li span.result { /* Fades in unobtrusively */ transition-timing-function: ease; transition: border-color 0.3s; - /* Respect people's wishes to not have animations */ } +/* Respect people's wishes to not have animations anywhere */ @media (prefers-reduced-motion: reduce) { data-lsp { transition: none; @@ -511,7 +511,7 @@ pre:hover data-lsp { border-color: #747474; } /** The tooltip-like which provides the LSP response */ -#twoslash-mouse-hover-info { +/* #twoslash-mouse-hover-info { background-color: #3f3f3f; color: #fff; text-align: left; @@ -523,6 +523,21 @@ pre:hover data-lsp { border-radius: 2px; z-index: 100; pointer-events: none; +} */ + +.twoslash data-lsp:hover::before { + content: attr(lsp); + position: absolute; + transform: translate(0, 1rem); + + background-color: #3f3f3f; + color: #fff; + text-align: left; + padding: 5px 8px; + border-radius: 2px; + font-family: "JetBrains Mono", Menlo, Monaco, Consolas, Courier New, monospace; + font-size: 14px; + white-space: pre-wrap; } .language-id {