@volar/typescript 1.7.10 → 1.8.1

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/out/dtsHost.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import type { FileStat, FileType } from '@volar/language-service';
2
- export interface IDtsHost {
3
- stat(uri: string): Promise<FileStat | undefined>;
4
- readFile(fileName: string): Promise<string | undefined>;
5
- readDirectory(dirName: string): Promise<[string, FileType][]>;
6
- }
7
- export declare function createJsDelivrDtsHost(versions?: Record<string, string>, onFetch?: (fileName: string, text: string) => void): IDtsHost;
8
- export declare function getPackageNameOfDtsPath(path: string): string | undefined;
1
+ import { FileSystem, ServiceEnvironment } from '@volar/language-service';
2
+ export declare const jsDelivrUriBase = "https://cdn.jsdelivr.net/npm";
3
+ export declare function decorateServiceEnvironment(env: ServiceEnvironment, jsDelivrUriResolver: ReturnType<typeof createJsDelivrUriResolver>, jsDelivrFs: FileSystem): void;
4
+ export declare function createJsDelivrUriResolver(versions?: Record<string, string>, fileNameBase?: string): {
5
+ uriToFileName: (uri: string) => string | undefined;
6
+ fileNameToUri: (fileName: string) => string | undefined;
7
+ };
8
+ export declare function createJsDelivrFs(): FileSystem;
package/out/dtsHost.js CHANGED
@@ -1,127 +1,203 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getPackageNameOfDtsPath = exports.createJsDelivrDtsHost = void 0;
4
- function createJsDelivrDtsHost(versions = {}, onFetch) {
5
- return new DtsHost(async (fileName) => {
6
- const requestFileName = resolveRequestFileName(fileName);
7
- const url = 'https://cdn.jsdelivr.net/npm/' + requestFileName.slice('/node_modules/'.length);
8
- const text = await fetchText(url);
9
- if (text !== undefined) {
10
- onFetch?.(fileName, text);
11
- }
12
- return text;
13
- }, async (pkg) => {
14
- let version = versions[pkg];
15
- if (!version) {
16
- const data = await fetchJson(`https://data.jsdelivr.com/v1/package/resolve/npm/${pkg}@latest`);
17
- if (data?.version) {
18
- version = data.version;
3
+ exports.createJsDelivrFs = exports.createJsDelivrUriResolver = exports.decorateServiceEnvironment = exports.jsDelivrUriBase = void 0;
4
+ exports.jsDelivrUriBase = 'https://cdn.jsdelivr.net/npm';
5
+ function decorateServiceEnvironment(env, jsDelivrUriResolver, jsDelivrFs) {
6
+ const fileNameToUri = env.fileNameToUri;
7
+ const uriToFileName = env.uriToFileName;
8
+ const fs = env.fs;
9
+ env.fileNameToUri = fileName => {
10
+ return jsDelivrUriResolver.fileNameToUri(fileName) ?? fileNameToUri(fileName);
11
+ };
12
+ env.uriToFileName = fileName => {
13
+ return jsDelivrUriResolver.uriToFileName(fileName) ?? uriToFileName(fileName);
14
+ };
15
+ env.fs = {
16
+ stat(uri) {
17
+ if (jsDelivrUriResolver.uriToFileName(uri)) {
18
+ return jsDelivrFs.stat(uri);
19
19
  }
20
+ return fs?.stat(uri);
21
+ },
22
+ readDirectory(uri) {
23
+ if (jsDelivrUriResolver.uriToFileName(uri)) {
24
+ return jsDelivrFs.readDirectory(uri);
25
+ }
26
+ return fs?.readDirectory(uri) ?? [];
27
+ },
28
+ readFile(uri) {
29
+ if (jsDelivrUriResolver.uriToFileName(uri)) {
30
+ return jsDelivrFs.readFile(uri);
31
+ }
32
+ return fs?.readFile(uri);
33
+ },
34
+ };
35
+ }
36
+ exports.decorateServiceEnvironment = decorateServiceEnvironment;
37
+ function createJsDelivrUriResolver(versions = {}, fileNameBase = '/node_modules') {
38
+ return {
39
+ uriToFileName,
40
+ fileNameToUri,
41
+ };
42
+ function uriToFileName(uri) {
43
+ if (uri === exports.jsDelivrUriBase) {
44
+ return fileNameBase;
20
45
  }
21
- if (!version) {
22
- return [];
46
+ if (uri.startsWith(exports.jsDelivrUriBase + '/')) {
47
+ const path = uri.substring(exports.jsDelivrUriBase.length);
48
+ const pkgName = getPackageName(path);
49
+ if (pkgName?.substring(1).includes('@')) {
50
+ const trimedVersion = pkgName.substring(0, pkgName.lastIndexOf('@'));
51
+ return `${fileNameBase}${path.replace(pkgName, trimedVersion)}`;
52
+ }
53
+ return `${fileNameBase}${path}`;
23
54
  }
24
- const flat = await fetchJson(`https://data.jsdelivr.com/v1/package/npm/${pkg}@${version}/flat`);
25
- if (!flat) {
26
- return [];
55
+ }
56
+ function fileNameToUri(fileName) {
57
+ if (fileName === fileNameBase) {
58
+ return exports.jsDelivrUriBase;
27
59
  }
28
- return flat.files.map(file => file.name);
29
- });
30
- function resolveRequestFileName(fileName) {
31
- for (const [key, version] of Object.entries(versions)) {
32
- if (fileName.startsWith(`/node_modules/${key}/`)) {
33
- fileName = fileName.replace(`/node_modules/${key}/`, `/node_modules/${key}@${version}/`);
34
- return fileName;
60
+ if (fileName.startsWith(fileNameBase + '/')) {
61
+ const path = fileName.substring(fileNameBase.length);
62
+ const pkgName = getPackageName(path);
63
+ if (pkgName) {
64
+ const version = versions[pkgName] ?? 'latest';
65
+ return `${exports.jsDelivrUriBase}/${pkgName}@${version}${path.substring(1 + pkgName.length)}`;
35
66
  }
67
+ return `${exports.jsDelivrUriBase}${path}`;
36
68
  }
37
- return fileName;
38
69
  }
39
70
  }
40
- exports.createJsDelivrDtsHost = createJsDelivrDtsHost;
41
- class DtsHost {
42
- constructor(fetchText, flat) {
43
- this.fetchText = fetchText;
44
- this.flat = flat;
45
- this.fetchResults = new Map();
46
- this.flatResults = new Map();
47
- }
48
- async stat(fileName) {
49
- if (!await this.valid(fileName)) {
50
- return;
51
- }
52
- const pkgName = getPackageNameOfDtsPath(fileName);
53
- if (!pkgName) {
54
- return;
55
- }
56
- if (!this.flatResults.has(pkgName)) {
57
- this.flatResults.set(pkgName, this.flat(pkgName));
58
- }
59
- const flat = await this.flatResults.get(pkgName);
60
- const filePath = fileName.slice(`/node_modules/${pkgName}`.length);
61
- if (flat.includes(filePath)) {
62
- return {
63
- type: 1,
64
- ctime: -1,
65
- mtime: -1,
66
- size: -1,
67
- };
68
- }
69
- else if (flat.some(f => f.startsWith(filePath + '/'))) {
71
+ exports.createJsDelivrUriResolver = createJsDelivrUriResolver;
72
+ function createJsDelivrFs() {
73
+ const fetchResults = new Map();
74
+ const flatResults = new Map();
75
+ return {
76
+ stat,
77
+ readDirectory,
78
+ readFile,
79
+ };
80
+ function stat(uri) {
81
+ if (uri === exports.jsDelivrUriBase) {
70
82
  return {
71
83
  type: 2,
84
+ size: -1,
72
85
  ctime: -1,
73
86
  mtime: -1,
74
- size: -1,
75
87
  };
76
88
  }
77
- }
78
- async readDirectory(dirName) {
79
- if (!await this.valid(dirName)) {
80
- return [];
81
- }
82
- const pkgName = getPackageNameOfDtsPath(dirName);
83
- if (!pkgName) {
84
- return [];
89
+ if (uri.startsWith(exports.jsDelivrUriBase + '/')) {
90
+ const path = uri.substring(exports.jsDelivrUriBase.length);
91
+ const pkgName = getPackageName(path);
92
+ if (!pkgName || !isValidPackageNameSync(pkgName)) {
93
+ return;
94
+ }
95
+ return (async () => {
96
+ if (!await isValidPackageNameAsync(pkgName)) {
97
+ return;
98
+ }
99
+ if (!flatResults.has(pkgName)) {
100
+ flatResults.set(pkgName, flat(pkgName));
101
+ }
102
+ const flatResult = await flatResults.get(pkgName);
103
+ const filePath = path.slice(`/${pkgName}`.length);
104
+ const file = flatResult.find(file => file.name === filePath);
105
+ if (file) {
106
+ return {
107
+ type: 1,
108
+ ctime: new Date(file.time).valueOf(),
109
+ mtime: new Date(file.time).valueOf(),
110
+ size: file.size,
111
+ };
112
+ }
113
+ else if (flatResult.some(file => file.name.startsWith(filePath + '/'))) {
114
+ return {
115
+ type: 2,
116
+ ctime: -1,
117
+ mtime: -1,
118
+ size: -1,
119
+ };
120
+ }
121
+ })();
85
122
  }
86
- if (!this.flatResults.has(pkgName)) {
87
- this.flatResults.set(pkgName, this.flat(pkgName));
88
- }
89
- const flat = await this.flatResults.get(pkgName);
90
- const dirPath = dirName.slice(`/node_modules/${pkgName}`.length);
91
- const files = flat
92
- .filter(f => f.substring(0, f.lastIndexOf('/')) === dirPath)
93
- .map(f => f.slice(dirPath.length + 1));
94
- const dirs = flat
95
- .filter(f => f.startsWith(dirPath + '/') && f.substring(dirPath.length + 1).split('/').length >= 2)
96
- .map(f => f.slice(dirPath.length + 1).split('/')[0]);
97
- return [
98
- ...files.map(f => [f, 1]),
99
- ...[...new Set(dirs)].map(f => [f, 2]),
100
- ];
101
123
  }
102
- async readFile(fileName) {
103
- if (!await this.valid(fileName)) {
104
- return;
124
+ function readDirectory(uri) {
125
+ if (uri.startsWith(exports.jsDelivrUriBase + '/')) {
126
+ const path = uri.substring(exports.jsDelivrUriBase.length);
127
+ const pkgName = getPackageName(path);
128
+ if (!pkgName || !isValidPackageNameSync(pkgName)) {
129
+ return [];
130
+ }
131
+ return (async () => {
132
+ if (!await isValidPackageNameAsync(pkgName)) {
133
+ return [];
134
+ }
135
+ if (!flatResults.has(pkgName)) {
136
+ flatResults.set(pkgName, flat(pkgName));
137
+ }
138
+ const flatResult = await flatResults.get(pkgName);
139
+ const dirPath = path.slice(`/${pkgName}`.length);
140
+ const files = flatResult
141
+ .filter(f => f.name.substring(0, f.name.lastIndexOf('/')) === dirPath)
142
+ .map(f => f.name.slice(dirPath.length + 1));
143
+ const dirs = flatResult
144
+ .filter(f => f.name.startsWith(dirPath + '/') && f.name.substring(dirPath.length + 1).split('/').length >= 2)
145
+ .map(f => f.name.slice(dirPath.length + 1).split('/')[0]);
146
+ return [
147
+ ...files.map(f => [f, 1]),
148
+ ...[...new Set(dirs)].map(f => [f, 2]),
149
+ ];
150
+ })();
105
151
  }
106
- if (!this.fetchResults.has(fileName)) {
107
- this.fetchResults.set(fileName, this.fetchFile(fileName));
152
+ return [];
153
+ }
154
+ function readFile(uri) {
155
+ if (uri.startsWith(exports.jsDelivrUriBase + '/')) {
156
+ const path = uri.substring(exports.jsDelivrUriBase.length);
157
+ const pkgName = getPackageName(path);
158
+ if (!pkgName || !isValidPackageNameSync(pkgName)) {
159
+ return;
160
+ }
161
+ return (async () => {
162
+ if (!await isValidPackageNameAsync(pkgName)) {
163
+ return;
164
+ }
165
+ if (!fetchResults.has(path)) {
166
+ fetchResults.set(path, (async () => {
167
+ if ((await stat(uri))?.type !== 1) {
168
+ return;
169
+ }
170
+ return await fetchText(uri);
171
+ })());
172
+ }
173
+ return await fetchResults.get(path);
174
+ })();
108
175
  }
109
- return await this.fetchResults.get(fileName);
110
176
  }
111
- async fetchFile(fileName) {
112
- const pkgName = getPackageNameOfDtsPath(fileName);
113
- if (!pkgName) {
114
- return undefined;
177
+ async function flat(pkgNameWithVersion) {
178
+ let pkgName = pkgNameWithVersion;
179
+ let version = 'latest';
180
+ if (pkgNameWithVersion.substring(1).includes('@')) {
181
+ pkgName = pkgNameWithVersion.substring(0, pkgNameWithVersion.lastIndexOf('@'));
182
+ version = pkgNameWithVersion.substring(pkgNameWithVersion.lastIndexOf('@') + 1);
115
183
  }
116
- if ((await this.stat(fileName))?.type !== 1) {
117
- return undefined;
184
+ // resolve tag version
185
+ if (version === 'latest') {
186
+ const data = await fetchJson(`https://data.jsdelivr.com/v1/package/resolve/npm/${pkgName}@latest`);
187
+ if (!data?.version) {
188
+ return [];
189
+ }
190
+ version = data.version;
191
+ }
192
+ const flat = await fetchJson(`https://data.jsdelivr.com/v1/package/npm/${pkgName}@${version}/flat`);
193
+ if (!flat) {
194
+ return [];
118
195
  }
119
- return await this.fetchText(fileName);
196
+ return flat.files;
120
197
  }
121
- async valid(fileName) {
122
- const pkgName = getPackageNameOfDtsPath(fileName);
123
- if (!pkgName) {
124
- return false;
198
+ function isValidPackageNameSync(pkgName) {
199
+ if (pkgName.substring(1).includes('@')) {
200
+ pkgName = pkgName.substring(0, pkgName.lastIndexOf('@'));
125
201
  }
126
202
  if (pkgName.indexOf('.') >= 0 || pkgName.endsWith('/node_modules')) {
127
203
  return false;
@@ -130,19 +206,25 @@ class DtsHost {
130
206
  if (pkgName.startsWith('@typescript/') || pkgName.startsWith('@types/typescript__')) {
131
207
  return false;
132
208
  }
209
+ return true;
210
+ }
211
+ async function isValidPackageNameAsync(pkgName) {
212
+ if (pkgName.substring(1).includes('@')) {
213
+ pkgName = pkgName.substring(0, pkgName.lastIndexOf('@'));
214
+ }
133
215
  // don't check @types if original package already having types
134
216
  if (pkgName.startsWith('@types/')) {
135
217
  let originalPkgName = pkgName.slice('@types/'.length);
136
218
  if (originalPkgName.indexOf('__') >= 0) {
137
219
  originalPkgName = '@' + originalPkgName.replace('__', '/');
138
220
  }
139
- const packageJson = await this.readFile(`/node_modules/${originalPkgName}/package.json`);
221
+ const packageJson = await readFile(`${exports.jsDelivrUriBase}/${originalPkgName}/package.json`);
140
222
  if (packageJson) {
141
223
  const packageJsonObj = JSON.parse(packageJson);
142
224
  if (packageJsonObj.types || packageJsonObj.typings) {
143
225
  return false;
144
226
  }
145
- const indexDts = await this.stat(`/node_modules/${originalPkgName}/index.d.ts`);
227
+ const indexDts = await stat(`${exports.jsDelivrUriBase}/${originalPkgName}/index.d.ts`);
146
228
  if (indexDts?.type === 1) {
147
229
  return false;
148
230
  }
@@ -151,6 +233,7 @@ class DtsHost {
151
233
  return true;
152
234
  }
153
235
  }
236
+ exports.createJsDelivrFs = createJsDelivrFs;
154
237
  async function fetchText(url) {
155
238
  try {
156
239
  const res = await fetch(url);
@@ -173,18 +256,21 @@ async function fetchJson(url) {
173
256
  // ignore
174
257
  }
175
258
  }
176
- function getPackageNameOfDtsPath(path) {
177
- if (!path.startsWith('/node_modules/')) {
178
- return undefined;
179
- }
180
- let pkgName = path.split('/')[2];
259
+ /**
260
+ * @example
261
+ * "/a/b/c" -> "a"
262
+ * "/@a/b/c" -> "@a/b"
263
+ * "/@a/b@1.2.3/c" -> "@a/b@1.2.3"
264
+ */
265
+ function getPackageName(path) {
266
+ const parts = path.split('/');
267
+ let pkgName = parts[1];
181
268
  if (pkgName.startsWith('@')) {
182
- if (path.split('/').length < 4) {
269
+ if (parts.length < 3 || !parts[2]) {
183
270
  return undefined;
184
271
  }
185
- pkgName += '/' + path.split('/')[3];
272
+ pkgName += '/' + parts[2];
186
273
  }
187
274
  return pkgName;
188
275
  }
189
- exports.getPackageNameOfDtsPath = getPackageNameOfDtsPath;
190
276
  //# sourceMappingURL=dtsHost.js.map
package/out/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  export * from './documentRegistry';
2
- export * from './dtsHost';
3
2
  export * from './languageService';
4
3
  export * from './languageServiceHost';
5
4
  export * from './sys';
package/out/index.js CHANGED
@@ -15,7 +15,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./documentRegistry"), exports);
18
- __exportStar(require("./dtsHost"), exports);
19
18
  __exportStar(require("./languageService"), exports);
20
19
  __exportStar(require("./languageServiceHost"), exports);
21
20
  __exportStar(require("./sys"), exports);
@@ -1,4 +1,4 @@
1
- import type { LanguageContext } from '@volar/language-service';
1
+ import type { LanguageContext } from '@volar/language-core';
2
2
  import type * as ts from 'typescript/lib/tsserverlibrary';
3
3
  export declare function createLanguageServiceHost(ctx: LanguageContext, ts: typeof import('typescript/lib/tsserverlibrary'), sys: ts.System & {
4
4
  version?: number;
package/out/sys.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import type { ServiceEnvironment, Disposable } from '@volar/language-service';
2
2
  import type * as ts from 'typescript/lib/tsserverlibrary';
3
- import { IDtsHost } from './dtsHost';
4
- export declare function createSys(ts: typeof import('typescript/lib/tsserverlibrary'), env: ServiceEnvironment, dtsHost?: IDtsHost): ts.System & {
3
+ export declare function createSys(ts: typeof import('typescript/lib/tsserverlibrary'), env: ServiceEnvironment): ts.System & {
5
4
  version: number;
6
5
  sync(): Promise<number>;
7
6
  } & Disposable;
package/out/sys.js CHANGED
@@ -3,9 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createSys = void 0;
4
4
  const path_1 = require("path");
5
5
  const utilities_1 = require("./typescript/utilities");
6
- const dtsHost_1 = require("./dtsHost");
7
6
  let currentCwd = '';
8
- function createSys(ts, env, dtsHost) {
7
+ function createSys(ts, env) {
9
8
  let version = 0;
10
9
  const rootPath = env.uriToFileName(env.rootUri.toString());
11
10
  const sys = ts.sys;
@@ -105,17 +104,9 @@ function createSys(ts, env, dtsHost) {
105
104
  function directoryExists(dirName) {
106
105
  dirName = resolvePath(dirName);
107
106
  const dir = getDir(dirName);
108
- if (dirName === '/node_modules' && dtsHost) {
109
- dir.exists = true;
110
- }
111
- else if (dirName.startsWith('/node_modules/') && dtsHost && !(0, dtsHost_1.getPackageNameOfDtsPath)(dirName)) {
112
- dir.exists = true;
113
- }
114
- else if (dir.exists === undefined) {
107
+ if (dir.exists === undefined) {
115
108
  dir.exists = false;
116
- const result = dirName.startsWith('/node_modules/') && dtsHost
117
- ? dtsHost.stat(dirName)
118
- : env.fs?.stat(env.fileNameToUri(dirName));
109
+ const result = env.fs?.stat(env.fileNameToUri(dirName));
119
110
  if (typeof result === 'object' && 'then' in result) {
120
111
  const promise = result;
121
112
  promises.add(promise);
@@ -141,9 +132,7 @@ function createSys(ts, env, dtsHost) {
141
132
  const file = dir.files[baseName] ??= {};
142
133
  if (file.exists === undefined) {
143
134
  file.exists = false;
144
- const result = fileName.startsWith('/node_modules/') && dtsHost
145
- ? dtsHost.stat(fileName)
146
- : env.fs?.stat(env.fileNameToUri(fileName));
135
+ const result = env.fs?.stat(env.fileNameToUri(fileName));
147
136
  if (typeof result === 'object' && 'then' in result) {
148
137
  const promise = result;
149
138
  promises.add(promise);
@@ -192,9 +181,7 @@ function createSys(ts, env, dtsHost) {
192
181
  }
193
182
  file.requested = true;
194
183
  const uri = env.fileNameToUri(fileName);
195
- const result = fileName.startsWith('/node_modules/') && dtsHost
196
- ? dtsHost.readFile(fileName)
197
- : env.fs?.readFile(uri, encoding);
184
+ const result = env.fs?.readFile(uri, encoding);
198
185
  if (typeof result === 'object' && 'then' in result) {
199
186
  const promise = result;
200
187
  promises.add(promise);
@@ -228,9 +215,7 @@ function createSys(ts, env, dtsHost) {
228
215
  return;
229
216
  }
230
217
  dir.requested = true;
231
- const result = dirName.startsWith('/node_modules/') && dtsHost
232
- ? dtsHost.readDirectory(dirName)
233
- : env.fs?.readDirectory(env.fileNameToUri(dirName || '.'));
218
+ const result = env.fs?.readDirectory(env.fileNameToUri(dirName || '.'));
234
219
  if (typeof result === 'object' && 'then' in result) {
235
220
  const promise = result;
236
221
  promises.add(promise);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volar/typescript",
3
- "version": "1.7.10",
3
+ "version": "1.8.1",
4
4
  "main": "out/index.js",
5
5
  "license": "MIT",
6
6
  "files": [
@@ -13,10 +13,10 @@
13
13
  "directory": "packages/typescript"
14
14
  },
15
15
  "dependencies": {
16
- "@volar/language-core": "1.7.10"
16
+ "@volar/language-core": "1.8.1"
17
17
  },
18
18
  "devDependencies": {
19
- "@volar/language-service": "1.7.10"
19
+ "@volar/language-service": "1.8.1"
20
20
  },
21
- "gitHead": "53c67c3fd1d11be3dba0ef199c282e605c980638"
21
+ "gitHead": "1fec004d7e3c5a28c0ad1d6a1d7a41ab98381abd"
22
22
  }