Create docs navigation sidebar (#40)
* crawl files and create directory tree for sidebar * dropdown * Working on dropdown links and styling * setup header nav * Styles * DocumentNav sidebar done * wrap up header sidebar * setup top level nav * update root level data and fix link bug * doc links yaml * nav links for docs * remove character * prettier * fix build error * MDX style * Update src/components/UI/docs/DocsLinks.tsx Co-authored-by: Paul Wackerow <54227730+wackerow@users.noreply.github.com> * Abstract LinksList component into its own file * change requests * AccordionButton styles * AccordionButton styled * fix broken links * prettier * prettier * fix broken default code snippet * fix accordion spacing * fix gap at top of DocsNav lg * fix but of persistent header link * remove test content * setup Notes and prettier * rehype * Note component * Note font styling * convert old notes to use component * Breadcrumb cleanup and prettier * MDXComponents -> MDComponent and documentation Co-authored-by: Paul Wackerow <54227730+wackerow@users.noreply.github.com>
This commit is contained in:
parent
fc52cc75e4
commit
0b9ff8b1e6
|
@ -49,3 +49,11 @@ You can check out [the Next.js GitHub repository](https://github.com/vercel/next
|
||||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||||
|
|
||||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
||||||
|
|
||||||
|
## Adding a new documentation page
|
||||||
|
|
||||||
|
Documentation pages are located in the `/docs` folder in the root directory of the project.
|
||||||
|
|
||||||
|
When you want to add a new page, add the new file in the appropriate folder in the `/docs` page. `index.md` files will be the default page for a directory, and `{pagename}.md` will define subpages for a directory.
|
||||||
|
|
||||||
|
After adding this page, you will need to add it `/src/data/documentation-links.yaml` which adds documentation structure which you will see on the left sidebar in the documentation pages.
|
||||||
|
|
|
@ -12,11 +12,8 @@ If you'd like to contribute to the Geth source code, please fork the [Github rep
|
||||||
Please make sure your contributions adhere to our coding guidelines:
|
Please make sure your contributions adhere to our coding guidelines:
|
||||||
|
|
||||||
- Code must adhere to the official Go formatting guidelines (i.e. uses gofmt).
|
- Code must adhere to the official Go formatting guidelines (i.e. uses gofmt).
|
||||||
|
|
||||||
- Code must be documented adhering to the official Go commentary guidelines.
|
- Code must be documented adhering to the official Go commentary guidelines.
|
||||||
|
|
||||||
- Pull requests need to be based on and opened against the master branch.
|
- Pull requests need to be based on and opened against the master branch.
|
||||||
|
|
||||||
- Commit messages should be prefixed with the package(s) they modify.
|
- Commit messages should be prefixed with the package(s) they modify.
|
||||||
E.g. "eth, rpc: make trace configs optional"
|
E.g. "eth, rpc: make trace configs optional"
|
||||||
|
|
||||||
|
|
|
@ -176,7 +176,6 @@ Return:
|
||||||
Things to note about the call tracer:
|
Things to note about the call tracer:
|
||||||
|
|
||||||
- Calls to precompiles are also included in the result
|
- Calls to precompiles are also included in the result
|
||||||
|
|
||||||
- In case a frame reverts, the field `output` will contain the raw return data
|
- In case a frame reverts, the field `output` will contain the raw return data
|
||||||
|
|
||||||
- In case the top level frame reverts, its `revertReason` field will contain the parsed reason of revert as returned by the Solidity contract
|
- In case the top level frame reverts, its `revertReason` field will contain the parsed reason of revert as returned by the Solidity contract
|
||||||
|
@ -186,7 +185,6 @@ Things to note about the call tracer:
|
||||||
`callTracer` accepts two options:
|
`callTracer` accepts two options:
|
||||||
|
|
||||||
- `onlyTopCall: true` instructs the tracer to only process the main (top-level) call and none of the sub-calls. This avoids extra processing for each call frame if only the top-level call info are required.
|
- `onlyTopCall: true` instructs the tracer to only process the main (top-level) call and none of the sub-calls. This avoids extra processing for each call frame if only the top-level call info are required.
|
||||||
|
|
||||||
- `withLog: true` instructs the tracer to also collect the logs emitted during each call.
|
- `withLog: true` instructs the tracer to also collect the logs emitted during each call.
|
||||||
|
|
||||||
Example invokation with the `onlyTopCall` flag:
|
Example invokation with the `onlyTopCall` flag:
|
||||||
|
|
|
@ -6,15 +6,10 @@ description: Instructions for setting up Geth in developer mode
|
||||||
It is often convenient for developers to work in an environment where changes to client or application software can be deployed and tested rapidly and without putting real-world users or assets at risk. For this purpose, Geth has a `--dev` flag that spins up Geth in "developer mode". This creates a single-node Ethereum test network with no connections to any external peers. It exists solely on the local machine. Starting Geth in developer mode does the following:
|
It is often convenient for developers to work in an environment where changes to client or application software can be deployed and tested rapidly and without putting real-world users or assets at risk. For this purpose, Geth has a `--dev` flag that spins up Geth in "developer mode". This creates a single-node Ethereum test network with no connections to any external peers. It exists solely on the local machine. Starting Geth in developer mode does the following:
|
||||||
|
|
||||||
- Initializes the data directory with a testing genesis block
|
- Initializes the data directory with a testing genesis block
|
||||||
|
|
||||||
- Sets max peers to 0 (meaning Geth does not search for peers)
|
- Sets max peers to 0 (meaning Geth does not search for peers)
|
||||||
|
|
||||||
- Turns off discovery by other nodes (meaning the node is invisible to other nodes)
|
- Turns off discovery by other nodes (meaning the node is invisible to other nodes)
|
||||||
|
|
||||||
- Sets the gas price to 0 (no cost to send transactions)
|
- Sets the gas price to 0 (no cost to send transactions)
|
||||||
|
|
||||||
- Uses the Clique proof-of-authority consensus engine which allows blocks to be mined as-needed without excessive CPU and memory consumption
|
- Uses the Clique proof-of-authority consensus engine which allows blocks to be mined as-needed without excessive CPU and memory consumption
|
||||||
|
|
||||||
- Uses on-demand block generation, producing blocks when transactions are waiting to be mined
|
- Uses on-demand block generation, producing blocks when transactions are waiting to be mined
|
||||||
|
|
||||||
This configuration enables developers to experiment with Geth's source code or develop new applications without having to sync to a pre-existing public network. Blocks are only mined when there are pending transactions. Developers can break things on this network without affecting other users. This page will demonstrate how to spin up a local Geth testnet and a simple smart contract will be deployed to it using the Remix online integrated development environment (IDE).
|
This configuration enables developers to experiment with Geth's source code or develop new applications without having to sync to a pre-existing public network. Blocks are only mined when there are pending transactions. Developers can break things on this network without affecting other users. This page will demonstrate how to spin up a local Geth testnet and a simple smart contract will be deployed to it using the Remix online integrated development environment (IDE).
|
||||||
|
|
|
@ -78,7 +78,7 @@ The console will hang because Clef is waiting for manual approval. Switch to the
|
||||||
|
|
||||||
It is critical to backup the account password safely and securely as it cannot be retrieved or reset.
|
It is critical to backup the account password safely and securely as it cannot be retrieved or reset.
|
||||||
|
|
||||||
{% include note.html content=" If the password provided on account creation is lost or forgotten, there is no way to retrive it and the account will simply stay locked forever. The password MUST be backed up safely and securely! **IT IS CRITICAL TO BACKUP THE KEYSTORE AND REMEMBER PASSWORDS**" %}
|
<Note>If the password provided on account creation is lost or forgotten, there is no way to retrive it and the account will simply stay locked forever. The password MUST be backed up safely and securely! **IT IS CRITICAL TO BACKUP THE KEYSTORE AND REMEMBER PASSWORDS**</Note>
|
||||||
|
|
||||||
The newly generated key files can be viewed in `<datadir>/keystore/`. The file naming format is `UTC--<date>--<address>` where `date` is the date and time of key creation formatted according to [UTC 8601](https://www.iso.org/iso-8601-date-and-time-format.html) with zero time offset and seconds precise to eight decimal places. `address` is the 40 hexadecimal characters that make up the account address without a leading `0x`, for example:
|
The newly generated key files can be viewed in `<datadir>/keystore/`. The file naming format is `UTC--<date>--<address>` where `date` is the date and time of key creation formatted according to [UTC 8601](https://www.iso.org/iso-8601-date-and-time-format.html) with zero time offset and seconds precise to eight decimal places. `address` is the 40 hexadecimal characters that make up the account address without a leading `0x`, for example:
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,13 @@ title: Light client
|
||||||
description: Introduction to Geth's light sync mode
|
description: Introduction to Geth's light sync mode
|
||||||
---
|
---
|
||||||
|
|
||||||
{% include note.html content="Light nodes do not currently work on proof-of-stake Ethereum, but new proof-of-stake light clients are expected to ship soon!" %}
|
<Note>Light nodes do not currently work on proof-of-stake Ethereum, but new proof-of-stake light clients are expected to ship soon!</Note>
|
||||||
|
|
||||||
Running a full node is the most trustless, private, decentralized and censorship resistant way to interact with Ethereum. It is also the best choice for the health of the network, because a decentralized network relies on having many individual nodes that independently verify the head of the chain. In a full node a copy of the blockchain is stored locally enabling users to verify incoming data against a local source of truth. However, running a full node requires a lot of disk space and non-negligible CPU allocation and takes hours (for snap sync) or days (for full sync) to sync the blockchain from genesis. Geth also offers a light mode that overcomes these issues and provides some of the benefits of running a node but requires only a fraction of the resources.
|
Running a full node is the most trustless, private, decentralized and censorship resistant way to interact with Ethereum. It is also the best choice for the health of the network, because a decentralized network relies on having many individual nodes that independently verify the head of the chain. In a full node a copy of the blockchain is stored locally enabling users to verify incoming data against a local source of truth. However, running a full node requires a lot of disk space and non-negligible CPU allocation and takes hours (for snap sync) or days (for full sync) to sync the blockchain from genesis. Geth also offers a light mode that overcomes these issues and provides some of the benefits of running a node but requires only a fraction of the resources.
|
||||||
|
|
||||||
Read more about the reasons to run nodes on [ethereum.org](https://ethereum.org/en/run-a-node/).
|
Read more about the reasons to run nodes on [ethereum.org](https://ethereum.org/en/run-a-node/).
|
||||||
|
|
||||||
{% include note.html content=" Geth light clients **do not currently work** on proof-of-stake Ethereum. New light clients that work with the proof-of-stake consensus engine are expected to ship soon!" %}
|
<Note>Geth light clients **do not currently work** on proof-of-stake Ethereum. New light clients that work with the proof-of-stake consensus engine are expected to ship soon!</Note>
|
||||||
|
|
||||||
## Light node vs full node {#light-node-vs-full-node}
|
## Light node vs full node {#light-node-vs-full-node}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ title: Proof-of-work mining with Ethash
|
||||||
description: Introduction to proof-of-work mining with Geth
|
description: Introduction to proof-of-work mining with Geth
|
||||||
---
|
---
|
||||||
|
|
||||||
{% include note.html content=" Proof-of-work mining is no longer used to secure Ethereum Mainnet. The information below is included because the Ethash code is still part of Geth and it could be used to create a private proof-of-work network or testnet." %}
|
<Note>Proof-of-work mining is no longer used to secure Ethereum Mainnet. The information below is included because the Ethash code is still part of Geth and it could be used to create a private proof-of-work network or testnet.</Note>
|
||||||
|
|
||||||
Blockchains grow when individual nodes create valid blocks and distribute them to their peers who check the blocks and add them to their own local databases.
|
Blockchains grow when individual nodes create valid blocks and distribute them to their peers who check the blocks and add them to their own local databases.
|
||||||
Nodes that add blocks are rewarded with ether payouts. On Ethereum Mainnet, the proof-of-stake consensus engine randomly selects a node to produce each block.
|
Nodes that add blocks are rewarded with ether payouts. On Ethereum Mainnet, the proof-of-stake consensus engine randomly selects a node to produce each block.
|
||||||
|
|
|
@ -3,7 +3,7 @@ title: Pruning
|
||||||
description: Instructions for pruning a Geth node
|
description: Instructions for pruning a Geth node
|
||||||
---
|
---
|
||||||
|
|
||||||
{% include note.html content="Offline pruning is only for the hash-based state scheme. Soon, we will have a path-based state scheme which enables the pruning by default. Once the hash-based state scheme is no longer supported, offline pruning will be deprecated." %}
|
<Note>Offline pruning is only for the hash-based state scheme. Soon, we will have a path-based state scheme which enables the pruning by default. Once the hash-based state scheme is no longer supported, offline pruning will be deprecated.</Note>
|
||||||
|
|
||||||
A snap-sync'd Geth node currently requires more than 650 GB of disk space to store the historic blockchain data. With default cache size the database grows by about 14 GB/week. This means that Geth users will rapidly run out of space on 1TB hard drives. To solve this problem without needing to purchase additional hardware, Geth can be pruned. Pruning is the process of erasing older data to save disk space. Since Geth `v1.10`, users have been able to trigger a snapshot offline prune to bring the total storage back down to the original ~650 GB in about 4-5 hours. This has to be done periodically to keep the total disk storage
|
A snap-sync'd Geth node currently requires more than 650 GB of disk space to store the historic blockchain data. With default cache size the database grows by about 14 GB/week. This means that Geth users will rapidly run out of space on 1TB hard drives. To solve this problem without needing to purchase additional hardware, Geth can be pruned. Pruning is the process of erasing older data to save disk space. Since Geth `v1.10`, users have been able to trigger a snapshot offline prune to bring the total storage back down to the original ~650 GB in about 4-5 hours. This has to be done periodically to keep the total disk storage
|
||||||
within the bounds of the local hardware (e.g. every month or so for a 1TB disk).
|
within the bounds of the local hardware (e.g. every month or so for a 1TB disk).
|
||||||
|
@ -13,13 +13,9 @@ To prune a Geth node at least 40 GB of free disk space is recommended. This mean
|
||||||
## Pruning rules {#pruning-rules}
|
## Pruning rules {#pruning-rules}
|
||||||
|
|
||||||
1. Do not try to prune an archive node. Archive nodes need to maintain ALL historic data by definition.
|
1. Do not try to prune an archive node. Archive nodes need to maintain ALL historic data by definition.
|
||||||
|
|
||||||
2. Ensure there is at least 40 GB of storage space still available on the disk that will be pruned. Failures have been reported with ~25GB of free space.
|
2. Ensure there is at least 40 GB of storage space still available on the disk that will be pruned. Failures have been reported with ~25GB of free space.
|
||||||
|
|
||||||
3. Geth is at least `v1.10` ideally > `v1.10.3`
|
3. Geth is at least `v1.10` ideally > `v1.10.3`
|
||||||
|
|
||||||
4. Geth is fully sync'd
|
4. Geth is fully sync'd
|
||||||
|
|
||||||
5. Geth has finished creating a snapshot that is at least 128 blocks old. This is true when "state snapshot generation" is no longer reported in the logs.
|
5. Geth has finished creating a snapshot that is at least 128 blocks old. This is true when "state snapshot generation" is no longer reported in the logs.
|
||||||
|
|
||||||
With these rules satisfied, Geth's database can be pruned.
|
With these rules satisfied, Geth's database can be pruned.
|
||||||
|
|
|
@ -21,7 +21,7 @@ In order to get the most value from the tutorials on this page, the following sk
|
||||||
Users that need to revisit these fundamentals can find helpful resources relating to the command line [here](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Command_line), Ethereum and its testnets [here](https://ethereum.org/en/developers/tutorials/), http [here](https://developer.mozilla.org/en-US/docs/Web/HTTP) and Javascript [here](https://www.javascript.com/learn). Information on node architecture can be found [here](/docs/fundamentals/node-architecture) and our guide for configuring Geth to connect to a
|
Users that need to revisit these fundamentals can find helpful resources relating to the command line [here](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Command_line), Ethereum and its testnets [here](https://ethereum.org/en/developers/tutorials/), http [here](https://developer.mozilla.org/en-US/docs/Web/HTTP) and Javascript [here](https://www.javascript.com/learn). Information on node architecture can be found [here](/docs/fundamentals/node-architecture) and our guide for configuring Geth to connect to a
|
||||||
consensus client is [here](/docs/getting_started/consensus-clients).
|
consensus client is [here](/docs/getting_started/consensus-clients).
|
||||||
|
|
||||||
{% include note.html content="If Geth was installed from source on Linux, `make` saves the binaries for Geth and the associated tools in `/build/bin`. To run these programs it is convenient to move them to the top level project directory (e.g. running `mv ./build/bin/* ./`) from `/go-ethereum`. Then `./` must be prepended to the commands in the code snippets in order to execute a particular program, e.g. `./geth` instead of simply `geth`. If the executables are not moved then either navigate to the `bin` directory to run them (e.g. `cd ./build/bin` and `./geth`) or provide their path (e.g. `./build/bin/geth`). These instructions can be ignored for other installations." %}
|
<Note>If Geth was installed from source on Linux, `make` saves the binaries for Geth and the associated tools in `/build/bin`. To run these programs it is convenient to move them to the top level project directory (e.g. running `mv ./build/bin/* ./`) from `/go-ethereum`. Then `./` must be prepended to the commands in the code snippets in order to execute a particular program, e.g. `./geth` instead of simply `geth`. If the executables are not moved then either navigate to the `bin` directory to run them (e.g. `cd ./build/bin` and `./geth`) or provide their path (e.g. `./build/bin/geth`). These instructions can be ignored for other installations.</Note>
|
||||||
|
|
||||||
## Background {#background}
|
## Background {#background}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ This returns a result which is also a JSON object, with values expressed as hexa
|
||||||
This is a low level and rather error-prone way to interact with Geth. Most developers prefer to use convenience libraries that abstract away some of the more tedious and awkward tasks such as converting values from hexadecimal strings into numbers, or converting between denominations of ether (Wei, Gwei, etc). One such library is [Web3.js](https://web3js.readthedocs.io/en/v1.7.3/).
|
This is a low level and rather error-prone way to interact with Geth. Most developers prefer to use convenience libraries that abstract away some of the more tedious and awkward tasks such as converting values from hexadecimal strings into numbers, or converting between denominations of ether (Wei, Gwei, etc). One such library is [Web3.js](https://web3js.readthedocs.io/en/v1.7.3/).
|
||||||
The purpose of Geth's Javascript console is to provide a built-in environment to use a subset of the Web3.js libraries to interact with a Geth node.
|
The purpose of Geth's Javascript console is to provide a built-in environment to use a subset of the Web3.js libraries to interact with a Geth node.
|
||||||
|
|
||||||
{% include note.html content="The web3.js version that comes bundled with Geth is not up to date with the official Web3.js documentation. There are several Web3.js libraries that are not available in the Geth Javascript Console. There are also administrative APIs included in the Geth console that are not documented in the Web3.js documentation. The full list of libraries available in the Geth console is available on the [JSON-RPC API page](/docs/interacting-with-geth/rpc/server)." %}
|
<Note>The web3.js version that comes bundled with Geth is not up to date with the official Web3.js documentation. There are several Web3.js libraries that are not available in the Geth Javascript Console. There are also administrative APIs included in the Geth console that are not documented in the Web3.js documentation. The full list of libraries available in the Geth console is available on the [JSON-RPC API page](/docs/interacting-with-geth/rpc/server).</Note>
|
||||||
|
|
||||||
## Starting the console {#starting-the-console}
|
## Starting the console {#starting-the-console}
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ geth --ws --ws.origins http://myapp.example.com
|
||||||
|
|
||||||
As with `--http.corsdomain`, using the wildcard `--ws.origins '*'` allows access from any origin.
|
As with `--http.corsdomain`, using the wildcard `--ws.origins '*'` allows access from any origin.
|
||||||
|
|
||||||
{% include note.html content=" By default, **account unlocking is forbidden when HTTP or Websocket access is enabled** (i.e. by passing `--http` or `ws` flag). This is because an attacker that manages to access the node via the externally-exposed HTTP/WS port can then control the unlocked account. It is possible to force account unlock by including the `--allow-insecure-unlock` flag but this is unsafe and **not recommended** except for expert users that completely understand how it can be used safely. This is not a hypothetical risk: **there are bots that continually scan for http-enabled Ethereum nodes to attack**" %}
|
<Note>By default, **account unlocking is forbidden when HTTP or Websocket access is enabled** (i.e. by passing `--http` or `ws` flag). This is because an attacker that manages to access the node via the externally-exposed HTTP/WS port can then control the unlocked account. It is possible to force account unlock by including the `--allow-insecure-unlock` flag but this is unsafe and **not recommended** except for expert users that completely understand how it can be used safely. This is not a hypothetical risk: **there are bots that continually scan for http-enabled Ethereum nodes to attack**</Note>
|
||||||
|
|
||||||
### IPC Server {#ipc-server}
|
### IPC Server {#ipc-server}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ The location is specified as `<filename>:<line>`.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
``` js
|
```js
|
||||||
> debug.backtraceAt("server.go:443")
|
> debug.backtraceAt("server.go:443")
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -579,13 +579,16 @@ No specific call options:
|
||||||
Tracing a call with a destination and specific sender, disabling the storage and memory output (less data returned over RPC)
|
Tracing a call with a destination and specific sender, disabling the storage and memory output (less data returned over RPC)
|
||||||
|
|
||||||
```js
|
```js
|
||||||
debug.traceCall({
|
debug.traceCall(
|
||||||
"from": "0xdeadbeef29292929192939494959594933929292",
|
{
|
||||||
"to": "0xde929f939d939d393f939393f93939f393929023",
|
from: '0xdeadbeef29292929192939494959594933929292',
|
||||||
"gas": "0x7a120",
|
to: '0xde929f939d939d393f939393f93939f393929023',
|
||||||
"data": "0xf00d4b5d00000000000000000000000001291230982139282304923482304912923823920000000000000000000000001293123098123928310239129839291010293810"
|
gas: '0x7a120',
|
||||||
},
|
data: '0xf00d4b5d00000000000000000000000001291230982139282304923482304912923823920000000000000000000000001293123098123928310239129839291010293810'
|
||||||
"latest", {"disableStorage": true, "disableMemory": true})
|
},
|
||||||
|
'latest',
|
||||||
|
{ disableStorage: true, disableMemory: true }
|
||||||
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
It is possible to supply 'overrides' for both state-data (accounts/storage) and block data (number, timestamp etc). In the example below, a call which executes `NUMBER` is performed, and the overridden number is placed on the stack:
|
It is possible to supply 'overrides' for both state-data (accounts/storage) and block data (number, timestamp etc). In the example below, a call which executes `NUMBER` is performed, and the overridden number is placed on the stack:
|
||||||
|
@ -731,26 +734,26 @@ Sets the logging verbosity pattern.
|
||||||
|
|
||||||
If you want to see messages from a particular Go package (directory) and all subdirectories, use:
|
If you want to see messages from a particular Go package (directory) and all subdirectories, use:
|
||||||
|
|
||||||
``` js
|
```js
|
||||||
> debug.vmodule("eth/*=6")
|
> debug.vmodule("eth/*=6")
|
||||||
```
|
```
|
||||||
|
|
||||||
If you want to restrict messages to a particular package (e.g. p2p) but exclude subdirectories, use:
|
If you want to restrict messages to a particular package (e.g. p2p) but exclude subdirectories, use:
|
||||||
|
|
||||||
``` js
|
```js
|
||||||
> debug.vmodule("p2p=6")
|
> debug.vmodule("p2p=6")
|
||||||
```
|
```
|
||||||
|
|
||||||
If you want to see log messages from a particular source file, use
|
If you want to see log messages from a particular source file, use
|
||||||
|
|
||||||
``` js
|
```js
|
||||||
> debug.vmodule("server.go=6")
|
> debug.vmodule("server.go=6")
|
||||||
```
|
```
|
||||||
|
|
||||||
You can compose these basic patterns. If you want to see all output from peer.go in a package below eth (eth/peer.go, eth/downloader/peer.go) as well as output from package p2p at level <= 5, use:
|
You can compose these basic patterns. If you want to see all output from peer.go in a package below eth (eth/peer.go, eth/downloader/peer.go) as well as output from package p2p at level <= 5, use:
|
||||||
|
|
||||||
``` js
|
```js
|
||||||
debug.vmodule("eth/*/peer.go=6,p2p=5")
|
debug.vmodule('eth/*/peer.go=6,p2p=5');
|
||||||
```
|
```
|
||||||
|
|
||||||
### debug_writeBlockProfile
|
### debug_writeBlockProfile
|
||||||
|
|
|
@ -40,7 +40,6 @@ The _state override set_ is an optional address-to-state mapping, where each ent
|
||||||
The goal of the _state override set_ is manyfold:
|
The goal of the _state override set_ is manyfold:
|
||||||
|
|
||||||
- It can be used by DApps to reduce the amount of contract code needed to be deployed on chain. Code that simply returns internal state or does pre-defined validations can be kept off chain and fed to the node on-demand.
|
- It can be used by DApps to reduce the amount of contract code needed to be deployed on chain. Code that simply returns internal state or does pre-defined validations can be kept off chain and fed to the node on-demand.
|
||||||
|
|
||||||
- It can be used for smart contract analysis by extending the code deployed on chain with custom methods and invoking them. This avoids having to download and reconstruct the entire state in a sandbox to run custom code against.
|
- It can be used for smart contract analysis by extending the code deployed on chain with custom methods and invoking them. This avoids having to download and reconstruct the entire state in a sandbox to run custom code against.
|
||||||
|
|
||||||
- It can be used to debug smart contracts in an already deployed large suite of contracts by selectively overriding some code or state and seeing how execution changes. Specialized tooling will probably be necessary.
|
- It can be used to debug smart contracts in an already deployed large suite of contracts by selectively overriding some code or state and seeing how execution changes. Specialized tooling will probably be necessary.
|
||||||
|
|
|
@ -3,7 +3,7 @@ title: personal Namespace
|
||||||
description: Documentation for the JSON-RPC API "personal" namespace
|
description: Documentation for the JSON-RPC API "personal" namespace
|
||||||
---
|
---
|
||||||
|
|
||||||
{% include note.html content="The personal namespace will be deprecated in the very near future." %}
|
<Note>The personal namespace will be deprecated in the very near future.</Note>
|
||||||
|
|
||||||
The personal API managed private keys in the key store. It is deprecated in favour of using [Clef](/docs/tools/clef/Introduction) for interacting with accounts Please refer to the [ns_personal deprecation page](/docs/interacting-with-geth/rpc/ns_personal_deprecation) to see the equivalent methods. The following documentation should be treated as archive information and users should migrate tousing Clef for account interactions.
|
The personal API managed private keys in the key store. It is deprecated in favour of using [Clef](/docs/tools/clef/Introduction) for interacting with accounts Please refer to the [ns_personal deprecation page](/docs/interacting-with-geth/rpc/ns_personal_deprecation) to see the equivalent methods. The following documentation should be treated as archive information and users should migrate tousing Clef for account interactions.
|
||||||
|
|
||||||
|
|
|
@ -34,11 +34,8 @@ to cancel the subscription:
|
||||||
## Considerations {#considerations}
|
## Considerations {#considerations}
|
||||||
|
|
||||||
1. Notifications are sent for current events and not for past events. For use cases that depend on not to miss any notifications subscriptions are probably not the best option.
|
1. Notifications are sent for current events and not for past events. For use cases that depend on not to miss any notifications subscriptions are probably not the best option.
|
||||||
|
|
||||||
2. Subscriptions require a full duplex connection. Geth offers such connections in the form of WebSocket and IPC (enabled by default).
|
2. Subscriptions require a full duplex connection. Geth offers such connections in the form of WebSocket and IPC (enabled by default).
|
||||||
|
|
||||||
3. Subscriptions are coupled to a connection. If the connection is closed all subscriptions that are created over this connection are removed.
|
3. Subscriptions are coupled to a connection. If the connection is closed all subscriptions that are created over this connection are removed.
|
||||||
|
|
||||||
4. Notifications are stored in an internal buffer and sent from this buffer to the client. If the client is unable to keep up and the number of buffered notifications reaches a limit (currently 10k) the connection is closed. Keep in mind that subscribing to some events can cause a flood of notifications, e.g. listening for all logs/blocks when the node starts to synchronize.
|
4. Notifications are stored in an internal buffer and sent from this buffer to the client. If the client is unable to keep up and the number of buffered notifications reaches a limit (currently 10k) the connection is closed. Keep in mind that subscribing to some events can cause a flood of notifications, e.g. listening for all logs/blocks when the node starts to synchronize.
|
||||||
|
|
||||||
## Create subscription {#create-subscriptions}
|
## Create subscription {#create-subscriptions}
|
||||||
|
|
|
@ -10,7 +10,6 @@ There are several ways to monitor the performance of a Geth node. Insights into
|
||||||
To follow along with the instructions on this page it will be useful to have:
|
To follow along with the instructions on this page it will be useful to have:
|
||||||
|
|
||||||
- a running Geth instance.
|
- a running Geth instance.
|
||||||
|
|
||||||
- basic working knowlegde of bash/terminal.
|
- basic working knowlegde of bash/terminal.
|
||||||
|
|
||||||
[This video](https://www.youtube.com/watch?v=cOBab8IJMYI) provides an excellent introduction to Geth monitoring.
|
[This video](https://www.youtube.com/watch?v=cOBab8IJMYI) provides an excellent introduction to Geth monitoring.
|
||||||
|
|
|
@ -50,11 +50,11 @@ each with detailed installation instructions. They all share the common trait th
|
||||||
started with a specific URL that can be passed to Geth.
|
started with a specific URL that can be passed to Geth.
|
||||||
|
|
||||||
[EthNetStats "Classic"](https://github.com/ethereum/eth-netstats)
|
[EthNetStats "Classic"](https://github.com/ethereum/eth-netstats)
|
||||||
|
|
||||||
[EthNet Intelligence API](https://github.com/ethereum/eth-net-intelligence-api)
|
[EthNet Intelligence API](https://github.com/ethereum/eth-net-intelligence-api)
|
||||||
|
|
||||||
[Goerli Ethstats client](https://github.com/goerli/ethstats-client)
|
[Goerli Ethstats client](https://github.com/goerli/ethstats-client)
|
||||||
|
|
||||||
[Goerli Ethstats server](https://github.com/goerli/ethstats-server)
|
[Goerli Ethstats server](https://github.com/goerli/ethstats-server)
|
||||||
|
|
||||||
If enabled, Geth spins up a minimal Ethstats reporting daemon that pushes statistics about the
|
If enabled, Geth spins up a minimal Ethstats reporting daemon that pushes statistics about the
|
||||||
|
|
|
@ -69,6 +69,7 @@ Initiate Geth:
|
||||||
```sh
|
```sh
|
||||||
$ geth --datadir ./ddir init genesis.json
|
$ geth --datadir ./ddir init genesis.json
|
||||||
```
|
```
|
||||||
|
|
||||||
```terminal
|
```terminal
|
||||||
...
|
...
|
||||||
INFO [06-16|11:14:54.123] Writing custom genesis block
|
INFO [06-16|11:14:54.123] Writing custom genesis block
|
||||||
|
@ -90,6 +91,7 @@ These two things are independent of each other. First of all, however, `clef` mu
|
||||||
```sh
|
```sh
|
||||||
$ clef --keystore ./ddir/keystore --configdir ./clef --chainid 15 --suppress-bootwarn init
|
$ clef --keystore ./ddir/keystore --configdir ./clef --chainid 15 --suppress-bootwarn init
|
||||||
```
|
```
|
||||||
|
|
||||||
```terminal
|
```terminal
|
||||||
The master seed of clef will be locked with a password.
|
The master seed of clef will be locked with a password.
|
||||||
Please specify a password. Do not forget this password!
|
Please specify a password. Do not forget this password!
|
||||||
|
@ -117,6 +119,7 @@ With that done, `clef` can be made aware of the password. To do this `setpw <add
|
||||||
```sh
|
```sh
|
||||||
$ clef --keystore ./ddir/keystore --configdir ./clef --chainid 15 --suppress-bootwarn setpw 0x9CD932F670F7eDe5dE86F756A6D02548e5899f47
|
$ clef --keystore ./ddir/keystore --configdir ./clef --chainid 15 --suppress-bootwarn setpw 0x9CD932F670F7eDe5dE86F756A6D02548e5899f47
|
||||||
```
|
```
|
||||||
|
|
||||||
```terminal
|
```terminal
|
||||||
Please enter a password to store for this address:
|
Please enter a password to store for this address:
|
||||||
Password:
|
Password:
|
||||||
|
|
|
@ -12,6 +12,7 @@ First things first, Clef needs to store some data itself. Since that data might
|
||||||
```sh
|
```sh
|
||||||
$ clef init
|
$ clef init
|
||||||
```
|
```
|
||||||
|
|
||||||
```terminal
|
```terminal
|
||||||
WARNING!
|
WARNING!
|
||||||
|
|
||||||
|
@ -134,7 +135,7 @@ geth attach goerli-data/geth.ipc
|
||||||
A simple request to list the accounts in the keystore will cause the Javascript console to hang.
|
A simple request to list the accounts in the keystore will cause the Javascript console to hang.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
eth.accounts
|
eth.accounts;
|
||||||
```
|
```
|
||||||
|
|
||||||
Switching to the Clef terminal reveals that this is because the request is awaiting explicit confirmation from the user. The log is identical to the one shown above, when the same request for account information was made to Clef via Netcat:
|
Switching to the Clef terminal reveals that this is because the request is awaiting explicit confirmation from the user. The log is identical to the one shown above, when the same request for account information was made to Clef via Netcat:
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"react-markdown": "^8.0.3",
|
"react-markdown": "^8.0.3",
|
||||||
"react-syntax-highlighter": "^15.5.0",
|
"react-syntax-highlighter": "^15.5.0",
|
||||||
|
"rehype-raw": "^6.1.1",
|
||||||
"remark-gfm": "^3.0.1"
|
"remark-gfm": "^3.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -1,114 +0,0 @@
|
||||||
import {
|
|
||||||
Flex,
|
|
||||||
Heading,
|
|
||||||
Link,
|
|
||||||
ListItem,
|
|
||||||
OrderedList,
|
|
||||||
Stack,
|
|
||||||
Table,
|
|
||||||
Text,
|
|
||||||
UnorderedList
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
import NextLink from 'next/link';
|
|
||||||
|
|
||||||
import { Code } from './UI/docs';
|
|
||||||
import { textStyles } from '../theme/foundations';
|
|
||||||
|
|
||||||
const { header1, header2, header3, header4 } = textStyles;
|
|
||||||
|
|
||||||
const MDXComponents = {
|
|
||||||
// paragraphs
|
|
||||||
p: ({ children }: any) => {
|
|
||||||
return (
|
|
||||||
<Text mb={7} lineHeight={1.5}>
|
|
||||||
{children}
|
|
||||||
</Text>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
// links
|
|
||||||
a: ({ children, href }: any) => {
|
|
||||||
return (
|
|
||||||
<NextLink href={href} passHref>
|
|
||||||
<Link
|
|
||||||
isExternal={href.startsWith('http') && !href.includes('geth.ethereum.org')}
|
|
||||||
variant='light'
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</Link>
|
|
||||||
</NextLink>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
// headings
|
|
||||||
h1: ({ children }: any) => {
|
|
||||||
return (
|
|
||||||
<Heading as='h1' textAlign='start' mb={5} {...header1}>
|
|
||||||
{children}
|
|
||||||
</Heading>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
h2: ({ children }: any) => {
|
|
||||||
return (
|
|
||||||
<Heading as='h2' textAlign='start' mt='16 !important' mb={4} {...header2}>
|
|
||||||
{children}
|
|
||||||
</Heading>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
h3: ({ children }: any) => {
|
|
||||||
return (
|
|
||||||
<Heading as='h3' mt={5} mb={2.5} {...header3}>
|
|
||||||
{children}
|
|
||||||
</Heading>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
h4: ({ children }: any) => {
|
|
||||||
return (
|
|
||||||
<Heading as='h4' mb={2.5} {...header4}>
|
|
||||||
{children}
|
|
||||||
</Heading>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
// tables
|
|
||||||
table: ({ children }: any) => (
|
|
||||||
<Flex maxW='min(100%, 100vw)' overflowX='scroll'>
|
|
||||||
<Table
|
|
||||||
variant='striped'
|
|
||||||
colorScheme='greenAlpha'
|
|
||||||
border='1px'
|
|
||||||
borderColor='blackAlpha.50'
|
|
||||||
my={6}
|
|
||||||
size={{ base: 'sm', lg: 'md' }}
|
|
||||||
w='auto'
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</Table>
|
|
||||||
</Flex>
|
|
||||||
),
|
|
||||||
// pre
|
|
||||||
pre: ({ children }: any) => (
|
|
||||||
<Stack mb={5}>
|
|
||||||
<pre>{children}</pre>
|
|
||||||
</Stack>
|
|
||||||
),
|
|
||||||
// code
|
|
||||||
code: ({ children, ...props }: any) => <Code {...props}>{children}</Code>,
|
|
||||||
// list
|
|
||||||
ul: ({ children }: any) => {
|
|
||||||
return (
|
|
||||||
<UnorderedList mb={7} px={4}>
|
|
||||||
{children}
|
|
||||||
</UnorderedList>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
ol: ({ children }: any) => {
|
|
||||||
return (
|
|
||||||
<OrderedList mb={7} px={4}>
|
|
||||||
{children}
|
|
||||||
</OrderedList>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
li: ({ children }: any) => {
|
|
||||||
return <ListItem color='primary'>{children}</ListItem>;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default MDXComponents;
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, Stack } from '@chakra-ui/react';
|
||||||
|
import NextLink from 'next/link';
|
||||||
|
import { useRouter } from 'next/router';
|
||||||
|
import { FC } from 'react';
|
||||||
|
|
||||||
|
export const Breadcrumbs: FC = () => {
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
let pathSplit = router.asPath.split('/');
|
||||||
|
pathSplit = pathSplit.splice(1, pathSplit.length);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{router.asPath !== '/docs' ? (
|
||||||
|
<Breadcrumb>
|
||||||
|
{pathSplit.map((path: string, idx: number) => {
|
||||||
|
return (
|
||||||
|
<BreadcrumbItem key={path}>
|
||||||
|
<NextLink href={`/${pathSplit.slice(0, idx + 1).join('/')}`} passHref>
|
||||||
|
<BreadcrumbLink color={idx + 1 === pathSplit.length ? 'body' : 'primary'}>
|
||||||
|
{path}
|
||||||
|
</BreadcrumbLink>
|
||||||
|
</NextLink>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Breadcrumb>
|
||||||
|
) : (
|
||||||
|
<Stack h='24px'></Stack>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
|
@ -73,5 +73,11 @@ export const Code: React.FC<Props> = ({ className, children, inline }) => {
|
||||||
{content}
|
{content}
|
||||||
</SyntaxHighlighter>
|
</SyntaxHighlighter>
|
||||||
);
|
);
|
||||||
return <Stack>{content}</Stack>;
|
return (
|
||||||
|
<Stack>
|
||||||
|
<ChakraCode overflow='auto' p={6} background='terminal-bg' color='terminal-text'>
|
||||||
|
{content}
|
||||||
|
</ChakraCode>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
import { FC } from 'react';
|
||||||
|
import {
|
||||||
|
Accordion,
|
||||||
|
AccordionButton,
|
||||||
|
AccordionItem,
|
||||||
|
AccordionPanel,
|
||||||
|
Center,
|
||||||
|
Link,
|
||||||
|
Stack,
|
||||||
|
Text
|
||||||
|
} from '@chakra-ui/react';
|
||||||
|
import { AddIcon, MinusIcon } from '@chakra-ui/icons';
|
||||||
|
import NextLink from 'next/link';
|
||||||
|
|
||||||
|
import { LinksList } from './';
|
||||||
|
|
||||||
|
import { NavLink } from '../../../types';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
navLinks: NavLink[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DocsLinks: FC<Props> = ({ navLinks }) => (
|
||||||
|
<Stack border='2px' borderColor='primary'>
|
||||||
|
{navLinks.map(({ id, to, items }, idx) => {
|
||||||
|
return (
|
||||||
|
<Accordion key={id} allowToggle mt='0 !important' defaultIndex={[0]}>
|
||||||
|
<AccordionItem border='none'>
|
||||||
|
{({ isExpanded }) => (
|
||||||
|
<>
|
||||||
|
<AccordionButton
|
||||||
|
borderBottom={navLinks.length - 1 === idx ? 'none' : '2px'}
|
||||||
|
p={0}
|
||||||
|
borderColor='primary'
|
||||||
|
justifyContent='space-between'
|
||||||
|
placeContent='flex-end'
|
||||||
|
bg='button-bg'
|
||||||
|
>
|
||||||
|
<Stack
|
||||||
|
p={4}
|
||||||
|
borderRight={items ? '2px' : 'none'}
|
||||||
|
borderColor='primary'
|
||||||
|
w='100%'
|
||||||
|
bg='bg'
|
||||||
|
>
|
||||||
|
{to ? (
|
||||||
|
<NextLink href={to} passHref>
|
||||||
|
<Link>
|
||||||
|
<Text textStyle='docs-nav-dropdown'>{id}</Text>
|
||||||
|
</Link>
|
||||||
|
</NextLink>
|
||||||
|
) : (
|
||||||
|
<Text textStyle='docs-nav-dropdown'>{id}</Text>
|
||||||
|
)}
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
{items && (
|
||||||
|
<Stack minW='61px'>
|
||||||
|
<Center>
|
||||||
|
{isExpanded ? (
|
||||||
|
<MinusIcon w='20px' h='20px' color='primary' />
|
||||||
|
) : (
|
||||||
|
<AddIcon w='20px' h='20px' color='primary' />
|
||||||
|
)}
|
||||||
|
</Center>
|
||||||
|
</Stack>
|
||||||
|
)}
|
||||||
|
</AccordionButton>
|
||||||
|
{items && (
|
||||||
|
<AccordionPanel borderBottom='2px solid' borderColor='primary' px={0} py={4}>
|
||||||
|
<LinksList links={items} />
|
||||||
|
</AccordionPanel>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</AccordionItem>
|
||||||
|
</Accordion>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Stack>
|
||||||
|
);
|
|
@ -0,0 +1,59 @@
|
||||||
|
import { FC } from 'react';
|
||||||
|
import {
|
||||||
|
Accordion,
|
||||||
|
AccordionButton,
|
||||||
|
AccordionIcon,
|
||||||
|
AccordionItem,
|
||||||
|
AccordionPanel,
|
||||||
|
Stack,
|
||||||
|
Text
|
||||||
|
} from '@chakra-ui/react';
|
||||||
|
import { DocsLinks } from './DocsLinks';
|
||||||
|
|
||||||
|
import { NavLink } from '../../../types';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
navLinks: NavLink[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DocsNav: FC<Props> = ({ navLinks }) => {
|
||||||
|
return (
|
||||||
|
<Stack w={{ base: '100%', lg: 72 }}>
|
||||||
|
<Stack display={{ base: 'none', lg: 'block' }}>
|
||||||
|
<DocsLinks navLinks={navLinks} />
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Stack display={{ base: 'block', lg: 'none' }}>
|
||||||
|
<Accordion allowToggle>
|
||||||
|
<AccordionItem border='none'>
|
||||||
|
<AccordionButton
|
||||||
|
display='flex'
|
||||||
|
py={4}
|
||||||
|
px={8}
|
||||||
|
border='2px'
|
||||||
|
borderColor='primary'
|
||||||
|
placeContent='space-between'
|
||||||
|
bg='button-bg'
|
||||||
|
_hover={{
|
||||||
|
bg: 'primary',
|
||||||
|
color: 'bg'
|
||||||
|
}}
|
||||||
|
_expanded={{
|
||||||
|
bg: 'primary',
|
||||||
|
color: 'bg'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text as='h4' textStyle='docs-nav-dropdown'>
|
||||||
|
Documentation
|
||||||
|
</Text>
|
||||||
|
<AccordionIcon />
|
||||||
|
</AccordionButton>
|
||||||
|
<AccordionPanel p={0}>
|
||||||
|
<DocsLinks navLinks={navLinks} />
|
||||||
|
</AccordionPanel>
|
||||||
|
</AccordionItem>
|
||||||
|
</Accordion>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,44 @@
|
||||||
|
import { FC } from 'react';
|
||||||
|
import { Divider, Link, Stack, Text } from '@chakra-ui/react';
|
||||||
|
import NextLink from 'next/link';
|
||||||
|
|
||||||
|
import { parseHeadingId } from '../../../utils/parseHeadingId';
|
||||||
|
import { useActiveHash } from '../../../hooks/useActiveHash';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DocumentNav: FC<Props> = ({ content }) => {
|
||||||
|
const parsedHeadings = content
|
||||||
|
.split('\n\n')
|
||||||
|
.map(item => item.replace(/[\n\r]/g, ''))
|
||||||
|
.filter(item => item.startsWith('#'))
|
||||||
|
.map(item => parseHeadingId([item]))
|
||||||
|
.filter(item => item);
|
||||||
|
|
||||||
|
const activeHash = useActiveHash(parsedHeadings.map(heading => heading!.headingId));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Stack position='sticky' top='4'>
|
||||||
|
<Text as='h5' textStyle='document-nav-title'>
|
||||||
|
on this page
|
||||||
|
</Text>
|
||||||
|
<Divider borderColor='primary' my={`4 !important`} />
|
||||||
|
{parsedHeadings.map((heading, idx) => {
|
||||||
|
return (
|
||||||
|
<NextLink key={`${idx} ${heading?.title}`} href={`#${heading?.headingId}`}>
|
||||||
|
<Link m={0}>
|
||||||
|
<Text
|
||||||
|
color={activeHash === heading?.headingId ? 'body' : 'primary'}
|
||||||
|
textStyle='document-nav-link'
|
||||||
|
>
|
||||||
|
{heading?.title}
|
||||||
|
</Text>
|
||||||
|
</Link>
|
||||||
|
</NextLink>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,35 @@
|
||||||
|
import { FC } from 'react';
|
||||||
|
import { Link, Stack, Text } from '@chakra-ui/react';
|
||||||
|
import NextLink from 'next/link';
|
||||||
|
|
||||||
|
import { NavLink } from '../../../types';
|
||||||
|
|
||||||
|
interface LinksListProps {
|
||||||
|
links: NavLink[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const LinksList: FC<LinksListProps> = ({ links }) => (
|
||||||
|
<Stack px={4}>
|
||||||
|
{links.map(({ id, to, items }) => {
|
||||||
|
return to ? (
|
||||||
|
<Stack key={id}>
|
||||||
|
<NextLink href={to} passHref key={id}>
|
||||||
|
<Link>
|
||||||
|
<Text textStyle='docs-nav-links' color={items ? 'primary' : 'body'}>
|
||||||
|
{id}
|
||||||
|
</Text>
|
||||||
|
</Link>
|
||||||
|
</NextLink>
|
||||||
|
{items && <LinksList links={items} />}
|
||||||
|
</Stack>
|
||||||
|
) : (
|
||||||
|
<Stack key={id}>
|
||||||
|
<Text textStyle='docs-nav-links' color={items ? 'primary' : 'body'}>
|
||||||
|
{id}
|
||||||
|
</Text>
|
||||||
|
{items && <LinksList links={items} />}
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Stack>
|
||||||
|
);
|
|
@ -0,0 +1,153 @@
|
||||||
|
import {
|
||||||
|
Flex,
|
||||||
|
Heading,
|
||||||
|
Link,
|
||||||
|
ListItem,
|
||||||
|
OrderedList,
|
||||||
|
Stack,
|
||||||
|
Table,
|
||||||
|
Text,
|
||||||
|
UnorderedList
|
||||||
|
} from '@chakra-ui/react';
|
||||||
|
import NextLink from 'next/link';
|
||||||
|
|
||||||
|
import { Code, Note } from '.';
|
||||||
|
import { textStyles } from '../../../theme/foundations';
|
||||||
|
import { parseHeadingId } from '../../../utils/parseHeadingId';
|
||||||
|
|
||||||
|
const { header1, header2, header3, header4 } = textStyles;
|
||||||
|
|
||||||
|
const MDComponents = {
|
||||||
|
// paragraphs
|
||||||
|
p: ({ children }: any) => {
|
||||||
|
return (
|
||||||
|
<Text mb='7 !important' lineHeight={1.5}>
|
||||||
|
{children}
|
||||||
|
</Text>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
// links
|
||||||
|
a: ({ children, href }: any) => {
|
||||||
|
return (
|
||||||
|
<NextLink href={href} passHref>
|
||||||
|
<Link
|
||||||
|
isExternal={href.startsWith('http') && !href.includes('geth.ethereum.org')}
|
||||||
|
variant='light'
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Link>
|
||||||
|
</NextLink>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
// headings
|
||||||
|
h1: ({ children }: any) => {
|
||||||
|
const heading = parseHeadingId(children);
|
||||||
|
|
||||||
|
return heading ? (
|
||||||
|
<Heading as='h1' textAlign='start' mb='5 !important' {...header1} id={heading.headingId}>
|
||||||
|
{heading.children}
|
||||||
|
</Heading>
|
||||||
|
) : (
|
||||||
|
<Heading as='h1' textAlign='start' mb='5 !important' {...header1}>
|
||||||
|
{children}
|
||||||
|
</Heading>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
h2: ({ children }: any) => {
|
||||||
|
const heading = parseHeadingId(children);
|
||||||
|
|
||||||
|
return heading ? (
|
||||||
|
<Heading
|
||||||
|
as='h2'
|
||||||
|
textAlign='start'
|
||||||
|
mt='16 !important'
|
||||||
|
mb='4 !important'
|
||||||
|
{...header2}
|
||||||
|
id={heading.headingId}
|
||||||
|
>
|
||||||
|
{heading.children}
|
||||||
|
</Heading>
|
||||||
|
) : (
|
||||||
|
<Heading as='h2' textAlign='start' mt='16 !important' mb='4 !important' {...header2}>
|
||||||
|
{children}
|
||||||
|
</Heading>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
h3: ({ children }: any) => {
|
||||||
|
const heading = parseHeadingId(children);
|
||||||
|
|
||||||
|
return heading ? (
|
||||||
|
<Heading as='h3' mt='5 !important' mb='2.5 !important' {...header3} id={heading.headingId}>
|
||||||
|
{heading.children}
|
||||||
|
</Heading>
|
||||||
|
) : (
|
||||||
|
<Heading as='h3' mt='5 !important' mb='2.5 !important' {...header3}>
|
||||||
|
{children}
|
||||||
|
</Heading>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
h4: ({ children }: any) => {
|
||||||
|
const heading = parseHeadingId(children);
|
||||||
|
|
||||||
|
return heading ? (
|
||||||
|
<Heading as='h4' mb='2.5 !important' {...header4} id={heading.headingId}>
|
||||||
|
{heading.children}
|
||||||
|
</Heading>
|
||||||
|
) : (
|
||||||
|
<Heading as='h4' mb='2.5 !important' {...header4}>
|
||||||
|
{children}
|
||||||
|
</Heading>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
// tables
|
||||||
|
table: ({ children }: any) => (
|
||||||
|
<Flex maxW='min(100%, 100vw)' overflowX='auto'>
|
||||||
|
<Table
|
||||||
|
variant='striped'
|
||||||
|
colorScheme='greenAlpha'
|
||||||
|
border='1px'
|
||||||
|
borderColor='blackAlpha.50'
|
||||||
|
my='6 !important'
|
||||||
|
size={{ base: 'sm', lg: 'md' }}
|
||||||
|
w='auto'
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Table>
|
||||||
|
</Flex>
|
||||||
|
),
|
||||||
|
// pre
|
||||||
|
pre: ({ children }: any) => (
|
||||||
|
<Stack mb={5}>
|
||||||
|
<pre>{children}</pre>
|
||||||
|
</Stack>
|
||||||
|
),
|
||||||
|
// code
|
||||||
|
code: ({ children, ...props }: any) => <Code {...props}>{children}</Code>,
|
||||||
|
// list
|
||||||
|
ul: ({ children }: any) => {
|
||||||
|
return (
|
||||||
|
<Stack>
|
||||||
|
<UnorderedList mb={7} px={4}>
|
||||||
|
{children}
|
||||||
|
</UnorderedList>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
ol: ({ children }: any) => {
|
||||||
|
return (
|
||||||
|
<Stack>
|
||||||
|
<OrderedList mb={7} px={4}>
|
||||||
|
{children}
|
||||||
|
</OrderedList>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
li: ({ children }: any) => {
|
||||||
|
return <ListItem color='primary'>{children}</ListItem>;
|
||||||
|
},
|
||||||
|
note: ({ children }: any) => {
|
||||||
|
return <Note>{children}</Note>;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MDComponents;
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { FC } from 'react';
|
||||||
|
import { Stack, Text } from '@chakra-ui/react';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
children: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Note: FC<Props> = ({ children }) => {
|
||||||
|
return (
|
||||||
|
<Stack w='100%' bg='button-bg' border='2px' borderColor='primary' p={4}>
|
||||||
|
<Text as='h4' textStyle='header4'>
|
||||||
|
Note
|
||||||
|
</Text>
|
||||||
|
<Text textStyle='note-text'>{children}</Text>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,8 @@
|
||||||
|
export * from './Breadcrumbs';
|
||||||
|
export * from './Code';
|
||||||
|
export * from './DocsLinks';
|
||||||
|
export * from './DocsNav';
|
||||||
|
export * from './DocumentNav';
|
||||||
|
export * from './LinkList';
|
||||||
|
export * from './Note';
|
||||||
|
export { default } from './MDComponents';
|
|
@ -1 +0,0 @@
|
||||||
export * from './Code';
|
|
|
@ -1,27 +0,0 @@
|
||||||
import { Breadcrumb, BreadcrumbItem, BreadcrumbLink } from '@chakra-ui/react';
|
|
||||||
import NextLink from 'next/link';
|
|
||||||
import { useRouter } from 'next/router';
|
|
||||||
import { FC } from 'react';
|
|
||||||
|
|
||||||
export const Breadcrumbs: FC = () => {
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
let pathSplit = router.asPath.split('/');
|
|
||||||
pathSplit = pathSplit.splice(1, pathSplit.length);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Breadcrumb>
|
|
||||||
{pathSplit.map((path: string, idx: number) => {
|
|
||||||
return (
|
|
||||||
<BreadcrumbItem key={path}>
|
|
||||||
<NextLink href={`/${pathSplit.slice(0, idx + 1).join('/')}`} passHref>
|
|
||||||
<BreadcrumbLink color={idx + 1 === pathSplit.length ? 'body' : 'primary'}>
|
|
||||||
{path}
|
|
||||||
</BreadcrumbLink>
|
|
||||||
</NextLink>
|
|
||||||
</BreadcrumbItem>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Breadcrumb>
|
|
||||||
);
|
|
||||||
};
|
|
|
@ -1 +0,0 @@
|
||||||
export * from './Breadcrumbs';
|
|
|
@ -1 +0,0 @@
|
||||||
export { default } from './MDXComponents';
|
|
|
@ -0,0 +1,149 @@
|
||||||
|
- id: Getting started
|
||||||
|
to: /docs/getting-started
|
||||||
|
items:
|
||||||
|
- id: Hardware requirements
|
||||||
|
to: /docs/getting-started/hardware-requirements
|
||||||
|
- id: Installing Geth
|
||||||
|
to: /docs/getting-started/installing-geth
|
||||||
|
- id: Consensus clients
|
||||||
|
to: /docs/getting-started/consensus-clients
|
||||||
|
- id: Fundamentals
|
||||||
|
to: /docs/fundamentals
|
||||||
|
items:
|
||||||
|
- id: Node architecture
|
||||||
|
to: /docs/fundamentals/node-architecture
|
||||||
|
- id: Command-line options
|
||||||
|
to: /docs/fundamentals/command-line-options
|
||||||
|
- id: Security
|
||||||
|
to: /docs/fundamentals/security
|
||||||
|
- id: Sync-modes
|
||||||
|
to: /docs/fundamentals/sync-modes
|
||||||
|
- id: Account management
|
||||||
|
to: /docs/fundamentals/account-management
|
||||||
|
- id: Backup restore
|
||||||
|
to: /docs/fundamentals/backup-restore
|
||||||
|
- id: Logs
|
||||||
|
to: /docs/fundamentals/logs
|
||||||
|
- id: Peer-to-peer
|
||||||
|
to: /docs/fundamentals/peer-to-peer
|
||||||
|
- id: Pruning
|
||||||
|
to: /docs/fundamentals/pruning
|
||||||
|
- id: Light client
|
||||||
|
to: /docs/fundamentals/les
|
||||||
|
- id: Mining
|
||||||
|
to: /docs/fundamentals/mining
|
||||||
|
- id: Interacting with Geth
|
||||||
|
items:
|
||||||
|
- id: JSON-RPC Server
|
||||||
|
to: /docs/interacting-with-geth/rpc
|
||||||
|
items:
|
||||||
|
- id: Batch requests
|
||||||
|
to: /docs/interacting-with-geth/rpc/batch
|
||||||
|
- id: GraphQL server
|
||||||
|
to: /docs/interacting-with-geth/rpc/graphql
|
||||||
|
- id: admin Namespace
|
||||||
|
to: /docs/interacting-with-geth/rpc/ns-admin
|
||||||
|
- id: clique Namespace
|
||||||
|
to: /docs/interacting-with-geth/rpc/ns-clique
|
||||||
|
- id: debug Namespace
|
||||||
|
to: /docs/interacting-with-geth/rpc/ns-debug
|
||||||
|
- id: eth Namespace
|
||||||
|
to: /docs/interacting-with-geth/rpc/ns-eth
|
||||||
|
- id: les Namespace
|
||||||
|
to: /docs/interacting-with-geth/rpc/ns-les
|
||||||
|
- id: miner Namespace
|
||||||
|
to: /docs/interacting-with-geth/rpc/ns-miner
|
||||||
|
- id: net Namespace
|
||||||
|
to: /docs/interacting-with-geth/rpc/ns-net
|
||||||
|
- id: Personal namespace deprecation notes
|
||||||
|
to: /docs/interacting-with-geth/rpc/ns-personal-deprecation
|
||||||
|
- id: Personal Namespace
|
||||||
|
to: /docs/interacting-with-geth/rpc/ns-personal
|
||||||
|
- id: txpool Namespace
|
||||||
|
to: /docs/interacting-with-geth/rpc/ns-txpool
|
||||||
|
- id: Objects
|
||||||
|
to: /docs/interacting-with-geth/rpc/objects
|
||||||
|
- id: Real-time Events
|
||||||
|
to: /docs/interacting-with-geth/rpc/pubsub
|
||||||
|
- id: JavaScript Console
|
||||||
|
to: /docs/interacting-with-geth/javascript-console
|
||||||
|
- id: 'JavaScript Console 2: Contracts'
|
||||||
|
to: /docs/interacting-with-geth/javascript-console-contracts
|
||||||
|
- id: Developers
|
||||||
|
to: /docs/developers
|
||||||
|
items:
|
||||||
|
- id: Dapp developers
|
||||||
|
items:
|
||||||
|
- id: Go API
|
||||||
|
to: /docs/developers/dapp-developer/native
|
||||||
|
- id: Go Account Management
|
||||||
|
to: /docs/developers/dapp-developer/native-accounts
|
||||||
|
- id: Go Contract Bindings
|
||||||
|
to: /docs/developers/dapp-developer/native-bindings
|
||||||
|
- id: Geth for Mobile
|
||||||
|
to: /docs/developers/dapp-developer/mobile
|
||||||
|
- id: EVM tracing
|
||||||
|
to: /docs/developers/evm-tracing
|
||||||
|
items:
|
||||||
|
- id: Basic traces
|
||||||
|
to: /docs/developers/evm-tracing/basic-traces
|
||||||
|
- id: Built-in tracers
|
||||||
|
to: /docs/developers/evm-tracing/built-in-tracers
|
||||||
|
- id: Custom EVM tracer
|
||||||
|
to: /docs/developers/evm-tracing/custom-tracer
|
||||||
|
- id: Tutorial for Javascript tracing
|
||||||
|
to: /docs/developers/evm-tracing/javascript-tutorial
|
||||||
|
- id: Geth developer
|
||||||
|
items:
|
||||||
|
- id: Developer guide
|
||||||
|
to: /docs/developers/geth-developer/dev-guide
|
||||||
|
- id: Developer mode
|
||||||
|
to: /docs/developers/geth-developer/dev-mode
|
||||||
|
- id: Disclosures
|
||||||
|
to: /docs/developers/geth-developer/disclosures
|
||||||
|
- id: Issue handling workflow
|
||||||
|
to: /docs/developers/geth-developer/issue-handling-workflow
|
||||||
|
- id: DNS discovery setup guide
|
||||||
|
to: /docs/developers/geth-developer/dns-discovery-setup
|
||||||
|
- id: Code review guidelines
|
||||||
|
to: /docs/developers/geth-developer/code-review-guidelines
|
||||||
|
- id: Private networks
|
||||||
|
to: /docs/developers/geth-developer/private-network
|
||||||
|
- id: Contributing
|
||||||
|
to: /docs/developers/contributing
|
||||||
|
- id: Monitoring
|
||||||
|
items:
|
||||||
|
- id: Dashboards
|
||||||
|
to: /docs/monitoring/dashboards
|
||||||
|
- id: Ethstats
|
||||||
|
to: /docs/monitoring/ethstats
|
||||||
|
- id: Metrics
|
||||||
|
to: /docs/monitoring/metrics
|
||||||
|
- id: Tools
|
||||||
|
items:
|
||||||
|
- id: Clef
|
||||||
|
items:
|
||||||
|
- id: Introduction
|
||||||
|
to: /docs/tools/clef/introduction
|
||||||
|
- id: APIs
|
||||||
|
to: /docs/tools/clef/apis
|
||||||
|
- id: Rules
|
||||||
|
to: /docs/tools/clef/rules
|
||||||
|
- id: Setup
|
||||||
|
to: /docs/tools/clef/setup
|
||||||
|
- id: Datatypes
|
||||||
|
to: /docs/tools/clef/datatypes
|
||||||
|
- id: Tutorial
|
||||||
|
to: /docs/tools/clef/tutorial
|
||||||
|
- id: Clique-signing
|
||||||
|
to: /docs/tools/clef/clique-signing
|
||||||
|
- id: puppeth
|
||||||
|
to: /docs/tools/puppeth
|
||||||
|
- id: Abigen
|
||||||
|
to: /docs/tools/abigen
|
||||||
|
- id: devp2p
|
||||||
|
to: /docs/tools/devp2p
|
||||||
|
- id: FAQs
|
||||||
|
to: /docs/faq
|
||||||
|
- id: Resources
|
||||||
|
to: /docs/resources
|
|
@ -0,0 +1,42 @@
|
||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A hook to determine which section of the page is currently in the viewport.
|
||||||
|
* @param {*} itemIds Array of document ids to observe
|
||||||
|
* @param {*} rootMargin
|
||||||
|
* @returns id of the element currently in viewport
|
||||||
|
*/
|
||||||
|
export const useActiveHash = (itemIds: Array<string>, rootMargin = `0% 0% -80% 0%`): string => {
|
||||||
|
const [activeHash, setActiveHash] = useState(``);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const observer = new IntersectionObserver(
|
||||||
|
entries => {
|
||||||
|
entries.forEach(entry => {
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
setActiveHash(`${entry.target.id}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
{ rootMargin }
|
||||||
|
);
|
||||||
|
|
||||||
|
itemIds?.forEach(id => {
|
||||||
|
const element = document.getElementById(id);
|
||||||
|
if (element !== null) {
|
||||||
|
observer.observe(element);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
itemIds?.forEach(id => {
|
||||||
|
const element = document.getElementById(id);
|
||||||
|
if (element !== null) {
|
||||||
|
observer.unobserve(element);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}, [itemIds, rootMargin]);
|
||||||
|
|
||||||
|
return activeHash;
|
||||||
|
};
|
|
@ -1,16 +1,24 @@
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import matter from 'gray-matter';
|
import matter from 'gray-matter';
|
||||||
import yaml from 'js-yaml';
|
import yaml from 'js-yaml';
|
||||||
import { Stack, Heading, Text } from '@chakra-ui/react';
|
import { Flex, Stack, Heading, Text } from '@chakra-ui/react';
|
||||||
import ChakraUIRenderer from 'chakra-ui-markdown-renderer';
|
import ChakraUIRenderer from 'chakra-ui-markdown-renderer';
|
||||||
import ReactMarkdown from 'react-markdown';
|
import ReactMarkdown from 'react-markdown';
|
||||||
|
import { useRouter } from 'next/router';
|
||||||
|
import { useEffect } from 'react';
|
||||||
import gfm from 'remark-gfm';
|
import gfm from 'remark-gfm';
|
||||||
|
import rehypeRaw from 'rehype-raw';
|
||||||
import { ParsedUrlQuery } from 'querystring';
|
import { ParsedUrlQuery } from 'querystring';
|
||||||
import type { GetStaticPaths, GetStaticProps, NextPage } from 'next';
|
import type { GetStaticPaths, GetStaticProps, NextPage } from 'next';
|
||||||
|
|
||||||
import MDXComponents from '../components/';
|
import MDComponents from '../components/UI/docs';
|
||||||
import { Breadcrumbs } from '../components/docs';
|
import { Breadcrumbs, DocsNav, DocumentNav } from '../components/UI/docs';
|
||||||
import { PageMetadata } from '../components/UI';
|
import { PageMetadata } from '../components/UI';
|
||||||
|
|
||||||
|
import { NavLink } from '../types';
|
||||||
|
|
||||||
|
import { getFileList } from '../utils/getFileList';
|
||||||
|
|
||||||
import { textStyles } from '../theme/foundations';
|
import { textStyles } from '../theme/foundations';
|
||||||
import { getParsedDate } from '../utils';
|
import { getParsedDate } from '../utils';
|
||||||
|
|
||||||
|
@ -22,21 +30,6 @@ const MATTER_OPTIONS = {
|
||||||
|
|
||||||
// This method crawls for all valid docs paths
|
// This method crawls for all valid docs paths
|
||||||
export const getStaticPaths: GetStaticPaths = () => {
|
export const getStaticPaths: GetStaticPaths = () => {
|
||||||
const getFileList = (dirName: string) => {
|
|
||||||
let files: string[] = [];
|
|
||||||
const items = fs.readdirSync(dirName, { withFileTypes: true });
|
|
||||||
|
|
||||||
for (const item of items) {
|
|
||||||
if (item.isDirectory()) {
|
|
||||||
files = [...files, ...getFileList(`${dirName}/${item.name}`)];
|
|
||||||
} else {
|
|
||||||
files.push(`/${dirName}/${item.name}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return files.map(file => file.replace('.md', '')).map(file => file.replace('/index', ''));
|
|
||||||
};
|
|
||||||
|
|
||||||
const paths: string[] = getFileList('docs'); // This is folder that get crawled for valid docs paths. Change if this path changes.
|
const paths: string[] = getFileList('docs'); // This is folder that get crawled for valid docs paths. Change if this path changes.
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -52,6 +45,8 @@ export const getStaticProps: GetStaticProps = async context => {
|
||||||
let file;
|
let file;
|
||||||
let lastModified;
|
let lastModified;
|
||||||
|
|
||||||
|
const navLinks = yaml.load(fs.readFileSync('src/data/documentation-links.yaml', 'utf8'));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
file = fs.readFileSync(`${filePath}.md`, 'utf-8');
|
file = fs.readFileSync(`${filePath}.md`, 'utf-8');
|
||||||
lastModified = fs.statSync(`${filePath}.md`);
|
lastModified = fs.statSync(`${filePath}.md`);
|
||||||
|
@ -66,6 +61,7 @@ export const getStaticProps: GetStaticProps = async context => {
|
||||||
props: {
|
props: {
|
||||||
frontmatter,
|
frontmatter,
|
||||||
content,
|
content,
|
||||||
|
navLinks,
|
||||||
lastModified: getParsedDate(lastModified.mtime, {
|
lastModified: getParsedDate(lastModified.mtime, {
|
||||||
month: 'numeric',
|
month: 'numeric',
|
||||||
day: 'numeric',
|
day: 'numeric',
|
||||||
|
@ -80,27 +76,62 @@ interface Props {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
};
|
};
|
||||||
content: string;
|
content: string;
|
||||||
|
navLinks: NavLink[];
|
||||||
lastModified: string;
|
lastModified: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DocPage: NextPage<Props> = ({ frontmatter, content, lastModified }) => {
|
const DocPage: NextPage<Props> = ({ frontmatter, content, navLinks, lastModified }) => {
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const id = router.asPath.split('#')[1];
|
||||||
|
const element = document.getElementById(id);
|
||||||
|
|
||||||
|
if (!element) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
element.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||||
|
}, [router.asPath]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageMetadata title={frontmatter.title} description={frontmatter.description} />
|
<PageMetadata title={frontmatter.title} description={frontmatter.description} />
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<Stack mb={16}>
|
<Flex direction={{ base: 'column', lg: 'row' }} gap={{ base: 4, lg: 8 }}>
|
||||||
<Breadcrumbs />
|
<Stack>
|
||||||
<Heading as='h1' mt='4 !important' mb={0} {...textStyles.header1}>
|
<DocsNav navLinks={navLinks} />
|
||||||
{frontmatter.title}
|
</Stack>
|
||||||
</Heading>
|
|
||||||
<Text as='span' mt='0 !important'>
|
<Stack pb={4} width='100%'>
|
||||||
last edited {lastModified}
|
<Stack mb={16}>
|
||||||
</Text>
|
<Breadcrumbs />
|
||||||
</Stack>
|
<Heading as='h1' mt='4 !important' mb={0} {...textStyles.header1}>
|
||||||
<ReactMarkdown remarkPlugins={[gfm]} components={ChakraUIRenderer(MDXComponents)}>
|
{frontmatter.title}
|
||||||
{content}
|
</Heading>
|
||||||
</ReactMarkdown>
|
<Text as='span' mt='0 !important'>
|
||||||
|
last edited {lastModified}
|
||||||
|
</Text>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Flex width='100%' placeContent='space-between'>
|
||||||
|
<Stack maxW='768px'>
|
||||||
|
<ReactMarkdown
|
||||||
|
remarkPlugins={[gfm]}
|
||||||
|
rehypePlugins={[rehypeRaw]}
|
||||||
|
components={ChakraUIRenderer(MDComponents)}
|
||||||
|
>
|
||||||
|
{content}
|
||||||
|
</ReactMarkdown>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Stack display={{ base: 'none', xl: 'block' }} w={48}>
|
||||||
|
<DocumentNav content={content} />
|
||||||
|
</Stack>
|
||||||
|
</Flex>
|
||||||
|
</Stack>
|
||||||
|
</Flex>
|
||||||
</main>
|
</main>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { MDXProvider } from '@mdx-js/react';
|
||||||
|
|
||||||
import { Layout } from '../components/layouts';
|
import { Layout } from '../components/layouts';
|
||||||
|
|
||||||
import MDXComponents from '../components/';
|
import MDComponents from '../components/UI/docs';
|
||||||
|
|
||||||
import 'focus-visible/dist/focus-visible';
|
import 'focus-visible/dist/focus-visible';
|
||||||
import theme from '../theme';
|
import theme from '../theme';
|
||||||
|
@ -12,7 +12,7 @@ import theme from '../theme';
|
||||||
export default function App({ Component, pageProps }: AppProps) {
|
export default function App({ Component, pageProps }: AppProps) {
|
||||||
return (
|
return (
|
||||||
<ChakraProvider theme={theme}>
|
<ChakraProvider theme={theme}>
|
||||||
<MDXProvider components={MDXComponents}>
|
<MDXProvider components={MDComponents}>
|
||||||
<Layout>
|
<Layout>
|
||||||
<Component {...pageProps} />
|
<Component {...pageProps} />
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
|
@ -107,7 +107,7 @@ export const textStyles = {
|
||||||
color: 'body'
|
color: 'body'
|
||||||
},
|
},
|
||||||
'footer-link-label': {
|
'footer-link-label': {
|
||||||
fontFamily: '"JetBrains Mono", monospace',
|
fontFamily: 'heading',
|
||||||
fontWeight: 700,
|
fontWeight: 700,
|
||||||
textTransform: 'uppercase',
|
textTransform: 'uppercase',
|
||||||
lineHeight: '21.12px',
|
lineHeight: '21.12px',
|
||||||
|
@ -139,13 +139,28 @@ export const textStyles = {
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
fontSize: 'sm'
|
fontSize: 'sm'
|
||||||
},
|
},
|
||||||
|
'docs-nav-dropdown': {
|
||||||
|
fontFamily: 'heading',
|
||||||
|
fontWeight: 400,
|
||||||
|
fontSize: '18px',
|
||||||
|
lineHeight: 6,
|
||||||
|
letterSpacing: '4%',
|
||||||
|
textAlign: 'left'
|
||||||
|
},
|
||||||
|
'docs-nav-links': {
|
||||||
|
fontFamily: 'heading',
|
||||||
|
weight: 400,
|
||||||
|
fontSize: 'md',
|
||||||
|
lineHeight: 8,
|
||||||
|
letterSpacing: '0.01em'
|
||||||
|
},
|
||||||
'header-button': {
|
'header-button': {
|
||||||
fontFamily: '"JetBrains Mono", monospace',
|
fontFamily: 'heading',
|
||||||
fontWeight: 700,
|
fontWeight: 700,
|
||||||
fontSize: { base: '0.86rem', sm: '1rem' }
|
fontSize: { base: '0.86rem', sm: '1rem' }
|
||||||
},
|
},
|
||||||
'header-mobile-button': {
|
'header-mobile-button': {
|
||||||
fontFamily: '"JetBrains Mono", monospace',
|
fontFamily: 'heading',
|
||||||
textTransform: 'uppercase',
|
textTransform: 'uppercase',
|
||||||
fontSize: '2xl'
|
fontSize: '2xl'
|
||||||
},
|
},
|
||||||
|
@ -163,8 +178,25 @@ export const textStyles = {
|
||||||
lineHeight: '21.12px',
|
lineHeight: '21.12px',
|
||||||
letterSpacing: '0.01rem'
|
letterSpacing: '0.01rem'
|
||||||
},
|
},
|
||||||
// TODO: refactor w/ semantic tokens for light/dark mode
|
'document-nav-title': {
|
||||||
'link-light': {},
|
fontFamily: 'heading',
|
||||||
// TODO: refactor w/ semantic tokens for light/dark mode
|
fontWeight: 400,
|
||||||
'text-light': {}
|
fontSize: 'md',
|
||||||
|
lineHeight: '21.12px',
|
||||||
|
letterSpacing: '2%'
|
||||||
|
},
|
||||||
|
'document-nav-link': {
|
||||||
|
fontFamily: 'body',
|
||||||
|
fontWeight: 400,
|
||||||
|
fontSize: '13px',
|
||||||
|
lineHeight: 5,
|
||||||
|
letterSpacing: '1%',
|
||||||
|
mb: 4
|
||||||
|
},
|
||||||
|
'note-text': {
|
||||||
|
fontFamily: 'body',
|
||||||
|
fontWeight: 400,
|
||||||
|
fontSize: 'md',
|
||||||
|
lineHeight: '26px'
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,6 +35,12 @@ export interface ReleaseParams {
|
||||||
isStableRelease: boolean;
|
isStableRelease: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface NavLink {
|
||||||
|
id: string;
|
||||||
|
to?: string;
|
||||||
|
items?: NavLink[];
|
||||||
|
}
|
||||||
|
|
||||||
export interface OpenPGPSignaturesData {
|
export interface OpenPGPSignaturesData {
|
||||||
'build server': string;
|
'build server': string;
|
||||||
'unique id': string;
|
'unique id': string;
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
import fs from 'fs';
|
||||||
|
|
||||||
|
export const getFileList = (dirName: string) => {
|
||||||
|
let files: string[] = [];
|
||||||
|
const items = fs.readdirSync(dirName, { withFileTypes: true });
|
||||||
|
|
||||||
|
for (const item of items) {
|
||||||
|
if (item.isDirectory()) {
|
||||||
|
files = [...files, ...getFileList(`${dirName}/${item.name}`)];
|
||||||
|
} else {
|
||||||
|
files.push(`/${dirName}/${item.name}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return files.map(file => file.replace('.md', '')).map(file => file.replace('/index', ''));
|
||||||
|
};
|
|
@ -0,0 +1,18 @@
|
||||||
|
const check = '{#';
|
||||||
|
|
||||||
|
export const parseHeadingId = (children: string[]) => {
|
||||||
|
if (children[children.length - 1].includes(check)) {
|
||||||
|
const temp = children[children.length - 1].split(check);
|
||||||
|
const headingId = temp[temp.length - 1].split('}')[0];
|
||||||
|
|
||||||
|
children[children.length - 1] = temp[0];
|
||||||
|
|
||||||
|
return {
|
||||||
|
children,
|
||||||
|
title: temp[0].replaceAll('#', ''),
|
||||||
|
headingId
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
103
yarn.lock
103
yarn.lock
|
@ -1269,6 +1269,11 @@
|
||||||
resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz"
|
resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz"
|
||||||
integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
|
integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
|
||||||
|
|
||||||
|
"@types/parse5@^6.0.0":
|
||||||
|
version "6.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-6.0.3.tgz#705bb349e789efa06f43f128cef51240753424cb"
|
||||||
|
integrity sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==
|
||||||
|
|
||||||
"@types/prop-types@*", "@types/prop-types@^15.0.0":
|
"@types/prop-types@*", "@types/prop-types@^15.0.0":
|
||||||
version "15.7.5"
|
version "15.7.5"
|
||||||
resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz"
|
resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz"
|
||||||
|
@ -2427,11 +2432,62 @@ has@^1.0.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
function-bind "^1.1.1"
|
function-bind "^1.1.1"
|
||||||
|
|
||||||
|
hast-to-hyperscript@^10.0.0:
|
||||||
|
version "10.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/hast-to-hyperscript/-/hast-to-hyperscript-10.0.1.tgz#3decd7cb4654bca8883f6fcbd4fb3695628c4296"
|
||||||
|
integrity sha512-dhIVGoKCQVewFi+vz3Vt567E4ejMppS1haBRL6TEmeLeJVB1i/FJIIg/e6s1Bwn0g5qtYojHEKvyGA+OZuyifw==
|
||||||
|
dependencies:
|
||||||
|
"@types/unist" "^2.0.0"
|
||||||
|
comma-separated-tokens "^2.0.0"
|
||||||
|
property-information "^6.0.0"
|
||||||
|
space-separated-tokens "^2.0.0"
|
||||||
|
style-to-object "^0.3.0"
|
||||||
|
unist-util-is "^5.0.0"
|
||||||
|
web-namespaces "^2.0.0"
|
||||||
|
|
||||||
|
hast-util-from-parse5@^7.0.0:
|
||||||
|
version "7.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-7.1.0.tgz#c129dd3a24dd8a867ab8a029ca47e27aa54864b7"
|
||||||
|
integrity sha512-m8yhANIAccpU4K6+121KpPP55sSl9/samzQSQGpb0mTExcNh2WlvjtMwSWFhg6uqD4Rr6Nfa8N6TMypQM51rzQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/hast" "^2.0.0"
|
||||||
|
"@types/parse5" "^6.0.0"
|
||||||
|
"@types/unist" "^2.0.0"
|
||||||
|
hastscript "^7.0.0"
|
||||||
|
property-information "^6.0.0"
|
||||||
|
vfile "^5.0.0"
|
||||||
|
vfile-location "^4.0.0"
|
||||||
|
web-namespaces "^2.0.0"
|
||||||
|
|
||||||
hast-util-parse-selector@^2.0.0:
|
hast-util-parse-selector@^2.0.0:
|
||||||
version "2.2.5"
|
version "2.2.5"
|
||||||
resolved "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz"
|
resolved "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz"
|
||||||
integrity sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==
|
integrity sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==
|
||||||
|
|
||||||
|
hast-util-parse-selector@^3.0.0:
|
||||||
|
version "3.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-3.1.0.tgz#a519e27e8b61bd5a98fad494ed06131ce68d9c3f"
|
||||||
|
integrity sha512-AyjlI2pTAZEOeu7GeBPZhROx0RHBnydkQIXlhnFzDi0qfXTmGUWoCYZtomHbrdrheV4VFUlPcfJ6LMF5T6sQzg==
|
||||||
|
dependencies:
|
||||||
|
"@types/hast" "^2.0.0"
|
||||||
|
|
||||||
|
hast-util-raw@^7.2.0:
|
||||||
|
version "7.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/hast-util-raw/-/hast-util-raw-7.2.2.tgz#1974360b2d7f15b5ce26c2a4bac892d5d8185a18"
|
||||||
|
integrity sha512-0x3BhhdlBcqRIKyc095lBSDvmQNMY3Eulj2PLsT5XCyKYrxssI5yr3P4Kv/PBo1s/DMkZy2voGkMXECnFCZRLQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/hast" "^2.0.0"
|
||||||
|
"@types/parse5" "^6.0.0"
|
||||||
|
hast-util-from-parse5 "^7.0.0"
|
||||||
|
hast-util-to-parse5 "^7.0.0"
|
||||||
|
html-void-elements "^2.0.0"
|
||||||
|
parse5 "^6.0.0"
|
||||||
|
unist-util-position "^4.0.0"
|
||||||
|
unist-util-visit "^4.0.0"
|
||||||
|
vfile "^5.0.0"
|
||||||
|
web-namespaces "^2.0.0"
|
||||||
|
zwitch "^2.0.0"
|
||||||
|
|
||||||
hast-util-to-estree@^2.0.0:
|
hast-util-to-estree@^2.0.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-2.1.0.tgz"
|
resolved "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-2.1.0.tgz"
|
||||||
|
@ -2453,6 +2509,18 @@ hast-util-to-estree@^2.0.0:
|
||||||
unist-util-position "^4.0.0"
|
unist-util-position "^4.0.0"
|
||||||
zwitch "^2.0.0"
|
zwitch "^2.0.0"
|
||||||
|
|
||||||
|
hast-util-to-parse5@^7.0.0:
|
||||||
|
version "7.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/hast-util-to-parse5/-/hast-util-to-parse5-7.0.0.tgz#a39808e69005d10afeed1866029a1fb137df3f7c"
|
||||||
|
integrity sha512-YHiS6aTaZ3N0Q3nxaY/Tj98D6kM8QX5Q8xqgg8G45zR7PvWnPGPP0vcKCgb/moIydEJ/QWczVrX0JODCVeoV7A==
|
||||||
|
dependencies:
|
||||||
|
"@types/hast" "^2.0.0"
|
||||||
|
"@types/parse5" "^6.0.0"
|
||||||
|
hast-to-hyperscript "^10.0.0"
|
||||||
|
property-information "^6.0.0"
|
||||||
|
web-namespaces "^2.0.0"
|
||||||
|
zwitch "^2.0.0"
|
||||||
|
|
||||||
hast-util-whitespace@^2.0.0:
|
hast-util-whitespace@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.0.tgz"
|
resolved "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.0.tgz"
|
||||||
|
@ -2469,6 +2537,17 @@ hastscript@^6.0.0:
|
||||||
property-information "^5.0.0"
|
property-information "^5.0.0"
|
||||||
space-separated-tokens "^1.0.0"
|
space-separated-tokens "^1.0.0"
|
||||||
|
|
||||||
|
hastscript@^7.0.0:
|
||||||
|
version "7.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-7.1.0.tgz#e402ed48f46161cf2f093badbff30583a5c3c315"
|
||||||
|
integrity sha512-uBjaTTLN0MkCZxY/R2fWUOcu7FRtUVzKRO5P/RAfgsu3yFiMB1JWCO4AjeVkgHxAira1f2UecHK5WfS9QurlWA==
|
||||||
|
dependencies:
|
||||||
|
"@types/hast" "^2.0.0"
|
||||||
|
comma-separated-tokens "^2.0.0"
|
||||||
|
hast-util-parse-selector "^3.0.0"
|
||||||
|
property-information "^6.0.0"
|
||||||
|
space-separated-tokens "^2.0.0"
|
||||||
|
|
||||||
hey-listen@^1.0.8:
|
hey-listen@^1.0.8:
|
||||||
version "1.0.8"
|
version "1.0.8"
|
||||||
resolved "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz"
|
resolved "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz"
|
||||||
|
@ -2486,6 +2565,11 @@ hoist-non-react-statics@^3.3.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
react-is "^16.7.0"
|
react-is "^16.7.0"
|
||||||
|
|
||||||
|
html-void-elements@^2.0.0:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-2.0.1.tgz#29459b8b05c200b6c5ee98743c41b979d577549f"
|
||||||
|
integrity sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==
|
||||||
|
|
||||||
ignore@^5.2.0:
|
ignore@^5.2.0:
|
||||||
version "5.2.0"
|
version "5.2.0"
|
||||||
resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz"
|
resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz"
|
||||||
|
@ -3617,6 +3701,11 @@ parse-json@^5.0.0:
|
||||||
json-parse-even-better-errors "^2.3.0"
|
json-parse-even-better-errors "^2.3.0"
|
||||||
lines-and-columns "^1.1.6"
|
lines-and-columns "^1.1.6"
|
||||||
|
|
||||||
|
parse5@^6.0.0:
|
||||||
|
version "6.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
|
||||||
|
integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==
|
||||||
|
|
||||||
path-exists@^4.0.0:
|
path-exists@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz"
|
resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz"
|
||||||
|
@ -3867,6 +3956,15 @@ regexpp@^3.2.0:
|
||||||
resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz"
|
resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz"
|
||||||
integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==
|
integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==
|
||||||
|
|
||||||
|
rehype-raw@^6.1.1:
|
||||||
|
version "6.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/rehype-raw/-/rehype-raw-6.1.1.tgz#81bbef3793bd7abacc6bf8335879d1b6c868c9d4"
|
||||||
|
integrity sha512-d6AKtisSRtDRX4aSPsJGTfnzrX2ZkHQLE5kiUuGOeEoLpbEulFF4hj0mLPbsa+7vmguDKOVVEQdHKDSwoaIDsQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/hast" "^2.0.0"
|
||||||
|
hast-util-raw "^7.2.0"
|
||||||
|
unified "^10.0.0"
|
||||||
|
|
||||||
remark-gfm@^3.0.1:
|
remark-gfm@^3.0.1:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/remark-gfm/-/remark-gfm-3.0.1.tgz#0b180f095e3036545e9dddac0e8df3fa5cfee54f"
|
resolved "https://registry.yarnpkg.com/remark-gfm/-/remark-gfm-3.0.1.tgz#0b180f095e3036545e9dddac0e8df3fa5cfee54f"
|
||||||
|
@ -4389,6 +4487,11 @@ vfile@^5.0.0:
|
||||||
unist-util-stringify-position "^3.0.0"
|
unist-util-stringify-position "^3.0.0"
|
||||||
vfile-message "^3.0.0"
|
vfile-message "^3.0.0"
|
||||||
|
|
||||||
|
web-namespaces@^2.0.0:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-2.0.1.tgz#1010ff7c650eccb2592cebeeaf9a1b253fd40692"
|
||||||
|
integrity sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==
|
||||||
|
|
||||||
which-boxed-primitive@^1.0.2:
|
which-boxed-primitive@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz"
|
resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz"
|
||||||
|
|
Loading…
Reference in New Issue