cspell-io 8.9.1 → 8.10.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.
@@ -0,0 +1,8 @@
1
+ import type { CSpellIO } from './CSpellIO.js';
2
+ import { VFileSystem, VFileSystemCore } from './VFileSystem.js';
3
+ import { VirtualFS } from './VirtualFS.js';
4
+ export declare function createVirtualFS(cspellIO?: CSpellIO): VirtualFS;
5
+ export declare function getDefaultVirtualFs(): VirtualFS;
6
+ export declare function getDefaultVFileSystemCore(): VFileSystemCore;
7
+ export declare function getDefaultVFileSystem(): VFileSystem;
8
+ //# sourceMappingURL=CVirtualFS.d.ts.map
@@ -0,0 +1,148 @@
1
+ import { urlOrReferenceToUrl } from './common/index.js';
2
+ import { getDefaultCSpellIO } from './CSpellIONode.js';
3
+ import { debug } from './VirtualFS.js';
4
+ import { CVFileSystem } from './VirtualFS/CVFileSystem.js';
5
+ import { chopUrl, cspellIOToFsProvider, CVfsDirEntry, rPad, VFSErrorUnsupportedRequest, WrappedProviderFs, } from './VirtualFS/WrappedProviderFs.js';
6
+ class CVirtualFS {
7
+ providers = new Set();
8
+ cachedFs = new Map();
9
+ revCacheFs = new Map();
10
+ fsc;
11
+ fs;
12
+ loggingEnabled = debug;
13
+ constructor() {
14
+ this.fsc = fsPassThroughCore((url) => this._getFS(url));
15
+ this.fs = new CVFileSystem(this.fsc);
16
+ }
17
+ enableLogging(value) {
18
+ this.loggingEnabled = value ?? true;
19
+ }
20
+ log = console.log;
21
+ logEvent = (event) => {
22
+ if (this.loggingEnabled) {
23
+ const id = event.traceID.toFixed(13).replaceAll(/\d{4}(?=\d)/g, '$&.');
24
+ const msg = event.message ? `\n\t\t${event.message}` : '';
25
+ const method = rPad(`${event.method}-${event.event}`, 16);
26
+ this.log(`${method} ID:${id} ts:${event.ts.toFixed(13)} ${chopUrl(event.url)}${msg}`);
27
+ }
28
+ };
29
+ registerFileSystemProvider(...providers) {
30
+ providers.forEach((provider) => this.providers.add(provider));
31
+ this.reset();
32
+ return {
33
+ dispose: () => {
34
+ for (const provider of providers) {
35
+ for (const key of this.revCacheFs.get(provider) || []) {
36
+ this.cachedFs.delete(key);
37
+ }
38
+ this.providers.delete(provider) && undefined;
39
+ }
40
+ this.reset();
41
+ },
42
+ };
43
+ }
44
+ getFS(url) {
45
+ return new CVFileSystem(this._getFS(url));
46
+ }
47
+ _getFS(url) {
48
+ const key = `${url.protocol}${url.hostname}`;
49
+ const cached = this.cachedFs.get(key);
50
+ if (cached) {
51
+ return cached;
52
+ }
53
+ const fnNext = (provider, next) => {
54
+ return (url) => {
55
+ let calledNext = false;
56
+ const fs = provider.getFileSystem(url, (_url) => {
57
+ calledNext = calledNext || url === _url;
58
+ return next(_url);
59
+ });
60
+ if (fs) {
61
+ const s = this.revCacheFs.get(provider) || new Set();
62
+ s.add(key);
63
+ this.revCacheFs.set(provider, s);
64
+ return fs;
65
+ }
66
+ if (!calledNext) {
67
+ return next(url);
68
+ }
69
+ return undefined;
70
+ };
71
+ };
72
+ let next = (_url) => undefined;
73
+ for (const provider of this.providers) {
74
+ next = fnNext(provider, next);
75
+ }
76
+ const fs = new WrappedProviderFs(next(url), this.logEvent);
77
+ this.cachedFs.set(key, fs);
78
+ return fs;
79
+ }
80
+ reset() {
81
+ this.disposeOfCachedFs();
82
+ }
83
+ disposeOfCachedFs() {
84
+ for (const [key, fs] of [...this.cachedFs].reverse()) {
85
+ try {
86
+ WrappedProviderFs.disposeOf(fs);
87
+ }
88
+ catch {
89
+ // continue - we are cleaning up.
90
+ }
91
+ this.cachedFs.delete(key);
92
+ }
93
+ this.cachedFs.clear();
94
+ this.revCacheFs.clear();
95
+ }
96
+ dispose() {
97
+ this.disposeOfCachedFs();
98
+ const providers = [...this.providers].reverse();
99
+ for (const provider of providers) {
100
+ try {
101
+ provider.dispose?.();
102
+ }
103
+ catch {
104
+ // continue - we are cleaning up.
105
+ }
106
+ }
107
+ }
108
+ }
109
+ function fsPassThroughCore(fs) {
110
+ function gfs(ur, name) {
111
+ const url = urlOrReferenceToUrl(ur);
112
+ const f = fs(url);
113
+ if (!f.hasProvider)
114
+ throw new VFSErrorUnsupportedRequest(name, url, ur instanceof URL ? undefined : { url: ur.url.toString(), encoding: ur.encoding });
115
+ return f;
116
+ }
117
+ return {
118
+ providerInfo: { name: 'default' },
119
+ hasProvider: true,
120
+ stat: async (url) => gfs(url, 'stat').stat(url),
121
+ readFile: async (url) => gfs(url, 'readFile').readFile(url),
122
+ writeFile: async (file) => gfs(file, 'writeFile').writeFile(file),
123
+ readDirectory: async (url) => gfs(url, 'readDirectory')
124
+ .readDirectory(url)
125
+ .then((entries) => entries.map((e) => new CVfsDirEntry(e))),
126
+ getCapabilities: (url) => gfs(url, 'getCapabilities').getCapabilities(url),
127
+ };
128
+ }
129
+ export function createVirtualFS(cspellIO) {
130
+ const cspell = cspellIO || getDefaultCSpellIO();
131
+ const vfs = new CVirtualFS();
132
+ vfs.registerFileSystemProvider(cspellIOToFsProvider(cspell));
133
+ return vfs;
134
+ }
135
+ let defaultVirtualFs = undefined;
136
+ export function getDefaultVirtualFs() {
137
+ if (!defaultVirtualFs) {
138
+ defaultVirtualFs = createVirtualFS();
139
+ }
140
+ return defaultVirtualFs;
141
+ }
142
+ export function getDefaultVFileSystemCore() {
143
+ return getDefaultVirtualFs().fsc;
144
+ }
145
+ export function getDefaultVFileSystem() {
146
+ return getDefaultVirtualFs().fs;
147
+ }
148
+ //# sourceMappingURL=CVirtualFS.js.map
@@ -0,0 +1,85 @@
1
+ import type { BufferEncoding, DirEntry, FileReference, FileResource, Stats, TextFileResource } from './models/index.js';
2
+ export type UrlOrReference = URL | FileReference;
3
+ export declare enum FSCapabilityFlags {
4
+ None = 0,
5
+ Stat = 1,
6
+ Read = 2,
7
+ Write = 4,
8
+ ReadWrite = 6,
9
+ ReadDir = 8,
10
+ WriteDir = 16,
11
+ ReadWriteDir = 24
12
+ }
13
+ export interface FileSystemProviderInfo {
14
+ name: string;
15
+ }
16
+ export interface VFileSystemCore {
17
+ /**
18
+ * Read a file.
19
+ * @param url - URL to read
20
+ * @param encoding - optional encoding
21
+ * @returns A FileResource, the content will not be decoded. Use `.getText()` to get the decoded text.
22
+ */
23
+ readFile(url: UrlOrReference, encoding?: BufferEncoding): Promise<TextFileResource>;
24
+ /**
25
+ * Write a file
26
+ * @param file - the file to write
27
+ */
28
+ writeFile(file: FileResource): Promise<FileReference>;
29
+ /**
30
+ * Get the stats for a url.
31
+ * @param url - Url to fetch stats for.
32
+ */
33
+ stat(url: UrlOrReference): Promise<VfsStat>;
34
+ /**
35
+ * Read the directory entries for a url.
36
+ * The url should end with `/` to indicate a directory.
37
+ * @param url - the url to read the directory entries for.
38
+ */
39
+ readDirectory(url: URL): Promise<VfsDirEntry[]>;
40
+ /**
41
+ * Get the capabilities for a URL.
42
+ * The capabilities can be more restrictive than the general capabilities of the provider.
43
+ * @param url - the url to try
44
+ */
45
+ getCapabilities(url: URL): FSCapabilities;
46
+ /**
47
+ * Information about the provider.
48
+ * It is up to the provider to define what information is available.
49
+ */
50
+ providerInfo: FileSystemProviderInfo;
51
+ /**
52
+ * Indicates that a provider was found for the url.
53
+ */
54
+ hasProvider: boolean;
55
+ }
56
+ export interface VFileSystem extends VFileSystemCore {
57
+ findUp(name: string | string[] | VFindUpPredicate, from: URL, options?: VFindUpURLOptions): Promise<URL | undefined>;
58
+ }
59
+ export interface FSCapabilities {
60
+ readonly flags: FSCapabilityFlags;
61
+ readonly readFile: boolean;
62
+ readonly writeFile: boolean;
63
+ readonly readDirectory: boolean;
64
+ readonly writeDirectory: boolean;
65
+ readonly stat: boolean;
66
+ }
67
+ export interface VfsStat extends Stats {
68
+ isDirectory(): boolean;
69
+ isFile(): boolean;
70
+ isUnknown(): boolean;
71
+ isSymbolicLink(): boolean;
72
+ }
73
+ export interface VfsDirEntry extends DirEntry {
74
+ isDirectory(): boolean;
75
+ isFile(): boolean;
76
+ isUnknown(): boolean;
77
+ isSymbolicLink(): boolean;
78
+ }
79
+ export type VFindEntryType = 'file' | 'directory' | '!file' | '!directory';
80
+ export interface VFindUpURLOptions {
81
+ type?: VFindEntryType;
82
+ stopAt?: URL;
83
+ }
84
+ export type VFindUpPredicate = (dir: URL) => URL | undefined | Promise<URL | undefined>;
85
+ //# sourceMappingURL=VFileSystem.d.ts.map
@@ -0,0 +1,12 @@
1
+ export var FSCapabilityFlags;
2
+ (function (FSCapabilityFlags) {
3
+ FSCapabilityFlags[FSCapabilityFlags["None"] = 0] = "None";
4
+ FSCapabilityFlags[FSCapabilityFlags["Stat"] = 1] = "Stat";
5
+ FSCapabilityFlags[FSCapabilityFlags["Read"] = 2] = "Read";
6
+ FSCapabilityFlags[FSCapabilityFlags["Write"] = 4] = "Write";
7
+ FSCapabilityFlags[FSCapabilityFlags["ReadWrite"] = 6] = "ReadWrite";
8
+ FSCapabilityFlags[FSCapabilityFlags["ReadDir"] = 8] = "ReadDir";
9
+ FSCapabilityFlags[FSCapabilityFlags["WriteDir"] = 16] = "WriteDir";
10
+ FSCapabilityFlags[FSCapabilityFlags["ReadWriteDir"] = 24] = "ReadWriteDir";
11
+ })(FSCapabilityFlags || (FSCapabilityFlags = {}));
12
+ //# sourceMappingURL=VFileSystem.js.map
@@ -0,0 +1,14 @@
1
+ import { VFileSystem, VFileSystemCore, VFindUpPredicate, VFindUpURLOptions } from '../VFileSystem.js';
2
+ export declare class CVFileSystem implements VFileSystem {
3
+ #private;
4
+ readFile: VFileSystem['readFile'];
5
+ writeFile: VFileSystem['writeFile'];
6
+ stat: VFileSystem['stat'];
7
+ readDirectory: VFileSystem['readDirectory'];
8
+ getCapabilities: VFileSystem['getCapabilities'];
9
+ constructor(core: VFileSystemCore);
10
+ get providerInfo(): VFileSystem['providerInfo'];
11
+ get hasProvider(): VFileSystem['hasProvider'];
12
+ findUp(name: string | string[] | VFindUpPredicate, from: URL, options?: VFindUpURLOptions): Promise<URL | undefined>;
13
+ }
14
+ //# sourceMappingURL=CVFileSystem.d.ts.map
@@ -0,0 +1,28 @@
1
+ import { findUpFromUrl } from './findUpFromUrl.js';
2
+ export class CVFileSystem {
3
+ #core;
4
+ readFile;
5
+ writeFile;
6
+ stat;
7
+ readDirectory;
8
+ getCapabilities;
9
+ constructor(core) {
10
+ this.#core = core;
11
+ this.readFile = this.#core.readFile.bind(this.#core);
12
+ this.writeFile = this.#core.writeFile.bind(this.#core);
13
+ this.stat = this.#core.stat.bind(this.#core);
14
+ this.readDirectory = this.#core.readDirectory.bind(this.#core);
15
+ this.getCapabilities = this.#core.getCapabilities.bind(this.#core);
16
+ }
17
+ get providerInfo() {
18
+ return this.#core.providerInfo;
19
+ }
20
+ get hasProvider() {
21
+ return this.#core.hasProvider;
22
+ }
23
+ findUp(name, from, options = {}) {
24
+ const opts = { ...options, fs: this.#core };
25
+ return findUpFromUrl(name, from, opts);
26
+ }
27
+ }
28
+ //# sourceMappingURL=CVFileSystem.js.map
@@ -0,0 +1,56 @@
1
+ import type { CSpellIO } from '../CSpellIO.js';
2
+ import type { BufferEncoding, DirEntry, FileReference, FileResource, TextFileResource } from '../models/index.js';
3
+ import { FileType } from '../models/index.js';
4
+ import type { LogEvent } from '../models/LogEvent.js';
5
+ import { FileSystemProviderInfo, FSCapabilities, FSCapabilityFlags, UrlOrReference, VFileSystemCore, VfsDirEntry, VfsStat } from '../VFileSystem.js';
6
+ import { VFileSystemProvider, VProviderFileSystem } from '../VirtualFS.js';
7
+ export declare function cspellIOToFsProvider(cspellIO: CSpellIO): VFileSystemProvider;
8
+ export declare class VFSError extends Error {
9
+ constructor(message: string, options?: {
10
+ cause?: unknown;
11
+ });
12
+ }
13
+ export declare class VFSErrorUnsupportedRequest extends VFSError {
14
+ readonly request: string;
15
+ readonly parameters?: unknown | undefined;
16
+ readonly url?: string | undefined;
17
+ constructor(request: string, url?: URL | string, parameters?: unknown | undefined);
18
+ }
19
+ export declare function fsCapabilities(flags: FSCapabilityFlags): FSCapabilities;
20
+ export declare class WrappedProviderFs implements VFileSystemCore {
21
+ private readonly fs;
22
+ readonly eventLogger: (event: LogEvent) => void;
23
+ readonly hasProvider: boolean;
24
+ readonly capabilities: FSCapabilityFlags;
25
+ readonly providerInfo: FileSystemProviderInfo;
26
+ private _capabilities;
27
+ constructor(fs: VProviderFileSystem | undefined, eventLogger: (event: LogEvent) => void);
28
+ private logEvent;
29
+ getCapabilities(url: URL): FSCapabilities;
30
+ stat(urlRef: UrlOrReference): Promise<VfsStat>;
31
+ readFile(urlRef: UrlOrReference, encoding?: BufferEncoding): Promise<TextFileResource>;
32
+ readDirectory(url: URL): Promise<VfsDirEntry[]>;
33
+ writeFile(file: FileResource): Promise<FileReference>;
34
+ static disposeOf<V extends VFileSystemCore>(fs: V): void;
35
+ }
36
+ declare class CFileType {
37
+ readonly fileType: FileType;
38
+ constructor(fileType: FileType);
39
+ isFile(): boolean;
40
+ isDirectory(): boolean;
41
+ isUnknown(): boolean;
42
+ isSymbolicLink(): boolean;
43
+ }
44
+ export declare class CVfsDirEntry extends CFileType implements VfsDirEntry {
45
+ private entry;
46
+ private _url;
47
+ constructor(entry: DirEntry);
48
+ get name(): string;
49
+ get dir(): URL;
50
+ get url(): URL;
51
+ toJSON(): DirEntry;
52
+ }
53
+ export declare function chopUrl(url: URL | undefined): string;
54
+ export declare function rPad(str: string, len: number, ch?: string): string;
55
+ export {};
56
+ //# sourceMappingURL=WrappedProviderFs.d.ts.map
@@ -0,0 +1,250 @@
1
+ import { createTextFileResource, urlOrReferenceToUrl } from '../common/index.js';
2
+ import { FileType } from '../models/index.js';
3
+ import { FSCapabilityFlags, } from '../VFileSystem.js';
4
+ export function cspellIOToFsProvider(cspellIO) {
5
+ const capabilities = FSCapabilityFlags.Stat | FSCapabilityFlags.ReadWrite | FSCapabilityFlags.ReadDir;
6
+ const capabilitiesHttp = capabilities & ~FSCapabilityFlags.Write & ~FSCapabilityFlags.ReadDir;
7
+ const capMap = {
8
+ 'file:': capabilities,
9
+ 'http:': capabilitiesHttp,
10
+ 'https:': capabilitiesHttp,
11
+ };
12
+ const name = 'CSpellIO';
13
+ const supportedProtocols = new Set(['file:', 'http:', 'https:']);
14
+ const fs = {
15
+ providerInfo: { name },
16
+ stat: (url) => cspellIO.getStat(url),
17
+ readFile: (url) => cspellIO.readFile(url),
18
+ readDirectory: (url) => cspellIO.readDirectory(url),
19
+ writeFile: (file) => cspellIO.writeFile(file.url, file.content),
20
+ dispose: () => undefined,
21
+ capabilities,
22
+ getCapabilities(url) {
23
+ return fsCapabilities(capMap[url.protocol] || FSCapabilityFlags.None);
24
+ },
25
+ };
26
+ return {
27
+ name,
28
+ getFileSystem: (url, _next) => {
29
+ return supportedProtocols.has(url.protocol) ? fs : undefined;
30
+ },
31
+ };
32
+ }
33
+ function wrapError(e) {
34
+ if (e instanceof VFSError)
35
+ return e;
36
+ // return new VFSError(e instanceof Error ? e.message : String(e), { cause: e });
37
+ return e;
38
+ }
39
+ export class VFSError extends Error {
40
+ constructor(message, options) {
41
+ super(message, options);
42
+ }
43
+ }
44
+ export class VFSErrorUnsupportedRequest extends VFSError {
45
+ request;
46
+ parameters;
47
+ url;
48
+ constructor(request, url, parameters) {
49
+ super(`Unsupported request: ${request}`);
50
+ this.request = request;
51
+ this.parameters = parameters;
52
+ this.url = url?.toString();
53
+ }
54
+ }
55
+ class CFsCapabilities {
56
+ flags;
57
+ constructor(flags) {
58
+ this.flags = flags;
59
+ }
60
+ get readFile() {
61
+ return !!(this.flags & FSCapabilityFlags.Read);
62
+ }
63
+ get writeFile() {
64
+ return !!(this.flags & FSCapabilityFlags.Write);
65
+ }
66
+ get readDirectory() {
67
+ return !!(this.flags & FSCapabilityFlags.ReadDir);
68
+ }
69
+ get writeDirectory() {
70
+ return !!(this.flags & FSCapabilityFlags.WriteDir);
71
+ }
72
+ get stat() {
73
+ return !!(this.flags & FSCapabilityFlags.Stat);
74
+ }
75
+ }
76
+ export function fsCapabilities(flags) {
77
+ return new CFsCapabilities(flags);
78
+ }
79
+ export class WrappedProviderFs {
80
+ fs;
81
+ eventLogger;
82
+ hasProvider;
83
+ capabilities;
84
+ providerInfo;
85
+ _capabilities;
86
+ constructor(fs, eventLogger) {
87
+ this.fs = fs;
88
+ this.eventLogger = eventLogger;
89
+ this.hasProvider = !!fs;
90
+ this.capabilities = fs?.capabilities || FSCapabilityFlags.None;
91
+ this._capabilities = fsCapabilities(this.capabilities);
92
+ this.providerInfo = fs?.providerInfo || { name: 'unknown' };
93
+ }
94
+ logEvent(method, event, traceID, url, message) {
95
+ this.eventLogger({ method, event, url, traceID, ts: performance.now(), message });
96
+ }
97
+ getCapabilities(url) {
98
+ if (this.fs?.getCapabilities)
99
+ return this.fs.getCapabilities(url);
100
+ return this._capabilities;
101
+ }
102
+ async stat(urlRef) {
103
+ const traceID = performance.now();
104
+ const url = urlOrReferenceToUrl(urlRef);
105
+ this.logEvent('stat', 'start', traceID, url);
106
+ try {
107
+ checkCapabilityOrThrow(this.fs, this.capabilities, FSCapabilityFlags.Stat, 'stat', url);
108
+ return new CVfsStat(await this.fs.stat(urlRef));
109
+ }
110
+ catch (e) {
111
+ this.logEvent('stat', 'error', traceID, url, e instanceof Error ? e.message : '');
112
+ throw wrapError(e);
113
+ }
114
+ finally {
115
+ this.logEvent('stat', 'end', traceID, url);
116
+ }
117
+ }
118
+ async readFile(urlRef, encoding) {
119
+ const traceID = performance.now();
120
+ const url = urlOrReferenceToUrl(urlRef);
121
+ this.logEvent('readFile', 'start', traceID, url);
122
+ try {
123
+ checkCapabilityOrThrow(this.fs, this.capabilities, FSCapabilityFlags.Read, 'readFile', url);
124
+ return createTextFileResource(await this.fs.readFile(urlRef), encoding);
125
+ }
126
+ catch (e) {
127
+ this.logEvent('readFile', 'error', traceID, url, e instanceof Error ? e.message : '');
128
+ throw wrapError(e);
129
+ }
130
+ finally {
131
+ this.logEvent('readFile', 'end', traceID, url);
132
+ }
133
+ }
134
+ async readDirectory(url) {
135
+ const traceID = performance.now();
136
+ this.logEvent('readDir', 'start', traceID, url);
137
+ try {
138
+ checkCapabilityOrThrow(this.fs, this.capabilities, FSCapabilityFlags.ReadDir, 'readDirectory', url);
139
+ return (await this.fs.readDirectory(url)).map((e) => new CVfsDirEntry(e));
140
+ }
141
+ catch (e) {
142
+ this.logEvent('readDir', 'error', traceID, url, e instanceof Error ? e.message : '');
143
+ throw wrapError(e);
144
+ }
145
+ finally {
146
+ this.logEvent('readDir', 'end', traceID, url);
147
+ }
148
+ }
149
+ async writeFile(file) {
150
+ const traceID = performance.now();
151
+ const url = file.url;
152
+ this.logEvent('writeFile', 'start', traceID, url);
153
+ try {
154
+ checkCapabilityOrThrow(this.fs, this.capabilities, FSCapabilityFlags.Write, 'writeFile', file.url);
155
+ return await this.fs.writeFile(file);
156
+ }
157
+ catch (e) {
158
+ this.logEvent('writeFile', 'error', traceID, url, e instanceof Error ? e.message : '');
159
+ throw wrapError(e);
160
+ }
161
+ finally {
162
+ this.logEvent('writeFile', 'end', traceID, url);
163
+ }
164
+ }
165
+ static disposeOf(fs) {
166
+ fs instanceof WrappedProviderFs && fs.fs?.dispose();
167
+ }
168
+ }
169
+ function checkCapabilityOrThrow(fs, capabilities, flag, name, url) {
170
+ if (!(capabilities & flag)) {
171
+ throw new VFSErrorUnsupportedRequest(name, url);
172
+ }
173
+ }
174
+ class CFileType {
175
+ fileType;
176
+ constructor(fileType) {
177
+ this.fileType = fileType;
178
+ }
179
+ isFile() {
180
+ return this.fileType === FileType.File;
181
+ }
182
+ isDirectory() {
183
+ return this.fileType === FileType.Directory;
184
+ }
185
+ isUnknown() {
186
+ return !this.fileType;
187
+ }
188
+ isSymbolicLink() {
189
+ return !!(this.fileType & FileType.SymbolicLink);
190
+ }
191
+ }
192
+ class CVfsStat extends CFileType {
193
+ stat;
194
+ constructor(stat) {
195
+ super(stat.fileType || FileType.Unknown);
196
+ this.stat = stat;
197
+ }
198
+ get size() {
199
+ return this.stat.size;
200
+ }
201
+ get mtimeMs() {
202
+ return this.stat.mtimeMs;
203
+ }
204
+ get eTag() {
205
+ return this.stat.eTag;
206
+ }
207
+ }
208
+ export class CVfsDirEntry extends CFileType {
209
+ entry;
210
+ _url;
211
+ constructor(entry) {
212
+ super(entry.fileType);
213
+ this.entry = entry;
214
+ }
215
+ get name() {
216
+ return this.entry.name;
217
+ }
218
+ get dir() {
219
+ return this.entry.dir;
220
+ }
221
+ get url() {
222
+ if (this._url)
223
+ return this._url;
224
+ this._url = new URL(this.entry.name, this.entry.dir);
225
+ return this._url;
226
+ }
227
+ toJSON() {
228
+ return {
229
+ name: this.name,
230
+ dir: this.dir,
231
+ fileType: this.fileType,
232
+ };
233
+ }
234
+ }
235
+ export function chopUrl(url) {
236
+ if (!url)
237
+ return '';
238
+ const href = url.href;
239
+ const parts = href.split('/');
240
+ const n = parts.indexOf('node_modules');
241
+ if (n > 0) {
242
+ const tail = parts.slice(Math.max(parts.length - 3, n + 1));
243
+ return parts.slice(0, n + 1).join('/') + '/…/' + tail.join('/');
244
+ }
245
+ return href;
246
+ }
247
+ export function rPad(str, len, ch = ' ') {
248
+ return str.padEnd(len, ch);
249
+ }
250
+ //# sourceMappingURL=WrappedProviderFs.js.map
@@ -0,0 +1,8 @@
1
+ import type { VFileSystemCore, VFindUpURLOptions } from '../VFileSystem.js';
2
+ export type FindUpFileSystem = Pick<VFileSystemCore, 'stat'>;
3
+ export interface FindUpURLOptions extends VFindUpURLOptions {
4
+ fs: FindUpFileSystem;
5
+ }
6
+ export type FindUpPredicate = (dir: URL) => URL | undefined | Promise<URL | undefined>;
7
+ export declare function findUpFromUrl(name: string | string[] | FindUpPredicate, from: URL, options: FindUpURLOptions): Promise<URL | undefined>;
8
+ //# sourceMappingURL=findUpFromUrl.d.ts.map
@@ -0,0 +1,43 @@
1
+ export async function findUpFromUrl(name, from, options) {
2
+ const { type: entryType = 'file', stopAt, fs } = options;
3
+ let dir = new URL('.', from);
4
+ const root = new URL('/', dir);
5
+ const predicate = makePredicate(fs, name, entryType);
6
+ const stopAtDir = stopAt || root;
7
+ let last = '';
8
+ while (dir.href !== last) {
9
+ const found = await predicate(dir);
10
+ if (found !== undefined)
11
+ return found;
12
+ last = dir.href;
13
+ if (dir.href === root.href || dir.href === stopAtDir.href)
14
+ break;
15
+ dir = new URL('..', dir);
16
+ }
17
+ return undefined;
18
+ }
19
+ function makePredicate(fs, name, entryType) {
20
+ if (typeof name === 'function')
21
+ return name;
22
+ const checkStat = entryType === 'file' || entryType === '!file' ? 'isFile' : 'isDirectory';
23
+ const checkValue = entryType.startsWith('!') ? false : true;
24
+ function checkName(dir, name) {
25
+ const f = new URL(name, dir);
26
+ return fs
27
+ .stat(f)
28
+ .then((stats) => ((stats.isUnknown() || stats[checkStat]() === checkValue) && f) || undefined)
29
+ .catch(() => undefined);
30
+ }
31
+ if (!Array.isArray(name))
32
+ return (dir) => checkName(dir, name);
33
+ return async (dir) => {
34
+ const pending = name.map((n) => checkName(dir, n));
35
+ for (const p of pending) {
36
+ const found = await p;
37
+ if (found)
38
+ return found;
39
+ }
40
+ return undefined;
41
+ };
42
+ }
43
+ //# sourceMappingURL=findUpFromUrl.js.map
@@ -1,4 +1,5 @@
1
- import type { FSCapabilityFlags, VFileSystemProvider } from '../VirtualFS.js';
1
+ import type { FSCapabilityFlags } from '../VFileSystem.js';
2
+ import type { VFileSystemProvider } from '../VirtualFS.js';
2
3
  export interface RedirectOptions {
3
4
  /**
4
5
  * Option ts to mask the capabilities of the provider.
@@ -1,6 +1,6 @@
1
1
  import assert from 'node:assert';
2
2
  import { renameFileReference, renameFileResource, urlOrReferenceToUrl } from '../common/index.js';
3
- import { fsCapabilities, VFSErrorUnsupportedRequest } from '../VirtualFS.js';
3
+ import { fsCapabilities, VFSErrorUnsupportedRequest } from './WrappedProviderFs.js';
4
4
  class RedirectProvider {
5
5
  name;
6
6
  publicRoot;
@@ -1,7 +1,7 @@
1
- import type { CSpellIO } from './CSpellIO.js';
2
- import type { BufferEncoding, DirEntry, Disposable, FileReference, FileResource, Stats, TextFileResource } from './models/index.js';
3
- type UrlOrReference = URL | FileReference;
4
- type NextProvider = (url: URL) => VProviderFileSystem | undefined;
1
+ import type { DirEntry, Disposable, FileReference, FileResource, Stats } from './models/index.js';
2
+ import type { FileSystemProviderInfo, FSCapabilities, FSCapabilityFlags, UrlOrReference, VFileSystem, VFileSystemCore } from './VFileSystem.js';
3
+ export type NextProvider = (url: URL) => VProviderFileSystem | undefined;
4
+ export declare const debug = false;
5
5
  export interface VirtualFS extends Disposable {
6
6
  registerFileSystemProvider(provider: VFileSystemProvider, ...providers: VFileSystemProvider[]): Disposable;
7
7
  /**
@@ -12,6 +12,10 @@ export interface VirtualFS extends Disposable {
12
12
  * The file system. All requests will first use getFileSystem to get the file system before making the request.
13
13
  */
14
14
  readonly fs: Required<VFileSystem>;
15
+ /**
16
+ * The file system core. All requests will first use getFileSystem to get the file system before making the request.
17
+ */
18
+ readonly fsc: Required<VFileSystemCore>;
15
19
  /**
16
20
  * Clear the cache of file systems.
17
21
  */
@@ -22,59 +26,6 @@ export interface VirtualFS extends Disposable {
22
26
  loggingEnabled: boolean;
23
27
  enableLogging(value?: boolean): void;
24
28
  }
25
- export declare enum FSCapabilityFlags {
26
- None = 0,
27
- Stat = 1,
28
- Read = 2,
29
- Write = 4,
30
- ReadWrite = 6,
31
- ReadDir = 8,
32
- WriteDir = 16,
33
- ReadWriteDir = 24
34
- }
35
- interface FileSystemProviderInfo {
36
- name: string;
37
- }
38
- export interface VFileSystem {
39
- /**
40
- * Read a file.
41
- * @param url - URL to read
42
- * @param encoding - optional encoding
43
- * @returns A FileResource, the content will not be decoded. Use `.getText()` to get the decoded text.
44
- */
45
- readFile(url: UrlOrReference, encoding?: BufferEncoding): Promise<TextFileResource>;
46
- /**
47
- * Write a file
48
- * @param file - the file to write
49
- */
50
- writeFile(file: FileResource): Promise<FileReference>;
51
- /**
52
- * Get the stats for a url.
53
- * @param url - Url to fetch stats for.
54
- */
55
- stat(url: UrlOrReference): Promise<VfsStat>;
56
- /**
57
- * Read the directory entries for a url.
58
- * The url should end with `/` to indicate a directory.
59
- * @param url - the url to read the directory entries for.
60
- */
61
- readDirectory(url: URL): Promise<VfsDirEntry[]>;
62
- /**
63
- * Get the capabilities for a URL.
64
- * The capabilities can be more restrictive than the general capabilities of the provider.
65
- * @param url - the url to try
66
- */
67
- getCapabilities(url: URL): FSCapabilities;
68
- /**
69
- * Information about the provider.
70
- * It is up to the provider to define what information is available.
71
- */
72
- providerInfo: FileSystemProviderInfo;
73
- /**
74
- * Indicates that a provider was found for the url.
75
- */
76
- hasProvider: boolean;
77
- }
78
29
  export interface VProviderFileSystem extends Disposable {
79
30
  readFile(url: UrlOrReference): Promise<FileResource>;
80
31
  writeFile(file: FileResource): Promise<FileReference>;
@@ -108,39 +59,4 @@ export interface VFileSystemProvider extends Partial<Disposable> {
108
59
  */
109
60
  getFileSystem(url: URL, next: NextProvider): VProviderFileSystem | undefined;
110
61
  }
111
- export declare function createVirtualFS(cspellIO?: CSpellIO): VirtualFS;
112
- export declare function getDefaultVirtualFs(): VirtualFS;
113
- export declare class VFSError extends Error {
114
- constructor(message: string, options?: {
115
- cause?: unknown;
116
- });
117
- }
118
- export declare class VFSErrorUnsupportedRequest extends VFSError {
119
- readonly request: string;
120
- readonly parameters?: unknown;
121
- readonly url?: string | undefined;
122
- constructor(request: string, url?: URL | string, parameters?: unknown);
123
- }
124
- export interface FSCapabilities {
125
- readonly flags: FSCapabilityFlags;
126
- readonly readFile: boolean;
127
- readonly writeFile: boolean;
128
- readonly readDirectory: boolean;
129
- readonly writeDirectory: boolean;
130
- readonly stat: boolean;
131
- }
132
- export declare function fsCapabilities(flags: FSCapabilityFlags): FSCapabilities;
133
- export interface VfsStat extends Stats {
134
- isDirectory(): boolean;
135
- isFile(): boolean;
136
- isUnknown(): boolean;
137
- isSymbolicLink(): boolean;
138
- }
139
- export interface VfsDirEntry extends DirEntry {
140
- isDirectory(): boolean;
141
- isFile(): boolean;
142
- isUnknown(): boolean;
143
- isSymbolicLink(): boolean;
144
- }
145
- export {};
146
62
  //# sourceMappingURL=VirtualFS.d.ts.map
@@ -1,397 +1,2 @@
1
- import { createTextFileResource, urlOrReferenceToUrl } from './common/index.js';
2
- import { getDefaultCSpellIO } from './CSpellIONode.js';
3
- import { FileType } from './models/index.js';
4
- const debug = false;
5
- export var FSCapabilityFlags;
6
- (function (FSCapabilityFlags) {
7
- FSCapabilityFlags[FSCapabilityFlags["None"] = 0] = "None";
8
- FSCapabilityFlags[FSCapabilityFlags["Stat"] = 1] = "Stat";
9
- FSCapabilityFlags[FSCapabilityFlags["Read"] = 2] = "Read";
10
- FSCapabilityFlags[FSCapabilityFlags["Write"] = 4] = "Write";
11
- FSCapabilityFlags[FSCapabilityFlags["ReadWrite"] = 6] = "ReadWrite";
12
- FSCapabilityFlags[FSCapabilityFlags["ReadDir"] = 8] = "ReadDir";
13
- FSCapabilityFlags[FSCapabilityFlags["WriteDir"] = 16] = "WriteDir";
14
- FSCapabilityFlags[FSCapabilityFlags["ReadWriteDir"] = 24] = "ReadWriteDir";
15
- })(FSCapabilityFlags || (FSCapabilityFlags = {}));
16
- class CVirtualFS {
17
- providers = new Set();
18
- cachedFs = new Map();
19
- revCacheFs = new Map();
20
- fs;
21
- loggingEnabled = debug;
22
- constructor() {
23
- this.fs = fsPassThrough((url) => this._getFS(url));
24
- }
25
- enableLogging(value) {
26
- this.loggingEnabled = value ?? true;
27
- }
28
- log = console.log;
29
- logEvent = (event) => {
30
- if (this.loggingEnabled) {
31
- const id = event.traceID.toFixed(13).replaceAll(/\d{4}(?=\d)/g, '$&.');
32
- const msg = event.message ? `\n\t\t${event.message}` : '';
33
- const method = rPad(`${event.method}-${event.event}`, 16);
34
- this.log(`${method} ID:${id} ts:${event.ts.toFixed(13)} ${chopUrl(event.url)}${msg}`);
35
- }
36
- };
37
- registerFileSystemProvider(...providers) {
38
- providers.forEach((provider) => this.providers.add(provider));
39
- this.reset();
40
- return {
41
- dispose: () => {
42
- for (const provider of providers) {
43
- for (const key of this.revCacheFs.get(provider) || []) {
44
- this.cachedFs.delete(key);
45
- }
46
- this.providers.delete(provider) && undefined;
47
- }
48
- this.reset();
49
- },
50
- };
51
- }
52
- getFS(url) {
53
- return this._getFS(url);
54
- }
55
- _getFS(url) {
56
- const key = `${url.protocol}${url.hostname}`;
57
- const cached = this.cachedFs.get(key);
58
- if (cached) {
59
- return cached;
60
- }
61
- const fnNext = (provider, next) => {
62
- return (url) => {
63
- let calledNext = false;
64
- const fs = provider.getFileSystem(url, (_url) => {
65
- calledNext = calledNext || url === _url;
66
- return next(_url);
67
- });
68
- if (fs) {
69
- const s = this.revCacheFs.get(provider) || new Set();
70
- s.add(key);
71
- this.revCacheFs.set(provider, s);
72
- return fs;
73
- }
74
- if (!calledNext) {
75
- return next(url);
76
- }
77
- return undefined;
78
- };
79
- };
80
- let next = (_url) => undefined;
81
- for (const provider of this.providers) {
82
- next = fnNext(provider, next);
83
- }
84
- const fs = new WrappedProviderFs(next(url), this.logEvent);
85
- this.cachedFs.set(key, fs);
86
- return fs;
87
- }
88
- reset() {
89
- this.cachedFs.clear();
90
- this.revCacheFs.clear();
91
- this.disposeOfCachedFs();
92
- }
93
- disposeOfCachedFs() {
94
- for (const [key, fs] of [...this.cachedFs].reverse()) {
95
- try {
96
- WrappedProviderFs.disposeOf(fs);
97
- }
98
- catch {
99
- // continue - we are cleaning up.
100
- }
101
- this.cachedFs.delete(key);
102
- }
103
- this.cachedFs.clear();
104
- }
105
- dispose() {
106
- this.disposeOfCachedFs();
107
- const providers = [...this.providers].reverse();
108
- for (const provider of providers) {
109
- try {
110
- provider.dispose?.();
111
- }
112
- catch {
113
- // continue - we are cleaning up.
114
- }
115
- }
116
- }
117
- }
118
- function fsPassThrough(fs) {
119
- function gfs(ur, name) {
120
- const url = urlOrReferenceToUrl(ur);
121
- const f = fs(url);
122
- if (!f.hasProvider)
123
- throw new VFSErrorUnsupportedRequest(name, url, ur instanceof URL ? undefined : { url: ur.url.toString(), encoding: ur.encoding });
124
- return f;
125
- }
126
- return {
127
- providerInfo: { name: 'default' },
128
- hasProvider: true,
129
- stat: async (url) => gfs(url, 'stat').stat(url),
130
- readFile: async (url) => gfs(url, 'readFile').readFile(url),
131
- writeFile: async (file) => gfs(file, 'writeFile').writeFile(file),
132
- readDirectory: async (url) => gfs(url, 'readDirectory')
133
- .readDirectory(url)
134
- .then((entries) => entries.map((e) => new CVfsDirEntry(e))),
135
- getCapabilities: (url) => gfs(url, 'getCapabilities').getCapabilities(url),
136
- };
137
- }
138
- export function createVirtualFS(cspellIO) {
139
- const cspell = cspellIO || getDefaultCSpellIO();
140
- const vfs = new CVirtualFS();
141
- vfs.registerFileSystemProvider(cspellIOToFsProvider(cspell));
142
- return vfs;
143
- }
144
- function cspellIOToFsProvider(cspellIO) {
145
- const capabilities = FSCapabilityFlags.Stat | FSCapabilityFlags.ReadWrite | FSCapabilityFlags.ReadDir;
146
- const capabilitiesHttp = capabilities & ~FSCapabilityFlags.Write & ~FSCapabilityFlags.ReadDir;
147
- const capMap = {
148
- 'file:': capabilities,
149
- 'http:': capabilitiesHttp,
150
- 'https:': capabilitiesHttp,
151
- };
152
- const name = 'CSpellIO';
153
- const supportedProtocols = new Set(['file:', 'http:', 'https:']);
154
- const fs = {
155
- providerInfo: { name },
156
- stat: (url) => cspellIO.getStat(url),
157
- readFile: (url) => cspellIO.readFile(url),
158
- readDirectory: (url) => cspellIO.readDirectory(url),
159
- writeFile: (file) => cspellIO.writeFile(file.url, file.content),
160
- dispose: () => undefined,
161
- capabilities,
162
- getCapabilities(url) {
163
- return fsCapabilities(capMap[url.protocol] || FSCapabilityFlags.None);
164
- },
165
- };
166
- return {
167
- name,
168
- getFileSystem: (url, _next) => {
169
- return supportedProtocols.has(url.protocol) ? fs : undefined;
170
- },
171
- };
172
- }
173
- let defaultVirtualFs = undefined;
174
- export function getDefaultVirtualFs() {
175
- if (!defaultVirtualFs) {
176
- defaultVirtualFs = createVirtualFS();
177
- }
178
- return defaultVirtualFs;
179
- }
180
- function wrapError(e) {
181
- if (e instanceof VFSError)
182
- return e;
183
- // return new VFSError(e instanceof Error ? e.message : String(e), { cause: e });
184
- return e;
185
- }
186
- export class VFSError extends Error {
187
- constructor(message, options) {
188
- super(message, options);
189
- }
190
- }
191
- export class VFSErrorUnsupportedRequest extends VFSError {
192
- request;
193
- parameters;
194
- url;
195
- constructor(request, url, parameters) {
196
- super(`Unsupported request: ${request}`);
197
- this.request = request;
198
- this.parameters = parameters;
199
- this.url = url?.toString();
200
- }
201
- }
202
- class CFsCapabilities {
203
- flags;
204
- constructor(flags) {
205
- this.flags = flags;
206
- }
207
- get readFile() {
208
- return !!(this.flags & FSCapabilityFlags.Read);
209
- }
210
- get writeFile() {
211
- return !!(this.flags & FSCapabilityFlags.Write);
212
- }
213
- get readDirectory() {
214
- return !!(this.flags & FSCapabilityFlags.ReadDir);
215
- }
216
- get writeDirectory() {
217
- return !!(this.flags & FSCapabilityFlags.WriteDir);
218
- }
219
- get stat() {
220
- return !!(this.flags & FSCapabilityFlags.Stat);
221
- }
222
- }
223
- export function fsCapabilities(flags) {
224
- return new CFsCapabilities(flags);
225
- }
226
- class WrappedProviderFs {
227
- fs;
228
- eventLogger;
229
- hasProvider;
230
- capabilities;
231
- providerInfo;
232
- _capabilities;
233
- constructor(fs, eventLogger) {
234
- this.fs = fs;
235
- this.eventLogger = eventLogger;
236
- this.hasProvider = !!fs;
237
- this.capabilities = fs?.capabilities || FSCapabilityFlags.None;
238
- this._capabilities = fsCapabilities(this.capabilities);
239
- this.providerInfo = fs?.providerInfo || { name: 'unknown' };
240
- }
241
- logEvent(method, event, traceID, url, message) {
242
- this.eventLogger({ method, event, url, traceID, ts: performance.now(), message });
243
- }
244
- getCapabilities(url) {
245
- if (this.fs?.getCapabilities)
246
- return this.fs.getCapabilities(url);
247
- return this._capabilities;
248
- }
249
- async stat(urlRef) {
250
- const traceID = performance.now();
251
- const url = urlOrReferenceToUrl(urlRef);
252
- this.logEvent('stat', 'start', traceID, url);
253
- try {
254
- checkCapabilityOrThrow(this.fs, this.capabilities, FSCapabilityFlags.Stat, 'stat', url);
255
- return new CVfsStat(await this.fs.stat(urlRef));
256
- }
257
- catch (e) {
258
- this.logEvent('stat', 'error', traceID, url, e instanceof Error ? e.message : '');
259
- throw wrapError(e);
260
- }
261
- finally {
262
- this.logEvent('stat', 'end', traceID, url);
263
- }
264
- }
265
- async readFile(urlRef, encoding) {
266
- const traceID = performance.now();
267
- const url = urlOrReferenceToUrl(urlRef);
268
- this.logEvent('readFile', 'start', traceID, url);
269
- try {
270
- checkCapabilityOrThrow(this.fs, this.capabilities, FSCapabilityFlags.Read, 'readFile', url);
271
- return createTextFileResource(await this.fs.readFile(urlRef), encoding);
272
- }
273
- catch (e) {
274
- this.logEvent('readFile', 'error', traceID, url, e instanceof Error ? e.message : '');
275
- throw wrapError(e);
276
- }
277
- finally {
278
- this.logEvent('readFile', 'end', traceID, url);
279
- }
280
- }
281
- async readDirectory(url) {
282
- const traceID = performance.now();
283
- this.logEvent('readDir', 'start', traceID, url);
284
- try {
285
- checkCapabilityOrThrow(this.fs, this.capabilities, FSCapabilityFlags.ReadDir, 'readDirectory', url);
286
- return (await this.fs.readDirectory(url)).map((e) => new CVfsDirEntry(e));
287
- }
288
- catch (e) {
289
- this.logEvent('readDir', 'error', traceID, url, e instanceof Error ? e.message : '');
290
- throw wrapError(e);
291
- }
292
- finally {
293
- this.logEvent('readDir', 'end', traceID, url);
294
- }
295
- }
296
- async writeFile(file) {
297
- const traceID = performance.now();
298
- const url = file.url;
299
- this.logEvent('writeFile', 'start', traceID, url);
300
- try {
301
- checkCapabilityOrThrow(this.fs, this.capabilities, FSCapabilityFlags.Write, 'writeFile', file.url);
302
- return await this.fs.writeFile(file);
303
- }
304
- catch (e) {
305
- this.logEvent('writeFile', 'error', traceID, url, e instanceof Error ? e.message : '');
306
- throw wrapError(e);
307
- }
308
- finally {
309
- this.logEvent('writeFile', 'end', traceID, url);
310
- }
311
- }
312
- static disposeOf(fs) {
313
- fs instanceof WrappedProviderFs && fs.fs?.dispose();
314
- }
315
- }
316
- function checkCapabilityOrThrow(fs, capabilities, flag, name, url) {
317
- if (!(capabilities & flag)) {
318
- throw new VFSErrorUnsupportedRequest(name, url);
319
- }
320
- }
321
- class CFileType {
322
- fileType;
323
- constructor(fileType) {
324
- this.fileType = fileType;
325
- }
326
- isFile() {
327
- return this.fileType === FileType.File;
328
- }
329
- isDirectory() {
330
- return this.fileType === FileType.Directory;
331
- }
332
- isUnknown() {
333
- return !this.fileType;
334
- }
335
- isSymbolicLink() {
336
- return !!(this.fileType & FileType.SymbolicLink);
337
- }
338
- }
339
- class CVfsStat extends CFileType {
340
- stat;
341
- constructor(stat) {
342
- super(stat.fileType || FileType.Unknown);
343
- this.stat = stat;
344
- }
345
- get size() {
346
- return this.stat.size;
347
- }
348
- get mtimeMs() {
349
- return this.stat.mtimeMs;
350
- }
351
- get eTag() {
352
- return this.stat.eTag;
353
- }
354
- }
355
- class CVfsDirEntry extends CFileType {
356
- entry;
357
- _url;
358
- constructor(entry) {
359
- super(entry.fileType);
360
- this.entry = entry;
361
- }
362
- get name() {
363
- return this.entry.name;
364
- }
365
- get dir() {
366
- return this.entry.dir;
367
- }
368
- get url() {
369
- if (this._url)
370
- return this._url;
371
- this._url = new URL(this.entry.name, this.entry.dir);
372
- return this._url;
373
- }
374
- toJSON() {
375
- return {
376
- name: this.name,
377
- dir: this.dir,
378
- fileType: this.fileType,
379
- };
380
- }
381
- }
382
- function chopUrl(url) {
383
- if (!url)
384
- return '';
385
- const href = url.href;
386
- const parts = href.split('/');
387
- const n = parts.indexOf('node_modules');
388
- if (n > 0) {
389
- const tail = parts.slice(Math.max(parts.length - 3, n + 1));
390
- return parts.slice(0, n + 1).join('/') + '/…/' + tail.join('/');
391
- }
392
- return href;
393
- }
394
- function rPad(str, len, ch = ' ') {
395
- return str + ch.repeat(Math.max(0, len - str.length));
396
- }
1
+ export const debug = false;
397
2
  //# sourceMappingURL=VirtualFS.js.map
@@ -1,4 +1,3 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
1
  /**
3
2
  * Treat a ArrayBufferView as a Uint8Array.
4
3
  * The Uint8Array will share the same underlying ArrayBuffer.
@@ -3,13 +3,15 @@ export * from './common/index.js';
3
3
  export { compareStats, createTextFileResource } from './common/index.js';
4
4
  export type { CSpellIO } from './CSpellIO.js';
5
5
  export { CSpellIONode, getDefaultCSpellIO } from './CSpellIONode.js';
6
+ export { createVirtualFS, getDefaultVirtualFs } from './CVirtualFS.js';
6
7
  export { getStat, getStatSync, readFileText, readFileTextSync, writeToFile, writeToFileIterable, writeToFileIterableP, } from './file/index.js';
7
8
  export type { BufferEncoding, TextEncoding } from './models/BufferEncoding.js';
8
9
  export type { Stats } from './models/Stats.js';
9
10
  export { FileType as VFileType } from './models/Stats.js';
10
11
  export { encodeDataUrl, toDataUrl } from './node/dataUrl.js';
11
12
  export { isFileURL, isUrlLike, toFileURL, toURL, urlBasename, urlDirname } from './node/file/url.js';
12
- export type { VFileSystem as VFileSystem, VFileSystemProvider, VfsDirEntry, VfsStat, VirtualFS, VProviderFileSystem, } from './VirtualFS.js';
13
- export { createVirtualFS, FSCapabilityFlags, getDefaultVirtualFs } from './VirtualFS.js';
13
+ export type { VFileSystem, VFileSystemCore, VFindEntryType, VFindUpPredicate, VFindUpURLOptions, VfsDirEntry, VfsStat, } from './VFileSystem.js';
14
+ export { FSCapabilityFlags } from './VFileSystem.js';
15
+ export type { VFileSystemProvider, VirtualFS, VProviderFileSystem } from './VirtualFS.js';
14
16
  export { createRedirectProvider } from './VirtualFS/redirectProvider.js';
15
17
  //# sourceMappingURL=index.d.ts.map
package/dist/esm/index.js CHANGED
@@ -2,10 +2,11 @@ export { toArray as asyncIterableToArray } from './async/asyncIterable.js';
2
2
  export * from './common/index.js';
3
3
  export { compareStats, createTextFileResource } from './common/index.js';
4
4
  export { CSpellIONode, getDefaultCSpellIO } from './CSpellIONode.js';
5
+ export { createVirtualFS, getDefaultVirtualFs } from './CVirtualFS.js';
5
6
  export { getStat, getStatSync, readFileText, readFileTextSync, writeToFile, writeToFileIterable, writeToFileIterableP, } from './file/index.js';
6
7
  export { FileType as VFileType } from './models/Stats.js';
7
8
  export { encodeDataUrl, toDataUrl } from './node/dataUrl.js';
8
9
  export { isFileURL, isUrlLike, toFileURL, toURL, urlBasename, urlDirname } from './node/file/url.js';
9
- export { createVirtualFS, FSCapabilityFlags, getDefaultVirtualFs } from './VirtualFS.js';
10
+ export { FSCapabilityFlags } from './VFileSystem.js';
10
11
  export { createRedirectProvider } from './VirtualFS/redirectProvider.js';
11
12
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,24 @@
1
+ export type EventMethods = 'stat' | 'readFile' | 'writeFile' | 'readDir';
2
+ export type LogEvents = 'start' | 'end' | 'error' | 'other';
3
+ export interface LogEvent {
4
+ /**
5
+ * The request method
6
+ */
7
+ method: EventMethods;
8
+ event: LogEvents;
9
+ message?: string | undefined;
10
+ /**
11
+ * The trace id can be used to link request and response events.
12
+ * The trace id is unique for a given request.
13
+ */
14
+ traceID: number;
15
+ /**
16
+ * The request url
17
+ */
18
+ url?: URL | undefined;
19
+ /**
20
+ * The time in milliseconds, see `performance.now()`
21
+ */
22
+ ts: number;
23
+ }
24
+ //# sourceMappingURL=LogEvent.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=LogEvent.js.map
@@ -1,4 +1,3 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
1
  /**
3
2
  * Generates a string of the following format:
4
3
  *
@@ -1,4 +1,3 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
1
  export declare class FetchUrlError extends Error implements NodeJS.ErrnoException {
3
2
  readonly code: string | undefined;
4
3
  readonly status: number | undefined;
@@ -1,4 +1,3 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
1
  export declare function fetchHead(request: string | URL): Promise<Headers>;
3
2
  export declare function fetchURL(url: URL): Promise<Buffer>;
4
3
  //# sourceMappingURL=fetch.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cspell-io",
3
- "version": "8.9.1",
3
+ "version": "8.10.0",
4
4
  "description": "A library of useful I/O functions used across various cspell tools.",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -49,11 +49,11 @@
49
49
  },
50
50
  "devDependencies": {
51
51
  "lorem-ipsum": "^2.0.8",
52
- "typescript": "^5.4.5"
52
+ "typescript": "^5.5.3"
53
53
  },
54
54
  "dependencies": {
55
- "@cspell/cspell-service-bus": "8.9.1",
56
- "@cspell/url": "8.9.1"
55
+ "@cspell/cspell-service-bus": "8.10.0",
56
+ "@cspell/url": "8.10.0"
57
57
  },
58
- "gitHead": "f532c77cca4bfae380293c586f02f377354c850b"
58
+ "gitHead": "a5dde6ae7e2ac86ac956220d4b8c39a0e58e1bc6"
59
59
  }