@dxup/nuxt 0.1.1 → 0.2.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.
package/README.md CHANGED
@@ -9,6 +9,7 @@ This is a TypeScript plugin that improves Nuxt DX.
9
9
  ## Features
10
10
 
11
11
  - Update references when renaming auto imported component files
12
+ - Go to definition for dynamic imports with glob patterns
12
13
  - Go to definition for nitro routes in data fetching methods
13
14
  - Go to definition for runtime config
14
15
  - [@dxup/unimport](/packages/unimport)
package/dist/module.d.ts CHANGED
@@ -2,26 +2,33 @@ import * as _nuxt_schema0 from "@nuxt/schema";
2
2
 
3
3
  //#region src/module/index.d.ts
4
4
  interface ModuleOptions {
5
- /**
6
- * Whether to update references when renaming auto imported component files.
7
- * @default true
8
- */
9
- components?: boolean;
10
- /**
11
- * Whether to enable Go to Definition for nitro routes in data fetching methods.
12
- * @default true
13
- */
14
- nitroRoutes?: boolean;
15
- /**
16
- * Whether to enable Go to Definition for runtime config.
17
- * @default true
18
- */
19
- runtimeConfig?: boolean;
20
- /**
21
- * Whether to enable enhanced navigation for auto imported APIs.
22
- * @default true
23
- */
24
- unimport?: boolean;
5
+ features?: {
6
+ /**
7
+ * Whether to update references when renaming auto imported component files.
8
+ * @default true
9
+ */
10
+ components?: boolean;
11
+ /**
12
+ * Whether to enable Go to Definition for dynamic imports with glob patterns.
13
+ * @default true
14
+ */
15
+ importGlob?: boolean;
16
+ /**
17
+ * Whether to enable Go to Definition for nitro routes in data fetching methods.
18
+ * @default true
19
+ */
20
+ nitroRoutes?: boolean;
21
+ /**
22
+ * Whether to enable Go to Definition for runtime config.
23
+ * @default true
24
+ */
25
+ runtimeConfig?: boolean;
26
+ /**
27
+ * Whether to enable enhanced navigation for auto imported APIs.
28
+ * @default true
29
+ */
30
+ unimport?: boolean;
31
+ };
25
32
  }
26
33
  declare const _default: _nuxt_schema0.NuxtModule<ModuleOptions, ModuleOptions, false>;
27
34
  //#endregion
