@nuxt/hints 0.0.0 → 1.0.0-alpha.2

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 (169) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +122 -0
  3. package/dist/client/200.html +1 -0
  4. package/dist/client/404.html +1 -0
  5. package/dist/client/_nuxt/2EtD6e53.js +1 -0
  6. package/dist/client/_nuxt/2GP93Pxi.js +1 -0
  7. package/dist/client/_nuxt/3e1v2bzS.js +1 -0
  8. package/dist/client/_nuxt/5i3qLPDT.js +1 -0
  9. package/dist/client/_nuxt/B0m2ddpp.js +1 -0
  10. package/dist/client/_nuxt/B1dDrJ26.js +1 -0
  11. package/dist/client/_nuxt/B6aJPvgy.js +1 -0
  12. package/dist/client/_nuxt/B7mTdjB0.js +1 -0
  13. package/dist/client/_nuxt/BEDo0Tqx.js +1 -0
  14. package/dist/client/_nuxt/BGJmEYvX.js +1 -0
  15. package/dist/client/_nuxt/BHrmToEH.js +1 -0
  16. package/dist/client/_nuxt/BIGW1oBm.js +1 -0
  17. package/dist/client/_nuxt/BLmx8bSh.js +1 -0
  18. package/dist/client/_nuxt/BLtJtn59.js +1 -0
  19. package/dist/client/_nuxt/BPQ3VLAy.js +1 -0
  20. package/dist/client/_nuxt/BXkSAIEj.js +1 -0
  21. package/dist/client/_nuxt/BfHTSMKl.js +1 -0
  22. package/dist/client/_nuxt/BfjtVDDH.js +1 -0
  23. package/dist/client/_nuxt/BgDCqdQA.js +1 -0
  24. package/dist/client/_nuxt/Bkuqu6BP.js +1 -0
  25. package/dist/client/_nuxt/Bp3cYrEr.js +1 -0
  26. package/dist/client/_nuxt/Br6cN0cg.js +1 -0
  27. package/dist/client/_nuxt/BthQWCQV.js +1 -0
  28. package/dist/client/_nuxt/Buea-lGh.js +1 -0
  29. package/dist/client/_nuxt/Bw305WKR.js +1 -0
  30. package/dist/client/_nuxt/BzJJZx-M.js +1 -0
  31. package/dist/client/_nuxt/C-Jbm3Hp.js +1 -0
  32. package/dist/client/_nuxt/C39BiMTA.js +1 -0
  33. package/dist/client/_nuxt/C8M2exoo.js +1 -0
  34. package/dist/client/_nuxt/C9dUb6Cb.js +1 -0
  35. package/dist/client/_nuxt/C9oPPf7i.js +1 -0
  36. package/dist/client/_nuxt/C9tS-k6U.js +1 -0
  37. package/dist/client/_nuxt/CDVJQ6XC.js +1 -0
  38. package/dist/client/_nuxt/CEG3Q07z.js +1 -0
  39. package/dist/client/_nuxt/CFHQjOhq.js +1 -0
  40. package/dist/client/_nuxt/CG6Dc4jp.js +1 -0
  41. package/dist/client/_nuxt/CGQlbfJh.js +6 -0
  42. package/dist/client/_nuxt/CH1njM8p.js +1 -0
  43. package/dist/client/_nuxt/CJC4nrSc.js +1 -0
  44. package/dist/client/_nuxt/CMFEf1DS.js +1 -0
  45. package/dist/client/_nuxt/COt5Ahok.js +1 -0
  46. package/dist/client/_nuxt/CS3Unz2-.js +1 -0
  47. package/dist/client/_nuxt/CTRr51gU.js +1 -0
  48. package/dist/client/_nuxt/CVO1_9PV.js +1 -0
  49. package/dist/client/_nuxt/CVdnzihN.js +1 -0
  50. package/dist/client/_nuxt/CXZktZb0.js +1 -0
  51. package/dist/client/_nuxt/CXtECtnM.js +1 -0
  52. package/dist/client/_nuxt/CYsAdtH9.js +1 -0
  53. package/dist/client/_nuxt/CafNBF8u.js +1 -0
  54. package/dist/client/_nuxt/CbfX1IO0.js +1 -0
  55. package/dist/client/_nuxt/CfQXZHmo.js +1 -0
  56. package/dist/client/_nuxt/CgjmDhmW.js +1 -0
  57. package/dist/client/_nuxt/Cj5Yp3dK.js +1 -0
  58. package/dist/client/_nuxt/CkXjmgJE.js +1 -0
  59. package/dist/client/_nuxt/Cl0AqbOI.js +1 -0
  60. package/dist/client/_nuxt/Cm3UrAx6.js +1 -0
  61. package/dist/client/_nuxt/CmIQRyeF.js +1 -0
  62. package/dist/client/_nuxt/Cmh6b_Ma.js +1 -0
  63. package/dist/client/_nuxt/CnK8MTSM.js +1 -0
  64. package/dist/client/_nuxt/CnnebwVN.js +1 -0
  65. package/dist/client/_nuxt/Cp-IABpG.js +1 -0
  66. package/dist/client/_nuxt/Csfq5Kiy.js +1 -0
  67. package/dist/client/_nuxt/CufHLc7y.js +1 -0
  68. package/dist/client/_nuxt/Cuk6v7N8.js +1 -0
  69. package/dist/client/_nuxt/Cv9koXgw.js +1 -0
  70. package/dist/client/_nuxt/Cvjx9yec.js +1 -0
  71. package/dist/client/_nuxt/Cw07ACep.js +1 -0
  72. package/dist/client/_nuxt/CxbxFI8M.js +1 -0
  73. package/dist/client/_nuxt/CyktbL80.js +1 -0
  74. package/dist/client/_nuxt/CylS5w8V.js +1 -0
  75. package/dist/client/_nuxt/D-2ljcwZ.js +1 -0
  76. package/dist/client/_nuxt/D0r3Knsf.js +1 -0
  77. package/dist/client/_nuxt/D4h5O-jR.js +1 -0
  78. package/dist/client/_nuxt/D5KoaKCx.js +1 -0
  79. package/dist/client/_nuxt/D7VJQ_DO.js +1 -0
  80. package/dist/client/_nuxt/D7oLnXFd.js +1 -0
  81. package/dist/client/_nuxt/D87Tk5Gz.js +1 -0
  82. package/dist/client/_nuxt/DAi9KRSo.js +1 -0
  83. package/dist/client/_nuxt/DDBovgxi.js +1 -0
  84. package/dist/client/_nuxt/DFWUc33u.js +1 -0
  85. package/dist/client/_nuxt/DGP4VlC8.js +1 -0
  86. package/dist/client/_nuxt/DGztddWO.js +1 -0
  87. package/dist/client/_nuxt/DH5Ifo-i.js +1 -0
  88. package/dist/client/_nuxt/DH652Aoo.js +6 -0
  89. package/dist/client/_nuxt/DHJKELXO.js +1 -0
  90. package/dist/client/_nuxt/DJJ7OUMB.js +1 -0
  91. package/dist/client/_nuxt/DNMeEaky.js +1 -0
  92. package/dist/client/_nuxt/DPfMkruS.js +1 -0
  93. package/dist/client/_nuxt/DQyhUUbL.js +1 -0
  94. package/dist/client/_nuxt/DRw_LuNl.js +1 -0
  95. package/dist/client/_nuxt/DU1UobuO.js +1 -0
  96. package/dist/client/_nuxt/DU4nAREn.js +9 -0
  97. package/dist/client/_nuxt/DUszq2jm.js +1 -0
  98. package/dist/client/_nuxt/DVMEJ2y_.js +1 -0
  99. package/dist/client/_nuxt/DWedfzmr.js +1 -0
  100. package/dist/client/_nuxt/DXbdFlpD.js +1 -0
  101. package/dist/client/_nuxt/DZxFcAj9.js +1 -0
  102. package/dist/client/_nuxt/DcaNXYhu.js +1 -0
  103. package/dist/client/_nuxt/Ddv68eIx.js +1 -0
  104. package/dist/client/_nuxt/Des-eS-w.js +1 -0
  105. package/dist/client/_nuxt/DiinP2Uv.js +1 -0
  106. package/dist/client/_nuxt/DnULxvSX.js +1 -0
  107. package/dist/client/_nuxt/Do-INFgi.js +1 -0
  108. package/dist/client/_nuxt/DqwNpetd.js +1 -0
  109. package/dist/client/_nuxt/Dx-B1_4e.js +1 -0
  110. package/dist/client/_nuxt/DxNHbxmM.js +1 -0
  111. package/dist/client/_nuxt/DxSwrfjg.js +1 -0
  112. package/dist/client/_nuxt/E3gJ1_iC.js +1 -0
  113. package/dist/client/_nuxt/GsRaNv29.js +1 -0
  114. package/dist/client/_nuxt/L9t79GZl.js +1 -0
  115. package/dist/client/_nuxt/MKoRwnMq.js +1 -0
  116. package/dist/client/_nuxt/MzD3tlZU.js +1 -0
  117. package/dist/client/_nuxt/NleAzG8P.js +1 -0
  118. package/dist/client/_nuxt/PoHY5YXO.js +1 -0
  119. package/dist/client/_nuxt/TsXTqZ29.js +1 -0
  120. package/dist/client/_nuxt/Xqf5ue2O.js +1 -0
  121. package/dist/client/_nuxt/Yzrsuije.js +1 -0
  122. package/dist/client/_nuxt/bN70gL4F.js +1 -0
  123. package/dist/client/_nuxt/builds/latest.json +1 -0
  124. package/dist/client/_nuxt/builds/meta/13453bb2-1adb-44c7-ac19-ec44784e7219.json +1 -0
  125. package/dist/client/_nuxt/eOWES_5F.js +1 -0
  126. package/dist/client/_nuxt/entry.CqH3PPiL.css +1 -0
  127. package/dist/client/_nuxt/error-404.CrTd3IxL.css +1 -0
  128. package/dist/client/_nuxt/error-500.evxQRSU6.css +1 -0
  129. package/dist/client/_nuxt/fuZLfV_i.js +1 -0
  130. package/dist/client/_nuxt/g9-lgVsj.js +1 -0
  131. package/dist/client/_nuxt/hJgmCMqR.js +1 -0
  132. package/dist/client/_nuxt/hegEt444.js +1 -0
  133. package/dist/client/_nuxt/hydration.B5wxUWyr.css +1 -0
  134. package/dist/client/_nuxt/m17aaUwq.js +1 -0
  135. package/dist/client/_nuxt/nO2mFgKf.js +1 -0
  136. package/dist/client/_nuxt/qj2RPQZX.js +1 -0
  137. package/dist/client/_nuxt/rlWm2Bc0.js +1 -0
  138. package/dist/client/_nuxt/sLvN_949.js +1 -0
  139. package/dist/client/_nuxt/tqtdBwhO.js +1 -0
  140. package/dist/client/_nuxt/umNIi3wV.js +21 -0
  141. package/dist/client/_nuxt/wDzz0qaB.js +1 -0
  142. package/dist/client/_nuxt/z9IIGYC-.js +1 -0
  143. package/dist/client/hydration/index.html +1 -0
  144. package/dist/client/index.html +1 -0
  145. package/dist/client/third-party-scripts/index.html +1 -0
  146. package/dist/client/web-vitals/index.html +1 -0
  147. package/dist/module.d.mts +9 -0
  148. package/dist/module.json +9 -0
  149. package/dist/module.mjs +115 -0
  150. package/dist/runtime/core/components/nuxt-island.d.ts +137 -0
  151. package/dist/runtime/core/components/nuxt-island.js +14 -0
  152. package/dist/runtime/core/plugins/vue-tracer-state.client.d.ts +2 -0
  153. package/dist/runtime/core/plugins/vue-tracer-state.client.js +7 -0
  154. package/dist/runtime/hydration/composables.d.ts +5 -0
  155. package/dist/runtime/hydration/composables.js +46 -0
  156. package/dist/runtime/hydration/plugin.client.d.ts +2 -0
  157. package/dist/runtime/hydration/plugin.client.js +11 -0
  158. package/dist/runtime/third-party-scripts/nitro.plugin.d.ts +2 -0
  159. package/dist/runtime/third-party-scripts/nitro.plugin.js +48 -0
  160. package/dist/runtime/third-party-scripts/plugin.client.d.ts +2 -0
  161. package/dist/runtime/third-party-scripts/plugin.client.js +88 -0
  162. package/dist/runtime/types.d.ts +48 -0
  163. package/dist/runtime/web-vitals/plugin.client.d.ts +13 -0
  164. package/dist/runtime/web-vitals/plugin.client.js +137 -0
  165. package/dist/runtime/web-vitals/utils.d.ts +35 -0
  166. package/dist/runtime/web-vitals/utils.js +13 -0
  167. package/dist/types.d.mts +3 -0
  168. package/package.json +61 -2
  169. /package/dist/{.gitkeep → client/_nuxt/third-party-scripts.tn0RQdqM.css} +0 -0
@@ -0,0 +1,137 @@
1
+ import { defineNuxtPlugin, useNuxtApp } from "#imports";
2
+ import { onINP, onLCP, onCLS } from "web-vitals/attribution";
3
+ import { defu } from "defu";
4
+ import { ref } from "vue";
5
+ function isImgElement(element) {
6
+ return element instanceof Element && element.tagName === "IMG";
7
+ }
8
+ export default defineNuxtPlugin({
9
+ name: "nuxt-hints:performance",
10
+ setup() {
11
+ const nuxtApp = useNuxtApp();
12
+ nuxtApp.__hints = defu(nuxtApp.__hints, {
13
+ webvitals: {
14
+ lcp: ref([]),
15
+ inp: ref([]),
16
+ cls: ref([])
17
+ }
18
+ });
19
+ nuxtApp.hook("hints:webvitals:sync", (webvitals) => {
20
+ webvitals.lcp.value = [...nuxtApp.__hints.webvitals.lcp.value];
21
+ webvitals.inp.value = [...nuxtApp.__hints.webvitals.inp.value];
22
+ webvitals.cls.value = [...nuxtApp.__hints.webvitals.cls.value];
23
+ });
24
+ nuxtApp.hook("app:mounted", () => {
25
+ onINP((metric) => {
26
+ if (metric.rating === "good") {
27
+ return;
28
+ }
29
+ console.info(
30
+ "[@nuxt/hints:web-vitals] INP Metric: ",
31
+ metric
32
+ );
33
+ nuxtApp.__hints.webvitals.inp.value.push(metric);
34
+ nuxtApp.callHook("hints:webvitals:inp", metric);
35
+ }, {
36
+ reportAllChanges: true
37
+ });
38
+ onLCP((metric) => {
39
+ if (metric.rating === "good") {
40
+ return;
41
+ }
42
+ console.info(
43
+ `[@nuxt/hints:web-vitals] LCP Metric: `,
44
+ metric
45
+ );
46
+ nuxtApp.__hints.webvitals.lcp.value.push(metric);
47
+ nuxtApp.callHook("hints:webvitals:lcp", metric);
48
+ for (const performanceEntry of metric.entries) {
49
+ if (!performanceEntry.element || !isImgElement(performanceEntry.element)) {
50
+ continue;
51
+ }
52
+ if (performanceEntry.element.attributes?.getNamedItem("loading")?.value === "lazy") {
53
+ console.warn(
54
+ '[@nuxt/hints:performance] LCP Element should not have `loading="lazy"` \n\n Learn more: https://web.dev/optimize-lcp/#optimize-the-priority-the-resource-is-given'
55
+ );
56
+ }
57
+ if (hasImageFormat(performanceEntry.element.src)) {
58
+ if (!performanceEntry.element.src.includes("webp") || !performanceEntry.element.src.includes("avif")) {
59
+ console.warn(
60
+ "[@nuxt/hints:performance] LCP Element can be served in a next gen format like `webp` or `avif` \n\n Learn more: https://web.dev/choose-the-right-image-format/ \n\n Use: https://image.nuxt.com/usage/nuxt-img#format"
61
+ );
62
+ }
63
+ }
64
+ if (performanceEntry.element.fetchPriority !== "high") {
65
+ console.warn(
66
+ '[@nuxt/hints:performance] LCP Element can have `fetchPriority="high"` to load as soon as possible \n\n Learn more: https://web.dev/optimize-lcp/#optimize-the-priority-the-resource-is-given'
67
+ );
68
+ }
69
+ if (!performanceEntry.element.attributes.getNamedItem("height") || !performanceEntry.element.attributes.getNamedItem("width")) {
70
+ console.warn(
71
+ "[@nuxt/hints:performance] Images should have `width` and `height` sizes set \n\n Learn more: https://web.dev/optimize-cls/#images-without-dimensions \n\n Use: https://image.nuxt.com/usage/nuxt-img#width-height"
72
+ );
73
+ }
74
+ if (performanceEntry.startTime > 2500) {
75
+ console.warn(
76
+ `[@nuxt/hints:performance] LCP Element loaded in ${performanceEntry.startTime} miliseconds. Good result is below 2500 miliseconds
77
+
78
+ Learn more: https://web.dev/lcp/#what-is-a-good-lcp-score`
79
+ );
80
+ }
81
+ if (!isElementPreloaded(performanceEntry.element.src)) {
82
+ console.warn(
83
+ "[@nuxt/hints:performance] LCP Element can be preloaded in `head` to improve load time \n\n Learn more: https://web.dev/optimize-lcp/#optimize-when-the-resource-is-discovered \n\n Use: https://image.nuxt.com/usage/nuxt-img#preload"
84
+ );
85
+ }
86
+ }
87
+ }, {
88
+ reportAllChanges: true
89
+ });
90
+ onCLS((metric) => {
91
+ if (metric.rating === "good") {
92
+ return;
93
+ }
94
+ console.info(
95
+ "[@nuxt/hints:web-vitals] CLS Metric: ",
96
+ metric
97
+ );
98
+ nuxtApp.callHook(
99
+ "hints:webvitals:cls",
100
+ metric
101
+ );
102
+ nuxtApp.__hints.webvitals.cls.value.push(metric);
103
+ for (const entry of metric.entries) {
104
+ const performanceEntry = entry;
105
+ if (!performanceEntry.sources?.[0]) return;
106
+ const sourceElement = performanceEntry.sources?.[0].node;
107
+ if (!sourceElement || sourceElement.parentElement?.className.includes("nuxt-devtools")) return;
108
+ console.info(
109
+ "[@nuxt/hints:performance] Potential CLS Element: ",
110
+ sourceElement
111
+ );
112
+ if ((performanceEntry.value ?? 0) > 0.1) {
113
+ console.warn(
114
+ `[@nuxt/hints:performance] CLS was ${performanceEntry.value}. Good result is below 0.1
115
+
116
+ Learn more: https://web.dev/articles/cls#what-is-a-good-cls-score`
117
+ );
118
+ }
119
+ if (isImgElement(sourceElement) && (!sourceElement.attributes.getNamedItem("height") || !sourceElement.attributes.getNamedItem("width"))) {
120
+ console.warn(
121
+ "[@nuxt/hints:performance] Images should have `width` and `height` sizes set \n\n Learn more: https://web.dev/optimize-cls/#images-without-dimensions \n\n Use: https://image.nuxt.com/usage/nuxt-img#width-height"
122
+ );
123
+ }
124
+ }
125
+ });
126
+ });
127
+ }
128
+ });
129
+ const hasImageFormat = (src) => {
130
+ const imageFormats = ["avif", "jpg", "jpeg", "png", "webp"];
131
+ return imageFormats.some((format) => src.includes(format));
132
+ };
133
+ const isElementPreloaded = (src) => {
134
+ return Array.from(document.head.childNodes).filter(
135
+ (el) => el.nodeName === "LINK" && el.attributes.href.value === src
136
+ ).length;
137
+ };
@@ -0,0 +1,35 @@
1
+ export declare enum ImagePerformanceIssueType {
2
+ LazyAttrOnLCPElement = 0,
3
+ ImgFormat = 1,
4
+ FetchPriorityMissingOnLCPElement = 2,
5
+ HeightWidthMissingOnLCPElement = 3,
6
+ LoadingTooLong = 4,
7
+ PreloadMissingOnLCPElement = 5
8
+ }
9
+ type LazyAttrOnLCPElementDetails = {
10
+ type: ImagePerformanceIssueType.LazyAttrOnLCPElement;
11
+ };
12
+ type ImgFormatDetails = {
13
+ type: ImagePerformanceIssueType.ImgFormat;
14
+ };
15
+ type FetchPriorityMissingOnLCPElementDetails = {
16
+ type: ImagePerformanceIssueType.FetchPriorityMissingOnLCPElement;
17
+ };
18
+ type HeightWidthMissingOnLCPElementDetails = {
19
+ type: ImagePerformanceIssueType.HeightWidthMissingOnLCPElement;
20
+ };
21
+ type LoadingTooLongDetails = {
22
+ type: ImagePerformanceIssueType.LoadingTooLong;
23
+ };
24
+ type PreloadMissingOnLCPElementDetails = {
25
+ type: ImagePerformanceIssueType.PreloadMissingOnLCPElement;
26
+ };
27
+ export type ImagePerformanceIssueDetails = LazyAttrOnLCPElementDetails | ImgFormatDetails | FetchPriorityMissingOnLCPElementDetails | HeightWidthMissingOnLCPElementDetails | LoadingTooLongDetails | PreloadMissingOnLCPElementDetails;
28
+ export declare enum CLSIssueType {
29
+ LayoutShiftTooBig = 0
30
+ }
31
+ type LayoutShiftTooBigDetails = {
32
+ type: CLSIssueType.LayoutShiftTooBig;
33
+ };
34
+ export type CLSIssueDetails = LayoutShiftTooBigDetails;
35
+ export {};
@@ -0,0 +1,13 @@
1
+ export var ImagePerformanceIssueType = /* @__PURE__ */ ((ImagePerformanceIssueType2) => {
2
+ ImagePerformanceIssueType2[ImagePerformanceIssueType2["LazyAttrOnLCPElement"] = 0] = "LazyAttrOnLCPElement";
3
+ ImagePerformanceIssueType2[ImagePerformanceIssueType2["ImgFormat"] = 1] = "ImgFormat";
4
+ ImagePerformanceIssueType2[ImagePerformanceIssueType2["FetchPriorityMissingOnLCPElement"] = 2] = "FetchPriorityMissingOnLCPElement";
5
+ ImagePerformanceIssueType2[ImagePerformanceIssueType2["HeightWidthMissingOnLCPElement"] = 3] = "HeightWidthMissingOnLCPElement";
6
+ ImagePerformanceIssueType2[ImagePerformanceIssueType2["LoadingTooLong"] = 4] = "LoadingTooLong";
7
+ ImagePerformanceIssueType2[ImagePerformanceIssueType2["PreloadMissingOnLCPElement"] = 5] = "PreloadMissingOnLCPElement";
8
+ return ImagePerformanceIssueType2;
9
+ })(ImagePerformanceIssueType || {});
10
+ export var CLSIssueType = /* @__PURE__ */ ((CLSIssueType2) => {
11
+ CLSIssueType2[CLSIssueType2["LayoutShiftTooBig"] = 0] = "LayoutShiftTooBig";
12
+ return CLSIssueType2;
13
+ })(CLSIssueType || {});
@@ -0,0 +1,3 @@
1
+ export { default } from './module.mjs'
2
+
3
+ export { type ModuleOptions } from './module.mjs'
package/package.json CHANGED
@@ -1,8 +1,67 @@
1
1
  {
2
2
  "name": "@nuxt/hints",
3
- "version": "0.0.0",
3
+ "version": "1.0.0-alpha.2",
4
+ "description": "Nuxt module that shows hints for aspects of your application such as Performance, Security, and more!",
5
+ "repository": "https://github.com/nuxt/hints",
6
+ "homepage": "https://github.com/nuxt/hints",
7
+ "license": "MIT",
8
+ "type": "module",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/types.d.mts",
12
+ "import": "./dist/module.mjs"
13
+ },
14
+ "./runtime/*": {
15
+ "types": "./dist/runtime/*",
16
+ "import": "./dist/runtime/*"
17
+ }
18
+ },
19
+ "main": "./dist/module.mjs",
4
20
  "files": [
5
21
  "dist"
6
22
  ],
