@dxup/nuxt 0.2.0 → 0.2.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.
package/README.md CHANGED
@@ -6,13 +6,8 @@
6
6
 
7
7
  This is a TypeScript plugin that improves Nuxt DX.
8
8
 
9
- ## Features
10
-
11
- - Update references when renaming auto imported component files
12
- - Go to definition for dynamic imports with glob patterns
13
- - Go to definition for nitro routes in data fetching methods
14
- - Go to definition for runtime config
15
- - [@dxup/unimport](/packages/unimport)
9
+ > [!note]
10
+ > It's now an experimental builtin feature of Nuxt. Please refer to the [documentation](https://nuxt.com/docs/4.x/guide/going-further/experimental-features#typescriptplugin) for more details.
16
11
 
17
12
  ## Installation
18
13
 
@@ -31,3 +26,51 @@ export default defineNuxtConfig({
31
26
  ],
32
27
  });
33
28
  ```
29
+
30
+ ## Features
31
+
32
+ ### 1. components
33
+
34
+ Update references when renaming auto imported component files.
35
+
36
+ For example, when renaming `components/foo/bar.vue` to `components/foo/baz.vue`, all usages of `<FooBar />` will be updated to `<FooBaz />`.
37
+
38
+ It only works when the dev server is active.
39
+
40
+ ### 2. importGlob
41
+
42
+ Go to definition for dynamic imports with glob patterns.
43
+
44
+ ```ts
45
+ import(`~/assets/${name}.webp`);
46
+ // ^^^^^^^^^^^^^^^^^^^^^^^
47
+ import.meta.glob("~/assets/*.webp");
48
+ // ^^^^^^^^^^^^^^^^^
49
+ ```
50
+
51
+ ### 3. nitroRoutes
52
+
53
+ Go to definition for nitro routes in data fetching methods.
54
+
55
+ ```ts
56
+ useFetch("/api/foo");
57
+ // ^^^^^^^^^^
58
+ // Also `$fetch` and `useLazyFetch`.
59
+ ```
60
+
61
+ It will fallback to resolve the URL from your `public` directory when no nitro routes match.
62
+
63
+ ### 4. runtimeConfig
64
+
65
+ Go to definition for runtime config.
66
+
67
+ ```vue
68
+ <template>
69
+ {{ $config.public.domain }}
70
+ <!-- ^^^^^^ -->
71
+ </template>
72
+ ```
73
+
74
+ ### 5. unimport
75
+
76
+ Please refer to the [@dxup/unimport](/packages/unimport) package for more details.
@@ -88,19 +88,17 @@ var module_default = defineNuxtModule({
88
88
  write: true,
89
89
  getContents({ nuxt: nuxt$1 }) {
90
90
  const nitro = useNitro();
91
- const nitroRoutes = options.features?.nitroRoutes && Object.fromEntries(nitro.scannedHandlers.filter((item) => item.route).map((item) => [`${item.route}+${item.method ?? "get"}`, item.handler]));
92
91
  const data = {
93
92
  buildDir: nuxt$1.options.buildDir,
93
+ publicDir: nuxt$1.options.dir.public,
94
94
  configFiles: [...nuxt$1.options._nuxtConfigFiles, ...nuxt$1.options._layers.map((layer) => layer._configFile).filter(Boolean)],
95
- components: options.features?.components,
96
- importGlob: options.features?.importGlob,
97
- nitroRoutes,
98
- runtimeConfig: options.features?.runtimeConfig
95
+ nitroRoutes: Object.fromEntries(nitro.scannedHandlers.filter((item) => item.route).map((item) => [`${item.route}+${item.method ?? "get"}`, item.handler])),
96
+ features: options.features
99
97
  };
100
98
  return JSON.stringify(data, null, 2);
101
99
  }
102
100
  });
103
- (await createEventClient(nuxt)).on("components:rename", (data) => onComponentsRename(nuxt, data));
101
+ if (nuxt.options.dev) (await createEventClient(nuxt)).on("components:rename", (data) => onComponentsRename(nuxt, data));
104
102
  }
105
103
  });
106
104
  function append(plugins, target, ...keys) {
@@ -1,32 +1,6 @@
1
- //#region rolldown:runtime
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __copyProps = (to, from, except, desc) => {
9
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
- key = keys[i];
11
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
- get: ((k) => from[k]).bind(null, key),
13
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
- });
15
- }
16
- return to;
17
- };
18
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
- value: mod,
20
- enumerable: true
21
- }) : target, mod));
22
-
23
- //#endregion
24
- let pathe = require("pathe");
25
- pathe = __toESM(pathe);
26
1
  let node_fs_promises = require("node:fs/promises");
27
- node_fs_promises = __toESM(node_fs_promises);
2
+ let pathe = require("pathe");
28
3
  let tinyglobby = require("tinyglobby");
29
- tinyglobby = __toESM(tinyglobby);
30
4
 
31
5
  //#region src/event/server.ts
32
6
  function createEventServer(info) {
@@ -39,6 +13,39 @@ function createEventServer(info) {
39
13
  return { write };
40
14
  }
41
15
 
16
+ //#endregion
17
+ //#region src/typescript/data.ts
18
+ const initialValue = {
19
+ buildDir: "",
20
+ publicDir: "",
21
+ configFiles: [],
22
+ nitroRoutes: {},
23
+ features: {
24
+ components: true,
25
+ importGlob: true,
26
+ nitroRoutes: true,
27
+ runtimeConfig: true
28
+ }
29
+ };
30
+ const callbacks = {};
31
+ function createData(ts, info) {
32
+ const path = (0, pathe.join)(info.languageServiceHost.getCurrentDirectory(), "dxup/data.json");
33
+ const data = {};
34
+ const updates = callbacks[path] ??= (ts.sys.watchFile?.(path, () => {
35
+ const text$1 = ts.sys.readFile(path);
36
+ for (const update of updates) update(text$1);
37
+ }), []);
38
+ updates.push((text$1) => {
39
+ Object.assign(data, {
40
+ ...initialValue,
41
+ ...text$1 ? JSON.parse(text$1) : {}
42
+ });
43
+ });
44
+ const text = ts.sys.readFile(path);
45
+ updates.at(-1)(text);
46
+ return data;
47
+ }
48
+
42
49
  //#endregion
43
50
  //#region src/typescript/features/findRenameLocations.ts
44
51
  function findRenameLocations(context, findRenameLocations$1) {
@@ -74,8 +81,8 @@ function* binaryVisit(ts, sourceFile, node, position) {
74
81
  }
75
82
  }
76
83
  }
77
- function isTextSpanEqual(node, textSpan, sourceFile) {
78
- return textSpan.start + textSpan.length === node.getEnd() && textSpan.start === node.getStart(sourceFile);
84
+ function isTextSpanWithin(node, textSpan, sourceFile) {
85
+ return textSpan.start + textSpan.length <= node.getEnd() && textSpan.start >= node.getStart(sourceFile);
79
86
  }
80
87
 
81
88
  //#endregion
@@ -96,8 +103,8 @@ function getDefinitionAndBoundSpan(context, getDefinitionAndBoundSpan$1) {
96
103
  const checker = program$1.getTypeChecker();
97
104
  let res;
98
105
  for (const node of forEachTouchingNode(ts, sourceFile, args[1])) {
99
- if (data.importGlob) res ??= visitImportGlob(ts, info, sourceFile, node, args[1]);
100
- if (data.nitroRoutes) res ??= visitNitroRoutes(ts, checker, sourceFile, node, args[1], data.nitroRoutes);
106
+ if (data.features.importGlob) res ??= visitImportGlob(ts, info, sourceFile, node, args[1]);
107
+ if (data.features.nitroRoutes) res ??= visitNitroRoutes(ts, data, checker, sourceFile, node, args[1]);
101
108
  }
102
109
  if (res) return res;
103
110
  }
@@ -108,7 +115,7 @@ function getDefinitionAndBoundSpan(context, getDefinitionAndBoundSpan$1) {
108
115
  const sourceFile = program.getSourceFile(definition.fileName);
109
116
  if (!sourceFile) continue;
110
117
  let result$1 = [];
111
- if (data.runtimeConfig && definition.fileName.endsWith("runtime-config.d.ts")) result$1 = visitRuntimeConfig(context, sourceFile, definition);
118
+ if (data.features.runtimeConfig && definition.fileName.endsWith("runtime-config.d.ts")) result$1 = visitRuntimeConfig(context, sourceFile, definition);
112
119
  if (result$1?.length) {
113
120
  for (const definition$1 of result$1) definitions.add(definition$1);
114
121
  definitions.delete(definition);
@@ -159,8 +166,8 @@ function visitImportGlob(ts, info, sourceFile, node, position) {
159
166
  }))
160
167
  };
161
168
  }
162
- function visitNitroRoutes(ts, checker, sourceFile, node, position, nitroRoutes) {
163
- if (!ts.isCallExpression(node) || !ts.isIdentifier(node.expression) || !fetchFunctions.has(node.expression.text) || !node.arguments.length) return;
169
+ function visitNitroRoutes(ts, data, checker, sourceFile, node, position) {
170
+ if (!ts.isCallExpression(node) || !ts.isIdentifier(node.expression) || !fetchFunctions.has(node.expression.text) || !node.arguments.length || !ts.isStringLiteralLike(node.arguments[0])) return;
164
171
  const firstArg = node.arguments[0];
165
172
  const start = firstArg.getStart(sourceFile);
166
173
  const end = firstArg.getEnd();
@@ -178,11 +185,16 @@ function visitNitroRoutes(ts, checker, sourceFile, node, position, nitroRoutes)
178
185
  routeType = typeArguments?.[2];
179
186
  methodType = typeArguments?.[3];
180
187
  }
181
- if (!routeType?.isStringLiteral()) return;
182
188
  const paths = [];
183
- for (const type of methodType?.isUnion() ? methodType.types : [methodType]) if (type?.isStringLiteral()) {
184
- const path = nitroRoutes[`${routeType.value}+${type.value}`];
185
- if (path !== void 0) paths.push(path);
189
+ if (routeType?.isStringLiteral()) {
190
+ for (const type of methodType?.isUnion() ? methodType.types : [methodType]) if (type?.isStringLiteral()) {
191
+ const path = data.nitroRoutes[`${routeType.value}+${type.value}`];
192
+ if (path !== void 0) paths.push(path);
193
+ }
194
+ }
195
+ if (!paths.length && firstArg.text.startsWith("/")) {
196
+ const fallback = (0, pathe.join)(data.publicDir, firstArg.text);
197
+ if (ts.sys.fileExists(fallback)) paths.push(fallback);
186
198
  }
187
199
  return {
188
200
  textSpan: {
@@ -211,7 +223,7 @@ function visitRuntimeConfig(context, sourceFile, definition) {
211
223
  if (ts.isInterfaceDeclaration(node) && ts.isIdentifier(node.name)) key = node.name.text;
212
224
  else if (ts.isPropertySignature(node) && ts.isIdentifier(node.name)) {
213
225
  key = node.name.text;
214
- if (isTextSpanEqual(node.name, definition.textSpan, sourceFile)) {
226
+ if (isTextSpanWithin(node.name, definition.textSpan, sourceFile)) {
215
227
  path.push(key);
216
228
  definitions = [...forwardRuntimeConfig(context, definition, path)];
217
229
  break;
@@ -303,7 +315,7 @@ function getEditsForFileRename(context, getEditsForFileRename$1) {
303
315
  const references = {};
304
316
  for (const change of result) {
305
317
  const { fileName, textChanges } = change;
306
- if (data.components && fileName.endsWith("components.d.ts")) {
318
+ if (data.features.components && fileName.endsWith("components.d.ts")) {
307
319
  const sourceFile = program.getSourceFile(fileName);
308
320
  if (!sourceFile) continue;
309
321
  for (const { span } of textChanges) for (const node of forEachTouchingNode(ts, sourceFile, span.start)) {
@@ -355,28 +367,6 @@ const plugin = (module$1) => {
355
367
  } };
356
368
  };
357
369
  var typescript_default = plugin;
358
- function createData(ts, info) {
359
- const initialValue = {
360
- buildDir: "",
361
- configFiles: [],
362
- components: true,
363
- importGlob: true,
364
- nitroRoutes: {},
365
- runtimeConfig: true
366
- };
367
- const path = (0, pathe.join)(info.languageServiceHost.getCurrentDirectory(), "dxup/data.json");
368
- const data = {};
369
- update();
370
- ts.sys.watchFile?.(path, update);
371
- return data;
372
- function update() {
373
- const text = ts.sys.readFile(path);
374
- Object.assign(data, {
375
- ...initialValue,
376
- ...text ? JSON.parse(text) : {}
377
- });
378
- }
379
- }
380
370
 
381
371
  //#endregion
382
372
  module.exports = typescript_default;
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@dxup/nuxt",
3
3
  "type": "module",
4
- "version": "0.2.0",
4
+ "version": "0.2.2",
5
5
  "description": "TypeScript plugin for Nuxt",
6
6
  "author": "KazariEX",
7
7
  "license": "MIT",
8
8
  "repository": "KazariEX/dxup",
9
9
  "exports": {
10
- ".": "./dist/module.js",
10
+ ".": "./dist/module.mjs",
11
11
  "./package.json": "./package.json"
12
12
  },
13
13
  "main": "./dist/typescript.cjs",
@@ -16,18 +16,18 @@
16
16
  "dist"
17
17
  ],
18
18
  "dependencies": {
19
- "@nuxt/kit": "^4.1.3",
19
+ "@nuxt/kit": "^4.2.1",
20
20
  "chokidar": "^4.0.3",
21
- "pathe": "2.0.3",
21
+ "pathe": "^2.0.3",
22
22
  "tinyglobby": "^0.2.15",
23
- "@dxup/unimport": "^0.1.0"
23
+ "@dxup/unimport": "^0.1.2"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@dxup/shared": "",
27
27
  "@volar/language-core": "^2.4.23",
28
28
  "@volar/typescript": "^2.4.23",
29
- "@vue/language-core": "^3.1.1",
30
- "nuxt": "^4.1.3",
29
+ "@vue/language-core": "^3.1.3",
30
+ "nuxt": "^4.2.1",
31
31
  "typescript": "^5.9.3"
32
32
  },
33
33
  "scripts": {
File without changes