package/dist/module.js CHANGED
@@ -69,15 +69,16 @@ var module_default = defineNuxtModule({
69
69
  name,
70
70
  configKey: "dxup"
71
71
  },
72
- defaults: {
72
+ defaults: { features: {
73
73
  components: true,
74
+ importGlob: true,
74
75
  nitroRoutes: true,
75
76
  runtimeConfig: true,
76
77
  unimport: true
77
- },
78
+ } },
78
79
  async setup(options, nuxt) {
79
80
  const pluginsTs = [{ name: "@dxup/nuxt" }];
80
- if (options.unimport) pluginsTs.unshift({ name: "@dxup/unimport" });
81
+ if (options.features?.unimport) pluginsTs.unshift({ name: "@dxup/unimport" });
81
82
  append(pluginsTs, nuxt.options, "typescript", "tsConfig", "compilerOptions");
82
83
  append(pluginsTs, nuxt.options.nitro, "typescript", "tsConfig", "compilerOptions");
83
84
  append(pluginsTs, nuxt.options, "typescript", "sharedTsConfig", "compilerOptions");
@@ -87,13 +88,14 @@ var module_default = defineNuxtModule({
87
88
  write: true,
88
89
  getContents({ nuxt: nuxt$1 }) {
89
90
  const nitro = useNitro();
90
- const nitroRoutes = options.nitroRoutes && Object.fromEntries(nitro.scannedHandlers.filter((item) => item.route).map((item) => [`${item.route}+${item.method ?? "get"}`, item.handler]));
91
+ const nitroRoutes = options.features?.nitroRoutes && Object.fromEntries(nitro.scannedHandlers.filter((item) => item.route).map((item) => [`${item.route}+${item.method ?? "get"}`, item.handler]));
91
92
  const data = {
92
93
  buildDir: nuxt$1.options.buildDir,
93
94
  configFiles: [...nuxt$1.options._nuxtConfigFiles, ...nuxt$1.options._layers.map((layer) => layer._configFile).filter(Boolean)],
94
- components: options.components,
95
+ components: options.features?.components,
96
+ importGlob: options.features?.importGlob,
95
97
  nitroRoutes,
96
- runtimeConfig: options.runtimeConfig
98
+ runtimeConfig: options.features?.runtimeConfig
97
99
  };
98
100
  return JSON.stringify(data, null, 2);
99
101
  }
@@ -25,6 +25,8 @@ let pathe = require("pathe");
25
25
  pathe = __toESM(pathe);
26
26
  let node_fs_promises = require("node:fs/promises");
27
27
  node_fs_promises = __toESM(node_fs_promises);
28
+ let tinyglobby = require("tinyglobby");
29
+ tinyglobby = __toESM(tinyglobby);
28
30
 
29
31
  //#region src/event/server.ts
30
32
  function createEventServer(info) {
@@ -87,54 +89,17 @@ function getDefinitionAndBoundSpan(context, getDefinitionAndBoundSpan$1) {
87
89
  const { ts, info, data } = context;
88
90
  return (...args) => {
89
91
  const result = getDefinitionAndBoundSpan$1(...args);
90
- if (!result && data.nitroRoutes) {
92
+ if (!result) {
91
93
  const program$1 = info.languageService.getProgram();
92
94
  const sourceFile = program$1.getSourceFile(args[0]);
93
95
  if (!sourceFile) return;
94
96
  const checker = program$1.getTypeChecker();
97
+ let res;
95
98
  for (const node of forEachTouchingNode(ts, sourceFile, args[1])) {
96
- if (!ts.isCallExpression(node) || !ts.isIdentifier(node.expression) || !fetchFunctions.has(node.expression.text) || !node.arguments.length) continue;
97
- const firstArg = node.arguments[0];
98
- const start = firstArg.getStart(sourceFile);
99
- const end = firstArg.getEnd();
100
- if (args[1] < start || args[1] > end) continue;
101
- const resolvedSignature = checker.getResolvedSignature(node);
102
- if (!resolvedSignature) continue;
103
- const typeArguments = checker.getTypeArgumentsForResolvedSignature(resolvedSignature);
104
- let routeType;
105
- let methodType;
106
- if (node.expression.text === "$fetch") {
107
- routeType = typeArguments?.[1];
108
- const symbol = typeArguments?.[2].getProperty("method");
109
- methodType = symbol ? checker.getTypeOfSymbol(symbol) : void 0;
110
- } else {
111
- routeType = typeArguments?.[2];
112
- methodType = typeArguments?.[3];
113
- }
114
- if (!routeType?.isStringLiteral()) continue;
115
- const paths = [];
116
- for (const type of methodType?.isUnion() ? methodType.types : [methodType]) if (type?.isStringLiteral()) {
117
- const path = data.nitroRoutes[`${routeType.value}+${type.value}`];
118
- if (path !== void 0) paths.push(path);
119
- }
120
- return {
121
- textSpan: {
122
- start,
123
- length: end - start
124
- },
125
- definitions: paths.map((path) => ({
126
- fileName: path,
127
- textSpan: {
128
- start: 0,
129
- length: 0
130
- },
131
- kind: ts.ScriptElementKind.scriptElement,
132
- name: path,
133
- containerKind: ts.ScriptElementKind.unknown,
134
- containerName: ""
135
- }))
136
- };
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);
137
101
  }
102
+ if (res) return res;
138
103
  }
139
104
  if (!result?.definitions?.length) return result;
140
105
  const program = info.languageService.getProgram();
@@ -155,6 +120,88 @@ function getDefinitionAndBoundSpan(context, getDefinitionAndBoundSpan$1) {
155
120
  };
156
121
  };
157
122
  }
123
+ function visitImportGlob(ts, info, sourceFile, node, position) {
124
+ if (!ts.isCallExpression(node) || !node.arguments.length) return;
125
+ const firstArg = node.arguments[0];
126
+ const start = firstArg.getStart(sourceFile);
127
+ const end = firstArg.getEnd();
128
+ if (position < start || position > end) return;
129
+ let pattern;
130
+ const callText = node.expression.getText(sourceFile);
131
+ if (callText === "import" && ts.isTemplateExpression(firstArg)) pattern = [firstArg.head.text, ...firstArg.templateSpans.map((span) => span.literal.text)].join("*");
132
+ else if (callText === "import.meta.glob" && ts.isStringLiteral(firstArg)) pattern = firstArg.text;
133
+ if (pattern === void 0) return;
134
+ const resolved = ts.resolveModuleName(pattern, sourceFile.fileName, info.languageServiceHost.getCompilationSettings(), {
135
+ fileExists: () => true,
136
+ readFile: () => ""
137
+ });
138
+ if (!resolved?.resolvedModule) return;
139
+ const extension = (0, pathe.extname)(pattern);
140
+ const arbitrary = `.d${extension}.ts`;
141
+ pattern = resolved.resolvedModule.resolvedFileName;
142
+ if (resolved.resolvedModule.extension === arbitrary) pattern = pattern.slice(0, -arbitrary.length) + extension;
143
+ const fileNames = (0, tinyglobby.globSync)(pattern, { absolute: true });
144
+ return {
145
+ textSpan: {
146
+ start,
147
+ length: end - start
148
+ },
149
+ definitions: fileNames.map((fileName) => ({
150
+ fileName,
151
+ textSpan: {
152
+ start: 0,
153
+ length: 0
154
+ },
155
+ kind: ts.ScriptElementKind.unknown,
156
+ name: fileName,
157
+ containerKind: ts.ScriptElementKind.unknown,
158
+ containerName: ""
159
+ }))
160
+ };
161
+ }
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;
164
+ const firstArg = node.arguments[0];
165
+ const start = firstArg.getStart(sourceFile);
166
+ const end = firstArg.getEnd();
167
+ if (position < start || position > end) return;
168
+ const resolvedSignature = checker.getResolvedSignature(node);
169
+ if (!resolvedSignature) return;
170
+ const typeArguments = checker.getTypeArgumentsForResolvedSignature(resolvedSignature);
171
+ let routeType;
172
+ let methodType;
173
+ if (node.expression.text === "$fetch") {
174
+ routeType = typeArguments?.[1];
175
+ const symbol = typeArguments?.[2].getProperty("method");
176
+ methodType = symbol ? checker.getTypeOfSymbol(symbol) : void 0;
177
+ } else {
178
+ routeType = typeArguments?.[2];
179
+ methodType = typeArguments?.[3];
180
+ }
181
+ if (!routeType?.isStringLiteral()) return;
182
+ 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);
186
+ }
187
+ return {
188
+ textSpan: {
189
+ start,
190
+ length: end - start
191
+ },
192
+ definitions: paths.map((path) => ({
193
+ fileName: path,
194
+ textSpan: {
195
+ start: 0,
196
+ length: 0
197
+ },
198
+ kind: ts.ScriptElementKind.scriptElement,
199
+ name: path,
200
+ containerKind: ts.ScriptElementKind.unknown,
201
+ containerName: ""
202
+ }))
203
+ };
204
+ }
158
205
  function visitRuntimeConfig(context, sourceFile, definition) {
159
206
  const { ts } = context;
160
207
  let definitions = [];
@@ -297,12 +344,12 @@ const plugin = (module$1) => {
297
344
  context.language = (info.project.__vue__ ?? info.project["program"]?.__vue__)?.language;
298
345
  }, 500);
299
346
  for (const [key, method] of [
300
- ["findRenameLocations", findRenameLocations.bind(null, context)],
301
- ["getDefinitionAndBoundSpan", getDefinitionAndBoundSpan.bind(null, context)],
302
- ["getEditsForFileRename", getEditsForFileRename.bind(null, context)]
347
+ ["findRenameLocations", findRenameLocations],
348
+ ["getDefinitionAndBoundSpan", getDefinitionAndBoundSpan],
349
+ ["getEditsForFileRename", getEditsForFileRename]
303
350
  ]) {
304
351
  const original = info.languageService[key];
305
- info.languageService[key] = method(original);
352
+ info.languageService[key] = method(context, original);
306
353
  }
307
354
  return info.languageService;
308
355
  } };
@@ -313,6 +360,7 @@ function createData(ts, info) {
313
360
  buildDir: "",
314
361
  configFiles: [],
315
362
  components: true,
363
+ importGlob: true,
316
364
  nitroRoutes: {},
317
365
  runtimeConfig: true
318
366
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dxup/nuxt",
3
3
  "type": "module",
4
- "version": "0.1.1",
4
+ "version": "0.2.0",
5
5
  "description": "TypeScript plugin for Nuxt",
6
6
  "author": "KazariEX",
7
7
  "license": "MIT",
@@ -19,6 +19,7 @@
19
19
  "@nuxt/kit": "^4.1.3",
20
20
  "chokidar": "^4.0.3",
21
21
  "pathe": "2.0.3",
22
+ "tinyglobby": "^0.2.15",
22
23
  "@dxup/unimport": "^0.1.0"
23
24
  },
24
25
  "devDependencies": {