cspell-io 9.0.2 → 9.1.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/dist/index.d.ts +440 -408
- package/dist/index.js +1316 -1290
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -1,1498 +1,1524 @@
|
|
|
1
|
-
|
|
1
|
+
import { isFileURL, isUrlLike, toFileURL, toURL, urlBasename, urlParent as urlDirname } from "@cspell/url";
|
|
2
|
+
import * as zlib from "node:zlib";
|
|
3
|
+
import { gunzipSync, gzip } from "node:zlib";
|
|
4
|
+
import { ServiceBus, createResponse, createResponseFail, isServiceResponseSuccess, requestFactory } from "@cspell/cspell-service-bus";
|
|
5
|
+
import * as fs from "node:fs";
|
|
6
|
+
import { promises, readFileSync, statSync } from "node:fs";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
import { promisify } from "node:util";
|
|
9
|
+
import * as Stream from "node:stream";
|
|
10
|
+
import assert from "node:assert";
|
|
11
|
+
|
|
12
|
+
//#region src/async/asyncIterable.ts
|
|
13
|
+
/**
|
|
14
|
+
* Reads an entire iterable and converts it into a promise.
|
|
15
|
+
* @param asyncIterable the async iterable to wait for.
|
|
16
|
+
*/
|
|
2
17
|
async function toArray(asyncIterable) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
7
|
-
return data;
|
|
18
|
+
const data = [];
|
|
19
|
+
for await (const item of asyncIterable) data.push(item);
|
|
20
|
+
return data;
|
|
8
21
|
}
|
|
9
22
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if (_CFileReference.isCFileReference(fileReference)) return fileReference;
|
|
42
|
-
if (fileReference instanceof URL) return new _CFileReference(fileReference, encoding, baseFilename, gz);
|
|
43
|
-
return new _CFileReference(
|
|
44
|
-
fileReference.url,
|
|
45
|
-
fileReference.encoding,
|
|
46
|
-
fileReference.baseFilename,
|
|
47
|
-
fileReference.gz
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
toJson() {
|
|
51
|
-
return {
|
|
52
|
-
url: this.url.href,
|
|
53
|
-
encoding: this.encoding,
|
|
54
|
-
baseFilename: this.baseFilename,
|
|
55
|
-
gz: this.gz
|
|
56
|
-
};
|
|
57
|
-
}
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/common/CFileReference.ts
|
|
25
|
+
var CFileReference = class CFileReference {
|
|
26
|
+
/**
|
|
27
|
+
* Use to ensure the nominal type separation between CFileReference and FileReference
|
|
28
|
+
* See: https://github.com/microsoft/TypeScript/wiki/FAQ#when-and-why-are-classes-nominal
|
|
29
|
+
*/
|
|
30
|
+
_;
|
|
31
|
+
gz;
|
|
32
|
+
constructor(url, encoding, baseFilename, gz) {
|
|
33
|
+
this.url = url;
|
|
34
|
+
this.encoding = encoding;
|
|
35
|
+
this.baseFilename = baseFilename;
|
|
36
|
+
this.gz = gz ?? (baseFilename?.endsWith(".gz") || void 0) ?? (url.pathname.endsWith(".gz") || void 0);
|
|
37
|
+
}
|
|
38
|
+
static isCFileReference(obj) {
|
|
39
|
+
return obj instanceof CFileReference;
|
|
40
|
+
}
|
|
41
|
+
static from(fileReference, encoding, baseFilename, gz) {
|
|
42
|
+
if (CFileReference.isCFileReference(fileReference)) return fileReference;
|
|
43
|
+
if (fileReference instanceof URL) return new CFileReference(fileReference, encoding, baseFilename, gz);
|
|
44
|
+
return new CFileReference(fileReference.url, fileReference.encoding, fileReference.baseFilename, fileReference.gz);
|
|
45
|
+
}
|
|
46
|
+
toJson() {
|
|
47
|
+
return {
|
|
48
|
+
url: this.url.href,
|
|
49
|
+
encoding: this.encoding,
|
|
50
|
+
baseFilename: this.baseFilename,
|
|
51
|
+
gz: this.gz
|
|
52
|
+
};
|
|
53
|
+
}
|
|
58
54
|
};
|
|
55
|
+
/**
|
|
56
|
+
*
|
|
57
|
+
* @param file - a URL, file path, or FileReference
|
|
58
|
+
* @param encoding - optional encoding used to decode the file.
|
|
59
|
+
* @param baseFilename - optional base filename used with data URLs.
|
|
60
|
+
* @param gz - optional flag to indicate if the file is gzipped.
|
|
61
|
+
* @returns a FileReference
|
|
62
|
+
*/
|
|
59
63
|
function toFileReference(file, encoding, baseFilename, gz) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
64
|
+
const fileReference = typeof file === "string" ? toFileURL(file) : file;
|
|
65
|
+
if (fileReference instanceof URL) return new CFileReference(fileReference, encoding, baseFilename, gz);
|
|
66
|
+
return CFileReference.from(fileReference);
|
|
63
67
|
}
|
|
64
68
|
function isFileReference(ref) {
|
|
65
|
-
|
|
69
|
+
return CFileReference.isCFileReference(ref) || !(ref instanceof URL) && typeof ref !== "string";
|
|
66
70
|
}
|
|
67
71
|
function renameFileReference(ref, newUrl) {
|
|
68
|
-
|
|
72
|
+
return new CFileReference(newUrl, ref.encoding, ref.baseFilename, ref.gz);
|
|
69
73
|
}
|
|
70
74
|
function toFileResourceRequest(file, encoding, signal) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
75
|
+
const fileReference = typeof file === "string" ? toFileURL(file) : file;
|
|
76
|
+
if (fileReference instanceof URL) return {
|
|
77
|
+
url: fileReference,
|
|
78
|
+
encoding,
|
|
79
|
+
signal
|
|
80
|
+
};
|
|
81
|
+
return {
|
|
82
|
+
url: fileReference.url,
|
|
83
|
+
encoding: encoding ?? fileReference.encoding,
|
|
84
|
+
signal
|
|
85
|
+
};
|
|
74
86
|
}
|
|
75
87
|
|
|
76
|
-
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region src/errors/errors.ts
|
|
77
90
|
var ErrorNotImplemented = class extends Error {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
91
|
+
constructor(method, options) {
|
|
92
|
+
super(`Method ${method} is not supported.`, options);
|
|
93
|
+
this.method = method;
|
|
94
|
+
}
|
|
82
95
|
};
|
|
83
96
|
var AssertionError = class extends Error {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
97
|
+
constructor(message, options) {
|
|
98
|
+
super(message, options);
|
|
99
|
+
this.message = message;
|
|
100
|
+
}
|
|
88
101
|
};
|
|
89
102
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
103
|
+
//#endregion
|
|
104
|
+
//#region src/errors/assert.ts
|
|
105
|
+
function assert$1(value, message) {
|
|
106
|
+
if (!value) throw new AssertionError(message ?? "Assertion failed");
|
|
95
107
|
}
|
|
96
108
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
109
|
+
//#endregion
|
|
110
|
+
//#region src/common/arrayBuffers.ts
|
|
111
|
+
/**
|
|
112
|
+
* Treat a ArrayBufferView as a Uint8Array.
|
|
113
|
+
* The Uint8Array will share the same underlying ArrayBuffer.
|
|
114
|
+
* @param data - source data
|
|
115
|
+
* @returns Uint8Array
|
|
116
|
+
*/
|
|
101
117
|
function asUint8Array(data) {
|
|
102
|
-
|
|
118
|
+
return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
103
119
|
}
|
|
104
120
|
function arrayBufferViewToBuffer(data) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
121
|
+
if (data instanceof Buffer) return data;
|
|
122
|
+
const buf = Buffer.from(data.buffer);
|
|
123
|
+
if (data.byteOffset === 0 && data.byteLength === data.buffer.byteLength) return buf;
|
|
124
|
+
return buf.subarray(data.byteOffset, data.byteOffset + data.byteLength);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Copy the data buffer.
|
|
128
|
+
* @param data - source data
|
|
129
|
+
* @returns A copy of the data
|
|
130
|
+
*/
|
|
114
131
|
function copyArrayBufferView(data) {
|
|
115
|
-
|
|
132
|
+
return new Uint8Array(data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength));
|
|
116
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
* Swap the bytes in a buffer.
|
|
136
|
+
* @param data - data to swap
|
|
137
|
+
* @returns data
|
|
138
|
+
*/
|
|
117
139
|
function swap16Poly(data) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
140
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
141
|
+
for (let i = 0; i < view.byteLength; i += 2) view.setUint16(i, view.getUint16(i, false), true);
|
|
142
|
+
return data;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Swap the bytes in a buffer.
|
|
146
|
+
* @param data - data to swap
|
|
147
|
+
* @returns data
|
|
148
|
+
*/
|
|
124
149
|
function swap16(data) {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
return swap16Poly(data);
|
|
150
|
+
if (typeof Buffer !== "undefined") return arrayBufferViewToBuffer(data).swap16();
|
|
151
|
+
return swap16Poly(data);
|
|
129
152
|
}
|
|
130
153
|
function swapBytes(data) {
|
|
131
|
-
|
|
132
|
-
|
|
154
|
+
const buf = copyArrayBufferView(data);
|
|
155
|
+
return swap16(buf);
|
|
133
156
|
}
|
|
134
157
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
158
|
+
//#endregion
|
|
159
|
+
//#region src/common/encode-decode.ts
|
|
160
|
+
const BOM_BE = 65279;
|
|
161
|
+
const BOM_LE = 65534;
|
|
162
|
+
const decoderUTF8 = new TextDecoder("utf8");
|
|
163
|
+
const decoderUTF16LE = new TextDecoder("utf-16le");
|
|
164
|
+
const decoderUTF16BE = createTextDecoderUtf16BE();
|
|
165
|
+
const encoderUTF8 = new TextEncoder();
|
|
142
166
|
function decodeUtf16LE(data) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
167
|
+
const buf = asUint8Array(data);
|
|
168
|
+
const bom = buf[0] << 8 | buf[1];
|
|
169
|
+
return decoderUTF16LE.decode(bom === BOM_LE ? buf.subarray(2) : buf);
|
|
146
170
|
}
|
|
147
171
|
function decodeUtf16BE(data) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
172
|
+
const buf = asUint8Array(data);
|
|
173
|
+
const bom = buf[0] << 8 | buf[1];
|
|
174
|
+
return decoderUTF16BE.decode(bom === BOM_BE ? buf.subarray(2) : buf);
|
|
151
175
|
}
|
|
152
176
|
function decodeToString(data, encoding) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
return decodeUtf16LE(buf);
|
|
169
|
-
}
|
|
170
|
-
case "utf-8":
|
|
171
|
-
case "utf8": {
|
|
172
|
-
return decoderUTF8.decode(buf);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
throw new UnsupportedEncodingError(encoding);
|
|
177
|
+
if (isGZipped(data)) return decodeToString(decompressBuffer(data), encoding);
|
|
178
|
+
const buf = asUint8Array(data);
|
|
179
|
+
const bom = buf[0] << 8 | buf[1];
|
|
180
|
+
if (bom === BOM_BE || buf[0] === 0 && buf[1] !== 0) return decodeUtf16BE(buf);
|
|
181
|
+
if (bom === BOM_LE || buf[0] !== 0 && buf[1] === 0) return decodeUtf16LE(buf);
|
|
182
|
+
if (!encoding) return decoderUTF8.decode(buf);
|
|
183
|
+
switch (encoding) {
|
|
184
|
+
case "utf-16be":
|
|
185
|
+
case "utf16be": return decodeUtf16BE(buf);
|
|
186
|
+
case "utf-16le":
|
|
187
|
+
case "utf16le": return decodeUtf16LE(buf);
|
|
188
|
+
case "utf-8":
|
|
189
|
+
case "utf8": return decoderUTF8.decode(buf);
|
|
190
|
+
}
|
|
191
|
+
throw new UnsupportedEncodingError(encoding);
|
|
176
192
|
}
|
|
177
193
|
function decode(data, encoding) {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
const result = decodeToString(data, encoding);
|
|
186
|
-
return result;
|
|
194
|
+
switch (encoding) {
|
|
195
|
+
case "base64":
|
|
196
|
+
case "base64url":
|
|
197
|
+
case "hex": return arrayBufferViewToBuffer(data).toString(encoding);
|
|
198
|
+
}
|
|
199
|
+
const result = decodeToString(data, encoding);
|
|
200
|
+
return result;
|
|
187
201
|
}
|
|
188
202
|
function encodeString(str, encoding, bom) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
case "utf-16le":
|
|
200
|
-
case "utf16le": {
|
|
201
|
-
return encodeUtf16LE(str, bom);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
return Buffer.from(str, encoding);
|
|
203
|
+
switch (encoding) {
|
|
204
|
+
case void 0:
|
|
205
|
+
case "utf-8":
|
|
206
|
+
case "utf8": return encoderUTF8.encode(str);
|
|
207
|
+
case "utf-16be":
|
|
208
|
+
case "utf16be": return encodeUtf16BE(str, bom);
|
|
209
|
+
case "utf-16le":
|
|
210
|
+
case "utf16le": return encodeUtf16LE(str, bom);
|
|
211
|
+
}
|
|
212
|
+
return Buffer.from(str, encoding);
|
|
205
213
|
}
|
|
206
214
|
function encodeUtf16LE(str, bom = true) {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
+
const buf = Buffer.from(str, "utf16le");
|
|
216
|
+
if (bom) {
|
|
217
|
+
const target = Buffer.alloc(buf.length + 2);
|
|
218
|
+
target.writeUint16LE(BOM_BE);
|
|
219
|
+
buf.copy(target, 2);
|
|
220
|
+
return target;
|
|
221
|
+
}
|
|
222
|
+
return buf;
|
|
215
223
|
}
|
|
216
224
|
function encodeUtf16BE(str, bom = true) {
|
|
217
|
-
|
|
225
|
+
return swap16(encodeUtf16LE(str, bom));
|
|
218
226
|
}
|
|
219
227
|
function createTextDecoderUtf16BE() {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
228
|
+
try {
|
|
229
|
+
const decoder = new TextDecoder("utf-16be");
|
|
230
|
+
return decoder;
|
|
231
|
+
} catch {
|
|
232
|
+
return {
|
|
233
|
+
encoding: "utf-16be",
|
|
234
|
+
fatal: false,
|
|
235
|
+
ignoreBOM: false,
|
|
236
|
+
decode: (input) => decoderUTF16LE.decode(swapBytes(input))
|
|
237
|
+
};
|
|
238
|
+
}
|
|
231
239
|
}
|
|
232
240
|
var UnsupportedEncodingError = class extends Error {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
241
|
+
constructor(encoding) {
|
|
242
|
+
super(`Unsupported encoding: ${encoding}`);
|
|
243
|
+
}
|
|
236
244
|
};
|
|
237
245
|
function isGZipped(data) {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
246
|
+
if (typeof data === "string") return false;
|
|
247
|
+
const buf = asUint8Array(data);
|
|
248
|
+
return buf[0] === 31 && buf[1] === 139;
|
|
241
249
|
}
|
|
242
250
|
function decompressBuffer(data) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
251
|
+
if (!isGZipped(data)) return data;
|
|
252
|
+
const buf = arrayBufferViewToBuffer(data);
|
|
253
|
+
return gunzipSync(buf);
|
|
246
254
|
}
|
|
247
255
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
fileResource.encoding,
|
|
310
|
-
fileResource.baseFilename,
|
|
311
|
-
fileResource.gz
|
|
312
|
-
);
|
|
313
|
-
}
|
|
256
|
+
//#endregion
|
|
257
|
+
//#region src/common/CFileResource.ts
|
|
258
|
+
var CFileResource = class CFileResource {
|
|
259
|
+
_text;
|
|
260
|
+
baseFilename;
|
|
261
|
+
_gz;
|
|
262
|
+
constructor(url, content, encoding, baseFilename, gz) {
|
|
263
|
+
this.url = url;
|
|
264
|
+
this.content = content;
|
|
265
|
+
this.encoding = encoding;
|
|
266
|
+
this.baseFilename = baseFilename ?? (url.protocol !== "data:" && url.pathname.split("/").pop() || void 0);
|
|
267
|
+
this._gz = gz;
|
|
268
|
+
}
|
|
269
|
+
get gz() {
|
|
270
|
+
if (this._gz !== void 0) return this._gz;
|
|
271
|
+
if (this.url.pathname.endsWith(".gz")) return true;
|
|
272
|
+
if (typeof this.content === "string") return false;
|
|
273
|
+
return isGZipped(this.content);
|
|
274
|
+
}
|
|
275
|
+
getText(encoding) {
|
|
276
|
+
if (this._text !== void 0) return this._text;
|
|
277
|
+
const text = typeof this.content === "string" ? this.content : decode(this.content, encoding ?? this.encoding);
|
|
278
|
+
this._text = text;
|
|
279
|
+
return text;
|
|
280
|
+
}
|
|
281
|
+
getBytes() {
|
|
282
|
+
const arrayBufferview = typeof this.content === "string" ? encodeString(this.content, this.encoding) : this.content;
|
|
283
|
+
return arrayBufferview instanceof Uint8Array ? arrayBufferview : new Uint8Array(arrayBufferview.buffer, arrayBufferview.byteOffset, arrayBufferview.byteLength);
|
|
284
|
+
}
|
|
285
|
+
toJson() {
|
|
286
|
+
return {
|
|
287
|
+
url: this.url.href,
|
|
288
|
+
content: this.getText(),
|
|
289
|
+
encoding: this.encoding,
|
|
290
|
+
baseFilename: this.baseFilename,
|
|
291
|
+
gz: this.gz
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
static isCFileResource(obj) {
|
|
295
|
+
return obj instanceof CFileResource;
|
|
296
|
+
}
|
|
297
|
+
static from(urlOrFileResource, content, encoding, baseFilename, gz) {
|
|
298
|
+
if (CFileResource.isCFileResource(urlOrFileResource)) {
|
|
299
|
+
if (content) {
|
|
300
|
+
const { url, encoding: encoding$1, baseFilename: baseFilename$1, gz: gz$1 } = urlOrFileResource;
|
|
301
|
+
return new CFileResource(url, content, encoding$1, baseFilename$1, gz$1);
|
|
302
|
+
}
|
|
303
|
+
return urlOrFileResource;
|
|
304
|
+
}
|
|
305
|
+
if (urlOrFileResource instanceof URL) {
|
|
306
|
+
assert$1(content !== void 0);
|
|
307
|
+
return new CFileResource(urlOrFileResource, content, encoding, baseFilename, gz);
|
|
308
|
+
}
|
|
309
|
+
if (content !== void 0) {
|
|
310
|
+
const fileRef = urlOrFileResource;
|
|
311
|
+
return new CFileResource(fileRef.url, content, fileRef.encoding, fileRef.baseFilename, fileRef.gz);
|
|
312
|
+
}
|
|
313
|
+
assert$1("content" in urlOrFileResource && urlOrFileResource.content !== void 0);
|
|
314
|
+
const fileResource = urlOrFileResource;
|
|
315
|
+
return new CFileResource(fileResource.url, fileResource.content, fileResource.encoding, fileResource.baseFilename, fileResource.gz);
|
|
316
|
+
}
|
|
314
317
|
};
|
|
315
318
|
function fromFileResource(fileResource, encoding) {
|
|
316
|
-
|
|
319
|
+
return CFileResource.from(encoding ? {
|
|
320
|
+
...fileResource,
|
|
321
|
+
encoding
|
|
322
|
+
} : fileResource);
|
|
317
323
|
}
|
|
318
324
|
function renameFileResource(fileResource, url) {
|
|
319
|
-
|
|
325
|
+
return CFileResource.from({
|
|
326
|
+
...fileResource,
|
|
327
|
+
url
|
|
328
|
+
});
|
|
320
329
|
}
|
|
321
330
|
|
|
322
|
-
|
|
331
|
+
//#endregion
|
|
332
|
+
//#region src/common/stat.ts
|
|
333
|
+
/**
|
|
334
|
+
* Compare two Stats to see if they have the same value.
|
|
335
|
+
* @param left - Stats
|
|
336
|
+
* @param right - Stats
|
|
337
|
+
* @returns 0 - equal; 1 - left > right; -1 left < right
|
|
338
|
+
*/
|
|
323
339
|
function compareStats(left, right) {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
340
|
+
if (left === right) return 0;
|
|
341
|
+
if (left.eTag || right.eTag) return left.eTag === right.eTag ? 0 : (left.eTag || "") < (right.eTag || "") ? -1 : 1;
|
|
342
|
+
const diff = left.size - right.size || left.mtimeMs - right.mtimeMs;
|
|
343
|
+
return diff < 0 ? -1 : diff > 0 ? 1 : 0;
|
|
328
344
|
}
|
|
329
345
|
|
|
330
|
-
|
|
346
|
+
//#endregion
|
|
347
|
+
//#region src/common/urlOrReferenceToUrl.ts
|
|
331
348
|
function urlOrReferenceToUrl(urlOrReference) {
|
|
332
|
-
|
|
349
|
+
return urlOrReference instanceof URL ? urlOrReference : urlOrReference.url;
|
|
333
350
|
}
|
|
334
351
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
// src/CSpellIO.ts
|
|
352
|
+
//#endregion
|
|
353
|
+
//#region src/CSpellIO.ts
|
|
339
354
|
function toReadFileOptions(options) {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
}
|
|
344
|
-
return options;
|
|
355
|
+
if (!options) return options;
|
|
356
|
+
if (typeof options === "string") return { encoding: options };
|
|
357
|
+
return options;
|
|
345
358
|
}
|
|
346
359
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
import { fileURLToPath } from "url";
|
|
350
|
-
import { promisify } from "util";
|
|
351
|
-
import { gunzipSync as gunzipSync2, gzip } from "zlib";
|
|
352
|
-
import { createResponse, createResponseFail, isServiceResponseSuccess } from "@cspell/cspell-service-bus";
|
|
353
|
-
|
|
354
|
-
// src/errors/error.ts
|
|
360
|
+
//#endregion
|
|
361
|
+
//#region src/errors/error.ts
|
|
355
362
|
function toError(e) {
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
}
|
|
360
|
-
return new Error(e && e.toString());
|
|
363
|
+
if (e instanceof Error) return e;
|
|
364
|
+
if (typeof e === "object" && e && "message" in e && typeof e.message === "string") return new Error(e.message, { cause: e });
|
|
365
|
+
return new Error(e && e.toString());
|
|
361
366
|
}
|
|
362
367
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
368
|
+
//#endregion
|
|
369
|
+
//#region src/models/Stats.ts
|
|
370
|
+
let FileType = /* @__PURE__ */ function(FileType$1) {
|
|
371
|
+
/**
|
|
372
|
+
* The file type is unknown.
|
|
373
|
+
*/
|
|
374
|
+
FileType$1[FileType$1["Unknown"] = 0] = "Unknown";
|
|
375
|
+
/**
|
|
376
|
+
* A regular file.
|
|
377
|
+
*/
|
|
378
|
+
FileType$1[FileType$1["File"] = 1] = "File";
|
|
379
|
+
/**
|
|
380
|
+
* A directory.
|
|
381
|
+
*/
|
|
382
|
+
FileType$1[FileType$1["Directory"] = 2] = "Directory";
|
|
383
|
+
/**
|
|
384
|
+
* A symbolic link.
|
|
385
|
+
*/
|
|
386
|
+
FileType$1[FileType$1["SymbolicLink"] = 64] = "SymbolicLink";
|
|
387
|
+
return FileType$1;
|
|
388
|
+
}({});
|
|
371
389
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
390
|
+
//#endregion
|
|
391
|
+
//#region src/node/dataUrl.ts
|
|
392
|
+
/**
|
|
393
|
+
* Generates a string of the following format:
|
|
394
|
+
*
|
|
395
|
+
* `data:[mediaType][;charset=<encoding>[;base64],<data>`
|
|
396
|
+
*
|
|
397
|
+
* - `encoding` - defaults to `utf8` for text data
|
|
398
|
+
* @param data
|
|
399
|
+
* @param mediaType - The mediaType is a [MIME](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types) type string
|
|
400
|
+
* @param attributes - Additional attributes
|
|
401
|
+
*/
|
|
375
402
|
function encodeDataUrl(data, mediaType, attributes) {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
403
|
+
if (typeof data === "string") return encodeString$1(data, mediaType, attributes);
|
|
404
|
+
const attribs = encodeAttributes(attributes || []);
|
|
405
|
+
const buf = arrayBufferViewToBuffer(data);
|
|
406
|
+
return `data:${mediaType}${attribs};base64,${buf.toString("base64url")}`;
|
|
380
407
|
}
|
|
381
408
|
function toDataUrl(data, mediaType, attributes) {
|
|
382
|
-
|
|
383
|
-
}
|
|
384
|
-
function
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
409
|
+
return new URL(encodeDataUrl(data, mediaType, attributes));
|
|
410
|
+
}
|
|
411
|
+
function encodeString$1(data, mediaType, attributes) {
|
|
412
|
+
mediaType = mediaType || "text/plain";
|
|
413
|
+
attributes = attributes || [];
|
|
414
|
+
const asUrlComp = encodeURIComponent(data);
|
|
415
|
+
const asBase64 = Buffer.from(data).toString("base64url");
|
|
416
|
+
const useBase64 = asBase64.length < asUrlComp.length - 7;
|
|
417
|
+
const encoded = useBase64 ? asBase64 : asUrlComp;
|
|
418
|
+
const attribMap = new Map([["charset", "utf-8"], ...attributes]);
|
|
419
|
+
attribMap.set("charset", "utf-8");
|
|
420
|
+
const attribs = encodeAttributes(attribMap);
|
|
421
|
+
return `data:${mediaType}${attribs}${useBase64 ? ";base64" : ""},${encoded}`;
|
|
395
422
|
}
|
|
396
423
|
function encodeAttributes(attributes) {
|
|
397
|
-
|
|
424
|
+
return [...attributes].map(([key, value]) => `;${key}=${encodeURIComponent(value)}`).join("");
|
|
398
425
|
}
|
|
399
|
-
|
|
426
|
+
const dataUrlRegExHead = /^data:(?<mediaType>[^;,]*)(?<attributes>(?:;[^=]+=[^;,]*)*)(?<base64>;base64)?$/;
|
|
400
427
|
function decodeDataUrl(url) {
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
428
|
+
url = url.toString();
|
|
429
|
+
const [head, encodedData] = url.split(",", 2);
|
|
430
|
+
if (!head || encodedData === void 0) throw new Error("Not a data url");
|
|
431
|
+
const match = head.match(dataUrlRegExHead);
|
|
432
|
+
if (!match || !match.groups) throw new Error("Not a data url");
|
|
433
|
+
const mediaType = match.groups["mediaType"] || "";
|
|
434
|
+
const rawAttributes = (match.groups["attributes"] || "").split(";").filter((a) => !!a).map((entry) => entry.split("=", 2)).map(([key, value]) => [key, decodeURIComponent(value)]);
|
|
435
|
+
const attributes = new Map(rawAttributes);
|
|
436
|
+
const encoding = attributes.get("charset");
|
|
437
|
+
const isBase64 = !!match.groups["base64"];
|
|
438
|
+
const data = isBase64 ? Buffer.from(encodedData, "base64url") : Buffer.from(decodeURIComponent(encodedData));
|
|
439
|
+
return {
|
|
440
|
+
mediaType,
|
|
441
|
+
data,
|
|
442
|
+
encoding,
|
|
443
|
+
attributes
|
|
444
|
+
};
|
|
413
445
|
}
|
|
414
446
|
function guessMimeType(filename) {
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
447
|
+
if (filename.endsWith(".trie")) return {
|
|
448
|
+
mimeType: "application/vnd.cspell.dictionary+trie",
|
|
449
|
+
encoding: "utf-8"
|
|
450
|
+
};
|
|
451
|
+
if (filename.endsWith(".trie.gz")) return { mimeType: "application/vnd.cspell.dictionary+trie.gz" };
|
|
452
|
+
if (filename.endsWith(".txt")) return {
|
|
453
|
+
mimeType: "text/plain",
|
|
454
|
+
encoding: "utf-8"
|
|
455
|
+
};
|
|
456
|
+
if (filename.endsWith(".txt.gz")) return { mimeType: "application/gzip" };
|
|
457
|
+
if (filename.endsWith(".gz")) return { mimeType: "application/gzip" };
|
|
458
|
+
if (filename.endsWith(".json")) return {
|
|
459
|
+
mimeType: "application/json",
|
|
460
|
+
encoding: "utf-8"
|
|
461
|
+
};
|
|
462
|
+
if (filename.endsWith(".yaml") || filename.endsWith(".yml")) return {
|
|
463
|
+
mimeType: "application/x-yaml",
|
|
464
|
+
encoding: "utf-8"
|
|
465
|
+
};
|
|
466
|
+
return void 0;
|
|
424
467
|
}
|
|
425
468
|
|
|
426
|
-
|
|
427
|
-
|
|
469
|
+
//#endregion
|
|
470
|
+
//#region src/node/file/_fetch.ts
|
|
471
|
+
/** alias of global.fetch, useful for mocking */
|
|
472
|
+
const _fetch = global.fetch;
|
|
428
473
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
return new _FetchUrlError(e.message, e.code, void 0, url);
|
|
451
|
-
}
|
|
452
|
-
return new _FetchUrlError(e.message, void 0, void 0, url);
|
|
453
|
-
}
|
|
474
|
+
//#endregion
|
|
475
|
+
//#region src/node/file/FetchError.ts
|
|
476
|
+
var FetchUrlError = class FetchUrlError extends Error {
|
|
477
|
+
constructor(message, code, status, url) {
|
|
478
|
+
super(message);
|
|
479
|
+
this.code = code;
|
|
480
|
+
this.status = status;
|
|
481
|
+
this.url = url;
|
|
482
|
+
this.name = "FetchUrlError";
|
|
483
|
+
}
|
|
484
|
+
static create(url, status, message) {
|
|
485
|
+
if (status === 404) return new FetchUrlError(message || "URL not found.", "ENOENT", status, url);
|
|
486
|
+
if (status >= 400 && status < 500) return new FetchUrlError(message || "Permission denied.", "EACCES", status, url);
|
|
487
|
+
return new FetchUrlError(message || "Fatal Error", "ECONNREFUSED", status, url);
|
|
488
|
+
}
|
|
489
|
+
static fromError(url, e) {
|
|
490
|
+
const cause = getCause(e);
|
|
491
|
+
if (cause) return new FetchUrlError(cause.message, cause.code, void 0, url);
|
|
492
|
+
if (isNodeError(e)) return new FetchUrlError(e.message, e.code, void 0, url);
|
|
493
|
+
return new FetchUrlError(e.message, void 0, void 0, url);
|
|
494
|
+
}
|
|
454
495
|
};
|
|
455
496
|
function isNodeError(e) {
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
497
|
+
if (e instanceof Error && "code" in e && typeof e.code === "string") return true;
|
|
498
|
+
if (e && typeof e === "object" && "code" in e && typeof e.code === "string") return true;
|
|
499
|
+
return false;
|
|
459
500
|
}
|
|
460
501
|
function isError(e) {
|
|
461
|
-
|
|
502
|
+
return e instanceof Error;
|
|
462
503
|
}
|
|
463
504
|
function isErrorWithOptionalCause(e) {
|
|
464
|
-
|
|
505
|
+
return isError(e) && (!("cause" in e) || isNodeError(e.cause) || isNodeError(e));
|
|
465
506
|
}
|
|
466
507
|
function getCause(e) {
|
|
467
|
-
|
|
508
|
+
return isErrorWithOptionalCause(e) ? e.cause : void 0;
|
|
468
509
|
}
|
|
469
510
|
function toFetchUrlError(err, url) {
|
|
470
|
-
|
|
511
|
+
return err instanceof FetchUrlError ? err : FetchUrlError.fromError(url, toError$1(err));
|
|
471
512
|
}
|
|
472
|
-
function
|
|
473
|
-
|
|
513
|
+
function toError$1(err) {
|
|
514
|
+
return err instanceof Error ? err : new Error("Unknown Error", { cause: err });
|
|
474
515
|
}
|
|
475
516
|
|
|
476
|
-
|
|
517
|
+
//#endregion
|
|
518
|
+
//#region src/node/file/fetch.ts
|
|
477
519
|
async function fetchHead(request) {
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
throw toFetchUrlError(e, url);
|
|
487
|
-
}
|
|
520
|
+
const url = toURL$1(request);
|
|
521
|
+
try {
|
|
522
|
+
const r = await _fetch(url, { method: "HEAD" });
|
|
523
|
+
if (!r.ok) throw FetchUrlError.create(url, r.status);
|
|
524
|
+
return r.headers;
|
|
525
|
+
} catch (e) {
|
|
526
|
+
throw toFetchUrlError(e, url);
|
|
527
|
+
}
|
|
488
528
|
}
|
|
489
529
|
async function fetchURL(url, signal) {
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
function toURL2(url) {
|
|
502
|
-
return typeof url === "string" ? new URL(url) : url;
|
|
530
|
+
try {
|
|
531
|
+
const request = signal ? new Request(url, { signal }) : url;
|
|
532
|
+
const response = await _fetch(request);
|
|
533
|
+
if (!response.ok) throw FetchUrlError.create(url, response.status);
|
|
534
|
+
return Buffer.from(await response.arrayBuffer());
|
|
535
|
+
} catch (e) {
|
|
536
|
+
throw toFetchUrlError(e, url);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
function toURL$1(url) {
|
|
540
|
+
return typeof url === "string" ? new URL(url) : url;
|
|
503
541
|
}
|
|
504
542
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
import { format } from "util";
|
|
543
|
+
//#endregion
|
|
544
|
+
//#region src/node/file/stat.ts
|
|
508
545
|
async function getStatHttp(url) {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
546
|
+
const headers = await fetchHead(url);
|
|
547
|
+
const eTag = headers.get("etag") || void 0;
|
|
548
|
+
const guessSize = Number.parseInt(headers.get("content-length") || "0", 10);
|
|
549
|
+
return {
|
|
550
|
+
size: eTag ? -1 : guessSize,
|
|
551
|
+
mtimeMs: 0,
|
|
552
|
+
eTag
|
|
553
|
+
};
|
|
517
554
|
}
|
|
518
555
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
RequestType
|
|
524
|
-
);
|
|
556
|
+
//#endregion
|
|
557
|
+
//#region src/requests/RequestFsReadFile.ts
|
|
558
|
+
const RequestType$4 = "fs:readFile";
|
|
559
|
+
const RequestFsReadFile = requestFactory(RequestType$4);
|
|
525
560
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
RequestType2
|
|
531
|
-
);
|
|
561
|
+
//#endregion
|
|
562
|
+
//#region src/requests/RequestFsReadFileSync.ts
|
|
563
|
+
const RequestType$3 = "fs:readFileSync";
|
|
564
|
+
const RequestFsReadFileTextSync = requestFactory(RequestType$3);
|
|
532
565
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
RequestTypeStatSync
|
|
540
|
-
);
|
|
566
|
+
//#endregion
|
|
567
|
+
//#region src/requests/RequestFsStat.ts
|
|
568
|
+
const RequestTypeStat = "fs:stat";
|
|
569
|
+
const RequestFsStat = requestFactory(RequestTypeStat);
|
|
570
|
+
const RequestTypeStatSync = "fs:statSync";
|
|
571
|
+
const RequestFsStatSync = requestFactory(RequestTypeStatSync);
|
|
541
572
|
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
RequestType3
|
|
547
|
-
);
|
|
573
|
+
//#endregion
|
|
574
|
+
//#region src/requests/RequestFsWriteFile.ts
|
|
575
|
+
const RequestType$2 = "fs:writeFile";
|
|
576
|
+
const RequestFsWriteFile = requestFactory(RequestType$2);
|
|
548
577
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
578
|
+
//#endregion
|
|
579
|
+
//#region src/requests/RequestZlibInflate.ts
|
|
580
|
+
const RequestType$1 = "zlib:inflate";
|
|
581
|
+
const RequestZlibInflate = requestFactory(RequestType$1);
|
|
553
582
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
RequestType5
|
|
559
|
-
);
|
|
583
|
+
//#endregion
|
|
584
|
+
//#region src/requests/RequestFsReadDirectory.ts
|
|
585
|
+
const RequestType = "fs:readDir";
|
|
586
|
+
const RequestFsReadDirectory = requestFactory(RequestType);
|
|
560
587
|
|
|
561
|
-
|
|
562
|
-
|
|
588
|
+
//#endregion
|
|
589
|
+
//#region src/handlers/node/file.ts
|
|
590
|
+
const isGzFileRegExp = /\.gz($|[?#])/;
|
|
563
591
|
function isGzFile(url) {
|
|
564
|
-
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
);
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
);
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
);
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
592
|
+
return isGzFileRegExp.test(typeof url === "string" ? url : url.pathname);
|
|
593
|
+
}
|
|
594
|
+
const pGzip = promisify(gzip);
|
|
595
|
+
/**
|
|
596
|
+
* Handle Binary File Reads
|
|
597
|
+
*/
|
|
598
|
+
const handleRequestFsReadFile = RequestFsReadFile.createRequestHandler(({ params }) => {
|
|
599
|
+
const baseFilename = urlBasename(params.url);
|
|
600
|
+
return createResponse(promises.readFile(fileURLToPath(params.url)).then((content) => CFileResource.from(params.url, content, params.encoding, baseFilename)));
|
|
601
|
+
}, void 0, "Node: Read Binary File.");
|
|
602
|
+
/**
|
|
603
|
+
* Handle Binary File Sync Reads
|
|
604
|
+
*/
|
|
605
|
+
const handleRequestFsReadFileSync = RequestFsReadFileTextSync.createRequestHandler(({ params }) => createResponse(CFileResource.from({
|
|
606
|
+
...params,
|
|
607
|
+
content: readFileSync(fileURLToPath(params.url))
|
|
608
|
+
})), void 0, "Node: Sync Read Binary File.");
|
|
609
|
+
/**
|
|
610
|
+
* Handle Binary File Reads
|
|
611
|
+
*/
|
|
612
|
+
const handleRequestFsReadDirectory = RequestFsReadDirectory.createRequestHandler(({ params }) => {
|
|
613
|
+
return createResponse(promises.readdir(fileURLToPath(params.url), { withFileTypes: true }).then((entries) => direntToDirEntries(params.url, entries)));
|
|
614
|
+
}, void 0, "Node: Read Directory.");
|
|
615
|
+
/**
|
|
616
|
+
* Handle deflating gzip data
|
|
617
|
+
*/
|
|
618
|
+
const handleRequestZlibInflate = RequestZlibInflate.createRequestHandler(({ params }) => createResponse(gunzipSync(arrayBufferViewToBuffer(params.data))), void 0, "Node: gz deflate.");
|
|
619
|
+
const supportedFetchProtocols = {
|
|
620
|
+
"http:": true,
|
|
621
|
+
"https:": true
|
|
622
|
+
};
|
|
623
|
+
/**
|
|
624
|
+
* Handle fetching a file from http
|
|
625
|
+
*/
|
|
626
|
+
const handleRequestFsReadFileHttp = RequestFsReadFile.createRequestHandler((req, next) => {
|
|
627
|
+
const { url, signal, encoding } = req.params;
|
|
628
|
+
if (!(url.protocol in supportedFetchProtocols)) return next(req);
|
|
629
|
+
return createResponse(fetchURL(url, signal).then((content) => CFileResource.from({
|
|
630
|
+
url,
|
|
631
|
+
encoding,
|
|
632
|
+
content
|
|
633
|
+
})));
|
|
634
|
+
}, void 0, "Node: Read Http(s) file.");
|
|
635
|
+
/**
|
|
636
|
+
* Handle decoding a data url
|
|
637
|
+
*/
|
|
638
|
+
const handleRequestFsReadFileSyncData = RequestFsReadFileTextSync.createRequestHandler((req, next) => {
|
|
639
|
+
const { url, encoding } = req.params;
|
|
640
|
+
if (url.protocol !== "data:") return next(req);
|
|
641
|
+
const data = decodeDataUrl(url);
|
|
642
|
+
return createResponse(CFileResource.from({
|
|
643
|
+
url,
|
|
644
|
+
content: data.data,
|
|
645
|
+
encoding,
|
|
646
|
+
baseFilename: data.attributes.get("filename")
|
|
647
|
+
}));
|
|
648
|
+
}, void 0, "Node: Read data: urls.");
|
|
649
|
+
/**
|
|
650
|
+
* Handle decoding a data url
|
|
651
|
+
*/
|
|
652
|
+
const handleRequestFsReadFileData = RequestFsReadFile.createRequestHandler((req, next, dispatcher) => {
|
|
653
|
+
const { url } = req.params;
|
|
654
|
+
if (url.protocol !== "data:") return next(req);
|
|
655
|
+
const res = dispatcher.dispatch(RequestFsReadFileTextSync.create(req.params));
|
|
656
|
+
if (!isServiceResponseSuccess(res)) return res;
|
|
657
|
+
return createResponse(Promise.resolve(res.value));
|
|
658
|
+
}, void 0, "Node: Read data: urls.");
|
|
659
|
+
/**
|
|
660
|
+
* Handle fs:stat
|
|
661
|
+
*/
|
|
662
|
+
const handleRequestFsStat = RequestFsStat.createRequestHandler(({ params }) => createResponse(toPromiseStats(promises.stat(fileURLToPath(params.url)))), void 0, "Node: fs.stat.");
|
|
634
663
|
function toStats(stat) {
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
664
|
+
return {
|
|
665
|
+
size: stat.size,
|
|
666
|
+
mtimeMs: stat.mtimeMs,
|
|
667
|
+
fileType: toFileType(stat)
|
|
668
|
+
};
|
|
640
669
|
}
|
|
641
670
|
function toPromiseStats(pStat) {
|
|
642
|
-
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
void 0,
|
|
668
|
-
"Node: fs.writeFile"
|
|
669
|
-
);
|
|
671
|
+
return pStat.then(toStats);
|
|
672
|
+
}
|
|
673
|
+
/**
|
|
674
|
+
* Handle fs:statSync
|
|
675
|
+
*/
|
|
676
|
+
const handleRequestFsStatSync = RequestFsStatSync.createRequestHandler((req) => {
|
|
677
|
+
const { params } = req;
|
|
678
|
+
try {
|
|
679
|
+
return createResponse(statSync(fileURLToPath(params.url)));
|
|
680
|
+
} catch (e) {
|
|
681
|
+
return createResponseFail(req, toError(e));
|
|
682
|
+
}
|
|
683
|
+
}, void 0, "Node: fs.stat.");
|
|
684
|
+
/**
|
|
685
|
+
* Handle deflating gzip data
|
|
686
|
+
*/
|
|
687
|
+
const handleRequestFsStatHttp = RequestFsStat.createRequestHandler((req, next) => {
|
|
688
|
+
const { url } = req.params;
|
|
689
|
+
if (!(url.protocol in supportedFetchProtocols)) return next(req);
|
|
690
|
+
return createResponse(getStatHttp(url));
|
|
691
|
+
}, void 0, "Node: http get stat");
|
|
692
|
+
/**
|
|
693
|
+
* Handle fs:writeFile
|
|
694
|
+
*/
|
|
695
|
+
const handleRequestFsWriteFile = RequestFsWriteFile.createRequestHandler(({ params }) => createResponse(writeFile(params, params.content)), void 0, "Node: fs.writeFile");
|
|
670
696
|
async function writeFile(fileRef, content) {
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
);
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
697
|
+
const gz = isGZipped(content);
|
|
698
|
+
const { url, encoding, baseFilename } = fileRef;
|
|
699
|
+
const resultRef = {
|
|
700
|
+
url,
|
|
701
|
+
encoding,
|
|
702
|
+
baseFilename,
|
|
703
|
+
gz
|
|
704
|
+
};
|
|
705
|
+
await promises.writeFile(fileURLToPath(fileRef.url), encodeContent(fileRef, content));
|
|
706
|
+
return resultRef;
|
|
707
|
+
}
|
|
708
|
+
/**
|
|
709
|
+
* Handle fs:writeFile
|
|
710
|
+
*/
|
|
711
|
+
const handleRequestFsWriteFileDataUrl = RequestFsWriteFile.createRequestHandler((req, next) => {
|
|
712
|
+
const fileResource = req.params;
|
|
713
|
+
const { url } = req.params;
|
|
714
|
+
if (url.protocol !== "data:") return next(req);
|
|
715
|
+
const gz = isGZipped(fileResource.content);
|
|
716
|
+
const baseFilename = fileResource.baseFilename || "file.txt" + (gz ? ".gz" : "");
|
|
717
|
+
const mt = guessMimeType(baseFilename);
|
|
718
|
+
const mediaType = mt?.mimeType || "text/plain";
|
|
719
|
+
const dataUrl = toDataUrl(fileResource.content, mediaType, [["filename", baseFilename]]);
|
|
720
|
+
return createResponse(Promise.resolve({
|
|
721
|
+
url: dataUrl,
|
|
722
|
+
baseFilename,
|
|
723
|
+
gz,
|
|
724
|
+
encoding: mt?.encoding
|
|
725
|
+
}));
|
|
726
|
+
}, void 0, "Node: fs.writeFile DataUrl");
|
|
727
|
+
/**
|
|
728
|
+
* Handle fs:writeFile compressed
|
|
729
|
+
*/
|
|
730
|
+
const handleRequestFsWriteFileGz = RequestFsWriteFile.createRequestHandler((req, next, dispatcher) => {
|
|
731
|
+
const fileResource = req.params;
|
|
732
|
+
if (!fileResource.gz && !isGzFile(fileResource.url) && (!fileResource.baseFilename || !isGzFile(fileResource.baseFilename))) return next(req);
|
|
733
|
+
if (typeof fileResource.content !== "string" && isGZipped(fileResource.content)) return next(req);
|
|
734
|
+
return createResponse(compressAndChainWriteRequest(dispatcher, fileResource, fileResource.content));
|
|
735
|
+
}, void 0, "Node: fs.writeFile compressed");
|
|
706
736
|
async function compressAndChainWriteRequest(dispatcher, fileRef, content) {
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
737
|
+
const buf = await pGzip(encodeContent(fileRef, content));
|
|
738
|
+
const res = dispatcher.dispatch(RequestFsWriteFile.create({
|
|
739
|
+
...fileRef,
|
|
740
|
+
content: buf
|
|
741
|
+
}));
|
|
742
|
+
assert$1(isServiceResponseSuccess(res));
|
|
743
|
+
return res.value;
|
|
711
744
|
}
|
|
712
745
|
function registerHandlers(serviceBus) {
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
746
|
+
/**
|
|
747
|
+
* Handlers are in order of low to high level
|
|
748
|
+
* Order is VERY important.
|
|
749
|
+
*/
|
|
750
|
+
const handlers = [
|
|
751
|
+
handleRequestFsReadFile,
|
|
752
|
+
handleRequestFsReadFileSync,
|
|
753
|
+
handleRequestFsWriteFile,
|
|
754
|
+
handleRequestFsWriteFileDataUrl,
|
|
755
|
+
handleRequestFsWriteFileGz,
|
|
756
|
+
handleRequestFsReadFileHttp,
|
|
757
|
+
handleRequestFsReadFileData,
|
|
758
|
+
handleRequestFsReadFileSyncData,
|
|
759
|
+
handleRequestFsReadDirectory,
|
|
760
|
+
handleRequestZlibInflate,
|
|
761
|
+
handleRequestFsStatSync,
|
|
762
|
+
handleRequestFsStat,
|
|
763
|
+
handleRequestFsStatHttp
|
|
764
|
+
];
|
|
765
|
+
handlers.forEach((handler) => serviceBus.addHandler(handler));
|
|
729
766
|
}
|
|
730
767
|
function encodeContent(ref, content) {
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
768
|
+
if (typeof content === "string") {
|
|
769
|
+
if ([
|
|
770
|
+
void 0,
|
|
771
|
+
"utf8",
|
|
772
|
+
"utf-8"
|
|
773
|
+
].includes(ref.encoding)) return content;
|
|
774
|
+
return arrayBufferViewToBuffer(encodeString(content, ref.encoding));
|
|
775
|
+
}
|
|
776
|
+
return arrayBufferViewToBuffer(content);
|
|
736
777
|
}
|
|
737
778
|
function mapperDirentToDirEntry(dir) {
|
|
738
|
-
|
|
779
|
+
return (dirent) => direntToDirEntry(dir, dirent);
|
|
739
780
|
}
|
|
740
781
|
function direntToDirEntries(dir, dirent) {
|
|
741
|
-
|
|
782
|
+
return dirent.map(mapperDirentToDirEntry(dir));
|
|
742
783
|
}
|
|
743
784
|
function direntToDirEntry(dir, dirent) {
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
785
|
+
return {
|
|
786
|
+
name: dirent.name,
|
|
787
|
+
dir,
|
|
788
|
+
fileType: toFileType(dirent)
|
|
789
|
+
};
|
|
749
790
|
}
|
|
750
791
|
function toFileType(statLike) {
|
|
751
|
-
|
|
752
|
-
|
|
792
|
+
const t = statLike.isFile() ? FileType.File : statLike.isDirectory() ? FileType.Directory : FileType.Unknown;
|
|
793
|
+
return statLike.isSymbolicLink() ? t | FileType.SymbolicLink : t;
|
|
753
794
|
}
|
|
754
795
|
|
|
755
|
-
|
|
756
|
-
|
|
796
|
+
//#endregion
|
|
797
|
+
//#region src/CSpellIONode.ts
|
|
798
|
+
let defaultCSpellIONode = void 0;
|
|
757
799
|
var CSpellIONode = class {
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
return toURL(urlOrFilename, relativeTo);
|
|
818
|
-
}
|
|
819
|
-
toFileURL(urlOrFilename, relativeTo) {
|
|
820
|
-
if (isFileReference(urlOrFilename)) return urlOrFilename.url;
|
|
821
|
-
return toFileURL(urlOrFilename, relativeTo);
|
|
822
|
-
}
|
|
823
|
-
urlBasename(urlOrFilename) {
|
|
824
|
-
return urlBasename(this.toURL(urlOrFilename));
|
|
825
|
-
}
|
|
826
|
-
urlDirname(urlOrFilename) {
|
|
827
|
-
return urlParent(this.toURL(urlOrFilename));
|
|
828
|
-
}
|
|
800
|
+
constructor(serviceBus = new ServiceBus()) {
|
|
801
|
+
this.serviceBus = serviceBus;
|
|
802
|
+
registerHandlers(serviceBus);
|
|
803
|
+
}
|
|
804
|
+
readFile(urlOrFilename, options) {
|
|
805
|
+
const readOptions = toReadFileOptions(options);
|
|
806
|
+
const ref = toFileResourceRequest(urlOrFilename, readOptions?.encoding, readOptions?.signal);
|
|
807
|
+
const res = this.serviceBus.dispatch(RequestFsReadFile.create(ref));
|
|
808
|
+
if (!isServiceResponseSuccess(res)) throw genError(res.error, "readFile");
|
|
809
|
+
return res.value;
|
|
810
|
+
}
|
|
811
|
+
readDirectory(urlOrFilename) {
|
|
812
|
+
const ref = toFileReference(urlOrFilename);
|
|
813
|
+
const res = this.serviceBus.dispatch(RequestFsReadDirectory.create(ref));
|
|
814
|
+
if (!isServiceResponseSuccess(res)) throw genError(res.error, "readDirectory");
|
|
815
|
+
return res.value;
|
|
816
|
+
}
|
|
817
|
+
readFileSync(urlOrFilename, encoding) {
|
|
818
|
+
const ref = toFileReference(urlOrFilename, encoding);
|
|
819
|
+
const res = this.serviceBus.dispatch(RequestFsReadFileTextSync.create(ref));
|
|
820
|
+
if (!isServiceResponseSuccess(res)) throw genError(res.error, "readFileSync");
|
|
821
|
+
return res.value;
|
|
822
|
+
}
|
|
823
|
+
writeFile(urlOrFilename, content) {
|
|
824
|
+
const ref = toFileReference(urlOrFilename);
|
|
825
|
+
const fileResource = CFileResource.from(ref, content);
|
|
826
|
+
const res = this.serviceBus.dispatch(RequestFsWriteFile.create(fileResource));
|
|
827
|
+
if (!isServiceResponseSuccess(res)) throw genError(res.error, "writeFile");
|
|
828
|
+
return res.value;
|
|
829
|
+
}
|
|
830
|
+
getStat(urlOrFilename) {
|
|
831
|
+
const ref = toFileReference(urlOrFilename);
|
|
832
|
+
const res = this.serviceBus.dispatch(RequestFsStat.create(ref));
|
|
833
|
+
if (!isServiceResponseSuccess(res)) throw genError(res.error, "getStat");
|
|
834
|
+
return res.value;
|
|
835
|
+
}
|
|
836
|
+
getStatSync(urlOrFilename) {
|
|
837
|
+
const ref = toFileReference(urlOrFilename);
|
|
838
|
+
const res = this.serviceBus.dispatch(RequestFsStatSync.create(ref));
|
|
839
|
+
if (!isServiceResponseSuccess(res)) throw genError(res.error, "getStatSync");
|
|
840
|
+
return res.value;
|
|
841
|
+
}
|
|
842
|
+
compareStats(left, right) {
|
|
843
|
+
return compareStats(left, right);
|
|
844
|
+
}
|
|
845
|
+
toURL(urlOrFilename, relativeTo) {
|
|
846
|
+
if (isFileReference(urlOrFilename)) return urlOrFilename.url;
|
|
847
|
+
return toURL(urlOrFilename, relativeTo);
|
|
848
|
+
}
|
|
849
|
+
toFileURL(urlOrFilename, relativeTo) {
|
|
850
|
+
if (isFileReference(urlOrFilename)) return urlOrFilename.url;
|
|
851
|
+
return toFileURL(urlOrFilename, relativeTo);
|
|
852
|
+
}
|
|
853
|
+
urlBasename(urlOrFilename) {
|
|
854
|
+
return urlBasename(this.toURL(urlOrFilename));
|
|
855
|
+
}
|
|
856
|
+
urlDirname(urlOrFilename) {
|
|
857
|
+
return urlDirname(this.toURL(urlOrFilename));
|
|
858
|
+
}
|
|
829
859
|
};
|
|
830
860
|
function genError(err, alt) {
|
|
831
|
-
|
|
861
|
+
return err || new ErrorNotImplemented(alt);
|
|
832
862
|
}
|
|
833
863
|
function getDefaultCSpellIO() {
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
864
|
+
if (defaultCSpellIONode) return defaultCSpellIONode;
|
|
865
|
+
const cspellIO = new CSpellIONode();
|
|
866
|
+
defaultCSpellIONode = cspellIO;
|
|
867
|
+
return cspellIO;
|
|
838
868
|
}
|
|
839
869
|
|
|
840
|
-
|
|
841
|
-
|
|
870
|
+
//#endregion
|
|
871
|
+
//#region src/VirtualFS.ts
|
|
872
|
+
const debug = false;
|
|
842
873
|
|
|
843
|
-
|
|
874
|
+
//#endregion
|
|
875
|
+
//#region src/VirtualFS/findUpFromUrl.ts
|
|
844
876
|
async function findUpFromUrl(name, from, options) {
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
}
|
|
860
|
-
function makePredicate(
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
+
const { type: entryType = "file", stopAt, fs: fs$1 } = options;
|
|
878
|
+
let dir = new URL(".", from);
|
|
879
|
+
const root = new URL("/", dir);
|
|
880
|
+
const predicate = makePredicate(fs$1, name, entryType);
|
|
881
|
+
const stopAtHrefs = new Set((Array.isArray(stopAt) ? stopAt : [stopAt || root]).map((p) => new URL(".", p).href));
|
|
882
|
+
let last = "";
|
|
883
|
+
while (dir.href !== last) {
|
|
884
|
+
const found = await predicate(dir);
|
|
885
|
+
if (found !== void 0) return found;
|
|
886
|
+
last = dir.href;
|
|
887
|
+
if (dir.href === root.href || stopAtHrefs.has(dir.href)) break;
|
|
888
|
+
dir = new URL("..", dir);
|
|
889
|
+
}
|
|
890
|
+
return void 0;
|
|
891
|
+
}
|
|
892
|
+
function makePredicate(fs$1, name, entryType) {
|
|
893
|
+
if (typeof name === "function") return name;
|
|
894
|
+
const checkStat = entryType === "file" || entryType === "!file" ? "isFile" : "isDirectory";
|
|
895
|
+
const checkValue = entryType.startsWith("!") ? false : true;
|
|
896
|
+
function checkName(dir, name$1) {
|
|
897
|
+
const f = new URL(name$1, dir);
|
|
898
|
+
return fs$1.stat(f).then((stats) => (stats.isUnknown() || stats[checkStat]() === checkValue) && f || void 0).catch(() => void 0);
|
|
899
|
+
}
|
|
900
|
+
if (!Array.isArray(name)) return (dir) => checkName(dir, name);
|
|
901
|
+
return async (dir) => {
|
|
902
|
+
const pending = name.map((n) => checkName(dir, n));
|
|
903
|
+
for (const p of pending) {
|
|
904
|
+
const found = await p;
|
|
905
|
+
if (found) return found;
|
|
906
|
+
}
|
|
907
|
+
return void 0;
|
|
908
|
+
};
|
|
877
909
|
}
|
|
878
910
|
|
|
879
|
-
|
|
911
|
+
//#endregion
|
|
912
|
+
//#region src/VirtualFS/CVFileSystem.ts
|
|
880
913
|
var CVFileSystem = class {
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
914
|
+
#core;
|
|
915
|
+
readFile;
|
|
916
|
+
writeFile;
|
|
917
|
+
stat;
|
|
918
|
+
readDirectory;
|
|
919
|
+
getCapabilities;
|
|
920
|
+
constructor(core) {
|
|
921
|
+
this.#core = core;
|
|
922
|
+
this.readFile = this.#core.readFile.bind(this.#core);
|
|
923
|
+
this.writeFile = this.#core.writeFile.bind(this.#core);
|
|
924
|
+
this.stat = this.#core.stat.bind(this.#core);
|
|
925
|
+
this.readDirectory = this.#core.readDirectory.bind(this.#core);
|
|
926
|
+
this.getCapabilities = this.#core.getCapabilities.bind(this.#core);
|
|
927
|
+
}
|
|
928
|
+
get providerInfo() {
|
|
929
|
+
return this.#core.providerInfo;
|
|
930
|
+
}
|
|
931
|
+
get hasProvider() {
|
|
932
|
+
return this.#core.hasProvider;
|
|
933
|
+
}
|
|
934
|
+
findUp(name, from, options = {}) {
|
|
935
|
+
const opts = {
|
|
936
|
+
...options,
|
|
937
|
+
fs: this.#core
|
|
938
|
+
};
|
|
939
|
+
return findUpFromUrl(name, from, opts);
|
|
940
|
+
}
|
|
905
941
|
};
|
|
906
942
|
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
943
|
+
//#endregion
|
|
944
|
+
//#region src/VFileSystem.ts
|
|
945
|
+
let FSCapabilityFlags = /* @__PURE__ */ function(FSCapabilityFlags$1) {
|
|
946
|
+
FSCapabilityFlags$1[FSCapabilityFlags$1["None"] = 0] = "None";
|
|
947
|
+
FSCapabilityFlags$1[FSCapabilityFlags$1["Stat"] = 1] = "Stat";
|
|
948
|
+
FSCapabilityFlags$1[FSCapabilityFlags$1["Read"] = 2] = "Read";
|
|
949
|
+
FSCapabilityFlags$1[FSCapabilityFlags$1["Write"] = 4] = "Write";
|
|
950
|
+
FSCapabilityFlags$1[FSCapabilityFlags$1["ReadWrite"] = 6] = "ReadWrite";
|
|
951
|
+
FSCapabilityFlags$1[FSCapabilityFlags$1["ReadDir"] = 8] = "ReadDir";
|
|
952
|
+
FSCapabilityFlags$1[FSCapabilityFlags$1["WriteDir"] = 16] = "WriteDir";
|
|
953
|
+
FSCapabilityFlags$1[FSCapabilityFlags$1["ReadWriteDir"] = 24] = "ReadWriteDir";
|
|
954
|
+
return FSCapabilityFlags$1;
|
|
955
|
+
}({});
|
|
919
956
|
|
|
920
|
-
|
|
957
|
+
//#endregion
|
|
958
|
+
//#region src/VirtualFS/WrappedProviderFs.ts
|
|
921
959
|
function cspellIOToFsProvider(cspellIO) {
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
960
|
+
const capabilities = FSCapabilityFlags.Stat | FSCapabilityFlags.ReadWrite | FSCapabilityFlags.ReadDir;
|
|
961
|
+
const capabilitiesHttp = capabilities & ~FSCapabilityFlags.Write & ~FSCapabilityFlags.ReadDir;
|
|
962
|
+
const capMap = {
|
|
963
|
+
"file:": capabilities,
|
|
964
|
+
"http:": capabilitiesHttp,
|
|
965
|
+
"https:": capabilitiesHttp
|
|
966
|
+
};
|
|
967
|
+
const name = "CSpellIO";
|
|
968
|
+
const supportedProtocols = new Set([
|
|
969
|
+
"file:",
|
|
970
|
+
"http:",
|
|
971
|
+
"https:"
|
|
972
|
+
]);
|
|
973
|
+
const fs$1 = {
|
|
974
|
+
providerInfo: { name },
|
|
975
|
+
stat: (url) => cspellIO.getStat(url),
|
|
976
|
+
readFile: (url, options) => cspellIO.readFile(url, options),
|
|
977
|
+
readDirectory: (url) => cspellIO.readDirectory(url),
|
|
978
|
+
writeFile: (file) => cspellIO.writeFile(file.url, file.content),
|
|
979
|
+
dispose: () => void 0,
|
|
980
|
+
capabilities,
|
|
981
|
+
getCapabilities(url) {
|
|
982
|
+
return fsCapabilities(capMap[url.protocol] || FSCapabilityFlags.None);
|
|
983
|
+
}
|
|
984
|
+
};
|
|
985
|
+
return {
|
|
986
|
+
name,
|
|
987
|
+
getFileSystem: (url, _next) => {
|
|
988
|
+
return supportedProtocols.has(url.protocol) ? fs$1 : void 0;
|
|
989
|
+
}
|
|
990
|
+
};
|
|
949
991
|
}
|
|
950
992
|
function wrapError(e) {
|
|
951
|
-
|
|
952
|
-
|
|
993
|
+
if (e instanceof VFSError) return e;
|
|
994
|
+
return e;
|
|
953
995
|
}
|
|
954
996
|
var VFSError = class extends Error {
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
997
|
+
constructor(message, options) {
|
|
998
|
+
super(message, options);
|
|
999
|
+
}
|
|
958
1000
|
};
|
|
959
1001
|
var VFSErrorUnsupportedRequest = class extends VFSError {
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
1002
|
+
url;
|
|
1003
|
+
constructor(request, url, parameters) {
|
|
1004
|
+
super(`Unsupported request: ${request}`);
|
|
1005
|
+
this.request = request;
|
|
1006
|
+
this.parameters = parameters;
|
|
1007
|
+
this.url = url?.toString();
|
|
1008
|
+
}
|
|
967
1009
|
};
|
|
968
1010
|
var CFsCapabilities = class {
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
1011
|
+
constructor(flags) {
|
|
1012
|
+
this.flags = flags;
|
|
1013
|
+
}
|
|
1014
|
+
get readFile() {
|
|
1015
|
+
return !!(this.flags & FSCapabilityFlags.Read);
|
|
1016
|
+
}
|
|
1017
|
+
get writeFile() {
|
|
1018
|
+
return !!(this.flags & FSCapabilityFlags.Write);
|
|
1019
|
+
}
|
|
1020
|
+
get readDirectory() {
|
|
1021
|
+
return !!(this.flags & FSCapabilityFlags.ReadDir);
|
|
1022
|
+
}
|
|
1023
|
+
get writeDirectory() {
|
|
1024
|
+
return !!(this.flags & FSCapabilityFlags.WriteDir);
|
|
1025
|
+
}
|
|
1026
|
+
get stat() {
|
|
1027
|
+
return !!(this.flags & FSCapabilityFlags.Stat);
|
|
1028
|
+
}
|
|
987
1029
|
};
|
|
988
1030
|
function fsCapabilities(flags) {
|
|
989
|
-
|
|
990
|
-
}
|
|
991
|
-
var WrappedProviderFs = class
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1031
|
+
return new CFsCapabilities(flags);
|
|
1032
|
+
}
|
|
1033
|
+
var WrappedProviderFs = class WrappedProviderFs {
|
|
1034
|
+
hasProvider;
|
|
1035
|
+
capabilities;
|
|
1036
|
+
providerInfo;
|
|
1037
|
+
_capabilities;
|
|
1038
|
+
constructor(fs$1, eventLogger) {
|
|
1039
|
+
this.fs = fs$1;
|
|
1040
|
+
this.eventLogger = eventLogger;
|
|
1041
|
+
this.hasProvider = !!fs$1;
|
|
1042
|
+
this.capabilities = fs$1?.capabilities || FSCapabilityFlags.None;
|
|
1043
|
+
this._capabilities = fsCapabilities(this.capabilities);
|
|
1044
|
+
this.providerInfo = fs$1?.providerInfo || { name: "unknown" };
|
|
1045
|
+
}
|
|
1046
|
+
logEvent(method, event, traceID, url, message) {
|
|
1047
|
+
this.eventLogger({
|
|
1048
|
+
method,
|
|
1049
|
+
event,
|
|
1050
|
+
url,
|
|
1051
|
+
traceID,
|
|
1052
|
+
ts: performance.now(),
|
|
1053
|
+
message
|
|
1054
|
+
});
|
|
1055
|
+
}
|
|
1056
|
+
getCapabilities(url) {
|
|
1057
|
+
if (this.fs?.getCapabilities) return this.fs.getCapabilities(url);
|
|
1058
|
+
return this._capabilities;
|
|
1059
|
+
}
|
|
1060
|
+
async stat(urlRef) {
|
|
1061
|
+
const traceID = performance.now();
|
|
1062
|
+
const url = urlOrReferenceToUrl(urlRef);
|
|
1063
|
+
this.logEvent("stat", "start", traceID, url);
|
|
1064
|
+
try {
|
|
1065
|
+
checkCapabilityOrThrow(this.fs, this.capabilities, FSCapabilityFlags.Stat, "stat", url);
|
|
1066
|
+
return new CVfsStat(await this.fs.stat(urlRef));
|
|
1067
|
+
} catch (e) {
|
|
1068
|
+
this.logEvent("stat", "error", traceID, url, e instanceof Error ? e.message : "");
|
|
1069
|
+
throw wrapError(e);
|
|
1070
|
+
} finally {
|
|
1071
|
+
this.logEvent("stat", "end", traceID, url);
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
async readFile(urlRef, optionsOrEncoding) {
|
|
1075
|
+
const traceID = performance.now();
|
|
1076
|
+
const url = urlOrReferenceToUrl(urlRef);
|
|
1077
|
+
this.logEvent("readFile", "start", traceID, url);
|
|
1078
|
+
try {
|
|
1079
|
+
checkCapabilityOrThrow(this.fs, this.capabilities, FSCapabilityFlags.Read, "readFile", url);
|
|
1080
|
+
const readOptions = toOptions(optionsOrEncoding);
|
|
1081
|
+
return fromFileResource(await this.fs.readFile(urlRef, readOptions), readOptions?.encoding);
|
|
1082
|
+
} catch (e) {
|
|
1083
|
+
this.logEvent("readFile", "error", traceID, url, e instanceof Error ? e.message : "");
|
|
1084
|
+
throw wrapError(e);
|
|
1085
|
+
} finally {
|
|
1086
|
+
this.logEvent("readFile", "end", traceID, url);
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
async readDirectory(url) {
|
|
1090
|
+
const traceID = performance.now();
|
|
1091
|
+
this.logEvent("readDir", "start", traceID, url);
|
|
1092
|
+
try {
|
|
1093
|
+
checkCapabilityOrThrow(this.fs, this.capabilities, FSCapabilityFlags.ReadDir, "readDirectory", url);
|
|
1094
|
+
return (await this.fs.readDirectory(url)).map((e) => new CVfsDirEntry(e));
|
|
1095
|
+
} catch (e) {
|
|
1096
|
+
this.logEvent("readDir", "error", traceID, url, e instanceof Error ? e.message : "");
|
|
1097
|
+
throw wrapError(e);
|
|
1098
|
+
} finally {
|
|
1099
|
+
this.logEvent("readDir", "end", traceID, url);
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
async writeFile(file) {
|
|
1103
|
+
const traceID = performance.now();
|
|
1104
|
+
const url = file.url;
|
|
1105
|
+
this.logEvent("writeFile", "start", traceID, url);
|
|
1106
|
+
try {
|
|
1107
|
+
checkCapabilityOrThrow(this.fs, this.capabilities, FSCapabilityFlags.Write, "writeFile", file.url);
|
|
1108
|
+
return await this.fs.writeFile(file);
|
|
1109
|
+
} catch (e) {
|
|
1110
|
+
this.logEvent("writeFile", "error", traceID, url, e instanceof Error ? e.message : "");
|
|
1111
|
+
throw wrapError(e);
|
|
1112
|
+
} finally {
|
|
1113
|
+
this.logEvent("writeFile", "end", traceID, url);
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
static disposeOf(fs$1) {
|
|
1117
|
+
fs$1 instanceof WrappedProviderFs && fs$1.fs?.dispose();
|
|
1118
|
+
}
|
|
1070
1119
|
};
|
|
1071
|
-
function checkCapabilityOrThrow(
|
|
1072
|
-
|
|
1073
|
-
throw new VFSErrorUnsupportedRequest(name, url);
|
|
1074
|
-
}
|
|
1120
|
+
function checkCapabilityOrThrow(fs$1, capabilities, flag, name, url) {
|
|
1121
|
+
if (!(capabilities & flag)) throw new VFSErrorUnsupportedRequest(name, url);
|
|
1075
1122
|
}
|
|
1076
1123
|
var CFileType = class {
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1124
|
+
constructor(fileType) {
|
|
1125
|
+
this.fileType = fileType;
|
|
1126
|
+
}
|
|
1127
|
+
isFile() {
|
|
1128
|
+
return this.fileType === FileType.File;
|
|
1129
|
+
}
|
|
1130
|
+
isDirectory() {
|
|
1131
|
+
return this.fileType === FileType.Directory;
|
|
1132
|
+
}
|
|
1133
|
+
isUnknown() {
|
|
1134
|
+
return !this.fileType;
|
|
1135
|
+
}
|
|
1136
|
+
isSymbolicLink() {
|
|
1137
|
+
return !!(this.fileType & FileType.SymbolicLink);
|
|
1138
|
+
}
|
|
1092
1139
|
};
|
|
1093
1140
|
var CVfsStat = class extends CFileType {
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1141
|
+
constructor(stat) {
|
|
1142
|
+
super(stat.fileType || FileType.Unknown);
|
|
1143
|
+
this.stat = stat;
|
|
1144
|
+
}
|
|
1145
|
+
get size() {
|
|
1146
|
+
return this.stat.size;
|
|
1147
|
+
}
|
|
1148
|
+
get mtimeMs() {
|
|
1149
|
+
return this.stat.mtimeMs;
|
|
1150
|
+
}
|
|
1151
|
+
get eTag() {
|
|
1152
|
+
return this.stat.eTag;
|
|
1153
|
+
}
|
|
1107
1154
|
};
|
|
1108
1155
|
var CVfsDirEntry = class extends CFileType {
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1156
|
+
_url;
|
|
1157
|
+
constructor(entry) {
|
|
1158
|
+
super(entry.fileType);
|
|
1159
|
+
this.entry = entry;
|
|
1160
|
+
}
|
|
1161
|
+
get name() {
|
|
1162
|
+
return this.entry.name;
|
|
1163
|
+
}
|
|
1164
|
+
get dir() {
|
|
1165
|
+
return this.entry.dir;
|
|
1166
|
+
}
|
|
1167
|
+
get url() {
|
|
1168
|
+
if (this._url) return this._url;
|
|
1169
|
+
this._url = new URL(this.entry.name, this.entry.dir);
|
|
1170
|
+
return this._url;
|
|
1171
|
+
}
|
|
1172
|
+
toJSON() {
|
|
1173
|
+
return {
|
|
1174
|
+
name: this.name,
|
|
1175
|
+
dir: this.dir,
|
|
1176
|
+
fileType: this.fileType
|
|
1177
|
+
};
|
|
1178
|
+
}
|
|
1132
1179
|
};
|
|
1133
1180
|
function chopUrl(url) {
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1181
|
+
if (!url) return "";
|
|
1182
|
+
const href = url.href;
|
|
1183
|
+
const parts = href.split("/");
|
|
1184
|
+
const n = parts.indexOf("node_modules");
|
|
1185
|
+
if (n > 0) {
|
|
1186
|
+
const tail = parts.slice(Math.max(parts.length - 3, n + 1));
|
|
1187
|
+
return parts.slice(0, n + 1).join("/") + "/…/" + tail.join("/");
|
|
1188
|
+
}
|
|
1189
|
+
return href;
|
|
1143
1190
|
}
|
|
1144
1191
|
function rPad(str, len, ch = " ") {
|
|
1145
|
-
|
|
1192
|
+
return str.padEnd(len, ch);
|
|
1146
1193
|
}
|
|
1147
1194
|
function toOptions(val) {
|
|
1148
|
-
|
|
1195
|
+
return typeof val === "string" ? { encoding: val } : val;
|
|
1149
1196
|
}
|
|
1150
1197
|
|
|
1151
|
-
|
|
1198
|
+
//#endregion
|
|
1199
|
+
//#region src/CVirtualFS.ts
|
|
1152
1200
|
var CVirtualFS = class {
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
this.cachedFs.delete(key);
|
|
1237
|
-
}
|
|
1238
|
-
this.cachedFs.clear();
|
|
1239
|
-
this.revCacheFs.clear();
|
|
1240
|
-
}
|
|
1241
|
-
dispose() {
|
|
1242
|
-
this.disposeOfCachedFs();
|
|
1243
|
-
const providers = [...this.providers].reverse();
|
|
1244
|
-
for (const provider of providers) {
|
|
1245
|
-
try {
|
|
1246
|
-
provider.dispose?.();
|
|
1247
|
-
} catch {
|
|
1248
|
-
}
|
|
1249
|
-
}
|
|
1250
|
-
}
|
|
1201
|
+
providers = /* @__PURE__ */ new Set();
|
|
1202
|
+
cachedFs = /* @__PURE__ */ new Map();
|
|
1203
|
+
revCacheFs = /* @__PURE__ */ new Map();
|
|
1204
|
+
fsc;
|
|
1205
|
+
fs;
|
|
1206
|
+
loggingEnabled = debug;
|
|
1207
|
+
constructor() {
|
|
1208
|
+
this.fsc = fsPassThroughCore((url) => this._getFS(url));
|
|
1209
|
+
this.fs = new CVFileSystem(this.fsc);
|
|
1210
|
+
}
|
|
1211
|
+
enableLogging(value) {
|
|
1212
|
+
this.loggingEnabled = value ?? true;
|
|
1213
|
+
}
|
|
1214
|
+
log = console.log;
|
|
1215
|
+
logEvent = (event) => {
|
|
1216
|
+
if (this.loggingEnabled) {
|
|
1217
|
+
const id = event.traceID.toFixed(13).replaceAll(/\d{4}(?=\d)/g, "$&.");
|
|
1218
|
+
const msg = event.message ? `\n\t\t${event.message}` : "";
|
|
1219
|
+
const method = rPad(`${event.method}-${event.event}`, 16);
|
|
1220
|
+
this.log(`${method} ID:${id} ts:${event.ts.toFixed(13)} ${chopUrl(event.url)}${msg}`);
|
|
1221
|
+
}
|
|
1222
|
+
};
|
|
1223
|
+
registerFileSystemProvider(...providers) {
|
|
1224
|
+
providers.forEach((provider) => this.providers.add(provider));
|
|
1225
|
+
this.reset();
|
|
1226
|
+
return { dispose: () => {
|
|
1227
|
+
for (const provider of providers) {
|
|
1228
|
+
for (const key of this.revCacheFs.get(provider) || []) this.cachedFs.delete(key);
|
|
1229
|
+
this.providers.delete(provider);
|
|
1230
|
+
}
|
|
1231
|
+
this.reset();
|
|
1232
|
+
} };
|
|
1233
|
+
}
|
|
1234
|
+
getFS(url) {
|
|
1235
|
+
return new CVFileSystem(this._getFS(url));
|
|
1236
|
+
}
|
|
1237
|
+
_getFS(url) {
|
|
1238
|
+
const key = `${url.protocol}${url.hostname}`;
|
|
1239
|
+
const cached = this.cachedFs.get(key);
|
|
1240
|
+
if (cached) return cached;
|
|
1241
|
+
const fnNext = (provider, next$1) => {
|
|
1242
|
+
return (url$1) => {
|
|
1243
|
+
let calledNext = false;
|
|
1244
|
+
const fs$2 = provider.getFileSystem(url$1, (_url) => {
|
|
1245
|
+
calledNext = calledNext || url$1 === _url;
|
|
1246
|
+
return next$1(_url);
|
|
1247
|
+
});
|
|
1248
|
+
if (fs$2) {
|
|
1249
|
+
const s = this.revCacheFs.get(provider) || /* @__PURE__ */ new Set();
|
|
1250
|
+
s.add(key);
|
|
1251
|
+
this.revCacheFs.set(provider, s);
|
|
1252
|
+
return fs$2;
|
|
1253
|
+
}
|
|
1254
|
+
if (!calledNext) return next$1(url$1);
|
|
1255
|
+
return void 0;
|
|
1256
|
+
};
|
|
1257
|
+
};
|
|
1258
|
+
let next = (_url) => void 0;
|
|
1259
|
+
for (const provider of this.providers) next = fnNext(provider, next);
|
|
1260
|
+
const fs$1 = new WrappedProviderFs(next(url), this.logEvent);
|
|
1261
|
+
this.cachedFs.set(key, fs$1);
|
|
1262
|
+
return fs$1;
|
|
1263
|
+
}
|
|
1264
|
+
reset() {
|
|
1265
|
+
this.disposeOfCachedFs();
|
|
1266
|
+
}
|
|
1267
|
+
disposeOfCachedFs() {
|
|
1268
|
+
for (const [key, fs$1] of [...this.cachedFs].reverse()) {
|
|
1269
|
+
try {
|
|
1270
|
+
WrappedProviderFs.disposeOf(fs$1);
|
|
1271
|
+
} catch {}
|
|
1272
|
+
this.cachedFs.delete(key);
|
|
1273
|
+
}
|
|
1274
|
+
this.cachedFs.clear();
|
|
1275
|
+
this.revCacheFs.clear();
|
|
1276
|
+
}
|
|
1277
|
+
dispose() {
|
|
1278
|
+
this.disposeOfCachedFs();
|
|
1279
|
+
const providers = [...this.providers].reverse();
|
|
1280
|
+
for (const provider of providers) try {
|
|
1281
|
+
provider.dispose?.();
|
|
1282
|
+
} catch {}
|
|
1283
|
+
}
|
|
1251
1284
|
};
|
|
1252
|
-
function fsPassThroughCore(
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
getCapabilities: (url) => gfs(url, "getCapabilities").getCapabilities(url)
|
|
1272
|
-
};
|
|
1285
|
+
function fsPassThroughCore(fs$1) {
|
|
1286
|
+
function gfs(ur, name) {
|
|
1287
|
+
const url = urlOrReferenceToUrl(ur);
|
|
1288
|
+
const f = fs$1(url);
|
|
1289
|
+
if (!f.hasProvider) throw new VFSErrorUnsupportedRequest(name, url, ur instanceof URL ? void 0 : {
|
|
1290
|
+
url: ur.url.toString(),
|
|
1291
|
+
encoding: ur.encoding
|
|
1292
|
+
});
|
|
1293
|
+
return f;
|
|
1294
|
+
}
|
|
1295
|
+
return {
|
|
1296
|
+
providerInfo: { name: "default" },
|
|
1297
|
+
hasProvider: true,
|
|
1298
|
+
stat: async (url) => gfs(url, "stat").stat(url),
|
|
1299
|
+
readFile: async (url, options) => gfs(url, "readFile").readFile(url, options),
|
|
1300
|
+
writeFile: async (file) => gfs(file, "writeFile").writeFile(file),
|
|
1301
|
+
readDirectory: async (url) => gfs(url, "readDirectory").readDirectory(url).then((entries) => entries.map((e) => new CVfsDirEntry(e))),
|
|
1302
|
+
getCapabilities: (url) => gfs(url, "getCapabilities").getCapabilities(url)
|
|
1303
|
+
};
|
|
1273
1304
|
}
|
|
1274
1305
|
function createVirtualFS(cspellIO) {
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1306
|
+
const cspell = cspellIO || getDefaultCSpellIO();
|
|
1307
|
+
const vfs = new CVirtualFS();
|
|
1308
|
+
vfs.registerFileSystemProvider(cspellIOToFsProvider(cspell));
|
|
1309
|
+
return vfs;
|
|
1279
1310
|
}
|
|
1280
|
-
|
|
1311
|
+
let defaultVirtualFs = void 0;
|
|
1281
1312
|
function getDefaultVirtualFs() {
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
}
|
|
1285
|
-
return defaultVirtualFs;
|
|
1313
|
+
if (!defaultVirtualFs) defaultVirtualFs = createVirtualFS();
|
|
1314
|
+
return defaultVirtualFs;
|
|
1286
1315
|
}
|
|
1287
1316
|
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
import * as Stream from "stream";
|
|
1291
|
-
import { promisify as promisify2 } from "util";
|
|
1292
|
-
import * as zlib from "zlib";
|
|
1293
|
-
|
|
1294
|
-
// src/common/transformers.ts
|
|
1317
|
+
//#endregion
|
|
1318
|
+
//#region src/common/transformers.ts
|
|
1295
1319
|
function encoderTransformer(iterable, encoding) {
|
|
1296
|
-
|
|
1320
|
+
return isAsyncIterable(iterable) ? encoderAsyncIterable(iterable, encoding) : encoderIterable(iterable, encoding);
|
|
1297
1321
|
}
|
|
1298
1322
|
function* encoderIterable(iterable, encoding) {
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1323
|
+
let useBom = true;
|
|
1324
|
+
for (const chunk of iterable) {
|
|
1325
|
+
yield encodeString(chunk, encoding, useBom);
|
|
1326
|
+
useBom = false;
|
|
1327
|
+
}
|
|
1304
1328
|
}
|
|
1305
1329
|
async function* encoderAsyncIterable(iterable, encoding) {
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1330
|
+
let useBom = true;
|
|
1331
|
+
for await (const chunk of iterable) {
|
|
1332
|
+
yield encodeString(chunk, encoding, useBom);
|
|
1333
|
+
useBom = false;
|
|
1334
|
+
}
|
|
1311
1335
|
}
|
|
1312
1336
|
function isAsyncIterable(v) {
|
|
1313
|
-
|
|
1337
|
+
return v && typeof v === "object" && !!v[Symbol.asyncIterator];
|
|
1314
1338
|
}
|
|
1315
1339
|
|
|
1316
|
-
|
|
1317
|
-
|
|
1340
|
+
//#endregion
|
|
1341
|
+
//#region src/node/file/fileWriter.ts
|
|
1342
|
+
const pipeline = promisify(Stream.pipeline);
|
|
1318
1343
|
function writeToFile(filename, data, encoding) {
|
|
1319
|
-
|
|
1344
|
+
return writeToFileIterable(filename, typeof data === "string" ? [data] : data, encoding);
|
|
1320
1345
|
}
|
|
1321
1346
|
function writeToFileIterable(filename, data, encoding) {
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1347
|
+
const stream = Stream.Readable.from(encoderTransformer(data, encoding));
|
|
1348
|
+
const zip = /\.gz$/.test(filename) ? zlib.createGzip() : new Stream.PassThrough();
|
|
1349
|
+
return pipeline(stream, zip, fs.createWriteStream(filename));
|
|
1325
1350
|
}
|
|
1326
1351
|
|
|
1327
|
-
|
|
1352
|
+
//#endregion
|
|
1353
|
+
//#region src/file/file.ts
|
|
1328
1354
|
async function readFileText(filename, encoding) {
|
|
1329
|
-
|
|
1330
|
-
|
|
1355
|
+
const fr = await getDefaultCSpellIO().readFile(filename, encoding);
|
|
1356
|
+
return fr.getText();
|
|
1331
1357
|
}
|
|
1332
1358
|
function readFileTextSync(filename, encoding) {
|
|
1333
|
-
|
|
1359
|
+
return getDefaultCSpellIO().readFileSync(filename, encoding).getText();
|
|
1334
1360
|
}
|
|
1335
1361
|
async function getStat(filenameOrUri) {
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1362
|
+
try {
|
|
1363
|
+
return await getDefaultCSpellIO().getStat(filenameOrUri);
|
|
1364
|
+
} catch (e) {
|
|
1365
|
+
return toError(e);
|
|
1366
|
+
}
|
|
1341
1367
|
}
|
|
1342
1368
|
function getStatSync(filenameOrUri) {
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1369
|
+
try {
|
|
1370
|
+
return getDefaultCSpellIO().getStatSync(filenameOrUri);
|
|
1371
|
+
} catch (e) {
|
|
1372
|
+
return toError(e);
|
|
1373
|
+
}
|
|
1348
1374
|
}
|
|
1349
1375
|
|
|
1350
|
-
|
|
1351
|
-
|
|
1376
|
+
//#endregion
|
|
1377
|
+
//#region src/VirtualFS/redirectProvider.ts
|
|
1352
1378
|
var RedirectProvider = class {
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
}
|
|
1367
|
-
const shadowFS = next(url);
|
|
1368
|
-
return remapFS(this.name, privateFs, shadowFS, this.publicRoot, this.privateRoot, this.options);
|
|
1369
|
-
}
|
|
1379
|
+
constructor(name, publicRoot, privateRoot, options = { capabilitiesMask: -1 }) {
|
|
1380
|
+
this.name = name;
|
|
1381
|
+
this.publicRoot = publicRoot;
|
|
1382
|
+
this.privateRoot = privateRoot;
|
|
1383
|
+
this.options = options;
|
|
1384
|
+
}
|
|
1385
|
+
getFileSystem(url, next) {
|
|
1386
|
+
if (url.protocol !== this.publicRoot.protocol || url.host !== this.publicRoot.host) return void 0;
|
|
1387
|
+
const privateFs = next(this.privateRoot);
|
|
1388
|
+
if (!privateFs) return void 0;
|
|
1389
|
+
const shadowFS = next(url);
|
|
1390
|
+
return remapFS(this.name, privateFs, shadowFS, this.publicRoot, this.privateRoot, this.options);
|
|
1391
|
+
}
|
|
1370
1392
|
};
|
|
1393
|
+
/**
|
|
1394
|
+
* Create a provider that will redirect requests from the publicRoot to the privateRoot.
|
|
1395
|
+
* This is useful for creating a virtual file system that is a subset of another file system.
|
|
1396
|
+
*
|
|
1397
|
+
* Example:
|
|
1398
|
+
* ```ts
|
|
1399
|
+
* const vfs = createVirtualFS();
|
|
1400
|
+
* const provider = createRedirectProvider('test', new URL('file:///public/'), new URL('file:///private/'))
|
|
1401
|
+
* vfs.registerFileSystemProvider(provider);
|
|
1402
|
+
* // Read the content of `file:///private/file.txt`
|
|
1403
|
+
* const file = vfs.fs.readFile(new URL('file:///public/file.txt');
|
|
1404
|
+
* ```
|
|
1405
|
+
*
|
|
1406
|
+
* @param name - name of the provider
|
|
1407
|
+
* @param publicRoot - the root of the public file system.
|
|
1408
|
+
* @param privateRoot - the root of the private file system.
|
|
1409
|
+
* @param options - options for the provider.
|
|
1410
|
+
* @returns FileSystemProvider
|
|
1411
|
+
*/
|
|
1371
1412
|
function createRedirectProvider(name, publicRoot, privateRoot, options) {
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
}
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
isUrlLike,
|
|
1484
|
-
readFileText,
|
|
1485
|
-
readFileTextSync,
|
|
1486
|
-
renameFileReference,
|
|
1487
|
-
renameFileResource,
|
|
1488
|
-
toDataUrl,
|
|
1489
|
-
toFileURL,
|
|
1490
|
-
toURL,
|
|
1491
|
-
urlBasename,
|
|
1492
|
-
urlParent as urlDirname,
|
|
1493
|
-
urlOrReferenceToUrl,
|
|
1494
|
-
writeToFile,
|
|
1495
|
-
writeToFileIterable,
|
|
1496
|
-
writeToFileIterable as writeToFileIterableP
|
|
1497
|
-
};
|
|
1413
|
+
assert(publicRoot.pathname.endsWith("/"), "publicRoot must end with a slash");
|
|
1414
|
+
assert(privateRoot.pathname.endsWith("/"), "privateRoot must end with a slash");
|
|
1415
|
+
return new RedirectProvider(name, publicRoot, privateRoot, options);
|
|
1416
|
+
}
|
|
1417
|
+
/**
|
|
1418
|
+
* Create a Remapped file system that will redirect requests from the publicRoot to the privateRoot.
|
|
1419
|
+
* Requests that do not match the publicRoot will be passed to the shadowFs.
|
|
1420
|
+
* @param name - name of the provider
|
|
1421
|
+
* @param fs - the private file system
|
|
1422
|
+
* @param shadowFs - the file system that is obscured by the redirect.
|
|
1423
|
+
* @param publicRoot - the root of the public file system.
|
|
1424
|
+
* @param privateRoot - the root of the private file system.
|
|
1425
|
+
* @returns ProviderFileSystem
|
|
1426
|
+
*/
|
|
1427
|
+
function remapFS(name, fs$1, shadowFs, publicRoot, privateRoot, options) {
|
|
1428
|
+
const { capabilitiesMask = -1, capabilities } = options;
|
|
1429
|
+
function mapToPrivate(url) {
|
|
1430
|
+
const relativePath = url.pathname.slice(publicRoot.pathname.length);
|
|
1431
|
+
return new URL(relativePath, privateRoot);
|
|
1432
|
+
}
|
|
1433
|
+
function mapToPublic(url) {
|
|
1434
|
+
const relativePath = url.pathname.slice(privateRoot.pathname.length);
|
|
1435
|
+
return new URL(relativePath, publicRoot);
|
|
1436
|
+
}
|
|
1437
|
+
const mapFileReferenceToPrivate = (ref) => {
|
|
1438
|
+
return renameFileReference(ref, mapToPrivate(ref.url));
|
|
1439
|
+
};
|
|
1440
|
+
const mapFileReferenceToPublic = (ref) => {
|
|
1441
|
+
return renameFileReference(ref, mapToPublic(ref.url));
|
|
1442
|
+
};
|
|
1443
|
+
const mapUrlOrReferenceToPrivate = (urlOrRef) => {
|
|
1444
|
+
return urlOrRef instanceof URL ? mapToPrivate(urlOrRef) : mapFileReferenceToPrivate(urlOrRef);
|
|
1445
|
+
};
|
|
1446
|
+
const mapFileResourceToPublic = (res) => {
|
|
1447
|
+
return renameFileResource(res, mapToPublic(res.url));
|
|
1448
|
+
};
|
|
1449
|
+
const mapFileResourceToPrivate = (res) => {
|
|
1450
|
+
return renameFileResource(res, mapToPrivate(res.url));
|
|
1451
|
+
};
|
|
1452
|
+
const mapDirEntryToPublic = (de) => {
|
|
1453
|
+
const dir = mapToPublic(de.dir);
|
|
1454
|
+
return {
|
|
1455
|
+
...de,
|
|
1456
|
+
dir
|
|
1457
|
+
};
|
|
1458
|
+
};
|
|
1459
|
+
const fs2 = {
|
|
1460
|
+
stat: async (url) => {
|
|
1461
|
+
const url2 = mapUrlOrReferenceToPrivate(url);
|
|
1462
|
+
const stat = await fs$1.stat(url2);
|
|
1463
|
+
return stat;
|
|
1464
|
+
},
|
|
1465
|
+
readFile: async (url, options$1) => {
|
|
1466
|
+
const url2 = mapUrlOrReferenceToPrivate(url);
|
|
1467
|
+
const file = await fs$1.readFile(url2, options$1);
|
|
1468
|
+
return mapFileResourceToPublic(file);
|
|
1469
|
+
},
|
|
1470
|
+
readDirectory: async (url) => {
|
|
1471
|
+
const url2 = mapToPrivate(url);
|
|
1472
|
+
const dir = await fs$1.readDirectory(url2);
|
|
1473
|
+
return dir.map(mapDirEntryToPublic);
|
|
1474
|
+
},
|
|
1475
|
+
writeFile: async (file) => {
|
|
1476
|
+
const fileRef2 = mapFileResourceToPrivate(file);
|
|
1477
|
+
const fileRef3 = await fs$1.writeFile(fileRef2);
|
|
1478
|
+
return mapFileReferenceToPublic(fileRef3);
|
|
1479
|
+
},
|
|
1480
|
+
providerInfo: {
|
|
1481
|
+
...fs$1.providerInfo,
|
|
1482
|
+
name
|
|
1483
|
+
},
|
|
1484
|
+
capabilities: capabilities ?? fs$1.capabilities & capabilitiesMask,
|
|
1485
|
+
dispose: () => fs$1.dispose()
|
|
1486
|
+
};
|
|
1487
|
+
return fsPassThrough(fs2, shadowFs, publicRoot);
|
|
1488
|
+
}
|
|
1489
|
+
function fsPassThrough(fs$1, shadowFs, root) {
|
|
1490
|
+
function gfs(ur, name) {
|
|
1491
|
+
const url = urlOrReferenceToUrl(ur);
|
|
1492
|
+
const f = url.href.startsWith(root.href) ? fs$1 : shadowFs;
|
|
1493
|
+
if (!f) throw new VFSErrorUnsupportedRequest(name, url, ur instanceof URL ? void 0 : {
|
|
1494
|
+
url: ur.url.toString(),
|
|
1495
|
+
encoding: ur.encoding
|
|
1496
|
+
});
|
|
1497
|
+
return f;
|
|
1498
|
+
}
|
|
1499
|
+
const passThroughFs = {
|
|
1500
|
+
get providerInfo() {
|
|
1501
|
+
return fs$1.providerInfo;
|
|
1502
|
+
},
|
|
1503
|
+
get capabilities() {
|
|
1504
|
+
return fs$1.capabilities;
|
|
1505
|
+
},
|
|
1506
|
+
stat: async (url) => gfs(url, "stat").stat(url),
|
|
1507
|
+
readFile: async (url) => gfs(url, "readFile").readFile(url),
|
|
1508
|
+
writeFile: async (file) => gfs(file, "writeFile").writeFile(file),
|
|
1509
|
+
readDirectory: async (url) => gfs(url, "readDirectory").readDirectory(url),
|
|
1510
|
+
getCapabilities(url) {
|
|
1511
|
+
const f = gfs(url, "getCapabilities");
|
|
1512
|
+
return f.getCapabilities ? f.getCapabilities(url) : fsCapabilities(f.capabilities);
|
|
1513
|
+
},
|
|
1514
|
+
dispose: () => {
|
|
1515
|
+
fs$1.dispose();
|
|
1516
|
+
shadowFs?.dispose();
|
|
1517
|
+
}
|
|
1518
|
+
};
|
|
1519
|
+
return passThroughFs;
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1522
|
+
//#endregion
|
|
1523
|
+
export { CFileReference, CFileResource, CSpellIONode, FSCapabilityFlags, FileType as VFileType, toArray as asyncIterableToArray, compareStats, createRedirectProvider, fromFileResource as createTextFileResource, createVirtualFS, encodeDataUrl, getDefaultCSpellIO, getDefaultVirtualFs, getStat, getStatSync, isFileURL, isUrlLike, readFileText, readFileTextSync, renameFileReference, renameFileResource, toDataUrl, toFileURL, toURL, urlBasename, urlDirname, urlOrReferenceToUrl, writeToFile, writeToFileIterable, writeToFileIterable as writeToFileIterableP };
|
|
1498
1524
|
//# sourceMappingURL=index.js.map
|