Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
e4103622
Unverified
Commit
e4103622
authored
Jun 01, 2021
by
smartcontracts
Committed by
GitHub
Jun 01, 2021
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' into regenesis/0.4.0
parents
c4c7beaa
5e3c5d1c
Changes
23
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
1085 additions
and
21 deletions
+1085
-21
cool-baboons-guess.md
.changeset/cool-baboons-guess.md
+5
-0
nasty-dots-grow.md
.changeset/nasty-dots-grow.md
+6
-0
sharp-files-knock.md
.changeset/sharp-files-knock.md
+5
-0
client.go
l2geth/rollup/client.go
+2
-2
transport-db.ts
packages/data-transport-layer/src/db/transport-db.ts
+26
-3
sequencer-batch-appended.ts
...ervices/l1-ingestion/handlers/sequencer-batch-appended.ts
+3
-3
transaction-enqueued.ts
...rc/services/l1-ingestion/handlers/transaction-enqueued.ts
+1
-1
transaction.ts
...t-layer/src/services/l2-ingestion/handlers/transaction.ts
+2
-2
database-types.ts
packages/data-transport-layer/src/types/database-types.ts
+2
-2
event-handler-types.ts
...ges/data-transport-layer/src/types/event-handler-types.ts
+1
-1
sequencer-batch-appended.spec.ts
...es/l1-ingestion/handlers/sequencer-batch-appended.spec.ts
+1
-1
transaction-enqueued.spec.ts
...rvices/l1-ingestion/handlers/transaction-enqueued.spec.ts
+2
-2
hardhat.config.ts
packages/message-relayer/hardhat.config.ts
+15
-0
package.json
packages/message-relayer/package.json
+15
-2
index.ts
packages/message-relayer/src/index.ts
+1
-0
relay-tx.ts
packages/message-relayer/src/relay-tx.ts
+418
-0
setup.ts
packages/message-relayer/test/setup.ts
+12
-0
MockL2CrossDomainMessenger.sol
...elayer/test/test-contracts/MockL2CrossDomainMessenger.sol
+44
-0
relay-tx.spec.ts
packages/message-relayer/test/unit-tests/relay-tx.spec.ts
+377
-0
smockit.ts
packages/smock/src/smockit/smockit.ts
+9
-2
TestHelpers_MockCaller.sol
packages/smock/test/contracts/TestHelpers_MockCaller.sol
+8
-0
call-assertions.spec.ts
packages/smock/test/smockit/call-assertions.spec.ts
+72
-0
yarn.lock
yarn.lock
+58
-0
No files found.
.changeset/cool-baboons-guess.md
0 → 100644
View file @
e4103622
---
'
@eth-optimism/smock'
:
patch
---
Fixes a bug that would break call assertions for overloaded smocked functions
.changeset/nasty-dots-grow.md
0 → 100644
View file @
e4103622
---
'
@eth-optimism/l2geth'
:
patch
'
@eth-optimism/data-transport-layer'
:
patch
---
Fix gasLimit overflow
.changeset/sharp-files-knock.md
0 → 100644
View file @
e4103622
---
'
@eth-optimism/message-relayer'
:
patch
---
Adds a new set of tools for generating messages to be relayed and their proofs
l2geth/rollup/client.go
View file @
e4103622
...
...
@@ -69,7 +69,7 @@ type transaction struct {
BlockNumber
uint64
`json:"blockNumber"`
Timestamp
uint64
`json:"timestamp"`
Value
hexutil
.
Uint64
`json:"value"`
GasLimit
uint64
`json:"gasLimit"`
GasLimit
uint64
`json:"gasLimit
,string
"`
Target
common
.
Address
`json:"target"`
Origin
*
common
.
Address
`json:"origin"`
Data
hexutil
.
Bytes
`json:"data"`
...
...
@@ -83,7 +83,7 @@ type Enqueue struct {
Index
*
uint64
`json:"ctcIndex"`
Target
*
common
.
Address
`json:"target"`
Data
*
hexutil
.
Bytes
`json:"data"`
GasLimit
*
uint64
`json:"gasLimit"`
GasLimit
*
uint64
`json:"gasLimit
,string
"`
Origin
*
common
.
Address
`json:"origin"`
BlockNumber
*
uint64
`json:"blockNumber"`
Timestamp
*
uint64
`json:"timestamp"`
...
...
packages/data-transport-layer/src/db/transport-db.ts
View file @
e4103622
...
...
@@ -379,8 +379,9 @@ export class TransportDB {
if
(
index
===
null
)
{
return
null
}
return
this
.
db
.
get
<
TEntry
>
(
`
${
key
}
:index`
,
index
)
let
entry
=
await
this
.
db
.
get
<
TEntry
>
(
`
${
key
}
:index`
,
index
)
entry
=
stringify
(
entry
)
return
entry
}
private
async
_getEntries
<
TEntry
extends
Indexed
>
(
...
...
@@ -388,6 +389,28 @@ export class TransportDB {
startIndex
:
number
,
endIndex
:
number
):
Promise
<
TEntry
[]
|
[]
>
{
return
this
.
db
.
range
<
TEntry
>
(
`
${
key
}
:index`
,
startIndex
,
endIndex
)
const
entries
=
await
this
.
db
.
range
<
TEntry
>
(
`
${
key
}
:index`
,
startIndex
,
endIndex
)
const
results
=
[]
for
(
const
entry
of
entries
)
{
results
.
push
(
stringify
(
entry
))
}
return
results
}
}
function
stringify
(
entry
)
{
if
(
entry
===
null
||
entry
===
undefined
)
{
return
entry
}
if
(
entry
.
gasLimit
)
{
entry
.
gasLimit
=
BigNumber
.
from
(
entry
.
gasLimit
).
toString
()
}
if
(
entry
.
decoded
)
{
entry
.
decoded
.
gasLimit
=
BigNumber
.
from
(
entry
.
decoded
.
gasLimit
).
toString
()
}
return
entry
}
packages/data-transport-layer/src/services/l1-ingestion/handlers/sequencer-batch-appended.ts
View file @
e4103622
...
...
@@ -69,7 +69,7 @@ export const handleEventsSequencerBatchAppended: EventHandlerSet<
submitter
:
l1Transaction
.
from
,
l1TransactionHash
:
l1Transaction
.
hash
,
l1TransactionData
:
l1Transaction
.
data
,
gasLimit
:
SEQUENCER_GAS_LIMIT
,
gasLimit
:
`
${
SEQUENCER_GAS_LIMIT
}
`
,
prevTotalElements
:
batchSubmissionEvent
.
args
.
_prevTotalElements
,
batchIndex
:
batchSubmissionEvent
.
args
.
_batchIndex
,
...
...
@@ -115,7 +115,7 @@ export const handleEventsSequencerBatchAppended: EventHandlerSet<
batchIndex
:
extraData
.
batchIndex
.
toNumber
(),
blockNumber
:
BigNumber
.
from
(
context
.
blockNumber
).
toNumber
(),
timestamp
:
BigNumber
.
from
(
context
.
timestamp
).
toNumber
(),
gasLimit
:
BigNumber
.
from
(
extraData
.
gasLimit
).
to
Number
(),
gasLimit
:
BigNumber
.
from
(
extraData
.
gasLimit
).
to
String
(),
target
:
SEQUENCER_ENTRYPOINT_ADDRESS
,
origin
:
null
,
data
:
toHexString
(
sequencerTransaction
),
...
...
@@ -147,7 +147,7 @@ export const handleEventsSequencerBatchAppended: EventHandlerSet<
batchIndex
:
extraData
.
batchIndex
.
toNumber
(),
blockNumber
:
BigNumber
.
from
(
0
).
toNumber
(),
timestamp
:
BigNumber
.
from
(
0
).
toNumber
(),
gasLimit
:
BigNumber
.
from
(
0
).
to
Number
(),
gasLimit
:
BigNumber
.
from
(
0
).
to
String
(),
target
:
constants
.
AddressZero
,
origin
:
constants
.
AddressZero
,
data
:
'
0x
'
,
...
...
packages/data-transport-layer/src/services/l1-ingestion/handlers/transaction-enqueued.ts
View file @
e4103622
...
...
@@ -17,7 +17,7 @@ export const handleEventsTransactionEnqueued: EventHandlerSet<
index
:
event
.
args
.
_queueIndex
.
toNumber
(),
target
:
event
.
args
.
_target
,
data
:
event
.
args
.
_data
,
gasLimit
:
event
.
args
.
_gasLimit
.
to
Number
(),
gasLimit
:
event
.
args
.
_gasLimit
.
to
String
(),
origin
:
event
.
args
.
_l1TxOrigin
,
blockNumber
:
BigNumber
.
from
(
event
.
blockNumber
).
toNumber
(),
timestamp
:
event
.
args
.
_timestamp
.
toNumber
(),
...
...
packages/data-transport-layer/src/services/l2-ingestion/handlers/transaction.ts
View file @
e4103622
...
...
@@ -57,7 +57,7 @@ export const handleSequencerBlock = {
transactionEntry
=
{
...
transactionEntry
,
gasLimit
:
SEQUENCER_GAS_LIMIT
,
// ?
gasLimit
:
`
${
SEQUENCER_GAS_LIMIT
}
`
,
// ?
target
:
SEQUENCER_ENTRYPOINT_ADDRESS
,
origin
:
null
,
data
:
serialize
(
...
...
@@ -82,7 +82,7 @@ export const handleSequencerBlock = {
}
else
{
transactionEntry
=
{
...
transactionEntry
,
gasLimit
:
BigNumber
.
from
(
transaction
.
gas
).
to
Number
(),
gasLimit
:
BigNumber
.
from
(
transaction
.
gas
).
to
String
(),
target
:
ethers
.
utils
.
getAddress
(
transaction
.
to
),
origin
:
ethers
.
utils
.
getAddress
(
transaction
.
l1TxOrigin
),
data
:
transaction
.
input
,
...
...
packages/data-transport-layer/src/types/database-types.ts
View file @
e4103622
...
...
@@ -16,7 +16,7 @@ export interface EnqueueEntry {
index
:
number
target
:
string
data
:
string
gasLimit
:
number
gasLimit
:
string
origin
:
string
blockNumber
:
number
timestamp
:
number
...
...
@@ -28,7 +28,7 @@ export interface TransactionEntry {
data
:
string
blockNumber
:
number
timestamp
:
number
gasLimit
:
number
gasLimit
:
string
target
:
string
origin
:
string
value
:
string
...
...
packages/data-transport-layer/src/types/event-handler-types.ts
View file @
e4103622
...
...
@@ -40,7 +40,7 @@ export interface SequencerBatchAppendedExtraData {
submitter
:
string
l1TransactionData
:
string
l1TransactionHash
:
string
gasLimit
:
number
gasLimit
:
string
// Stuff from TransactionBatchAppended.
prevTotalElements
:
BigNumber
...
...
packages/data-transport-layer/test/unit-tests/services/l1-ingestion/handlers/sequencer-batch-appended.spec.ts
View file @
e4103622
...
...
@@ -18,7 +18,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.SequencerBatchAppended',
submitter
:
'
0xfd7d4de366850c08ee2cba32d851385a3071ec8d
'
,
l1TransactionHash
:
'
0x6effe006836b841205ace4d99d7ae1b74ee96aac499a3f358b97fccd32ee9af2
'
,
gasLimit
:
548976
,
gasLimit
:
'
548976
'
,
prevTotalElements
:
BigNumber
.
from
(
73677
),
batchIndex
:
BigNumber
.
from
(
743
),
batchSize
:
BigNumber
.
from
(
101
),
...
...
packages/data-transport-layer/test/unit-tests/services/l1-ingestion/handlers/transaction-enqueued.spec.ts
View file @
e4103622
...
...
@@ -93,7 +93,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.TransactionEnqueued', ()
}
})
it
(
'
should have a gasLimit equal to the
integer
value of the _gasLimit argument
'
,
()
=>
{
it
(
'
should have a gasLimit equal to the
string
value of the _gasLimit argument
'
,
()
=>
{
for
(
let
i
=
0
;
i
<
Number
.
MAX_SAFE_INTEGER
;
...
...
@@ -113,7 +113,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.TransactionEnqueued', ()
const
output1
=
handleEventsTransactionEnqueued
.
parseEvent
(...
input1
)
const
expected1
=
BigNumber
.
from
(
i
).
to
Number
()
const
expected1
=
BigNumber
.
from
(
i
).
to
String
()
expect
(
output1
).
to
.
have
.
property
(
'
gasLimit
'
,
expected1
)
}
...
...
packages/message-relayer/hardhat.config.ts
0 → 100644
View file @
e4103622
import
{
HardhatUserConfig
}
from
'
hardhat/config
'
import
'
@nomiclabs/hardhat-ethers
'
import
'
@nomiclabs/hardhat-waffle
'
const
config
:
HardhatUserConfig
=
{
paths
:
{
sources
:
'
./test/test-contracts
'
,
},
solidity
:
{
version
:
'
0.7.6
'
,
},
}
export
default
config
packages/message-relayer/package.json
View file @
e4103622
...
...
@@ -14,7 +14,8 @@
"clean"
:
"rimraf dist/ ./tsconfig.build.tsbuildinfo"
,
"lint"
:
"yarn lint:fix && yarn lint:check"
,
"lint:fix"
:
"prettier --config .prettierrc.json --write
\"
{src,exec,test}/**/*.ts
\"
"
,
"lint:check"
:
"tslint --format stylish --project ."
"lint:check"
:
"tslint --format stylish --project ."
,
"test"
:
"hardhat test --show-stack-traces"
},
"keywords"
:
[
"optimism"
,
...
...
@@ -30,9 +31,9 @@
},
"dependencies"
:
{
"@eth-optimism/common-ts"
:
"^0.1.2"
,
"bcfg"
:
"^0.1.6"
,
"@eth-optimism/contracts"
:
"^0.3.3"
,
"@eth-optimism/core-utils"
:
"^0.4.3"
,
"bcfg"
:
"^0.1.6"
,
"dotenv"
:
"^8.2.0"
,
"ethers"
:
"^5.1.0"
,
"google-spreadsheet"
:
"^3.1.15"
,
...
...
@@ -40,6 +41,18 @@
"rlp"
:
"^2.2.6"
},
"devDependencies"
:
{
"@eth-optimism/smock"
:
"^1.1.4"
,
"@nomiclabs/hardhat-ethers"
:
"^2.0.2"
,
"@nomiclabs/hardhat-waffle"
:
"^2.0.1"
,
"@types/chai"
:
"^4.2.18"
,
"@types/chai-as-promised"
:
"^7.1.4"
,
"@types/mocha"
:
"^8.2.2"
,
"chai"
:
"^4.3.4"
,
"chai-as-promised"
:
"^7.1.1"
,
"ethereum-waffle"
:
"^3.3.0"
,
"hardhat"
:
"^2.3.0"
,
"lodash"
:
"^4.17.21"
,
"mocha"
:
"^8.4.0"
,
"prettier"
:
"^2.2.1"
,
"tslint"
:
"^6.1.3"
,
"tslint-config-prettier"
:
"^1.18.0"
,
...
...
packages/message-relayer/src/index.ts
0 → 100644
View file @
e4103622
export
*
from
'
./relay-tx
'
packages/message-relayer/src/relay-tx.ts
0 → 100644
View file @
e4103622
This diff is collapsed.
Click to expand it.
packages/message-relayer/test/setup.ts
0 → 100644
View file @
e4103622
/* External Imports */
import
chai
=
require
(
'
chai
'
)
import
Mocha
from
'
mocha
'
import
{
solidity
}
from
'
ethereum-waffle
'
import
chaiAsPromised
from
'
chai-as-promised
'
chai
.
use
(
solidity
)
chai
.
use
(
chaiAsPromised
)
const
should
=
chai
.
should
()
const
expect
=
chai
.
expect
export
{
should
,
expect
,
Mocha
}
packages/message-relayer/test/test-contracts/MockL2CrossDomainMessenger.sol
0 → 100644
View file @
e4103622
// SPDX-License-Identifier: MIT
pragma solidity >0.7.0 <0.9.0;
pragma experimental ABIEncoderV2;
contract MockL2CrossDomainMessenger {
struct MessageData {
address target;
address sender;
bytes message;
uint256 messageNonce;
}
event SentMessage(bytes message);
function emitSentMessageEvent(
MessageData memory _message
)
public
{
emit SentMessage(
abi.encodeWithSignature(
"relayMessage(address,address,bytes,uint256)",
_message.target,
_message.sender,
_message.message,
_message.messageNonce
)
);
}
function emitMultipleSentMessageEvents(
MessageData[] memory _messages
)
public
{
for (uint256 i = 0; i < _messages.length; i++) {
emitSentMessageEvent(
_messages[i]
);
}
}
function doNothing() public {}
}
packages/message-relayer/test/unit-tests/relay-tx.spec.ts
0 → 100644
View file @
e4103622
This diff is collapsed.
Click to expand it.
packages/smock/src/smockit/smockit.ts
View file @
e4103622
...
...
@@ -79,18 +79,25 @@ const smockifyFunction = (
let
data
:
any
=
toHexString
(
calldataBuf
)
try
{
data
=
contract
.
interface
.
decodeFunctionData
(
fragment
.
name
,
data
)
data
=
contract
.
interface
.
decodeFunctionData
(
fragment
.
format
(),
data
)
}
catch
(
e
)
{
console
.
error
(
e
)
}
return
{
functionName
:
fragment
.
name
,
functionSignature
:
fragment
.
format
(),
data
,
}
})
.
filter
((
functionResult
:
any
)
=>
{
return
functionResult
.
functionName
===
functionName
return
(
functionResult
.
functionName
===
functionName
||
functionResult
.
functionSignature
===
functionName
)
})
.
map
((
functionResult
:
any
)
=>
{
return
functionResult
.
data
...
...
packages/smock/test/contracts/TestHelpers_MockCaller.sol
0 → 100644
View file @
e4103622
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
contract TestHelpers_MockCaller {
function callMock(address _target, bytes memory _data) public {
_target.call(_data);
}
}
packages/smock/test/smockit/call-assertions.spec.ts
0 → 100644
View file @
e4103622
/* Imports: External */
import
hre
from
'
hardhat
'
import
{
expect
}
from
'
chai
'
import
{
Contract
}
from
'
ethers
'
/* Imports: Internal */
import
{
MockContract
,
smockit
}
from
'
../../src
'
describe
(
'
[smock]: call assertion tests
'
,
()
=>
{
const
ethers
=
(
hre
as
any
).
ethers
let
mock
:
MockContract
beforeEach
(
async
()
=>
{
mock
=
await
smockit
(
'
TestHelpers_BasicReturnContract
'
)
})
let
mockCaller
:
Contract
before
(
async
()
=>
{
const
mockCallerFactory
=
await
ethers
.
getContractFactory
(
'
TestHelpers_MockCaller
'
)
mockCaller
=
await
mockCallerFactory
.
deploy
()
})
describe
(
'
call assertions for functions
'
,
()
=>
{
it
(
'
should be able to make assertions about a non-overloaded function
'
,
async
()
=>
{
mock
.
smocked
.
getInputtedUint256
.
will
.
return
.
with
(
0
)
const
expected1
=
ethers
.
BigNumber
.
from
(
1234
)
await
mockCaller
.
callMock
(
mock
.
address
,
mock
.
interface
.
encodeFunctionData
(
'
getInputtedUint256(uint256)
'
,
[
expected1
,
])
)
expect
(
mock
.
smocked
.
getInputtedUint256
.
calls
[
0
]).
to
.
deep
.
equal
([
expected1
,
])
})
it
(
'
should be able to make assertions about both versions of an overloaded function
'
,
async
()
=>
{
mock
.
smocked
[
'
overloadedFunction(uint256)
'
].
will
.
return
.
with
(
0
)
mock
.
smocked
[
'
overloadedFunction(uint256,uint256)
'
].
will
.
return
.
with
(
0
)
const
expected1
=
ethers
.
BigNumber
.
from
(
1234
)
await
mockCaller
.
callMock
(
mock
.
address
,
mock
.
interface
.
encodeFunctionData
(
'
overloadedFunction(uint256)
'
,
[
expected1
,
])
)
expect
(
mock
.
smocked
[
'
overloadedFunction(uint256)
'
].
calls
[
0
]
).
to
.
deep
.
equal
([
expected1
])
const
expected2
=
ethers
.
BigNumber
.
from
(
5678
)
await
mockCaller
.
callMock
(
mock
.
address
,
mock
.
interface
.
encodeFunctionData
(
'
overloadedFunction(uint256,uint256)
'
,
[
expected2
,
expected2
]
)
)
expect
(
mock
.
smocked
[
'
overloadedFunction(uint256,uint256)
'
].
calls
[
0
]
).
to
.
deep
.
equal
([
expected2
,
expected2
])
})
})
})
yarn.lock
View file @
e4103622
...
...
@@ -2248,6 +2248,13 @@
dependencies:
"@types/chai" "*"
"@types/chai-as-promised@^7.1.4":
version "7.1.4"
resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.4.tgz#caf64e76fb056b8c8ced4b761ed499272b737601"
integrity sha512-1y3L1cHePcIm5vXkh1DSGf/zQq5n5xDKG1fpCvf18+uOkpce0Z1ozNFPkyWsVswK7ntN1sZBw3oU6gmN+pDUcA==
dependencies:
"@types/chai" "*"
"@types/chai@*", "@types/chai@^4.1.7":
version "4.2.16"
resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.16.tgz#f09cc36e18d28274f942e7201147cce34d97e8c8"
...
...
@@ -7178,6 +7185,57 @@ hardhat@^2.2.1:
uuid "^3.3.2"
ws "^7.2.1"
hardhat@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.3.0.tgz#5c29f8b4d08155c3dc8c908af9713fd5079522d5"
integrity sha512-nc4ro2bM4wPaA6/0Y22o5F5QrifQk2KCyPUUKLPUeFFZoGNGYB8vmeW/k9gV9DdMukdWTzfYlKc2Jn4bfb6tDQ==
dependencies:
"@ethereumjs/block" "^3.2.1"
"@ethereumjs/blockchain" "^5.2.1"
"@ethereumjs/common" "^2.2.0"
"@ethereumjs/tx" "^3.1.3"
"@ethereumjs/vm" "^5.3.2"
"@sentry/node" "^5.18.1"
"@solidity-parser/parser" "^0.11.0"
"@types/bn.js" "^5.1.0"
"@types/lru-cache" "^5.1.0"
abort-controller "^3.0.0"
adm-zip "^0.4.16"
ansi-escapes "^4.3.0"
chalk "^2.4.2"
chokidar "^3.4.0"
ci-info "^2.0.0"
debug "^4.1.1"
enquirer "^2.3.0"
env-paths "^2.2.0"
eth-sig-util "^2.5.2"
ethereum-cryptography "^0.1.2"
ethereumjs-abi "^0.6.8"
ethereumjs-util "^7.0.10"
find-up "^2.1.0"
fp-ts "1.19.3"
fs-extra "^7.0.1"
glob "^7.1.3"
immutable "^4.0.0-rc.12"
io-ts "1.10.4"
lodash "^4.17.11"
merkle-patricia-tree "^4.1.0"
mnemonist "^0.38.0"
mocha "^7.1.2"
node-fetch "^2.6.0"
qs "^6.7.0"
raw-body "^2.4.1"
resolve "1.17.0"
semver "^6.3.0"
slash "^3.0.0"
solc "0.7.3"
source-map-support "^0.5.13"
stacktrace-parser "^0.1.10"
"true-case-path" "^2.2.1"
tsort "0.0.1"
uuid "^3.3.2"
ws "^7.2.1"
has-ansi@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment