@nuxt/devtools 1.4.1 → 1.5.0

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 (196) hide show
  1. package/dist/chunks/analyze-build.mjs +1 -1
  2. package/dist/chunks/module-main.mjs +648 -648
  3. package/dist/chunks/vite-inspect.mjs +1 -1
  4. package/dist/chunks/vscode.mjs +15 -15
  5. package/dist/client/200.html +18 -34
  6. package/dist/client/404.html +18 -34
  7. package/dist/client/_nuxt/__blank-c3ogaker.js +1 -0
  8. package/dist/client/_nuxt/analyze-build-ea1eck8p.js +1 -0
  9. package/dist/client/_nuxt/assets-n3kfhorl.js +16 -0
  10. package/dist/client/_nuxt/builds/latest.json +1 -1
  11. package/dist/client/_nuxt/builds/meta/9a9f67ed-5b9a-4514-bf49-62859c510bf6.json +1 -0
  12. package/dist/client/_nuxt/client-klf75x38.js +1 -0
  13. package/dist/client/_nuxt/code-diff.vue-3ei6zne1.js +8 -0
  14. package/dist/client/_nuxt/code-snippets.vue-jr6ih8m7.js +1 -0
  15. package/dist/client/_nuxt/components-c38lzacq.js +1 -0
  16. package/dist/client/_nuxt/components-tree-ihs546mg.js +1 -0
  17. package/dist/client/_nuxt/composable-item.vue-fyg5hnt4.js +1 -0
  18. package/dist/client/_nuxt/custom-_name_-eeczuiaf.js +1 -0
  19. package/dist/client/_nuxt/default-iofn16rr.js +1 -0
  20. package/dist/client/_nuxt/duration-display.vue-h3qa2740.js +1 -0
  21. package/dist/client/_nuxt/entry.css-bgn3dvs3.css +1 -0
  22. package/dist/client/_nuxt/error-404-m1rb28qo.js +1 -0
  23. package/dist/client/_nuxt/error-404.css-l9hojrit.css +1 -0
  24. package/dist/client/_nuxt/error-500-diual75d.js +1 -0
  25. package/dist/client/_nuxt/error-500.css-jiufalsw.css +1 -0
  26. package/dist/client/_nuxt/error-j0kod4j7.js +9 -0
  27. package/dist/client/_nuxt/filepath-item.vue-gspuql6t.js +1 -0
  28. package/dist/client/_nuxt/full-gbkjzbjn.js +1 -0
  29. package/dist/client/_nuxt/help-fab.vue-hr5z89ai.js +1 -0
  30. package/dist/client/_nuxt/hooks-bmqjn5uk.js +1 -0
  31. package/dist/client/_nuxt/imports-bpqh8uz0.js +1 -0
  32. package/dist/client/_nuxt/index-i6v3sxsq.js +1 -0
  33. package/dist/client/_nuxt/index-kk8qg4i0.js +2 -0
  34. package/dist/client/_nuxt/l4ouzdbv.js +16 -0
  35. package/dist/client/_nuxt/launch-page.vue-o72v57lt.js +1 -0
  36. package/dist/client/_nuxt/modules-hfiy1oig.js +1 -0
  37. package/dist/client/_nuxt/nbadge-nscxg0ea.js +1 -0
  38. package/dist/client/_nuxt/ncheckbox.vue-e9ud9j5x.js +1 -0
  39. package/dist/client/_nuxt/ncode-block.vue-bfbbo3c9.js +2 -0
  40. package/dist/client/_nuxt/ndrawer.vue-mplxtid5.js +1 -0
  41. package/dist/client/_nuxt/ndropdown.vue-e87kxadx.js +1 -0
  42. package/dist/client/_nuxt/nicon-title.vue-g9trlv29.js +1 -0
  43. package/dist/client/_nuxt/nlink.vue-eiz3iwjv.js +1 -0
  44. package/dist/client/_nuxt/nmarkdown.vue-nnge8mex.js +1 -0
  45. package/dist/client/_nuxt/nnavbar.vue-g8533enj.js +1 -0
  46. package/dist/client/_nuxt/none-e5nk9q3m.js +1 -0
  47. package/dist/client/_nuxt/nsection-block-mvrkafth.js +1 -0
  48. package/dist/client/_nuxt/nselect-tabs.vue-fwkap4uo.js +1 -0
  49. package/dist/client/_nuxt/nselect.vue-fw7xtqj5.js +1 -0
  50. package/dist/client/_nuxt/open-graph-mg0wvem5.js +3 -0
  51. package/dist/client/_nuxt/{open-graph.-BQyihv8.css → open-graph.css-np61an3p.css} +1 -1
  52. package/dist/client/_nuxt/overview-dwng171y.js +1 -0
  53. package/dist/client/_nuxt/pages-dw5vn1ay.js +1 -0
  54. package/dist/client/_nuxt/payload-n5bpui5g.js +1 -0
  55. package/dist/client/_nuxt/pinia-hflvu3wk.js +1 -0
  56. package/dist/client/_nuxt/plugins-is0jalvz.js +1 -0
  57. package/dist/client/_nuxt/runtime-configs-j2weq3a8.js +1 -0
  58. package/dist/client/_nuxt/server-route-inputs.vue-f12vix3z.js +1 -0
  59. package/dist/client/_nuxt/server-routes-fukasdvq.js +9 -0
  60. package/dist/client/_nuxt/server-tasks-k1h90jj9.js +1 -0
  61. package/dist/client/_nuxt/settings-bwoka9ty.js +1 -0
  62. package/dist/client/_nuxt/stacktrace-list.vue-ctsox658.js +1 -0
  63. package/dist/client/_nuxt/state-components-3qxyvdiu.js +1 -0
  64. package/dist/client/_nuxt/state-editor.vue-mh0eij72.js +1 -0
  65. package/dist/client/_nuxt/state-modules-fxsj7vyw.js +1 -0
  66. package/dist/client/_nuxt/storage-i7qr12jo.js +1 -0
  67. package/dist/client/_nuxt/terminals-elxq15i6.js +1 -0
  68. package/dist/client/_nuxt/terminals.css-o071tnq5.css +1 -0
  69. package/dist/client/_nuxt/timeline-o2dlglei.js +31 -0
  70. package/dist/client/_nuxt/timeline.css-i7fpg75n.css +1 -0
  71. package/dist/client/_nuxt/unocss-runtime-ks657l4w.js +1 -0
  72. package/dist/client/_nuxt/vendor/json-editor-vue-mdfcgt41.js +124 -0
  73. package/dist/client/_nuxt/vendor/json-editor-vue.css-o0jf01nd.css +1 -0
  74. package/dist/client/_nuxt/vendor/shiki-fpe2sz4h.js +87 -0
  75. package/dist/client/_nuxt/vendor/unocss-mnpxkox6.js +2 -0
  76. package/dist/client/_nuxt/vendor/unocss.css-na153c8v.css +1 -0
  77. package/dist/client/_nuxt/vendor/vis-cum19y28.js +98 -0
  78. package/dist/client/_nuxt/{BMmGYe_n.js → vendor/xterm-h0ftnevm.js} +6 -6
  79. package/dist/client/_nuxt/{terminals.BIEho_Pa.css → vendor/xterm.css-egivkam7.css} +1 -1
  80. package/dist/client/_nuxt/virtual-files-j88ybqgt.js +1 -0
  81. package/dist/client/_nuxt/vue-virtual-scroller.esm-k82i9hy2.js +2 -0
  82. package/dist/client/index.html +18 -34
  83. package/dist/module.json +1 -1
  84. package/dist/runtime/function-metrics-helpers.d.ts +1 -1
  85. package/dist/runtime/function-metrics-helpers.js +1 -1
  86. package/dist/runtime/plugins/view/FrameBox.vue +1 -1
  87. package/dist/runtime/plugins/view/Main.vue +3 -3
  88. package/dist/runtime/plugins/view/client.d.ts +1 -2
  89. package/dist/runtime/plugins/view/client.js +2 -2
  90. package/dist/runtime/plugins/view/state.d.ts +1 -2
  91. package/dist/runtime/plugins/view/utils.d.ts +12 -12
  92. package/dist/runtime/settings.d.ts +1 -1
  93. package/dist/runtime/shared/hooks.d.ts +0 -1
  94. package/dist/runtime/use-nuxt-devtools.d.ts +1 -1
  95. package/dist/runtime/use-nuxt-devtools.js +1 -1
  96. package/dist/runtime/vue-devtools/overlay.js +1 -1
  97. package/package.json +35 -35
  98. package/dist/client/_nuxt/32IlS-eL.js +0 -15
  99. package/dist/client/_nuxt/6ngNN4Yp.js +0 -1
  100. package/dist/client/_nuxt/7oK7PdYH.js +0 -1
  101. package/dist/client/_nuxt/B1veJI6T.js +0 -1
  102. package/dist/client/_nuxt/B3uNdhXb.js +0 -100
  103. package/dist/client/_nuxt/B6E6ObS_.js +0 -8
  104. package/dist/client/_nuxt/BECRlsCL.js +0 -1
  105. package/dist/client/_nuxt/BHh_UM9T.js +0 -1
  106. package/dist/client/_nuxt/BI3hykgO.js +0 -1
  107. package/dist/client/_nuxt/BKeomq25.js +0 -1
  108. package/dist/client/_nuxt/BKukfVLl.js +0 -1
  109. package/dist/client/_nuxt/BLmvGqlk.js +0 -1
  110. package/dist/client/_nuxt/BMbUeBqv.js +0 -74
  111. package/dist/client/_nuxt/BOV_C5BD.js +0 -1
  112. package/dist/client/_nuxt/BYelj_cE.js +0 -1
  113. package/dist/client/_nuxt/BZfs-ost.js +0 -1
  114. package/dist/client/_nuxt/BiRcA7Ly.js +0 -1
  115. package/dist/client/_nuxt/BiWblMbN.js +0 -505
  116. package/dist/client/_nuxt/BiWf_U1D.js +0 -1
  117. package/dist/client/_nuxt/BkwfBuTq.js +0 -1
  118. package/dist/client/_nuxt/BopA0WYG.js +0 -1
  119. package/dist/client/_nuxt/Br6ll-O0.js +0 -1
  120. package/dist/client/_nuxt/BsEGx9wN.js +0 -1
  121. package/dist/client/_nuxt/Bu2gNcUf.js +0 -1
  122. package/dist/client/_nuxt/Bxkoe-BC.js +0 -1
  123. package/dist/client/_nuxt/ByTwm2ax.js +0 -1
  124. package/dist/client/_nuxt/C1fpCDlE.js +0 -1
  125. package/dist/client/_nuxt/C2HmjCtb.js +0 -1
  126. package/dist/client/_nuxt/C8RrL2-P.js +0 -1
  127. package/dist/client/_nuxt/C9bF3W-8.js +0 -1032
  128. package/dist/client/_nuxt/CCJYS4Qc.js +0 -4
  129. package/dist/client/_nuxt/CCXTpRMt.js +0 -1
  130. package/dist/client/_nuxt/CCfUy938.js +0 -2
  131. package/dist/client/_nuxt/CEL3Rl_8.js +0 -1
  132. package/dist/client/_nuxt/CHuuZgn4.js +0 -699
  133. package/dist/client/_nuxt/CIvuwNIv.js +0 -2
  134. package/dist/client/_nuxt/CNzQK24q.js +0 -1
  135. package/dist/client/_nuxt/CO7Eo6nF.js +0 -1
  136. package/dist/client/_nuxt/CTKqK4eG.js +0 -2002
  137. package/dist/client/_nuxt/CUZJ8tqD.js +0 -1
  138. package/dist/client/_nuxt/CWDIGLyg.js +0 -1
  139. package/dist/client/_nuxt/C_n3_iyW.js +0 -16
  140. package/dist/client/_nuxt/C_tLznPO.js +0 -43
  141. package/dist/client/_nuxt/CbViG2Xw.js +0 -74
  142. package/dist/client/_nuxt/CbYhyuC0.js +0 -505
  143. package/dist/client/_nuxt/CoNBQO3e.js +0 -1
  144. package/dist/client/_nuxt/CsTmP73Z.js +0 -1
  145. package/dist/client/_nuxt/CupVZNk8.js +0 -25
  146. package/dist/client/_nuxt/D4C_EO1O.js +0 -9
  147. package/dist/client/_nuxt/D4FLysGE.js +0 -1
  148. package/dist/client/_nuxt/D4V9JMY9.js +0 -1
  149. package/dist/client/_nuxt/D5Dg5B9b.js +0 -1
  150. package/dist/client/_nuxt/D86udNSS.js +0 -1
  151. package/dist/client/_nuxt/DAg81ukK.js +0 -30
  152. package/dist/client/_nuxt/DC8MraHL.js +0 -666
  153. package/dist/client/_nuxt/DDDCUP5E.js +0 -3
  154. package/dist/client/_nuxt/DDMtKJxh.js +0 -1
  155. package/dist/client/_nuxt/DHFOa8tC.js +0 -200
  156. package/dist/client/_nuxt/DHZqFavZ.js +0 -2
  157. package/dist/client/_nuxt/DHsLiygU.js +0 -1
  158. package/dist/client/_nuxt/DJg41Obz.js +0 -1
  159. package/dist/client/_nuxt/DJn5wykB.js +0 -1
  160. package/dist/client/_nuxt/DK4oFTHQ.js +0 -200
  161. package/dist/client/_nuxt/DMjsYTya.js +0 -1
  162. package/dist/client/_nuxt/DOv5BRyJ.js +0 -1
  163. package/dist/client/_nuxt/DajZvwFy.js +0 -1
  164. package/dist/client/_nuxt/Dch3xQiY.js +0 -699
  165. package/dist/client/_nuxt/Di-fSNio.js +0 -1
  166. package/dist/client/_nuxt/DiyNht5f.js +0 -9
  167. package/dist/client/_nuxt/Dm9RYIcI.js +0 -1
  168. package/dist/client/_nuxt/DockxStG.js +0 -1
  169. package/dist/client/_nuxt/DpYuRYxj.js +0 -2072
  170. package/dist/client/_nuxt/DqpvVAaa.js +0 -1
  171. package/dist/client/_nuxt/DrswlxM3.js +0 -1
  172. package/dist/client/_nuxt/DtfHoqTV.js +0 -1
  173. package/dist/client/_nuxt/DvyTQcux.js +0 -1
  174. package/dist/client/_nuxt/J0gvLlTF.js +0 -1
  175. package/dist/client/_nuxt/L3q7etZW.js +0 -1
  176. package/dist/client/_nuxt/Q9LIRUci.js +0 -25
  177. package/dist/client/_nuxt/QxrU7fRC.js +0 -1
  178. package/dist/client/_nuxt/RBAD4-dW.js +0 -1
  179. package/dist/client/_nuxt/T8d8zkkH.js +0 -1
  180. package/dist/client/_nuxt/U0su7k1z.js +0 -1
  181. package/dist/client/_nuxt/UI0GwUC_.js +0 -1
  182. package/dist/client/_nuxt/YWCqik9X.js +0 -98
  183. package/dist/client/_nuxt/_ECCzcZq.js +0 -666
  184. package/dist/client/_nuxt/builds/meta/1766755b-b307-4775-82c4-edb6a4a7e185.json +0 -1
  185. package/dist/client/_nuxt/entry.eFSfOpqI.css +0 -1
  186. package/dist/client/_nuxt/error-404.HYsbWGh9.css +0 -1
  187. package/dist/client/_nuxt/error-500.BwPFg8q2.css +0 -1
  188. package/dist/client/_nuxt/nhLZZe93.js +0 -1
  189. package/dist/client/_nuxt/timeline.BVVcTKn-.css +0 -1
  190. /package/dist/client/_nuxt/{assets.DGT3vQsf.css → assets.css-l0xw7n9m.css} +0 -0
  191. /package/dist/client/_nuxt/{BcJws1i5.js → constants-b32h69zq.js} +0 -0
  192. /package/dist/client/_nuxt/{HelpFab.DHTsX8io.css → help-fab.css-l22fo390.css} +0 -0
  193. /package/dist/client/_nuxt/{NCodeBlock.BJ-XAY5s.css → ncode-block.css-enx2fys6.css} +0 -0
  194. /package/dist/client/_nuxt/{NSectionBlock.Dnwb6MN5.css → nsection-block.css-nz74xks7.css} +0 -0
  195. /package/dist/client/_nuxt/{Blr6EMNg.js → vendor/markdown-it-fvu08dbs.js} +0 -0
  196. /package/dist/client/_nuxt/{virtual-files.CWZEM3J4.css → virtual-files.css-i6taatd1.css} +0 -0
@@ -1,37 +1,37 @@
1
1
  import fs$1, { existsSync } from 'node:fs';
2
- import os, { homedir } from 'node:os';
3
2
  import fs from 'node:fs/promises';
4
- import { join, resolve, dirname as dirname$1 } from 'pathe';
3
+ import os, { homedir } from 'node:os';
5
4
  import { logger, useNuxt, addPlugin, addTemplate, addVitePlugin } from '@nuxt/kit';
6
- import { searchForWorkspaceRoot } from 'vite';
7
- import sirv from 'sirv';
8
5
  import { colors } from 'consola/utils';
9
- import { createBirpcGroup } from 'birpc';
10
- import { stringify, parse as parse$1 } from 'flatted';
6
+ import { join, dirname as dirname$1, resolve } from 'pathe';
7
+ import sirv from 'sirv';
8
+ import { searchForWorkspaceRoot } from 'vite';
11
9
  import { d as defaultAllowedExtensions, a as defaultTabOptions, W as WS_EVENT_NAME } from '../shared/devtools.68e43ed6.mjs';
12
10
  import { dirname, join as join$1, relative, parse } from 'node:path';
13
11
  import { randomStr } from '@antfu/utils';
14
12
  import { hash } from 'ohash';
13
+ import { runtimeDir, clientDir, packageDir, isGlobalInstall } from '../dirs.mjs';
14
+ import { createBirpcGroup } from 'birpc';
15
+ import { stringify, parse as parse$1 } from 'flatted';
16
+ import { startSubprocess } from '@nuxt/devtools-kit';
17
+ import Git from 'simple-git';
18
+ import { glob } from 'tinyglobby';
15
19
  import { imageMeta } from 'image-meta';
16
20
  import { debounce } from 'perfect-debounce';
17
- import { glob } from 'tinyglobby';
18
- import { startSubprocess } from '@nuxt/devtools-kit';
21
+ import destr from 'destr';
22
+ import { snakeCase } from 'scule';
23
+ import { resolveBuiltinPresets } from 'unimport';
24
+ import { setupHooksDebug } from '../../dist/runtime/shared/hooks.js';
19
25
  import isInstalledGlobally from 'is-installed-globally';
20
- import { detectPackageManager } from 'nypm';
21
26
  import { parseModule } from 'magicast';
22
27
  import { addNuxtModule, getDefaultExportOptions } from 'magicast/helpers';
28
+ import { detectPackageManager } from 'nypm';
23
29
  import { createRequire } from 'node:module';
30
+ import { getPackageInfo } from 'local-pkg';
24
31
  import 'pkg-types';
25
32
  import semver from 'semver';
26
- import destr from 'destr';
27
- import { getPackageInfo } from 'local-pkg';
28
- import { resolveBuiltinPresets } from 'unimport';
29
- import { snakeCase } from 'scule';
30
- import { setupHooksDebug } from '../../dist/runtime/shared/hooks.js';
31
- import Git from 'simple-git';
32
- import { runtimeDir, clientDir, packageDir, isGlobalInstall } from '../dirs.mjs';
33
33
 
34
- const version = "1.4.1";
34
+ const version = "1.5.0";
35
35
 
36
36
  function getHomeDir() {
37
37
  return process.env.XDG_CONFIG_HOME || homedir();
@@ -106,68 +106,90 @@ async function getDevAuthToken() {
106
106
  return token;
107
107
  }
108
108
 
109
- const IGNORE_STORAGE_MOUNTS = ["root", "build", "src", "cache"];
110
- function shouldIgnoreStorageKey(key) {
111
- return IGNORE_STORAGE_MOUNTS.includes(key.split(":")[0]);
112
- }
113
- function setupStorageRPC({
114
- nuxt,
115
- rpc,
116
- ensureDevAuthToken
117
- }) {
118
- const storageMounts = {};
119
- let storage;
120
- nuxt.hook("nitro:init", (nitro) => {
121
- storage = nitro.storage;
122
- nuxt.hook("ready", () => {
123
- storage.watch((event, key) => {
124
- if (shouldIgnoreStorageKey(key))
125
- return;
126
- rpc.broadcast.callHook.asEvent("storage:key:update", key, event);
127
- });
109
+ function setupAnalyzeBuildRPC({ nuxt, refresh, ensureDevAuthToken }) {
110
+ let builds = [];
111
+ let promise;
112
+ let initalized;
113
+ const processId = "devtools:analyze-build";
114
+ const analyzeDir = join(nuxt.options.rootDir, ".nuxt/analyze");
115
+ async function startAnalyzeBuild(name) {
116
+ if (promise)
117
+ throw new Error("Already building");
118
+ const result = startSubprocess({
119
+ command: "npx",
120
+ args: ["nuxi", "analyze", "--no-serve", "--name", name],
121
+ cwd: nuxt.options.rootDir
122
+ }, {
123
+ id: processId,
124
+ name: "Analyze Build",
125
+ icon: "logos-nuxt-icon"
126
+ }, nuxt);
127
+ refresh("getAnalyzeBuildInfo");
128
+ promise = result.getProcess().then(() => {
129
+ refresh("getAnalyzeBuildInfo");
130
+ return readBuildInfo();
131
+ }).finally(() => {
132
+ promise = void 0;
133
+ initalized = void 0;
134
+ refresh("getAnalyzeBuildInfo");
128
135
  });
129
- const mounts = {
130
- ...nitro.options.storage,
131
- ...nitro.options.devStorage
132
- };
133
- for (const name of Object.keys(mounts)) {
134
- if (shouldIgnoreStorageKey(name))
135
- continue;
136
- storageMounts[name] = mounts[name];
136
+ return processId;
137
+ }
138
+ async function readBuildInfo() {
139
+ const files = await glob(["*/meta.json"], { cwd: analyzeDir, onlyFiles: true, absolute: true });
140
+ builds = await Promise.all(files.map(async (file) => {
141
+ const dir = dirname$1(file);
142
+ const json = JSON.parse(await fs.readFile(file, "utf-8"));
143
+ return {
144
+ ...json,
145
+ features: {
146
+ bundleClient: fs$1.existsSync(join(dir, "client.html")),
147
+ bundleNitro: fs$1.existsSync(join(dir, "nitro.html")),
148
+ viteInspect: fs$1.existsSync(join(dir, ".vite-inspect"))
149
+ }
150
+ };
151
+ }));
152
+ return builds.sort((a, b) => b.endTime - a.endTime);
153
+ }
154
+ async function generateAnalyzeBuildName() {
155
+ try {
156
+ const git = Git(nuxt.options.rootDir);
157
+ const branch = await git.branch();
158
+ const branchName = branch.current || "head";
159
+ const sha = await git.revparse(["--short", "HEAD"]);
160
+ const isWorkingTreeClean = (await git.status()).isClean();
161
+ if (isWorkingTreeClean)
162
+ return `${branchName}#${sha}`;
163
+ return `${branchName}#${sha}-dirty`;
164
+ } catch {
165
+ return (/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-");
137
166
  }
138
- });
167
+ }
139
168
  return {
140
- async getStorageMounts() {
141
- return storageMounts;
142
- },
143
- async getStorageKeys(base) {
144
- if (!storage)
145
- return [];
146
- try {
147
- const keys = await storage.getKeys(base);
148
- return keys.filter((key) => !shouldIgnoreStorageKey(key));
149
- } catch (err) {
150
- console.error(`Cloud not fetch storage keys for ${base}:`, err);
151
- return [];
152
- }
153
- },
154
- async getStorageItem(token, key) {
155
- await ensureDevAuthToken(token);
156
- if (!storage)
157
- return null;
158
- return await storage.getItem(key);
169
+ async getAnalyzeBuildInfo() {
170
+ if (!initalized)
171
+ initalized = readBuildInfo();
172
+ await initalized;
173
+ return {
174
+ isBuilding: !!promise,
175
+ builds
176
+ };
159
177
  },
160
- async setStorageItem(token, key, value) {
178
+ async clearAnalyzeBuilds(token, names) {
161
179
  await ensureDevAuthToken(token);
162
- if (!storage)
163
- return;
164
- return await storage.setItem(key, value);
180
+ if (!names) {
181
+ await fs.rm(analyzeDir, { recursive: true, force: true });
182
+ } else {
183
+ const targets = builds.filter((build) => names.includes(build.name));
184
+ await Promise.all(targets.map((target) => fs.rm(join(analyzeDir, target.slug), { recursive: true, force: true })));
185
+ }
186
+ initalized = readBuildInfo();
187
+ refresh("getAnalyzeBuildInfo");
165
188
  },
166
- async removeStorageItem(token, key) {
189
+ generateAnalyzeBuildName,
190
+ async startAnalyzeBuild(token, ...args) {
167
191
  await ensureDevAuthToken(token);
168
- if (!storage)
169
- return;
170
- return await storage.removeItem(key);
192
+ return startAnalyzeBuild(...args);
171
193
  }
172
194
  };
173
195
  }
@@ -312,59 +334,300 @@ function guessType(path) {
312
334
  return "other";
313
335
  }
314
336
 
315
- const HASH_RE = /#/g;
316
- const AMPERSAND_RE = /&/g;
317
- const SLASH_RE = /\//g;
318
- const EQUAL_RE = /=/g;
319
- const PLUS_RE = /\+/g;
320
- const ENC_CARET_RE = /%5e/gi;
321
- const ENC_BACKTICK_RE = /%60/gi;
322
- const ENC_PIPE_RE = /%7c/gi;
323
- const ENC_SPACE_RE = /%20/gi;
324
- function encode(text) {
325
- return encodeURI("" + text).replace(ENC_PIPE_RE, "|");
326
- }
327
- function encodeQueryValue(input) {
328
- return encode(typeof input === "string" ? input : JSON.stringify(input)).replace(PLUS_RE, "%2B").replace(ENC_SPACE_RE, "+").replace(HASH_RE, "%23").replace(AMPERSAND_RE, "%26").replace(ENC_BACKTICK_RE, "`").replace(ENC_CARET_RE, "^").replace(SLASH_RE, "%2F");
329
- }
330
- function encodeQueryKey(text) {
331
- return encodeQueryValue(text).replace(EQUAL_RE, "%3D");
332
- }
333
- function decode(text = "") {
334
- try {
335
- return decodeURIComponent("" + text);
336
- } catch {
337
- return "" + text;
337
+ function setupCustomTabRPC({ nuxt, options, refresh }) {
338
+ const iframeTabs = [];
339
+ const customTabs = [];
340
+ if (options.customTabs?.length)
341
+ customTabs.push(...options.customTabs);
342
+ async function initHooks() {
343
+ nuxt.hook("devtools:customTabs:refresh", initCustomTabs);
344
+ await initCustomTabs();
338
345
  }
339
- }
340
- function decodeQueryKey(text) {
341
- return decode(text.replace(PLUS_RE, " "));
342
- }
343
- function decodeQueryValue(text) {
344
- return decode(text.replace(PLUS_RE, " "));
345
- }
346
-
347
- function parseQuery(parametersString = "") {
348
- const object = {};
349
- if (parametersString[0] === "?") {
350
- parametersString = parametersString.slice(1);
346
+ async function initCustomTabs() {
347
+ customTabs.length = 0;
348
+ if (options.customTabs?.length)
349
+ customTabs.push(...options.customTabs);
350
+ await nuxt.callHook("devtools:customTabs", customTabs);
351
+ refresh("getCustomTabs");
351
352
  }
352
- for (const parameter of parametersString.split("&")) {
353
- const s = parameter.match(/([^=]+)=?(.*)/) || [];
354
- if (s.length < 2) {
355
- continue;
356
- }
357
- const key = decodeQueryKey(s[1]);
358
- if (key === "__proto__" || key === "constructor") {
359
- continue;
353
+ nuxt.hook("app:resolve", async () => {
354
+ await initHooks();
355
+ });
356
+ return {
357
+ getCustomTabs() {
358
+ return [
359
+ ...iframeTabs,
360
+ ...customTabs
361
+ ].map((i) => {
362
+ i.category = i.category || "modules";
363
+ return i;
364
+ });
365
+ },
366
+ async customTabAction(name, actionIndex) {
367
+ const tab = customTabs.find((i) => i.name === name);
368
+ if (!tab)
369
+ return false;
370
+ const view = tab.view;
371
+ if (view.type !== "launch")
372
+ return false;
373
+ const action = view.actions?.[actionIndex];
374
+ if (!action)
375
+ return false;
376
+ Promise.resolve(action.handle?.()).catch((e) => {
377
+ console.error(e);
378
+ }).finally(() => {
379
+ nuxt.callHook("devtools:customTabs:refresh");
380
+ });
381
+ nuxt.callHook("devtools:customTabs:refresh");
382
+ return true;
360
383
  }
361
- const value = decodeQueryValue(s[2] || "");
362
- if (object[key] === void 0) {
363
- object[key] = value;
364
- } else if (Array.isArray(object[key])) {
365
- object[key].push(value);
366
- } else {
367
- object[key] = [object[key], value];
384
+ };
385
+ }
386
+
387
+ function setupGeneralRPC({
388
+ nuxt,
389
+ options,
390
+ refresh,
391
+ ensureDevAuthToken,
392
+ openInEditorHooks
393
+ }) {
394
+ const components = [];
395
+ const imports = [];
396
+ const importPresets = [];
397
+ let importDirs = [];
398
+ const serverPages = [];
399
+ let serverApp;
400
+ const serverHooks = setupHooksDebug(nuxt.hooks);
401
+ let unimport;
402
+ let app;
403
+ nuxt.hook("components:extend", (v) => {
404
+ components.length = 0;
405
+ components.push(...v);
406
+ components.sort((a, b) => a.pascalName.localeCompare(b.pascalName));
407
+ refresh("getComponents");
408
+ });
409
+ nuxt.hook("imports:extend", (v) => {
410
+ imports.length = 0;
411
+ imports.push(...v);
412
+ refresh("getAutoImports");
413
+ });
414
+ nuxt.hook("pages:extend", (v) => {
415
+ serverPages.length = 0;
416
+ const pagesSet = new Set(v);
417
+ function searchChildren(page) {
418
+ if (pagesSet.has(page))
419
+ return;
420
+ pagesSet.add(page);
421
+ page.children?.forEach(searchChildren);
422
+ }
423
+ v.forEach(searchChildren);
424
+ serverPages.push(...Array.from(pagesSet).sort((a, b) => a.path.localeCompare(b.path)));
425
+ refresh("getServerPages");
426
+ });
427
+ nuxt.hook("app:resolve", (app2) => {
428
+ serverApp = app2;
429
+ });
430
+ nuxt.hook("imports:sources", async (v) => {
431
+ const result = (await resolveBuiltinPresets(v)).flat();
432
+ importPresets.length = 0;
433
+ importPresets.push(...result);
434
+ refresh("getAutoImports");
435
+ });
436
+ nuxt.hook("imports:context", (_unimport) => {
437
+ unimport = _unimport;
438
+ });
439
+ nuxt.hook("imports:dirs", (dirs) => {
440
+ importDirs = dirs;
441
+ });
442
+ nuxt.hook("app:resolve", (v) => {
443
+ app = v;
444
+ });
445
+ return {
446
+ getServerConfig() {
447
+ return nuxt.options;
448
+ },
449
+ getServerRuntimeConfig() {
450
+ const ENV_PREFIX = "NITRO_";
451
+ const ENV_PREFIX_ALT = "NUXT_";
452
+ function _getEnv(key) {
453
+ const envKey = snakeCase(key).toUpperCase();
454
+ return destr(process.env[ENV_PREFIX + envKey] ?? process.env[ENV_PREFIX_ALT + envKey]);
455
+ }
456
+ function _isObject(input) {
457
+ return typeof input === "object" && !Array.isArray(input);
458
+ }
459
+ function _applyEnv(obj, parentKey = "") {
460
+ for (const key in obj) {
461
+ const subKey = parentKey ? `${parentKey}_${key}` : key;
462
+ const envValue = _getEnv(subKey);
463
+ if (_isObject(obj[key])) {
464
+ if (_isObject(envValue))
465
+ obj[key] = { ...obj[key], ...envValue };
466
+ _applyEnv(obj[key], subKey);
467
+ } else {
468
+ obj[key] = envValue ?? obj[key];
469
+ }
470
+ }
471
+ return obj;
472
+ }
473
+ const runtime = { ...nuxt.options.runtimeConfig };
474
+ _applyEnv(runtime);
475
+ return runtime;
476
+ },
477
+ getModuleOptions() {
478
+ return options;
479
+ },
480
+ getServerApp() {
481
+ return serverApp;
482
+ },
483
+ getComponents() {
484
+ return components;
485
+ },
486
+ async getComponentsRelationships() {
487
+ return [];
488
+ },
489
+ getServerPages() {
490
+ return serverPages;
491
+ },
492
+ getAutoImports() {
493
+ return {
494
+ imports: [
495
+ ...imports,
496
+ ...importPresets
497
+ ],
498
+ metadata: unimport?.getMetadata(),
499
+ dirs: importDirs
500
+ };
501
+ },
502
+ getServerLayouts() {
503
+ return Object.values(app?.layouts || []);
504
+ },
505
+ getServerHooks() {
506
+ return Object.values(serverHooks);
507
+ },
508
+ async openInEditor(input) {
509
+ if (input.startsWith("./"))
510
+ input = resolve(process.cwd(), input);
511
+ const match = input.match(/^(.*?)(:[:\d]*)$/);
512
+ let suffix = "";
513
+ if (match) {
514
+ input = match[1];
515
+ suffix = match[2];
516
+ }
517
+ const path = [
518
+ input,
519
+ `${input}.js`,
520
+ `${input}.mjs`,
521
+ `${input}.ts`
522
+ ].find((i) => existsSync(i));
523
+ if (!path) {
524
+ console.error("File not found:", input);
525
+ return false;
526
+ }
527
+ try {
528
+ for (const hook of openInEditorHooks) {
529
+ const result = await hook(path);
530
+ if (result)
531
+ return true;
532
+ }
533
+ await import('launch-editor').then((r) => (r.default || r)(path + suffix));
534
+ return true;
535
+ } catch (e) {
536
+ console.error(e);
537
+ return false;
538
+ }
539
+ },
540
+ async restartNuxt(token, hard = true) {
541
+ await ensureDevAuthToken(token);
542
+ logger.info("Restarting Nuxt...");
543
+ return nuxt.callHook("restart", { hard });
544
+ },
545
+ async requestForAuth(info, origin) {
546
+ if (options.disableAuthorization)
547
+ return;
548
+ const token = await getDevAuthToken();
549
+ origin ||= `${nuxt.options.devServer.https ? "https" : "http"}://${nuxt.options.devServer.host === "::" ? "localhost" : nuxt.options.devServer.host || "localhost"}:${nuxt.options.devServer.port}`;
550
+ const ROUTE_AUTH = `${nuxt.options.app.baseURL || "/"}/__nuxt_devtools__/auth`.replace(/\/+/g, "/");
551
+ const message = [
552
+ `A browser is requesting permissions of ${colors.bold(colors.yellow("writing files and running commands"))} from the DevTools UI.`,
553
+ colors.bold(info || "Unknown"),
554
+ "",
555
+ "Please open the following URL in the browser:",
556
+ colors.bold(colors.green(`${origin}${ROUTE_AUTH}?token=${token}`)),
557
+ "",
558
+ "Or manually copy and paste the following token:",
559
+ colors.bold(colors.cyan(token))
560
+ ];
561
+ logger.box({
562
+ message: message.join("\n"),
563
+ title: colors.bold(colors.yellow(" Permission Request ")),
564
+ style: {
565
+ borderColor: "yellow",
566
+ borderStyle: "rounded"
567
+ }
568
+ });
569
+ },
570
+ async verifyAuthToken(token) {
571
+ if (options.disableAuthorization)
572
+ return true;
573
+ return token === await getDevAuthToken();
574
+ }
575
+ };
576
+ }
577
+
578
+ const HASH_RE = /#/g;
579
+ const AMPERSAND_RE = /&/g;
580
+ const SLASH_RE = /\//g;
581
+ const EQUAL_RE = /=/g;
582
+ const PLUS_RE = /\+/g;
583
+ const ENC_CARET_RE = /%5e/gi;
584
+ const ENC_BACKTICK_RE = /%60/gi;
585
+ const ENC_PIPE_RE = /%7c/gi;
586
+ const ENC_SPACE_RE = /%20/gi;
587
+ function encode(text) {
588
+ return encodeURI("" + text).replace(ENC_PIPE_RE, "|");
589
+ }
590
+ function encodeQueryValue(input) {
591
+ return encode(typeof input === "string" ? input : JSON.stringify(input)).replace(PLUS_RE, "%2B").replace(ENC_SPACE_RE, "+").replace(HASH_RE, "%23").replace(AMPERSAND_RE, "%26").replace(ENC_BACKTICK_RE, "`").replace(ENC_CARET_RE, "^").replace(SLASH_RE, "%2F");
592
+ }
593
+ function encodeQueryKey(text) {
594
+ return encodeQueryValue(text).replace(EQUAL_RE, "%3D");
595
+ }
596
+ function decode(text = "") {
597
+ try {
598
+ return decodeURIComponent("" + text);
599
+ } catch {
600
+ return "" + text;
601
+ }
602
+ }
603
+ function decodeQueryKey(text) {
604
+ return decode(text.replace(PLUS_RE, " "));
605
+ }
606
+ function decodeQueryValue(text) {
607
+ return decode(text.replace(PLUS_RE, " "));
608
+ }
609
+
610
+ function parseQuery(parametersString = "") {
611
+ const object = {};
612
+ if (parametersString[0] === "?") {
613
+ parametersString = parametersString.slice(1);
614
+ }
615
+ for (const parameter of parametersString.split("&")) {
616
+ const s = parameter.match(/([^=]+)=?(.*)/) || [];
617
+ if (s.length < 2) {
618
+ continue;
619
+ }
620
+ const key = decodeQueryKey(s[1]);
621
+ if (key === "__proto__" || key === "constructor") {
622
+ continue;
623
+ }
624
+ const value = decodeQueryValue(s[2] || "");
625
+ if (object[key] === void 0) {
626
+ object[key] = value;
627
+ } else if (Array.isArray(object[key])) {
628
+ object[key].push(value);
629
+ } else {
630
+ object[key] = [object[key], value];
368
631
  }
369
632
  }
370
633
  return object;
@@ -1029,374 +1292,51 @@ function setupNpmRPC({ nuxt, ensureDevAuthToken }) {
1029
1292
  };
1030
1293
  }
1031
1294
 
1032
- function setupCustomTabRPC({ nuxt, options, refresh }) {
1033
- const iframeTabs = [];
1034
- const customTabs = [];
1035
- if (options.customTabs?.length)
1036
- customTabs.push(...options.customTabs);
1037
- async function initHooks() {
1038
- nuxt.hook("devtools:customTabs:refresh", initCustomTabs);
1039
- await initCustomTabs();
1040
- }
1041
- async function initCustomTabs() {
1042
- customTabs.length = 0;
1043
- if (options.customTabs?.length)
1044
- customTabs.push(...options.customTabs);
1045
- await nuxt.callHook("devtools:customTabs", customTabs);
1046
- refresh("getCustomTabs");
1047
- }
1048
- nuxt.hook("app:resolve", async () => {
1049
- await initHooks();
1050
- });
1051
- return {
1052
- getCustomTabs() {
1053
- return [
1054
- ...iframeTabs,
1055
- ...customTabs
1056
- ].map((i) => {
1057
- i.category = i.category || "modules";
1058
- return i;
1059
- });
1060
- },
1061
- async customTabAction(name, actionIndex) {
1062
- const tab = customTabs.find((i) => i.name === name);
1063
- if (!tab)
1064
- return false;
1065
- const view = tab.view;
1066
- if (view.type !== "launch")
1067
- return false;
1068
- const action = view.actions?.[actionIndex];
1069
- if (!action)
1070
- return false;
1071
- Promise.resolve(action.handle?.()).catch((e) => {
1072
- console.error(e);
1073
- }).finally(() => {
1074
- nuxt.callHook("devtools:customTabs:refresh");
1075
- });
1076
- nuxt.callHook("devtools:customTabs:refresh");
1077
- return true;
1078
- }
1079
- };
1080
- }
1081
-
1082
- function setupGeneralRPC({
1083
- nuxt,
1084
- options,
1085
- refresh,
1086
- ensureDevAuthToken,
1087
- openInEditorHooks
1088
- }) {
1089
- const components = [];
1090
- const imports = [];
1091
- const importPresets = [];
1092
- let importDirs = [];
1093
- const serverPages = [];
1094
- let serverApp;
1095
- const serverHooks = setupHooksDebug(nuxt.hooks);
1096
- let unimport;
1097
- let app;
1098
- nuxt.hook("components:extend", (v) => {
1099
- components.length = 0;
1100
- components.push(...v);
1101
- components.sort((a, b) => a.pascalName.localeCompare(b.pascalName));
1102
- refresh("getComponents");
1103
- });
1104
- nuxt.hook("imports:extend", (v) => {
1105
- imports.length = 0;
1106
- imports.push(...v);
1107
- refresh("getAutoImports");
1108
- });
1109
- nuxt.hook("pages:extend", (v) => {
1110
- serverPages.length = 0;
1111
- const pagesSet = new Set(v);
1112
- function searchChildren(page) {
1113
- if (pagesSet.has(page))
1114
- return;
1115
- pagesSet.add(page);
1116
- page.children?.forEach(searchChildren);
1117
- }
1118
- v.forEach(searchChildren);
1119
- serverPages.push(...Array.from(pagesSet).sort((a, b) => a.path.localeCompare(b.path)));
1120
- refresh("getServerPages");
1121
- });
1122
- nuxt.hook("app:resolve", (app2) => {
1123
- serverApp = app2;
1124
- });
1125
- nuxt.hook("imports:sources", async (v) => {
1126
- const result = (await resolveBuiltinPresets(v)).flat();
1127
- importPresets.length = 0;
1128
- importPresets.push(...result);
1129
- refresh("getAutoImports");
1130
- });
1131
- nuxt.hook("imports:context", (_unimport) => {
1132
- unimport = _unimport;
1133
- });
1134
- nuxt.hook("imports:dirs", (dirs) => {
1135
- importDirs = dirs;
1136
- });
1137
- nuxt.hook("app:resolve", (v) => {
1138
- app = v;
1139
- });
1140
- return {
1141
- getServerConfig() {
1142
- return nuxt.options;
1143
- },
1144
- getServerRuntimeConfig() {
1145
- const ENV_PREFIX = "NITRO_";
1146
- const ENV_PREFIX_ALT = "NUXT_";
1147
- function _getEnv(key) {
1148
- const envKey = snakeCase(key).toUpperCase();
1149
- return destr(process.env[ENV_PREFIX + envKey] ?? process.env[ENV_PREFIX_ALT + envKey]);
1150
- }
1151
- function _isObject(input) {
1152
- return typeof input === "object" && !Array.isArray(input);
1153
- }
1154
- function _applyEnv(obj, parentKey = "") {
1155
- for (const key in obj) {
1156
- const subKey = parentKey ? `${parentKey}_${key}` : key;
1157
- const envValue = _getEnv(subKey);
1158
- if (_isObject(obj[key])) {
1159
- if (_isObject(envValue))
1160
- obj[key] = { ...obj[key], ...envValue };
1161
- _applyEnv(obj[key], subKey);
1162
- } else {
1163
- obj[key] = envValue ?? obj[key];
1164
- }
1165
- }
1166
- return obj;
1167
- }
1168
- const runtime = { ...nuxt.options.runtimeConfig };
1169
- _applyEnv(runtime);
1170
- return runtime;
1171
- },
1172
- getModuleOptions() {
1173
- return options;
1174
- },
1175
- getServerApp() {
1176
- return serverApp;
1177
- },
1178
- getComponents() {
1179
- return components;
1180
- },
1181
- async getComponentsRelationships() {
1182
- return [];
1183
- },
1184
- getServerPages() {
1185
- return serverPages;
1186
- },
1187
- getAutoImports() {
1188
- return {
1189
- imports: [
1190
- ...imports,
1191
- ...importPresets
1192
- ],
1193
- metadata: unimport?.getMetadata(),
1194
- dirs: importDirs
1195
- };
1196
- },
1197
- getServerLayouts() {
1198
- return Object.values(app?.layouts || []);
1199
- },
1200
- getServerHooks() {
1201
- return Object.values(serverHooks);
1202
- },
1203
- async openInEditor(input) {
1204
- if (input.startsWith("./"))
1205
- input = resolve(process.cwd(), input);
1206
- const match = input.match(/^(.*?)(:[:\d]*)$/);
1207
- let suffix = "";
1208
- if (match) {
1209
- input = match[1];
1210
- suffix = match[2];
1211
- }
1212
- const path = [
1213
- input,
1214
- `${input}.js`,
1215
- `${input}.mjs`,
1216
- `${input}.ts`
1217
- ].find((i) => existsSync(i));
1218
- if (!path) {
1219
- console.error("File not found:", input);
1220
- return false;
1221
- }
1222
- try {
1223
- for (const hook of openInEditorHooks) {
1224
- const result = await hook(path);
1225
- if (result)
1226
- return true;
1227
- }
1228
- await import('launch-editor').then((r) => (r.default || r)(path + suffix));
1229
- return true;
1230
- } catch (e) {
1231
- console.error(e);
1232
- return false;
1233
- }
1234
- },
1235
- async restartNuxt(token, hard = true) {
1236
- await ensureDevAuthToken(token);
1237
- logger.info("Restarting Nuxt...");
1238
- return nuxt.callHook("restart", { hard });
1239
- },
1240
- async requestForAuth(info, origin) {
1241
- if (options.disableAuthorization)
1242
- return;
1243
- const token = await getDevAuthToken();
1244
- origin ||= `${nuxt.options.devServer.https ? "https" : "http"}://${nuxt.options.devServer.host === "::" ? "localhost" : nuxt.options.devServer.host || "localhost"}:${nuxt.options.devServer.port}`;
1245
- const ROUTE_AUTH = `${nuxt.options.app.baseURL || "/"}/__nuxt_devtools__/auth`.replace(/\/+/g, "/");
1246
- const message = [
1247
- `A browser is requesting permissions of ${colors.bold(colors.yellow("writing files and running commands"))} from the DevTools UI.`,
1248
- colors.bold(info || "Unknown"),
1249
- "",
1250
- "Please open the following URL in the browser:",
1251
- colors.bold(colors.green(`${origin}${ROUTE_AUTH}?token=${token}`)),
1252
- "",
1253
- "Or manually copy and paste the following token:",
1254
- colors.bold(colors.cyan(token))
1255
- ];
1256
- logger.box({
1257
- message: message.join("\n"),
1258
- title: colors.bold(colors.yellow(" Permission Request ")),
1259
- style: {
1260
- borderColor: "yellow",
1261
- borderStyle: "rounded"
1262
- }
1263
- });
1264
- },
1265
- async verifyAuthToken(token) {
1266
- if (options.disableAuthorization)
1267
- return true;
1268
- return token === await getDevAuthToken();
1269
- }
1270
- };
1271
- }
1272
-
1273
- const pagesIndexTemplate = `<script setup lang="ts">
1274
- const route = useRoute()
1275
- <\/script>
1276
-
1277
- <template>
1278
- <div>
1279
- <h1>Nuxt Routing set up successfully!</h1>
1280
- <p>Current route: {{ route.path }}</p>
1281
- <a href="https://nuxt.com/docs/getting-started/routing" target="_blank">Learn more about Nuxt Routing</a>
1282
- </div>
1283
- </template>
1284
- `;
1285
- async function enablePages(nuxt) {
1286
- const pathApp = join(nuxt.options.srcDir, "app.vue");
1287
- const pathPageIndex = join(nuxt.options.srcDir, "pages/index.vue");
1288
- if (fs$1.existsSync(pathPageIndex)) {
1289
- logger.warn("pages/index.vue already exists, skipping");
1290
- return;
1291
- }
1292
- let appContent = fs$1.existsSync(pathApp) ? await fs.readFile(pathApp, "utf-8") : void 0;
1293
- await fs.mkdir(dirname$1(pathPageIndex), { recursive: true });
1294
- await fs.writeFile(pathPageIndex, pagesIndexTemplate, "utf-8");
1295
- if (appContent && !appContent.includes("<NuxtPage")) {
1296
- appContent = appContent.replace("</template>", " <NuxtPage />\n</template>").replace(/<NuxtWelcome\s*\/>/, "");
1297
- await fs.writeFile(pathApp, appContent, "utf-8");
1298
- }
1299
- logger.success("Routing creation wizard completed");
1300
- }
1301
-
1302
- const wizard = {
1303
- enablePages
1304
- };
1305
-
1306
- const LOG_PREFIX = colors.cyan("Nuxt DevTools:");
1307
-
1308
- function setupWizardRPC({ nuxt, ensureDevAuthToken }) {
1309
- return {
1310
- async runWizard(token, name, ...args) {
1311
- await ensureDevAuthToken(token);
1312
- logger.info(LOG_PREFIX, `Running wizard ${colors.green(name)}...`);
1313
- return wizard[name](nuxt, ...args);
1314
- }
1315
- };
1295
+ let options;
1296
+ function getOptions() {
1297
+ return options;
1316
1298
  }
1317
-
1318
- function setupTerminalRPC({ nuxt, rpc, refresh, ensureDevAuthToken }) {
1319
- const terminals = /* @__PURE__ */ new Map();
1320
- nuxt.hook("devtools:terminal:register", (terminal) => {
1321
- terminals.set(terminal.id, terminal);
1322
- refresh("getTerminals");
1323
- return terminal.id;
1324
- });
1325
- nuxt.hook("devtools:terminal:remove", ({ id }) => {
1326
- if (!terminals.has(id))
1327
- return false;
1328
- terminals.delete(id);
1329
- refresh("getTerminals");
1330
- return true;
1331
- });
1332
- nuxt.hook("devtools:terminal:write", ({ id, data }) => {
1333
- const terminal = terminals.get(id);
1334
- if (!terminal)
1335
- return false;
1336
- terminal.buffer ||= "";
1337
- terminal.buffer += data;
1338
- rpc.broadcast.onTerminalData.asEvent({ id, data });
1339
- return true;
1340
- });
1341
- nuxt.hook("devtools:terminal:exit", ({ id, code }) => {
1342
- const terminal = terminals.get(id);
1343
- if (!terminal)
1344
- return false;
1345
- terminal.isTerminated = true;
1346
- rpc.broadcast.onTerminalExit.asEvent({ id, code });
1347
- refresh("getTerminals");
1348
- return true;
1349
- });
1350
- function serializeTerminal(terminal, buffer = false) {
1351
- if (!terminal)
1352
- return;
1353
- return {
1354
- id: terminal.id,
1355
- name: terminal.name,
1356
- description: terminal.description,
1357
- icon: terminal.icon,
1358
- terminatable: terminal.terminatable ?? !!terminal.onActionTerminate,
1359
- restartable: terminal.restartable ?? !!terminal.onActionRestart,
1360
- isTerminated: terminal.isTerminated,
1361
- buffer: buffer ? terminal.buffer : void 0
1362
- };
1299
+ function setupOptionsRPC({ nuxt }) {
1300
+ async function getOptions2(tab) {
1301
+ if (!options || options[tab]) {
1302
+ options = defaultTabOptions;
1303
+ await read(tab);
1304
+ }
1305
+ return options[tab];
1306
+ }
1307
+ async function read(tab) {
1308
+ options[tab] = await readLocalOptions(defaultTabOptions[tab], {
1309
+ root: nuxt.options.rootDir,
1310
+ key: tab !== "ui" && tab
1311
+ });
1312
+ return options;
1313
+ }
1314
+ getOptions2("ui");
1315
+ async function clearOptions() {
1316
+ options = void 0;
1317
+ await clearLocalOptions({
1318
+ root: nuxt.options.rootDir
1319
+ });
1363
1320
  }
1364
1321
  return {
1365
- getTerminals() {
1366
- return Array.from(terminals.values()).map((i) => serializeTerminal(i));
1367
- },
1368
- async getTerminalDetail(token, id) {
1369
- await ensureDevAuthToken(token);
1370
- return serializeTerminal(terminals.get(id), true);
1322
+ async updateOptions(tab, _settings) {
1323
+ const settings = await getOptions2(tab);
1324
+ Object.assign(settings, _settings);
1325
+ await writeLocalOptions(
1326
+ { ...settings },
1327
+ {
1328
+ root: nuxt.options.rootDir,
1329
+ key: tab !== "ui" && tab
1330
+ }
1331
+ );
1332
+ nuxt.callHook("builder:generateApp", {
1333
+ filter(template) {
1334
+ return template.filename.includes("devtools/settings.js");
1335
+ }
1336
+ });
1371
1337
  },
1372
- async runTerminalAction(token, id, action) {
1373
- await ensureDevAuthToken(token);
1374
- const terminal = terminals.get(id);
1375
- if (!terminal)
1376
- return false;
1377
- switch (action) {
1378
- case "restart":
1379
- if (!terminal.onActionRestart)
1380
- return false;
1381
- await terminal.onActionRestart();
1382
- return true;
1383
- case "terminate":
1384
- if (!terminal.onActionTerminate)
1385
- return false;
1386
- await terminal.onActionTerminate();
1387
- return true;
1388
- case "remove":
1389
- if (!terminal.isTerminated)
1390
- terminal.onActionTerminate?.();
1391
- terminals.delete(id);
1392
- refresh("getTerminals");
1393
- return true;
1394
- case "clear":
1395
- terminal.buffer = "";
1396
- refresh("getTerminals");
1397
- return true;
1398
- }
1399
- }
1338
+ getOptions: getOptions2,
1339
+ clearOptions
1400
1340
  };
1401
1341
  }
1402
1342
 
@@ -1478,175 +1418,83 @@ function setupServerTasksRPC({ nuxt, refresh }) {
1478
1418
  }
1479
1419
  return {
1480
1420
  tasks: nitro.options.tasks,
1481
- scheduledTasks: Object.entries(nitro.options.scheduledTasks ?? {}).reduce((acc, [cron, tasks]) => {
1482
- acc[cron] = Array.isArray(tasks) ? tasks : [tasks];
1483
- return acc;
1484
- }, {})
1485
- };
1486
- })();
1487
- return cache;
1488
- }
1489
- return {
1490
- getServerTasks() {
1491
- return scan();
1492
- }
1493
- };
1494
- }
1495
-
1496
- function setupAnalyzeBuildRPC({ nuxt, refresh, ensureDevAuthToken }) {
1497
- let builds = [];
1498
- let promise;
1499
- let initalized;
1500
- const processId = "devtools:analyze-build";
1501
- const analyzeDir = join(nuxt.options.rootDir, ".nuxt/analyze");
1502
- async function startAnalyzeBuild(name) {
1503
- if (promise)
1504
- throw new Error("Already building");
1505
- const result = startSubprocess({
1506
- command: "npx",
1507
- args: ["nuxi", "analyze", "--no-serve", "--name", name],
1508
- cwd: nuxt.options.rootDir
1509
- }, {
1510
- id: processId,
1511
- name: "Analyze Build",
1512
- icon: "logos-nuxt-icon"
1513
- }, nuxt);
1514
- refresh("getAnalyzeBuildInfo");
1515
- promise = result.getProcess().then(() => {
1516
- refresh("getAnalyzeBuildInfo");
1517
- return readBuildInfo();
1518
- }).finally(() => {
1519
- promise = void 0;
1520
- initalized = void 0;
1521
- refresh("getAnalyzeBuildInfo");
1522
- });
1523
- return processId;
1524
- }
1525
- async function readBuildInfo() {
1526
- const files = await glob(["*/meta.json"], { cwd: analyzeDir, onlyFiles: true, absolute: true });
1527
- builds = await Promise.all(files.map(async (file) => {
1528
- const dir = dirname$1(file);
1529
- const json = JSON.parse(await fs.readFile(file, "utf-8"));
1530
- return {
1531
- ...json,
1532
- features: {
1533
- bundleClient: fs$1.existsSync(join(dir, "client.html")),
1534
- bundleNitro: fs$1.existsSync(join(dir, "nitro.html")),
1535
- viteInspect: fs$1.existsSync(join(dir, ".vite-inspect"))
1536
- }
1537
- };
1538
- }));
1539
- return builds.sort((a, b) => b.endTime - a.endTime);
1540
- }
1541
- async function generateAnalyzeBuildName() {
1542
- try {
1543
- const git = Git(nuxt.options.rootDir);
1544
- const branch = await git.branch();
1545
- const branchName = branch.current || "head";
1546
- const sha = await git.revparse(["--short", "HEAD"]);
1547
- const isWorkingTreeClean = (await git.status()).isClean();
1548
- if (isWorkingTreeClean)
1549
- return `${branchName}#${sha}`;
1550
- return `${branchName}#${sha}-dirty`;
1551
- } catch {
1552
- return (/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-");
1553
- }
1554
- }
1555
- return {
1556
- async getAnalyzeBuildInfo() {
1557
- if (!initalized)
1558
- initalized = readBuildInfo();
1559
- await initalized;
1560
- return {
1561
- isBuilding: !!promise,
1562
- builds
1563
- };
1564
- },
1565
- async clearAnalyzeBuilds(token, names) {
1566
- await ensureDevAuthToken(token);
1567
- if (!names) {
1568
- await fs.rm(analyzeDir, { recursive: true, force: true });
1569
- } else {
1570
- const targets = builds.filter((build) => names.includes(build.name));
1571
- await Promise.all(targets.map((target) => fs.rm(join(analyzeDir, target.slug), { recursive: true, force: true })));
1572
- }
1573
- initalized = readBuildInfo();
1574
- refresh("getAnalyzeBuildInfo");
1575
- },
1576
- generateAnalyzeBuildName,
1577
- async startAnalyzeBuild(token, ...args) {
1578
- await ensureDevAuthToken(token);
1579
- return startAnalyzeBuild(...args);
1580
- }
1581
- };
1582
- }
1583
-
1584
- let options;
1585
- function getOptions() {
1586
- return options;
1587
- }
1588
- function setupOptionsRPC({ nuxt }) {
1589
- async function getOptions2(tab) {
1590
- if (!options || options[tab]) {
1591
- options = defaultTabOptions;
1592
- await read(tab);
1593
- }
1594
- return options[tab];
1595
- }
1596
- async function read(tab) {
1597
- options[tab] = await readLocalOptions(defaultTabOptions[tab], {
1598
- root: nuxt.options.rootDir,
1599
- key: tab !== "ui" && tab
1600
- });
1601
- return options;
1602
- }
1603
- getOptions2("ui");
1604
- async function clearOptions() {
1605
- options = void 0;
1606
- await clearLocalOptions({
1607
- root: nuxt.options.rootDir
1608
- });
1421
+ scheduledTasks: Object.entries(nitro.options.scheduledTasks ?? {}).reduce((acc, [cron, tasks]) => {
1422
+ acc[cron] = Array.isArray(tasks) ? tasks : [tasks];
1423
+ return acc;
1424
+ }, {})
1425
+ };
1426
+ })();
1427
+ return cache;
1609
1428
  }
1610
1429
  return {
1611
- async updateOptions(tab, _settings) {
1612
- const settings = await getOptions2(tab);
1613
- Object.assign(settings, _settings);
1614
- await writeLocalOptions(
1615
- { ...settings },
1616
- {
1617
- root: nuxt.options.rootDir,
1618
- key: tab !== "ui" && tab
1619
- }
1620
- );
1621
- nuxt.callHook("builder:generateApp", {
1622
- filter(template) {
1623
- return template.filename.includes("devtools/settings.js");
1624
- }
1625
- });
1626
- },
1627
- getOptions: getOptions2,
1628
- clearOptions
1430
+ getServerTasks() {
1431
+ return scan();
1432
+ }
1629
1433
  };
1630
1434
  }
1631
1435
 
1632
- function setupTimelineRPC({ nuxt }) {
1436
+ const IGNORE_STORAGE_MOUNTS = ["root", "build", "src", "cache"];
1437
+ function shouldIgnoreStorageKey(key) {
1438
+ return IGNORE_STORAGE_MOUNTS.includes(key.split(":")[0]);
1439
+ }
1440
+ function setupStorageRPC({
1441
+ nuxt,
1442
+ rpc,
1443
+ ensureDevAuthToken
1444
+ }) {
1445
+ const storageMounts = {};
1446
+ let storage;
1447
+ nuxt.hook("nitro:init", (nitro) => {
1448
+ storage = nitro.storage;
1449
+ nuxt.hook("ready", () => {
1450
+ storage.watch((event, key) => {
1451
+ if (shouldIgnoreStorageKey(key))
1452
+ return;
1453
+ rpc.broadcast.callHook.asEvent("storage:key:update", key, event);
1454
+ });
1455
+ });
1456
+ const mounts = {
1457
+ ...nitro.options.storage,
1458
+ ...nitro.options.devStorage
1459
+ };
1460
+ for (const name of Object.keys(mounts)) {
1461
+ if (shouldIgnoreStorageKey(name))
1462
+ continue;
1463
+ storageMounts[name] = mounts[name];
1464
+ }
1465
+ });
1633
1466
  return {
1634
- async enableTimeline(dry) {
1635
- const filepath = nuxt.options._nuxtConfigFile;
1636
- const source = await fs.readFile(filepath, "utf-8");
1637
- const generated = await magicastGuard(async () => {
1638
- const mod = parseModule(source, { sourceFileName: filepath });
1639
- const options = getDefaultExportOptions(mod);
1640
- options.devtools = options.devtools || {};
1641
- options.devtools.timeline = options.devtools.timeline || {};
1642
- options.devtools.timeline.enabled = true;
1643
- return mod.generate().code;
1644
- }, "\nYou can enable timeline manually by adding `devtools: { timeline: { enabled: true } }`");
1645
- if (!dry) {
1646
- await fs.writeFile(filepath, generated, "utf-8");
1647
- await nuxt.callHook("restart", { hard: true });
1467
+ async getStorageMounts() {
1468
+ return storageMounts;
1469
+ },
1470
+ async getStorageKeys(base) {
1471
+ if (!storage)
1472
+ return [];
1473
+ try {
1474
+ const keys = await storage.getKeys(base);
1475
+ return keys.filter((key) => !shouldIgnoreStorageKey(key));
1476
+ } catch (err) {
1477
+ console.error(`Cloud not fetch storage keys for ${base}:`, err);
1478
+ return [];
1648
1479
  }
1649
- return [source, generated];
1480
+ },
1481
+ async getStorageItem(token, key) {
1482
+ await ensureDevAuthToken(token);
1483
+ if (!storage)
1484
+ return null;
1485
+ return await storage.getItem(key);
1486
+ },
1487
+ async setStorageItem(token, key, value) {
1488
+ await ensureDevAuthToken(token);
1489
+ if (!storage)
1490
+ return;
1491
+ return await storage.setItem(key, value);
1492
+ },
1493
+ async removeStorageItem(token, key) {
1494
+ await ensureDevAuthToken(token);
1495
+ if (!storage)
1496
+ return;
1497
+ return await storage.removeItem(key);
1650
1498
  }
1651
1499
  };
1652
1500
  }
@@ -1699,6 +1547,158 @@ function telemetryEvent(payload, immediate = false) {
1699
1547
  throttledSend();
1700
1548
  }
1701
1549
 
1550
+ function setupTerminalRPC({ nuxt, rpc, refresh, ensureDevAuthToken }) {
1551
+ const terminals = /* @__PURE__ */ new Map();
1552
+ nuxt.hook("devtools:terminal:register", (terminal) => {
1553
+ terminals.set(terminal.id, terminal);
1554
+ refresh("getTerminals");
1555
+ return terminal.id;
1556
+ });
1557
+ nuxt.hook("devtools:terminal:remove", ({ id }) => {
1558
+ if (!terminals.has(id))
1559
+ return false;
1560
+ terminals.delete(id);
1561
+ refresh("getTerminals");
1562
+ return true;
1563
+ });
1564
+ nuxt.hook("devtools:terminal:write", ({ id, data }) => {
1565
+ const terminal = terminals.get(id);
1566
+ if (!terminal)
1567
+ return false;
1568
+ terminal.buffer ||= "";
1569
+ terminal.buffer += data;
1570
+ rpc.broadcast.onTerminalData.asEvent({ id, data });
1571
+ return true;
1572
+ });
1573
+ nuxt.hook("devtools:terminal:exit", ({ id, code }) => {
1574
+ const terminal = terminals.get(id);
1575
+ if (!terminal)
1576
+ return false;
1577
+ terminal.isTerminated = true;
1578
+ rpc.broadcast.onTerminalExit.asEvent({ id, code });
1579
+ refresh("getTerminals");
1580
+ return true;
1581
+ });
1582
+ function serializeTerminal(terminal, buffer = false) {
1583
+ if (!terminal)
1584
+ return;
1585
+ return {
1586
+ id: terminal.id,
1587
+ name: terminal.name,
1588
+ description: terminal.description,
1589
+ icon: terminal.icon,
1590
+ terminatable: terminal.terminatable ?? !!terminal.onActionTerminate,
1591
+ restartable: terminal.restartable ?? !!terminal.onActionRestart,
1592
+ isTerminated: terminal.isTerminated,
1593
+ buffer: buffer ? terminal.buffer : void 0
1594
+ };
1595
+ }
1596
+ return {
1597
+ getTerminals() {
1598
+ return Array.from(terminals.values()).map((i) => serializeTerminal(i));
1599
+ },
1600
+ async getTerminalDetail(token, id) {
1601
+ await ensureDevAuthToken(token);
1602
+ return serializeTerminal(terminals.get(id), true);
1603
+ },
1604
+ async runTerminalAction(token, id, action) {
1605
+ await ensureDevAuthToken(token);
1606
+ const terminal = terminals.get(id);
1607
+ if (!terminal)
1608
+ return false;
1609
+ switch (action) {
1610
+ case "restart":
1611
+ if (!terminal.onActionRestart)
1612
+ return false;
1613
+ await terminal.onActionRestart();
1614
+ return true;
1615
+ case "terminate":
1616
+ if (!terminal.onActionTerminate)
1617
+ return false;
1618
+ await terminal.onActionTerminate();
1619
+ return true;
1620
+ case "remove":
1621
+ if (!terminal.isTerminated)
1622
+ terminal.onActionTerminate?.();
1623
+ terminals.delete(id);
1624
+ refresh("getTerminals");
1625
+ return true;
1626
+ case "clear":
1627
+ terminal.buffer = "";
1628
+ refresh("getTerminals");
1629
+ return true;
1630
+ }
1631
+ }
1632
+ };
1633
+ }
1634
+
1635
+ function setupTimelineRPC({ nuxt }) {
1636
+ return {
1637
+ async enableTimeline(dry) {
1638
+ const filepath = nuxt.options._nuxtConfigFile;
1639
+ const source = await fs.readFile(filepath, "utf-8");
1640
+ const generated = await magicastGuard(async () => {
1641
+ const mod = parseModule(source, { sourceFileName: filepath });
1642
+ const options = getDefaultExportOptions(mod);
1643
+ options.devtools = options.devtools || {};
1644
+ options.devtools.timeline = options.devtools.timeline || {};
1645
+ options.devtools.timeline.enabled = true;
1646
+ return mod.generate().code;
1647
+ }, "\nYou can enable timeline manually by adding `devtools: { timeline: { enabled: true } }`");
1648
+ if (!dry) {
1649
+ await fs.writeFile(filepath, generated, "utf-8");
1650
+ await nuxt.callHook("restart", { hard: true });
1651
+ }
1652
+ return [source, generated];
1653
+ }
1654
+ };
1655
+ }
1656
+
1657
+ const LOG_PREFIX = colors.cyan("Nuxt DevTools:");
1658
+
1659
+ const pagesIndexTemplate = `<script setup lang="ts">
1660
+ const route = useRoute()
1661
+ <\/script>
1662
+
1663
+ <template>
1664
+ <div>
1665
+ <h1>Nuxt Routing set up successfully!</h1>
1666
+ <p>Current route: {{ route.path }}</p>
1667
+ <a href="https://nuxt.com/docs/getting-started/routing" target="_blank">Learn more about Nuxt Routing</a>
1668
+ </div>
1669
+ </template>
1670
+ `;
1671
+ async function enablePages(nuxt) {
1672
+ const pathApp = join(nuxt.options.srcDir, "app.vue");
1673
+ const pathPageIndex = join(nuxt.options.srcDir, "pages/index.vue");
1674
+ if (fs$1.existsSync(pathPageIndex)) {
1675
+ logger.warn("pages/index.vue already exists, skipping");
1676
+ return;
1677
+ }
1678
+ let appContent = fs$1.existsSync(pathApp) ? await fs.readFile(pathApp, "utf-8") : void 0;
1679
+ await fs.mkdir(dirname$1(pathPageIndex), { recursive: true });
1680
+ await fs.writeFile(pathPageIndex, pagesIndexTemplate, "utf-8");
1681
+ if (appContent && !appContent.includes("<NuxtPage")) {
1682
+ appContent = appContent.replace("</template>", " <NuxtPage />\n</template>").replace(/<NuxtWelcome\s*\/>/, "");
1683
+ await fs.writeFile(pathApp, appContent, "utf-8");
1684
+ }
1685
+ logger.success("Routing creation wizard completed");
1686
+ }
1687
+
1688
+ const wizard = {
1689
+ enablePages
1690
+ };
1691
+
1692
+ function setupWizardRPC({ nuxt, ensureDevAuthToken }) {
1693
+ return {
1694
+ async runWizard(token, name, ...args) {
1695
+ await ensureDevAuthToken(token);
1696
+ logger.info(LOG_PREFIX, `Running wizard ${colors.green(name)}...`);
1697
+ return wizard[name](nuxt, ...args);
1698
+ }
1699
+ };
1700
+ }
1701
+
1702
1702
  function setupRPC(nuxt, options) {
1703
1703
  const serverFunctions = {};
1704
1704
  const extendedRpcMap = /* @__PURE__ */ new Map();