feat: you can now abort transaction confirmations in web3.js (#29057)
* Upgrade Typescript, `@types/node`, and `typedoc` to versions that play well together In this instance it means they: * understand `AbortSignal` * don't cause build errors * You can now abort transaction confirmation using an `AbortSignal` * Pipe an `AbortSignal` down through `sendAndConfirmTransaction()` * Add `AbortController` polyfill to test so that test works in Node 14
This commit is contained in:
parent
9725a4552e
commit
35f3c18aa8
|
@ -95,7 +95,7 @@
|
||||||
"@types/express-serve-static-core": "^4.17.21",
|
"@types/express-serve-static-core": "^4.17.21",
|
||||||
"@types/mocha": "^10.0.0",
|
"@types/mocha": "^10.0.0",
|
||||||
"@types/mz": "^2.7.3",
|
"@types/mz": "^2.7.3",
|
||||||
"@types/node": "^17.0.24",
|
"@types/node": "^18.11.10",
|
||||||
"@types/node-fetch": "2",
|
"@types/node-fetch": "2",
|
||||||
"@types/sinon": "^10.0.0",
|
"@types/sinon": "^10.0.0",
|
||||||
"@types/sinon-chai": "^3.2.8",
|
"@types/sinon-chai": "^3.2.8",
|
||||||
|
@ -114,6 +114,7 @@
|
||||||
"mocha": "^10.1.0",
|
"mocha": "^10.1.0",
|
||||||
"mockttp": "^2.0.1",
|
"mockttp": "^2.0.1",
|
||||||
"mz": "^2.7.0",
|
"mz": "^2.7.0",
|
||||||
|
"node-abort-controller": "^3.0.1",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"nyc": "^15.1.0",
|
"nyc": "^15.1.0",
|
||||||
"prettier": "^2.3.0",
|
"prettier": "^2.3.0",
|
||||||
|
@ -129,8 +130,8 @@
|
||||||
"ts-mocha": "^10.0.0",
|
"ts-mocha": "^10.0.0",
|
||||||
"ts-node": "^10.0.0",
|
"ts-node": "^10.0.0",
|
||||||
"tslib": "^2.1.0",
|
"tslib": "^2.1.0",
|
||||||
"typedoc": "^0.22.2",
|
"typedoc": "^0.23",
|
||||||
"typescript": "^4.3.2"
|
"typescript": "^4.9"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12.20.0"
|
"node": ">=12.20.0"
|
||||||
|
|
|
@ -311,9 +311,39 @@ export type BlockhashWithExpiryBlockHeight = Readonly<{
|
||||||
* A strategy for confirming transactions that uses the last valid
|
* A strategy for confirming transactions that uses the last valid
|
||||||
* block height for a given blockhash to check for transaction expiration.
|
* block height for a given blockhash to check for transaction expiration.
|
||||||
*/
|
*/
|
||||||
export type BlockheightBasedTransactionConfirmationStrategy = {
|
export type BlockheightBasedTransactionConfirmationStrategy =
|
||||||
|
BaseTransactionConfirmationStrategy & BlockhashWithExpiryBlockHeight;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A strategy for confirming durable nonce transactions.
|
||||||
|
*/
|
||||||
|
export type DurableNonceTransactionConfirmationStrategy =
|
||||||
|
BaseTransactionConfirmationStrategy & {
|
||||||
|
/**
|
||||||
|
* The lowest slot at which to fetch the nonce value from the
|
||||||
|
* nonce account. This should be no lower than the slot at
|
||||||
|
* which the last-known value of the nonce was fetched.
|
||||||
|
*/
|
||||||
|
minContextSlot: number;
|
||||||
|
/**
|
||||||
|
* The account where the current value of the nonce is stored.
|
||||||
|
*/
|
||||||
|
nonceAccountPubkey: PublicKey;
|
||||||
|
/**
|
||||||
|
* The nonce value that was used to sign the transaction
|
||||||
|
* for which confirmation is being sought.
|
||||||
|
*/
|
||||||
|
nonceValue: DurableNonce;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Properties shared by all transaction confirmation strategies
|
||||||
|
*/
|
||||||
|
export type BaseTransactionConfirmationStrategy = Readonly<{
|
||||||
|
/** A signal that, when aborted, cancels any outstanding transaction confirmation operations */
|
||||||
|
abortSignal?: AbortSignal;
|
||||||
signature: TransactionSignature;
|
signature: TransactionSignature;
|
||||||
} & BlockhashWithExpiryBlockHeight;
|
}>;
|
||||||
|
|
||||||
/* @internal */
|
/* @internal */
|
||||||
function assertEndpointUrl(putativeUrl: string) {
|
function assertEndpointUrl(putativeUrl: string) {
|
||||||
|
@ -340,28 +370,6 @@ function extractCommitmentFromConfig<TConfig>(
|
||||||
return {commitment, config};
|
return {commitment, config};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A strategy for confirming durable nonce transactions.
|
|
||||||
*/
|
|
||||||
export type DurableNonceTransactionConfirmationStrategy = {
|
|
||||||
/**
|
|
||||||
* The lowest slot at which to fetch the nonce value from the
|
|
||||||
* nonce account. This should be no lower than the slot at
|
|
||||||
* which the last-known value of the nonce was fetched.
|
|
||||||
*/
|
|
||||||
minContextSlot: number;
|
|
||||||
/**
|
|
||||||
* The account where the current value of the nonce is stored.
|
|
||||||
*/
|
|
||||||
nonceAccountPubkey: PublicKey;
|
|
||||||
/**
|
|
||||||
* The nonce value that was used to sign the transaction
|
|
||||||
* for which confirmation is being sought.
|
|
||||||
*/
|
|
||||||
nonceValue: DurableNonce;
|
|
||||||
signature: TransactionSignature;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
|
@ -3571,6 +3579,9 @@ export class Connection {
|
||||||
const config = strategy as
|
const config = strategy as
|
||||||
| BlockheightBasedTransactionConfirmationStrategy
|
| BlockheightBasedTransactionConfirmationStrategy
|
||||||
| DurableNonceTransactionConfirmationStrategy;
|
| DurableNonceTransactionConfirmationStrategy;
|
||||||
|
if (config.abortSignal?.aborted) {
|
||||||
|
return Promise.reject(config.abortSignal.reason);
|
||||||
|
}
|
||||||
rawSignature = config.signature;
|
rawSignature = config.signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3602,6 +3613,21 @@ export class Connection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getCancellationPromise(signal?: AbortSignal): Promise<never> {
|
||||||
|
return new Promise<never>((_, reject) => {
|
||||||
|
if (signal == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (signal.aborted) {
|
||||||
|
reject(signal.reason);
|
||||||
|
} else {
|
||||||
|
signal.addEventListener('abort', () => {
|
||||||
|
reject(signal.reason);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private getTransactionConfirmationPromise({
|
private getTransactionConfirmationPromise({
|
||||||
commitment,
|
commitment,
|
||||||
signature,
|
signature,
|
||||||
|
@ -3722,7 +3748,7 @@ export class Connection {
|
||||||
|
|
||||||
private async confirmTransactionUsingBlockHeightExceedanceStrategy({
|
private async confirmTransactionUsingBlockHeightExceedanceStrategy({
|
||||||
commitment,
|
commitment,
|
||||||
strategy: {lastValidBlockHeight, signature},
|
strategy: {abortSignal, lastValidBlockHeight, signature},
|
||||||
}: {
|
}: {
|
||||||
commitment?: Commitment;
|
commitment?: Commitment;
|
||||||
strategy: BlockheightBasedTransactionConfirmationStrategy;
|
strategy: BlockheightBasedTransactionConfirmationStrategy;
|
||||||
|
@ -3753,9 +3779,14 @@ export class Connection {
|
||||||
});
|
});
|
||||||
const {abortConfirmation, confirmationPromise} =
|
const {abortConfirmation, confirmationPromise} =
|
||||||
this.getTransactionConfirmationPromise({commitment, signature});
|
this.getTransactionConfirmationPromise({commitment, signature});
|
||||||
|
const cancellationPromise = this.getCancellationPromise(abortSignal);
|
||||||
let result: RpcResponseAndContext<SignatureResult>;
|
let result: RpcResponseAndContext<SignatureResult>;
|
||||||
try {
|
try {
|
||||||
const outcome = await Promise.race([confirmationPromise, expiryPromise]);
|
const outcome = await Promise.race([
|
||||||
|
cancellationPromise,
|
||||||
|
confirmationPromise,
|
||||||
|
expiryPromise,
|
||||||
|
]);
|
||||||
if (outcome.__type === TransactionStatus.PROCESSED) {
|
if (outcome.__type === TransactionStatus.PROCESSED) {
|
||||||
result = outcome.response;
|
result = outcome.response;
|
||||||
} else {
|
} else {
|
||||||
|
@ -3770,7 +3801,13 @@ export class Connection {
|
||||||
|
|
||||||
private async confirmTransactionUsingDurableNonceStrategy({
|
private async confirmTransactionUsingDurableNonceStrategy({
|
||||||
commitment,
|
commitment,
|
||||||
strategy: {minContextSlot, nonceAccountPubkey, nonceValue, signature},
|
strategy: {
|
||||||
|
abortSignal,
|
||||||
|
minContextSlot,
|
||||||
|
nonceAccountPubkey,
|
||||||
|
nonceValue,
|
||||||
|
signature,
|
||||||
|
},
|
||||||
}: {
|
}: {
|
||||||
commitment?: Commitment;
|
commitment?: Commitment;
|
||||||
strategy: DurableNonceTransactionConfirmationStrategy;
|
strategy: DurableNonceTransactionConfirmationStrategy;
|
||||||
|
@ -3821,9 +3858,14 @@ export class Connection {
|
||||||
});
|
});
|
||||||
const {abortConfirmation, confirmationPromise} =
|
const {abortConfirmation, confirmationPromise} =
|
||||||
this.getTransactionConfirmationPromise({commitment, signature});
|
this.getTransactionConfirmationPromise({commitment, signature});
|
||||||
|
const cancellationPromise = this.getCancellationPromise(abortSignal);
|
||||||
let result: RpcResponseAndContext<SignatureResult>;
|
let result: RpcResponseAndContext<SignatureResult>;
|
||||||
try {
|
try {
|
||||||
const outcome = await Promise.race([confirmationPromise, expiryPromise]);
|
const outcome = await Promise.race([
|
||||||
|
cancellationPromise,
|
||||||
|
confirmationPromise,
|
||||||
|
expiryPromise,
|
||||||
|
]);
|
||||||
if (outcome.__type === TransactionStatus.PROCESSED) {
|
if (outcome.__type === TransactionStatus.PROCESSED) {
|
||||||
result = outcome.response;
|
result = outcome.response;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -26,7 +26,7 @@ function nextPowerOfTwo(n: number) {
|
||||||
/**
|
/**
|
||||||
* Epoch schedule
|
* Epoch schedule
|
||||||
* (see https://docs.solana.com/terminology#epoch)
|
* (see https://docs.solana.com/terminology#epoch)
|
||||||
* Can be retrieved with the {@link connection.getEpochSchedule} method
|
* Can be retrieved with the {@link Connection.getEpochSchedule} method
|
||||||
*/
|
*/
|
||||||
export class EpochSchedule {
|
export class EpochSchedule {
|
||||||
/** The maximum number of slots in each epoch */
|
/** The maximum number of slots in each epoch */
|
||||||
|
|
|
@ -19,7 +19,11 @@ export async function sendAndConfirmTransaction(
|
||||||
connection: Connection,
|
connection: Connection,
|
||||||
transaction: Transaction,
|
transaction: Transaction,
|
||||||
signers: Array<Signer>,
|
signers: Array<Signer>,
|
||||||
options?: ConfirmOptions,
|
options?: ConfirmOptions &
|
||||||
|
Readonly<{
|
||||||
|
// A signal that, when aborted, cancels any outstanding transaction confirmation operations
|
||||||
|
abortSignal?: AbortSignal;
|
||||||
|
}>,
|
||||||
): Promise<TransactionSignature> {
|
): Promise<TransactionSignature> {
|
||||||
const sendOptions = options && {
|
const sendOptions = options && {
|
||||||
skipPreflight: options.skipPreflight,
|
skipPreflight: options.skipPreflight,
|
||||||
|
@ -42,6 +46,7 @@ export async function sendAndConfirmTransaction(
|
||||||
status = (
|
status = (
|
||||||
await connection.confirmTransaction(
|
await connection.confirmTransaction(
|
||||||
{
|
{
|
||||||
|
abortSignal: options?.abortSignal,
|
||||||
signature: signature,
|
signature: signature,
|
||||||
blockhash: transaction.recentBlockhash,
|
blockhash: transaction.recentBlockhash,
|
||||||
lastValidBlockHeight: transaction.lastValidBlockHeight,
|
lastValidBlockHeight: transaction.lastValidBlockHeight,
|
||||||
|
@ -58,6 +63,7 @@ export async function sendAndConfirmTransaction(
|
||||||
status = (
|
status = (
|
||||||
await connection.confirmTransaction(
|
await connection.confirmTransaction(
|
||||||
{
|
{
|
||||||
|
abortSignal: options?.abortSignal,
|
||||||
minContextSlot: transaction.minNonceContextSlot,
|
minContextSlot: transaction.minNonceContextSlot,
|
||||||
nonceAccountPubkey,
|
nonceAccountPubkey,
|
||||||
nonceValue: transaction.nonceInfo.nonce,
|
nonceValue: transaction.nonceInfo.nonce,
|
||||||
|
@ -67,6 +73,13 @@ export async function sendAndConfirmTransaction(
|
||||||
)
|
)
|
||||||
).value;
|
).value;
|
||||||
} else {
|
} else {
|
||||||
|
if (options?.abortSignal != null) {
|
||||||
|
console.warn(
|
||||||
|
'sendAndConfirmTransaction(): A transaction with a deprecated confirmation strategy was ' +
|
||||||
|
'supplied along with an `abortSignal`. Only transactions having `lastValidBlockHeight` ' +
|
||||||
|
'or a combination of `nonceInfo` and `minNonceContextSlot` are abortable.',
|
||||||
|
);
|
||||||
|
}
|
||||||
status = (
|
status = (
|
||||||
await connection.confirmTransaction(
|
await connection.confirmTransaction(
|
||||||
signature,
|
signature,
|
||||||
|
|
|
@ -3,6 +3,7 @@ import {Buffer} from 'buffer';
|
||||||
import * as splToken from '@solana/spl-token';
|
import * as splToken from '@solana/spl-token';
|
||||||
import {expect, use} from 'chai';
|
import {expect, use} from 'chai';
|
||||||
import chaiAsPromised from 'chai-as-promised';
|
import chaiAsPromised from 'chai-as-promised';
|
||||||
|
import {AbortController} from 'node-abort-controller';
|
||||||
import {mock, useFakeTimers, SinonFakeTimers} from 'sinon';
|
import {mock, useFakeTimers, SinonFakeTimers} from 'sinon';
|
||||||
import sinonChai from 'sinon-chai';
|
import sinonChai from 'sinon-chai';
|
||||||
|
|
||||||
|
@ -1167,6 +1168,44 @@ describe('Connection', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('block height strategy', () => {
|
describe('block height strategy', () => {
|
||||||
|
it('rejects if called with an already-aborted `abortSignal`', () => {
|
||||||
|
const mockSignature =
|
||||||
|
'w2Zeq8YkpyB463DttvfzARD7k9ZxGEwbsEw4boEK7jDp3pfoxZbTdLFSsEPhzXhpCcjGi2kHtHFobgX49MMhbWt';
|
||||||
|
const abortController = new AbortController();
|
||||||
|
abortController.abort();
|
||||||
|
expect(
|
||||||
|
connection.confirmTransaction({
|
||||||
|
abortSignal: abortController.signal,
|
||||||
|
blockhash: 'sampleBlockhash',
|
||||||
|
lastValidBlockHeight: 1,
|
||||||
|
signature: mockSignature,
|
||||||
|
}),
|
||||||
|
).to.eventually.be.rejectedWith('AbortError');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejects upon receiving an abort signal', async () => {
|
||||||
|
const mockSignature =
|
||||||
|
'w2Zeq8YkpyB463DttvfzARD7k9ZxGEwbsEw4boEK7jDp3pfoxZbTdLFSsEPhzXhpCcjGi2kHtHFobgX49MMhbWt';
|
||||||
|
const abortController = new AbortController();
|
||||||
|
// Keep the subscription from ever returning data.
|
||||||
|
await mockRpcMessage({
|
||||||
|
method: 'signatureSubscribe',
|
||||||
|
params: [mockSignature, {commitment: 'finalized'}],
|
||||||
|
result: new Promise(() => {}), // Never resolve.
|
||||||
|
});
|
||||||
|
clock.runAllAsync();
|
||||||
|
const confirmationPromise = connection.confirmTransaction({
|
||||||
|
abortSignal: abortController.signal,
|
||||||
|
blockhash: 'sampleBlockhash',
|
||||||
|
lastValidBlockHeight: 1,
|
||||||
|
signature: mockSignature,
|
||||||
|
});
|
||||||
|
clock.runAllAsync();
|
||||||
|
expect(confirmationPromise).not.to.have.been.rejected;
|
||||||
|
abortController.abort();
|
||||||
|
await expect(confirmationPromise).to.eventually.be.rejected;
|
||||||
|
});
|
||||||
|
|
||||||
it('throws a `TransactionExpiredBlockheightExceededError` when the block height advances past the last valid one for this transaction without a signature confirmation', async () => {
|
it('throws a `TransactionExpiredBlockheightExceededError` when the block height advances past the last valid one for this transaction without a signature confirmation', async () => {
|
||||||
const mockSignature =
|
const mockSignature =
|
||||||
'4oCEqwGrMdBeMxpzuWiukCYqSfV4DsSKXSiVVCh1iJ6pS772X7y219JZP3mgqBz5PhsvprpKyhzChjYc3VSBQXzG';
|
'4oCEqwGrMdBeMxpzuWiukCYqSfV4DsSKXSiVVCh1iJ6pS772X7y219JZP3mgqBz5PhsvprpKyhzChjYc3VSBQXzG';
|
||||||
|
@ -1295,6 +1334,46 @@ describe('Connection', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('nonce strategy', () => {
|
describe('nonce strategy', () => {
|
||||||
|
it('rejects if called with an already-aborted `abortSignal`', () => {
|
||||||
|
const mockSignature =
|
||||||
|
'w2Zeq8YkpyB463DttvfzARD7k9ZxGEwbsEw4boEK7jDp3pfoxZbTdLFSsEPhzXhpCcjGi2kHtHFobgX49MMhbWt';
|
||||||
|
const abortController = new AbortController();
|
||||||
|
abortController.abort();
|
||||||
|
expect(
|
||||||
|
connection.confirmTransaction({
|
||||||
|
abortSignal: abortController.signal,
|
||||||
|
minContextSlot: 1,
|
||||||
|
nonceAccountPubkey: new PublicKey(1),
|
||||||
|
nonceValue: 'fakenonce',
|
||||||
|
signature: mockSignature,
|
||||||
|
}),
|
||||||
|
).to.eventually.be.rejectedWith('AbortError');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejects upon receiving an abort signal', async () => {
|
||||||
|
const mockSignature =
|
||||||
|
'w2Zeq8YkpyB463DttvfzARD7k9ZxGEwbsEw4boEK7jDp3pfoxZbTdLFSsEPhzXhpCcjGi2kHtHFobgX49MMhbWt';
|
||||||
|
const abortController = new AbortController();
|
||||||
|
// Keep the subscription from ever returning data.
|
||||||
|
await mockRpcMessage({
|
||||||
|
method: 'signatureSubscribe',
|
||||||
|
params: [mockSignature, {commitment: 'finalized'}],
|
||||||
|
result: new Promise(() => {}), // Never resolve.
|
||||||
|
});
|
||||||
|
clock.runAllAsync();
|
||||||
|
const confirmationPromise = connection.confirmTransaction({
|
||||||
|
abortSignal: abortController.signal,
|
||||||
|
minContextSlot: 1,
|
||||||
|
nonceAccountPubkey: new PublicKey(1),
|
||||||
|
nonceValue: 'fakenonce',
|
||||||
|
signature: mockSignature,
|
||||||
|
});
|
||||||
|
clock.runAllAsync();
|
||||||
|
expect(confirmationPromise).not.to.have.been.rejected;
|
||||||
|
abortController.abort();
|
||||||
|
await expect(confirmationPromise).to.eventually.be.rejected;
|
||||||
|
});
|
||||||
|
|
||||||
it('confirms the transaction if the signature confirmation is received before the nonce is advanced', async () => {
|
it('confirms the transaction if the signature confirmation is received before the nonce is advanced', async () => {
|
||||||
const mockSignature =
|
const mockSignature =
|
||||||
'4oCEqwGrMdBeMxpzuWiukCYqSfV4DsSKXSiVVCh1iJ6pS772X7y219JZP3mgqBz5PhsvprpKyhzChjYc3VSBQXzG';
|
'4oCEqwGrMdBeMxpzuWiukCYqSfV4DsSKXSiVVCh1iJ6pS772X7y219JZP3mgqBz5PhsvprpKyhzChjYc3VSBQXzG';
|
||||||
|
|
|
@ -1654,7 +1654,7 @@
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
form-data "^3.0.0"
|
form-data "^3.0.0"
|
||||||
|
|
||||||
"@types/node@*", "@types/node@^17.0.24":
|
"@types/node@*":
|
||||||
version "17.0.35"
|
version "17.0.35"
|
||||||
resolved "https://registry.npmjs.org/@types/node/-/node-17.0.35.tgz"
|
resolved "https://registry.npmjs.org/@types/node/-/node-17.0.35.tgz"
|
||||||
|
|
||||||
|
@ -1666,6 +1666,11 @@
|
||||||
version "16.11.27"
|
version "16.11.27"
|
||||||
resolved "https://registry.npmjs.org/@types/node/-/node-16.11.27.tgz"
|
resolved "https://registry.npmjs.org/@types/node/-/node-16.11.27.tgz"
|
||||||
|
|
||||||
|
"@types/node@^18.11.10":
|
||||||
|
version "18.11.10"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.10.tgz#4c64759f3c2343b7e6c4b9caf761c7a3a05cee34"
|
||||||
|
integrity sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==
|
||||||
|
|
||||||
"@types/normalize-package-data@^2.4.0":
|
"@types/normalize-package-data@^2.4.0":
|
||||||
version "2.4.1"
|
version "2.4.1"
|
||||||
resolved "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz"
|
resolved "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz"
|
||||||
|
@ -3569,7 +3574,7 @@ glob-parent@^6.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-glob "^4.0.3"
|
is-glob "^4.0.3"
|
||||||
|
|
||||||
glob@7.2.0, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.0:
|
glob@7.2.0, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
|
||||||
version "7.2.0"
|
version "7.2.0"
|
||||||
resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz"
|
resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -4633,10 +4638,15 @@ marked-terminal@^5.0.0:
|
||||||
node-emoji "^1.11.0"
|
node-emoji "^1.11.0"
|
||||||
supports-hyperlinks "^2.2.0"
|
supports-hyperlinks "^2.2.0"
|
||||||
|
|
||||||
marked@^4.0.10, marked@^4.0.12:
|
marked@^4.0.10:
|
||||||
version "4.0.16"
|
version "4.0.16"
|
||||||
resolved "https://registry.npmjs.org/marked/-/marked-4.0.16.tgz"
|
resolved "https://registry.npmjs.org/marked/-/marked-4.0.16.tgz"
|
||||||
|
|
||||||
|
marked@^4.0.19:
|
||||||
|
version "4.2.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/marked/-/marked-4.2.3.tgz#bd76a5eb510ff1d8421bc6c3b2f0b93488c15bea"
|
||||||
|
integrity sha512-slWRdJkbTZ+PjkyJnE30Uid64eHwbwa1Q25INCAYfZlK4o6ylagBy/Le9eWntqJFoFT93ikUKMv47GZ4gTwHkw==
|
||||||
|
|
||||||
matched@^5.0.0:
|
matched@^5.0.0:
|
||||||
version "5.0.1"
|
version "5.0.1"
|
||||||
resolved "https://registry.npmjs.org/matched/-/matched-5.0.1.tgz"
|
resolved "https://registry.npmjs.org/matched/-/matched-5.0.1.tgz"
|
||||||
|
@ -4743,6 +4753,13 @@ minimatch@^5.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion "^2.0.1"
|
brace-expansion "^2.0.1"
|
||||||
|
|
||||||
|
minimatch@^5.1.0:
|
||||||
|
version "5.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.1.tgz#6c9dffcf9927ff2a31e74b5af11adf8b9604b022"
|
||||||
|
integrity sha512-362NP+zlprccbEt/SkxKfRMHnNY85V74mVnpUpNyr3F35covl09Kec7/sEFLt3RA4oXmewtoaanoIf67SE5Y5g==
|
||||||
|
dependencies:
|
||||||
|
brace-expansion "^2.0.1"
|
||||||
|
|
||||||
minimist-options@4.1.0:
|
minimist-options@4.1.0:
|
||||||
version "4.1.0"
|
version "4.1.0"
|
||||||
resolved "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz"
|
resolved "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz"
|
||||||
|
@ -4981,6 +4998,11 @@ no-case@^3.0.4:
|
||||||
lower-case "^2.0.2"
|
lower-case "^2.0.2"
|
||||||
tslib "^2.0.3"
|
tslib "^2.0.3"
|
||||||
|
|
||||||
|
node-abort-controller@^3.0.1:
|
||||||
|
version "3.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-3.0.1.tgz#f91fa50b1dee3f909afabb7e261b1e1d6b0cb74e"
|
||||||
|
integrity sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw==
|
||||||
|
|
||||||
node-addon-api@^2.0.0:
|
node-addon-api@^2.0.0:
|
||||||
version "2.0.2"
|
version "2.0.2"
|
||||||
resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz"
|
resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz"
|
||||||
|
@ -6224,13 +6246,14 @@ shell-quote@^1.6.1:
|
||||||
version "1.7.3"
|
version "1.7.3"
|
||||||
resolved "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz"
|
resolved "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz"
|
||||||
|
|
||||||
shiki@^0.10.1:
|
shiki@^0.11.1:
|
||||||
version "0.10.1"
|
version "0.11.1"
|
||||||
resolved "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz"
|
resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.11.1.tgz#df0f719e7ab592c484d8b73ec10e215a503ab8cc"
|
||||||
|
integrity sha512-EugY9VASFuDqOexOgXR18ZV+TbFrQHeCpEYaXamO+SZlsnT/2LxuLBX25GGtIrwaEVFXUAbUQ601SWE2rMwWHA==
|
||||||
dependencies:
|
dependencies:
|
||||||
jsonc-parser "^3.0.0"
|
jsonc-parser "^3.0.0"
|
||||||
vscode-oniguruma "^1.6.1"
|
vscode-oniguruma "^1.6.1"
|
||||||
vscode-textmate "5.2.0"
|
vscode-textmate "^6.0.0"
|
||||||
|
|
||||||
side-channel@^1.0.4:
|
side-channel@^1.0.4:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
|
@ -6812,19 +6835,20 @@ typedarray-to-buffer@^3.1.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-typedarray "^1.0.0"
|
is-typedarray "^1.0.0"
|
||||||
|
|
||||||
typedoc@^0.22.2:
|
typedoc@^0.23:
|
||||||
version "0.22.15"
|
version "0.23.21"
|
||||||
resolved "https://registry.npmjs.org/typedoc/-/typedoc-0.22.15.tgz"
|
resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.23.21.tgz#2a6b0e155f91ffa9689086706ad7e3e4bc11d241"
|
||||||
|
integrity sha512-VNE9Jv7BgclvyH9moi2mluneSviD43dCE9pY8RWkO88/DrEgJZk9KpUk7WO468c9WWs/+aG6dOnoH7ccjnErhg==
|
||||||
dependencies:
|
dependencies:
|
||||||
glob "^7.2.0"
|
|
||||||
lunr "^2.3.9"
|
lunr "^2.3.9"
|
||||||
marked "^4.0.12"
|
marked "^4.0.19"
|
||||||
minimatch "^5.0.1"
|
minimatch "^5.1.0"
|
||||||
shiki "^0.10.1"
|
shiki "^0.11.1"
|
||||||
|
|
||||||
typescript@^4.3.2:
|
typescript@^4.9:
|
||||||
version "4.6.4"
|
version "4.9.3"
|
||||||
resolved "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.3.tgz#3aea307c1746b8c384435d8ac36b8a2e580d85db"
|
||||||
|
integrity sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==
|
||||||
|
|
||||||
uglify-js@^3.1.4:
|
uglify-js@^3.1.4:
|
||||||
version "3.15.3"
|
version "3.15.3"
|
||||||
|
@ -6978,9 +7002,10 @@ vscode-oniguruma@^1.6.1:
|
||||||
version "1.6.2"
|
version "1.6.2"
|
||||||
resolved "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz"
|
resolved "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz"
|
||||||
|
|
||||||
vscode-textmate@5.2.0:
|
vscode-textmate@^6.0.0:
|
||||||
version "5.2.0"
|
version "6.0.0"
|
||||||
resolved "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz"
|
resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-6.0.0.tgz#a3777197235036814ac9a92451492f2748589210"
|
||||||
|
integrity sha512-gu73tuZfJgu+mvCSy4UZwd2JXykjK9zAZsfmDeut5dx/1a7FeTk0XwJsSuqQn+cuMCGVbIBfl+s53X4T19DnzQ==
|
||||||
|
|
||||||
wait-on@6.0.0:
|
wait-on@6.0.0:
|
||||||
version "6.0.0"
|
version "6.0.0"
|
||||||
|
|
Loading…
Reference in New Issue