@nuxt/devtools 3.4.1 → 4.0.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (229) hide show
  1. package/README.md +89 -7
  2. package/dist/chunks/analyze-build.mjs +33 -2
  3. package/dist/chunks/code-server.mjs +75 -0
  4. package/dist/chunks/module-main.mjs +1102 -737
  5. package/dist/chunks/timeline.mjs +2 -3
  6. package/dist/chunks/vite-inspect.mjs +93 -53
  7. package/dist/client/200.html +1 -1
  8. package/dist/client/404.html +1 -1
  9. package/dist/client/_nuxt/__blank-dil3nwfh.js +1 -0
  10. package/dist/client/_nuxt/analyze-build-2e03hfez.js +1 -0
  11. package/dist/client/_nuxt/assets-fyld29gf.js +6 -0
  12. package/dist/client/_nuxt/auth-required-panel-mm5lidl3.js +1 -0
  13. package/dist/client/_nuxt/builds/latest.json +1 -1
  14. package/dist/client/_nuxt/builds/meta/dbb6f1eb-fdec-4078-b409-19d1ed6035a2.json +1 -0
  15. package/dist/client/_nuxt/{client-jl5q3rle.js → client-botfq0nw.js} +1 -1
  16. package/dist/client/_nuxt/code-diff-oxve94ak.js +8 -0
  17. package/dist/client/_nuxt/code-snippets-mcrkbsd4.js +1 -0
  18. package/dist/client/_nuxt/components-k5rsm3c3.js +1 -0
  19. package/dist/client/_nuxt/composable-item-o8crh7o9.js +1 -0
  20. package/dist/client/_nuxt/composables-ml69kqh9.js +1 -0
  21. package/dist/client/_nuxt/custom-_name_-j6w4b10b.js +1 -0
  22. package/dist/client/_nuxt/data-schema-button-j2dsypzz.js +1 -0
  23. package/dist/client/_nuxt/data-schema-drawer-9s1351p5.js +2 -0
  24. package/dist/client/_nuxt/debug-muupfuzb.js +1 -0
  25. package/dist/client/_nuxt/default-k6jiq1wt.js +1 -0
  26. package/dist/client/_nuxt/dialog-c7wnj3nl.js +1 -0
  27. package/dist/client/_nuxt/{dist-ekw95yvx.js → dist-2c3gpsw0.js} +1 -1
  28. package/dist/client/_nuxt/{dist-f9baaez8.js → dist-d6zuldkp.js} +1 -1
  29. package/dist/client/_nuxt/duration-display-kup58tqe.js +1 -0
  30. package/dist/client/_nuxt/editor-bzxz1rcq.js +1 -0
  31. package/dist/client/_nuxt/entry.css-meav5jmw.css +1 -0
  32. package/dist/client/_nuxt/error-404-25vom0cq.js +1 -0
  33. package/dist/client/_nuxt/error-404.css-mpcol2vk.css +1 -0
  34. package/dist/client/_nuxt/{error-500-bu53sh58.js → error-500-htafeoa3.js} +1 -1
  35. package/dist/client/_nuxt/error-500.css-273x0c3h.css +1 -0
  36. package/dist/client/_nuxt/{error-dtx3jz5a.js → error-lj28vdr1.js} +2 -2
  37. package/dist/client/_nuxt/filepath-item-jdy5gc4m.js +1 -0
  38. package/dist/client/_nuxt/full-gpj1mlf5.js +1 -0
  39. package/dist/client/_nuxt/help-fab-ll6mbhgs.js +1 -0
  40. package/dist/client/_nuxt/hooks-hgffr865.js +1 -0
  41. package/dist/client/_nuxt/imports-i2fnwttt.js +1 -0
  42. package/dist/client/_nuxt/launch-page-ksxhzp2z.js +1 -0
  43. package/dist/client/_nuxt/modules-dae72omf.js +1 -0
  44. package/dist/client/_nuxt/nbadge-oyy0wjng.js +1 -0
  45. package/dist/client/_nuxt/nbutton-mtj8qzr9.js +1 -0
  46. package/dist/client/_nuxt/ncard-mtvdl2wf.js +1 -0
  47. package/dist/client/_nuxt/ncheckbox-mksfz5p0.js +1 -0
  48. package/dist/client/_nuxt/ncode-block-pfi5niis.js +2 -0
  49. package/dist/client/_nuxt/{ndialog-d7onas5p.js → ndialog-dj1ywkc1.js} +2 -2
  50. package/dist/client/_nuxt/ndrawer-h46qfenr.js +1 -0
  51. package/dist/client/_nuxt/ndropdown-ow0z3stn.js +1 -0
  52. package/dist/client/_nuxt/nicon-obdu3k9r.js +3 -0
  53. package/dist/client/_nuxt/nicon-title-e2gzkzl3.js +1 -0
  54. package/dist/client/_nuxt/nju74r39.js +2 -0
  55. package/dist/client/_nuxt/nlink-j55iyj5x.js +1 -0
  56. package/dist/client/_nuxt/nloading-k4sy0f8c.js +1 -0
  57. package/dist/client/_nuxt/nmarkdown-mnxob7ua.js +1 -0
  58. package/dist/client/_nuxt/nnavbar-dwxbkqvw.js +1 -0
  59. package/dist/client/_nuxt/none-md25735q.js +1 -0
  60. package/dist/client/_nuxt/npanel-grids-ga8arlvs.js +1 -0
  61. package/dist/client/_nuxt/npm-febdntx4.js +1 -0
  62. package/dist/client/_nuxt/nsection-block-cb29dqkc.js +1 -0
  63. package/dist/client/_nuxt/nselect-glgbbae4.js +1 -0
  64. package/dist/client/_nuxt/nselect-tabs-jzyd56a1.js +1 -0
  65. package/dist/client/_nuxt/nsplit-pane-b5ki4jwa.js +1 -0
  66. package/dist/client/_nuxt/{nsplit-pane.css-o64elxn9.css → nsplit-pane.css-k1gopk47.css} +1 -1
  67. package/dist/client/_nuxt/ntext-input-lzyyx3ym.js +1 -0
  68. package/dist/client/_nuxt/ntip-oohvtkqd.js +1 -0
  69. package/dist/client/_nuxt/nuxt-f4tmbbs7.js +1 -0
  70. package/dist/client/_nuxt/nuxt-link-dgri2bli.js +1 -0
  71. package/dist/client/_nuxt/{nuxt-logo-fsli1c7y.js → nuxt-logo-gzcu6lh0.js} +1 -1
  72. package/dist/client/_nuxt/open-graph-mc8dh9qn.js +3 -0
  73. package/dist/client/_nuxt/overview-lpfgamus.js +1 -0
  74. package/dist/client/_nuxt/pages-bv99uu3p.js +1 -0
  75. package/dist/client/_nuxt/payload-k2hrsm04.js +1 -0
  76. package/dist/client/_nuxt/plugins-ljid8ktq.js +1 -0
  77. package/dist/client/_nuxt/ready-h6bi8le4.js +1 -0
  78. package/dist/client/_nuxt/rolldown-runtime-ln9q81id.js +1 -0
  79. package/dist/client/_nuxt/runtime-configs-lvgzbcdu.js +1 -0
  80. package/dist/client/_nuxt/server-route-inputs-iwv9ewrw.js +1 -0
  81. package/dist/client/_nuxt/server-routes-mkqbltfh.js +7 -0
  82. package/dist/client/_nuxt/server-tasks-kbf4txeq.js +1 -0
  83. package/dist/client/_nuxt/settings-ngc5p8qn.js +1 -0
  84. package/dist/client/_nuxt/stacktrace-list-chmjyp53.js +1 -0
  85. package/dist/client/_nuxt/state-commands-f4h87cfl.js +1 -0
  86. package/dist/client/_nuxt/state-components-jymg7dj7.js +1 -0
  87. package/dist/client/_nuxt/state-editor-bg13n53w.js +1 -0
  88. package/dist/client/_nuxt/state-modules-bewlxq5o.js +1 -0
  89. package/dist/client/_nuxt/state-routes-f5cna95h.js +1 -0
  90. package/dist/client/_nuxt/state-schema-espdew31.js +1 -0
  91. package/dist/client/_nuxt/state-tabs-m7neqayd.js +1 -0
  92. package/dist/client/_nuxt/storage-cep8dxy9.js +1 -0
  93. package/dist/client/_nuxt/tab-icon-nktg799o.js +1 -0
  94. package/dist/client/_nuxt/telemetry-9f19c0i9.js +1 -0
  95. package/dist/client/_nuxt/timeline-o9hhhb94.js +31 -0
  96. package/dist/client/_nuxt/unhead.dgx-hwv-uc-gaht5h60.js +1 -0
  97. package/dist/client/_nuxt/{unocss-runtime-ys3yvxrm.js → unocss-runtime-bjggyd5e.js} +1 -1
  98. package/dist/client/_nuxt/utils-bisj7255.js +1 -0
  99. package/dist/client/_nuxt/vendor/json-editor-vue-lmhxk84q.js +3862 -0
  100. package/dist/client/_nuxt/vendor/markdown-exit-n4f1gsja.js +12 -0
  101. package/dist/client/_nuxt/vendor/quicktype-core-b6sxxdgw.js +929 -0
  102. package/dist/client/_nuxt/vendor/shiki-abzmnals.js +152 -0
  103. package/dist/client/_nuxt/vendor/unocss-hqrnsbiy.js +3 -0
  104. package/dist/client/_nuxt/vendor/{unocss.css-flyrgbwp.css → unocss.css-bhad58wt.css} +1 -1
  105. package/dist/client/_nuxt/vendor/vis-i54ppuvk.js +26 -0
  106. package/dist/client/_nuxt/virtual-files-kcs310xn.js +1 -0
  107. package/dist/client/index.html +1 -1
  108. package/dist/dirs.d.mts +1 -2
  109. package/dist/dirs.mjs +1 -21
  110. package/dist/module.d.mts +1 -1
  111. package/dist/module.json +1 -1
  112. package/dist/module.mjs +1 -5
  113. package/dist/runtime/plugins/devtools.client.js +1 -1
  114. package/dist/runtime/plugins/view/client.js +23 -74
  115. package/dist/runtime/plugins/view/state.d.ts +0 -1
  116. package/dist/runtime/plugins/view/state.js +0 -2
  117. package/dist/shared/{devtools.DFpGUHRZ.mjs → devtools.CCWq4fFE.mjs} +50 -59
  118. package/dist/shared/{devtools.C1a10l_c.d.mts → devtools.LsRDzDTD.d.mts} +0 -12
  119. package/dist/types.d.mts +2 -6
  120. package/dist/webcomponents/index.d.mts +1 -3
  121. package/dist/webcomponents/index.mjs +11 -1187
  122. package/package.json +37 -43
  123. package/.discoveryrc.cjs +0 -13
  124. package/cli.mjs +0 -2
  125. package/dist/chunks/vscode.mjs +0 -197
  126. package/dist/chunks/vue-devtools.mjs +0 -19
  127. package/dist/client/_nuxt/__blank-m8zc7gto.js +0 -1
  128. package/dist/client/_nuxt/analyze-build-jwi76dz3.js +0 -1
  129. package/dist/client/_nuxt/assets-cpph6v46.js +0 -6
  130. package/dist/client/_nuxt/auth-required-panel-pb5dyado.js +0 -1
  131. package/dist/client/_nuxt/builds/meta/58990d98-ceb3-4b7a-a3b9-ed05fcb0ebda.json +0 -1
  132. package/dist/client/_nuxt/c4noe6b7.js +0 -2
  133. package/dist/client/_nuxt/client-kw9rd8gy.js +0 -2
  134. package/dist/client/_nuxt/code-diff-icy7s1zb.js +0 -8
  135. package/dist/client/_nuxt/code-snippets-iyqjogm4.js +0 -1
  136. package/dist/client/_nuxt/components-wm13ypb1.js +0 -1
  137. package/dist/client/_nuxt/composable-item-1gg3w2nv.js +0 -1
  138. package/dist/client/_nuxt/composables-m3a2xv3m.js +0 -1
  139. package/dist/client/_nuxt/custom-_name_-yd1nhb2d.js +0 -1
  140. package/dist/client/_nuxt/data-schema-button-gmxlrj4u.js +0 -1
  141. package/dist/client/_nuxt/data-schema-drawer-htftrpm4.js +0 -2
  142. package/dist/client/_nuxt/debug-esphaczf.js +0 -1
  143. package/dist/client/_nuxt/default-l4jud1s1.js +0 -1
  144. package/dist/client/_nuxt/dist-mpe1u0aj.js +0 -1
  145. package/dist/client/_nuxt/duration-display-i95mp3xf.js +0 -1
  146. package/dist/client/_nuxt/editor-gio3gzf5.js +0 -1
  147. package/dist/client/_nuxt/entry.css-du3mqati.css +0 -1
  148. package/dist/client/_nuxt/error-404-dvx9vrvw.js +0 -1
  149. package/dist/client/_nuxt/error-404.css-ndkb77p4.css +0 -1
  150. package/dist/client/_nuxt/error-500.css-iay0iq8l.css +0 -1
  151. package/dist/client/_nuxt/filepath-item-n14cgzrq.js +0 -1
  152. package/dist/client/_nuxt/full-e41d06vk.js +0 -1
  153. package/dist/client/_nuxt/help-fab-bxbzpji6.js +0 -1
  154. package/dist/client/_nuxt/hooks-b2zozecc.js +0 -1
  155. package/dist/client/_nuxt/imports-chkhxfjf.js +0 -1
  156. package/dist/client/_nuxt/launch-page-4gmg3dre.js +0 -1
  157. package/dist/client/_nuxt/modules-d4yrgxt0.js +0 -1
  158. package/dist/client/_nuxt/nbadge-gxsw3trl.js +0 -1
  159. package/dist/client/_nuxt/nbutton-n4jak7c4.js +0 -1
  160. package/dist/client/_nuxt/ncard-nwvxjytu.js +0 -1
  161. package/dist/client/_nuxt/ncheckbox-g0h4v30t.js +0 -1
  162. package/dist/client/_nuxt/ncode-block-pepewqmk.js +0 -2
  163. package/dist/client/_nuxt/ndark-toggle-hg693j9b.js +0 -1
  164. package/dist/client/_nuxt/ndrawer-rf7qwkr7.js +0 -1
  165. package/dist/client/_nuxt/ndropdown-hei8kmpv.js +0 -1
  166. package/dist/client/_nuxt/nicon-oi9zv8qe.js +0 -1
  167. package/dist/client/_nuxt/nicon-title-ckh1far6.js +0 -1
  168. package/dist/client/_nuxt/nlink-euky3zj2.js +0 -1
  169. package/dist/client/_nuxt/nloading-cxkye5sp.js +0 -1
  170. package/dist/client/_nuxt/nmarkdown-k6ubrkxy.js +0 -1
  171. package/dist/client/_nuxt/nnavbar-dxs3xl8m.js +0 -1
  172. package/dist/client/_nuxt/none-bqbddrhm.js +0 -1
  173. package/dist/client/_nuxt/npanel-grids-l34v8x7x.js +0 -1
  174. package/dist/client/_nuxt/npm-bs3acmpx.js +0 -1
  175. package/dist/client/_nuxt/nsection-block-deo3d5ca.js +0 -1
  176. package/dist/client/_nuxt/nselect-bihfcl5d.js +0 -1
  177. package/dist/client/_nuxt/nselect-tabs-e2nrw9h1.js +0 -1
  178. package/dist/client/_nuxt/nsplit-pane-c8b9c6ro.js +0 -1
  179. package/dist/client/_nuxt/nswitch-omy4wnlb.js +0 -1
  180. package/dist/client/_nuxt/ntext-input-m2w61kr5.js +0 -1
  181. package/dist/client/_nuxt/ntip-lla1rr8h.js +0 -1
  182. package/dist/client/_nuxt/nuxt-hhee6z5x.js +0 -1
  183. package/dist/client/_nuxt/nuxt-link-k77anppn.js +0 -1
  184. package/dist/client/_nuxt/open-graph-ksgni7te.js +0 -3
  185. package/dist/client/_nuxt/overview-ly9kgbva.js +0 -1
  186. package/dist/client/_nuxt/pages-inv9i4ar.js +0 -1
  187. package/dist/client/_nuxt/pages-mgwvumc9.js +0 -1
  188. package/dist/client/_nuxt/payload-c3lf06v2.js +0 -1
  189. package/dist/client/_nuxt/pinia-pdgcbxdt.js +0 -1
  190. package/dist/client/_nuxt/plugins-kv2qt5pc.js +0 -1
  191. package/dist/client/_nuxt/ready-j6igpruf.js +0 -1
  192. package/dist/client/_nuxt/render-tree-ok5eju7s.js +0 -1
  193. package/dist/client/_nuxt/rolldown-runtime-f96lzs6p.js +0 -1
  194. package/dist/client/_nuxt/runtime-configs-nrru3mzu.js +0 -1
  195. package/dist/client/_nuxt/server-discovery-b5y0tq1d.js +0 -1
  196. package/dist/client/_nuxt/server-route-inputs-8c4zt2y4.js +0 -1
  197. package/dist/client/_nuxt/server-routes-jrdh3byh.js +0 -7
  198. package/dist/client/_nuxt/server-tasks-i1wtl0e8.js +0 -1
  199. package/dist/client/_nuxt/settings-id2aeyhn.js +0 -1
  200. package/dist/client/_nuxt/stacktrace-list-mx9jtxx1.js +0 -1
  201. package/dist/client/_nuxt/state-components-dngh0clc.js +0 -1
  202. package/dist/client/_nuxt/state-editor-kg5k3jvy.js +0 -1
  203. package/dist/client/_nuxt/state-modules-gz46qq7c.js +0 -1
  204. package/dist/client/_nuxt/state-routes-ckw7s1pq.js +0 -1
  205. package/dist/client/_nuxt/state-schema-dl4a0tzs.js +0 -1
  206. package/dist/client/_nuxt/state-subprocess-omk907f9.js +0 -1
  207. package/dist/client/_nuxt/state-tabs-fe58vmvu.js +0 -1
  208. package/dist/client/_nuxt/storage-gflmc532.js +0 -1
  209. package/dist/client/_nuxt/storage-options-h4ted7ut.js +0 -1
  210. package/dist/client/_nuxt/storage-zf5nkzhm.js +0 -1
  211. package/dist/client/_nuxt/tab-icon-errppxip.js +0 -1
  212. package/dist/client/_nuxt/telemetry-pbqlai15.js +0 -1
  213. package/dist/client/_nuxt/terminals-lx3nbgm4.js +0 -1
  214. package/dist/client/_nuxt/terminals.css-mejv43xm.css +0 -1
  215. package/dist/client/_nuxt/timeline-ozwer8h0.js +0 -31
  216. package/dist/client/_nuxt/utils-gsui1utc.js +0 -1
  217. package/dist/client/_nuxt/vendor/json-editor-vue-ajxjng9j.js +0 -3870
  218. package/dist/client/_nuxt/vendor/markdown-it-hplpr18t.js +0 -14
  219. package/dist/client/_nuxt/vendor/quicktype-core-m8x9xlg1.js +0 -929
  220. package/dist/client/_nuxt/vendor/shiki-k3jqtxcz.js +0 -293
  221. package/dist/client/_nuxt/vendor/unocss-j0l832tn.js +0 -3
  222. package/dist/client/_nuxt/vendor/vis-kujfrgx6.js +0 -26
  223. package/dist/client/_nuxt/vendor/xterm-ilcgri3k.js +0 -18
  224. package/dist/client/_nuxt/vendor/xterm.css-j9zpjwmg.css +0 -1
  225. package/dist/client/_nuxt/virtual-files-dkyeb46c.js +0 -1
  226. package/dist/client/_nuxt/vue-devtools-imrq5lm7.js +0 -4
  227. package/dist/client/discovery/index.html +0 -611
  228. package/dist/runtime/vue-devtools-client.d.ts +0 -2
  229. package/dist/runtime/vue-devtools-client.js +0 -8
@@ -1,24 +1,24 @@
1
- import fs, { existsSync, promises, statSync, realpathSync, readFileSync, accessSync, constants } from 'node:fs';
2
- import fsp from 'node:fs/promises';
1
+ import fs$1, { promises, statSync, realpathSync, readFileSync, existsSync, accessSync, constants } from 'node:fs';
2
+ import fs from 'node:fs/promises';
3
3
  import os, { homedir } from 'node:os';
4
- import { logger, useNuxt, addVitePlugin, addPlugin, addTemplate, extendViteConfig, addImports } from '@nuxt/kit';
4
+ import { onDevtoolsReady, NUXT_DEVTOOLS_GROUP_ID, deprecate, registerHostDiagnostics } from '@nuxt/devtools-kit';
5
+ import { logger, useNuxt, extendViteConfig, addPlugin, addVitePlugin, addTemplate, addImports } from '@nuxt/kit';
5
6
  import { colors } from 'consola/utils';
6
- import { join, dirname as dirname$1, resolve, isAbsolute } from 'pathe';
7
+ import { join, dirname, resolve, isAbsolute } from 'pathe';
7
8
  import sirv from 'sirv';
8
9
  import { searchForWorkspaceRoot } from 'vite';
9
- import { d as defaultAllowedExtensions, a as defaultTabOptions, W as WS_EVENT_NAME } from '../shared/devtools.DFpGUHRZ.mjs';
10
- import path, { dirname, join as join$1, relative, parse } from 'node:path';
11
- import { hash } from 'ohash';
12
- import { runtimeDir, clientDir, packageDir, isGlobalInstall } from '../dirs.mjs';
13
- import { createBirpcGroup } from 'birpc';
14
- import { parse as parse$1, stringify } from 'structured-clone-es';
15
- import { startSubprocess } from '@nuxt/devtools-kit';
16
- import Git from 'simple-git';
10
+ import { d as defaultAllowedExtensions, c as createDefaultTabOptions, s as setServerTasksEnabledByDefault } from '../shared/devtools.CCWq4fFE.mjs';
11
+ import { runtimeDir, clientDir, packageDir } from '../dirs.mjs';
12
+ import { registerDataSource, createDataInspectorDevframe } from '@devframes/plugin-data-inspector';
13
+ import { mountDevframe } from '@vitejs/devtools-kit/node';
14
+ import { x } from 'tinyexec';
17
15
  import { glob } from 'tinyglobby';
16
+ import path, { relative, parse, dirname as dirname$1 } from 'node:path';
18
17
  import { imageMeta } from 'image-meta';
19
18
  import { debounce } from 'perfect-debounce';
20
19
  import destr from 'destr';
21
20
  import { setupHooksDebug } from '../../dist/runtime/shared/hooks.js';
21
+ import { hash } from 'ohash';
22
22
  import process$1 from 'node:process';
23
23
  import { builtinModules, createRequire } from 'node:module';
24
24
  import { resolvePackageJSON, readPackageJSON } from 'pkg-types';
@@ -27,140 +27,167 @@ import assert from 'node:assert';
27
27
  import v8 from 'node:v8';
28
28
  import { format, inspect } from 'node:util';
29
29
  import { resolveModule, getPackageInfo } from 'local-pkg';
30
- import isInstalledGlobally from 'is-installed-globally';
31
30
  import { parseModule } from 'magicast';
32
31
  import { getDefaultExportOptions, addNuxtModule } from 'magicast/helpers';
33
- import { detectPackageManager } from 'nypm';
34
- import semver from 'semver';
35
- import { normalizeBaseKey, normalizeKey } from 'unstorage';
32
+ import { isLess } from 'verkit';
33
+ import { DEVTOOLS_TERMINALS_DOCK_ID } from '@vitejs/devtools-kit/constants';
34
+ import { normalizeBaseKey, normalizeKey, createStorage, builtinDrivers } from 'unstorage';
36
35
 
37
- const version$1 = "3.4.1";
38
-
39
- const urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
40
- function randomStr(size = 16, dict = urlAlphabet) {
41
- let id = "";
42
- let i = size;
43
- const len = dict.length;
44
- while (i--)
45
- id += dict[Math.random() * len | 0];
46
- return id;
47
- }
36
+ const version$1 = "4.0.0-alpha.10";
48
37
 
49
- function getHomeDir() {
50
- return process.env.XDG_CONFIG_HOME || homedir();
51
- }
52
- async function readLocalOptions(defaults, options) {
53
- const { filePath } = getOptionsFilepath(options);
54
- if (existsSync(filePath)) {
55
- try {
56
- const options2 = {
57
- ...defaults,
58
- ...JSON.parse(await fsp.readFile(filePath, "utf-8")).settings || {}
59
- };
60
- return options2;
61
- } catch (e) {
62
- console.error(`[DevTools] failed to parse local options file: ${filePath}, fallback to defaults`);
63
- console.error(e);
64
- return { ...defaults };
65
- }
66
- } else {
67
- return { ...defaults };
68
- }
69
- }
70
- function getOptionsFilepath(options) {
71
- let hashedKey;
72
- if (options.key)
73
- hashedKey = hash(`${options.root}:${options.key}`);
74
- else
75
- hashedKey = hash(options.root);
76
- const home = getHomeDir();
77
- const filePath = join(home, ".nuxt/devtools", `${hashedKey}.json`);
38
+ const captured = {};
39
+ function normalizeViteConfig(config) {
78
40
  return {
79
- filePath,
80
- hashedKey
41
+ ...config,
42
+ environments: Object.fromEntries(
43
+ Object.entries(config.env ?? {}).map(([key, _]) => {
44
+ return [key, null];
45
+ })
46
+ ),
47
+ plugins: (config.plugins ?? []).map((i) => {
48
+ const clone = { ...i };
49
+ delete clone.api;
50
+ return clone;
51
+ }),
52
+ inlineConfig: null
81
53
  };
82
54
  }
83
- async function clearLocalOptions(options) {
84
- const { filePath } = getOptionsFilepath(options);
85
- if (existsSync(filePath))
86
- await fsp.unlink(filePath);
55
+ function setup(ctx) {
56
+ const { nuxt } = ctx;
57
+ nuxt.hook("nitro:build:before", (nitro) => {
58
+ captured.nitro = nitro;
59
+ });
60
+ nuxt.hook("vite:serverCreated", (server) => {
61
+ captured.vite = server;
62
+ });
63
+ const dataSource = registerDataSource({
64
+ id: "nuxt:application",
65
+ title: "Nuxt Application",
66
+ description: "Live Nuxt, Nitro, and Vite configuration",
67
+ icon: "i-ph:database-duotone",
68
+ static: false,
69
+ data: () => ({
70
+ nuxt: nuxt.options,
71
+ nitro: captured.nitro?.options,
72
+ vite: captured.vite
73
+ }),
74
+ queries: [
75
+ { title: "Overview", query: "", excludeFunctions: true },
76
+ { title: "Nuxt modules", query: "nuxt.modules", excludeFunctions: true },
77
+ { title: "Vite plugins", query: "vite.config.plugins", excludeFunctions: true },
78
+ { title: "Vite config", query: "vite.config", excludeFunctions: true },
79
+ { title: "Vite environments", query: "vite.environments", excludeFunctions: true },
80
+ { title: "Nitro routes", query: "nitro.handlers", excludeFunctions: true }
81
+ ]
82
+ });
83
+ nuxt.hook("close", () => {
84
+ dataSource.unregister();
85
+ captured.nitro = void 0;
86
+ captured.vite = void 0;
87
+ });
88
+ const definition = createDataInspectorDevframe({ exampleSource: false });
89
+ onDevtoolsReady((kit) => {
90
+ return mountDevframe(kit, definition, {
91
+ dock: {
92
+ groupId: NUXT_DEVTOOLS_GROUP_ID,
93
+ category: "advanced"
94
+ }
95
+ });
96
+ }, nuxt);
87
97
  }
88
- async function writeLocalOptions(settings, options) {
89
- const { filePath, hashedKey } = getOptionsFilepath(options);
90
- await fsp.mkdir(dirname(filePath), { recursive: true });
91
- await fsp.writeFile(
92
- filePath,
93
- JSON.stringify(
94
- {
95
- root: options.root,
96
- hash: hashedKey,
97
- settings
98
- },
99
- null,
100
- 2
101
- ),
102
- "utf-8"
103
- );
98
+ function getServerData(nuxt) {
99
+ deprecate(nuxt, "NDT_DEP_0009", {
100
+ api: "getServerData()",
101
+ replacement: "the Nuxt Application source in the Data Inspector panel"
102
+ });
103
+ const config = captured.vite?.config;
104
+ return {
105
+ nuxt: nuxt.options,
106
+ nitro: captured.nitro?.options,
107
+ vite: {
108
+ server: config ? normalizeViteConfig(config) : void 0,
109
+ client: config ? normalizeViteConfig(config) : void 0
110
+ }
111
+ // `nuxt.options` is `@nuxt/schema`'s `NuxtOptions` while `NuxtServerData`
112
+ // pins the structurally-identical `nuxt/schema` one; bridge the two.
113
+ };
104
114
  }
105
115
 
106
- let token;
107
- async function getDevAuthToken() {
108
- if (token)
109
- return token;
110
- const home = getHomeDir();
111
- const dir = join$1(home, ".nuxt/devtools");
112
- const filepath = join$1(dir, "dev-auth-token.txt");
113
- if (existsSync(filepath))
114
- token = (await fsp.readFile(filepath, "utf-8")).trim();
115
- if (!token)
116
- token = randomStr(16);
117
- await fsp.mkdir(dir, { recursive: true });
118
- await fsp.writeFile(filepath, token, "utf-8");
119
- return token;
120
- }
121
-
122
- function isAllowedRpcOrigin(origin, host) {
123
- if (!origin)
124
- return true;
125
- let originHost;
126
- try {
127
- originHost = new URL(origin).host;
128
- } catch {
129
- return false;
130
- }
131
- return !!host && originHost === host;
116
+ const dataInspector = {
117
+ __proto__: null,
118
+ getServerData: getServerData,
119
+ setup: setup
120
+ };
121
+
122
+ const RPC_NAMESPACE = "nuxt:devtools";
123
+
124
+ let counter = 0;
125
+ function createUniqueSessionId(baseId) {
126
+ counter += 1;
127
+ return `${baseId}#${counter}`;
132
128
  }
133
129
 
134
130
  const COLON_RE = /:/g;
135
- function setupAnalyzeBuildRPC({ nuxt, refresh, ensureDevAuthToken }) {
131
+ function setupAnalyzeBuildRPC(ctx) {
132
+ const { nuxt, refresh } = ctx;
136
133
  let builds = [];
137
134
  let promise;
138
135
  let initalized;
139
- const processId = "devtools:analyze-build";
136
+ let activeSessionId;
140
137
  const devtoolsAnalyzeDir = join(nuxt.options.rootDir, "node_modules/.cache/nuxt-devtools/analyze");
141
138
  async function startAnalyzeBuild(name) {
142
139
  if (promise)
143
140
  throw new Error("[Nuxt DevTools] A building process is already running");
144
- const result = startSubprocess({
141
+ const kit = ctx.devtoolsKit;
142
+ if (!kit)
143
+ throw new Error("[Nuxt DevTools] Vite DevTools kit is not connected yet.");
144
+ const sessionId = createUniqueSessionId("devtools:analyze-build");
145
+ activeSessionId = sessionId;
146
+ const session = await kit.terminals.startChildProcess({
145
147
  command: "npx",
146
148
  args: ["nuxi", "analyze", "--no-serve", "--name", name],
147
149
  cwd: nuxt.options.rootDir
148
150
  }, {
149
- id: processId,
150
- name: "Analyze Build",
151
+ id: sessionId,
152
+ title: "Analyze Build",
151
153
  icon: "logos-nuxt-icon"
152
- }, nuxt);
154
+ });
153
155
  refresh("getAnalyzeBuildInfo");
154
156
  initalized = void 0;
155
- promise = result.getProcess().then(() => {
157
+ promise = Promise.resolve(session.getResult()).then((result) => {
158
+ if (result.exitCode && result.exitCode !== 0) {
159
+ ctx.notify({
160
+ message: `Build analysis "${name}" failed`,
161
+ level: "error",
162
+ description: `Process exited with code ${result.exitCode}. Check the Analyze Build terminal for details.`,
163
+ category: "build",
164
+ notify: true
165
+ });
166
+ } else {
167
+ ctx.notify({
168
+ message: `Build analysis "${name}" complete`,
169
+ level: "success",
170
+ category: "build",
171
+ notify: true
172
+ });
173
+ }
156
174
  refresh("getAnalyzeBuildInfo");
157
175
  return readBuildInfo();
176
+ }).catch((error) => {
177
+ ctx.notify({
178
+ message: `Build analysis "${name}" failed`,
179
+ level: "error",
180
+ description: error instanceof Error ? error.message : String(error),
181
+ category: "build",
182
+ notify: true
183
+ });
158
184
  }).finally(() => {
159
185
  promise = void 0;
160
186
  initalized = void 0;
187
+ activeSessionId = void 0;
161
188
  refresh("getAnalyzeBuildInfo");
162
189
  });
163
- return processId;
190
+ return sessionId;
164
191
  }
165
192
  async function readBuildInfo() {
166
193
  for (const dir of /* @__PURE__ */ new Set([
@@ -174,10 +201,10 @@ function setupAnalyzeBuildRPC({ nuxt, refresh, ensureDevAuthToken }) {
174
201
  absolute: true
175
202
  });
176
203
  for (const file of files2) {
177
- const slug = JSON.parse(await fsp.readFile(file, "utf-8")).slug;
178
- const dir2 = dirname$1(file);
179
- await fsp.mkdir(devtoolsAnalyzeDir, { recursive: true });
180
- await fsp.rename(dir2, join(devtoolsAnalyzeDir, slug));
204
+ const slug = JSON.parse(await fs.readFile(file, "utf-8")).slug;
205
+ const dir2 = dirname(file);
206
+ await fs.mkdir(devtoolsAnalyzeDir, { recursive: true });
207
+ await fs.rename(dir2, join(devtoolsAnalyzeDir, slug));
181
208
  }
182
209
  }
183
210
  const files = await glob(["**/meta.json"], {
@@ -186,27 +213,30 @@ function setupAnalyzeBuildRPC({ nuxt, refresh, ensureDevAuthToken }) {
186
213
  absolute: true
187
214
  });
188
215
  builds = await Promise.all(files.map(async (file) => {
189
- const dir = dirname$1(file);
190
- const json = JSON.parse(await fsp.readFile(file, "utf-8"));
216
+ const dir = dirname(file);
217
+ const json = JSON.parse(await fs.readFile(file, "utf-8"));
191
218
  return {
192
219
  ...json,
193
220
  features: {
194
- bundleClient: fs.existsSync(join(dir, "client.html")),
195
- bundleNitro: fs.existsSync(join(dir, "nitro.html")),
196
- viteInspect: fs.existsSync(join(dir, ".vite-inspect"))
221
+ bundleClient: fs$1.existsSync(join(dir, "client.html")),
222
+ bundleNitro: fs$1.existsSync(join(dir, "nitro.html")),
223
+ viteInspect: fs$1.existsSync(join(dir, ".vite-inspect"))
197
224
  }
198
225
  };
199
226
  }));
200
227
  return builds.sort((a, b) => b.endTime - a.endTime);
201
228
  }
229
+ async function git(...args) {
230
+ const result = await x("git", args, { nodeOptions: { cwd: nuxt.options.rootDir }, throwOnError: true });
231
+ return result.stdout.trim();
232
+ }
202
233
  async function generateAnalyzeBuildName() {
203
234
  try {
204
- const git = Git(nuxt.options.rootDir);
205
- const branch = await git.branch();
206
- const branchName = branch.current || "head";
207
- const sha = await git.revparse(["--short", "HEAD"]);
208
- const isWorkingTreeClean = (await git.status()).isClean();
209
- if (isWorkingTreeClean)
235
+ const branchName = await git("rev-parse", "--abbrev-ref", "HEAD") || "head";
236
+ const sha = await git("rev-parse", "--short", "HEAD");
237
+ const status = await git("status", "--porcelain");
238
+ const isClean = status === "";
239
+ if (isClean)
210
240
  return `${branchName}#${sha}`;
211
241
  return `${branchName}#${sha}-dirty`;
212
242
  } catch {
@@ -220,29 +250,28 @@ function setupAnalyzeBuildRPC({ nuxt, refresh, ensureDevAuthToken }) {
220
250
  await initalized;
221
251
  return {
222
252
  isBuilding: !!promise,
253
+ activeSessionId,
223
254
  builds
224
255
  };
225
256
  },
226
- async clearAnalyzeBuilds(token, names) {
227
- await ensureDevAuthToken(token);
257
+ async clearAnalyzeBuilds(names) {
228
258
  if (!names) {
229
- await fsp.rm(devtoolsAnalyzeDir, { recursive: true, force: true });
259
+ await fs.rm(devtoolsAnalyzeDir, { recursive: true, force: true });
230
260
  } else {
231
261
  const targets = builds.filter((build) => names.includes(build.name));
232
- await Promise.all(targets.map((target) => fsp.rm(join(devtoolsAnalyzeDir, target.slug), { recursive: true, force: true })));
262
+ await Promise.all(targets.map((target) => fs.rm(join(devtoolsAnalyzeDir, target.slug), { recursive: true, force: true })));
233
263
  }
234
264
  initalized = readBuildInfo();
235
265
  refresh("getAnalyzeBuildInfo");
236
266
  },
237
267
  generateAnalyzeBuildName,
238
- async startAnalyzeBuild(token, ...args) {
239
- await ensureDevAuthToken(token);
268
+ async startAnalyzeBuild(...args) {
240
269
  return startAnalyzeBuild(...args);
241
270
  }
242
271
  };
243
272
  }
244
273
 
245
- function setupAssetsRPC({ nuxt, ensureDevAuthToken, refresh, options }) {
274
+ function setupAssetsRPC({ nuxt, refresh, options }) {
246
275
  const _imageMetaCache = /* @__PURE__ */ new Map();
247
276
  let cache = null;
248
277
  const extensions = options.assets?.uploadExtensions || defaultAllowedExtensions;
@@ -276,7 +305,7 @@ function setupAssetsRPC({ nuxt, ensureDevAuthToken, refresh, options }) {
276
305
  const filePath = resolve(layerDir, path);
277
306
  if (!filePath.startsWith(layerDir))
278
307
  continue;
279
- const stat = await fsp.lstat(filePath);
308
+ const stat = await fs.lstat(filePath);
280
309
  const fullPath = join(baseURL, path);
281
310
  if (!uniquePaths.has(fullPath)) {
282
311
  cache.push({
@@ -298,12 +327,11 @@ function setupAssetsRPC({ nuxt, ensureDevAuthToken, refresh, options }) {
298
327
  async getStaticAssets() {
299
328
  return await scan();
300
329
  },
301
- async getImageMeta(token, filepath) {
302
- await ensureDevAuthToken(token);
330
+ async getImageMeta(filepath) {
303
331
  if (_imageMetaCache.has(filepath))
304
332
  return _imageMetaCache.get(filepath);
305
333
  try {
306
- const meta = imageMeta(await fsp.readFile(filepath));
334
+ const meta = imageMeta(await fs.readFile(filepath));
307
335
  _imageMetaCache.set(filepath, meta);
308
336
  return meta;
309
337
  } catch (e) {
@@ -312,18 +340,16 @@ function setupAssetsRPC({ nuxt, ensureDevAuthToken, refresh, options }) {
312
340
  return void 0;
313
341
  }
314
342
  },
315
- async getTextAssetContent(token, filepath, limit = 300) {
316
- await ensureDevAuthToken(token);
343
+ async getTextAssetContent(filepath, limit = 300) {
317
344
  try {
318
- const content = await fsp.readFile(filepath, "utf-8");
345
+ const content = await fs.readFile(filepath, "utf-8");
319
346
  return content.slice(0, limit);
320
347
  } catch (e) {
321
348
  console.error(e);
322
349
  return void 0;
323
350
  }
324
351
  },
325
- async writeStaticAssets(token, files, folder) {
326
- await ensureDevAuthToken(token);
352
+ async writeStaticAssets(files, folder) {
327
353
  const baseDir = resolve(nuxt.options.srcDir, nuxt.options.dir.public + folder);
328
354
  return await Promise.all(
329
355
  files.map(async ({ path, content, encoding, override }) => {
@@ -338,32 +364,30 @@ You can configure it in Nuxt config at \`devtools.assets.uploadExtensions\`.`);
338
364
  }
339
365
  if (!override) {
340
366
  try {
341
- await fsp.stat(finalPath);
367
+ await fs.stat(finalPath);
342
368
  const base = finalPath.slice(0, finalPath.length - ext.length - 1);
343
369
  let i = 1;
344
- while (await fsp.access(`${base}-${i}.${ext}`).then(() => true).catch(() => false))
370
+ while (await fs.access(`${base}-${i}.${ext}`).then(() => true).catch(() => false))
345
371
  i++;
346
372
  finalPath = `${base}-${i}.${ext}`;
347
373
  } catch {
348
374
  }
349
375
  }
350
- await fsp.writeFile(finalPath, content, {
376
+ await fs.writeFile(finalPath, content, {
351
377
  encoding: encoding ?? "utf-8"
352
378
  });
353
379
  return finalPath;
354
380
  })
355
381
  );
356
382
  },
357
- async deleteStaticAsset(token, path) {
358
- await ensureDevAuthToken(token);
359
- return await fsp.unlink(path);
383
+ async deleteStaticAsset(path) {
384
+ return await fs.unlink(path);
360
385
  },
361
- async renameStaticAsset(token, oldPath, newPath) {
362
- await ensureDevAuthToken(token);
386
+ async renameStaticAsset(oldPath, newPath) {
363
387
  const exist = cache?.find((asset) => asset.filePath === newPath);
364
388
  if (exist)
365
389
  throw new Error(`[Nuxt DevTools] File ${newPath} already exists, failed to rename`);
366
- return await fsp.rename(oldPath, newPath);
390
+ return await fs.rename(oldPath, newPath);
367
391
  }
368
392
  };
369
393
  }
@@ -386,7 +410,7 @@ function guessType(path) {
386
410
  return "other";
387
411
  }
388
412
 
389
- function setupCustomTabRPC({ nuxt, options, refresh, ensureDevAuthToken }) {
413
+ function setupCustomTabRPC({ nuxt, options, refresh }) {
390
414
  const iframeTabs = [];
391
415
  const customTabs = [];
392
416
  if (options.customTabs?.length)
@@ -415,8 +439,7 @@ function setupCustomTabRPC({ nuxt, options, refresh, ensureDevAuthToken }) {
415
439
  return i;
416
440
  });
417
441
  },
418
- async customTabAction(token, name, actionIndex) {
419
- await ensureDevAuthToken(token);
442
+ async customTabAction(name, actionIndex) {
420
443
  const tab = customTabs.find((i) => i.name === name);
421
444
  if (!tab)
422
445
  return false;
@@ -830,6 +853,9 @@ var defaultOptions = {
830
853
  // Can be either `"script"`, `"module"` or `"commonjs"`. This influences global
831
854
  // strict mode and parsing of `import` and `export` declarations.
832
855
  sourceType: "script",
856
+ // When set to true, enable strict parsing mode even if `sourceType`
857
+ // is `"script"`.
858
+ strict: false,
833
859
  // `onInsertedSemicolon` can be a callback that will be called when
834
860
  // a semicolon is automatically inserted. It will be passed the
835
861
  // position of the inserted semicolon as an offset, and if
@@ -871,6 +897,11 @@ var defaultOptions = {
871
897
  // line being 1-based and column 0-based) will be attached to the
872
898
  // nodes.
873
899
  locations: false,
900
+ // Pass an optional `{line, column}` object to use for the start of
901
+ // the parse. This is mostly useful when using `parseExpressionAt`
902
+ // with `locations: true`, to prevent the parser from having to
903
+ // determine the line position at the start position.
904
+ startLocation: null,
874
905
  // A function can be passed as `onToken` option, which will
875
906
  // cause Acorn to call that function with object in the same
876
907
  // format as tokens returned from `tokenizer().getToken()`. Note
@@ -1024,13 +1055,17 @@ var Parser = function Parser(options, input, startPos) {
1024
1055
  // Set up token state
1025
1056
 
1026
1057
  // The current position of the tokenizer in the input.
1027
- if (startPos) {
1028
- this.pos = startPos;
1058
+ this.pos = startPos || 0;
1059
+ this.curLine = 1;
1060
+ if (options.startLocation) {
1061
+ this.lineStart = this.pos - options.startLocation.column;
1062
+ this.curLine = options.startLocation.line;
1063
+ } else if (startPos) {
1029
1064
  this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1;
1030
- this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length;
1065
+ if (this.options.locations)
1066
+ { this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length; }
1031
1067
  } else {
1032
- this.pos = this.lineStart = 0;
1033
- this.curLine = 1;
1068
+ this.lineStart = 0;
1034
1069
  }
1035
1070
 
1036
1071
  // Properties of the current token:
@@ -1056,7 +1091,7 @@ var Parser = function Parser(options, input, startPos) {
1056
1091
 
1057
1092
  // Figure out if it's a module code.
1058
1093
  this.inModule = options.sourceType === "module";
1059
- this.strict = this.inModule || this.strictDirective(this.pos);
1094
+ this.strict = this.inModule || options.strict === true || this.strictDirective(this.pos);
1060
1095
 
1061
1096
  // Used to signify the start of a potential arrow function
1062
1097
  this.potentialArrowAt = -1;
@@ -1094,9 +1129,11 @@ var Parser = function Parser(options, input, startPos) {
1094
1129
  var prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },canAwait: { configurable: true },allowReturn: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true },allowNewDotTarget: { configurable: true },allowUsing: { configurable: true },inClassStaticBlock: { configurable: true } };
1095
1130
 
1096
1131
  Parser.prototype.parse = function parse () {
1132
+ var this$1$1 = this;
1133
+
1097
1134
  var node = this.options.program || this.startNode();
1098
1135
  this.nextToken();
1099
- return this.parseTopLevel(node)
1136
+ return this.catchStackOverflow(function () { return this$1$1.parseTopLevel(node); })
1100
1137
  };
1101
1138
 
1102
1139
  prototypeAccessors.inFunction.get = function () { return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0 };
@@ -1235,6 +1272,17 @@ pp$9.eatContextual = function(name) {
1235
1272
  return true
1236
1273
  };
1237
1274
 
1275
+ pp$9.catchStackOverflow = function(f) {
1276
+ try {
1277
+ return f()
1278
+ } catch (e) {
1279
+ if (e instanceof Error && (/\bstack\b.*\b(exceeded|overflow)\b/i.test(e.message) || /\btoo much recursion\b/i.test(e.message)))
1280
+ { this.raise(this.start, "Not enough stack space to parse input"); }
1281
+ else
1282
+ { throw e }
1283
+ }
1284
+ };
1285
+
1238
1286
  // Asserts that following token is given contextual keyword.
1239
1287
 
1240
1288
  pp$9.expectContextual = function(name) {
@@ -1338,10 +1386,10 @@ var pp$8 = Parser.prototype;
1338
1386
  // to its body instead of creating a new node.
1339
1387
 
1340
1388
  pp$8.parseTopLevel = function(node) {
1341
- var exports = Object.create(null);
1389
+ var exports$1 = Object.create(null);
1342
1390
  if (!node.body) { node.body = []; }
1343
1391
  while (this.type !== types$1.eof) {
1344
- var stmt = this.parseStatement(null, true, exports);
1392
+ var stmt = this.parseStatement(null, true, exports$1);
1345
1393
  node.body.push(stmt);
1346
1394
  }
1347
1395
  if (this.inModule)
@@ -1430,7 +1478,18 @@ pp$8.isUsingKeyword = function(isAwaitUsing, isFor) {
1430
1478
  while (isIdentifierChar(ch = this.fullCharCodeAt(next)))
1431
1479
  if (ch === 92) { return true }
1432
1480
  var id = this.input.slice(idStart, next);
1433
- if (keywordRelationalOperator.test(id) || isFor && id === "of") { return false }
1481
+ if (keywordRelationalOperator.test(id)) { return false }
1482
+ if (isFor && !isAwaitUsing && id === "of") {
1483
+ // Look ahead for using declaration with initializer, i.e., `for (using of = ...)`
1484
+ skipWhiteSpace.lastIndex = next;
1485
+ var skipAfterOf = skipWhiteSpace.exec(this.input);
1486
+ next = next + skipAfterOf[0].length;
1487
+ if (this.input.charCodeAt(next) !== 61 /* '=' */ ||
1488
+ // Check for ==, === and => operators
1489
+ (ch = this.input.charCodeAt(next + 1)) === 61 /* '=' */ || ch === 62 /* '>' */) {
1490
+ return false
1491
+ }
1492
+ }
1434
1493
  return true
1435
1494
  };
1436
1495
 
@@ -1449,7 +1508,7 @@ pp$8.isUsing = function(isFor) {
1449
1508
  // `if (foo) /blah/.exec(foo)`, where looking at the previous token
1450
1509
  // does not help.
1451
1510
 
1452
- pp$8.parseStatement = function(context, topLevel, exports) {
1511
+ pp$8.parseStatement = function(context, topLevel, exports$1) {
1453
1512
  var starttype = this.type, node = this.startNode(), kind;
1454
1513
 
1455
1514
  if (this.isLet(context)) {
@@ -1504,7 +1563,7 @@ pp$8.parseStatement = function(context, topLevel, exports) {
1504
1563
  if (!this.inModule)
1505
1564
  { this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); }
1506
1565
  }
1507
- return starttype === types$1._import ? this.parseImport(node) : this.parseExport(node, exports)
1566
+ return starttype === types$1._import ? this.parseImport(node) : this.parseExport(node, exports$1)
1508
1567
 
1509
1568
  // If the statement does not start with a statement keyword or a
1510
1569
  // brace, it's an ExpressionStatement or LabeledStatement. We
@@ -1523,6 +1582,10 @@ pp$8.parseStatement = function(context, topLevel, exports) {
1523
1582
  if (!this.allowUsing) {
1524
1583
  this.raise(this.start, "Using declaration cannot appear in the top level when source type is `script` or in the bare case statement");
1525
1584
  }
1585
+ if (context) {
1586
+ // Cases like `for (;;) using x = ...;`, `if (true) await using x = ...;`, etc. are not allowed.
1587
+ this.raise(this.start, "Using declaration is not allowed in single-statement positions");
1588
+ }
1526
1589
  if (usingKind === "await using") {
1527
1590
  if (!this.canAwait) {
1528
1591
  this.raise(this.start, "Await using cannot appear outside of async function");
@@ -1656,11 +1719,12 @@ pp$8.parseForStatement = function(node) {
1656
1719
  // Helper method to parse for loop after variable initialization
1657
1720
  pp$8.parseForAfterInit = function(node, init, awaitAt) {
1658
1721
  if ((this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init.declarations.length === 1) {
1659
- if (this.options.ecmaVersion >= 9) {
1660
- if (this.type === types$1._in) {
1661
- if (awaitAt > -1) { this.unexpected(awaitAt); }
1662
- } else { node.await = awaitAt > -1; }
1663
- }
1722
+ if (this.type === types$1._in) {
1723
+ if ((init.kind === "using" || init.kind === "await using") && !init.declarations[0].init) {
1724
+ this.raise(this.start, "Using declaration is not allowed in for-in loops");
1725
+ }
1726
+ if (this.options.ecmaVersion >= 9 && awaitAt > -1) { this.unexpected(awaitAt); }
1727
+ } else if (this.options.ecmaVersion >= 9) { node.await = awaitAt > -1; }
1664
1728
  return this.parseForIn(node, init)
1665
1729
  }
1666
1730
  if (awaitAt > -1) { this.unexpected(awaitAt); }
@@ -2265,11 +2329,11 @@ function checkKeyName(node, name) {
2265
2329
 
2266
2330
  // Parses module export declaration.
2267
2331
 
2268
- pp$8.parseExportAllDeclaration = function(node, exports) {
2332
+ pp$8.parseExportAllDeclaration = function(node, exports$1) {
2269
2333
  if (this.options.ecmaVersion >= 11) {
2270
2334
  if (this.eatContextual("as")) {
2271
2335
  node.exported = this.parseModuleExportName();
2272
- this.checkExport(exports, node.exported, this.lastTokStart);
2336
+ this.checkExport(exports$1, node.exported, this.lastTokStart);
2273
2337
  } else {
2274
2338
  node.exported = null;
2275
2339
  }
@@ -2283,14 +2347,14 @@ pp$8.parseExportAllDeclaration = function(node, exports) {
2283
2347
  return this.finishNode(node, "ExportAllDeclaration")
2284
2348
  };
2285
2349
 
2286
- pp$8.parseExport = function(node, exports) {
2350
+ pp$8.parseExport = function(node, exports$1) {
2287
2351
  this.next();
2288
2352
  // export * from '...'
2289
2353
  if (this.eat(types$1.star)) {
2290
- return this.parseExportAllDeclaration(node, exports)
2354
+ return this.parseExportAllDeclaration(node, exports$1)
2291
2355
  }
2292
2356
  if (this.eat(types$1._default)) { // export default ...
2293
- this.checkExport(exports, "default", this.lastTokStart);
2357
+ this.checkExport(exports$1, "default", this.lastTokStart);
2294
2358
  node.declaration = this.parseExportDefaultDeclaration();
2295
2359
  return this.finishNode(node, "ExportDefaultDeclaration")
2296
2360
  }
@@ -2298,16 +2362,16 @@ pp$8.parseExport = function(node, exports) {
2298
2362
  if (this.shouldParseExportStatement()) {
2299
2363
  node.declaration = this.parseExportDeclaration(node);
2300
2364
  if (node.declaration.type === "VariableDeclaration")
2301
- { this.checkVariableExport(exports, node.declaration.declarations); }
2365
+ { this.checkVariableExport(exports$1, node.declaration.declarations); }
2302
2366
  else
2303
- { this.checkExport(exports, node.declaration.id, node.declaration.id.start); }
2367
+ { this.checkExport(exports$1, node.declaration.id, node.declaration.id.start); }
2304
2368
  node.specifiers = [];
2305
2369
  node.source = null;
2306
2370
  if (this.options.ecmaVersion >= 16)
2307
2371
  { node.attributes = []; }
2308
2372
  } else { // export { x, y as z } [from '...']
2309
2373
  node.declaration = null;
2310
- node.specifiers = this.parseExportSpecifiers(exports);
2374
+ node.specifiers = this.parseExportSpecifiers(exports$1);
2311
2375
  if (this.eatContextual("from")) {
2312
2376
  if (this.type !== types$1.string) { this.unexpected(); }
2313
2377
  node.source = this.parseExprAtom();
@@ -2357,47 +2421,47 @@ pp$8.parseExportDefaultDeclaration = function() {
2357
2421
  }
2358
2422
  };
2359
2423
 
2360
- pp$8.checkExport = function(exports, name, pos) {
2361
- if (!exports) { return }
2424
+ pp$8.checkExport = function(exports$1, name, pos) {
2425
+ if (!exports$1) { return }
2362
2426
  if (typeof name !== "string")
2363
2427
  { name = name.type === "Identifier" ? name.name : name.value; }
2364
- if (hasOwn(exports, name))
2428
+ if (hasOwn(exports$1, name))
2365
2429
  { this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); }
2366
- exports[name] = true;
2430
+ exports$1[name] = true;
2367
2431
  };
2368
2432
 
2369
- pp$8.checkPatternExport = function(exports, pat) {
2433
+ pp$8.checkPatternExport = function(exports$1, pat) {
2370
2434
  var type = pat.type;
2371
2435
  if (type === "Identifier")
2372
- { this.checkExport(exports, pat, pat.start); }
2436
+ { this.checkExport(exports$1, pat, pat.start); }
2373
2437
  else if (type === "ObjectPattern")
2374
2438
  { for (var i = 0, list = pat.properties; i < list.length; i += 1)
2375
2439
  {
2376
2440
  var prop = list[i];
2377
2441
 
2378
- this.checkPatternExport(exports, prop);
2442
+ this.checkPatternExport(exports$1, prop);
2379
2443
  } }
2380
2444
  else if (type === "ArrayPattern")
2381
2445
  { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) {
2382
2446
  var elt = list$1[i$1];
2383
2447
 
2384
- if (elt) { this.checkPatternExport(exports, elt); }
2448
+ if (elt) { this.checkPatternExport(exports$1, elt); }
2385
2449
  } }
2386
2450
  else if (type === "Property")
2387
- { this.checkPatternExport(exports, pat.value); }
2451
+ { this.checkPatternExport(exports$1, pat.value); }
2388
2452
  else if (type === "AssignmentPattern")
2389
- { this.checkPatternExport(exports, pat.left); }
2453
+ { this.checkPatternExport(exports$1, pat.left); }
2390
2454
  else if (type === "RestElement")
2391
- { this.checkPatternExport(exports, pat.argument); }
2455
+ { this.checkPatternExport(exports$1, pat.argument); }
2392
2456
  };
2393
2457
 
2394
- pp$8.checkVariableExport = function(exports, decls) {
2395
- if (!exports) { return }
2458
+ pp$8.checkVariableExport = function(exports$1, decls) {
2459
+ if (!exports$1) { return }
2396
2460
  for (var i = 0, list = decls; i < list.length; i += 1)
2397
2461
  {
2398
2462
  var decl = list[i];
2399
2463
 
2400
- this.checkPatternExport(exports, decl.id);
2464
+ this.checkPatternExport(exports$1, decl.id);
2401
2465
  }
2402
2466
  };
2403
2467
 
@@ -2412,13 +2476,13 @@ pp$8.shouldParseExportStatement = function() {
2412
2476
 
2413
2477
  // Parses a comma-separated list of module exports.
2414
2478
 
2415
- pp$8.parseExportSpecifier = function(exports) {
2479
+ pp$8.parseExportSpecifier = function(exports$1) {
2416
2480
  var node = this.startNode();
2417
2481
  node.local = this.parseModuleExportName();
2418
2482
 
2419
2483
  node.exported = this.eatContextual("as") ? this.parseModuleExportName() : node.local;
2420
2484
  this.checkExport(
2421
- exports,
2485
+ exports$1,
2422
2486
  node.exported,
2423
2487
  node.exported.start
2424
2488
  );
@@ -2426,7 +2490,7 @@ pp$8.parseExportSpecifier = function(exports) {
2426
2490
  return this.finishNode(node, "ExportSpecifier")
2427
2491
  };
2428
2492
 
2429
- pp$8.parseExportSpecifiers = function(exports) {
2493
+ pp$8.parseExportSpecifiers = function(exports$1) {
2430
2494
  var nodes = [], first = true;
2431
2495
  // export { x, y as z } [from '...']
2432
2496
  this.expect(types$1.braceL);
@@ -2436,7 +2500,7 @@ pp$8.parseExportSpecifiers = function(exports) {
2436
2500
  if (this.afterTrailingComma(types$1.braceR)) { break }
2437
2501
  } else { first = false; }
2438
2502
 
2439
- nodes.push(this.parseExportSpecifier(exports));
2503
+ nodes.push(this.parseExportSpecifier(exports$1));
2440
2504
  }
2441
2505
  return nodes
2442
2506
  };
@@ -3167,15 +3231,19 @@ pp$5.checkPropClash = function(prop, propHash, refDestructuringErrors) {
3167
3231
  // delayed syntax error at correct position).
3168
3232
 
3169
3233
  pp$5.parseExpression = function(forInit, refDestructuringErrors) {
3170
- var startPos = this.start, startLoc = this.startLoc;
3171
- var expr = this.parseMaybeAssign(forInit, refDestructuringErrors);
3172
- if (this.type === types$1.comma) {
3173
- var node = this.startNodeAt(startPos, startLoc);
3174
- node.expressions = [expr];
3175
- while (this.eat(types$1.comma)) { node.expressions.push(this.parseMaybeAssign(forInit, refDestructuringErrors)); }
3176
- return this.finishNode(node, "SequenceExpression")
3177
- }
3178
- return expr
3234
+ var this$1$1 = this;
3235
+
3236
+ return this.catchStackOverflow(function () {
3237
+ var startPos = this$1$1.start, startLoc = this$1$1.startLoc;
3238
+ var expr = this$1$1.parseMaybeAssign(forInit, refDestructuringErrors);
3239
+ if (this$1$1.type === types$1.comma) {
3240
+ var node = this$1$1.startNodeAt(startPos, startLoc);
3241
+ node.expressions = [expr];
3242
+ while (this$1$1.eat(types$1.comma)) { node.expressions.push(this$1$1.parseMaybeAssign(forInit, refDestructuringErrors)); }
3243
+ return this$1$1.finishNode(node, "SequenceExpression")
3244
+ }
3245
+ return expr
3246
+ })
3179
3247
  };
3180
3248
 
3181
3249
  // Parse an assignment expression. This includes applications of
@@ -3240,7 +3308,7 @@ pp$5.parseMaybeConditional = function(forInit, refDestructuringErrors) {
3240
3308
  var startPos = this.start, startLoc = this.startLoc;
3241
3309
  var expr = this.parseExprOps(forInit, refDestructuringErrors);
3242
3310
  if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
3243
- if (this.eat(types$1.question)) {
3311
+ if (!(expr.type === "ArrowFunctionExpression" && expr.start === startPos) && this.eat(types$1.question)) {
3244
3312
  var node = this.startNodeAt(startPos, startLoc);
3245
3313
  node.test = expr;
3246
3314
  node.consequent = this.parseMaybeAssign();
@@ -3340,7 +3408,7 @@ pp$5.parseMaybeUnary = function(refDestructuringErrors, sawUnary, incDec, forIni
3340
3408
  }
3341
3409
  }
3342
3410
 
3343
- if (!incDec && this.eat(types$1.starstar)) {
3411
+ if (!incDec && !(expr.type === "ArrowFunctionExpression" && expr.start === startPos) && this.eat(types$1.starstar)) {
3344
3412
  if (sawUnary)
3345
3413
  { this.unexpected(this.lastTokStart); }
3346
3414
  else
@@ -3792,6 +3860,8 @@ pp$5.parseNew = function() {
3792
3860
  }
3793
3861
  var startPos = this.start, startLoc = this.startLoc;
3794
3862
  node.callee = this.parseSubscripts(this.parseExprAtom(null, false, true), startPos, startLoc, true, false);
3863
+ if (node.callee.type === "Super")
3864
+ { this.raiseRecoverable(startPos, "Invalid use of 'super'"); }
3795
3865
  if (this.eat(types$1.parenL)) { node.arguments = this.parseExprList(types$1.parenR, this.options.ecmaVersion >= 8, false); }
3796
3866
  else { node.arguments = empty; }
3797
3867
  return this.finishNode(node, "NewExpression")
@@ -6708,7 +6778,7 @@ pp.readWord = function() {
6708
6778
  // [ghbt]: https://github.com/acornjs/acorn/issues
6709
6779
 
6710
6780
 
6711
- var version = "8.16.0";
6781
+ var version = "8.18.0";
6712
6782
 
6713
6783
  Parser.acorn = {
6714
6784
  Parser: Parser,
@@ -7477,7 +7547,7 @@ function read(jsonPath, {base, specifier}) {
7477
7547
  let string;
7478
7548
 
7479
7549
  try {
7480
- string = fs.readFileSync(path.toNamespacedPath(jsonPath), 'utf8');
7550
+ string = fs$1.readFileSync(path.toNamespacedPath(jsonPath), 'utf8');
7481
7551
  } catch (error) {
7482
7552
  const exception = /** @type {ErrnoException} */ (error);
7483
7553
 
@@ -9299,7 +9369,7 @@ async function extractExports(name, url, cache = true) {
9299
9369
  return JSON.parse(await promises.readFile(cachePath, "utf-8"));
9300
9370
  const scanned = await resolveModuleExportNames(name, { url });
9301
9371
  if (useCache) {
9302
- await promises.mkdir(dirname$1(cachePath), { recursive: true });
9372
+ await promises.mkdir(dirname(cachePath), { recursive: true });
9303
9373
  await promises.writeFile(cachePath, JSON.stringify(scanned), "utf-8");
9304
9374
  }
9305
9375
  return scanned;
@@ -10280,36 +10350,93 @@ function safeKey(key) {
10280
10350
  return JSON.stringify(key);
10281
10351
  }
10282
10352
 
10353
+ function getHomeDir() {
10354
+ return process.env.XDG_CONFIG_HOME || homedir();
10355
+ }
10356
+ async function readLocalOptions(defaults, options) {
10357
+ const { filePath } = getOptionsFilepath(options);
10358
+ if (existsSync(filePath)) {
10359
+ try {
10360
+ const options2 = {
10361
+ ...defaults,
10362
+ ...JSON.parse(await fs.readFile(filePath, "utf-8")).settings || {}
10363
+ };
10364
+ return options2;
10365
+ } catch (e) {
10366
+ console.error(`[DevTools] failed to parse local options file: ${filePath}, fallback to defaults`);
10367
+ console.error(e);
10368
+ return { ...defaults };
10369
+ }
10370
+ } else {
10371
+ return { ...defaults };
10372
+ }
10373
+ }
10374
+ function getOptionsFilepath(options) {
10375
+ let hashedKey;
10376
+ if (options.key)
10377
+ hashedKey = hash(`${options.root}:${options.key}`);
10378
+ else
10379
+ hashedKey = hash(options.root);
10380
+ const home = getHomeDir();
10381
+ const filePath = join(home, ".nuxt/devtools", `${hashedKey}.json`);
10382
+ return {
10383
+ filePath,
10384
+ hashedKey
10385
+ };
10386
+ }
10387
+ async function clearLocalOptions(options) {
10388
+ const { filePath } = getOptionsFilepath(options);
10389
+ if (existsSync(filePath))
10390
+ await fs.unlink(filePath);
10391
+ }
10392
+ async function writeLocalOptions(settings, options) {
10393
+ const { filePath, hashedKey } = getOptionsFilepath(options);
10394
+ await fs.mkdir(dirname$1(filePath), { recursive: true });
10395
+ await fs.writeFile(
10396
+ filePath,
10397
+ JSON.stringify(
10398
+ {
10399
+ root: options.root,
10400
+ hash: hashedKey,
10401
+ settings
10402
+ },
10403
+ null,
10404
+ 2
10405
+ ),
10406
+ "utf-8"
10407
+ );
10408
+ }
10409
+
10283
10410
  let options;
10284
10411
  function getOptions() {
10285
10412
  return options;
10286
10413
  }
10287
- function setupOptionsRPC({ nuxt, ensureDevAuthToken }) {
10414
+ function setupOptionsRPC({ nuxt }) {
10415
+ const hasReadOnce = /* @__PURE__ */ new Set();
10288
10416
  async function getOptions2(tab) {
10289
- if (!options || options[tab]) {
10290
- options = defaultTabOptions;
10417
+ if (!options)
10418
+ options = createDefaultTabOptions();
10419
+ if (!hasReadOnce.has(tab))
10291
10420
  await read(tab);
10292
- }
10293
10421
  return options[tab];
10294
10422
  }
10295
10423
  async function read(tab) {
10296
- options[tab] = await readLocalOptions(defaultTabOptions[tab], {
10424
+ options[tab] = await readLocalOptions(createDefaultTabOptions()[tab], {
10297
10425
  root: nuxt.options.rootDir,
10298
10426
  key: tab !== "ui" && tab
10299
10427
  });
10428
+ hasReadOnce.add(tab);
10300
10429
  return options;
10301
10430
  }
10302
10431
  getOptions2("ui");
10303
- async function clearOptions(token) {
10304
- await ensureDevAuthToken(token);
10432
+ async function clearOptions() {
10305
10433
  options = void 0;
10306
10434
  await clearLocalOptions({
10307
10435
  root: nuxt.options.rootDir
10308
10436
  });
10309
10437
  }
10310
10438
  return {
10311
- async updateOptions(token, tab, _settings) {
10312
- await ensureDevAuthToken(token);
10439
+ async updateOptions(tab, _settings) {
10313
10440
  const settings = await getOptions2(tab);
10314
10441
  Object.assign(settings, _settings);
10315
10442
  await writeLocalOptions(
@@ -10332,12 +10459,11 @@ function setupOptionsRPC({ nuxt, ensureDevAuthToken }) {
10332
10459
 
10333
10460
  const ABSOLUTE_PATH_RE = /^[a-z]:|^\//i;
10334
10461
  const FILE_LINE_COL_RE = /^(.*?)(:[:\d]*)$/;
10335
- const MULTIPLE_SLASHES_RE$1 = /\/+/g;
10462
+ const NUXT_WELCOME_RE = /<NuxtWelcome\s*\/>/;
10336
10463
  function setupGeneralRPC({
10337
10464
  nuxt,
10338
10465
  options,
10339
10466
  refresh,
10340
- ensureDevAuthToken,
10341
10467
  openInEditorHooks
10342
10468
  }) {
10343
10469
  const components = [];
@@ -10393,14 +10519,7 @@ function setupGeneralRPC({
10393
10519
  });
10394
10520
  return {
10395
10521
  getServerConfig() {
10396
- const { runtimeConfig, ...rest } = nuxt.options;
10397
- return {
10398
- ...rest,
10399
- runtimeConfig: {
10400
- app: runtimeConfig?.app,
10401
- public: runtimeConfig?.public
10402
- }
10403
- };
10522
+ return nuxt.options;
10404
10523
  },
10405
10524
  async getServerDebugContext() {
10406
10525
  if (!nuxt._debug)
@@ -10434,8 +10553,7 @@ function setupGeneralRPC({
10434
10553
  )
10435
10554
  };
10436
10555
  },
10437
- async getServerRuntimeConfig(token) {
10438
- await ensureDevAuthToken(token);
10556
+ getServerRuntimeConfig() {
10439
10557
  const ENV_PREFIX = "NITRO_";
10440
10558
  const ENV_PREFIX_ALT = "NUXT_";
10441
10559
  function _getEnv(key) {
@@ -10494,8 +10612,7 @@ function setupGeneralRPC({
10494
10612
  getServerHooks() {
10495
10613
  return Object.values(serverHooks);
10496
10614
  },
10497
- async openInEditor(token, input) {
10498
- await ensureDevAuthToken(token);
10615
+ async openInEditor(input) {
10499
10616
  if (input.startsWith("./") || !ABSOLUTE_PATH_RE.test(input))
10500
10617
  input = resolve(process.cwd(), input);
10501
10618
  const match = input.match(FILE_LINE_COL_RE);
@@ -10530,44 +10647,261 @@ function setupGeneralRPC({
10530
10647
  return false;
10531
10648
  }
10532
10649
  },
10533
- async restartNuxt(token, hard = true) {
10534
- await ensureDevAuthToken(token);
10650
+ async enablePages() {
10651
+ const baseDir = nuxt.options.future.compatibilityVersion === 4 ? nuxt.options.dir.app : nuxt.options.srcDir;
10652
+ const pathApp = join(baseDir, "app.vue");
10653
+ const pathPageIndex = join(baseDir, "pages/index.vue");
10654
+ if (existsSync(pathPageIndex)) {
10655
+ logger.warn("pages/index.vue already exists, skipping");
10656
+ return;
10657
+ }
10658
+ const pagesIndexTemplate = `<script setup lang="ts">
10659
+ const route = useRoute()
10660
+ <\/script>
10661
+
10662
+ <template>
10663
+ <div>
10664
+ <h1>Nuxt Routing set up successfully!</h1>
10665
+ <p>Current route: {{ route.path }}</p>
10666
+ <a href="https://nuxt.com/docs/getting-started/routing" target="_blank">Learn more about Nuxt Routing</a>
10667
+ </div>
10668
+ </template>
10669
+ `;
10670
+ await fs.mkdir(dirname(pathPageIndex), { recursive: true });
10671
+ await fs.writeFile(pathPageIndex, pagesIndexTemplate, "utf-8");
10672
+ let appContent = existsSync(pathApp) ? await fs.readFile(pathApp, "utf-8") : void 0;
10673
+ if (appContent && !appContent.includes("<NuxtPage")) {
10674
+ appContent = appContent.replace("</template>", " <NuxtPage />\n</template>").replace(NUXT_WELCOME_RE, "");
10675
+ await fs.writeFile(pathApp, appContent, "utf-8");
10676
+ }
10677
+ logger.success("Routing creation completed");
10678
+ },
10679
+ async restartNuxt(hard = true) {
10535
10680
  logger.info("Restarting Nuxt...");
10536
10681
  return nuxt.callHook("restart", { hard });
10537
10682
  },
10538
- async requestForAuth(info) {
10539
- if (options.disableAuthorization)
10540
- return;
10541
- const token = await getDevAuthToken();
10542
- const origin = `${nuxt.options.devServer.https ? "https" : "http"}://${nuxt.options.devServer.host === "::" ? "localhost" : nuxt.options.devServer.host || "localhost"}:${nuxt.options.devServer.port}`;
10543
- const ROUTE_AUTH = `${nuxt.options.app.baseURL || "/"}/__nuxt_devtools__/auth`.replace(MULTIPLE_SLASHES_RE$1, "/");
10544
- const message = [
10545
- `A browser is requesting permissions of ${colors.bold(colors.yellow("writing files and running commands"))} from the DevTools UI.`,
10546
- colors.bold(info || "Unknown"),
10547
- "",
10548
- "Please open the following URL in the browser:",
10549
- colors.bold(colors.green(`${origin}${ROUTE_AUTH}?token=${token}`)),
10550
- "",
10551
- "Or manually copy and paste the following token:",
10552
- colors.bold(colors.cyan(token))
10553
- ];
10554
- logger.box({
10555
- message: message.join("\n"),
10556
- title: colors.bold(colors.yellow(" Permission Request ")),
10557
- style: {
10558
- borderColor: "yellow",
10559
- borderStyle: "rounded"
10560
- }
10561
- });
10683
+ /** @deprecated Auth is now handled by Vite DevTools */
10684
+ async requestForAuth() {
10685
+ logger.warn("[nuxt-devtools] `requestForAuth` is deprecated. Auth is now handled by Vite DevTools.");
10562
10686
  },
10563
- async verifyAuthToken(token) {
10564
- if (options.disableAuthorization)
10565
- return true;
10566
- return token === await getDevAuthToken();
10687
+ /** @deprecated Auth is now handled by Vite DevTools */
10688
+ async verifyAuthToken() {
10689
+ logger.warn("[nuxt-devtools] `verifyAuthToken` is deprecated. Auth is now handled by Vite DevTools.");
10690
+ return true;
10691
+ }
10692
+ };
10693
+ }
10694
+
10695
+ function toEntryInput(input) {
10696
+ return {
10697
+ message: input.message,
10698
+ level: input.level ?? "info",
10699
+ description: input.description,
10700
+ labels: input.labels,
10701
+ category: input.category,
10702
+ filePosition: input.filePosition,
10703
+ stacktrace: input.stacktrace,
10704
+ notify: input.notify,
10705
+ autoDismiss: input.autoDismiss,
10706
+ autoDelete: input.autoDelete
10707
+ };
10708
+ }
10709
+ function createNotifier(nuxt) {
10710
+ let messages;
10711
+ const pending = [];
10712
+ function add(input) {
10713
+ void messages.add(toEntryInput(input)).catch(() => {
10714
+ });
10715
+ }
10716
+ function notify(input) {
10717
+ if (!messages) {
10718
+ pending.push(input);
10719
+ return;
10720
+ }
10721
+ add(input);
10722
+ }
10723
+ onDevtoolsReady((kit) => {
10724
+ messages = kit.messages;
10725
+ for (const input of pending)
10726
+ add(input);
10727
+ pending.length = 0;
10728
+ }, nuxt);
10729
+ nuxt.hook("devtools:notify", notify);
10730
+ return notify;
10731
+ }
10732
+ function setupMessagesRPC(ctx) {
10733
+ return {
10734
+ async notify(input) {
10735
+ ctx.notify(input);
10567
10736
  }
10568
10737
  };
10569
10738
  }
10570
10739
 
10740
+ const AGENTS = [
10741
+ "npm",
10742
+ "yarn",
10743
+ "yarn@berry",
10744
+ "pnpm",
10745
+ "pnpm@6",
10746
+ "pnpm-rush",
10747
+ "bun",
10748
+ "deno",
10749
+ "nub",
10750
+ "aube"
10751
+ ];
10752
+ const LOCKS = {
10753
+ "aube-lock.yaml": "aube",
10754
+ "aube-workspace.yaml": "aube",
10755
+ "bun.lock": "bun",
10756
+ "bun.lockb": "bun",
10757
+ "deno.lock": "deno",
10758
+ "nub.lock": "nub",
10759
+ "pnpm-lock.yaml": "pnpm",
10760
+ "pnpm-workspace.yaml": "pnpm",
10761
+ "yarn.lock": "yarn",
10762
+ "package-lock.json": "npm",
10763
+ "npm-shrinkwrap.json": "npm"
10764
+ };
10765
+ const INSTALL_METADATA = {
10766
+ "node_modules/.aube/": "aube",
10767
+ "node_modules/.deno/": "deno",
10768
+ "node_modules/.pnpm/": "pnpm",
10769
+ "node_modules/.yarn-state.yml": "yarn",
10770
+ // yarn v2+ (node-modules)
10771
+ "node_modules/.yarn_integrity": "yarn",
10772
+ // yarn v1
10773
+ "node_modules/.package-lock.json": "npm",
10774
+ ".pnp.cjs": "yarn",
10775
+ // yarn v3+ (pnp)
10776
+ ".pnp.js": "yarn",
10777
+ // yarn v2 (pnp)
10778
+ "bun.lock": "bun",
10779
+ "bun.lockb": "bun"
10780
+ };
10781
+
10782
+ async function pathExists(path2, type) {
10783
+ try {
10784
+ const stat = await fs.stat(path2);
10785
+ return type === "file" ? stat.isFile() : stat.isDirectory();
10786
+ } catch {
10787
+ return false;
10788
+ }
10789
+ }
10790
+ function* lookup(cwd = process$1.cwd()) {
10791
+ let directory = path.resolve(cwd);
10792
+ const { root } = path.parse(directory);
10793
+ while (directory && directory !== root) {
10794
+ yield directory;
10795
+ directory = path.dirname(directory);
10796
+ }
10797
+ }
10798
+ async function parsePackageJson(filepath, options) {
10799
+ if (!filepath || !await pathExists(filepath, "file"))
10800
+ return null;
10801
+ return await handlePackageManager(filepath, options);
10802
+ }
10803
+ async function detect(options = {}) {
10804
+ const {
10805
+ cwd,
10806
+ strategies = ["lockfile", "packageManager-field", "devEngines-field"]
10807
+ } = options;
10808
+ let stopDir;
10809
+ if (typeof options.stopDir === "string") {
10810
+ const resolved = path.resolve(options.stopDir);
10811
+ stopDir = (dir) => dir === resolved;
10812
+ } else {
10813
+ stopDir = options.stopDir;
10814
+ }
10815
+ for (const directory of lookup(cwd)) {
10816
+ for (const strategy of strategies) {
10817
+ switch (strategy) {
10818
+ case "lockfile": {
10819
+ if (await pathExists(path.join(directory, "rush.json"), "file")) {
10820
+ return { name: "pnpm", agent: "pnpm-rush" };
10821
+ }
10822
+ for (const lock of Object.keys(LOCKS)) {
10823
+ if (await pathExists(path.join(directory, lock), "file")) {
10824
+ const name = LOCKS[lock];
10825
+ const result = await parsePackageJson(path.join(directory, "package.json"), options);
10826
+ if (result)
10827
+ return result;
10828
+ else
10829
+ return { name, agent: name };
10830
+ }
10831
+ }
10832
+ break;
10833
+ }
10834
+ case "packageManager-field":
10835
+ case "devEngines-field": {
10836
+ const result = await parsePackageJson(path.join(directory, "package.json"), options);
10837
+ if (result)
10838
+ return result;
10839
+ break;
10840
+ }
10841
+ case "install-metadata": {
10842
+ for (const metadata of Object.keys(INSTALL_METADATA)) {
10843
+ const fileOrDir = metadata.endsWith("/") ? "dir" : "file";
10844
+ if (await pathExists(path.join(directory, metadata), fileOrDir)) {
10845
+ const name = INSTALL_METADATA[metadata];
10846
+ const agent = name === "yarn" ? isMetadataYarnClassic(metadata) ? "yarn" : "yarn@berry" : name;
10847
+ return { name, agent };
10848
+ }
10849
+ }
10850
+ break;
10851
+ }
10852
+ }
10853
+ }
10854
+ if (stopDir?.(directory))
10855
+ break;
10856
+ }
10857
+ return null;
10858
+ }
10859
+ function getNameAndVer(pkg) {
10860
+ const handelVer = (version) => version?.match(/\d+(\.\d+){0,2}/)?.[0] ?? version;
10861
+ if (typeof pkg.packageManager === "string") {
10862
+ const [name, ver] = pkg.packageManager.replace(/^\^/, "").split("@");
10863
+ return { name, ver: handelVer(ver) };
10864
+ }
10865
+ if (typeof pkg.devEngines?.packageManager?.name === "string") {
10866
+ return {
10867
+ name: pkg.devEngines.packageManager.name,
10868
+ ver: handelVer(pkg.devEngines.packageManager.version)
10869
+ };
10870
+ }
10871
+ return void 0;
10872
+ }
10873
+ async function handlePackageManager(filepath, options) {
10874
+ try {
10875
+ const content = await fs.readFile(filepath, "utf8");
10876
+ const pkg = options.packageJsonParser ? await options.packageJsonParser(content, filepath) : JSON.parse(content);
10877
+ let agent;
10878
+ const nameAndVer = getNameAndVer(pkg);
10879
+ if (nameAndVer) {
10880
+ const name = nameAndVer.name;
10881
+ const ver = nameAndVer.ver;
10882
+ let version = ver;
10883
+ if (name === "yarn" && ver && Number.parseInt(ver) > 1) {
10884
+ agent = "yarn@berry";
10885
+ version = "berry";
10886
+ return { name, agent, version };
10887
+ } else if (name === "pnpm" && ver && Number.parseInt(ver) < 7) {
10888
+ agent = "pnpm@6";
10889
+ return { name, agent, version };
10890
+ } else if (AGENTS.includes(name)) {
10891
+ agent = name;
10892
+ return { name, agent, version };
10893
+ } else {
10894
+ return options.onUnknown?.(pkg.packageManager) ?? null;
10895
+ }
10896
+ }
10897
+ } catch {
10898
+ }
10899
+ return null;
10900
+ }
10901
+ function isMetadataYarnClassic(metadataPath) {
10902
+ return metadataPath.endsWith(".yarn_integrity");
10903
+ }
10904
+
10571
10905
  class FetchError extends Error {
10572
10906
  constructor(message, opts) {
10573
10907
  super(message, opts);
@@ -10952,7 +11286,7 @@ async function checkForUpdateOf(name, current, nuxt = useNuxt()) {
10952
11286
  const { version: latest } = await getLatestVersion(name, {
10953
11287
  fetch
10954
11288
  });
10955
- const needsUpdate = !!latest && latest !== current && semver.lt(current, latest);
11289
+ const needsUpdate = !!latest && latest !== current && isLess(current, latest);
10956
11290
  return {
10957
11291
  name,
10958
11292
  current,
@@ -10976,19 +11310,190 @@ async function magicastGuard(fn, message = "") {
10976
11310
  return generated;
10977
11311
  }
10978
11312
 
10979
- function setupNpmRPC({ nuxt, ensureDevAuthToken }) {
10980
- let detectPromise;
10981
- const updatesPromise = /* @__PURE__ */ new Map();
10982
- function getPackageManager() {
10983
- detectPromise ||= detectPackageManager(nuxt.options.rootDir);
10984
- return detectPromise;
11313
+ function removeNuxtModuleFromCode(source, name, filepath) {
11314
+ const mod = parseModule(source, filepath ? { sourceFileName: filepath } : void 0);
11315
+ const config = getDefaultExportOptions(mod);
11316
+ if (!Array.isArray(config.modules))
11317
+ return mod.generate().code;
11318
+ for (let i = config.modules.length - 1; i >= 0; i--) {
11319
+ const entry = config.modules[i];
11320
+ const matches = typeof entry === "string" ? entry === name : Array.isArray(entry) && entry[0] === name;
11321
+ if (matches)
11322
+ config.modules.splice(i, 1);
11323
+ }
11324
+ return mod.generate().code;
11325
+ }
11326
+
11327
+ function broadcastTerminalExit(ctx, id, code) {
11328
+ ctx.devtoolsKit?.rpc.broadcast({ method: "onTerminalExit", args: [{ id, code }], event: true });
11329
+ }
11330
+ function statusForExit(code) {
11331
+ return code == null || code === 0 ? "stopped" : "error";
11332
+ }
11333
+ function setupTerminalsBridge(ctx) {
11334
+ const { nuxt } = ctx;
11335
+ const runs = /* @__PURE__ */ new Map();
11336
+ const generations = /* @__PURE__ */ new Map();
11337
+ let host;
11338
+ function createRun(terminal) {
11339
+ const legacyId = terminal.id;
11340
+ const generation = (generations.get(legacyId) ?? 0) + 1;
11341
+ generations.set(legacyId, generation);
11342
+ let controller;
11343
+ const stream = new ReadableStream({
11344
+ start(c) {
11345
+ controller = c;
11346
+ }
11347
+ });
11348
+ const session = {
11349
+ id: createUniqueSessionId(legacyId),
11350
+ title: terminal.name,
11351
+ description: terminal.description,
11352
+ icon: terminal.icon,
11353
+ status: "running",
11354
+ interactive: false,
11355
+ stream
11356
+ };
11357
+ return {
11358
+ legacyId,
11359
+ sessionId: session.id,
11360
+ generation,
11361
+ session,
11362
+ controller,
11363
+ registered: false,
11364
+ streamClosed: false,
11365
+ pendingChunks: []
11366
+ };
10985
11367
  }
10986
- async function getNpmCommand(command, packageName, options = {}) {
10987
- const {
10988
- dev = true,
10989
- global = packageName === "@nuxt/devtools" && isInstalledGlobally
10990
- } = options;
10991
- const agent = await getPackageManager();
11368
+ function isCurrent(run) {
11369
+ return runs.get(run.legacyId) === run;
11370
+ }
11371
+ function closeStream(run) {
11372
+ if (run.streamClosed)
11373
+ return;
11374
+ run.streamClosed = true;
11375
+ try {
11376
+ run.controller?.close();
11377
+ } catch {
11378
+ }
11379
+ }
11380
+ function applyExit(run, code) {
11381
+ if (!isCurrent(run) || run.streamClosed)
11382
+ return;
11383
+ closeStream(run);
11384
+ run.session.status = statusForExit(code);
11385
+ host?.update(run.session);
11386
+ }
11387
+ function registerWithHost(run) {
11388
+ if (!host || run.registered || !isCurrent(run))
11389
+ return;
11390
+ host.register(run.session);
11391
+ run.registered = true;
11392
+ for (const chunk of run.pendingChunks) {
11393
+ try {
11394
+ run.controller?.enqueue(chunk);
11395
+ } catch {
11396
+ }
11397
+ }
11398
+ run.pendingChunks.length = 0;
11399
+ if (run.pendingExit) {
11400
+ const { code } = run.pendingExit;
11401
+ run.pendingExit = void 0;
11402
+ applyExit(run, code);
11403
+ }
11404
+ }
11405
+ nuxt.hook("devtools:terminal:register", (terminal) => {
11406
+ const existing = runs.get(terminal.id);
11407
+ if (existing) {
11408
+ closeStream(existing);
11409
+ if (host && existing.registered)
11410
+ host.remove(existing.session);
11411
+ }
11412
+ const run = createRun(terminal);
11413
+ runs.set(terminal.id, run);
11414
+ if (host)
11415
+ registerWithHost(run);
11416
+ return terminal.id;
11417
+ });
11418
+ nuxt.hook("devtools:terminal:write", ({ id, data }) => {
11419
+ const run = runs.get(id);
11420
+ if (!run || run.streamClosed)
11421
+ return false;
11422
+ if (run.registered) {
11423
+ try {
11424
+ run.controller?.enqueue(data);
11425
+ } catch {
11426
+ }
11427
+ } else {
11428
+ run.pendingChunks.push(data);
11429
+ }
11430
+ return true;
11431
+ });
11432
+ nuxt.hook("devtools:terminal:exit", ({ id, code }) => {
11433
+ const run = runs.get(id);
11434
+ if (!run)
11435
+ return false;
11436
+ if (run.registered)
11437
+ applyExit(run, code);
11438
+ else
11439
+ run.pendingExit = { code };
11440
+ return true;
11441
+ });
11442
+ nuxt.hook("devtools:terminal:remove", ({ id }) => {
11443
+ const run = runs.get(id);
11444
+ if (!run)
11445
+ return false;
11446
+ closeStream(run);
11447
+ runs.delete(id);
11448
+ if (host && run.registered)
11449
+ host.remove(run.session);
11450
+ return true;
11451
+ });
11452
+ nuxt.hook("devtools:ready", (kit) => {
11453
+ host = kit.terminals;
11454
+ for (const run of runs.values())
11455
+ registerWithHost(run);
11456
+ });
11457
+ return {
11458
+ /**
11459
+ * Focus the built-in **Terminals** dock on a session (Devframe 0.7
11460
+ * `docks.activate`, driven by the `hub:docks:activate` RPC). Replaces the
11461
+ * old in-client "go to Terminals tab" navigation now that terminals live in
11462
+ * the hub dock. `id` is a unique Devframe session id (from a bridged run or
11463
+ * a `startChildProcess` call). Returns `false` when the kit isn't connected
11464
+ * or the session is unknown.
11465
+ */
11466
+ async revealTerminal(id) {
11467
+ const kit = ctx.devtoolsKit;
11468
+ if (!kit)
11469
+ return false;
11470
+ if (!kit.terminals.sessions.has(id))
11471
+ return false;
11472
+ kit.docks.activate(DEVTOOLS_TERMINALS_DOCK_ID, { sessionId: id });
11473
+ return true;
11474
+ }
11475
+ };
11476
+ }
11477
+
11478
+ function setupNpmRPC(ctx) {
11479
+ const { nuxt } = ctx;
11480
+ function getTerminals() {
11481
+ const kit = ctx.devtoolsKit;
11482
+ if (!kit)
11483
+ throw new Error("[Nuxt DevTools] Vite DevTools kit is not connected yet.");
11484
+ return kit.terminals;
11485
+ }
11486
+ let detectPromise;
11487
+ const updatesPromise = /* @__PURE__ */ new Map();
11488
+ function getPackageManager() {
11489
+ detectPromise ||= detect({ cwd: nuxt.options.rootDir });
11490
+ return detectPromise;
11491
+ }
11492
+ async function getNpmCommand(command, packageName, options = {}) {
11493
+ const {
11494
+ dev = true
11495
+ } = options;
11496
+ const agent = await getPackageManager();
10992
11497
  const name = agent?.name || "npm";
10993
11498
  if (command === "install" || command === "update") {
10994
11499
  return [
@@ -10996,7 +11501,6 @@ function setupNpmRPC({ nuxt, ensureDevAuthToken }) {
10996
11501
  name === "npm" ? "install" : "add",
10997
11502
  `${packageName}@latest`,
10998
11503
  dev ? "-D" : "",
10999
- global ? "-g" : "",
11000
11504
  // In yarn berry, `--ignore-scripts` is removed
11001
11505
  name === "yarn" && !agent?.version?.startsWith("1.") ? "" : "--ignore-scripts"
11002
11506
  ].filter(Boolean);
@@ -11005,8 +11509,7 @@ function setupNpmRPC({ nuxt, ensureDevAuthToken }) {
11005
11509
  return [
11006
11510
  name,
11007
11511
  name === "npm" ? "uninstall" : "remove",
11008
- packageName,
11009
- global ? "-g" : ""
11512
+ packageName
11010
11513
  ].filter(Boolean);
11011
11514
  }
11012
11515
  }
@@ -11014,15 +11517,18 @@ function setupNpmRPC({ nuxt, ensureDevAuthToken }) {
11014
11517
  const args = await getNpmCommand(command, packageName, options);
11015
11518
  if (!args)
11016
11519
  return;
11017
- const processId = `npm:${command}:${packageName}`;
11018
- startSubprocess({
11520
+ const processId = createUniqueSessionId(`npm:${command}:${packageName}`);
11521
+ const session = await getTerminals().startChildProcess({
11019
11522
  command: args[0],
11020
11523
  args: args.slice(1)
11021
11524
  }, {
11022
11525
  id: processId,
11023
- name: `${command} ${packageName}`,
11024
- icon: "i-logos-npm-icon",
11025
- restartable: false
11526
+ title: `${command} ${packageName}`,
11527
+ icon: "i-logos-npm-icon"
11528
+ });
11529
+ void Promise.resolve(session.getResult()).then((result) => {
11530
+ broadcastTerminalExit(ctx, processId, result.exitCode);
11531
+ }).catch(() => {
11026
11532
  });
11027
11533
  return {
11028
11534
  processId
@@ -11037,46 +11543,55 @@ function setupNpmRPC({ nuxt, ensureDevAuthToken }) {
11037
11543
  return updatesPromise.get(name);
11038
11544
  },
11039
11545
  getNpmCommand,
11040
- async runNpmCommand(token, ...args) {
11041
- await ensureDevAuthToken(token);
11546
+ async runNpmCommand(...args) {
11042
11547
  return runNpmCommand(...args);
11043
11548
  },
11044
- async installNuxtModule(token, name, dry = true) {
11045
- await ensureDevAuthToken(token);
11549
+ async installNuxtModule(name, dry = true, sessionId) {
11046
11550
  const commands = await getNpmCommand("install", name, { dev: true });
11047
11551
  const filepath = nuxt.options._nuxtConfigFile;
11048
11552
  let source = latestGenerated;
11049
- source ??= await fsp.readFile(filepath, "utf-8");
11553
+ source ??= await fs.readFile(filepath, "utf-8");
11050
11554
  const generated = await magicastGuard(async () => {
11051
11555
  const mod = parseModule(source, { sourceFileName: filepath });
11052
11556
  addNuxtModule(mod, name);
11053
11557
  return mod.generate().code;
11054
11558
  });
11055
- const processId = `nuxt:add-module:${name}`;
11559
+ const processId = sessionId ?? createUniqueSessionId(`nuxt:add-module:${name}`);
11056
11560
  if (!dry) {
11057
11561
  latestGenerated = generated;
11058
11562
  installSet.add(name);
11059
- const process = startSubprocess({
11563
+ const session = await getTerminals().startChildProcess({
11060
11564
  command: commands[0],
11061
11565
  args: commands.slice(1)
11062
11566
  }, {
11063
11567
  id: processId,
11064
- name: `Install ${name}`,
11065
- icon: "carbon:intent-request-create",
11066
- restartable: false
11568
+ title: `Install ${name}`,
11569
+ icon: "carbon:intent-request-create"
11067
11570
  });
11068
- const execa = process.getProcess();
11069
- const result = await execa;
11571
+ const result = await session.getResult();
11070
11572
  await Promise.resolve();
11071
11573
  installSet.delete(name);
11072
11574
  const code = result.exitCode;
11073
11575
  if (code !== 0) {
11074
11576
  console.error(result.stderr);
11577
+ ctx.notify({
11578
+ message: `Failed to install ${name}`,
11579
+ level: "error",
11580
+ description: `Process exited with code ${code}. Check the Install ${name} terminal for details.`,
11581
+ category: "module",
11582
+ notify: true
11583
+ });
11075
11584
  throw new Error(`[Nuxt DevTools] Failed to install module, process exited with ${code}`);
11076
11585
  }
11586
+ ctx.notify({
11587
+ message: `Installed ${name}`,
11588
+ level: "success",
11589
+ category: "module",
11590
+ notify: true
11591
+ });
11077
11592
  if (installSet.size === 0) {
11078
11593
  latestGenerated = null;
11079
- await fsp.writeFile(filepath, generated, "utf-8");
11594
+ await fs.writeFile(filepath, generated, "utf-8");
11080
11595
  }
11081
11596
  }
11082
11597
  return {
@@ -11086,43 +11601,44 @@ function setupNpmRPC({ nuxt, ensureDevAuthToken }) {
11086
11601
  processId
11087
11602
  };
11088
11603
  },
11089
- async uninstallNuxtModule(token, name, dry = true) {
11090
- await ensureDevAuthToken(token);
11604
+ async uninstallNuxtModule(name, dry = true, sessionId) {
11091
11605
  const commands = await getNpmCommand("uninstall", name);
11092
11606
  const filepath = nuxt.options._nuxtConfigFile;
11093
- const source = await fsp.readFile(filepath, "utf-8");
11607
+ const source = await fs.readFile(filepath, "utf-8");
11094
11608
  const generated = await magicastGuard(async () => {
11095
- const mod = parseModule(source, { sourceFileName: filepath });
11096
- const config = getDefaultExportOptions(mod);
11097
- config.modules ||= [];
11098
- if (config.modules.includes(name)) {
11099
- Object.values(config.modules).forEach((value, index) => {
11100
- if (value === name)
11101
- config.modules.splice(index - 1, 1);
11102
- });
11103
- }
11104
- return mod.generate().code;
11609
+ return removeNuxtModuleFromCode(source, name, filepath);
11105
11610
  });
11106
- const processId = `nuxt:remove-module:${name}`;
11611
+ const processId = sessionId ?? createUniqueSessionId(`nuxt:remove-module:${name}`);
11107
11612
  if (!dry) {
11108
- const process = startSubprocess({
11613
+ const session = await getTerminals().startChildProcess({
11109
11614
  command: commands[0],
11110
11615
  args: commands.slice(1)
11111
11616
  }, {
11112
11617
  id: processId,
11113
- name: `Uninstall ${name}`,
11114
- icon: "carbon:intent-request-uninstall",
11115
- restartable: false
11618
+ title: `Uninstall ${name}`,
11619
+ icon: "carbon:intent-request-uninstall"
11116
11620
  });
11117
- const execa = process.getProcess();
11118
- const result = await execa;
11621
+ const result = await session.getResult();
11119
11622
  await Promise.resolve();
11120
11623
  const code = result.exitCode;
11121
11624
  if (code !== 0) {
11122
11625
  console.error(result.stderr);
11626
+ ctx.notify({
11627
+ message: `Failed to uninstall ${name}`,
11628
+ level: "error",
11629
+ description: `Process exited with code ${code}. Check the Uninstall ${name} terminal for details.`,
11630
+ category: "module",
11631
+ notify: true
11632
+ });
11123
11633
  throw new Error(`[Nuxt DevTools] Failed to uninstall module, process exited with ${code}`);
11124
11634
  }
11125
- await fsp.writeFile(filepath, generated, "utf-8");
11635
+ ctx.notify({
11636
+ message: `Uninstalled ${name}`,
11637
+ level: "success",
11638
+ category: "module",
11639
+ notify: true
11640
+ });
11641
+ await fs.writeFile(filepath, generated, "utf-8");
11126
11642
  }
11127
11643
  return {
11128
11644
  configOriginal: source,
@@ -11134,112 +11650,24 @@ function setupNpmRPC({ nuxt, ensureDevAuthToken }) {
11134
11650
  };
11135
11651
  }
11136
11652
 
11137
- function setupServerDataRPC({
11138
- nuxt,
11139
- ensureDevAuthToken
11140
- }) {
11141
- let nitro;
11142
- let viteServer;
11143
- let viteClient;
11144
- function normalizeViteConfig(config) {
11145
- return {
11146
- ...config,
11147
- environments: Object.fromEntries(
11148
- Object.entries(config.env).map(([key, _]) => {
11149
- return [key, null];
11150
- })
11151
- ),
11152
- plugins: config.plugins.map((i) => {
11153
- const clone = { ...i };
11154
- delete clone.api;
11155
- return clone;
11156
- }),
11157
- inlineConfig: null
11158
- };
11159
- }
11160
- nuxt.hook("nitro:build:before", (_nitro) => {
11161
- nitro = _nitro;
11162
- });
11163
- addVitePlugin({
11164
- name: "nuxt:devtools:config",
11165
- applyToEnvironment(environment) {
11166
- if (environment.name === "ssr") {
11167
- return {
11168
- name: "nuxt:devtools:config-retriever",
11169
- enforce: "post",
11170
- configResolved(config) {
11171
- viteServer = normalizeViteConfig(config);
11172
- }
11173
- };
11174
- }
11175
- if (environment.name === "client") {
11176
- return {
11177
- name: "nuxt:devtools:config-retriever",
11178
- enforce: "post",
11179
- configResolved(config) {
11180
- viteClient = normalizeViteConfig(config);
11181
- }
11182
- };
11183
- }
11184
- }
11185
- });
11186
- return {
11187
- getServerConfig() {
11188
- return nuxt.options;
11189
- },
11190
- async getServerData(token) {
11191
- await ensureDevAuthToken(token);
11192
- return {
11193
- nuxt: nuxt.options,
11194
- nitro: nitro?.options,
11195
- vite: {
11196
- server: viteServer,
11197
- client: viteClient
11198
- }
11199
- };
11200
- }
11201
- };
11202
- }
11203
-
11204
- async function watchStorageMount(storage, mountName, onChange) {
11205
- const mountKey = normalizeBaseKey(mountName);
11206
- const mount = storage.getMount(mountKey);
11207
- if (!mount || normalizeBaseKey(mount.base) !== mountKey || !mount.driver?.watch)
11208
- return () => {
11209
- };
11210
- const unwatch = await mount.driver.watch((event, key) => {
11211
- const fullKey = key.startsWith(mountKey) ? key : `${mountKey}${key}`;
11212
- onChange(event, normalizeKey(fullKey));
11213
- });
11214
- return unwatch ?? (() => {
11215
- });
11216
- }
11217
-
11218
11653
  function setupServerRoutesRPC({ nuxt, refresh }) {
11219
11654
  let nitro;
11220
- let unwatchStorage;
11655
+ let unhookDevReload;
11221
11656
  let cache = null;
11222
11657
  const refreshDebounced = debounce(() => {
11223
11658
  cache = null;
11224
11659
  refresh("getServerRoutes");
11225
11660
  }, 500);
11226
- nuxt.hook("nitro:init", (_) => {
11227
- nitro = _;
11661
+ nuxt.hook("nitro:init", (_nitro) => {
11662
+ nitro = _nitro;
11228
11663
  cache = null;
11229
11664
  refresh("getServerRoutes");
11665
+ unhookDevReload?.();
11666
+ unhookDevReload = _nitro.hooks.hook("dev:reload", () => refreshDebounced());
11230
11667
  });
11231
- nuxt.hook("ready", async () => {
11232
- if (!nitro)
11233
- return;
11234
- await unwatchStorage?.();
11235
- unwatchStorage = await watchStorageMount(nitro.storage, "src", (_event, key) => {
11236
- if (key.startsWith("src:api:") || key.startsWith("src:routes:"))
11237
- refreshDebounced();
11238
- });
11239
- });
11240
- nuxt.hook("close", async () => {
11241
- await unwatchStorage?.();
11242
- unwatchStorage = void 0;
11668
+ nuxt.hook("close", () => {
11669
+ unhookDevReload?.();
11670
+ unhookDevReload = void 0;
11243
11671
  });
11244
11672
  function scan() {
11245
11673
  if (cache)
@@ -11273,29 +11701,22 @@ function setupServerRoutesRPC({ nuxt, refresh }) {
11273
11701
 
11274
11702
  function setupServerTasksRPC({ nuxt, refresh }) {
11275
11703
  let nitro;
11276
- let unwatchStorage;
11704
+ let unhookDevReload;
11277
11705
  let cache = null;
11278
11706
  const refreshDebounced = debounce(() => {
11279
11707
  cache = null;
11280
11708
  refresh("getServerTasks");
11281
11709
  }, 500);
11282
- nuxt.hook("nitro:init", (_) => {
11283
- nitro = _;
11710
+ nuxt.hook("nitro:init", (_nitro) => {
11711
+ nitro = _nitro;
11284
11712
  cache = null;
11285
11713
  refresh("getServerTasks");
11714
+ unhookDevReload?.();
11715
+ unhookDevReload = _nitro.hooks.hook("dev:reload", () => refreshDebounced());
11286
11716
  });
11287
- nuxt.hook("ready", async () => {
11288
- if (!nitro)
11289
- return;
11290
- await unwatchStorage?.();
11291
- unwatchStorage = await watchStorageMount(nitro.storage, "src", (_event, key) => {
11292
- if (key.startsWith("src:tasks:"))
11293
- refreshDebounced();
11294
- });
11295
- });
11296
- nuxt.hook("close", async () => {
11297
- await unwatchStorage?.();
11298
- unwatchStorage = void 0;
11717
+ nuxt.hook("close", () => {
11718
+ unhookDevReload?.();
11719
+ unhookDevReload = void 0;
11299
11720
  });
11300
11721
  function scan() {
11301
11722
  if (cache)
@@ -11308,7 +11729,15 @@ function setupServerTasksRPC({ nuxt, refresh }) {
11308
11729
  };
11309
11730
  }
11310
11731
  return {
11311
- tasks: nitro.options.tasks,
11732
+ // Nitro v3's task config types `handler`/`description` as optional
11733
+ // (they're always populated in practice by Nitro's own task scanner),
11734
+ // so normalize with fallbacks to satisfy `ScannedNitroTasks`.
11735
+ tasks: Object.fromEntries(
11736
+ Object.entries(nitro.options.tasks ?? {}).map(([name, task]) => [
11737
+ name,
11738
+ { handler: task.handler ?? "", description: task.description ?? "" }
11739
+ ])
11740
+ ),
11312
11741
  scheduledTasks: Object.entries(nitro.options.scheduledTasks ?? {}).reduce((acc, [cron, tasks]) => {
11313
11742
  acc[cron] = Array.isArray(tasks) ? tasks : [tasks];
11314
11743
  return acc;
@@ -11324,24 +11753,53 @@ function setupServerTasksRPC({ nuxt, refresh }) {
11324
11753
  };
11325
11754
  }
11326
11755
 
11756
+ function skipInSSR(ctx) {
11757
+ return Boolean(ctx?.viteConfig?.build?.ssr);
11758
+ }
11759
+
11760
+ async function watchStorageMount(storage, mountName, onChange) {
11761
+ const mountKey = normalizeBaseKey(mountName);
11762
+ const mount = storage.getMount(mountKey);
11763
+ if (!mount || normalizeBaseKey(mount.base) !== mountKey || !mount.driver?.watch)
11764
+ return () => {
11765
+ };
11766
+ const unwatch = await mount.driver.watch((event, key) => {
11767
+ const fullKey = key.startsWith(mountKey) ? key : `${mountKey}${key}`;
11768
+ onChange(event, normalizeKey(fullKey));
11769
+ });
11770
+ return unwatch ?? (() => {
11771
+ });
11772
+ }
11773
+
11327
11774
  const IGNORE_STORAGE_MOUNTS = ["root", "build", "src", "cache"];
11328
11775
  function shouldIgnoreStorageKey(key) {
11329
11776
  return IGNORE_STORAGE_MOUNTS.includes(key.split(":")[0]);
11330
11777
  }
11331
- function setupStorageRPC({
11332
- nuxt,
11333
- rpc,
11334
- ensureDevAuthToken
11335
- }) {
11778
+ function setupStorageRPC(ctx) {
11779
+ const { nuxt } = ctx;
11336
11780
  const storageMounts = {};
11337
11781
  let storage;
11338
11782
  let unwatchStorageMounts = [];
11339
- nuxt.hook("nitro:init", (nitro) => {
11340
- storage = nitro.storage;
11783
+ nuxt.hook("nitro:init", async (nitro) => {
11341
11784
  const mounts = {
11342
11785
  ...nitro.options.storage,
11343
11786
  ...nitro.options.devStorage
11344
11787
  };
11788
+ const nextStorage = createStorage();
11789
+ for (const [path, opts] of Object.entries(mounts)) {
11790
+ if (!opts?.driver) {
11791
+ nitro.logger.warn(`No \`driver\` set for storage mount point "${path}".`);
11792
+ continue;
11793
+ }
11794
+ try {
11795
+ const driverImport = builtinDrivers[opts.driver] || opts.driver;
11796
+ const driverFactory = await import(driverImport).then((r) => r.default || r);
11797
+ nextStorage.mount(path, driverFactory(opts));
11798
+ } catch (err) {
11799
+ nitro.logger.warn(`Failed to mount storage driver "${opts.driver}" for the DevTools storage browser:`, err);
11800
+ }
11801
+ }
11802
+ storage = nextStorage;
11345
11803
  for (const key of Object.keys(storageMounts))
11346
11804
  delete storageMounts[key];
11347
11805
  for (const name of Object.keys(mounts)) {
@@ -11356,7 +11814,7 @@ function setupStorageRPC({
11356
11814
  return;
11357
11815
  await Promise.all(unwatchStorageMounts.map((unwatch) => unwatch()));
11358
11816
  unwatchStorageMounts = await Promise.all(Object.keys(storageMounts).map((mountName) => watchStorageMount(activeStorage, mountName, (event, key) => {
11359
- rpc.broadcast.callHook.asEvent("storage:key:update", key, event);
11817
+ ctx.devtoolsKit?.rpc.broadcast({ method: "callHook", args: ["storage:key:update", key, event], event: true });
11360
11818
  })));
11361
11819
  });
11362
11820
  nuxt.hook("close", async () => {
@@ -11378,20 +11836,17 @@ function setupStorageRPC({
11378
11836
  return [];
11379
11837
  }
11380
11838
  },
11381
- async getStorageItem(token, key) {
11382
- await ensureDevAuthToken(token);
11839
+ async getStorageItem(key) {
11383
11840
  if (!storage)
11384
11841
  return null;
11385
11842
  return await storage.getItem(key);
11386
11843
  },
11387
- async setStorageItem(token, key, value) {
11388
- await ensureDevAuthToken(token);
11844
+ async setStorageItem(key, value) {
11389
11845
  if (!storage)
11390
11846
  return;
11391
11847
  return await storage.setItem(key, value);
11392
11848
  },
11393
- async removeStorageItem(token, key) {
11394
- await ensureDevAuthToken(token);
11849
+ async removeStorageItem(key) {
11395
11850
  if (!storage)
11396
11851
  return;
11397
11852
  return await storage.removeItem(key);
@@ -11447,97 +11902,11 @@ function telemetryEvent(payload, immediate = false) {
11447
11902
  throttledSend();
11448
11903
  }
11449
11904
 
11450
- function setupTerminalRPC({ nuxt, rpc, refresh, ensureDevAuthToken }) {
11451
- const terminals = /* @__PURE__ */ new Map();
11452
- nuxt.hook("devtools:terminal:register", (terminal) => {
11453
- terminals.set(terminal.id, terminal);
11454
- refresh("getTerminals");
11455
- return terminal.id;
11456
- });
11457
- nuxt.hook("devtools:terminal:remove", ({ id }) => {
11458
- if (!terminals.has(id))
11459
- return false;
11460
- terminals.delete(id);
11461
- refresh("getTerminals");
11462
- return true;
11463
- });
11464
- nuxt.hook("devtools:terminal:write", ({ id, data }) => {
11465
- const terminal = terminals.get(id);
11466
- if (!terminal)
11467
- return false;
11468
- terminal.buffer ||= "";
11469
- terminal.buffer += data;
11470
- rpc.broadcast.onTerminalData.asEvent({ id, data });
11471
- return true;
11472
- });
11473
- nuxt.hook("devtools:terminal:exit", ({ id, code }) => {
11474
- const terminal = terminals.get(id);
11475
- if (!terminal)
11476
- return false;
11477
- terminal.isTerminated = true;
11478
- rpc.broadcast.onTerminalExit.asEvent({ id, code });
11479
- refresh("getTerminals");
11480
- return true;
11481
- });
11482
- function serializeTerminal(terminal, buffer = false) {
11483
- if (!terminal)
11484
- return;
11485
- return {
11486
- id: terminal.id,
11487
- name: terminal.name,
11488
- description: terminal.description,
11489
- icon: terminal.icon,
11490
- terminatable: terminal.terminatable ?? !!terminal.onActionTerminate,
11491
- restartable: terminal.restartable ?? !!terminal.onActionRestart,
11492
- isTerminated: terminal.isTerminated,
11493
- buffer: buffer ? terminal.buffer : void 0
11494
- };
11495
- }
11905
+ function setupTimelineRPC({ nuxt }) {
11496
11906
  return {
11497
- getTerminals() {
11498
- return Array.from(terminals.values(), (i) => serializeTerminal(i));
11499
- },
11500
- async getTerminalDetail(token, id) {
11501
- await ensureDevAuthToken(token);
11502
- return serializeTerminal(terminals.get(id), true);
11503
- },
11504
- async runTerminalAction(token, id, action) {
11505
- await ensureDevAuthToken(token);
11506
- const terminal = terminals.get(id);
11507
- if (!terminal)
11508
- return false;
11509
- switch (action) {
11510
- case "restart":
11511
- if (!terminal.onActionRestart)
11512
- return false;
11513
- await terminal.onActionRestart();
11514
- return true;
11515
- case "terminate":
11516
- if (!terminal.onActionTerminate)
11517
- return false;
11518
- await terminal.onActionTerminate();
11519
- return true;
11520
- case "remove":
11521
- if (!terminal.isTerminated)
11522
- terminal.onActionTerminate?.();
11523
- terminals.delete(id);
11524
- refresh("getTerminals");
11525
- return true;
11526
- case "clear":
11527
- terminal.buffer = "";
11528
- refresh("getTerminals");
11529
- return true;
11530
- }
11531
- }
11532
- };
11533
- }
11534
-
11535
- function setupTimelineRPC({ nuxt, ensureDevAuthToken }) {
11536
- return {
11537
- async enableTimeline(token, dry) {
11538
- await ensureDevAuthToken(token);
11907
+ async enableTimeline(dry) {
11539
11908
  const filepath = nuxt.options._nuxtConfigFile;
11540
- const source = await fsp.readFile(filepath, "utf-8");
11909
+ const source = await fs.readFile(filepath, "utf-8");
11541
11910
  const generated = await magicastGuard(async () => {
11542
11911
  const mod = parseModule(source, { sourceFileName: filepath });
11543
11912
  const options = getDefaultExportOptions(mod);
@@ -11547,7 +11916,7 @@ function setupTimelineRPC({ nuxt, ensureDevAuthToken }) {
11547
11916
  return mod.generate().code;
11548
11917
  }, "\nYou can enable timeline manually by adding `devtools: { timeline: { enabled: true } }`");
11549
11918
  if (!dry) {
11550
- await fsp.writeFile(filepath, generated, "utf-8");
11919
+ await fs.writeFile(filepath, generated, "utf-8");
11551
11920
  await nuxt.callHook("restart", { hard: true });
11552
11921
  }
11553
11922
  return [source, generated];
@@ -11555,181 +11924,158 @@ function setupTimelineRPC({ nuxt, ensureDevAuthToken }) {
11555
11924
  };
11556
11925
  }
11557
11926
 
11558
- const LOG_PREFIX = colors.cyan("Nuxt DevTools:");
11559
-
11560
- const NUXT_WELCOME_RE = /<NuxtWelcome\s*\/>/;
11561
- const pagesIndexTemplate = `<script setup lang="ts">
11562
- const route = useRoute()
11563
- <\/script>
11564
-
11565
- <template>
11566
- <div>
11567
- <h1>Nuxt Routing set up successfully!</h1>
11568
- <p>Current route: {{ route.path }}</p>
11569
- <a href="https://nuxt.com/docs/getting-started/routing" target="_blank">Learn more about Nuxt Routing</a>
11570
- </div>
11571
- </template>
11572
- `;
11573
- async function enablePages(nuxt) {
11574
- const baseDir = nuxt.options.future.compatibilityVersion === 4 ? nuxt.options.dir.app : nuxt.options.srcDir;
11575
- const pathApp = join(baseDir, "app.vue");
11576
- const pathPageIndex = join(baseDir, "pages/index.vue");
11577
- if (fs.existsSync(pathPageIndex)) {
11578
- logger.warn("pages/index.vue already exists, skipping");
11579
- return;
11580
- }
11581
- let appContent = fs.existsSync(pathApp) ? await fsp.readFile(pathApp, "utf-8") : void 0;
11582
- await fsp.mkdir(dirname$1(pathPageIndex), { recursive: true });
11583
- await fsp.writeFile(pathPageIndex, pagesIndexTemplate, "utf-8");
11584
- if (appContent && !appContent.includes("<NuxtPage")) {
11585
- appContent = appContent.replace("</template>", " <NuxtPage />\n</template>").replace(NUXT_WELCOME_RE, "");
11586
- await fsp.writeFile(pathApp, appContent, "utf-8");
11587
- }
11588
- logger.success("Routing creation wizard completed");
11589
- }
11590
-
11591
- const wizard = {
11592
- enablePages
11593
- };
11594
-
11595
- function setupWizardRPC({ nuxt, ensureDevAuthToken }) {
11596
- return {
11597
- async runWizard(token, name, ...args) {
11598
- await ensureDevAuthToken(token);
11599
- logger.info(LOG_PREFIX, `Running wizard ${colors.green(name)}...`);
11600
- return wizard[name](nuxt, ...args);
11601
- }
11602
- };
11603
- }
11604
-
11605
11927
  function setupRPC(nuxt, options) {
11606
11928
  const serverFunctions = {};
11607
11929
  const extendedRpcMap = /* @__PURE__ */ new Map();
11608
- const rpc = createBirpcGroup(
11609
- serverFunctions,
11610
- [],
11611
- {
11612
- resolver: (name, fn) => {
11613
- if (fn)
11614
- return fn;
11615
- if (!name.includes(":"))
11930
+ let devtoolsKitCtx;
11931
+ const pendingBroadcasts = [];
11932
+ function broadcast(method, ...args) {
11933
+ if (!devtoolsKitCtx) {
11934
+ pendingBroadcasts.push({ method, args });
11935
+ return;
11936
+ }
11937
+ devtoolsKitCtx.rpc.broadcast({
11938
+ method,
11939
+ args,
11940
+ event: true
11941
+ });
11942
+ }
11943
+ function createBroadcastProxy(prefix = "") {
11944
+ return new Proxy({}, {
11945
+ get: (_, method) => {
11946
+ if (typeof method !== "string")
11616
11947
  return;
11617
- const [namespace, fnName] = name.split(":");
11618
- return extendedRpcMap.get(namespace)?.[fnName];
11619
- },
11620
- onFunctionError(error, name) {
11621
- logger.error(
11622
- colors.yellow(`[nuxt-devtools] RPC error on executing "${colors.bold(name)}":
11623
- `) + colors.red(error?.message || "")
11624
- );
11625
- },
11626
- // A malformed or hostile frame over the (unauthenticated) HMR socket can
11627
- // make deserialization throw. Swallow it here so a bad frame is dropped
11628
- // rather than surfacing as an unhandled rejection that crashes dev.
11629
- onGeneralError(error) {
11630
- logger.error(
11631
- colors.yellow("[nuxt-devtools] RPC channel error:\n") + colors.red(error?.message || String(error))
11632
- );
11633
- return true;
11634
- },
11635
- timeout: 12e4
11948
+ const fullMethod = prefix ? `${prefix}:${method}` : method;
11949
+ const fn = (...args) => broadcast(fullMethod, ...args);
11950
+ fn.asEvent = (...args) => broadcast(fullMethod, ...args);
11951
+ return fn;
11952
+ }
11953
+ });
11954
+ }
11955
+ const functionsProxy = new Proxy(serverFunctions, {
11956
+ set(target, prop, value) {
11957
+ target[prop] = value;
11958
+ if (devtoolsKitCtx && typeof prop === "string") {
11959
+ if (devtoolsKitCtx.rpc.has(prop)) {
11960
+ devtoolsKitCtx.rpc.update({ name: prop, handler: value });
11961
+ } else {
11962
+ devtoolsKitCtx.rpc.register({ name: prop, handler: value });
11963
+ }
11964
+ }
11965
+ return true;
11636
11966
  }
11637
- );
11967
+ });
11968
+ const rpc = new Proxy({
11969
+ broadcast: createBroadcastProxy(),
11970
+ functions: functionsProxy
11971
+ }, {
11972
+ get(target, prop, receiver) {
11973
+ if (prop === "broadcast" || prop === "functions") {
11974
+ deprecate(nuxt, "NDT_DEP_0007", {
11975
+ api: `nuxt.devtools.rpc.${prop}`,
11976
+ replacement: "the connected ctx.rpc from onDevtoolsReady((ctx) => ...)"
11977
+ }, { key: prop });
11978
+ }
11979
+ return Reflect.get(target, prop, receiver);
11980
+ }
11981
+ });
11638
11982
  function refresh(event) {
11639
- rpc.broadcast.refresh.asEvent(event);
11983
+ broadcast("refresh", event);
11640
11984
  }
11985
+ const notify = createNotifier(nuxt);
11641
11986
  function extendServerRpc(namespace, functions) {
11987
+ deprecate(nuxt, "NDT_DEP_0003", {
11988
+ api: "extendServerRpc",
11989
+ replacement: "onDevtoolsReady((ctx) => ctx.rpc.register(defineRpcFunction(...)))"
11990
+ }, { key: namespace });
11642
11991
  extendedRpcMap.set(namespace, functions);
11643
- return {
11644
- broadcast: new Proxy({}, {
11645
- get: (_, key) => {
11646
- if (typeof key !== "string")
11647
- return;
11648
- return rpc.broadcast[`${namespace}:${key}`];
11992
+ if (devtoolsKitCtx) {
11993
+ for (const [fnName, handler] of Object.entries(functions)) {
11994
+ if (typeof handler === "function") {
11995
+ devtoolsKitCtx.rpc.register({ name: `${namespace}:${fnName}`, handler });
11649
11996
  }
11650
- })
11997
+ }
11998
+ }
11999
+ return {
12000
+ broadcast: createBroadcastProxy(namespace),
12001
+ functions,
12002
+ clients: [],
12003
+ updateChannels: () => []
11651
12004
  };
11652
12005
  }
11653
12006
  const ctx = {
11654
12007
  nuxt,
11655
12008
  options,
11656
12009
  rpc,
12010
+ get devtoolsKit() {
12011
+ return devtoolsKitCtx;
12012
+ },
11657
12013
  refresh,
12014
+ notify,
11658
12015
  extendServerRpc,
11659
- openInEditorHooks: [],
11660
- async ensureDevAuthToken(token) {
11661
- if (options.disableAuthorization)
11662
- return;
11663
- if (token !== await getDevAuthToken())
11664
- throw new Error("[Nuxt DevTools] Invalid dev auth token.");
11665
- }
12016
+ openInEditorHooks: []
11666
12017
  };
11667
12018
  nuxt.devtools = ctx;
11668
12019
  Object.assign(serverFunctions, {
11669
12020
  ...setupGeneralRPC(ctx),
12021
+ ...setupMessagesRPC(ctx),
11670
12022
  ...setupCustomTabRPC(ctx),
11671
12023
  ...setupStorageRPC(ctx),
11672
12024
  ...setupAssetsRPC(ctx),
11673
12025
  ...setupNpmRPC(ctx),
11674
- ...setupWizardRPC(ctx),
11675
- ...setupTerminalRPC(ctx),
12026
+ // Bridge the `devtools:terminal:*` hooks onto the Vite DevTools terminals
12027
+ // host so module terminals surface in the built-in Terminals dock. Also
12028
+ // registers its own hook listeners (including `devtools:ready`) as a side
12029
+ // effect, and contributes the `revealTerminal` RPC.
12030
+ ...setupTerminalsBridge(ctx),
11676
12031
  ...setupServerRoutesRPC(ctx),
11677
12032
  ...setupServerTasksRPC(ctx),
11678
12033
  ...setupAnalyzeBuildRPC(ctx),
11679
12034
  ...setupOptionsRPC(ctx),
11680
12035
  ...setupTimelineRPC(ctx),
11681
12036
  ...setupTelemetryRPC(ctx),
11682
- ...setupServerDataRPC(ctx)
12037
+ // Deprecated compat shim (NDT_DEP_0009). The capture + live source now live
12038
+ // in the Data Inspector integration; `getServerConfig` is served by the
12039
+ // canonical `setupGeneralRPC` above.
12040
+ getServerData: async () => getServerData(nuxt)
11683
12041
  });
11684
- const wsClients = /* @__PURE__ */ new Set();
11685
- const vitePlugin = {
11686
- name: "nuxt:devtools:rpc",
11687
- configureServer(server) {
11688
- server.ws.on("connection", (ws, request) => {
11689
- if (!isAllowedRpcOrigin(request?.headers?.origin, request?.headers?.host)) {
11690
- logger.warn(
11691
- colors.yellow(`[nuxt-devtools] Ignored a cross-origin RPC connection from origin "${request?.headers?.origin}".`)
11692
- );
11693
- return;
11694
- }
11695
- wsClients.add(ws);
11696
- const channel = {
11697
- post: (d) => ws.send(JSON.stringify({
11698
- type: "custom",
11699
- event: WS_EVENT_NAME,
11700
- data: d
11701
- })),
11702
- on: (fn) => {
11703
- ws.on("message", (e) => {
11704
- try {
11705
- const data = JSON.parse(String(e)) || {};
11706
- if (data.type === "custom" && data.event === WS_EVENT_NAME) {
11707
- fn(data.data);
11708
- }
11709
- } catch {
11710
- }
11711
- });
11712
- },
11713
- serialize: stringify,
11714
- deserialize: parse$1
11715
- };
11716
- rpc.updateChannels((c) => {
11717
- c.push(channel);
11718
- });
11719
- ws.on("close", () => {
11720
- wsClients.delete(ws);
11721
- rpc.updateChannels((c) => {
11722
- const index = c.indexOf(channel);
11723
- if (index >= 0)
11724
- c.splice(index, 1);
11725
- });
11726
- });
11727
- });
12042
+ async function connectDevToolsKit(kitCtx) {
12043
+ if (devtoolsKitCtx || skipInSSR(kitCtx))
12044
+ return;
12045
+ devtoolsKitCtx = kitCtx;
12046
+ const host = kitCtx.rpc;
12047
+ for (const { method, args } of pendingBroadcasts) {
12048
+ broadcast(method, ...args);
12049
+ }
12050
+ pendingBroadcasts.length = 0;
12051
+ registerHostDiagnostics(ctx);
12052
+ function registerFn(name, handler) {
12053
+ try {
12054
+ host.register({ name, handler });
12055
+ } catch (e) {
12056
+ logger.warn(
12057
+ colors.yellow(`[nuxt-devtools] Failed to register RPC function "${name}":
12058
+ `) + colors.red(e?.message || "")
12059
+ );
12060
+ }
11728
12061
  }
11729
- };
12062
+ for (const [name, handler] of Object.entries(serverFunctions)) {
12063
+ if (typeof handler !== "function")
12064
+ continue;
12065
+ registerFn(`${RPC_NAMESPACE}:${name}`, handler);
12066
+ registerFn(name, handler);
12067
+ }
12068
+ for (const [namespace, fns] of extendedRpcMap) {
12069
+ for (const [fnName, handler] of Object.entries(fns)) {
12070
+ if (typeof handler === "function")
12071
+ registerFn(`${namespace}:${fnName}`, handler);
12072
+ }
12073
+ }
12074
+ await nuxt.callHook("devtools:ready", kitCtx);
12075
+ }
11730
12076
  return {
11731
- vitePlugin,
11732
- ...ctx
12077
+ connectDevToolsKit,
12078
+ ctx
11733
12079
  };
11734
12080
  }
11735
12081
 
@@ -11747,8 +12093,14 @@ async function enableModule(options, nuxt) {
11747
12093
  await import('./analyze-build.mjs').then(({ setup }) => setup(nuxt, options));
11748
12094
  return;
11749
12095
  }
11750
- const enabledExplicitly = nuxt.options.devtools === true || nuxt.options.devtools && nuxt.options.devtools.enabled || nuxt.options.modules.some((m) => m === "@nuxt/devtools" || m === "@nuxt/devtools-edge" || m === "@nuxt/devtools-nightly");
11751
12096
  await nuxt.callHook("devtools:before");
12097
+ if (options.disableAuthorization) {
12098
+ extendViteConfig((config) => {
12099
+ const devtoolsConfig = config.devtools ||= {};
12100
+ if (devtoolsConfig.clientAuth === void 0)
12101
+ devtoolsConfig.clientAuth = false;
12102
+ });
12103
+ }
11752
12104
  if (options.iframeProps) {
11753
12105
  nuxt.options.runtimeConfig.app.devtools ||= {};
11754
12106
  nuxt.options.runtimeConfig.app.devtools.iframeProps = options.iframeProps;
@@ -11762,39 +12114,68 @@ async function enableModule(options, nuxt) {
11762
12114
  src: join(runtimeDir, "plugins/devtools.server"),
11763
12115
  mode: "server"
11764
12116
  });
11765
- if (options.viteDevTools) {
11766
- logger.info("[nuxt-devtools] Enabling experimental Vite DevTools integration");
11767
- const DevTools = await import('@vitejs/devtools').then((r) => r.DevTools());
11768
- addVitePlugin(DevTools);
11769
- addVitePlugin(defineViteDevToolsPlugin({
11770
- name: "nuxt:devtools",
11771
- devtools: {
11772
- setup(ctx2) {
12117
+ if (nuxt.options.dev) {
12118
+ nuxt.options.vite.optimizeDeps ||= {};
12119
+ nuxt.options.vite.optimizeDeps.include ||= [];
12120
+ nuxt.options.vite.optimizeDeps.include.push(
12121
+ "nuxt > @nuxt/devtools > @vitejs/devtools/client/inject",
12122
+ "nuxt > @nuxt/devtools > @vitejs/devtools-kit/client",
12123
+ "nuxt > @nuxt/devtools > error-stack-parser-es",
12124
+ "nuxt > @nuxt/devtools > vite-plugin-vue-tracer/client/overlay"
12125
+ );
12126
+ }
12127
+ const DevTools = await import('@vitejs/devtools').then((r) => r.DevTools());
12128
+ addVitePlugin(DevTools);
12129
+ let connectDevToolsKit;
12130
+ addVitePlugin(defineViteDevToolsPlugin({
12131
+ name: "nuxt:devtools",
12132
+ devtools: {
12133
+ async setup(ctx2) {
12134
+ if (!skipInSSR(ctx2)) {
12135
+ ctx2.docks.register({
12136
+ id: NUXT_DEVTOOLS_GROUP_ID,
12137
+ type: "group",
12138
+ title: "Nuxt",
12139
+ icon: "/__nuxt_devtools__/client/nuxt.svg",
12140
+ category: "framework",
12141
+ defaultOrder: -2e3,
12142
+ defaultChildId: "nuxt:devtools",
12143
+ categoryOrder: {
12144
+ pinned: 0,
12145
+ app: 1,
12146
+ analyze: 2,
12147
+ server: 3,
12148
+ modules: 4,
12149
+ documentation: 5,
12150
+ advanced: 6
12151
+ }
12152
+ });
11773
12153
  ctx2.docks.register({
11774
12154
  id: "nuxt:devtools",
11775
12155
  type: "iframe",
11776
- icon: "https://nuxt.com/assets/design-kit/icon-green.svg",
11777
12156
  title: "Nuxt DevTools",
11778
- url: "/__nuxt_devtools__/client/"
12157
+ icon: "/__nuxt_devtools__/client/nuxt.svg",
12158
+ url: "/__nuxt_devtools__/client/",
12159
+ groupId: NUXT_DEVTOOLS_GROUP_ID,
12160
+ frameId: "nuxt:devtools",
12161
+ subTabs: { protocol: "postmessage" },
12162
+ visibility: "false",
12163
+ defaultOrder: -300
11779
12164
  });
11780
12165
  }
12166
+ await connectDevToolsKit?.(ctx2);
11781
12167
  }
11782
- }));
11783
- addPlugin({
11784
- src: join(runtimeDir, "plugins/vite-devtools.client"),
11785
- mode: "client"
11786
- });
11787
- }
12168
+ }
12169
+ }));
12170
+ addPlugin({
12171
+ src: join(runtimeDir, "plugins/vite-devtools.client"),
12172
+ mode: "client"
12173
+ });
11788
12174
  addTemplate({
11789
12175
  filename: "devtools/settings.mjs",
11790
12176
  async getContents() {
11791
12177
  const uiOptions = await readLocalOptions(
11792
- {
11793
- ...defaultTabOptions.ui,
11794
- // When not enabled explicitly, we hide the panel by default
11795
- // When Vite DevTools is enabled, we hide the panel by default
11796
- showPanel: options.viteDevTools ? false : enabledExplicitly ? true : null
11797
- },
12178
+ createDefaultTabOptions().ui,
11798
12179
  { root: nuxt.options.rootDir }
11799
12180
  );
11800
12181
  return `export default ${JSON.stringify({
@@ -11804,10 +12185,18 @@ async function enableModule(options, nuxt) {
11804
12185
  });
11805
12186
  nuxt.hook("nitro:config", (config) => {
11806
12187
  if (config.experimental?.tasks)
11807
- defaultTabOptions.serverTasks.enabled = true;
11808
- config.externals = config.externals || {};
11809
- config.externals.inline = config.externals.inline || [];
11810
- config.externals.inline.push(join(runtimeDir, "nitro"));
12188
+ setServerTasksEnabledByDefault(true);
12189
+ const inlinePath = join(runtimeDir, "nitro");
12190
+ if ("externals" in config) {
12191
+ config.externals ||= {};
12192
+ config.externals.inline ||= [];
12193
+ config.externals.inline.push(inlinePath);
12194
+ }
12195
+ if ("noExternals" in config && Array.isArray(config.noExternals)) {
12196
+ config.noExternals.push(inlinePath);
12197
+ } else if (!("noExternals" in config) || config.noExternals === void 0) {
12198
+ config.noExternals = [inlinePath];
12199
+ }
11811
12200
  config.virtual = config.virtual || {};
11812
12201
  config.virtual["#nuxt-devtools-inline"] = `export const script = \`
11813
12202
  if (!window.__NUXT_DEVTOOLS_TIME_METRIC__) {
@@ -11823,10 +12212,10 @@ window.__NUXT_DEVTOOLS_TIME_METRIC__.appInit = Date.now()
11823
12212
  config.plugins.unshift(join(runtimeDir, "nitro/inline"));
11824
12213
  });
11825
12214
  const {
11826
- vitePlugin,
11827
- ...ctx
12215
+ connectDevToolsKit: _connectDevToolsKit,
12216
+ ctx
11828
12217
  } = setupRPC(nuxt, options);
11829
- addVitePlugin(vitePlugin);
12218
+ connectDevToolsKit = _connectDevToolsKit;
11830
12219
  const clientDirExists = existsSync(clientDir);
11831
12220
  extendViteConfig((config) => {
11832
12221
  config.server ||= {};
@@ -11848,15 +12237,13 @@ window.__NUXT_DEVTOOLS_TIME_METRIC__.appInit = Date.now()
11848
12237
  });
11849
12238
  const ROUTE_PATH = `${nuxt.options.app.baseURL || "/"}/__nuxt_devtools__`.replace(MULTIPLE_SLASHES_RE, "/");
11850
12239
  const ROUTE_CLIENT = `${ROUTE_PATH}/client`;
11851
- const ROUTE_AUTH = `${ROUTE_PATH}/auth`;
11852
- const ROUTE_AUTH_VERIFY = `${ROUTE_PATH}/auth-verify`;
11853
12240
  const ROUTE_ANALYZE = `${ROUTE_PATH}/analyze`;
11854
12241
  nuxt.hook("vite:serverCreated", (server) => {
11855
12242
  const devtoolsAnalyzeDir = join(nuxt.options.rootDir, "node_modules/.cache/nuxt-devtools/analyze");
11856
12243
  server.middlewares.use(ROUTE_ANALYZE, sirv(devtoolsAnalyzeDir, { single: false, dev: true, dotfiles: true, ignores: false }));
11857
12244
  if (clientDirExists) {
11858
12245
  const indexHtmlPath = join(clientDir, "index.html");
11859
- const indexContent = fsp.readFile(indexHtmlPath, "utf-8");
12246
+ const indexContent = fs.readFile(indexHtmlPath, "utf-8");
11860
12247
  const handleStatic = sirv(clientDir, {
11861
12248
  dev: true,
11862
12249
  single: false
@@ -11868,49 +12255,27 @@ window.__NUXT_DEVTOOLS_TIME_METRIC__.appInit = Date.now()
11868
12255
  res.end();
11869
12256
  };
11870
12257
  server.middlewares.use(ROUTE_CLIENT, (req, res) => {
11871
- if (req.url === "/")
12258
+ const pathname = (req.url || "/").split("?")[0];
12259
+ if (pathname === "/" || pathname === "")
11872
12260
  return handleIndex(res);
11873
12261
  return handleStatic(req, res, () => handleIndex(res));
11874
12262
  });
11875
12263
  }
11876
- server.middlewares.use(ROUTE_AUTH, sirv(join(runtimeDir, "auth"), { single: true, dev: true }));
11877
- server.middlewares.use(ROUTE_AUTH_VERIFY, async (req, res) => {
11878
- const search = req.url?.split("?")[1];
11879
- if (!search) {
11880
- res.statusCode = 400;
11881
- res.end("No token provided");
11882
- }
11883
- const query = new URLSearchParams(search);
11884
- const token = query.get("token");
11885
- if (!token) {
11886
- res.statusCode = 400;
11887
- res.end("No token provided");
11888
- }
11889
- if (token === await getDevAuthToken()) {
11890
- res.statusCode = 200;
11891
- res.end("Valid token");
11892
- } else {
11893
- res.statusCode = 403;
11894
- res.end("Invalid token");
11895
- }
11896
- });
11897
12264
  });
11898
12265
  await import('./plugin-metrics.mjs').then(({ setup }) => setup(ctx));
11899
- if (options.vueDevTools !== false)
11900
- await import('./vue-devtools.mjs').then(({ setup }) => setup(ctx));
12266
+ await Promise.resolve().then(function () { return dataInspector; }).then(({ setup }) => setup(ctx));
11901
12267
  if (options.viteInspect !== false)
11902
12268
  await import('./vite-inspect.mjs').then(({ setup }) => setup(ctx));
11903
12269
  if (options.componentInspector !== false)
11904
12270
  await import('./vue-tracer.mjs').then(({ setup }) => setup(ctx));
11905
12271
  const integrations = [
11906
- options.vscode?.enabled ? import('./vscode.mjs').then(({ setup }) => setup(ctx)) : null,
12272
+ import('./code-server.mjs').then(({ setup }) => setup(ctx)),
11907
12273
  options.experimental?.timeline || options.timeline?.enabled ? import('./timeline.mjs').then(({ setup }) => setup(ctx)) : null
11908
12274
  ];
11909
12275
  await Promise.all(integrations);
11910
12276
  nuxt.hook("modules:done", () => nuxt.callHook("devtools:initialized", {
11911
12277
  version: version$1,
11912
- packagePath: packageDir,
11913
- isGlobalInstall: isGlobalInstall()
12278
+ packagePath: packageDir
11914
12279
  }));
11915
12280
  const isMac = os.platform() === "darwin";
11916
12281
  logger.log([
@@ -11934,4 +12299,4 @@ const moduleMain = {
11934
12299
  enableModule: enableModule
11935
12300
  };
11936
12301
 
11937
- export { LOG_PREFIX as L, moduleMain as m };
12302
+ export { RPC_NAMESPACE as R, moduleMain as m };