From ff04b4635598a1d8988340303171067afacec069 Mon Sep 17 00:00:00 2001 From: Artem Kovalchuk Date: Tue, 16 Apr 2024 18:50:27 +0300 Subject: [PATCH 1/5] Add script to remove unused files --- .gitignore | 6 +- package-lock.json | 656 +++++++++++++++++++++++++++++++++ package.json | 20 + scripts/remove-unused-files.js | 81 ++++ 4 files changed, 762 insertions(+), 1 deletion(-) create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 scripts/remove-unused-files.js diff --git a/.gitignore b/.gitignore index 130dcf2b..7d0b7e0b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ .vscode +.idea + +node_modules +venv + forta-docs -venv \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..c676b776 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,656 @@ +{ + "name": "forta-docs", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "forta-docs", + "version": "1.0.0", + "license": "MIT", + "devDependencies": { + "fs-extra": "^11.2.0", + "glob": "^10.3.12", + "yamljs": "^0.3.0" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/glob": { + "version": "10.3.12", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", + "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.6", + "minimatch": "^9.0.1", + "minipass": "^7.0.4", + "path-scurry": "^1.10.2" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", + "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/yamljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz", + "integrity": "sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "glob": "^7.0.5" + }, + "bin": { + "json2yaml": "bin/json2yaml", + "yaml2json": "bin/yaml2json" + } + }, + "node_modules/yamljs/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/yamljs/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/yamljs/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..8448c42b --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "forta-docs", + "version": "1.0.0", + "description": "Forta Documentation", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [ + "forta", + "documentation" + ], + "author": "", + "license": "MIT", + "devDependencies": { + "fs-extra": "^11.2.0", + "glob": "^10.3.12", + "yamljs": "^0.3.0" + } +} diff --git a/scripts/remove-unused-files.js b/scripts/remove-unused-files.js new file mode 100644 index 00000000..c6ee721d --- /dev/null +++ b/scripts/remove-unused-files.js @@ -0,0 +1,81 @@ +const { globSync } = require('glob') +const yaml = require('yamljs') +const fs = require('fs') +const path = require('path') + +// Load and parse the mkdocs config +const mkdocsConfig = yaml.load('mkdocs.yml') +const docsDir = '../docs' + +function extractFilePaths(nav, fileList) { + if (Array.isArray(nav)) { + nav.forEach(item => extractFilePaths(item, fileList)); + } else if (typeof nav === 'object') { + Object.values(nav).forEach(value => { + if (typeof value === 'string') { + // Check if it's a local file (not a URL) + if (value.endsWith('.md') || value.endsWith('.html')) { + const fullPath = path.join(docsDir, value); + fileList.add(fullPath); + } + } else { + extractFilePaths(value, fileList); + } + }); + } +} + +const mkdocsFiles = new Set() +extractFilePaths(mkdocsConfig.nav, mkdocsFiles) + +// List of markdown files from mkdocs.yml +for (const page of mkdocsConfig.nav) { + if (typeof page === 'string') { + mkdocsFiles.add(page) + } else if (typeof page === 'object') { + Object.values(page).forEach((file) => { + if (typeof file === 'string') { + mkdocsFiles.add(file) + } + }) + } +} + +console.log(`Markdown files: ${mkdocsFiles.size}`) +for (const file of mkdocsFiles) { + console.log('- ' + file) +} + +// Find all .md files in the project +const allMarkdownFiles = globSync(`${docsDir}/**/*.md`) +const notUsedMarkdownFiles = allMarkdownFiles.filter((file) => { + const relativeFile = path.relative(docsDir, file) + return !mkdocsFiles.has(relativeFile) +}) + +console.log(`-----------`) + +console.log('Removing unused markdown files...') +for (const file of notUsedMarkdownFiles) { + console.log('- ' + file) + fs.unlinkSync(file) +} + +// Find and remove unused media files +const mediaExtensions = ['png', 'jpg', 'jpeg', 'gif', 'svg', 'mp4', 'avi', 'pdf', 'csv'] +const mediaFiles = globSync(`${docsDir}/**/*.{${mediaExtensions.join(',')}}`) + +console.log(`-----------`) +console.log(`Media files: ${mediaFiles.length}`) +console.log('Removing unused media files...') +for (const mediaFile of mediaFiles) { + const isUsed = [...mkdocsFiles].some(file => { + const content = fs.readFileSync(file, 'utf-8') + return content.includes(path.basename(mediaFile)) + }) + + if (!isUsed) { + console.log('- ' + mediaFile) + fs.unlinkSync(mediaFile) + } +} From 4c812b8cabed1c5d5062f7110c083f19e04fded8 Mon Sep 17 00:00:00 2001 From: Artem Kovalchuk Date: Thu, 9 May 2024 15:08:07 +0300 Subject: [PATCH 2/5] Fix importing --- docs/security-testing.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/security-testing.md b/docs/security-testing.md index 75cdca5e..c5672550 100644 --- a/docs/security-testing.md +++ b/docs/security-testing.md @@ -33,8 +33,8 @@ Adopting an attacker mindset, the Foundation went beyond employing secure design - [Dedalo's Airdrop Assessment, June 17th 2022](../2022Q2-FortaAirdrop-AuditReport.pdf) - OpenZeppelin's Airdrop Smart Contract Audit, June 9th 2022 -- [Dedalo's Forta Scan Node Assessment, April 7th 2022](../2022Q1-V2-FortaNode-AuditReport.pdf) +- [Dedalo's Forta Scan Node Assessment, April 7th 2022](2022Q1-V2-FortaNode-AuditReport.pdf) - OpenZeppelin's Protocol Audit, February 7th 2022 -- [Dedalo's Web Security Assessment, January 5th 2022 ](../Forta-Report-DDL-05-01-2022.pdf) +- [Dedalo's Web Security Assessment, January 5th 2022 ](Forta-Report-DDL-05-01-2022.pdf) - [MixBytes' Security Assessment of slash proposal changes, September 2nd 2022](https://github.com/forta-network/forta-contracts/commit/c940dc39b94bc8be6c298deab92a3dd55527f321) -- [Consensys' Security Assessment of Delegated Staking, November 2022](https://consensys.net/diligence/audits/2022/11/forta-delegated-staking/) \ No newline at end of file +- [Consensys' Security Assessment of Delegated Staking, November 2022](https://consensys.net/diligence/audits/2022/11/forta-delegated-staking/) From aa450816547b4162739dca155fd1d90f8ff45c54 Mon Sep 17 00:00:00 2001 From: Artem Kovalchuk Date: Tue, 28 May 2024 15:34:54 +0300 Subject: [PATCH 3/5] Add script to remove unused files --- scripts/remove-unused-files.js | 243 +++++++++++++++++++++++++-------- 1 file changed, 188 insertions(+), 55 deletions(-) diff --git a/scripts/remove-unused-files.js b/scripts/remove-unused-files.js index c6ee721d..6ef6b531 100644 --- a/scripts/remove-unused-files.js +++ b/scripts/remove-unused-files.js @@ -1,81 +1,214 @@ -const { globSync } = require('glob') -const yaml = require('yamljs') const fs = require('fs') const path = require('path') +const yaml = require('yamljs') +const { globSync } = require('glob') + +const SHOULD_REMOVE = false; +const SHOULD_LOG = true; // Load and parse the mkdocs config -const mkdocsConfig = yaml.load('mkdocs.yml') -const docsDir = '../docs' +const docsDir = path.resolve(__dirname, '../docs') -function extractFilePaths(nav, fileList) { +function exploreMarkdownFilesFromConfig (nav, markdownList, mediaList, visited) { if (Array.isArray(nav)) { - nav.forEach(item => extractFilePaths(item, fileList)); + nav.forEach(item => exploreMarkdownFilesFromConfig(item, markdownList, mediaList, visited)) } else if (typeof nav === 'object') { Object.values(nav).forEach(value => { if (typeof value === 'string') { - // Check if it's a local file (not a URL) - if (value.endsWith('.md') || value.endsWith('.html')) { - const fullPath = path.join(docsDir, value); - fileList.add(fullPath); - } + processFile(path.join(docsDir, value), markdownList, mediaList, visited) } else { - extractFilePaths(value, fileList); + exploreMarkdownFilesFromConfig(value, markdownList, mediaList, visited) } - }); + }) } } -const mkdocsFiles = new Set() -extractFilePaths(mkdocsConfig.nav, mkdocsFiles) - -// List of markdown files from mkdocs.yml -for (const page of mkdocsConfig.nav) { - if (typeof page === 'string') { - mkdocsFiles.add(page) - } else if (typeof page === 'object') { - Object.values(page).forEach((file) => { - if (typeof file === 'string') { - mkdocsFiles.add(file) - } - }) +function exploreFilesFromFile (filePath, markdownLinks, mediaLinks, visited) { + let absolutePath = path.resolve(filePath) + + if (visited.has(absolutePath)) { + return + } + + visited.add(absolutePath) + + if (absolutePath.includes('https:') || absolutePath.includes('http:')) { + return + } + + let content + try { + content = fs.readFileSync(absolutePath, 'utf8') + } catch (error) { + console.error(`Error reading file ${absolutePath}: ${error}`) + return + } + + const markdownLinkRegex = /\[.*?\]\((\S+\.[a-zA-Z-]+)(?:#[a-zA-Z-\d]+)?(?:\s+".+")?\s*\)/gi + const linkRegex = /docs\.forta\.network\/en\/latest\/([a-zA-Z-/\d\.]+)(?:#[a-zA-Z-\d]+)?/gi + const imgTagRegex = / folder/page-name/ + const pagePath = getPagePath(absolutePath) + + // Process HTML img tags + while ((match = imgTagRegex.exec(content)) !== null) { + processMediaLink(match[1], pagePath, markdownLinks, mediaLinks, visited) + } + + // Process HTML video tags + while ((match = videoTagRegex.exec(content)) !== null) { + processMediaLink(match[1], pagePath, markdownLinks, mediaLinks, visited) + } +} + +// path/docs/readme-file.md => path/docs/readme-file/ +function getPagePath (absolutePath) { + const parsedPath = path.parse(absolutePath) + + const folderPath = parsedPath.dir + const fileName = parsedPath.name // no ext + const pagePath = folderPath + '/' + fileName + '/' + + return pagePath +} + +function processFile (fullPath, markdownLinks, mediaLinks, visited) { + const fullPathLowerCase = fullPath.toLowerCase() + + if (fullPathLowerCase.endsWith('.md')) { + markdownLinks.add(fullPath) + exploreFilesFromFile(fullPath, markdownLinks, mediaLinks, visited) + } else if (/\.(png|jpg|jpeg|gif|bmp|svg|mp4|avi|mov|webm|pdf|csv)$/i.test(fullPathLowerCase)) { + mediaLinks.add(fullPath) + } +} + +function processSiteLink (linkPath, markdownLinks, mediaLinks, visited) { + if(!(/\S+\.\S+/.test(linkPath))) { + linkPath = linkPath.replace(/\/$/, "") + '.md'; } + + let absolutePath = path.resolve(docsDir, linkPath) + + processFile(absolutePath, markdownLinks, mediaLinks, visited) +} + +function processMarkdownLink (link, currentPath, markdownLinks, mediaLinks, visited) { + const fullPath = path.resolve(path.dirname(currentPath), link) + processFile(fullPath, markdownLinks, mediaLinks, visited) +} + +function processMediaLink (link, currentPath, markdownLinks, mediaLinks, visited) { + const fullPath = path.resolve(currentPath, link) + processFile(fullPath, markdownLinks, mediaLinks, visited) +} + +// Here we start execution +// ------------ + +const EXCLUDE_FOLDERS = ['forta-api-reference', 'stylesheets', 'contracts']; +const INCLUDE_DOC_FILES = ['scam-detector-bot.md', 'attack-detector-bot.md']; + + + +// const mkdocsConfig = yaml.load('../mkdocs.yml') +const mkdocsConfig = yaml.load('mkdocs.yml') + +const usedMarkdownFileSet = new Set() +const usedMediaFileSet = new Set() +const visitedFileSet = new Set() + +for(const docFile of INCLUDE_DOC_FILES) { + processFile(path.resolve(docsDir, docFile), usedMarkdownFileSet, usedMediaFileSet, visitedFileSet) } -console.log(`Markdown files: ${mkdocsFiles.size}`) -for (const file of mkdocsFiles) { - console.log('- ' + file) +// Parse mkdocs config +exploreMarkdownFilesFromConfig(mkdocsConfig.nav, usedMarkdownFileSet, usedMediaFileSet, visitedFileSet) +exploreMarkdownFilesFromConfig(mkdocsConfig.theme, usedMarkdownFileSet, usedMediaFileSet, visitedFileSet) +// Parse meta tags +exploreFilesFromFile(path.resolve(docsDir, '../overrides', 'main.html'), usedMarkdownFileSet, usedMediaFileSet, visitedFileSet) + +// Recursively find all related files referenced within each file +for (const filePath of [...usedMarkdownFileSet]) { + exploreFilesFromFile(filePath, usedMarkdownFileSet, usedMediaFileSet, visitedFileSet) } -// Find all .md files in the project -const allMarkdownFiles = globSync(`${docsDir}/**/*.md`) -const notUsedMarkdownFiles = allMarkdownFiles.filter((file) => { - const relativeFile = path.relative(docsDir, file) - return !mkdocsFiles.has(relativeFile) +const allMarkdownFiles = globSync(`${docsDir}/**/*.md`, { ignore: 'node_modules/**', absolute: true }) +const allMediaFiles = globSync(`${docsDir}/**/*.{png,jpg,jpeg,gif,bmp,svg,mp4,avi,mov,webm,pdf,csv}`, { + ignore: 'node_modules/**', + absolute: true }) -console.log(`-----------`) +const canBeRemovedMarkdownFiles = new Set(allMarkdownFiles.filter(file => !usedMarkdownFileSet.has(file) && !file.includes('index.md'))) +const canBeRemovedMediaFiles = new Set(allMediaFiles.filter(file => !usedMediaFileSet.has(file))) + +for(const folder of EXCLUDE_FOLDERS) { + const folderPath = path.resolve(docsDir, folder) -console.log('Removing unused markdown files...') -for (const file of notUsedMarkdownFiles) { - console.log('- ' + file) - fs.unlinkSync(file) + for(const filePath of canBeRemovedMarkdownFiles) { + if(filePath.includes(folderPath)) { + canBeRemovedMarkdownFiles.delete(filePath) + } + } + + for(const filePath of canBeRemovedMediaFiles) { + if(filePath.includes(folderPath)) { + canBeRemovedMediaFiles.delete(filePath) + } + } } -// Find and remove unused media files -const mediaExtensions = ['png', 'jpg', 'jpeg', 'gif', 'svg', 'mp4', 'avi', 'pdf', 'csv'] -const mediaFiles = globSync(`${docsDir}/**/*.{${mediaExtensions.join(',')}}`) - -console.log(`-----------`) -console.log(`Media files: ${mediaFiles.length}`) -console.log('Removing unused media files...') -for (const mediaFile of mediaFiles) { - const isUsed = [...mkdocsFiles].some(file => { - const content = fs.readFileSync(file, 'utf-8') - return content.includes(path.basename(mediaFile)) - }) - - if (!isUsed) { - console.log('- ' + mediaFile) - fs.unlinkSync(mediaFile) +console.log() +console.log('-----------------------------') +console.log(`Used markdown files: ${usedMarkdownFileSet.size}`) +console.log(`Unused markdown files: ${canBeRemovedMarkdownFiles.size}`) +console.log(`Used media files: ${usedMediaFileSet.size}`) +console.log(`Unused media files: ${canBeRemovedMediaFiles.size}`) +console.log('-----------------------------') +console.log() + +if(SHOULD_LOG) { + for (const file of usedMarkdownFileSet) { + console.log(`[IN USE]: ${file}`) + } + + console.log('--------------------') + + for (const file of canBeRemovedMarkdownFiles) { + console.log(`[REMOVE]: ${file}`) + } + + console.log('--------------------') + + for (const file of usedMediaFileSet) { + console.log(`[IN USE]: ${file}`) + } + + console.log('--------------------') + + for (const file of canBeRemovedMediaFiles) { + console.log(`[REMOVE]: ${file}`) + } +} + +if(SHOULD_REMOVE) { + for (const file of canBeRemovedMarkdownFiles) { + fs.unlinkSync(file); + } + for (const file of canBeRemovedMediaFiles) { + fs.unlinkSync(file); } } From 77bac998b79868edd680fc82fa5dbb5ef5079a96 Mon Sep 17 00:00:00 2001 From: Artem Kovalchuk Date: Tue, 28 May 2024 15:35:10 +0300 Subject: [PATCH 4/5] Fix links --- ... Litepaper.pdf => 2022-7-11_Forta_Litepaper.pdf} | Bin docs/FAQs.md | 4 ++-- ...t.pdf => Forta_Network_Airdrop_Audit_Report.pdf} | Bin ...otocol Audit.pdf => OZ_Forta_Protocol_Audit.pdf} | Bin docs/scam-detector-bot.md | 2 +- docs/scan-node/monitor.md | 2 +- docs/security-design.md | 4 ++-- docs/security-testing.md | 6 +++--- docs/slashing-creating-proposal.md | 2 +- docs/useful-libraries.md | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) rename docs/{2022-7-11 Forta Litepaper.pdf => 2022-7-11_Forta_Litepaper.pdf} (100%) rename docs/{Forta Network Airdrop Audit Report.pdf => Forta_Network_Airdrop_Audit_Report.pdf} (100%) rename docs/{OZ Forta Protocol Audit.pdf => OZ_Forta_Protocol_Audit.pdf} (100%) diff --git a/docs/2022-7-11 Forta Litepaper.pdf b/docs/2022-7-11_Forta_Litepaper.pdf similarity index 100% rename from docs/2022-7-11 Forta Litepaper.pdf rename to docs/2022-7-11_Forta_Litepaper.pdf diff --git a/docs/FAQs.md b/docs/FAQs.md index 483bddbd..bd447354 100644 --- a/docs/FAQs.md +++ b/docs/FAQs.md @@ -29,7 +29,7 @@ You can use Forta’s GraphQL API to query the data, or subscribe to notificatio [Here](https://docs.forta.network/en/latest/api-reference/) you can learn how to use the API. -[Here](https://docs.forta.network/en/latest/subcribing-to-bot/) you can learn how to subscribe to notifications using the Forta App. +[Here](subscribing-to-bot.md) you can learn how to subscribe to notifications using the Forta App. ### **How can I find valuable detection bots in the network?** @@ -167,4 +167,4 @@ The community of data scientists and developers in the Forta Network have create ### **Is Forta a blockchain?** -Short answer: no. Forta is not a blockchain in the sense that it does not maintain a shared state between nodes, but it has similar characteristics to a blockchain in that it is a decentralized network of nodes. Forta is more similar to The Graph protocol in that it runs on top of a blockchain. Forta uses a blockchain (i.e. Polygon) to coordinate scan nodes and store IPFS references to alerts generated by bots. \ No newline at end of file +Short answer: no. Forta is not a blockchain in the sense that it does not maintain a shared state between nodes, but it has similar characteristics to a blockchain in that it is a decentralized network of nodes. Forta is more similar to The Graph protocol in that it runs on top of a blockchain. Forta uses a blockchain (i.e. Polygon) to coordinate scan nodes and store IPFS references to alerts generated by bots. diff --git a/docs/Forta Network Airdrop Audit Report.pdf b/docs/Forta_Network_Airdrop_Audit_Report.pdf similarity index 100% rename from docs/Forta Network Airdrop Audit Report.pdf rename to docs/Forta_Network_Airdrop_Audit_Report.pdf diff --git a/docs/OZ Forta Protocol Audit.pdf b/docs/OZ_Forta_Protocol_Audit.pdf similarity index 100% rename from docs/OZ Forta Protocol Audit.pdf rename to docs/OZ_Forta_Protocol_Audit.pdf diff --git a/docs/scam-detector-bot.md b/docs/scam-detector-bot.md index 601def0d..b2b16aec 100644 --- a/docs/scam-detector-bot.md +++ b/docs/scam-detector-bot.md @@ -54,7 +54,7 @@ The Scam Detector *labels* are each available via Forta's GraphQL API. For acces ### *Labels* Labels allow a contributor to tag an entity (like an address) with a label. Labels are available via our [GraphQL API](https://docs.forta.network/en/latest/forta-api-reference/#query-labels). This API allows one to search by date range and page over results. -A recent one month sample of the labels can be downloaded [here (prod, V1 label format)](../ScamDetector_0x1d646c4045189991fdfd24a66b192a294158b839a6ec121d740474bdacb3ab23_labels_20230601-20230630.csv) and [here (beta, V2 label format)](../ScamDetector_0x47c45816807d2eac30ba88745bf2778b61bc106bc76411b520a5289495c76db8_labels_20230622-20230630.csv). +A recent one month sample of the labels can be downloaded [here (prod, V1 label format)](ScamDetector_0x1d646c4045189991fdfd24a66b192a294158b839a6ec121d740474bdacb3ab23_labels_20230601-20230630.csv) and [here (beta, V2 label format)](ScamDetector_0x47c45816807d2eac30ba88745bf2778b61bc106bc76411b520a5289495c76db8_labels_20230622-20230630.csv). **Note:** diff --git a/docs/scan-node/monitor.md b/docs/scan-node/monitor.md index 004052d3..6e686dd8 100644 --- a/docs/scan-node/monitor.md +++ b/docs/scan-node/monitor.md @@ -14,7 +14,7 @@ into your browser's search bar. ![View scan node SLA example](../scan-node-view.png) -You can use the [SLA API](sla-api.md) for more details insights. +You can use the [SLA API](../sla-api.md) for more details insights. Please note that the number in Forta App can differ from what SLA API returns because of time range differences (see Q3 in [FAQ](faq.md)). diff --git a/docs/security-design.md b/docs/security-design.md index 0e7ef198..e2a70e4d 100644 --- a/docs/security-design.md +++ b/docs/security-design.md @@ -1,6 +1,6 @@ ## Security - Design -Security starts in the design phase by incorporating strategies to disincentivize and mitigate malicious behaviors. As described in the [Forta Litepaper](../2022-7-11 Forta Litepaper.pdf), the primary guiding principles around the Forta protocol were: +Security starts in the design phase by incorporating strategies to disincentivize and mitigate malicious behaviors. As described in the [Forta Litepaper](2022-7-11_Forta_Litepaper.pdf), the primary guiding principles around the Forta protocol were: - **Decentralization** - this not only applies to the network of independent scan nodes, but also to the detection bots that the community develops and the governance over the Network. This creates redundancies and increases the reliability of the network in case isolated failures occur. - **Cryptoeconomic Incentives** - these incentives, like node and bot staking, encourage net positive behavior and disincentivize malicious behaviors. @@ -20,4 +20,4 @@ As an example, the [Forta Litepaper](../2022-7-11 Forta Litepaper.pdf) detailed The architecture of the Forta smart contracts can be seen in the below diagram. -![Forta Network Smart Contract architecture](Forta-Contract-Architecture.jpg) \ No newline at end of file +![Forta Network Smart Contract architecture](Forta-Contract-Architecture.jpg) diff --git a/docs/security-testing.md b/docs/security-testing.md index c5672550..45ea6d23 100644 --- a/docs/security-testing.md +++ b/docs/security-testing.md @@ -31,10 +31,10 @@ Testing of the code must happen through GitHub Actions on each pull request and Adopting an attacker mindset, the Foundation went beyond employing secure design, development, deployment and testing and enlisted external security experts to assess the Forta Network after it was built. This helped to surface erroneous assumptions and uncover security gaps that may have remained hidden. Forta primarily engaged OpenZeppelin's smart contract auditing expertise as well as Dedalo's web2 and broad threat assessment expertise for other critical components of the Network. All such reports/findings are linked below: -- [Dedalo's Airdrop Assessment, June 17th 2022](../2022Q2-FortaAirdrop-AuditReport.pdf) -- OpenZeppelin's Airdrop Smart Contract Audit, June 9th 2022 +- [Dedalo's Airdrop Assessment, June 17th 2022](2022Q2-FortaAirdrop-AuditReport.pdf) +- [OpenZeppelin's Airdrop Smart Contract Audit, June 9th 2022](Forta_Network_Airdrop_Audit_Report.pdf) - [Dedalo's Forta Scan Node Assessment, April 7th 2022](2022Q1-V2-FortaNode-AuditReport.pdf) -- OpenZeppelin's Protocol Audit, February 7th 2022 +- [OpenZeppelin's Protocol Audit, February 7th 2022](OZ_Forta_Protocol_Audit.pdf) - [Dedalo's Web Security Assessment, January 5th 2022 ](Forta-Report-DDL-05-01-2022.pdf) - [MixBytes' Security Assessment of slash proposal changes, September 2nd 2022](https://github.com/forta-network/forta-contracts/commit/c940dc39b94bc8be6c298deab92a3dd55527f321) - [Consensys' Security Assessment of Delegated Staking, November 2022](https://consensys.net/diligence/audits/2022/11/forta-delegated-staking/) diff --git a/docs/slashing-creating-proposal.md b/docs/slashing-creating-proposal.md index 355fda43..1144435c 100644 --- a/docs/slashing-creating-proposal.md +++ b/docs/slashing-creating-proposal.md @@ -4,7 +4,7 @@ Anyone who detects a slashable offence perpetrated by a Scan Node or Bot may rep ## Requirements. -- Have 1000 FORT bridged to Polygon, per proposal. ** This deposit can be slashed if the proposal does not follow appropriate formatting, it is malicious, false or spam**. Check the [slashing process](./slashing-process.md) for more info. +- Have 1000 FORT bridged to Polygon, per proposal. ** This deposit can be slashed if the proposal does not follow appropriate formatting, it is malicious, false or spam**. Check the [slashing policy](slashing-policy.md) for more info. - Present verifiable evidence, in the form of screen captures, log files or any file that proves the accusations. - Have knowledge of uploading files to IPFS. - Is able to present evidence following Forta's [Evidence Format](#evidence-format) diff --git a/docs/useful-libraries.md b/docs/useful-libraries.md index d375c2ca..5af889c8 100644 --- a/docs/useful-libraries.md +++ b/docs/useful-libraries.md @@ -1,6 +1,6 @@ # Useful libraries -Here is a collection of libraries and APIs that bot developers may find useful when building their bots. Want to add your library here? Check out [this section](/contributing/#improve-the-documentation) to suggest an edit. +Here is a collection of libraries and APIs that bot developers may find useful when building their bots. Want to add your library here? Check out [this section](contributing#improve-the-documentation) to suggest an edit. ## forta-helpers From 45b24a13cf12f8d3a40299b53091a930a8419485 Mon Sep 17 00:00:00 2001 From: Artem Kovalchuk Date: Tue, 28 May 2024 15:38:17 +0300 Subject: [PATCH 5/5] Refactor script --- scripts/remove-unused-files.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/scripts/remove-unused-files.js b/scripts/remove-unused-files.js index 6ef6b531..ed0d9835 100644 --- a/scripts/remove-unused-files.js +++ b/scripts/remove-unused-files.js @@ -3,12 +3,6 @@ const path = require('path') const yaml = require('yamljs') const { globSync } = require('glob') -const SHOULD_REMOVE = false; -const SHOULD_LOG = true; - -// Load and parse the mkdocs config -const docsDir = path.resolve(__dirname, '../docs') - function exploreMarkdownFilesFromConfig (nav, markdownList, mediaList, visited) { if (Array.isArray(nav)) { nav.forEach(item => exploreMarkdownFilesFromConfig(item, markdownList, mediaList, visited)) @@ -119,12 +113,15 @@ function processMediaLink (link, currentPath, markdownLinks, mediaLinks, visited // Here we start execution // ------------ +const SHOULD_REMOVE = false; +const SHOULD_LOG = true; + const EXCLUDE_FOLDERS = ['forta-api-reference', 'stylesheets', 'contracts']; const INCLUDE_DOC_FILES = ['scam-detector-bot.md', 'attack-detector-bot.md']; +// Load and parse the mkdocs config +const docsDir = path.resolve(__dirname, '../docs') - -// const mkdocsConfig = yaml.load('../mkdocs.yml') const mkdocsConfig = yaml.load('mkdocs.yml') const usedMarkdownFileSet = new Set()