From 610b0e287bb04947baf34c8e22206da22852b457 Mon Sep 17 00:00:00 2001 From: Arlo Date: Sun, 16 Jun 2024 18:04:31 +0800 Subject: [PATCH] feat: firefox extension (#446) --- .gitignore | 2 + package.json | 6 + packages/chrome-extension/icons/128-beta.png | Bin 0 -> 4620 bytes packages/chrome-extension/icons/16-beta.png | Bin 0 -> 644 bytes packages/chrome-extension/icons/48-beta.png | Bin 0 -> 1747 bytes packages/chrome-extension/manifest.json | 10 +- packages/chrome-extension/package.json | 2 +- .../popups/devtools-screenshot.png | Bin 11306 -> 13578 bytes packages/chrome-extension/popups/enabled.html | 2 +- .../chrome-extension/popups/enabled.nuxt.html | 2 +- packages/chrome-extension/tsup.config.ts | 3 +- packages/client/src/main.ts | 4 +- packages/client/src/pages/index.vue | 8 +- packages/client/src/pages/overview.vue | 2 +- packages/client/vite.lib.config.ts | 2 +- packages/firefox-extension/README.md | 3 + .../devtools-background.html | 9 + .../firefox-extension/devtools-panel.html | 28 ++ packages/firefox-extension/icons/128-beta.png | Bin 0 -> 4620 bytes packages/firefox-extension/icons/128-gray.png | Bin 0 -> 4012 bytes packages/firefox-extension/icons/128.nuxt.png | Bin 0 -> 2264 bytes packages/firefox-extension/icons/128.png | Bin 0 -> 5269 bytes packages/firefox-extension/icons/16-beta.png | Bin 0 -> 644 bytes packages/firefox-extension/icons/16-gray.png | Bin 0 -> 1500 bytes packages/firefox-extension/icons/16.nuxt.png | Bin 0 -> 441 bytes packages/firefox-extension/icons/16.png | Bin 0 -> 1603 bytes packages/firefox-extension/icons/48-beta.png | Bin 0 -> 1747 bytes packages/firefox-extension/icons/48-gray.png | Bin 0 -> 2253 bytes packages/firefox-extension/icons/48.nuxt.png | Bin 0 -> 968 bytes packages/firefox-extension/icons/48.png | Bin 0 -> 2752 bytes packages/firefox-extension/manifest.json | 58 ++++ packages/firefox-extension/package.json | 24 ++ .../popups/devtools-screenshot.png | Bin 0 -> 13578 bytes .../firefox-extension/popups/disabled.html | 8 + .../popups/disabled.nuxt.html | 8 + .../firefox-extension/popups/enabled.html | 23 ++ .../popups/enabled.nuxt.html | 23 ++ .../firefox-extension/popups/not-found.html | 6 + packages/firefox-extension/popups/popup.css | 47 +++ packages/firefox-extension/src/background.ts | 107 +++++++ packages/firefox-extension/src/detector.ts | 58 ++++ .../src/devtools-background.ts | 33 ++ .../firefox-extension/src/devtools-overlay.ts | 16 + .../firefox-extension/src/devtools-panel.ts | 55 ++++ packages/firefox-extension/src/injection.ts | 7 + packages/firefox-extension/src/prepare.ts | 5 + packages/firefox-extension/src/proxy.ts | 10 + packages/firefox-extension/src/user-app.ts | 16 + packages/firefox-extension/tsup.config.ts | 19 ++ packages/playground/basic/src/main.ts | 3 +- packages/shared/src/env.ts | 8 +- pnpm-lock.yaml | 302 ++++++++++++++---- scripts/extension-zip.ts | 10 +- scripts/release-extension.ts | 93 ++++++ turbo.json | 14 +- 55 files changed, 936 insertions(+), 100 deletions(-) create mode 100644 packages/chrome-extension/icons/128-beta.png create mode 100644 packages/chrome-extension/icons/16-beta.png create mode 100644 packages/chrome-extension/icons/48-beta.png create mode 100644 packages/firefox-extension/README.md create mode 100644 packages/firefox-extension/devtools-background.html create mode 100644 packages/firefox-extension/devtools-panel.html create mode 100644 packages/firefox-extension/icons/128-beta.png create mode 100644 packages/firefox-extension/icons/128-gray.png create mode 100644 packages/firefox-extension/icons/128.nuxt.png create mode 100644 packages/firefox-extension/icons/128.png create mode 100644 packages/firefox-extension/icons/16-beta.png create mode 100644 packages/firefox-extension/icons/16-gray.png create mode 100644 packages/firefox-extension/icons/16.nuxt.png create mode 100644 packages/firefox-extension/icons/16.png create mode 100644 packages/firefox-extension/icons/48-beta.png create mode 100644 packages/firefox-extension/icons/48-gray.png create mode 100644 packages/firefox-extension/icons/48.nuxt.png create mode 100644 packages/firefox-extension/icons/48.png create mode 100644 packages/firefox-extension/manifest.json create mode 100644 packages/firefox-extension/package.json create mode 100644 packages/firefox-extension/popups/devtools-screenshot.png create mode 100644 packages/firefox-extension/popups/disabled.html create mode 100644 packages/firefox-extension/popups/disabled.nuxt.html create mode 100644 packages/firefox-extension/popups/enabled.html create mode 100644 packages/firefox-extension/popups/enabled.nuxt.html create mode 100644 packages/firefox-extension/popups/not-found.html create mode 100644 packages/firefox-extension/popups/popup.css create mode 100644 packages/firefox-extension/src/background.ts create mode 100644 packages/firefox-extension/src/detector.ts create mode 100644 packages/firefox-extension/src/devtools-background.ts create mode 100644 packages/firefox-extension/src/devtools-overlay.ts create mode 100644 packages/firefox-extension/src/devtools-panel.ts create mode 100644 packages/firefox-extension/src/injection.ts create mode 100644 packages/firefox-extension/src/prepare.ts create mode 100644 packages/firefox-extension/src/proxy.ts create mode 100644 packages/firefox-extension/src/user-app.ts create mode 100644 packages/firefox-extension/tsup.config.ts create mode 100644 scripts/release-extension.ts diff --git a/.gitignore b/.gitignore index e3eeca6a..ded66549 100644 --- a/.gitignore +++ b/.gitignore @@ -91,6 +91,8 @@ components.d.ts packages/chrome-extension/overlay/**/* packages/chrome-extension/client/**/* +packages/firefox-extension/client/**/* +packages/firefox-extension/overlay/**/* packages/electron/client/**/* packages/vite/src/overlay/**/* packages/vite/client/**/* diff --git a/package.json b/package.json index 49d16ae1..6bbf2311 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,9 @@ "build:vite": "turbo build --filter=./packages/vite...", "build:devtools-api": "turbo build --filter=./packages/devtools-api...", "build:chrome-extension": "turbo build --filter=./packages/chrome-extension...", + "build:firefox-extension": "turbo build --filter=./packages/firefox-extension...", "dev:chrome-extension": "turbo dev --filter=./packages/chrome-extension", + "dev:firefox-extension": "turbo dev --filter=./packages/firefox-extension", "dev:ui-story": "turbo dev --filter=./packages/ui-story", "prepare:type": "turbo prepare:type --filter='./packages/*'", "dev": "NODE_OPTIONS=\"--max-old-space-size=8192\" nr prepare:type && nr build:ui && turbo stub --concurrency 20", @@ -66,12 +68,14 @@ "docs": "pnpm -C docs run docs:dev", "docs:build": "pnpm -C docs run docs:build", "zip": "tsx ./scripts/extension-zip.ts", + "release-extension": "tsx ./scripts/release-extension.ts && nr zip", "gen:vue-apis": "tsx ./scripts/vue-api-manifest.ts" }, "devDependencies": { "@antfu/eslint-config": "2.21.0", "@antfu/ni": "^0.21.12", "@arethetypeswrong/cli": "^0.15.3", + "@clack/prompts": "^0.7.0", "@types/chrome": "^0.0.268", "@types/degit": "^2.8.6", "@types/fs-extra": "^11.0.4", @@ -93,11 +97,13 @@ "jsdom": "^24.1.0", "lint-staged": "^15.2.5", "npm-run-all2": "^6.2.0", + "picocolors": "^1.0.1", "pnpm": "^9.3.0", "progress": "^2.0.3", "publint": "^0.2.8", "readdir-glob": "^2.0.0", "regex-extra": "^0.2.2", + "semver": "^7.6.2", "simple-git-hooks": "^2.11.1", "taze": "^0.13.8", "tsup": "^8.1.0", diff --git a/packages/chrome-extension/icons/128-beta.png b/packages/chrome-extension/icons/128-beta.png new file mode 100644 index 0000000000000000000000000000000000000000..a9642998d77ab097c511ec6a2aa3d9e405035f1e GIT binary patch literal 4620 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 literal 0 HcmV?d00001 diff --git a/packages/chrome-extension/manifest.json b/packages/chrome-extension/manifest.json index 3857fcc4..6b63f693 100644 --- a/packages/chrome-extension/manifest.json +++ b/packages/chrome-extension/manifest.json @@ -41,9 +41,9 @@ "" ], "icons": { - "16": "icons/16.png", - "48": "icons/48.png", - "128": "icons/128.png" + "16": "icons/16-beta.png", + "48": "icons/48-beta.png", + "128": "icons/128-beta.png" }, "manifest_version": 3, "name": "Vue.js DevTools", @@ -51,8 +51,8 @@ "scripting", "storage" ], - "version": "0.0.0", - "version_name": "0.0.0", + "version": "7.0.0.1", + "version_name": "7.0.0 beta 1", "web_accessible_resources": [ { "extension_ids": [], diff --git a/packages/chrome-extension/package.json b/packages/chrome-extension/package.json index e068b228..02670f97 100644 --- a/packages/chrome-extension/package.json +++ b/packages/chrome-extension/package.json @@ -1,7 +1,7 @@ { "name": "@vue/devtools-chrome-extension", "type": "module", - "version": "7.3.0-beta.3", + "version": "7.0.0-beta.1", "private": true, "author": "webfansplz", "license": "MIT", diff --git a/packages/chrome-extension/popups/devtools-screenshot.png b/packages/chrome-extension/popups/devtools-screenshot.png index 2cf3e0e1a6044f604c3caf3ec29b26c996f0cf9c..b2eb579b27d50154284e5ae1fd061cd805564f46 100644 GIT binary patch literal 13578 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
cq{Yb)!dE% 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 diff --git a/packages/chrome-extension/popups/enabled.html b/packages/chrome-extension/popups/enabled.html index 703c2679..bb57127c 100644 --- a/packages/chrome-extension/popups/enabled.html +++ b/packages/chrome-extension/popups/enabled.html @@ -14,7 +14,7 @@

Troubleshooting diff --git a/packages/chrome-extension/popups/enabled.nuxt.html b/packages/chrome-extension/popups/enabled.nuxt.html index 94fddaab..54fa33e1 100644 --- a/packages/chrome-extension/popups/enabled.nuxt.html +++ b/packages/chrome-extension/popups/enabled.nuxt.html @@ -14,7 +14,7 @@

Troubleshooting diff --git a/packages/chrome-extension/tsup.config.ts b/packages/chrome-extension/tsup.config.ts index e55a5e06..f49ab624 100644 --- a/packages/chrome-extension/tsup.config.ts +++ b/packages/chrome-extension/tsup.config.ts @@ -15,6 +15,5 @@ export default defineConfig({ }, clean: true, format: ['iife'], - dts: true, - shims: true, + minify: true, }) diff --git a/packages/client/src/main.ts b/packages/client/src/main.ts index 6c68d219..b4fbd666 100644 --- a/packages/client/src/main.ts +++ b/packages/client/src/main.ts @@ -2,7 +2,7 @@ import '@unocss/reset/tailwind.css' import 'floating-vue/dist/style.css' import { getViteClient } from 'vite-hot-client' -import { isInSeparateWindow } from '@vue/devtools-shared' +import { isInChromePanel, isInSeparateWindow } from '@vue/devtools-shared' import { VueDevToolsVuePlugin, createViteClientRpc, functions, rpc } from '@vue/devtools-core' import { createRpcClient, setViteClientContext } from '@vue/devtools-kit' import { createApp } from 'vue' @@ -50,7 +50,7 @@ app.use(VueDevToolsVuePlugin()) app.mount('#app') async function getViteHotContext() { - if (import.meta.url?.includes('chrome-extension://')) + if (isInChromePanel) return const viteClient = await getViteClient(`${location.pathname.split('/__devtools__')[0] || ''}/`.replace(/\/\//g, '/'), false) diff --git a/packages/client/src/pages/index.vue b/packages/client/src/pages/index.vue index 1a67cb80..ce35b7a1 100644 --- a/packages/client/src/pages/index.vue +++ b/packages/client/src/pages/index.vue @@ -19,12 +19,12 @@ function visit() { is a set of visual tools that help you to know your Vue app better, and enhance your development experience with Vue. Enjoy!

- +

Get Started diff --git a/packages/client/src/pages/overview.vue b/packages/client/src/pages/overview.vue index d220b1ff..96be240a 100644 --- a/packages/client/src/pages/overview.vue +++ b/packages/client/src/pages/overview.vue @@ -66,7 +66,7 @@ onUnmounted(() => {
-
+
Vue DevTools diff --git a/packages/client/vite.lib.config.ts b/packages/client/vite.lib.config.ts index 753c1fa2..6b88b9d6 100644 --- a/packages/client/vite.lib.config.ts +++ b/packages/client/vite.lib.config.ts @@ -44,7 +44,7 @@ export default defineConfig(mergeConfig(baseConfig, { closeBundle() { // copy const clientFile = resolve(__dirname, './dist/devtools-client-lib') - ;['../chrome-extension/client', '../electron/client'].forEach((dir) => { + ;['../chrome-extension/client', '../firefox-extension/client', '../electron/client'].forEach((dir) => { fse.copySync(clientFile, resolve(__dirname, dir)) }) }, diff --git a/packages/firefox-extension/README.md b/packages/firefox-extension/README.md new file mode 100644 index 00000000..77e14b66 --- /dev/null +++ b/packages/firefox-extension/README.md @@ -0,0 +1,3 @@ +# Browser extension + +> DevTools Browser extension, still under development... diff --git a/packages/firefox-extension/devtools-background.html b/packages/firefox-extension/devtools-background.html new file mode 100644 index 00000000..7596585a --- /dev/null +++ b/packages/firefox-extension/devtools-background.html @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/packages/firefox-extension/devtools-panel.html b/packages/firefox-extension/devtools-panel.html new file mode 100644 index 00000000..caeafa0d --- /dev/null +++ b/packages/firefox-extension/devtools-panel.html @@ -0,0 +1,28 @@ + + + + + + + + + +
+
+
+ + + diff --git a/packages/firefox-extension/icons/128-beta.png b/packages/firefox-extension/icons/128-beta.png new file mode 100644 index 0000000000000000000000000000000000000000..a9642998d77ab097c511ec6a2aa3d9e405035f1e GIT binary patch literal 4620 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 pzR_#{?@KHJR7Ze__B!Qm00`5{Tm<wz z1wrVce~Y=+a~OnzEM0;DKm`5^AmHgUnL`p3>|kLGRP@O$9wy*hSQ{(=yh;(-y9NOO zL86r@)-eq9BNux`|M>%x>uwpWNv?&}!O0S%qVD$Zi$Awph6Rlzz}WvVnTx`S@55WfQ-5Hg z{Yy-L9=}>BbbRQyiyy2d^v;(7uRm^jR$#JvrlvV=kfhQFU}K#`IFQN4x49pak9nho z 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 literal 0 HcmV?d00001 diff --git a/packages/firefox-extension/icons/16-beta.png b/packages/firefox-extension/icons/16-beta.png new file mode 100644 index 0000000000000000000000000000000000000000..469c8e9212112ecde4467ddc91c8b38c8261b325 GIT binary patch literal 644 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 literal 0 HcmV?d00001 diff --git a/packages/firefox-extension/icons/48-beta.png b/packages/firefox-extension/icons/48-beta.png new file mode 100644 index 0000000000000000000000000000000000000000..1c898eb89e19bcc1c09c1923c008d676e07fb0a4 GIT binary patch literal 1747 zcmV;^1}yoBP)vK~!jg?U-$FRMi>Bf6v{!dpG0_lB^`f7UV^+RWrU%x4_y2a;;WT8YQv&EUGK6PcSQgF0jlr!NU5LUx~kd{s$;EoD?DV-bpCYa4G-5 zJQE3E{o!tR043iw3B(ejOG=Ch5+}NEUF<%vP)oY5rB3&3(V7P$a|^JFBW8D^9uIo@ z02V-VO~W%lqe*1X$itpGK~E+Wi8BMg)lmyCc0A#A^yg{4IUynoi-Wv%S|R(PAOWNb z0PsS53(&tOfKyQdA<=T)+kMw8sIU9_;MjuAb(8&*-S?UDMaqkjXvpkLsfHJqt?e)i zl6b#>y|*`|eoqms}b!Zhu%(;>Y-&9fm$xP;9 zPyqn(c-RHrHHjnT#Ym3+sreoK6Z$T8Yz0`fuCBs6*;8)H<5a|qs|g^MtZJ!p6T#L~ z+VntW!@#S)@R%^eNsw>)!4)L~cwsij+K9w9il zXwM`7ym$JHttI@)iO9sT*^TgMQ*Fb4%mR%aU9hRTp-G9_X&PjIbOQEtZFe+JG$BOf z=At0U*{J9JXhcad6aZj{{Ot7XNyNM5#MG0R!w5>{>P54uRoBZv(xc5j_E(4HN0RRk0 zJjIiqtZxGzHX6#aiOib>K&UJSdse_f zr}$gb@^w#VZ_|wIPa>eQ*^NrSeFW4rt-$l?{>>?JYRU*rc7{);6f@s@$N%!t-D^JG z{?>^RIaTzMV4wVwAvehp6#(#=U7PMwqJD4U{flw!#$9msUwre>b4=+D{Ql1b55;zD zR?1e+!zc;>sA}BU3{+;Tzx~u}tUj;<(KoWu;3y#$$yUy1zln!HtpvPmlvnk>$Et(R z3^hOH2DtGK^Pp$}Sb-<}96YwbNV?D z-SSGH?7HN6QvE%cb~A_tCD%Y~hA#CN)mJGQMah+EKMb!w3%y;Ce-$VnCTsq86LLmf0KkP<>@nb2kftrSNPo*LnhM3! z!1ti-4d`lz=EvZbU%^0cvXJsG!CQNw^OW|gg5uZ*D&X()zZSQ|e;`P6xOnQ0VZn39 z;l!)Sjl5$u{C7W`JOE4Xhj0{He*v>9;NTx&#$x#Q%h2}E^eq37CpkK*Hkyvg#)qC4 zq((z^M(}1e?rUazOdZwB$xXLxD1XEoxq*4 zjaC@tL8e31u8of(tQr(LtQ_yA!GBPx`&oo=4=@85e%Ay__ag5{2;eTrj+}sgg319#K002ovPDHLkV1i0!Nh1IN literal 0 HcmV?d00001 diff --git a/packages/firefox-extension/icons/48-gray.png b/packages/firefox-extension/icons/48-gray.png new file mode 100644 index 0000000000000000000000000000000000000000..f1729d8fe15f475041f3dce2c792c0c7b7ebdf24 GIT binary patch literal 2253 zcmaJ@Yg7|w8Xjw$mJogB_y7Pvl*9`Y@i*+gy}j_K!gHhuf6c~3saTRZ3(Hob2*6jHGZ9c?RBDh! zM5*4ip%aM(fJs9-c`BAFUCvdRjWnejL$ez#I2!;x_A*7YvaSc+3~R<59I3X5m6mc6K%`JBnsTH4vS{;Xp70VlX0cM5J|-2~*l5P1XhD z7KDgZh3YJr&TInR7L}Q18^)vJO5cTGv`D2BhE3M7MByoe>`Dtnr@@fX=#Fa?ZN(Ci z-(~zE+A7~sf@{@l?xP_3H4S!}3bG)}b&LJWuzF=19*6n#_? zuAI99)!_wH8iZz*&HYs(tVpL#0ZU&V-q*+J){?j)_H3-9|($M$JZW zv=&_5A4tH1WigmB!YDDHjmu{W=xkWX62kl_HiI86Vo=Ap>i2Rs9{Lzp^nbY!E=H~5 zVmi!#j5R6WfQ_vTI(MUR4N8*+&q$;i$x_-37Hqwxw{j>~GKu$;b-wxK;gJ@r>0xJ9L(RUZ__kQWT1dj8979{|odr?0&oYqY`IIpI2jJV+3VKy_%s54O-W9@cJ$<&utH;1L|Z- z@qzYJm9|&Ie&*p+UN42Lx+gd{vFJ7oO{{O&`{n+76A5X z2(WtcVDk?92lgw!1YExnO4~hULG0ulBs|csVDic8YEl!qYtNBK@oldAg!4C_Qf7Xb z7ff=d+-wcdi#CUahZExkMM*_0XX}hY`O-Gufq?asr61>Nqfz$%%O?-{*>)zSnNtxV69c!<;4TlQ|#Tx_$(FlNE}&l1P-* zUgY>be!FbYq3xlp?C%eF8Y)OS|LYp=icI_6{lm0%Vc{ol``<5^D^I&9tjz!B%#t9| z42qYploT*@nslk4WVuI&K`PzJoEiT)(UJ0>IN#tXvd_>y*N+#T3tFcX$)^yzN8W7F zC6|^-gE+A#0$*?VlDNb8!>$=;yGe7}14o|eIxCs|0g^iJido9+v%T6=VU>Z7nwl=s z%-~h3I|+tP#kSBsXY~rf8%kMn^NSX8`m%x{BHfFh_3DslH!=*=&~(C*Mz5+F`rrpvYp>{Uupr&=bjzpG`KqVpoQ>} zrP_|h&ujXdMf+U&jb`BlLQ+d>=Qq1b^^5MRH&=P*n}{zShe2S;bZQFJ z)^A7kyPUi%&2X{jta|}nl(wepi=4S$k~)5m_dV16lh|NMMN5t6>xRM?w|qCyo;xi9 z&FlLY;e)FF(V-&l3|eDCqBo>GVh-iE3?m)ppDdk&;(30p{0 zAJjhy>br-^0IXwJiRr}AA(XgnHKtek+5So05|3}!G?cIWZf-kr`~dfj|K0@2Fj`u9 z)n}de{Ib;*vUwzOx`%AOf5k)FUtO1pgeq4SRQ_~Q*X~3az`XpH=hLyd`3_NRdYf=t zwW;-dL}T!0ZM=4c)pX`D#ecrF9H#!-tG>HxM6>$?!hZ4J3A2D&t%_2&kY#rNU`Rv> K!aBjay#E1w3~8(Y literal 0 HcmV?d00001 diff --git a/packages/firefox-extension/icons/48.nuxt.png b/packages/firefox-extension/icons/48.nuxt.png new file mode 100644 index 0000000000000000000000000000000000000000..7aa05062c14d98fa26208eb881c66314a6c4bb14 GIT binary patch literal 968 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 bY8oIs@{" + ], + "run_at": "document_start" + }, + { + "js": [ + "dist/devtools-overlay.js" + ], + "matches": [ + "" + ], + "run_at": "document_idle" + } + ], + "content_security_policy": "script-src 'self'; object-src 'self'", + "description": "DevTools browser extension for Vue.js", + "devtools_page": "devtools-background.html", + "icons": { + "16": "icons/16-beta.png", + "48": "icons/48-beta.png", + "128": "icons/128-beta.png" + }, + "manifest_version": 2, + "name": "Vue.js DevTools", + "permissions": [ + "", + "storage" + ], + "version": "7.0.0.1", + "version_name": "7.0.0 beta 1", + "web_accessible_resources": [ + "dist/user-app.js", + "client/devtools-panel.css", + "client/devtools-panel.js" + ] +} diff --git a/packages/firefox-extension/package.json b/packages/firefox-extension/package.json new file mode 100644 index 00000000..54587f87 --- /dev/null +++ b/packages/firefox-extension/package.json @@ -0,0 +1,24 @@ +{ + "name": "@vue/devtools-firefox-extension", + "type": "module", + "version": "7.0.0-beta.1", + "private": true, + "author": "webfansplz", + "license": "MIT", + "files": [ + "dist" + ], + "scripts": { + "build": "cross-env NODE_ENV=production tsup", + "dev": "cross-env NODE_ENV=development tsup --watch" + }, + "dependencies": { + "@vue/devtools-core": "workspace:^", + "@vue/devtools-kit": "workspace:^", + "@vue/devtools-shared": "workspace:^" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.0.5", + "vue": "^3.4.27" + } +} diff --git a/packages/firefox-extension/popups/devtools-screenshot.png b/packages/firefox-extension/popups/devtools-screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..b2eb579b27d50154284e5ae1fd061cd805564f46 GIT binary patch literal 13578 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 l(NBRZ5$+KGH;C> + + +

+ Vue.js is detected on this page.
+ Devtools inspection is not available because it's in production mode or + explicitly disabled by the author. +

diff --git a/packages/firefox-extension/popups/disabled.nuxt.html b/packages/firefox-extension/popups/disabled.nuxt.html new file mode 100644 index 00000000..412a8742 --- /dev/null +++ b/packages/firefox-extension/popups/disabled.nuxt.html @@ -0,0 +1,8 @@ + + + +

+ Nuxt + Vue.js is detected on this page.
+ Devtools inspection is not available because it's in production mode or + explicitly disabled by the author. +

diff --git a/packages/firefox-extension/popups/enabled.html b/packages/firefox-extension/popups/enabled.html new file mode 100644 index 00000000..bb57127c --- /dev/null +++ b/packages/firefox-extension/popups/enabled.html @@ -0,0 +1,23 @@ + + + +
diff --git a/packages/firefox-extension/popups/enabled.nuxt.html b/packages/firefox-extension/popups/enabled.nuxt.html new file mode 100644 index 00000000..54fa33e1 --- /dev/null +++ b/packages/firefox-extension/popups/enabled.nuxt.html @@ -0,0 +1,23 @@ + + + +
+
+ Screenshot +
+ +
+

+ Nuxt + Vue.js is detected on this page.
+ Open DevTools and look for the Vue panel. +

+ +

+ Troubleshooting +

+
+
diff --git a/packages/firefox-extension/popups/not-found.html b/packages/firefox-extension/popups/not-found.html new file mode 100644 index 00000000..f7e5139b --- /dev/null +++ b/packages/firefox-extension/popups/not-found.html @@ -0,0 +1,6 @@ + + + +

+ Vue.js not detected +

diff --git a/packages/firefox-extension/popups/popup.css b/packages/firefox-extension/popups/popup.css new file mode 100644 index 00000000..8f59e282 --- /dev/null +++ b/packages/firefox-extension/popups/popup.css @@ -0,0 +1,47 @@ +@import url('https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700,700i'); + +body { + font-family: Roboto, Avenir, Helvetica, Arial, sans-serif; + font-size: 14px; + font-weight: 400; + line-height: 1.4; + padding: 18px 24px; + color: #2c3e50; +} + +body, +p { + margin: 0; +} + +p { + min-width: 200px; + max-width: 300px; +} + +.short-paragraph { + min-width: initial; + white-space: nowrap; +} + +a { + color: #42b983; +} + +.flex { + display: flex; + align-items: center; +} + +.screenshot { + position: relative; +} + +.screenshot > img { + width: 140px; + height: 140px; + object-fit: cover; + border-radius: 100%; + margin-right: 24px; + box-shadow: 0 0 15px rgb(0 0 0 / 10%); +} diff --git a/packages/firefox-extension/src/background.ts b/packages/firefox-extension/src/background.ts new file mode 100644 index 00000000..34bd86ba --- /dev/null +++ b/packages/firefox-extension/src/background.ts @@ -0,0 +1,107 @@ +import { isNumeric } from '@vue/devtools-shared' + +type PortInfo = Record<'tab' | 'name', string | number> & { port: chrome.runtime.Port } +type PortDetail = Record<'devtools' | 'userApp', chrome.runtime.Port> +const ports: Record = {} + +function initPort(portInfo: PortInfo): Record<'devtools' | 'userApp', chrome.runtime.Port> { + const { tab, name, port } = portInfo + ports[tab] ??= { + devtools: null!, + userApp: null!, + } + ports[tab][name] = port + return ports[tab] +} + +function devtoolsUserAppPipe(tabId: string | number) { + const { devtools, userApp } = ports[tabId] + let disconnected = false + + function onDevtoolsMessage(message) { + if (disconnected) + return + if (process.env.NODE_ENV === 'development') { + console.log('%cdevtools -> userApp', 'color:#888;', message) + } + + userApp.postMessage(message) + } + devtools.onMessage.addListener(onDevtoolsMessage) + + function onUserAppMessage(message) { + if (disconnected) + return + if (process.env.NODE_ENV === 'development') { + console.log('%cuserApp -> devtools', 'color:#888;', message) + } + + devtools.postMessage(message) + } + userApp.onMessage.addListener(onUserAppMessage) + + function shutdown() { + disconnected = true + if (!ports[tabId]) + return + const { devtools, userApp } = ports[tabId] + devtools.onMessage.removeListener(onDevtoolsMessage) + userApp.onMessage.removeListener(onUserAppMessage) + devtools?.disconnect() + userApp?.disconnect() + delete ports[tabId] + // ports[tabId] = null! + } + + devtools.onDisconnect.addListener(shutdown) + userApp.onDisconnect.addListener(shutdown) +} + +chrome.runtime.onConnect.addListener((port) => { + const portInfo: PortInfo = { + tab: '', + name: '', + port, + } + + // devtools panel + if (isNumeric(port.name)) { + portInfo.tab = port.name + portInfo.name = 'devtools' + chrome.tabs.executeScript(+port.name, { + + file: '/dist/proxy.js', + }, (res) => { + }) + } + // userApp (user application) + else { + portInfo.tab = port.sender!.tab!.id! + portInfo.name = 'userApp' + } + + const tab = initPort(portInfo) + + if (tab.devtools && tab.userApp) + devtoolsUserAppPipe(portInfo.tab) +}) + +chrome.runtime.onMessage.addListener((req, sender) => { + if (sender.tab && req.vueDetected) { + const suffix = req.nuxtDetected ? '.nuxt' : '' + + chrome.browserAction.setIcon({ + tabId: sender.tab.id, + path: { + 16: `icons/16${suffix}.png`, + 48: `icons/48${suffix}.png`, + 128: `icons/128${suffix}.png`, + }, + }) + + chrome.browserAction.setPopup({ + tabId: sender.tab.id, + popup: req.devtoolsEnabled ? `popups/enabled${suffix}.html` : `popups/disabled${suffix}.html`, + }) + } +}) diff --git a/packages/firefox-extension/src/detector.ts b/packages/firefox-extension/src/detector.ts new file mode 100644 index 00000000..fb995061 --- /dev/null +++ b/packages/firefox-extension/src/detector.ts @@ -0,0 +1,58 @@ +function detect(win: Window) { + const detector = { + delay: 1000, + retry: 10, + } + function sendMessage(data) { + win.postMessage({ + key: '__VUE_DEVTOOLS_VUE_DETECTED_EVENT__', + data, + }, '*') + } + + function runDetect() { + // 1. check Nuxt + // @ts-expect-error types + const nuxtDetected = !!(window.__NUXT__) + + if (nuxtDetected) { + sendMessage({ + devtoolsEnabled: window.__VUE_DEVTOOLS_GLOBAL_HOOK__ && window.__VUE_DEVTOOLS_GLOBAL_HOOK__.enabled, + vueDetected: true, + nuxtDetected: true, + vitePluginDetected: !!window.__VUE_DEVTOOLS_VITE_PLUGIN_DETECTED__, + vitePluginClientUrl: window.__VUE_DEVTOOLS_VITE_PLUGIN_CLIENT_URL__, + }) + return + } + + // 2. check Vue + // @ts-expect-error types + const vueDetected = !!(window.__VUE__) + if (vueDetected) { + sendMessage({ + devtoolsEnabled: window.__VUE_DEVTOOLS_GLOBAL_HOOK__ && window.__VUE_DEVTOOLS_GLOBAL_HOOK__.enabled, + vueDetected: true, + vitePluginDetected: !!window.__VUE_DEVTOOLS_VITE_PLUGIN_DETECTED__, + vitePluginClientUrl: window.__VUE_DEVTOOLS_VITE_PLUGIN_CLIENT_URL__, + }) + return + } + + if (detector.retry > 0) { + detector.retry-- + setTimeout(() => { + runDetect() + }, detector.delay) + detector.delay *= 5 + } + } + + setTimeout(() => { + runDetect() + }, 100) +} + +if (document instanceof HTMLDocument) { + detect(window) +} diff --git a/packages/firefox-extension/src/devtools-background.ts b/packages/firefox-extension/src/devtools-background.ts new file mode 100644 index 00000000..474edb8c --- /dev/null +++ b/packages/firefox-extension/src/devtools-background.ts @@ -0,0 +1,33 @@ +let created = false +let checkCount = 0 + +chrome.devtools.network.onNavigated.addListener(createPanelOnVueDetected) +const checkVueInterval = setInterval(createPanelOnVueDetected, 1000) +createPanelOnVueDetected() + +function createPanelOnVueDetected() { + if (created || checkCount++ > 10) { + clearInterval(checkVueInterval) + return + } + chrome.devtools.inspectedWindow.eval( + '!!(window.__VUE_DEVTOOLS_GLOBAL_HOOK__ && (window.__VUE_DEVTOOLS_GLOBAL_HOOK__.Vue || window.__VUE_DEVTOOLS_GLOBAL_HOOK__.apps.length))', + (vueDetected) => { + if (!vueDetected || created) + return + + clearInterval(checkVueInterval) + created = true + chrome.devtools.panels.create( + 'Vue', + 'icons/128.png', + 'devtools-panel.html', + (panel) => { + panel.onShown.addListener((window) => { + + }) + }, + ) + }, + ) +} diff --git a/packages/firefox-extension/src/devtools-overlay.ts b/packages/firefox-extension/src/devtools-overlay.ts new file mode 100644 index 00000000..0a64e6f5 --- /dev/null +++ b/packages/firefox-extension/src/devtools-overlay.ts @@ -0,0 +1,16 @@ +const body = document.getElementsByTagName('body')[0] + +// create detector script +const detector = document.createElement('script') +detector.src = chrome.runtime.getURL('dist/detector.js') +detector.onload = () => { + detector.parentNode!.removeChild(detector) +} + +;(document.head || document.documentElement).appendChild(detector) + +window.addEventListener('message', (event) => { + if (event.data.key === '__VUE_DEVTOOLS_VUE_DETECTED_EVENT__') { + chrome.runtime.sendMessage(event.data.data) + } +}, false) diff --git a/packages/firefox-extension/src/devtools-panel.ts b/packages/firefox-extension/src/devtools-panel.ts new file mode 100644 index 00000000..6c1e5acf --- /dev/null +++ b/packages/firefox-extension/src/devtools-panel.ts @@ -0,0 +1,55 @@ +// import { Bridge } from '../../core/src/bridge' +import { createRpcClient } from '@vue/devtools-kit' +import { functions, onRpcConnected } from '@vue/devtools-core' +import { disconnectDevToolsClient, initDevTools, reloadDevToolsClient } from '../client/devtools-panel' + +const connectionInfo: { + retryTimer: NodeJS.Timeout | null + count: number + disconnected: boolean + port: chrome.runtime.Port + listeners: Array<() => void> +} = { + retryTimer: null, + count: 0, + disconnected: false, + port: null!, + listeners: [], +} + +function init() { + injectScript(chrome.runtime.getURL('dist/user-app.js'), () => { + initDevTools() + + createRpcClient(functions, { + preset: 'extension', + }) + }) + chrome.devtools.network.onNavigated.addListener(() => { + disconnectDevToolsClient() + injectScript(chrome.runtime.getURL('dist/user-app.js'), () => { + onRpcConnected(() => { + reloadDevToolsClient() + }) + }) + }) +} + +init() + +function injectScript(scriptName: string, cb: () => void) { + const src = ` + (function() { + var script = document.constructor.prototype.createElement.call(document, 'script'); + script.src = "${scriptName}"; + document.documentElement.appendChild(script); + script.parentNode.removeChild(script); + })() + ` + chrome.devtools.inspectedWindow.eval(src, (res, err) => { + if (err) + console.error(err) + + cb() + }) +} diff --git a/packages/firefox-extension/src/injection.ts b/packages/firefox-extension/src/injection.ts new file mode 100644 index 00000000..8b82c9f8 --- /dev/null +++ b/packages/firefox-extension/src/injection.ts @@ -0,0 +1,7 @@ +if (document instanceof HTMLDocument) { + const content = chrome.runtime.getURL('dist/prepare.js') + const script = document.createElement('script') + script.src = content + document.documentElement.appendChild(script) + script.parentNode?.removeChild(script) +} diff --git a/packages/firefox-extension/src/prepare.ts b/packages/firefox-extension/src/prepare.ts new file mode 100644 index 00000000..3e558957 --- /dev/null +++ b/packages/firefox-extension/src/prepare.ts @@ -0,0 +1,5 @@ +import { devtools } from '../../devtools-kit/src/index' + +devtools.init() + +window.__VUE_DEVTOOLS_BROWSER_EXTENSION_DETECTED__ = true diff --git a/packages/firefox-extension/src/proxy.ts b/packages/firefox-extension/src/proxy.ts new file mode 100644 index 00000000..2e49477c --- /dev/null +++ b/packages/firefox-extension/src/proxy.ts @@ -0,0 +1,10 @@ +// This is a content-script that is injected only when the devtools are +// activated. Because it is not injected using eval, it has full privilege +// to the chrome runtime API. It serves as a proxy between the injected +// user application and the Vue devtools panel. + +import { createRpcProxy } from '@vue/devtools-kit' + +createRpcProxy({ + preset: 'extension', +}) diff --git a/packages/firefox-extension/src/user-app.ts b/packages/firefox-extension/src/user-app.ts new file mode 100644 index 00000000..e19c4c7b --- /dev/null +++ b/packages/firefox-extension/src/user-app.ts @@ -0,0 +1,16 @@ +import { createRpcServer } from '@vue/devtools-kit' +import { functions } from '@vue/devtools-core' + +window.addEventListener('message', handshake) + +createRpcServer(functions, { + preset: 'extension', +}) + +function handshake(e: MessageEvent) { + if (e.data.source === 'proxy->server' && e.data.payload.event === 'init') { + window.removeEventListener('message', handshake) + + const listeners: ((event: unknown) => void)[] = [] + } +} diff --git a/packages/firefox-extension/tsup.config.ts b/packages/firefox-extension/tsup.config.ts new file mode 100644 index 00000000..f49ab624 --- /dev/null +++ b/packages/firefox-extension/tsup.config.ts @@ -0,0 +1,19 @@ +import { defineConfig } from 'tsup' + +export default defineConfig({ + entryPoints: [ + 'src/*.ts', + ], + esbuildOptions(options) { + if (options.format === 'iife') + options.outExtension = { '.js': '.js' } + }, + define: { + 'process.env': JSON.stringify(process.env), + '__VUE_OPTIONS_API__': 'true', + '__VUE_PROD_DEVTOOLS__': 'true', + }, + clean: true, + format: ['iife'], + minify: true, +}) diff --git a/packages/playground/basic/src/main.ts b/packages/playground/basic/src/main.ts index 3b81a99c..85983036 100644 --- a/packages/playground/basic/src/main.ts +++ b/packages/playground/basic/src/main.ts @@ -3,7 +3,6 @@ import type { RouteRecordRaw } from 'vue-router' import { createRouter, createWebHistory } from 'vue-router' import { VueQueryPlugin } from '@tanstack/vue-query' import { addCustomCommand } from '@vue/devtools-api' -import { devtools } from '@vue/devtools' import store from './stores/vuexStore' @@ -20,7 +19,7 @@ const pinia = createPinia() const app = createApp(App) -devtools.connect() +// devtools.connect() const routes: RouteRecordRaw[] = [ { diff --git a/packages/shared/src/env.ts b/packages/shared/src/env.ts index d79af817..4a8eb583 100644 --- a/packages/shared/src/env.ts +++ b/packages/shared/src/env.ts @@ -1,8 +1,8 @@ export const isBrowser = typeof navigator !== 'undefined' -export const target = (typeof globalThis !== 'undefined' - ? globalThis - : typeof window !== 'undefined' - ? window +export const target = (typeof window !== 'undefined' + ? window + : typeof globalThis !== 'undefined' + ? globalThis // eslint-disable-next-line no-restricted-globals : typeof global !== 'undefined' // eslint-disable-next-line no-restricted-globals diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 18526332..df7e4cbb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,6 +17,9 @@ importers: '@arethetypeswrong/cli': specifier: ^0.15.3 version: 0.15.3 + '@clack/prompts': + specifier: ^0.7.0 + version: 0.7.0 '@types/chrome': specifier: ^0.0.268 version: 0.0.268 @@ -80,6 +83,9 @@ importers: npm-run-all2: specifier: ^6.2.0 version: 6.2.0 + picocolors: + specifier: ^1.0.1 + version: 1.0.1 pnpm: specifier: ^9.3.0 version: 9.3.0 @@ -95,6 +101,9 @@ importers: regex-extra: specifier: ^0.2.2 version: 0.2.2 + semver: + specifier: ^7.6.2 + version: 7.6.2 simple-git-hooks: specifier: ^2.11.1 version: 2.11.1 @@ -103,7 +112,7 @@ importers: version: 0.13.8 tsup: specifier: ^8.1.0 - version: 8.1.0(@microsoft/api-extractor@7.43.0(@types/node@20.14.2))(postcss@8.4.38)(typescript@5.4.5) + version: 8.1.0(@microsoft/api-extractor@7.43.0(@types/node@20.14.2))(@swc/core@1.5.29)(postcss@8.4.38)(typescript@5.4.5) tsx: specifier: ^4.15.2 version: 4.15.2 @@ -447,6 +456,25 @@ importers: specifier: ^3.4.27 version: 3.4.27(typescript@5.4.5) + packages/firefox-extension: + dependencies: + '@vue/devtools-core': + specifier: workspace:^ + version: link:../core + '@vue/devtools-kit': + specifier: workspace:^ + version: link:../devtools-kit + '@vue/devtools-shared': + specifier: workspace:^ + version: link:../shared + devDependencies: + '@vitejs/plugin-vue': + specifier: ^5.0.5 + version: 5.0.5(vite@5.2.13(@types/node@20.14.2)(sass@1.77.4)(terser@5.26.0))(vue@3.4.27(typescript@5.4.5)) + vue: + specifier: ^3.4.27 + version: 3.4.27(typescript@5.4.5) + packages/overlay: dependencies: '@vue/devtools-core': @@ -716,13 +744,13 @@ importers: version: 7.24.7(@babel/core@7.24.7)(eslint@9.4.0) '@vue/cli-plugin-babel': specifier: ~5.0.8 - version: 5.0.8(@vue/cli-service@5.0.8(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3))(core-js@3.37.1)(esbuild@0.21.4)(vue@3.4.27(typescript@5.4.5)) + version: 5.0.8(@swc/core@1.5.29)(@vue/cli-service@5.0.8(@swc/core@1.5.29)(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3))(core-js@3.37.1)(esbuild@0.21.4)(vue@3.4.27(typescript@5.4.5)) '@vue/cli-plugin-eslint': specifier: ~5.0.8 - version: 5.0.8(@vue/cli-service@5.0.8(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3))(esbuild@0.21.4)(eslint@9.4.0) + version: 5.0.8(@swc/core@1.5.29)(@vue/cli-service@5.0.8(@swc/core@1.5.29)(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3))(esbuild@0.21.4)(eslint@9.4.0) '@vue/cli-service': specifier: ~5.0.8 - version: 5.0.8(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3) + version: 5.0.8(@swc/core@1.5.29)(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3) '@vue/devtools': specifier: workspace:* version: link:../../devtools @@ -2655,6 +2683,81 @@ packages: peerDependencies: eslint: '>=8.40.0' + '@swc/core-darwin-arm64@1.5.29': + resolution: {integrity: sha512-6F/sSxpHaq3nzg2ADv9FHLi4Fu2A8w8vP8Ich8gIl16D2htStlwnaPmCLjRswO+cFkzgVqy/l01gzNGWd4DFqA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + + '@swc/core-darwin-x64@1.5.29': + resolution: {integrity: sha512-rF/rXkvUOTdTIfoYbmszbSUGsCyvqACqy1VeP3nXONS+LxFl4bRmRcUTRrblL7IE5RTMCKUuPbqbQSE2hK7bqg==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + + '@swc/core-linux-arm-gnueabihf@1.5.29': + resolution: {integrity: sha512-2OAPL8iWBsmmwkjGXqvuUhbmmoLxS1xNXiMq87EsnCNMAKohGc7wJkdAOUL6J/YFpean/vwMWg64rJD4pycBeg==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + + '@swc/core-linux-arm64-gnu@1.5.29': + resolution: {integrity: sha512-eH/Q9+8O5qhSxMestZnhuS1xqQMr6M7SolZYxiXJqxArXYILLCF+nq2R9SxuMl0CfjHSpb6+hHPk/HXy54eIRA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-arm64-musl@1.5.29': + resolution: {integrity: sha512-TERh2OICAJz+SdDIK9+0GyTUwF6r4xDlFmpoiHKHrrD/Hh3u+6Zue0d7jQ/he/i80GDn4tJQkHlZys+RZL5UZg==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-x64-gnu@1.5.29': + resolution: {integrity: sha512-WMDPqU7Ji9dJpA+Llek2p9t7pcy7Bob8ggPUvgsIlv3R/eesF9DIzSbrgl6j3EAEPB9LFdSafsgf6kT/qnvqFg==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-linux-x64-musl@1.5.29': + resolution: {integrity: sha512-DO14glwpdKY4POSN0201OnGg1+ziaSVr6/RFzuSLggshwXeeyVORiHv3baj7NENhJhWhUy3NZlDsXLnRFkmhHQ==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-win32-arm64-msvc@1.5.29': + resolution: {integrity: sha512-V3Y1+a1zG1zpYXUMqPIHEMEOd+rHoVnIpO/KTyFwAmKVu8v+/xPEVx/AGoYE67x4vDAAvPQrKI3Aokilqa5yVg==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + + '@swc/core-win32-ia32-msvc@1.5.29': + resolution: {integrity: sha512-OrM6yfXw4wXhnVFosOJzarw0Fdz5Y0okgHfn9oFbTPJhoqxV5Rdmd6kXxWu2RiVKs6kGSJFZXHDeUq2w5rTIMg==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + + '@swc/core-win32-x64-msvc@1.5.29': + resolution: {integrity: sha512-eD/gnxqKyZQQR0hR7TMkIlJ+nCF9dzYmVVNbYZWuA1Xy94aBPUsEk3Uw3oG7q6R3ErrEUPP0FNf2ztEnv+I+dw==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + + '@swc/core@1.5.29': + resolution: {integrity: sha512-nvTtHJI43DUSOAf3h9XsqYg8YXKc0/N4il9y4j0xAkO0ekgDNo+3+jbw6MInawjKJF9uulyr+f5bAutTsOKVlw==} + engines: {node: '>=10'} + peerDependencies: + '@swc/helpers': '*' + peerDependenciesMeta: + '@swc/helpers': + optional: true + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/types@0.1.8': + resolution: {integrity: sha512-RNFA3+7OJFNYY78x0FYwi1Ow+iF1eF5WvmfY1nXPOEH4R2p/D4Cr1vzje7dNAI2aLFqpv8Wyz4oKSWqIZArpQA==} + '@szmarczak/http-timer@4.0.6': resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} engines: {node: '>=10'} @@ -10338,13 +10441,13 @@ snapshots: '@socket.io/component-emitter@3.1.0': {} - '@soda/friendly-errors-webpack-plugin@1.8.1(webpack@5.89.0(esbuild@0.21.4))': + '@soda/friendly-errors-webpack-plugin@1.8.1(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4))': dependencies: chalk: 3.0.0 error-stack-parser: 2.1.4 string-width: 4.2.3 strip-ansi: 6.0.1 - webpack: 5.89.0(esbuild@0.21.4) + webpack: 5.89.0(@swc/core@1.5.29)(esbuild@0.21.4) '@soda/get-current-script@1.0.2': {} @@ -10395,6 +10498,61 @@ snapshots: - supports-color - typescript + '@swc/core-darwin-arm64@1.5.29': + optional: true + + '@swc/core-darwin-x64@1.5.29': + optional: true + + '@swc/core-linux-arm-gnueabihf@1.5.29': + optional: true + + '@swc/core-linux-arm64-gnu@1.5.29': + optional: true + + '@swc/core-linux-arm64-musl@1.5.29': + optional: true + + '@swc/core-linux-x64-gnu@1.5.29': + optional: true + + '@swc/core-linux-x64-musl@1.5.29': + optional: true + + '@swc/core-win32-arm64-msvc@1.5.29': + optional: true + + '@swc/core-win32-ia32-msvc@1.5.29': + optional: true + + '@swc/core-win32-x64-msvc@1.5.29': + optional: true + + '@swc/core@1.5.29': + dependencies: + '@swc/counter': 0.1.3 + '@swc/types': 0.1.8 + optionalDependencies: + '@swc/core-darwin-arm64': 1.5.29 + '@swc/core-darwin-x64': 1.5.29 + '@swc/core-linux-arm-gnueabihf': 1.5.29 + '@swc/core-linux-arm64-gnu': 1.5.29 + '@swc/core-linux-arm64-musl': 1.5.29 + '@swc/core-linux-x64-gnu': 1.5.29 + '@swc/core-linux-x64-musl': 1.5.29 + '@swc/core-win32-arm64-msvc': 1.5.29 + '@swc/core-win32-ia32-msvc': 1.5.29 + '@swc/core-win32-x64-msvc': 1.5.29 + optional: true + + '@swc/counter@0.1.3': + optional: true + + '@swc/types@0.1.8': + dependencies: + '@swc/counter': 0.1.3 + optional: true + '@szmarczak/http-timer@4.0.6': dependencies: defer-to-connect: 2.0.1 @@ -11084,15 +11242,15 @@ snapshots: '@vue/cli-overlay@5.0.8': {} - '@vue/cli-plugin-babel@5.0.8(@vue/cli-service@5.0.8(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3))(core-js@3.37.1)(esbuild@0.21.4)(vue@3.4.27(typescript@5.4.5))': + '@vue/cli-plugin-babel@5.0.8(@swc/core@1.5.29)(@vue/cli-service@5.0.8(@swc/core@1.5.29)(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3))(core-js@3.37.1)(esbuild@0.21.4)(vue@3.4.27(typescript@5.4.5))': dependencies: '@babel/core': 7.24.7 '@vue/babel-preset-app': 5.0.8(@babel/core@7.24.7)(core-js@3.37.1)(vue@3.4.27(typescript@5.4.5)) - '@vue/cli-service': 5.0.8(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3) + '@vue/cli-service': 5.0.8(@swc/core@1.5.29)(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3) '@vue/cli-shared-utils': 5.0.8 - babel-loader: 8.3.0(@babel/core@7.24.7)(webpack@5.89.0(esbuild@0.21.4)) - thread-loader: 3.0.4(webpack@5.89.0(esbuild@0.21.4)) - webpack: 5.89.0(esbuild@0.21.4) + babel-loader: 8.3.0(@babel/core@7.24.7)(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)) + thread-loader: 3.0.4(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)) + webpack: 5.89.0(@swc/core@1.5.29)(esbuild@0.21.4) transitivePeerDependencies: - '@swc/core' - core-js @@ -11103,14 +11261,14 @@ snapshots: - vue - webpack-cli - '@vue/cli-plugin-eslint@5.0.8(@vue/cli-service@5.0.8(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3))(esbuild@0.21.4)(eslint@9.4.0)': + '@vue/cli-plugin-eslint@5.0.8(@swc/core@1.5.29)(@vue/cli-service@5.0.8(@swc/core@1.5.29)(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3))(esbuild@0.21.4)(eslint@9.4.0)': dependencies: - '@vue/cli-service': 5.0.8(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3) + '@vue/cli-service': 5.0.8(@swc/core@1.5.29)(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3) '@vue/cli-shared-utils': 5.0.8 eslint: 9.4.0 - eslint-webpack-plugin: 3.2.0(eslint@9.4.0)(webpack@5.89.0(esbuild@0.21.4)) + eslint-webpack-plugin: 3.2.0(eslint@9.4.0)(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)) globby: 11.1.0 - webpack: 5.89.0(esbuild@0.21.4) + webpack: 5.89.0(@swc/core@1.5.29)(esbuild@0.21.4) yorkie: 2.0.0 transitivePeerDependencies: - '@swc/core' @@ -11119,29 +11277,29 @@ snapshots: - uglify-js - webpack-cli - '@vue/cli-plugin-router@5.0.8(@vue/cli-service@5.0.8(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3))': + '@vue/cli-plugin-router@5.0.8(@vue/cli-service@5.0.8(@swc/core@1.5.29)(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3))': dependencies: - '@vue/cli-service': 5.0.8(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3) + '@vue/cli-service': 5.0.8(@swc/core@1.5.29)(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3) '@vue/cli-shared-utils': 5.0.8 transitivePeerDependencies: - encoding - '@vue/cli-plugin-vuex@5.0.8(@vue/cli-service@5.0.8(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3))': + '@vue/cli-plugin-vuex@5.0.8(@vue/cli-service@5.0.8(@swc/core@1.5.29)(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3))': dependencies: - '@vue/cli-service': 5.0.8(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3) + '@vue/cli-service': 5.0.8(@swc/core@1.5.29)(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3) - '@vue/cli-service@5.0.8(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3)': + '@vue/cli-service@5.0.8(@swc/core@1.5.29)(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3)': dependencies: '@babel/helper-compilation-targets': 7.24.7 - '@soda/friendly-errors-webpack-plugin': 1.8.1(webpack@5.89.0(esbuild@0.21.4)) + '@soda/friendly-errors-webpack-plugin': 1.8.1(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)) '@soda/get-current-script': 1.0.2 '@types/minimist': 1.2.5 '@vue/cli-overlay': 5.0.8 - '@vue/cli-plugin-router': 5.0.8(@vue/cli-service@5.0.8(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3)) - '@vue/cli-plugin-vuex': 5.0.8(@vue/cli-service@5.0.8(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3)) + '@vue/cli-plugin-router': 5.0.8(@vue/cli-service@5.0.8(@swc/core@1.5.29)(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3)) + '@vue/cli-plugin-vuex': 5.0.8(@vue/cli-service@5.0.8(@swc/core@1.5.29)(@vue/compiler-sfc@3.4.27)(esbuild@0.21.4)(lodash@4.17.21)(vue-template-compiler@2.7.15)(vue@3.4.27(typescript@5.4.5))(webpack-sources@3.2.3)) '@vue/cli-shared-utils': 5.0.8 '@vue/component-compiler-utils': 3.3.0(lodash@4.17.21) - '@vue/vue-loader-v15': vue-loader@15.11.1(@vue/compiler-sfc@3.4.27)(css-loader@6.8.1(webpack@5.89.0(esbuild@0.21.4)))(lodash@4.17.21)(vue-template-compiler@2.7.15)(webpack@5.89.0(esbuild@0.21.4)) + '@vue/vue-loader-v15': vue-loader@15.11.1(@vue/compiler-sfc@3.4.27)(css-loader@6.8.1(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)))(lodash@4.17.21)(vue-template-compiler@2.7.15)(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)) '@vue/web-component-wrapper': 1.3.0 acorn: 8.11.3 acorn-walk: 8.3.2 @@ -11152,9 +11310,9 @@ snapshots: cli-highlight: 2.1.11 clipboardy: 2.3.0 cliui: 7.0.4 - copy-webpack-plugin: 9.1.0(webpack@5.89.0(esbuild@0.21.4)) - css-loader: 6.8.1(webpack@5.89.0(esbuild@0.21.4)) - css-minimizer-webpack-plugin: 3.4.1(esbuild@0.21.4)(webpack@5.89.0(esbuild@0.21.4)) + copy-webpack-plugin: 9.1.0(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)) + css-loader: 6.8.1(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)) + css-minimizer-webpack-plugin: 3.4.1(esbuild@0.21.4)(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)) cssnano: 5.1.15(postcss@8.4.38) debug: 4.3.4 default-gateway: 6.0.3 @@ -11163,27 +11321,27 @@ snapshots: fs-extra: 9.1.0 globby: 11.1.0 hash-sum: 2.0.0 - html-webpack-plugin: 5.6.0(webpack@5.89.0(esbuild@0.21.4)) + html-webpack-plugin: 5.6.0(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)) is-file-esm: 1.0.0 launch-editor-middleware: 2.6.1 lodash.defaultsdeep: 4.6.1 lodash.mapvalues: 4.6.0 - mini-css-extract-plugin: 2.7.6(webpack@5.89.0(esbuild@0.21.4)) + mini-css-extract-plugin: 2.7.6(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)) minimist: 1.2.8 module-alias: 2.2.3 portfinder: 1.0.32 postcss: 8.4.38 - postcss-loader: 6.2.1(postcss@8.4.38)(webpack@5.89.0(esbuild@0.21.4)) - progress-webpack-plugin: 1.0.16(webpack@5.89.0(esbuild@0.21.4)) + postcss-loader: 6.2.1(postcss@8.4.38)(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)) + progress-webpack-plugin: 1.0.16(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)) ssri: 8.0.1 - terser-webpack-plugin: 5.3.10(esbuild@0.21.4)(webpack@5.89.0(esbuild@0.21.4)) - thread-loader: 3.0.4(webpack@5.89.0(esbuild@0.21.4)) - vue-loader: 17.4.2(@vue/compiler-sfc@3.4.27)(vue@3.4.27(typescript@5.4.5))(webpack@5.89.0(esbuild@0.21.4)) + terser-webpack-plugin: 5.3.10(@swc/core@1.5.29)(esbuild@0.21.4)(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)) + thread-loader: 3.0.4(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)) + vue-loader: 17.4.2(@vue/compiler-sfc@3.4.27)(vue@3.4.27(typescript@5.4.5))(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)) vue-style-loader: 4.1.3 - webpack: 5.89.0(esbuild@0.21.4) + webpack: 5.89.0(@swc/core@1.5.29)(esbuild@0.21.4) webpack-bundle-analyzer: 4.10.1 webpack-chain: 6.5.1 - webpack-dev-server: 4.15.1(debug@4.3.4)(webpack@5.89.0(esbuild@0.21.4)) + webpack-dev-server: 4.15.1(debug@4.3.4)(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)) webpack-merge: 5.10.0 webpack-virtual-modules: 0.4.6 whatwg-fetch: 3.6.20 @@ -11755,14 +11913,14 @@ snapshots: b4a@1.6.4: {} - babel-loader@8.3.0(@babel/core@7.24.7)(webpack@5.89.0(esbuild@0.21.4)): + babel-loader@8.3.0(@babel/core@7.24.7)(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)): dependencies: '@babel/core': 7.24.7 find-cache-dir: 3.3.2 loader-utils: 2.0.4 make-dir: 3.1.0 schema-utils: 2.7.1 - webpack: 5.89.0(esbuild@0.21.4) + webpack: 5.89.0(@swc/core@1.5.29)(esbuild@0.21.4) babel-plugin-dynamic-import-node@2.3.3: dependencies: @@ -12283,7 +12441,7 @@ snapshots: dependencies: is-what: 4.1.16 - copy-webpack-plugin@9.1.0(webpack@5.89.0(esbuild@0.21.4)): + copy-webpack-plugin@9.1.0(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)): dependencies: fast-glob: 3.3.2 glob-parent: 6.0.2 @@ -12291,7 +12449,7 @@ snapshots: normalize-path: 3.0.0 schema-utils: 3.3.0 serialize-javascript: 6.0.1 - webpack: 5.89.0(esbuild@0.21.4) + webpack: 5.89.0(@swc/core@1.5.29)(esbuild@0.21.4) core-js-compat@3.37.1: dependencies: @@ -12353,7 +12511,7 @@ snapshots: dependencies: postcss: 8.4.38 - css-loader@6.8.1(webpack@5.89.0(esbuild@0.21.4)): + css-loader@6.8.1(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)): dependencies: icss-utils: 5.1.0(postcss@8.4.38) postcss: 8.4.38 @@ -12363,9 +12521,9 @@ snapshots: postcss-modules-values: 4.0.0(postcss@8.4.38) postcss-value-parser: 4.2.0 semver: 7.6.2 - webpack: 5.89.0(esbuild@0.21.4) + webpack: 5.89.0(@swc/core@1.5.29)(esbuild@0.21.4) - css-minimizer-webpack-plugin@3.4.1(esbuild@0.21.4)(webpack@5.89.0(esbuild@0.21.4)): + css-minimizer-webpack-plugin@3.4.1(esbuild@0.21.4)(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)): dependencies: cssnano: 5.1.15(postcss@8.4.38) jest-worker: 27.5.1 @@ -12373,7 +12531,7 @@ snapshots: schema-utils: 4.2.0 serialize-javascript: 6.0.1 source-map: 0.6.1 - webpack: 5.89.0(esbuild@0.21.4) + webpack: 5.89.0(@swc/core@1.5.29)(esbuild@0.21.4) optionalDependencies: esbuild: 0.21.4 @@ -13113,7 +13271,7 @@ snapshots: eslint-visitor-keys@4.0.0: {} - eslint-webpack-plugin@3.2.0(eslint@9.4.0)(webpack@5.89.0(esbuild@0.21.4)): + eslint-webpack-plugin@3.2.0(eslint@9.4.0)(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)): dependencies: '@types/eslint': 8.56.10 eslint: 9.4.0 @@ -13121,7 +13279,7 @@ snapshots: micromatch: 4.0.7 normalize-path: 3.0.0 schema-utils: 4.2.0 - webpack: 5.89.0(esbuild@0.21.4) + webpack: 5.89.0(@swc/core@1.5.29)(esbuild@0.21.4) eslint@8.57.0: dependencies: @@ -13830,7 +13988,7 @@ snapshots: html-tags@3.3.1: {} - html-webpack-plugin@5.6.0(webpack@5.89.0(esbuild@0.21.4)): + html-webpack-plugin@5.6.0(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -13838,7 +13996,7 @@ snapshots: pretty-error: 4.0.0 tapable: 2.2.1 optionalDependencies: - webpack: 5.89.0(esbuild@0.21.4) + webpack: 5.89.0(@swc/core@1.5.29)(esbuild@0.21.4) htmlparser2@6.1.0: dependencies: @@ -14551,10 +14709,10 @@ snapshots: min-indent@1.0.1: {} - mini-css-extract-plugin@2.7.6(webpack@5.89.0(esbuild@0.21.4)): + mini-css-extract-plugin@2.7.6(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)): dependencies: schema-utils: 4.2.0 - webpack: 5.89.0(esbuild@0.21.4) + webpack: 5.89.0(@swc/core@1.5.29)(esbuild@0.21.4) minimalistic-assert@1.0.1: {} @@ -15054,13 +15212,13 @@ snapshots: optionalDependencies: postcss: 8.4.38 - postcss-loader@6.2.1(postcss@8.4.38)(webpack@5.89.0(esbuild@0.21.4)): + postcss-loader@6.2.1(postcss@8.4.38)(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)): dependencies: cosmiconfig: 7.1.0 klona: 2.0.6 postcss: 8.4.38 semver: 7.6.2 - webpack: 5.89.0(esbuild@0.21.4) + webpack: 5.89.0(@swc/core@1.5.29)(esbuild@0.21.4) postcss-merge-longhand@5.1.7(postcss@8.4.38): dependencies: @@ -15243,12 +15401,12 @@ snapshots: process@0.11.10: {} - progress-webpack-plugin@1.0.16(webpack@5.89.0(esbuild@0.21.4)): + progress-webpack-plugin@1.0.16(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)): dependencies: chalk: 2.4.2 figures: 2.0.0 log-update: 2.3.0 - webpack: 5.89.0(esbuild@0.21.4) + webpack: 5.89.0(@swc/core@1.5.29)(esbuild@0.21.4) progress@2.0.3: {} @@ -16086,15 +16244,16 @@ snapshots: unconfig: 0.3.13 yargs: 17.7.2 - terser-webpack-plugin@5.3.10(esbuild@0.21.4)(webpack@5.89.0(esbuild@0.21.4)): + terser-webpack-plugin@5.3.10(@swc/core@1.5.29)(esbuild@0.21.4)(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.1 terser: 5.26.0 - webpack: 5.89.0(esbuild@0.21.4) + webpack: 5.89.0(@swc/core@1.5.29)(esbuild@0.21.4) optionalDependencies: + '@swc/core': 1.5.29 esbuild: 0.21.4 terser@5.26.0: @@ -16114,14 +16273,14 @@ snapshots: dependencies: any-promise: 1.3.0 - thread-loader@3.0.4(webpack@5.89.0(esbuild@0.21.4)): + thread-loader@3.0.4(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)): dependencies: json-parse-better-errors: 1.0.2 loader-runner: 4.3.0 loader-utils: 2.0.4 neo-async: 2.6.2 schema-utils: 3.3.0 - webpack: 5.89.0(esbuild@0.21.4) + webpack: 5.89.0(@swc/core@1.5.29)(esbuild@0.21.4) three@0.165.0: {} @@ -16180,7 +16339,7 @@ snapshots: tslib@2.6.2: {} - tsup@8.1.0(@microsoft/api-extractor@7.43.0(@types/node@20.14.2))(postcss@8.4.38)(typescript@5.4.5): + tsup@8.1.0(@microsoft/api-extractor@7.43.0(@types/node@20.14.2))(@swc/core@1.5.29)(postcss@8.4.38)(typescript@5.4.5): dependencies: bundle-require: 4.0.2(esbuild@0.21.4) cac: 6.7.14 @@ -16198,6 +16357,7 @@ snapshots: tree-kill: 1.2.2 optionalDependencies: '@microsoft/api-extractor': 7.43.0(@types/node@20.14.2) + '@swc/core': 1.5.29 postcss: 8.4.38 typescript: 5.4.5 transitivePeerDependencies: @@ -16764,15 +16924,15 @@ snapshots: vue-hot-reload-api@2.3.4: {} - vue-loader@15.11.1(@vue/compiler-sfc@3.4.27)(css-loader@6.8.1(webpack@5.89.0(esbuild@0.21.4)))(lodash@4.17.21)(vue-template-compiler@2.7.15)(webpack@5.89.0(esbuild@0.21.4)): + vue-loader@15.11.1(@vue/compiler-sfc@3.4.27)(css-loader@6.8.1(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)))(lodash@4.17.21)(vue-template-compiler@2.7.15)(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)): dependencies: '@vue/component-compiler-utils': 3.3.0(lodash@4.17.21) - css-loader: 6.8.1(webpack@5.89.0(esbuild@0.21.4)) + css-loader: 6.8.1(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)) hash-sum: 1.0.2 loader-utils: 1.4.2 vue-hot-reload-api: 2.3.4 vue-style-loader: 4.1.3 - webpack: 5.89.0(esbuild@0.21.4) + webpack: 5.89.0(@swc/core@1.5.29)(esbuild@0.21.4) optionalDependencies: '@vue/compiler-sfc': 3.4.27 vue-template-compiler: 2.7.15 @@ -16831,12 +16991,12 @@ snapshots: - walrus - whiskers - vue-loader@17.4.2(@vue/compiler-sfc@3.4.27)(vue@3.4.27(typescript@5.4.5))(webpack@5.89.0(esbuild@0.21.4)): + vue-loader@17.4.2(@vue/compiler-sfc@3.4.27)(vue@3.4.27(typescript@5.4.5))(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)): dependencies: chalk: 4.1.2 hash-sum: 2.0.0 watchpack: 2.4.0 - webpack: 5.89.0(esbuild@0.21.4) + webpack: 5.89.0(@swc/core@1.5.29)(esbuild@0.21.4) optionalDependencies: '@vue/compiler-sfc': 3.4.27 vue: 3.4.27(typescript@5.4.5) @@ -16953,16 +17113,16 @@ snapshots: deepmerge: 1.5.2 javascript-stringify: 2.1.0 - webpack-dev-middleware@5.3.3(webpack@5.89.0(esbuild@0.21.4)): + webpack-dev-middleware@5.3.3(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)): dependencies: colorette: 2.0.20 memfs: 3.5.3 mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 4.2.0 - webpack: 5.89.0(esbuild@0.21.4) + webpack: 5.89.0(@swc/core@1.5.29)(esbuild@0.21.4) - webpack-dev-server@4.15.1(debug@4.3.4)(webpack@5.89.0(esbuild@0.21.4)): + webpack-dev-server@4.15.1(debug@4.3.4)(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -16992,10 +17152,10 @@ snapshots: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 5.3.3(webpack@5.89.0(esbuild@0.21.4)) + webpack-dev-middleware: 5.3.3(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)) ws: 8.17.0 optionalDependencies: - webpack: 5.89.0(esbuild@0.21.4) + webpack: 5.89.0(@swc/core@1.5.29)(esbuild@0.21.4) transitivePeerDependencies: - bufferutil - debug @@ -17014,7 +17174,7 @@ snapshots: webpack-virtual-modules@0.6.1: {} - webpack@5.89.0(esbuild@0.21.4): + webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.5 @@ -17037,7 +17197,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(esbuild@0.21.4)(webpack@5.89.0(esbuild@0.21.4)) + terser-webpack-plugin: 5.3.10(@swc/core@1.5.29)(esbuild@0.21.4)(webpack@5.89.0(@swc/core@1.5.29)(esbuild@0.21.4)) watchpack: 2.4.0 webpack-sources: 3.2.3 transitivePeerDependencies: diff --git a/scripts/extension-zip.ts b/scripts/extension-zip.ts index a885af5e..43b706d1 100644 --- a/scripts/extension-zip.ts +++ b/scripts/extension-zip.ts @@ -6,7 +6,6 @@ import readdirGlob from 'readdir-glob' import ProgressBar from 'progress' const __dirname = path.dirname(fileURLToPath(import.meta.url)) -const targetPkgDir = path.join(__dirname, '../packages/chrome-extension') const INCLUDE_FILES = [ 'client/**', 'dist/**', @@ -14,6 +13,8 @@ const INCLUDE_FILES = [ 'overlay/**', 'pages/**', 'popups/**', + 'devtools-background.html', + 'devtools-panel.html', 'manifest.json', 'package.json', ] @@ -31,7 +32,9 @@ function bytesToSize(bytes) { return `${size} ${sizes[i]}` } -async function zip(filename: string) { +async function zip(filename: string, target: string) { + const targetPkgDir = path.join(__dirname, `../packages/${target}-extension`) + const archive = archiver('zip', { zlib: { level: 9 } }) const output = fs.createWriteStream(path.join(__dirname, '../dist', `${filename}`)) @@ -130,4 +133,5 @@ async function zip(filename: string) { fs.rmSync(path.join(__dirname, '../dist'), { recursive: true, force: true }) fs.mkdirSync(path.join(__dirname, '../dist')) -await zip('devtools-chrome.zip') +await zip('devtools-chrome.zip', 'chrome') +await zip('devtools-firefox.zip', 'firefox') diff --git a/scripts/release-extension.ts b/scripts/release-extension.ts new file mode 100644 index 00000000..7e22bafc --- /dev/null +++ b/scripts/release-extension.ts @@ -0,0 +1,93 @@ +import * as fs from 'node:fs' +import * as path from 'node:path' +import * as p from '@clack/prompts' +import semver from 'semver' +import color from 'picocolors' +import pkg from '../packages/chrome-extension/package.json' +import firefoxPkg from '../packages/firefox-extension/package.json' +import manifest from '../packages/chrome-extension/manifest.json' +import firefoxManifest from '../packages/firefox-extension/manifest.json' + +const __dirname = path.dirname(new URL(import.meta.url).pathname) +const curVersion = pkg.version + +function applyIcons(manifest: Record, suffix = '') { + [16, 48, 128].forEach((size) => { + manifest.icons[size] = `icons/${size}${suffix}.png` + }) +} + +async function getNewVersion() { + const project = await p.group({ + version: () => + p.text({ + message: `Please provide a version (current: ${curVersion}):`, + validate: (value) => { + if (!value) { + return 'Version is required.' + } + if (!semver.valid(value)) { + return `Invalid version: ${value}` + } + if (semver.lt(value, curVersion)) { + return `New version (${value}) cannot be lower than current version (${curVersion}).` + } + }, + }), + confirm: ({ results }) => { + return p.confirm({ + message: `Are you sure to release version ${results.version}?`, + }) + }, + + }, { + onCancel: () => { + p.cancel('Release cancelled.') + process.exit(0) + }, + }) + return project.confirm ? project.version : '' +} + +async function release() { + p.intro(`${color.bgCyan(color.black(' Start to release chrome and firefox extension...'))}`) + getNewVersion().then(async (newVersion) => { + if (newVersion) { + console.log(`\n${color.bgGreen(color.black(` Bump version ${newVersion}...`))}`) + + const isBeta = newVersion.includes('beta') + pkg.version = newVersion + firefoxPkg.version = newVersion + if (isBeta) { + const [, baseVersion, betaVersion] = /(.*)-beta\.(\w+)/.exec(newVersion)! + manifest.version = `${baseVersion}.${betaVersion}` + manifest.version_name = `${baseVersion} beta ${betaVersion}` + applyIcons(manifest, '-beta') + + firefoxManifest.version = `${baseVersion}.${betaVersion}` + firefoxManifest.version_name = `${baseVersion} beta ${betaVersion}` + applyIcons(firefoxManifest, '-beta') + } + else { + manifest.version = newVersion + manifest.version_name = newVersion + applyIcons(manifest) + + firefoxManifest.version = newVersion + firefoxManifest.version_name = newVersion + applyIcons(firefoxManifest) + } + + fs.writeFileSync(path.resolve(__dirname, '../packages/chrome-extension/package.json'), JSON.stringify(pkg, null, 2)) + fs.writeFileSync(path.resolve(__dirname, '../packages/firefox-extension/package.json'), JSON.stringify(firefoxPkg, null, 2)) + fs.writeFileSync(path.resolve(__dirname, '../packages/chrome-extension/manifest.json'), JSON.stringify(manifest, null, 2)) + fs.writeFileSync(path.resolve(__dirname, '../packages/firefox-extension/manifest.json'), JSON.stringify(firefoxManifest, null, 2)) + } + else { + p.cancel(color.red('Release cancelled.')) + process.exit(0) + } + }) +} + +release() diff --git a/turbo.json b/turbo.json index 3e81143c..a33e7ace 100644 --- a/turbo.json +++ b/turbo.json @@ -1,6 +1,5 @@ { "$schema": "https://turbo.build/schema.json", - "ui": "stream", "tasks": { "@vue/devtools#stub": { "cache": false, @@ -25,6 +24,7 @@ "dist/**", "../electron/client/**", "../chrome-extension/client/**", + "../firefox-extension/client/**", "../vite/client/**" ] }, @@ -45,6 +45,15 @@ "^stub" ] }, + "@vue/devtools-firefox-extension#build": { + "dependsOn": [ + "@vue/devtools-client#build", + "^build" + ], + "outputs": [ + "dist/**" + ] + }, "@vue/devtools-ui#build": { "dependsOn": [ "^build" @@ -89,5 +98,6 @@ "dist/**/*.?{c|m}js" ] } - } + }, + "ui": "stream" }