7
- "author": "Daniel Roe <daniel@roe.dev>"
23
+ "dependencies": {
24
+ "@nuxt/devtools-kit": "^3.0.0",
25
+ "@nuxt/kit": "^4.1.2",
26
+ "h3": "^1.15.4",
27
+ "magic-string": "^0.30.19",
28
+ "nitropack": "^2.12.6",
29
+ "shiki": "^3.13.0",
30
+ "sirv": "^3.0.2",
31
+ "unplugin": "^2.3.10",
32
+ "vite-plugin-vue-tracer": "^1.0.1",
33
+ "web-vitals": "^5.1.0"
34
+ },
35
+ "devDependencies": {
36
+ "@nuxt/devtools": "^3.0.0",
37
+ "@nuxt/devtools-ui-kit": "^3.0.0",
38
+ "@nuxt/eslint": "^1.9.0",
39
+ "@nuxt/icon": "^2.0.0",
40
+ "@nuxt/module-builder": "^1.0.0",
41
+ "@nuxt/schema": "^4.1.2",
42
+ "@nuxt/test-utils": "^3.19.2",
43
+ "@shikijs/transformers": "^3.15.0",
44
+ "@types/node": "^24.0.0",
45
+ "changelogen": "^0.6.0",
46
+ "diff": "^8.0.2",
47
+ "eslint": "^9.36.0",
48
+ "happy-dom": "^20.0.10",
49
+ "pkg-pr-new": "0.0.60",
50
+ "rimraf": "^6.0.1",
51
+ "sass-embedded": "^1.93.3",
52
+ "vitest": "^4.0.0"
53
+ },
54
+ "scripts": {
55
+ "client:build": "nuxi generate client",
56
+ "client:dev": "nuxi dev client --port 3300",
57
+ "dev": "nuxi dev playground",
58
+ "dev:build": "nuxi build playground",
59
+ "dev:prepare": "nuxt-module-build build --stub && nuxi prepare && nuxi prepare playground",
60
+ "release": "npm run lint && npm run test && npm run prepack && changelogen --release && npm publish && git push --follow-tags",
61
+ "lint": "eslint .",
62
+ "test": "vitest run",
63
+ "test:types": "tsc --noEmit",
64
+ "test:watch": "vitest watch",
65
+ "cleanup": "rimraf **/node_modules **/dist **/.output **/.nuxt --glob"
66
+ }
8
67
  }