├── .editorconfig ├── .eslintrc.js ├── .github └── workflows │ └── main.yml ├── .gitignore ├── .husky ├── commit-msg └── pre-commit ├── README.md ├── commitlint.config.js ├── lerna.json ├── materials ├── icon.psd └── mac-tray.psd ├── package.json ├── packages ├── app │ ├── configs │ │ ├── electron-builder.config.mjs │ │ └── vite.renderer.ts │ ├── package.json │ ├── postcss.config.js │ ├── public │ │ ├── assets │ │ │ ├── icons │ │ │ │ ├── icon.icns │ │ │ │ ├── icon.ico │ │ │ │ ├── logo.png │ │ │ │ ├── logo@1.5x.png │ │ │ │ ├── logo@16x.png │ │ │ │ ├── logo@2x.png │ │ │ │ ├── logo@32x.png │ │ │ │ ├── logo@3x.png │ │ │ │ ├── logo@4x.png │ │ │ │ ├── logo@64x.png │ │ │ │ └── logo@8x.png │ │ │ └── tray │ │ │ │ ├── iconTemplate.png │ │ │ │ ├── iconTemplate@2x.png │ │ │ │ ├── iconTemplate@3x.png │ │ │ │ ├── iconTemplate@4x.png │ │ │ │ └── iconTemplate@512w.png │ │ └── logo.png │ ├── scripts │ │ ├── build.mjs │ │ ├── mitmproxy.js │ │ ├── package.json.tpl │ │ ├── util.mjs │ │ └── watch.mjs │ ├── src │ │ ├── common │ │ │ ├── bridge │ │ │ │ ├── api │ │ │ │ │ └── backend.js │ │ │ │ ├── auto-start │ │ │ │ │ ├── backend.js │ │ │ │ │ └── front.js │ │ │ │ ├── backend.js │ │ │ │ ├── error │ │ │ │ │ └── front.js │ │ │ │ ├── file-selector │ │ │ │ │ ├── backend.js │ │ │ │ │ └── front.js │ │ │ │ ├── front.js │ │ │ │ └── tongji │ │ │ │ │ ├── analysis.js │ │ │ │ │ └── backend.js │ │ │ └── log.js │ │ ├── main │ │ │ ├── index.ts │ │ │ ├── tsconfig.json │ │ │ └── utils │ │ │ │ └── index.ts │ │ ├── preload │ │ │ ├── index.ts │ │ │ └── tsconfig.json │ │ └── renderer │ │ │ ├── App.less │ │ │ ├── App.tsx │ │ │ ├── Routes.tsx │ │ │ ├── assets │ │ │ ├── images │ │ │ │ ├── close.svg │ │ │ │ └── crt-mac.jpg │ │ │ ├── index.css │ │ │ └── tailwind.css │ │ │ ├── components │ │ │ ├── CertTip.tsx │ │ │ ├── FooterToolbar │ │ │ │ ├── index.less │ │ │ │ └── index.tsx │ │ │ ├── Header │ │ │ │ ├── index.less │ │ │ │ └── index.tsx │ │ │ ├── Menu │ │ │ │ ├── index.less │ │ │ │ └── index.tsx │ │ │ ├── PageContainer │ │ │ │ ├── index.less │ │ │ │ └── index.tsx │ │ │ ├── PageLoading │ │ │ │ └── index.tsx │ │ │ ├── RouteContext.tsx │ │ │ ├── centerHook.ts │ │ │ ├── defaultSettings.ts │ │ │ └── hooks │ │ │ │ ├── useConfig.ts │ │ │ │ ├── useInterval.ts │ │ │ │ ├── useLatest.ts │ │ │ │ └── useMemoizedFn.ts │ │ │ ├── constants │ │ │ └── index.ts │ │ │ ├── index.html │ │ │ ├── layouts │ │ │ ├── BasicLayout.module.less │ │ │ ├── BasicLayout.tsx │ │ │ ├── TabLayout.less │ │ │ └── TabLayout.tsx │ │ │ ├── main.tsx │ │ │ ├── pages │ │ │ ├── Dns │ │ │ │ └── index.tsx │ │ │ ├── Domain │ │ │ │ ├── HighPriorityDomain.tsx │ │ │ │ └── index.tsx │ │ │ ├── Home │ │ │ │ ├── index.css │ │ │ │ └── index.tsx │ │ │ ├── Hosts │ │ │ │ └── index.tsx │ │ │ ├── Intercepts │ │ │ │ └── index.tsx │ │ │ ├── Log │ │ │ │ └── index.tsx │ │ │ ├── ProxyConfig │ │ │ │ ├── index.css │ │ │ │ └── index.tsx │ │ │ └── Speed │ │ │ │ └── index.tsx │ │ │ ├── utils │ │ │ ├── api.js │ │ │ ├── editor.ts │ │ │ ├── hooks.ts │ │ │ └── index.ts │ │ │ └── vite-env.d.ts │ ├── tailwind.config.js │ └── tsconfig.json ├── core │ ├── .eslintignore │ ├── index.js │ ├── package.json │ ├── src │ │ ├── config.js │ │ ├── config │ │ │ ├── index.js │ │ │ └── remote_config.json │ │ ├── event.js │ │ ├── expose.js │ │ ├── index.js │ │ ├── modules │ │ │ ├── index.js │ │ │ ├── plugin │ │ │ │ ├── git │ │ │ │ │ ├── config.js │ │ │ │ │ └── index.js │ │ │ │ └── index.js │ │ │ ├── proxy │ │ │ │ └── index.js │ │ │ └── server │ │ │ │ └── index.js │ │ ├── shell │ │ │ ├── index.js │ │ │ ├── scripts │ │ │ │ ├── get-npm-env.js │ │ │ │ ├── get-system-env.js │ │ │ │ ├── kill-by-port.js │ │ │ │ ├── set-npm-env.js │ │ │ │ ├── set-system-env.js │ │ │ │ ├── set-system-proxy │ │ │ │ │ ├── clear.bat │ │ │ │ │ ├── index.js │ │ │ │ │ ├── refresh-internet.js │ │ │ │ │ └── sysproxy.exe │ │ │ │ └── setup-ca.js │ │ │ └── shell.js │ │ ├── status.js │ │ └── utils │ │ │ └── log.js │ └── vite.config.ts ├── fast-ip │ ├── README.md │ ├── package.json │ ├── src │ │ ├── SpeedTester.ts │ │ ├── config.ts │ │ ├── index.ts │ │ ├── log.ts │ │ ├── type.d.ts │ │ └── vite-env.d.ts │ ├── tsconfig.json │ └── vite.config.ts └── mitmproxy │ ├── index.js │ ├── package.json │ ├── src │ ├── index.js │ ├── lib │ │ ├── choice │ │ │ ├── RequestCounter.js │ │ │ └── index.js │ │ ├── dns │ │ │ ├── base.js │ │ │ ├── https.js │ │ │ ├── index.js │ │ │ ├── ipaddress.js │ │ │ ├── lookup.js │ │ │ └── tls.js │ │ ├── interceptor │ │ │ ├── impl │ │ │ │ ├── abort.js │ │ │ │ ├── proxy.js │ │ │ │ ├── redirect.js │ │ │ │ ├── sni.js │ │ │ │ └── success.js │ │ │ └── index.js │ │ └── proxy │ │ │ ├── common │ │ │ ├── ProxyHttpAgent.js │ │ │ ├── ProxyHttpsAgent.js │ │ │ ├── config.js │ │ │ ├── passes │ │ │ │ ├── index.js │ │ │ │ ├── web-incoming.js │ │ │ │ ├── web-outgoing.js │ │ │ │ └── ws-incoming.js │ │ │ └── util.js │ │ │ ├── index.js │ │ │ ├── middleware │ │ │ └── headerTagMiddleware.js │ │ │ ├── mitmproxy │ │ │ ├── createConnectHandler.js │ │ │ ├── createFakeServerCenter.js │ │ │ ├── createRequestHandler.js │ │ │ ├── createUpgradeHandler.js │ │ │ └── index.js │ │ │ └── tls │ │ │ ├── CertAndKeyContainer.js │ │ │ ├── FakeServersCenter.js │ │ │ ├── sniUtil.js │ │ │ └── tlsUtils.js │ ├── options.js │ └── utils │ │ ├── log.js │ │ ├── match.js │ │ └── util.js │ └── vite.config.ts ├── scripts ├── release.js └── utils │ ├── changelog.js │ ├── exec.js │ ├── getPackages.js │ ├── git.js │ ├── index.js │ └── isNextVersion.js └── tsconfig.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["magic", "magic/react"], 3 | globals: {}, 4 | rules: { 5 | "max-params": 0 6 | }, 7 | overrides: [ 8 | { 9 | files: ["**/*.ts", "**/*.tsx"], 10 | extends: ["magic/typescript"], 11 | rules: {} 12 | } 13 | ] 14 | }; 15 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | # main.yml 2 | 3 | # Workflow's name 4 | name: Build Electron App For Win/Mac 5 | 6 | # Workflow's trigger 7 | on: 8 | push: 9 | tags: 10 | - "v*.*.*" 11 | 12 | # Workflow's jobs 13 | jobs: 14 | # job's id 15 | release: 16 | # job's name 17 | name: build and release electron app 18 | 19 | # the type of machine to run the job on 20 | runs-on: ${{ matrix.os }} 21 | 22 | # create a build matrix for jobs 23 | strategy: 24 | fail-fast: false 25 | matrix: 26 | os: [windows-2019, macos-10.15] 27 | 28 | # create steps 29 | steps: 30 | # step1: check out repository 31 | - name: Check out git repository 32 | uses: actions/checkout@v2 33 | 34 | # step2: install node env 35 | - name: Install Node.js 36 | uses: actions/setup-node@v2-beta 37 | 38 | # step3: npm install 39 | - name: npm install 40 | run: | 41 | npm install 42 | npx lerna bootstrap --no-ci 43 | 44 | # step4: build app for mac/win 45 | - name: build windows app 46 | if: matrix.os == 'windows-2019' 47 | run: | 48 | npm run build:windows 49 | env: 50 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 51 | 52 | - name: build mac app 53 | if: matrix.os == 'macos-10.15' 54 | run: | 55 | npm run build:mac 56 | env: 57 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 58 | 59 | # step5: cleanup artifacts in release 60 | - name: cleanup artifacts for windows 61 | if: matrix.os == 'windows-2019' 62 | run: | 63 | npx rimraf "release/!(*.exe)" 64 | 65 | - name: cleanup artifacts for macosZ 66 | if: matrix.os == 'macos-10.15' 67 | run: | 68 | npx rimraf "release/!(*.dmg)" 69 | 70 | # step6: upload artifacts 71 | - name: upload artifacts 72 | uses: actions/upload-artifact@v2 73 | with: 74 | name: ${{ matrix.os }} 75 | path: release 76 | 77 | # step7: create release 78 | - name: release 79 | uses: softprops/action-gh-release@v1 80 | if: startsWith(github.ref, 'refs/tags/') 81 | with: 82 | files: "release/**" 83 | env: 84 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 85 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules/ 3 | *.lock 4 | *.log 5 | .DS_Store 6 | release 7 | dist 8 | package-lock.json 9 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npm run commit-msg -- --commit.edit "$1" 5 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npm run pre-commit 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fast-dev 2 | 3 | `fast-dev`是一款主要用于解决`GitHub`访问问题的工具。 4 | 5 | ## 说明 6 | 7 | 1. 代理型工具,开启后无法直接和其他类似代理一起使用,请知悉。 8 | 9 | ## 安装 10 | 11 | 已构建好的版本: 12 | 13 | - [GitHub Release](https://github.com/ineo6/fast-dev/releases) 14 | - [Gitee Release](https://gitee.com/ineo6/fast-dev/releases) 15 | 16 | ## FAQ 17 | 18 | ### 如果提示损坏或者无法打开 19 | 20 | 可以尝试 [https://zhuanlan.zhihu.com/p/114919138](https://zhuanlan.zhihu.com/p/114919138) 21 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@commitlint/config-conventional"], 3 | rules: { 4 | "type-enum": [ 5 | 2, 6 | "always", 7 | [ 8 | "build", 9 | "chore", 10 | "ci", 11 | "docs", 12 | "feat", 13 | "fix", 14 | "perf", 15 | "refactor", 16 | "revert", 17 | "style", 18 | "test", 19 | "release" 20 | ] 21 | ] 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.2", 3 | "packages": [ 4 | "packages/*" 5 | ], 6 | "command": { 7 | "publish": { 8 | "ignoreChanges": [ 9 | "*.md" 10 | ], 11 | "registry": "https://registry.npmjs.org/" 12 | }, 13 | "bootstrap": { 14 | "ignore": [] 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /materials/icon.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ineo6/fast-dev/3d52bae6f2a665963e01d83d2c444c45524a2571/materials/icon.psd -------------------------------------------------------------------------------- /materials/mac-tray.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ineo6/fast-dev/3d52bae6f2a665963e01d83d2c444c45524a2571/materials/mac-tray.psd -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "workspaces": [ 4 | "packages/*" 5 | ], 6 | "scripts": { 7 | "build": "cd ./packages/app && node ./scripts/build.mjs", 8 | "build:mac": "cd ./packages/app && cross-env MAKE_FOR=mac node ./scripts/build.mjs", 9 | "build:windows": "cd ./packages/app && cross-env MAKE_FOR=win node ./scripts/build.mjs", 10 | "dev": "cd ./packages/app && node ./scripts/watch.mjs", 11 | "build:deps": "npm run build:fast-ip && npm run build:mitmproxy && npm run build:core", 12 | "build:fast-ip": "cd ./packages/fast-ip && npm run build", 13 | "build:mitmproxy": "cd ./packages/mitmproxy && npm run build", 14 | "build:core": "cd ./packages/core && npm run build", 15 | "release": "node scripts/release.js", 16 | "pre-commit": "magic-lint --staged --eslint --prettier --fix", 17 | "commit-msg": "magic-lint --commit", 18 | "prepare": "husky install" 19 | }, 20 | "devDependencies": { 21 | "@babel/eslint-parser": "^7.17.0", 22 | "@babel/preset-react": "^7.16.7", 23 | "@types/node": "14.17.4", 24 | "@typescript-eslint/eslint-plugin": "^5.18.0", 25 | "@typescript-eslint/parser": "^5.18.0", 26 | "chalk": "^4.1.2", 27 | "cross-env": "^7.0.3", 28 | "esbuild": "^0.14.11", 29 | "escape-goat": "^3.0.0", 30 | "eslint": "^7.32.0", 31 | "eslint-config-magic": "^2.3.0", 32 | "eslint-plugin-react": "^7.29.4", 33 | "execa": "^4.1.0", 34 | "git-repo-info": "^2.1.1", 35 | "husky": "^7.0.0", 36 | "inquirer": "^8.2.2", 37 | "lerna": "^3.22.1", 38 | "magic-lint": "^2.1.0", 39 | "typescript": "^4.6.3", 40 | "yargs-parser": "^21.0.1" 41 | }, 42 | "publishConfig": { 43 | "registry": "https://registry.npmjs.org/" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/app/configs/electron-builder.config.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-template-curly-in-string */ 2 | 3 | const TARGET_PLATFORMS_configs = { 4 | mac: { 5 | mac: ['dmg:x64', 'dmg:arm64'], 6 | }, 7 | win: { 8 | win: ['nsis:ia32', 'nsis:x64'], 9 | }, 10 | all: { 11 | mac: ['dmg:x64', 'dmg:arm64'], 12 | // linux: ['AppImage:x64', 'deb:x64'], 13 | win: ['nsis:ia32', 'nsis:x64'], 14 | }, 15 | } 16 | 17 | let targets = TARGET_PLATFORMS_configs.all 18 | 19 | if (process.env.MAKE_FOR === 'mac') { 20 | targets = TARGET_PLATFORMS_configs.mac 21 | } else if (process.env.MAKE_FOR === 'win') { 22 | targets = TARGET_PLATFORMS_configs.win 23 | } 24 | 25 | /** 26 | * @type {import('electron-builder').Configuration} 27 | */ 28 | const config = { 29 | appId: "com.avalon.fastDev", 30 | asar: true, 31 | directories: { 32 | output: "../../release", 33 | app: 'dist', 34 | buildResources: 'public', 35 | }, 36 | mac: { 37 | icon: 'assets/icons/icon.icns', 38 | identity: null, 39 | target: [ 40 | "dmg" 41 | ] 42 | }, 43 | dmg: { 44 | artifactName: '${productName}_mac_${arch}_${version}.${ext}' 45 | }, 46 | win: { 47 | icon: 'assets/icons/icon.ico' 48 | }, 49 | portable: undefined, 50 | nsis: { 51 | oneClick: false, 52 | allowToChangeInstallationDirectory: true, 53 | artifactName: '${productName}_installer_${arch}_${version}.${ext}' 54 | } 55 | } 56 | 57 | export { config, targets } 58 | -------------------------------------------------------------------------------- /packages/app/configs/vite.renderer.ts: -------------------------------------------------------------------------------- 1 | import { join } from "path"; 2 | import { defineConfig } from "vite"; 3 | import react from "@vitejs/plugin-react"; 4 | import styleImport from "vite-plugin-style-import"; 5 | import { builtinModules } from "module"; 6 | import commonjsExternals from "vite-plugin-commonjs-externals"; 7 | import svgrPlugin from "vite-plugin-svgr"; 8 | 9 | export default defineConfig({ 10 | mode: process.env.NODE_ENV, 11 | root: join(__dirname, "../src/renderer"), 12 | resolve: { 13 | mainFields: ["module", "main"] 14 | }, 15 | optimizeDeps: { 16 | exclude: builtinModules 17 | }, 18 | base: "./", 19 | css: { 20 | preprocessorOptions: { 21 | less: { 22 | javascriptEnabled: true 23 | } 24 | } 25 | }, 26 | plugins: [ 27 | svgrPlugin({ 28 | svgrOptions: { 29 | icon: true 30 | } 31 | }), 32 | react(), 33 | styleImport({ 34 | libs: [ 35 | { 36 | libraryName: "antd", 37 | esModule: true, 38 | resolveStyle: name => { 39 | return `antd/es/${name}/style/index`; 40 | } 41 | } 42 | ] 43 | }), 44 | commonjsExternals({ 45 | externals: ["path", /^electron(\/.+)?$/] 46 | }) 47 | ], 48 | build: { 49 | emptyOutDir: true, 50 | outDir: "../../dist/renderer", 51 | rollupOptions: { 52 | external: [...builtinModules, "electron"] 53 | } 54 | } 55 | }); 56 | -------------------------------------------------------------------------------- /packages/app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "version": "1.0.2", 4 | "main": "dist/main/index.js", 5 | "scripts": { 6 | "icons": "electron-icon-builder --input=./public/logo.png --output=public --flatten" 7 | }, 8 | "dependencies": { 9 | "@ant-design/icons": "^4.7.0", 10 | "@codemirror/stream-parser": "^0.19.3", 11 | "@fast-dev/core": "1.0.2", 12 | "@fast-dev/mitmproxy": "1.0.2", 13 | "@uiw/react-codemirror": "^4.3.1", 14 | "antd": "^4.16.13", 15 | "axios": "^0.25.0", 16 | "brace": "^0.11.1", 17 | "json5": "^2.2.0", 18 | "jsoneditor": "^9.5.9", 19 | "jsoneditor-react": "^3.1.2", 20 | "log4js": "^6.3.0", 21 | "react": "^17.0.0", 22 | "react-dom": "^17.0.0", 23 | "react-markdown": "^8.0.2", 24 | "react-router-dom": "^6.0.2", 25 | "semver": "^7.3.5" 26 | }, 27 | "devDependencies": { 28 | "@types/react": "^17.0.0", 29 | "@types/react-dom": "^17.0.0", 30 | "@vitejs/plugin-react": "^1.0.0", 31 | "autoprefixer": "^10.4.0", 32 | "chalk": "^5.0.0", 33 | "electron": "^16.0.2", 34 | "electron-builder": "^22.14.5", 35 | "electron-is-dev": "^2.0.0", 36 | "fs-extra": "^10.0.1", 37 | "less": "^4.1.2", 38 | "less-plugin-import-node-modules": "^1.0.0", 39 | "postcss": "^8.4.5", 40 | "tailwindcss": "^3.0.7", 41 | "typescript": "^4.3.2", 42 | "vite": "^2.6.4", 43 | "vite-plugin-commonjs-externals": "^0.1.1", 44 | "vite-plugin-style-import": "^1.3.0", 45 | "vite-plugin-svgr": "^1.0.1" 46 | }, 47 | "repository": "https://github.com/ineo6/fast-dev.git" 48 | } 49 | -------------------------------------------------------------------------------- /packages/app/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: { 4 | config: "./tailwind.config.js" 5 | }, 6 | autoprefixer: {} 7 | } 8 | }; 9 | -------------------------------------------------------------------------------- /packages/app/public/assets/icons/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ineo6/fast-dev/3d52bae6f2a665963e01d83d2c444c45524a2571/packages/app/public/assets/icons/icon.icns -------------------------------------------------------------------------------- /packages/app/public/assets/icons/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ineo6/fast-dev/3d52bae6f2a665963e01d83d2c444c45524a2571/packages/app/public/assets/icons/icon.ico -------------------------------------------------------------------------------- /packages/app/public/assets/icons/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ineo6/fast-dev/3d52bae6f2a665963e01d83d2c444c45524a2571/packages/app/public/assets/icons/logo.png -------------------------------------------------------------------------------- /packages/app/public/assets/icons/logo@1.5x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ineo6/fast-dev/3d52bae6f2a665963e01d83d2c444c45524a2571/packages/app/public/assets/icons/logo@1.5x.png -------------------------------------------------------------------------------- /packages/app/public/assets/icons/logo@16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ineo6/fast-dev/3d52bae6f2a665963e01d83d2c444c45524a2571/packages/app/public/assets/icons/logo@16x.png -------------------------------------------------------------------------------- /packages/app/public/assets/icons/logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ineo6/fast-dev/3d52bae6f2a665963e01d83d2c444c45524a2571/packages/app/public/assets/icons/logo@2x.png -------------------------------------------------------------------------------- /packages/app/public/assets/icons/logo@32x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ineo6/fast-dev/3d52bae6f2a665963e01d83d2c444c45524a2571/packages/app/public/assets/icons/logo@32x.png -------------------------------------------------------------------------------- /packages/app/public/assets/icons/logo@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ineo6/fast-dev/3d52bae6f2a665963e01d83d2c444c45524a2571/packages/app/public/assets/icons/logo@3x.png -------------------------------------------------------------------------------- /packages/app/public/assets/icons/logo@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ineo6/fast-dev/3d52bae6f2a665963e01d83d2c444c45524a2571/packages/app/public/assets/icons/logo@4x.png -------------------------------------------------------------------------------- /packages/app/public/assets/icons/logo@64x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ineo6/fast-dev/3d52bae6f2a665963e01d83d2c444c45524a2571/packages/app/public/assets/icons/logo@64x.png -------------------------------------------------------------------------------- /packages/app/public/assets/icons/logo@8x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ineo6/fast-dev/3d52bae6f2a665963e01d83d2c444c45524a2571/packages/app/public/assets/icons/logo@8x.png -------------------------------------------------------------------------------- /packages/app/public/assets/tray/iconTemplate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ineo6/fast-dev/3d52bae6f2a665963e01d83d2c444c45524a2571/packages/app/public/assets/tray/iconTemplate.png -------------------------------------------------------------------------------- /packages/app/public/assets/tray/iconTemplate@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ineo6/fast-dev/3d52bae6f2a665963e01d83d2c444c45524a2571/packages/app/public/assets/tray/iconTemplate@2x.png -------------------------------------------------------------------------------- /packages/app/public/assets/tray/iconTemplate@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ineo6/fast-dev/3d52bae6f2a665963e01d83d2c444c45524a2571/packages/app/public/assets/tray/iconTemplate@3x.png -------------------------------------------------------------------------------- /packages/app/public/assets/tray/iconTemplate@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ineo6/fast-dev/3d52bae6f2a665963e01d83d2c444c45524a2571/packages/app/public/assets/tray/iconTemplate@4x.png -------------------------------------------------------------------------------- /packages/app/public/assets/tray/iconTemplate@512w.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ineo6/fast-dev/3d52bae6f2a665963e01d83d2c444c45524a2571/packages/app/public/assets/tray/iconTemplate@512w.png -------------------------------------------------------------------------------- /packages/app/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ineo6/fast-dev/3d52bae6f2a665963e01d83d2c444c45524a2571/packages/app/public/logo.png -------------------------------------------------------------------------------- /packages/app/scripts/build.mjs: -------------------------------------------------------------------------------- 1 | import esbuild from "esbuild"; 2 | import { join } from 'path' 3 | import { build as viteBuild } from 'vite' 4 | import { build as electronBuild } from 'electron-builder' 5 | import chalk from 'chalk' 6 | import electron from "electron"; 7 | import { config as builderConfig, targets } from '../configs/electron-builder.config.mjs' 8 | import { generateBaseFile, workSpace } from "./util.mjs"; 9 | 10 | process.env.NODE_ENV = 'production' 11 | 12 | const TAG = chalk.bgBlue('[build.mjs]') 13 | 14 | function esbuildSync (entry, outFile, name = 'default') { 15 | console.group(TAG, name) 16 | 17 | esbuild.buildSync({ 18 | entryPoints: entry, 19 | outfile: outFile, 20 | absWorkingDir: workSpace, 21 | bundle: true, 22 | platform: 'node', 23 | external: ['electron', '@fast-dev/core'], 24 | }) 25 | 26 | console.groupEnd() 27 | console.log() 28 | } 29 | 30 | async function buildElectron () { 31 | esbuildSync([join(workSpace, './src/main/index.ts')], join(workSpace, './dist/main/index.js'), 'main') 32 | esbuildSync([join(workSpace, './src/preload/index.ts')], join(workSpace, './dist/preload/index.js'), 'preload') 33 | 34 | console.group(TAG, 'renderer') 35 | await viteBuild({ 36 | configFile: join(workSpace, 'configs/vite.renderer.ts'), 37 | mode: process.env.NODE_ENV, 38 | }) 39 | console.groupEnd() 40 | console.log() 41 | } 42 | 43 | async function packElectron () { 44 | return electronBuild({ 45 | ...targets, 46 | config: builderConfig, 47 | }).then(result => { 48 | console.log(TAG, 'files:', chalk.green(result)) 49 | }) 50 | } 51 | 52 | generateBaseFile() 53 | await buildElectron() 54 | await packElectron() 55 | -------------------------------------------------------------------------------- /packages/app/scripts/mitmproxy.js: -------------------------------------------------------------------------------- 1 | const server = require("@fast-dev/mitmproxy"); 2 | const JSON5 = require("json5"); 3 | 4 | const configPath = process.argv[2]; 5 | const fs = require("fs"); 6 | const configJson = fs.readFileSync(configPath); 7 | const config = JSON5.parse(configJson); 8 | 9 | config.setting.rootDir = __dirname; 10 | server.start(config); 11 | -------------------------------------------------------------------------------- /packages/app/scripts/package.json.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fast-dev", 3 | "productName": "FastDev", 4 | "version": "{{version}}", 5 | "description": "开发助手", 6 | "private": true, 7 | "author": "ineo6", 8 | "main": "./main/index.js", 9 | "dependencies": { 10 | "@fast-dev/mitmproxy": "{{version}}", 11 | "@fast-dev/core": "{{version}}", 12 | "is-browser": "2.1.0", 13 | "json5": "^2.1.3" 14 | }, 15 | "devDependencies": { 16 | "electron": "16.0.2" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/app/scripts/util.mjs: -------------------------------------------------------------------------------- 1 | import path, { join, relative } from "path"; 2 | import { readFileSync, writeFileSync, copyFileSync, existsSync } from "fs"; 3 | import chalk from "chalk"; 4 | import url from "url"; 5 | import fsExtra, { mkdirpSync } from 'fs-extra' 6 | 7 | const { __dirname } = getPath(import.meta.url) 8 | 9 | const pkg = JSON.parse( 10 | readFileSync( 11 | new URL('../package.json', import.meta.url) 12 | ) 13 | ); 14 | 15 | export function getPath (url2) { 16 | const __filename = url.fileURLToPath(url2); 17 | const __dirname = path.dirname(__filename); 18 | return { __filename, __dirname } 19 | } 20 | 21 | export const workSpace = join(__dirname, '../') 22 | export const dist = join(workSpace, 'dist') 23 | 24 | function createPackageJson () { 25 | const target = join(dist, 'package.json') 26 | 27 | const tpl = readFileSync(join(__dirname, 'package.json.tpl'), 'utf-8'); 28 | const content = tpl.replace(/{{version}}/g, pkg.version); 29 | console.log(`${chalk.green('Write:')} ${relative(workSpace, target)}`); 30 | writeFileSync(target, content, 'utf-8'); 31 | } 32 | 33 | export function generateBaseFile () { 34 | if (!existsSync(dist)) { 35 | mkdirpSync(dist) 36 | } 37 | 38 | createPackageJson() 39 | 40 | copyFileSync(join(workSpace, './scripts/mitmproxy.js'), join(dist, 'mitmproxy.js')) 41 | fsExtra.copySync(join(workSpace, './public/assets'), join(dist, 'assets')) 42 | } 43 | -------------------------------------------------------------------------------- /packages/app/scripts/watch.mjs: -------------------------------------------------------------------------------- 1 | import { readFileSync } from 'fs' 2 | import { join } from 'path' 3 | import electron from 'electron' 4 | import { spawn } from 'child_process' 5 | import { createServer } from 'vite' 6 | import esbuild from 'esbuild' 7 | import { dist, generateBaseFile, getPath, workSpace } from "./util.mjs"; 8 | 9 | process.env.NODE_ENV = 'development' 10 | 11 | const { __dirname } = getPath(import.meta.url) 12 | 13 | const pkg = JSON.parse(readFileSync(join(process.cwd(), 'package.json'), 'utf8')) 14 | 15 | function esbuildPromise (entry, outFile, onRebuild) { 16 | return esbuild.build({ 17 | entryPoints: entry, 18 | outfile: outFile, 19 | absWorkingDir: join(__dirname, '../'), 20 | bundle: true, 21 | platform: 'node', 22 | external: ['electron'], 23 | watch: { 24 | onRebuild (error) { 25 | if (error) { 26 | console.error('watch build failed:', error) 27 | } else { 28 | onRebuild() 29 | } 30 | }, 31 | } 32 | }).then((result) => { 33 | console.log('watching...') 34 | 35 | if (result.errors.length) { 36 | console.error('watch build failed:', result.errors) 37 | } else { 38 | onRebuild() 39 | } 40 | }) 41 | } 42 | 43 | async function watchMain () { 44 | let electronProcess = null 45 | 46 | return esbuildPromise( 47 | [join(workSpace, './src/main/index.ts')], 48 | join(dist, './main/index.js'), 49 | () => { 50 | electronProcess && electronProcess.kill() 51 | electronProcess = spawn(electron, ['.'], { 52 | stdio: 'inherit', 53 | env: Object.assign(process.env, pkg.env), // Why don't work? 54 | }) 55 | }) 56 | } 57 | 58 | async function watchPreload (viteDevServer) { 59 | return esbuildPromise( 60 | [join(workSpace, './src/preload/index.ts')], 61 | join(dist, './preload/index.js'), 62 | () => { 63 | viteDevServer.ws.send({ 64 | type: 'full-reload', 65 | }) 66 | }) 67 | } 68 | 69 | // bootstrap 70 | const viteDevServer = await createServer({ configFile: join(workSpace, 'configs/vite.renderer.ts') }) 71 | 72 | generateBaseFile() 73 | await viteDevServer.listen() 74 | await watchPreload(viteDevServer) 75 | await watchMain() 76 | -------------------------------------------------------------------------------- /packages/app/src/common/bridge/api/backend.js: -------------------------------------------------------------------------------- 1 | import lodash from "lodash"; 2 | import { ipcMain } from "electron"; 3 | import fs from "fs"; 4 | import JSON5 from "json5"; 5 | import path from "path"; 6 | import log from "../../log"; 7 | 8 | const Core = require("@fast-dev/core"); 9 | 10 | const mitmproxyPath = path.join(__dirname, "../mitmproxy.js"); 11 | 12 | const getDefaultConfigBasePath = function() { 13 | return Core.api.config.get().server.setting.userBasePath; 14 | }; 15 | const localApi = { 16 | /** 17 | * 返回所有api列表,供vue来ipc调用 18 | * @returns {[]} 19 | */ 20 | getApiList() { 21 | const core = lodash.cloneDeep(Core.api); 22 | const local = lodash.cloneDeep(localApi); 23 | 24 | lodash.merge(core, local); 25 | 26 | const list = []; 27 | _deepFindFunction(list, core, ""); 28 | 29 | return list; 30 | }, 31 | info: { 32 | get() { 33 | const pk = require(path.join(__dirname, "../package.json")); 34 | 35 | return { 36 | ...pk 37 | }; 38 | }, 39 | getConfigDir() { 40 | return getDefaultConfigBasePath(); 41 | }, 42 | getSystemPlatform() { 43 | return Core.api.shell.getSystemPlatform(); 44 | } 45 | }, 46 | /** 47 | * 软件设置 48 | */ 49 | setting: { 50 | load() { 51 | const settingPath = _getSettingsPath(); 52 | let setting = {}; 53 | 54 | if (fs.existsSync(settingPath)) { 55 | const file = fs.readFileSync(settingPath); 56 | setting = JSON5.parse(file.toString()); 57 | if (!setting) { 58 | setting = {}; 59 | } 60 | } 61 | 62 | if (!setting.installTime) { 63 | setting.installTime = new Date().getTime(); 64 | localApi.setting.save(setting); 65 | } 66 | return setting; 67 | }, 68 | save(setting = {}) { 69 | const settingPath = _getSettingsPath(); 70 | fs.writeFileSync(settingPath, JSON5.stringify(setting, null, 2)); 71 | } 72 | }, 73 | /** 74 | * 启动所有 75 | * @returns {Promise} 76 | */ 77 | startup() { 78 | return Core.api.startup({ mitmproxyPath }); 79 | }, 80 | server: { 81 | /** 82 | * 启动代理服务 83 | * @returns {Promise<{port: *}>} 84 | */ 85 | start() { 86 | return Core.api.server.start({ mitmproxyPath }); 87 | }, 88 | /** 89 | * 重启代理服务 90 | * @returns {Promise} 91 | */ 92 | restart() { 93 | return Core.api.server.restart({ mitmproxyPath }); 94 | } 95 | }, 96 | closeWin() { 97 | const { win } = coreBackend.context; 98 | 99 | win && win.isClosable() && win.close(); 100 | } 101 | }; 102 | 103 | function _deepFindFunction(list, parent, parentKey) { 104 | // eslint-disable-next-line guard-for-in 105 | for (const key in parent) { 106 | const item = parent[key]; 107 | if (item instanceof Function) { 108 | list.push(parentKey + key); 109 | } else if (item instanceof Object) { 110 | _deepFindFunction(list, item, parentKey + key + "."); 111 | } 112 | } 113 | } 114 | 115 | function _getSettingsPath() { 116 | const dir = getDefaultConfigBasePath(); 117 | if (!fs.existsSync(dir)) { 118 | fs.mkdirSync(dir); 119 | } 120 | return dir + "/setting.json"; 121 | } 122 | 123 | function invoke(api, param) { 124 | let target = lodash.get(localApi, api); 125 | if (!target) { 126 | target = lodash.get(Core.api, api); 127 | } 128 | if (!target) { 129 | log.info("找不到此接口方法:", api); 130 | } 131 | const ret = target(param); 132 | // log.info('api:', api, 'ret:', ret) 133 | return ret; 134 | } 135 | 136 | async function doStart() { 137 | // 开启自动下载远程配置 138 | await Core.api.config.startAutoDownloadRemoteConfig(); 139 | // 启动所有 140 | localApi.startup(); 141 | } 142 | 143 | const coreBackend = { 144 | context: {}, 145 | install(context) { 146 | const { win } = context; 147 | 148 | coreBackend.context = context; 149 | 150 | // 接收view的方法调用 151 | ipcMain.handle("apiInvoke", async (event, args) => { 152 | const api = args[0]; 153 | let param; 154 | if (args.length >= 2) { 155 | param = args[1]; 156 | } 157 | return invoke(api, param); 158 | }); 159 | // 注册从core里来的事件,并转发给view 160 | Core.api.event.register("status", event => { 161 | log.info("bridge on status", event); 162 | win.webContents.send("status", { ...event }); 163 | }); 164 | Core.api.event.register("error", event => { 165 | log.error("bridge on error", event); 166 | win.webContents.send("error.core", event); 167 | }); 168 | Core.api.event.register("speed", event => { 169 | win.webContents.send("speed", event); 170 | }); 171 | 172 | // 合并用户配置 173 | Core.api.config.reload(); 174 | doStart(); 175 | }, 176 | fastDevCore: Core, 177 | invoke 178 | }; 179 | 180 | export default coreBackend; 181 | -------------------------------------------------------------------------------- /packages/app/src/common/bridge/auto-start/backend.js: -------------------------------------------------------------------------------- 1 | const Core = require("@fast-dev/core"); 2 | 3 | async function setAutoStartForLinux(app, enable = true) { 4 | const path = app.getPath("exe"); 5 | if (enable) { 6 | const cmd = ` 7 | mkdir -p ~/.config/autostart/ 8 | cat >> ~/.config/autostart/fast-dev.desktop <