commit
2f9f862ef3
@ -0,0 +1,16 @@ |
||||
{ |
||||
"name": "solhint", |
||||
"version": "1.0.0", |
||||
"main": "index.js", |
||||
"license": "MIT", |
||||
"resolutions": { |
||||
"antlr4": "4.11" |
||||
}, |
||||
"dependencies": { |
||||
"solhint": "^3.4.1" |
||||
}, |
||||
"devDependencies": { |
||||
"@remixproject/plugin": "^0.3.31", |
||||
"@remixproject/plugin-webview": "^0.3.31" |
||||
} |
||||
} |
@ -0,0 +1,70 @@ |
||||
{ |
||||
"name": "solhint", |
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json", |
||||
"sourceRoot": "apps/solhint/src", |
||||
"projectType": "application", |
||||
"implicitDependencies": [], |
||||
"targets": { |
||||
"build": { |
||||
"executor": "@nrwl/webpack:webpack", |
||||
"outputs": [ |
||||
"{options.outputPath}" |
||||
], |
||||
"dependsOn": ["install"], |
||||
"defaultConfiguration": "development", |
||||
"options": { |
||||
"compiler": "babel", |
||||
"outputPath": "dist/apps/solhint", |
||||
"index": "apps/solhint/src/index.html", |
||||
"baseHref": "./", |
||||
"main": "apps/solhint/src/main.tsx", |
||||
"tsConfig": "apps/solhint/tsconfig.app.json", |
||||
"assets": [ |
||||
"apps/solhint/src/favicon.ico", |
||||
"apps/solhint/src/profile.json" |
||||
], |
||||
"styles": [], |
||||
"webpackConfig": "apps/solhint/webpack.config.js" |
||||
}, |
||||
"configurations": { |
||||
"development": {}, |
||||
"production": { |
||||
"fileReplacements": [ |
||||
{ |
||||
"replace": "apps/solhint/src/environments/environment.ts", |
||||
"with": "apps/solhint/src/environments/environment.prod.ts" |
||||
} |
||||
] |
||||
} |
||||
} |
||||
}, |
||||
"install": { |
||||
"executor": "nx:run-commands", |
||||
"options": { |
||||
"commands": [ |
||||
"cd apps/solhint && yarn" |
||||
], |
||||
"parallel": false |
||||
} |
||||
}, |
||||
"serve": { |
||||
"executor": "@nrwl/webpack:dev-server", |
||||
"defaultConfiguration": "development", |
||||
"options": { |
||||
"buildTarget": "solhint:build", |
||||
"hmr": true, |
||||
"baseHref": "/" |
||||
}, |
||||
"configurations": { |
||||
"development": { |
||||
"buildTarget": "solhint:build:development", |
||||
"port": 7003 |
||||
}, |
||||
"production": { |
||||
"buildTarget": "solhint:build:production" |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"tags": [] |
||||
} |
@ -0,0 +1,8 @@ |
||||
import React, { useEffect, useState } from "react"; |
||||
import { SolHint } from "./SolhintPluginClient"; |
||||
|
||||
const client = new SolHint(); |
||||
|
||||
export default function App() { |
||||
return <></>; |
||||
} |
@ -0,0 +1,145 @@ |
||||
import { PluginClient } from '@remixproject/plugin' |
||||
import { createClient } from '@remixproject/plugin-webview' |
||||
import EventEmitter from 'events' |
||||
import { processStr } from 'solhint' |
||||
import { applyExtends } from 'solhint/lib/config/config-file' |
||||
import bestPractises from 'solhint/lib/rules/best-practises' |
||||
import naming from 'solhint/lib/rules/naming' |
||||
import order from 'solhint/lib/rules/order' |
||||
import security from 'solhint/lib/rules/security' |
||||
import deprecations from 'solhint/lib/rules/deprecations' |
||||
import miscellaneous from 'solhint/lib/rules/miscellaneous' |
||||
import { customAction } from '@remixproject/plugin-api' |
||||
|
||||
type Report = {
|
||||
line: number, |
||||
column: number, |
||||
severity: string, |
||||
message: string, |
||||
ruleId: string, |
||||
fix: string |
||||
} |
||||
|
||||
const Config = `{
|
||||
"extends": "solhint:recommended", |
||||
"plugins": [], |
||||
"rules": { |
||||
"avoid-suicide": "error", |
||||
"avoid-sha3": "warn" |
||||
} |
||||
}` |
||||
|
||||
export class SolHint extends PluginClient { |
||||
triggerLinter: boolean |
||||
constructor() { |
||||
super() |
||||
this.methods = ['lintContract', 'lintOnCompilation', 'lintContractCustomAction', 'lint'] |
||||
createClient(this) |
||||
this.onload().then(async () => { |
||||
await this.lintOnCompilation() |
||||
}) |
||||
} |
||||
async createConfigFile () { |
||||
await this.call('fileManager', 'writeFile', '.solhint.json', Config) |
||||
} |
||||
|
||||
async lintOnCompilation() { |
||||
if(!this.triggerLinter) return |
||||
this.on('solidity', 'compilationFinished', async (fileName, source, languageVersion, data) => { |
||||
const hints = await this.lint(fileName) |
||||
console.log('after compile', { hints }) |
||||
this.emit('lintOnCompilationFinished', hints) |
||||
}) |
||||
this.triggerLinter = false |
||||
} |
||||
/** |
||||
* method to handle context menu action in file explorer for
|
||||
* solhint plugin |
||||
* @param action interface CustomAction |
||||
*/ |
||||
async lintContractCustomAction(action: customAction) { |
||||
this.triggerLinter = true |
||||
await this.call('solidity', 'compile', action.path[0]) |
||||
await this.lintContract(action.path[0]) |
||||
} |
||||
|
||||
async lintContract(file: string) { |
||||
const hints = await this.lint(file) |
||||
console.log({ hints }) |
||||
this.emit('lintingFinished', hints) |
||||
} |
||||
|
||||
public async lint(fileName: string) { |
||||
const content = await this.call('fileManager', 'readFile', fileName) |
||||
let configContent = Config |
||||
if (await this.call('fileManager' as any, 'exists', '.solhint.json')) { |
||||
configContent = await this.call('fileManager', 'readFile', '.solhint.json') |
||||
} |
||||
const configContentObj = JSON.parse(configContent) |
||||
// apply the extend property
|
||||
const rulesObj = applyExtends(configContentObj, (path) => this.rules[path]()) |
||||
configContentObj.rules = { ...rulesObj, ...configContentObj.rules } |
||||
configContentObj.extends = [] |
||||
|
||||
const reporters = processStr(content, configContentObj) |
||||
|
||||
const reports: Array<Report> = reporters.reports |
||||
const hints = reports.map((report: Report) => { |
||||
return { |
||||
formattedMessage: `${report.message}\n${report.fix ? report.fix : ''}`, |
||||
type: this.severity[report.severity] || 'error', |
||||
column: report.column, |
||||
line: report.line - 1 |
||||
} |
||||
}) |
||||
return hints |
||||
} |
||||
|
||||
severity = { |
||||
2: 'error', |
||||
3: 'warning' |
||||
} |
||||
|
||||
rules = { |
||||
'solhint:recommended': () => { |
||||
const enabledRules = {} |
||||
this.coreRules().forEach(rule => { |
||||
if (!rule.meta.deprecated && rule.meta.recommended) { |
||||
enabledRules[rule.ruleId] = rule.meta.defaultSetup |
||||
} |
||||
}) |
||||
return enabledRules |
||||
}, |
||||
'solhint:all': () => { |
||||
const enabledRules = {} |
||||
this.coreRules().forEach(rule => { |
||||
if (!rule.meta.deprecated) { |
||||
enabledRules[rule.ruleId] = rule.meta.defaultSetup |
||||
} |
||||
}) |
||||
return enabledRules |
||||
}, |
||||
'solhint:default': () => { |
||||
const enabledRules = {} |
||||
this.coreRules().forEach(rule => { |
||||
if (!rule.meta.deprecated && rule.meta.isDefault) { |
||||
enabledRules[rule.ruleId] = rule.meta.defaultSetup |
||||
} |
||||
}) |
||||
return enabledRules |
||||
} |
||||
} |
||||
|
||||
coreRules() { |
||||
return [ |
||||
...bestPractises(), |
||||
...deprecations(), |
||||
...miscellaneous(), |
||||
...naming(), |
||||
...order(), |
||||
...security() |
||||
] |
||||
} |
||||
|
||||
} |
||||
|
After Width: | Height: | Size: 15 KiB |
@ -0,0 +1,13 @@ |
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="utf-8" /> |
||||
<title>Solhint</title> |
||||
<base href="/" /> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1" /> |
||||
<link rel="icon" type="image/x-icon" href="favicon.ico" /> |
||||
</head> |
||||
<body> |
||||
<div id="root"></div> |
||||
</body> |
||||
</html> |
@ -0,0 +1,10 @@ |
||||
import React from 'react' |
||||
import ReactDOM from 'react-dom' |
||||
import App from './app/App' |
||||
|
||||
ReactDOM.render( |
||||
<React.StrictMode> |
||||
<App /> |
||||
</React.StrictMode>, |
||||
document.getElementById('root') |
||||
) |
@ -0,0 +1,20 @@ |
||||
{ |
||||
"name": "solhint", |
||||
"displayName": "Solhint Linter", |
||||
"description": "Linter for Solidity", |
||||
"version": "0.1.0", |
||||
"events": ["lintOnCompilationFinished", "lintingFinished"], |
||||
"methods": [ |
||||
"lintWithoutCompilationCustomAction", |
||||
"lintOnCompilation", |
||||
"lintContractCustomAction" |
||||
], |
||||
"kind": "none", |
||||
"icon": "https://raw.githubusercontent.com/protofire/solhint/master/solhint-icon.png", |
||||
"location": "hiddenPanel", |
||||
"url": "", |
||||
"documentation": "https://remix-plugins.readthedocs.io/en/latest/", |
||||
"repo": "https://github.com/ethereum/remix-project", |
||||
"maintainedBy": "Remix", |
||||
"authorContact": "remix@ethereum.org" |
||||
} |
@ -0,0 +1,23 @@ |
||||
{ |
||||
"extends": "./tsconfig.json", |
||||
"compilerOptions": { |
||||
"outDir": "../../dist/out-tsc", |
||||
"types": ["node"] |
||||
}, |
||||
"files": [ |
||||
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts", |
||||
"../../node_modules/@nrwl/react/typings/image.d.ts" |
||||
], |
||||
"exclude": [ |
||||
"jest.config.ts", |
||||
"**/*.spec.ts", |
||||
"**/*.test.ts", |
||||
"**/*.spec.tsx", |
||||
"**/*.test.tsx", |
||||
"**/*.spec.js", |
||||
"**/*.test.js", |
||||
"**/*.spec.jsx", |
||||
"**/*.test.jsx" |
||||
], |
||||
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] |
||||
} |
@ -0,0 +1,16 @@ |
||||
{ |
||||
"extends": "../../tsconfig.base.json", |
||||
"compilerOptions": { |
||||
"jsx": "react-jsx", |
||||
"allowJs": true, |
||||
"esModuleInterop": true, |
||||
"allowSyntheticDefaultImports": true |
||||
}, |
||||
"files": [], |
||||
"include": [], |
||||
"references": [ |
||||
{ |
||||
"path": "./tsconfig.app.json" |
||||
} |
||||
] |
||||
} |
@ -0,0 +1,60 @@ |
||||
const { composePlugins, withNx } = require('@nrwl/webpack') |
||||
const { withReact } = require('@nrwl/react') |
||||
const webpack = require('webpack') |
||||
const TerserPlugin = require("terser-webpack-plugin") |
||||
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin") |
||||
|
||||
// Nx plugins for webpack.
|
||||
module.exports = composePlugins(withNx(), withReact(), (config) => { |
||||
// Update the webpack config as needed here.
|
||||
config.resolve.fallback = { |
||||
...config.resolve.fallback, |
||||
"path": false, |
||||
"os": false,
|
||||
"fs": false, |
||||
"module": false, |
||||
} |
||||
|
||||
// add public path
|
||||
config.output.publicPath = '/' |
||||
|
||||
// add copy & provide plugin
|
||||
config.plugins.push( |
||||
new webpack.ProvidePlugin({ |
||||
Buffer: ['buffer', 'Buffer'], |
||||
url: ['url', 'URL'], |
||||
process: 'process/browser', |
||||
}), |
||||
new webpack.DefinePlugin({ |
||||
"BROWSER": true, |
||||
}), |
||||
) |
||||
|
||||
// souce-map loader
|
||||
config.module.rules.push({ |
||||
test: /\.js$/, |
||||
use: ["source-map-loader"], |
||||
enforce: "pre" |
||||
}) |
||||
|
||||
config.ignoreWarnings = [/Failed to parse source map/] // ignore source-map-loader warnings
|
||||
|
||||
// set minimizer
|
||||
config.optimization.minimizer = [ |
||||
new TerserPlugin({ |
||||
parallel: true, |
||||
terserOptions: { |
||||
ecma: 2015, |
||||
compress: false, |
||||
mangle: false, |
||||
format: { |
||||
comments: false, |
||||
}, |
||||
}, |
||||
extractComments: false, |
||||
}), |
||||
new CssMinimizerPlugin(), |
||||
]; |
||||
|
||||
return config; |
||||
}) |
@ -0,0 +1,517 @@ |
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. |
||||
# yarn lockfile v1 |
||||
|
||||
|
||||
"@babel/code-frame@^7.0.0": |
||||
version "7.21.4" |
||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.21.4.tgz#d0fa9e4413aca81f2b23b9442797bda1826edb39" |
||||
integrity sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g== |
||||
dependencies: |
||||
"@babel/highlight" "^7.18.6" |
||||
|
||||
"@babel/helper-validator-identifier@^7.18.6": |
||||
version "7.19.1" |
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" |
||||
integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== |
||||
|
||||
"@babel/highlight@^7.18.6": |
||||
version "7.18.6" |
||||
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" |
||||
integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== |
||||
dependencies: |
||||
"@babel/helper-validator-identifier" "^7.18.6" |
||||
chalk "^2.0.0" |
||||
js-tokens "^4.0.0" |
||||
|
||||
"@remixproject/plugin-api@0.3.31": |
||||
version "0.3.31" |
||||
resolved "https://registry.yarnpkg.com/@remixproject/plugin-api/-/plugin-api-0.3.31.tgz#86e7c458c58ff200bd927fd3d642877f4b5a0013" |
||||
integrity sha512-LOJRHxORNp7zW8k7//DQz5aZ7eqB7TwhYXrvzqvaryDTvtvJGWrlTHg81hzALynaxZKEWneohxjUxKvGp/eA4g== |
||||
dependencies: |
||||
"@remixproject/plugin-utils" "0.3.31" |
||||
|
||||
"@remixproject/plugin-utils@0.3.31": |
||||
version "0.3.31" |
||||
resolved "https://registry.yarnpkg.com/@remixproject/plugin-utils/-/plugin-utils-0.3.31.tgz#80771e00c1a1b776432abb17b1f4b2e25600d4f6" |
||||
integrity sha512-OOAjoSd+ErBMrcNQEh80NU3BjJ9fHXuftRfy5Ul9aGXN3b1LJSNVvfrG+FxX6lpyaAK5JBj+aB9pgFozgb2wlw== |
||||
dependencies: |
||||
tslib "2.0.1" |
||||
|
||||
"@remixproject/plugin-webview@^0.3.31": |
||||
version "0.3.31" |
||||
resolved "https://registry.yarnpkg.com/@remixproject/plugin-webview/-/plugin-webview-0.3.31.tgz#e5cce7d0089439b35aee4ab2a724add1e5d36b40" |
||||
integrity sha512-8yoKwIkRi9S+rqvFShNt01FfXX0H/Fijn7UkWFWJ/V6ULcw2cw9ViCz8cYZLhNUpxqezyu/LKDQL9g1TbJJoYw== |
||||
dependencies: |
||||
"@remixproject/plugin" "0.3.31" |
||||
"@remixproject/plugin-api" "0.3.31" |
||||
"@remixproject/plugin-utils" "0.3.31" |
||||
axios "^0.21.1" |
||||
|
||||
"@remixproject/plugin@0.3.31", "@remixproject/plugin@^0.3.31": |
||||
version "0.3.31" |
||||
resolved "https://registry.yarnpkg.com/@remixproject/plugin/-/plugin-0.3.31.tgz#b6c6b58d2c7964e37024eeca4819c70ece1f3953" |
||||
integrity sha512-9ntMU9CzStloahm/wXt4V8n64ERgJzY5nG0bzQfjnI12knrdTmUo+LC42M2xaTBDDP9CzMPdqClg7XhhRLzohA== |
||||
dependencies: |
||||
"@remixproject/plugin-api" "0.3.31" |
||||
"@remixproject/plugin-utils" "0.3.31" |
||||
events "3.2.0" |
||||
|
||||
"@solidity-parser/parser@^0.16.0": |
||||
version "0.16.0" |
||||
resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.16.0.tgz#1fb418c816ca1fc3a1e94b08bcfe623ec4e1add4" |
||||
integrity sha512-ESipEcHyRHg4Np4SqBCfcXwyxxna1DgFVz69bgpLV8vzl/NP1DtcKsJ4dJZXWQhY/Z4J2LeKBiOkOVZn9ct33Q== |
||||
dependencies: |
||||
antlr4ts "^0.5.0-alpha.4" |
||||
|
||||
ajv@^6.12.6: |
||||
version "6.12.6" |
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" |
||||
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== |
||||
dependencies: |
||||
fast-deep-equal "^3.1.1" |
||||
fast-json-stable-stringify "^2.0.0" |
||||
json-schema-traverse "^0.4.1" |
||||
uri-js "^4.2.2" |
||||
|
||||
ajv@^8.0.1: |
||||
version "8.12.0" |
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" |
||||
integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== |
||||
dependencies: |
||||
fast-deep-equal "^3.1.1" |
||||
json-schema-traverse "^1.0.0" |
||||
require-from-string "^2.0.2" |
||||
uri-js "^4.2.2" |
||||
|
||||
ansi-regex@^5.0.1: |
||||
version "5.0.1" |
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" |
||||
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== |
||||
|
||||
ansi-styles@^3.2.1: |
||||
version "3.2.1" |
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" |
||||
integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== |
||||
dependencies: |
||||
color-convert "^1.9.0" |
||||
|
||||
ansi-styles@^4.0.0, ansi-styles@^4.1.0: |
||||
version "4.3.0" |
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" |
||||
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== |
||||
dependencies: |
||||
color-convert "^2.0.1" |
||||
|
||||
antlr4@4.11, antlr4@^4.11.0: |
||||
version "4.11.0" |
||||
resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.11.0.tgz#d7466f5044fa6e333c0ec821b30c6157f6b004ae" |
||||
integrity sha512-GUGlpE2JUjAN+G8G5vY+nOoeyNhHsXoIJwP1XF1oRw89vifA1K46T6SEkwLwr7drihN7I/lf0DIjKc4OZvBX8w== |
||||
|
||||
antlr4ts@^0.5.0-alpha.4: |
||||
version "0.5.0-alpha.4" |
||||
resolved "https://registry.yarnpkg.com/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz#71702865a87478ed0b40c0709f422cf14d51652a" |
||||
integrity sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ== |
||||
|
||||
argparse@^2.0.1: |
||||
version "2.0.1" |
||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" |
||||
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== |
||||
|
||||
ast-parents@^0.0.1: |
||||
version "0.0.1" |
||||
resolved "https://registry.yarnpkg.com/ast-parents/-/ast-parents-0.0.1.tgz#508fd0f05d0c48775d9eccda2e174423261e8dd3" |
||||
integrity sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA== |
||||
|
||||
astral-regex@^2.0.0: |
||||
version "2.0.0" |
||||
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" |
||||
integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== |
||||
|
||||
axios@^0.21.1: |
||||
version "0.21.4" |
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" |
||||
integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== |
||||
dependencies: |
||||
follow-redirects "^1.14.0" |
||||
|
||||
balanced-match@^1.0.0: |
||||
version "1.0.2" |
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" |
||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== |
||||
|
||||
brace-expansion@^2.0.1: |
||||
version "2.0.1" |
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" |
||||
integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== |
||||
dependencies: |
||||
balanced-match "^1.0.0" |
||||
|
||||
callsites@^3.0.0: |
||||
version "3.1.0" |
||||
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" |
||||
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== |
||||
|
||||
chalk@^2.0.0: |
||||
version "2.4.2" |
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" |
||||
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== |
||||
dependencies: |
||||
ansi-styles "^3.2.1" |
||||
escape-string-regexp "^1.0.5" |
||||
supports-color "^5.3.0" |
||||
|
||||
chalk@^4.1.2: |
||||
version "4.1.2" |
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" |
||||
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== |
||||
dependencies: |
||||
ansi-styles "^4.1.0" |
||||
supports-color "^7.1.0" |
||||
|
||||
color-convert@^1.9.0: |
||||
version "1.9.3" |
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" |
||||
integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== |
||||
dependencies: |
||||
color-name "1.1.3" |
||||
|
||||
color-convert@^2.0.1: |
||||
version "2.0.1" |
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" |
||||
integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== |
||||
dependencies: |
||||
color-name "~1.1.4" |
||||
|
||||
color-name@1.1.3: |
||||
version "1.1.3" |
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" |
||||
integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== |
||||
|
||||
color-name@~1.1.4: |
||||
version "1.1.4" |
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" |
||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== |
||||
|
||||
commander@^10.0.0: |
||||
version "10.0.1" |
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" |
||||
integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== |
||||
|
||||
cosmiconfig@^8.0.0: |
||||
version "8.1.3" |
||||
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.1.3.tgz#0e614a118fcc2d9e5afc2f87d53cd09931015689" |
||||
integrity sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw== |
||||
dependencies: |
||||
import-fresh "^3.2.1" |
||||
js-yaml "^4.1.0" |
||||
parse-json "^5.0.0" |
||||
path-type "^4.0.0" |
||||
|
||||
emoji-regex@^8.0.0: |
||||
version "8.0.0" |
||||
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" |
||||
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== |
||||
|
||||
error-ex@^1.3.1: |
||||
version "1.3.2" |
||||
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" |
||||
integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== |
||||
dependencies: |
||||
is-arrayish "^0.2.1" |
||||
|
||||
escape-string-regexp@^1.0.5: |
||||
version "1.0.5" |
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" |
||||
integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== |
||||
|
||||
events@3.2.0: |
||||
version "3.2.0" |
||||
resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379" |
||||
integrity sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg== |
||||
|
||||
fast-deep-equal@^3.1.1: |
||||
version "3.1.3" |
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" |
||||
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== |
||||
|
||||
fast-diff@^1.2.0: |
||||
version "1.2.0" |
||||
resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" |
||||
integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== |
||||
|
||||
fast-json-stable-stringify@^2.0.0: |
||||
version "2.1.0" |
||||
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" |
||||
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== |
||||
|
||||
follow-redirects@^1.14.0: |
||||
version "1.15.2" |
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" |
||||
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== |
||||
|
||||
fs.realpath@^1.0.0: |
||||
version "1.0.0" |
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" |
||||
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== |
||||
|
||||
glob@^8.0.3: |
||||
version "8.1.0" |
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" |
||||
integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== |
||||
dependencies: |
||||
fs.realpath "^1.0.0" |
||||
inflight "^1.0.4" |
||||
inherits "2" |
||||
minimatch "^5.0.1" |
||||
once "^1.3.0" |
||||
|
||||
has-flag@^3.0.0: |
||||
version "3.0.0" |
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" |
||||
integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== |
||||
|
||||
has-flag@^4.0.0: |
||||
version "4.0.0" |
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" |
||||
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== |
||||
|
||||
ignore@^5.2.4: |
||||
version "5.2.4" |
||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" |
||||
integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== |
||||
|
||||
import-fresh@^3.2.1: |
||||
version "3.3.0" |
||||
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" |
||||
integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== |
||||
dependencies: |
||||
parent-module "^1.0.0" |
||||
resolve-from "^4.0.0" |
||||
|
||||
inflight@^1.0.4: |
||||
version "1.0.6" |
||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" |
||||
integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== |
||||
dependencies: |
||||
once "^1.3.0" |
||||
wrappy "1" |
||||
|
||||
inherits@2: |
||||
version "2.0.4" |
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" |
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== |
||||
|
||||
is-arrayish@^0.2.1: |
||||
version "0.2.1" |
||||
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" |
||||
integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== |
||||
|
||||
is-fullwidth-code-point@^3.0.0: |
||||
version "3.0.0" |
||||
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" |
||||
integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== |
||||
|
||||
js-tokens@^4.0.0: |
||||
version "4.0.0" |
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" |
||||
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== |
||||
|
||||
js-yaml@^4.1.0: |
||||
version "4.1.0" |
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" |
||||
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== |
||||
dependencies: |
||||
argparse "^2.0.1" |
||||
|
||||
json-parse-even-better-errors@^2.3.0: |
||||
version "2.3.1" |
||||
resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" |
||||
integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== |
||||
|
||||
json-schema-traverse@^0.4.1: |
||||
version "0.4.1" |
||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" |
||||
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== |
||||
|
||||
json-schema-traverse@^1.0.0: |
||||
version "1.0.0" |
||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" |
||||
integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== |
||||
|
||||
lines-and-columns@^1.1.6: |
||||
version "1.2.4" |
||||
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" |
||||
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== |
||||
|
||||
lodash.truncate@^4.4.2: |
||||
version "4.4.2" |
||||
resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" |
||||
integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== |
||||
|
||||
lodash@^4.17.21: |
||||
version "4.17.21" |
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" |
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== |
||||
|
||||
minimatch@^5.0.1: |
||||
version "5.1.6" |
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" |
||||
integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== |
||||
dependencies: |
||||
brace-expansion "^2.0.1" |
||||
|
||||
once@^1.3.0: |
||||
version "1.4.0" |
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" |
||||
integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== |
||||
dependencies: |
||||
wrappy "1" |
||||
|
||||
parent-module@^1.0.0: |
||||
version "1.0.1" |
||||
resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" |
||||
integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== |
||||
dependencies: |
||||
callsites "^3.0.0" |
||||
|
||||
parse-json@^5.0.0: |
||||
version "5.2.0" |
||||
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" |
||||
integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== |
||||
dependencies: |
||||
"@babel/code-frame" "^7.0.0" |
||||
error-ex "^1.3.1" |
||||
json-parse-even-better-errors "^2.3.0" |
||||
lines-and-columns "^1.1.6" |
||||
|
||||
path-type@^4.0.0: |
||||
version "4.0.0" |
||||
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" |
||||
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== |
||||
|
||||
pluralize@^8.0.0: |
||||
version "8.0.0" |
||||
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" |
||||
integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== |
||||
|
||||
prettier@^2.8.3: |
||||
version "2.8.7" |
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.7.tgz#bb79fc8729308549d28fe3a98fce73d2c0656450" |
||||
integrity sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw== |
||||
|
||||
punycode@^2.1.0: |
||||
version "2.3.0" |
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" |
||||
integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== |
||||
|
||||
require-from-string@^2.0.2: |
||||
version "2.0.2" |
||||
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" |
||||
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== |
||||
|
||||
resolve-from@^4.0.0: |
||||
version "4.0.0" |
||||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" |
||||
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== |
||||
|
||||
semver@^6.3.0: |
||||
version "6.3.0" |
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" |
||||
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== |
||||
|
||||
slice-ansi@^4.0.0: |
||||
version "4.0.0" |
||||
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" |
||||
integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== |
||||
dependencies: |
||||
ansi-styles "^4.0.0" |
||||
astral-regex "^2.0.0" |
||||
is-fullwidth-code-point "^3.0.0" |
||||
|
||||
solhint@^3.4.1: |
||||
version "3.4.1" |
||||
resolved "https://registry.yarnpkg.com/solhint/-/solhint-3.4.1.tgz#8ea15b21c13d1be0b53fd46d605a24d0b36a0c46" |
||||
integrity sha512-pzZn2RlZhws1XwvLPVSsxfHrwsteFf5eySOhpAytzXwKQYbTCJV6z8EevYDiSVKMpWrvbKpEtJ055CuEmzp4Xg== |
||||
dependencies: |
||||
"@solidity-parser/parser" "^0.16.0" |
||||
ajv "^6.12.6" |
||||
antlr4 "^4.11.0" |
||||
ast-parents "^0.0.1" |
||||
chalk "^4.1.2" |
||||
commander "^10.0.0" |
||||
cosmiconfig "^8.0.0" |
||||
fast-diff "^1.2.0" |
||||
glob "^8.0.3" |
||||
ignore "^5.2.4" |
||||
js-yaml "^4.1.0" |
||||
lodash "^4.17.21" |
||||
pluralize "^8.0.0" |
||||
semver "^6.3.0" |
||||
strip-ansi "^6.0.1" |
||||
table "^6.8.1" |
||||
text-table "^0.2.0" |
||||
optionalDependencies: |
||||
prettier "^2.8.3" |
||||
|
||||
string-width@^4.2.3: |
||||
version "4.2.3" |
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" |
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== |
||||
dependencies: |
||||
emoji-regex "^8.0.0" |
||||
is-fullwidth-code-point "^3.0.0" |
||||
strip-ansi "^6.0.1" |
||||
|
||||
strip-ansi@^6.0.1: |
||||
version "6.0.1" |
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" |
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== |
||||
dependencies: |
||||
ansi-regex "^5.0.1" |
||||
|
||||
supports-color@^5.3.0: |
||||
version "5.5.0" |
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" |
||||
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== |
||||
dependencies: |
||||
has-flag "^3.0.0" |
||||
|
||||
supports-color@^7.1.0: |
||||
version "7.2.0" |
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" |
||||
integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== |
||||
dependencies: |
||||
has-flag "^4.0.0" |
||||
|
||||
table@^6.8.1: |
||||
version "6.8.1" |
||||
resolved "https://registry.yarnpkg.com/table/-/table-6.8.1.tgz#ea2b71359fe03b017a5fbc296204471158080bdf" |
||||
integrity sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA== |
||||
dependencies: |
||||
ajv "^8.0.1" |
||||
lodash.truncate "^4.4.2" |
||||
slice-ansi "^4.0.0" |
||||
string-width "^4.2.3" |
||||
strip-ansi "^6.0.1" |
||||
|
||||
text-table@^0.2.0: |
||||
version "0.2.0" |
||||
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" |
||||
integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== |
||||
|
||||
tslib@2.0.1: |
||||
version "2.0.1" |
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.1.tgz#410eb0d113e5b6356490eec749603725b021b43e" |
||||
integrity sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ== |
||||
|
||||
uri-js@^4.2.2: |
||||
version "4.4.1" |
||||
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" |
||||
integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== |
||||
dependencies: |
||||
punycode "^2.1.0" |
||||
|
||||
wrappy@1: |
||||
version "1.0.2" |
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" |
||||
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== |
@ -1,14 +1,208 @@ |
||||
import { CompilationResult, SourceWithTarget } from '@remixproject/plugin-api' |
||||
import React from 'react' //eslint-disable-line
|
||||
import { AnalysisTab, RemixUiStaticAnalyserReducerActionType, RemixUiStaticAnalyserState, SolHintReport, SlitherAnalysisResults } from '../../staticanalyser' |
||||
import { RemixUiStaticAnalyserProps } from '@remix-ui/static-analyser' |
||||
|
||||
export const compilation = (analysisModule, dispatch) => { |
||||
/** |
||||
*
|
||||
* @param analysisModule { AnalysisTab } AnalysisTab ViewPlugin |
||||
* @param dispatch { React.Dispatch<any> } analysisReducer function's dispatch method |
||||
*/ |
||||
export const compilation = (analysisModule: AnalysisTab, |
||||
dispatch: React.Dispatch<RemixUiStaticAnalyserReducerActionType>) => { |
||||
if (analysisModule) { |
||||
analysisModule.on( |
||||
'solidity', |
||||
'compilationFinished', |
||||
(file, source, languageVersion, data, input, version) => { |
||||
(file: string, source: SourceWithTarget, languageVersion: string, data: CompilationResult, input: string, version: string) => { |
||||
if (languageVersion.indexOf('soljson') !== 0) return |
||||
dispatch({ type: 'compilationFinished', payload: { file, source, languageVersion, data, input, version } }) |
||||
} |
||||
) |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Run the analysis on the currently compiled contract |
||||
* @param lastCompilationResult
|
||||
* @param lastCompilationSource
|
||||
* @param currentFile {string} current file path |
||||
* @param state { RemixUiStaticAnalyserState} |
||||
* @param props {RemixUiStaticAnalyserProps} |
||||
* @param isSupportedVersion {boolean} |
||||
* @param slitherEnabled {boolean} |
||||
* @param categoryIndex {number[]} |
||||
* @param groupedModules {any} |
||||
* @param runner {any} |
||||
* @param _paq {any} |
||||
* @param message {any} |
||||
* @param showWarnings {boolean} |
||||
* @param allWarnings {React.RefObject<object>} |
||||
* @param warningContainer {React.RefObject<object>} |
||||
* @returns {Promise<void>} |
||||
*/ |
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export async function run (lastCompilationResult, lastCompilationSource, currentFile: string, state: RemixUiStaticAnalyserState, props: RemixUiStaticAnalyserProps, isSupportedVersion, showSlither, categoryIndex: number[], groupedModules, runner, _paq, message, showWarnings, allWarnings: React.RefObject<any>, warningContainer: React.RefObject<any>, calculateWarningStateEntries: (e:[string, any][]) => {length: number, errors: any[] }, warningState, setHints: React.Dispatch<React.SetStateAction<SolHintReport[]>>, hints: SolHintReport[], setSlitherWarnings: React.Dispatch<React.SetStateAction<any[]>>, setSsaWarnings: React.Dispatch<React.SetStateAction<any[]>>) { |
||||
|
||||
if (!isSupportedVersion) return |
||||
if (state.data !== null) { |
||||
if (lastCompilationResult && (categoryIndex.length > 0 || showSlither)) { |
||||
const warningMessage = [] |
||||
const warningErrors = [] |
||||
|
||||
// Run solhint
|
||||
const hintsResult = await props.analysisModule.call('solhint', 'lint', state.file) |
||||
setHints(hintsResult) |
||||
const warningResult = calculateWarningStateEntries(Object.entries(warningState)) |
||||
props.analysisModule.emit('statusChanged', { key: hints.length+warningResult.length,
|
||||
title: `${hints.length+warningResult.length} warning${hints.length+warningResult.length === 1 ? '' : 's'}`, type: 'warning'}) |
||||
|
||||
// Remix Analysis
|
||||
_paq.push(['trackEvent', 'solidityStaticAnalyzer', 'analyze', 'remixAnalyzer']) |
||||
const results = runner.run(lastCompilationResult, categoryIndex) |
||||
for (const result of results) { |
||||
let moduleName
|
||||
Object.keys(groupedModules).map(key => { |
||||
groupedModules[key].forEach(el => { |
||||
if (el.name === result.name) { |
||||
moduleName = groupedModules[key][0].categoryDisplayName |
||||
} |
||||
}) |
||||
}) |
||||
// iterate over the warnings and create an object
|
||||
for (const item of result.report) { |
||||
let location: any = {} |
||||
let locationString = 'not available' |
||||
let column = 0 |
||||
let row = 0 |
||||
let fileName = currentFile |
||||
let isLibrary = false |
||||
|
||||
if (item.location) { |
||||
const split = item.location.split(':') |
||||
const file = split[2] |
||||
location = { |
||||
start: parseInt(split[0]), |
||||
length: parseInt(split[1]) |
||||
} |
||||
location = props.analysisModule._deps.offsetToLineColumnConverter.offsetToLineColumn( |
||||
location, |
||||
parseInt(file), |
||||
lastCompilationSource.sources, |
||||
lastCompilationResult.sources |
||||
) |
||||
row = location.start.line |
||||
column = location.start.column |
||||
locationString = row + 1 + ':' + column + ':' |
||||
fileName = Object.keys(lastCompilationResult.sources)[file] |
||||
} |
||||
if(fileName !== currentFile) { |
||||
const {file, provider} = await props.analysisModule.call('fileManager', 'getPathFromUrl', fileName) |
||||
if (file.startsWith('.deps') || (provider.type === 'localhost' && file.startsWith('localhost/node_modules'))) isLibrary = true |
||||
} |
||||
const msg = message(result.name, item.warning, item.more, fileName, locationString) |
||||
const options = { |
||||
type: 'warning', |
||||
useSpan: true, |
||||
errFile: fileName, |
||||
fileName, |
||||
isLibrary, |
||||
errLine: row, |
||||
errCol: column, |
||||
item: item, |
||||
name: result.name, |
||||
locationString, |
||||
more: item.more, |
||||
location: location |
||||
} |
||||
warningErrors.push(options) |
||||
warningMessage.push({ msg, options, hasWarning: true, warningModuleName: moduleName }) |
||||
setSsaWarnings(warningErrors) |
||||
} |
||||
} |
||||
// Slither Analysis
|
||||
if (showSlither) { |
||||
try { |
||||
const compilerState = await props.analysisModule.call('solidity', 'getCompilerState') |
||||
const { currentVersion, optimize, evmVersion } = compilerState |
||||
await props.analysisModule.call('terminal', 'log', { type: 'log', value: '[Slither Analysis]: Running...' }) |
||||
_paq.push(['trackEvent', 'solidityStaticAnalyzer', 'analyze', 'slitherAnalyzer']) |
||||
const result: SlitherAnalysisResults = await props.analysisModule.call('slither', 'analyse', state.file, { currentVersion, optimize, evmVersion }) |
||||
if (result.status) { |
||||
props.analysisModule.call('terminal', 'log', { type: 'log', value: `[Slither Analysis]: Analysis Completed!! ${result.count} warnings found.` }) |
||||
const report = result.data |
||||
for (const item of report) { |
||||
let location: any = {} |
||||
let locationString = 'not available' |
||||
let column = 0 |
||||
let row = 0 |
||||
let fileName = currentFile |
||||
let isLibrary = false |
||||
|
||||
if (item.sourceMap && item.sourceMap.length) { |
||||
const path = item.sourceMap[0].source_mapping.filename_relative |
||||
let fileIndex = Object.keys(lastCompilationResult.sources).indexOf(path) |
||||
if (fileIndex === -1) { |
||||
const getpath = await props.analysisModule.call('fileManager', 'getUrlFromPath', path) |
||||
fileIndex = Object.keys(lastCompilationResult.sources).indexOf(getpath.file) |
||||
} |
||||
if (fileIndex >= 0) { |
||||
location = { |
||||
start: item.sourceMap[0].source_mapping.start, |
||||
length: item.sourceMap[0].source_mapping.length |
||||
} |
||||
location = props.analysisModule._deps.offsetToLineColumnConverter.offsetToLineColumn( |
||||
location, |
||||
fileIndex, |
||||
lastCompilationSource.sources, |
||||
lastCompilationResult.sources |
||||
) |
||||
row = location.start.line |
||||
column = location.start.column |
||||
locationString = row + 1 + ':' + column + ':' |
||||
fileName = Object.keys(lastCompilationResult.sources)[fileIndex] |
||||
} |
||||
} |
||||
if(fileName !== currentFile) { |
||||
const {file, provider} = await props.analysisModule.call('fileManager', 'getPathFromUrl', fileName) |
||||
if (file.startsWith('.deps') || (file.includes('.deps')) || (provider.type === 'localhost' && file.startsWith('localhost/node_modules'))) isLibrary = true |
||||
} |
||||
const msg = message(item.title, item.description, item.more ?? '', fileName, locationString) |
||||
const options = { |
||||
type: item.sourceMap[0].type, |
||||
useSpan: true, |
||||
errFile: fileName, |
||||
fileName, |
||||
isLibrary, |
||||
errLine: row, |
||||
errCol: column, |
||||
item: { warning: item.description }, |
||||
name: item.title, |
||||
locationString, |
||||
more: item.more ?? '', |
||||
location: location |
||||
} |
||||
|
||||
const slitherwarnings = [] |
||||
setSlitherWarnings((prev) => { |
||||
slitherwarnings.push(...prev) |
||||
slitherwarnings.push({ msg, options, hasWarning: true, warningModuleName: 'Slither Analysis' }) |
||||
return slitherwarnings |
||||
}) |
||||
} |
||||
showWarnings(warningMessage, 'warningModuleName') |
||||
} |
||||
} catch(error) { |
||||
props.analysisModule.call('terminal', 'log', { type: 'error', value: '[Slither Analysis]: Error occured! See remixd console for details.' }) |
||||
showWarnings(warningMessage, 'warningModuleName') |
||||
} |
||||
} else showWarnings(warningMessage, 'warningModuleName') |
||||
} else { |
||||
if (categoryIndex.length) { |
||||
warningContainer.current.innerText = 'No compiled AST available' |
||||
} |
||||
props.event.trigger('staticAnaysisWarning', [-1]) |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
@ -0,0 +1,44 @@ |
||||
import React from 'react' |
||||
import { ErrorRendererOptions } from '../../staticanalyser' |
||||
|
||||
type BasicTitleProps = { |
||||
warningStateEntries: any |
||||
hideWarnings?: boolean |
||||
} |
||||
|
||||
type warningResultOption = { |
||||
hasWarning: boolean |
||||
msg: string |
||||
options: ErrorRendererOptions |
||||
} |
||||
|
||||
type WarningResultType = { |
||||
categoryName: string |
||||
opts: warningResultOption[] |
||||
} |
||||
|
||||
export function calculateWarningStateEntries(entries: [string, any][]) { |
||||
let warninglength = 0 |
||||
entries.forEach((entry) => { |
||||
warninglength += entry[1].length |
||||
}) |
||||
let errors = [] |
||||
entries.forEach((entry) => { |
||||
errors = entry[1].filter(x => x.options.type === 'error') |
||||
}) |
||||
return { length: warninglength, errors } |
||||
} |
||||
|
||||
export function BasicTitle(props: BasicTitleProps) { |
||||
|
||||
return ( |
||||
<span>Remix{props.warningStateEntries.length > 0 && !props.hideWarnings ? <i data-id="StaticAnalysisErrorCount" className="badge badge-info rounded-circle ml-1">{calculateWarningStateEntries(props.warningStateEntries).length}</i>: ( |
||||
<i className="badge badge-info rounded-circle ml-1"> |
||||
{ |
||||
calculateWarningStateEntries(props.warningStateEntries).errors.length |
||||
} |
||||
</i> |
||||
)} |
||||
</span> |
||||
) |
||||
} |
@ -0,0 +1,138 @@ |
||||
import { CompilationResult, SourceWithTarget } from '@remixproject/plugin-api' |
||||
|
||||
import { ViewPlugin } from '@remixproject/engine-web'; |
||||
import { EventEmitter } from 'events'; |
||||
import Registry from '../state/registry'; |
||||
export declare class AnalysisTab extends ViewPlugin { |
||||
event: EventManager; |
||||
events: EventEmitter; |
||||
registry: Registry; |
||||
element: HTMLDivElement; |
||||
_components: any; |
||||
_deps: { |
||||
offsetToLineColumnConverter: any; |
||||
}; |
||||
dispatch: any; |
||||
constructor(); |
||||
onActivation(): Promise<void>; |
||||
setDispatch(dispatch: any): void; |
||||
render(): JSX.Element; |
||||
updateComponent(state: any): JSX.Element; |
||||
renderComponent(): void; |
||||
} |
||||
|
||||
type RemixUiStaticAnalyserState = { |
||||
file: string, |
||||
source: SourceWithTarget, |
||||
languageVersion: string, |
||||
data: CompilationResult |
||||
input?: string |
||||
version?: string |
||||
} |
||||
|
||||
type SolHintReport = { |
||||
column: number, |
||||
line: number, |
||||
type: 'warning' | 'error', |
||||
formattedMessage: string, |
||||
options?: ErrorRendererOptions |
||||
} |
||||
|
||||
type SolHintTabChildProps = { |
||||
analysisModule: AnalysisTab |
||||
currentFile: string |
||||
hints: SolHintReport[] |
||||
} |
||||
|
||||
type RemixUiStaticAnalyserReducerActionType = { |
||||
type: 'compilationFinished' | '' | any, |
||||
payload: RemixUiStaticAnalyserState |
||||
} |
||||
|
||||
interface ErrorRendererProps { |
||||
message: any; |
||||
opt: ErrorRendererOptions, |
||||
warningErrors: any |
||||
editor: any, |
||||
name: string, |
||||
} |
||||
|
||||
type ErrorRendererOptions = { |
||||
"type": "warning" | "error", |
||||
"useSpan": true, |
||||
"errFile": string |
||||
"fileName": string, |
||||
"isLibrary": boolean, |
||||
"errLine": number, |
||||
"errCol": number, |
||||
"item": { |
||||
"warning": string, |
||||
"location": string |
||||
}, |
||||
"name": string, |
||||
"locationString": string, |
||||
"location": { |
||||
"start": { |
||||
"line": number, |
||||
"column": number |
||||
}, |
||||
"end": { |
||||
"line": number, |
||||
"column": number |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
type SlitherAnalysisResultType = { |
||||
description: string, |
||||
title: string, |
||||
confidence: string, |
||||
severity: string, |
||||
more?: any, |
||||
sourceMap: [ |
||||
{ |
||||
type: string, |
||||
name: string, |
||||
source_mapping: { |
||||
start: number, |
||||
length: number, |
||||
filename_relative: string, |
||||
filename_absolute: string, |
||||
filename_short: string, |
||||
is_dependency: false, |
||||
lines: number[], |
||||
starting_column: number, |
||||
ending_column: number |
||||
}, |
||||
type_specific_fields: { |
||||
parent: { |
||||
type: string, |
||||
name: string, |
||||
source_mapping: { |
||||
start: number, |
||||
length: number, |
||||
filename_relative: string, |
||||
filename_absolute: string, |
||||
filename_short: string, |
||||
is_dependency: false, |
||||
lines: number[], |
||||
starting_column: number, |
||||
ending_column: number |
||||
} |
||||
}, |
||||
signature: string |
||||
}, |
||||
additional_fields: { |
||||
target: string, |
||||
convention: string |
||||
} |
||||
} |
||||
] |
||||
} |
||||
|
||||
export type SlitherAnalysisResults = { |
||||
count: number, |
||||
data: SlitherAnalysisResultType[] |
||||
status: boolean |
||||
} |
Loading…
Reference in new issue