@legit-sdk/core 0.1.7
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/LICENSE +131 -0
- package/README.md +102 -0
- package/dist/index.d.ts +780 -0
- package/dist/index.js +133 -0
- package/package.json +59 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,780 @@
|
|
|
1
|
+
import * as nodeFs from 'node:fs';
|
|
2
|
+
import { MakeDirectoryOptions, Mode } from 'node:fs';
|
|
3
|
+
import * as memfs_lib_node_types_misc_js from 'memfs/lib/node/types/misc.js';
|
|
4
|
+
import { IDir, TFileHandleReadResult, TData, TMode, IStats, TTime, TFileHandleWriteResult, TFileHandleWritevResult, TFileHandleReadvResult, IFileHandle, TDataOut, IDirent, PathLike } from 'memfs/lib/node/types/misc.js';
|
|
5
|
+
import { IAppendFileOptions, IStatOptions, IReadFileOptions, IWriteFileOptions, IReadableWebStreamOptions } from 'memfs/lib/node/types/options.js';
|
|
6
|
+
import { PathLike as PathLike$1 } from 'fs';
|
|
7
|
+
import { IFs } from 'memfs';
|
|
8
|
+
import { FsClient } from 'isomorphic-git';
|
|
9
|
+
import { fileSave, FileWithHandle } from 'browser-fs-access';
|
|
10
|
+
|
|
11
|
+
type CompositeSubFsDir = Pick<IDir, "path" | "close" | "read" | typeof Symbol.asyncIterator>;
|
|
12
|
+
|
|
13
|
+
type FileHandleDelegate = {
|
|
14
|
+
fileType: () => number;
|
|
15
|
+
open: (filePath: string, flags: string, mode?: number) => Promise<CompositFsFileHandle>;
|
|
16
|
+
/**
|
|
17
|
+
* @returns a unique number per subfs
|
|
18
|
+
*/
|
|
19
|
+
close: (fh: CompositFsFileHandle) => void;
|
|
20
|
+
dataSync: (fh: CompositFsFileHandle) => Promise<void>;
|
|
21
|
+
read: (fh: CompositFsFileHandle, buffer: Buffer | Uint8Array, offset: number, length: number, position: number) => Promise<TFileHandleReadResult>;
|
|
22
|
+
appendFile: (fh: CompositFsFileHandle, data: TData, options?: IAppendFileOptions | string) => Promise<void>;
|
|
23
|
+
fchmod: (fh: CompositFsFileHandle, mode: TMode) => Promise<void>;
|
|
24
|
+
fchown: (fh: CompositFsFileHandle, uid: number, gid: number) => Promise<void>;
|
|
25
|
+
ftruncate(fh: CompositFsFileHandle, len?: number): Promise<void>;
|
|
26
|
+
fstat(fh: CompositFsFileHandle, options?: IStatOptions): Promise<IStats>;
|
|
27
|
+
futimes(fh: CompositFsFileHandle, atime: TTime, mtime: TTime): Promise<void>;
|
|
28
|
+
write(fh: CompositFsFileHandle, buffer: Buffer | ArrayBufferView | DataView, offset?: number, length?: number, position?: number): Promise<TFileHandleWriteResult>;
|
|
29
|
+
writev(fh: CompositFsFileHandle, buffers: ArrayBufferView[], position?: number | null): Promise<TFileHandleWritevResult>;
|
|
30
|
+
readv(fh: CompositFsFileHandle, buffers: ArrayBufferView[], position?: number | null): Promise<TFileHandleReadvResult>;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
type CompositeSubFs = Pick<typeof nodeFs.promises, 'access' | 'link' | 'readdir' | 'readlink' | 'unlink' | 'rename' | 'rmdir' | 'symlink'> & {
|
|
34
|
+
readFile(path: nodeFs.PathLike | IFileHandle, options?: IReadFileOptions | string): Promise<TDataOut>;
|
|
35
|
+
stat(path: nodeFs.PathLike, opts?: IStatOptions & {
|
|
36
|
+
bigint?: false;
|
|
37
|
+
}): Promise<IStats<number>>;
|
|
38
|
+
stat(path: nodeFs.PathLike, opts: IStatOptions & {
|
|
39
|
+
bigint: true;
|
|
40
|
+
}): Promise<IStats<bigint>>;
|
|
41
|
+
stat(path: nodeFs.PathLike, opts?: IStatOptions): Promise<IStats<number> | IStats<bigint>>;
|
|
42
|
+
lstat(path: nodeFs.PathLike, opts?: IStatOptions & {
|
|
43
|
+
bigint?: false;
|
|
44
|
+
}): Promise<IStats<number>>;
|
|
45
|
+
lstat(path: nodeFs.PathLike, opts: IStatOptions & {
|
|
46
|
+
bigint: true;
|
|
47
|
+
}): Promise<IStats<bigint>>;
|
|
48
|
+
lstat(path: nodeFs.PathLike, opts?: IStatOptions): Promise<IStats<number> | IStats<bigint>>;
|
|
49
|
+
mkdir: (path: nodeFs.PathLike, options?: MakeDirectoryOptions | Mode | null) => Promise<void>;
|
|
50
|
+
fileType: () => number;
|
|
51
|
+
writeFile: (path: string, data: TData, options: IWriteFileOptions | string) => Promise<void>;
|
|
52
|
+
opendir(dirPath: nodeFs.PathLike, options?: nodeFs.OpenDirOptions): Promise<CompositeSubFsDir>;
|
|
53
|
+
lookup: (path: string) => Promise<number>;
|
|
54
|
+
responsible(filePath: string): Promise<boolean>;
|
|
55
|
+
resolvePath: (fd: number) => string;
|
|
56
|
+
} & FileHandleDelegate;
|
|
57
|
+
|
|
58
|
+
interface ICompositFsFileHandle {
|
|
59
|
+
subFsFileDescriptor: number;
|
|
60
|
+
fsType: number;
|
|
61
|
+
fd: number;
|
|
62
|
+
appendFile(data: TData, options?: IAppendFileOptions | string): Promise<void>;
|
|
63
|
+
chmod(mode: TMode): Promise<void>;
|
|
64
|
+
chown(uid: number, gid: number): Promise<void>;
|
|
65
|
+
close(): Promise<void>;
|
|
66
|
+
datasync(): Promise<void>;
|
|
67
|
+
readableWebStream(options?: IReadableWebStreamOptions): ReadableStream;
|
|
68
|
+
read(buffer: Buffer | Uint8Array, offset: number, length: number, position: number): Promise<TFileHandleReadResult>;
|
|
69
|
+
readv(buffers: ArrayBufferView[], position?: number | null): Promise<TFileHandleReadvResult>;
|
|
70
|
+
stat(options?: IStatOptions): Promise<IStats>;
|
|
71
|
+
truncate(len?: number): Promise<void>;
|
|
72
|
+
utimes(atime: TTime, mtime: TTime): Promise<void>;
|
|
73
|
+
write(buffer: Buffer | ArrayBufferView | DataView, offset?: number, length?: number, position?: number): Promise<TFileHandleWriteResult>;
|
|
74
|
+
writev(buffers: ArrayBufferView[], position?: number | null): Promise<TFileHandleWritevResult>;
|
|
75
|
+
sync(): Promise<void>;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* While a filehandle in node env usually is an independent (from its fs) entity to keep fs operatons colocated per type (vritual, managed... files) we
|
|
79
|
+
* wrap the filehandle in a SubFsFileHandle and forward all operations to there origin filesystem
|
|
80
|
+
*/
|
|
81
|
+
declare class CompositFsFileHandle implements ICompositFsFileHandle {
|
|
82
|
+
private delegate;
|
|
83
|
+
get fsType(): number;
|
|
84
|
+
private _subFsFileDescriptor;
|
|
85
|
+
get subFsFileDescriptor(): number;
|
|
86
|
+
handleType: string;
|
|
87
|
+
private _compositFsFileDescriptor;
|
|
88
|
+
get fd(): number;
|
|
89
|
+
realize(compositeFd: number): void;
|
|
90
|
+
constructor(args: {
|
|
91
|
+
fs: FileHandleDelegate;
|
|
92
|
+
subFsFileDescriptor: number;
|
|
93
|
+
parentFsFileDescriptors: number[];
|
|
94
|
+
});
|
|
95
|
+
readableWebStream(options?: IReadableWebStreamOptions): ReadableStream;
|
|
96
|
+
appendFile(data: TData, options?: IAppendFileOptions | string): Promise<void>;
|
|
97
|
+
chmod(mode: TMode): Promise<void>;
|
|
98
|
+
chown(uid: number, gid: number): Promise<void>;
|
|
99
|
+
close(): Promise<void>;
|
|
100
|
+
datasync(): Promise<void>;
|
|
101
|
+
read(buffer: Buffer | Uint8Array, offset: number, length: number, position: number): Promise<TFileHandleReadResult>;
|
|
102
|
+
readv(buffers: ArrayBufferView[], position?: number | null): Promise<TFileHandleReadvResult>;
|
|
103
|
+
stat(options?: IStatOptions): Promise<IStats>;
|
|
104
|
+
truncate(len?: number): Promise<void>;
|
|
105
|
+
utimes(atime: TTime, mtime: TTime): Promise<void>;
|
|
106
|
+
write(buffer: Buffer | ArrayBufferView | DataView, offset?: number, length?: number, position?: number): Promise<TFileHandleWriteResult>;
|
|
107
|
+
writev(buffers: ArrayBufferView[], position?: number | null): Promise<TFileHandleWritevResult>;
|
|
108
|
+
sync(): Promise<void>;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
declare class CompositeFsDir {
|
|
112
|
+
private entries;
|
|
113
|
+
private currentIndex;
|
|
114
|
+
private closed;
|
|
115
|
+
private compositFs;
|
|
116
|
+
private dirPath;
|
|
117
|
+
private initialized;
|
|
118
|
+
constructor(compositFs: CompositeFs, dirPath: string);
|
|
119
|
+
private initialize;
|
|
120
|
+
[Symbol.asyncIterator](): AsyncIterableIterator<IDirent>;
|
|
121
|
+
read(): Promise<nodeFs.Dirent | null>;
|
|
122
|
+
close(): Promise<void>;
|
|
123
|
+
get path(): string;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
*
|
|
128
|
+
* The CompositFs handles distribution of file operations to its sub filesystems and keeps track of open file handles.
|
|
129
|
+
* open returns a CompositFsFileHandle that wraps the real filehandle from the responsible SubFs and allows
|
|
130
|
+
* to forward operations
|
|
131
|
+
*
|
|
132
|
+
* Each SubFs determines if it is responsible for a given path. The Composite fs probes each subsystem for responsibility.
|
|
133
|
+
*
|
|
134
|
+
* The responisbility is probed in the following order:
|
|
135
|
+
*
|
|
136
|
+
* hiddenFilesFileSystem -> ephemeralFilesFileSystem -> other subFs in order of addition -> passThroughFileSystem
|
|
137
|
+
*
|
|
138
|
+
* Composit fs consists of two special sub filesystems:
|
|
139
|
+
*
|
|
140
|
+
* HiddenFilesSubFs - a filesystem that makes files inaccessible from the user
|
|
141
|
+
* -> this is useful if you want to protect files like .git from being accessed or modified by the user
|
|
142
|
+
*
|
|
143
|
+
* EphemeralFilesSubFs - a filesystem that provides files that only exist in memory and are not persisted
|
|
144
|
+
* -> this is usefull when you mount the compositfs as a Network drive for example via NFS to provide a space OS specific User files like .DS_
|
|
145
|
+
*
|
|
146
|
+
* Beyond those special subsystems additional systems cann be plugged in - the order matters
|
|
147
|
+
* and "the other" sub systems added via addSubFs
|
|
148
|
+
*
|
|
149
|
+
|
|
150
|
+
*
|
|
151
|
+
* Renames over subfs bounderies are are managed by this fs
|
|
152
|
+
*
|
|
153
|
+
* writeFile and readFile open a short living filehandle to execute the operations
|
|
154
|
+
*
|
|
155
|
+
*
|
|
156
|
+
*/
|
|
157
|
+
declare class CompositeFs {
|
|
158
|
+
promises: {
|
|
159
|
+
access: (filePath: string, mode?: number) => Promise<void>;
|
|
160
|
+
opendir: (dirPath: nodeFs.PathLike, options?: nodeFs.OpenDirOptions) => Promise<CompositeFsDir>;
|
|
161
|
+
mkdir: (dirPath: string, options?: any) => Promise<void>;
|
|
162
|
+
readdir: (dirPath: nodeFs.PathLike, options?: any) => Promise<string[]>;
|
|
163
|
+
open: (filePath: string, flags: string, mode?: number) => Promise<CompositFsFileHandle>;
|
|
164
|
+
stat: (path: nodeFs.PathLike, opts?: {
|
|
165
|
+
bigint?: boolean;
|
|
166
|
+
}) => Promise<nodeFs.Stats | nodeFs.BigIntStats>;
|
|
167
|
+
lstat: (path: nodeFs.PathLike, opts?: {
|
|
168
|
+
bigint?: boolean;
|
|
169
|
+
}) => Promise<nodeFs.Stats | nodeFs.BigIntStats>;
|
|
170
|
+
link: (existingPath: nodeFs.PathLike, newPath: nodeFs.PathLike) => Promise<void>;
|
|
171
|
+
readlink: (path: nodeFs.PathLike, options?: nodeFs.ObjectEncodingOptions | BufferEncoding | null) => Promise<any>;
|
|
172
|
+
unlink: (filePath: nodeFs.PathLike) => Promise<void>;
|
|
173
|
+
rename: (oldPath: nodeFs.PathLike, newPath: nodeFs.PathLike) => Promise<void>;
|
|
174
|
+
rmdir: (dirPath: nodeFs.PathLike, options?: nodeFs.RmDirOptions) => Promise<void>;
|
|
175
|
+
symlink: (target: nodeFs.PathLike, path: nodeFs.PathLike, type?: string | null) => Promise<void>;
|
|
176
|
+
readFile: (typeof nodeFs.promises)['readFile'];
|
|
177
|
+
writeFile: (file: nodeFs.PathOrFileDescriptor, data: string | Buffer | Uint8Array, options?: any) => Promise<void>;
|
|
178
|
+
getFilehandle: (fd: number) => CompositFsFileHandle | undefined;
|
|
179
|
+
};
|
|
180
|
+
gitRoot: string;
|
|
181
|
+
ephemeralFilesFileSystem: CompositeSubFs | undefined;
|
|
182
|
+
hiddenFilesFileSystem: CompositeSubFs | undefined;
|
|
183
|
+
passThroughFileSystem: CompositeSubFs;
|
|
184
|
+
subFilesystems: CompositeSubFs[];
|
|
185
|
+
parentFs: CompositeFs | undefined;
|
|
186
|
+
name: string;
|
|
187
|
+
pathToFileDescriptors: Map<
|
|
188
|
+
/** path */
|
|
189
|
+
string, number[]>;
|
|
190
|
+
openFileHandles: Map<number, CompositFsFileHandle>;
|
|
191
|
+
private getNextFileDescriptor;
|
|
192
|
+
constructor({ name, parentFs, storageFs, gitRoot, }: {
|
|
193
|
+
name: string;
|
|
194
|
+
parentFs: CompositeFs | undefined;
|
|
195
|
+
storageFs: typeof nodeFs | undefined;
|
|
196
|
+
gitRoot: string;
|
|
197
|
+
});
|
|
198
|
+
getFilehandle(fd: number): CompositFsFileHandle | undefined;
|
|
199
|
+
setEphemeralFilesSubFs(subFs: CompositeSubFs): void;
|
|
200
|
+
setHiddenFilesSubFs(subFs: CompositeSubFs): void;
|
|
201
|
+
addSubFs(subFs: CompositeSubFs): void;
|
|
202
|
+
/**
|
|
203
|
+
* helper function that takes a filePath and returns the fs that is responsible Sub filesystem for it
|
|
204
|
+
* @param filePath
|
|
205
|
+
* @returns
|
|
206
|
+
*/
|
|
207
|
+
private getResponsibleFs;
|
|
208
|
+
access(filePath: string, mode?: number): Promise<void>;
|
|
209
|
+
opendir(dirPath: nodeFs.PathLike, options?: nodeFs.OpenDirOptions): Promise<CompositeFsDir>;
|
|
210
|
+
mkdir(dirPath: string, options?: any): Promise<void>;
|
|
211
|
+
/**
|
|
212
|
+
* Read dir needs to check if one subfs takes control.
|
|
213
|
+
*
|
|
214
|
+
* TODO also implement the option to return stats
|
|
215
|
+
*
|
|
216
|
+
* @param dirPath
|
|
217
|
+
* @param options
|
|
218
|
+
* @returns
|
|
219
|
+
*/
|
|
220
|
+
readdir(dirPath: nodeFs.PathLike, options?: any): Promise<string[]>;
|
|
221
|
+
open(filePath: string, flags: string, mode?: number): Promise<CompositFsFileHandle>;
|
|
222
|
+
close(fh: CompositFsFileHandle): Promise<void>;
|
|
223
|
+
stat(path: nodeFs.PathLike, opts?: {
|
|
224
|
+
bigint?: false;
|
|
225
|
+
}): Promise<nodeFs.Stats>;
|
|
226
|
+
stat(path: nodeFs.PathLike, opts: {
|
|
227
|
+
bigint: true;
|
|
228
|
+
}): Promise<nodeFs.BigIntStats>;
|
|
229
|
+
stat(path: nodeFs.PathLike, opts?: {
|
|
230
|
+
bigint?: boolean;
|
|
231
|
+
}): Promise<nodeFs.Stats | nodeFs.BigIntStats>;
|
|
232
|
+
lstat(path: nodeFs.PathLike, opts?: {
|
|
233
|
+
bigint?: false;
|
|
234
|
+
}): Promise<nodeFs.Stats>;
|
|
235
|
+
lstat(path: nodeFs.PathLike, opts: {
|
|
236
|
+
bigint: true;
|
|
237
|
+
}): Promise<nodeFs.BigIntStats>;
|
|
238
|
+
lstat(path: nodeFs.PathLike, opts?: {
|
|
239
|
+
bigint?: boolean;
|
|
240
|
+
}): Promise<nodeFs.Stats | nodeFs.BigIntStats>;
|
|
241
|
+
link(existingPath: nodeFs.PathLike, newPath: nodeFs.PathLike): Promise<void>;
|
|
242
|
+
readlink(path: nodeFs.PathLike, options?: nodeFs.ObjectEncodingOptions | BufferEncoding | null): Promise<void>;
|
|
243
|
+
unlink(filePath: nodeFs.PathLike): Promise<void>;
|
|
244
|
+
rename(oldPath: nodeFs.PathLike, newPath: nodeFs.PathLike): Promise<void>;
|
|
245
|
+
rmdir(dirPath: nodeFs.PathLike, options?: nodeFs.RmDirOptions): Promise<void>;
|
|
246
|
+
symlink(target: nodeFs.PathLike, path: nodeFs.PathLike, type?: string | null): Promise<void>;
|
|
247
|
+
readFile(path: nodeFs.PathOrFileDescriptor, options?: {
|
|
248
|
+
encoding?: null;
|
|
249
|
+
flag?: string;
|
|
250
|
+
} | null): Promise<Buffer>;
|
|
251
|
+
readFile(path: nodeFs.PathOrFileDescriptor, options: {
|
|
252
|
+
encoding: BufferEncoding;
|
|
253
|
+
flag?: string;
|
|
254
|
+
} | BufferEncoding): Promise<string>;
|
|
255
|
+
writeFile(file: nodeFs.PathOrFileDescriptor, data: string | Buffer | Uint8Array, options?: {
|
|
256
|
+
encoding?: BufferEncoding;
|
|
257
|
+
mode?: number;
|
|
258
|
+
flag?: string;
|
|
259
|
+
} | BufferEncoding | null): Promise<void>;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
declare abstract class BaseCompositeSubFs implements CompositeSubFs {
|
|
263
|
+
protected toStr(p: any): string;
|
|
264
|
+
protected compositFs: CompositeFs;
|
|
265
|
+
protected gitRoot: string;
|
|
266
|
+
constructor({ parentFs, gitRoot, }: {
|
|
267
|
+
parentFs: CompositeFs;
|
|
268
|
+
gitRoot: string;
|
|
269
|
+
});
|
|
270
|
+
abstract responsible(filePath: string): Promise<boolean>;
|
|
271
|
+
abstract fileType(): number;
|
|
272
|
+
open(path: PathLike, flags: string, mode?: number): Promise<CompositFsFileHandle>;
|
|
273
|
+
access(path: PathLike, mode?: number): Promise<void>;
|
|
274
|
+
stat(path: PathLike, opts?: {
|
|
275
|
+
bigint?: false;
|
|
276
|
+
}): Promise<nodeFs.Stats>;
|
|
277
|
+
stat(path: PathLike, opts: {
|
|
278
|
+
bigint: true;
|
|
279
|
+
}): Promise<nodeFs.BigIntStats>;
|
|
280
|
+
stat(path: PathLike, opts?: {
|
|
281
|
+
bigint?: boolean;
|
|
282
|
+
}): Promise<nodeFs.Stats | nodeFs.BigIntStats>;
|
|
283
|
+
lstat(path: PathLike, opts?: {
|
|
284
|
+
bigint?: false;
|
|
285
|
+
}): Promise<nodeFs.Stats>;
|
|
286
|
+
lstat(path: PathLike, opts: {
|
|
287
|
+
bigint: true;
|
|
288
|
+
}): Promise<nodeFs.BigIntStats>;
|
|
289
|
+
lstat(path: PathLike, opts?: {
|
|
290
|
+
bigint?: boolean;
|
|
291
|
+
}): Promise<nodeFs.Stats | nodeFs.BigIntStats>;
|
|
292
|
+
opendir(path: PathLike, options?: nodeFs.OpenDirOptions): Promise<CompositeSubFsDir>;
|
|
293
|
+
link(existingPath: PathLike, newPath: PathLike): Promise<void>;
|
|
294
|
+
mkdir(path: PathLike, options?: nodeFs.MakeDirectoryOptions | nodeFs.Mode | null): Promise<void>;
|
|
295
|
+
readdir(path: PathLike, options?: (nodeFs.ObjectEncodingOptions & {
|
|
296
|
+
withFileTypes?: false | undefined;
|
|
297
|
+
recursive?: boolean | undefined;
|
|
298
|
+
}) | BufferEncoding | null): Promise<string[]>;
|
|
299
|
+
readdir(path: PathLike, options?: {
|
|
300
|
+
encoding: 'buffer';
|
|
301
|
+
withFileTypes?: false | undefined;
|
|
302
|
+
recursive?: boolean | undefined;
|
|
303
|
+
} | 'buffer' | null): Promise<Buffer[]>;
|
|
304
|
+
readdir(path: PathLike, options?: (nodeFs.ObjectEncodingOptions & {
|
|
305
|
+
withFileTypes?: false | undefined;
|
|
306
|
+
recursive?: boolean | undefined;
|
|
307
|
+
}) | BufferEncoding | null): Promise<string[] | Buffer[]>;
|
|
308
|
+
readdir(path: PathLike, options: nodeFs.ObjectEncodingOptions & {
|
|
309
|
+
withFileTypes: true;
|
|
310
|
+
recursive?: boolean | undefined;
|
|
311
|
+
}): Promise<nodeFs.Dirent[]>;
|
|
312
|
+
readlink(path: PathLike, ...args: any[]): Promise<any>;
|
|
313
|
+
unlink(path: PathLike): Promise<void>;
|
|
314
|
+
rename(oldPath: PathLike, newPath: PathLike): Promise<void>;
|
|
315
|
+
rmdir(path: PathLike, ...args: any[]): Promise<void>;
|
|
316
|
+
symlink(target: PathLike, path: PathLike, type?: string | null): Promise<void>;
|
|
317
|
+
lookup(filePath: string): Promise<number>;
|
|
318
|
+
resolvePath(fd: number): string;
|
|
319
|
+
close(fh: CompositFsFileHandle): Promise<void>;
|
|
320
|
+
dataSync(fh: CompositFsFileHandle): Promise<void>;
|
|
321
|
+
read(fh: CompositFsFileHandle, buffer: Buffer | Uint8Array, offset: number, length: number, position: number): Promise<TFileHandleReadResult>;
|
|
322
|
+
appendFile(fh: CompositFsFileHandle, data: TData, options?: IAppendFileOptions | string): Promise<void>;
|
|
323
|
+
fchmod(fh: CompositFsFileHandle, mode: TMode): Promise<void>;
|
|
324
|
+
fchown(fh: CompositFsFileHandle, uid: number, gid: number): Promise<void>;
|
|
325
|
+
ftruncate(fh: CompositFsFileHandle, len?: number): Promise<void>;
|
|
326
|
+
fstat(fh: CompositFsFileHandle, options?: IStatOptions): Promise<IStats>;
|
|
327
|
+
futimes(fh: CompositFsFileHandle, atime: TTime, mtime: TTime): Promise<void>;
|
|
328
|
+
write(fh: CompositFsFileHandle, buffer: Buffer | ArrayBufferView | DataView, offset?: number, length?: number, position?: number): Promise<TFileHandleWriteResult>;
|
|
329
|
+
writev(fh: CompositFsFileHandle, buffers: ArrayBufferView[], position?: number | null): Promise<TFileHandleWritevResult>;
|
|
330
|
+
readv(fh: CompositFsFileHandle, buffers: ArrayBufferView[], position?: number | null): Promise<TFileHandleReadvResult>;
|
|
331
|
+
readFile(path: PathLike | IFileHandle, options?: IReadFileOptions | string): Promise<TDataOut>;
|
|
332
|
+
writeFile(path: string, data: TData, options: IWriteFileOptions | string): Promise<void>;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* FS utilized to hide files, it is responsible for files found in hiddenFiles
|
|
337
|
+
*
|
|
338
|
+
* For those files it fails on open, close etc.
|
|
339
|
+
*/
|
|
340
|
+
declare class HiddenFileSubFs extends BaseCompositeSubFs {
|
|
341
|
+
private ig;
|
|
342
|
+
constructor({ parentFs, gitRoot, hiddenFiles, }: {
|
|
343
|
+
parentFs: CompositeFs;
|
|
344
|
+
gitRoot: string;
|
|
345
|
+
hiddenFiles: string[];
|
|
346
|
+
});
|
|
347
|
+
responsible(filePath: string): Promise<boolean>;
|
|
348
|
+
fileType(): number;
|
|
349
|
+
private error;
|
|
350
|
+
open(path: PathLike$1, flags: string, mode?: number): Promise<CompositFsFileHandle>;
|
|
351
|
+
access(path: PathLike$1): Promise<void>;
|
|
352
|
+
stat(path: PathLike$1): Promise<any>;
|
|
353
|
+
lstat(path: PathLike$1): Promise<any>;
|
|
354
|
+
opendir(path: PathLike$1): Promise<any>;
|
|
355
|
+
link(existingPath: PathLike$1): Promise<void>;
|
|
356
|
+
mkdir(path: PathLike$1): Promise<any>;
|
|
357
|
+
readdir(path: PathLike$1): Promise<any>;
|
|
358
|
+
readlink(path: PathLike$1): Promise<any>;
|
|
359
|
+
unlink(path: PathLike$1): Promise<void>;
|
|
360
|
+
rename(oldPath: PathLike$1): Promise<void>;
|
|
361
|
+
rmdir(path: PathLike$1): Promise<void>;
|
|
362
|
+
symlink(_target: PathLike$1, path: PathLike$1): Promise<void>;
|
|
363
|
+
lookup(filePath: string): Promise<number>;
|
|
364
|
+
resolvePath(fd: number): string;
|
|
365
|
+
close(fh: CompositFsFileHandle): Promise<void>;
|
|
366
|
+
dataSync(fh: CompositFsFileHandle): Promise<void>;
|
|
367
|
+
read(fh: CompositFsFileHandle, buffer: Buffer | Uint8Array, offset: number, length: number, position: number): Promise<any>;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* FS utilized to provide ephemeral storage using in-memory filesystem
|
|
372
|
+
* Files matching ephemeralPatterns are stored in memory and lost on restart
|
|
373
|
+
*/
|
|
374
|
+
declare class EphemeralSubFs extends BaseCompositeSubFs {
|
|
375
|
+
private openFh;
|
|
376
|
+
private memFs;
|
|
377
|
+
private ig;
|
|
378
|
+
patterns: string[];
|
|
379
|
+
private normalizePath;
|
|
380
|
+
constructor({ parentFs, gitRoot, ephemeralPatterns, }: {
|
|
381
|
+
parentFs: CompositeFs;
|
|
382
|
+
gitRoot: string;
|
|
383
|
+
ephemeralPatterns: string[];
|
|
384
|
+
});
|
|
385
|
+
responsible(filePath: string): Promise<boolean>;
|
|
386
|
+
fileType(): number;
|
|
387
|
+
open(filePath: string, flags: string, mode?: number): Promise<CompositFsFileHandle>;
|
|
388
|
+
access(filePath: PathLike$1, mode?: number): Promise<void>;
|
|
389
|
+
stat(path: PathLike$1, opts?: {
|
|
390
|
+
bigint?: false;
|
|
391
|
+
}): Promise<nodeFs.Stats>;
|
|
392
|
+
stat(path: PathLike$1, opts: {
|
|
393
|
+
bigint: true;
|
|
394
|
+
}): Promise<nodeFs.BigIntStats>;
|
|
395
|
+
stat(path: PathLike$1, opts?: {
|
|
396
|
+
bigint?: boolean;
|
|
397
|
+
}): Promise<nodeFs.Stats | nodeFs.BigIntStats>;
|
|
398
|
+
lstat(path: PathLike$1, opts?: {
|
|
399
|
+
bigint?: false;
|
|
400
|
+
}): Promise<nodeFs.Stats>;
|
|
401
|
+
lstat(path: PathLike$1, opts: {
|
|
402
|
+
bigint: true;
|
|
403
|
+
}): Promise<nodeFs.BigIntStats>;
|
|
404
|
+
lstat(path: PathLike$1, opts?: {
|
|
405
|
+
bigint?: boolean;
|
|
406
|
+
}): Promise<nodeFs.Stats | nodeFs.BigIntStats>;
|
|
407
|
+
opendir(folderPath: nodeFs.PathLike, options?: nodeFs.OpenDirOptions): Promise<memfs_lib_node_types_misc_js.IDir>;
|
|
408
|
+
link(existingPath: PathLike$1, newPath: PathLike$1): Promise<void>;
|
|
409
|
+
mkdir(dirPath: PathLike$1, options?: nodeFs.MakeDirectoryOptions | nodeFs.Mode | null): Promise<void>;
|
|
410
|
+
readdir(path: PathLike$1, ...args: any[]): Promise<any>;
|
|
411
|
+
readlink(path: PathLike$1): Promise<any>;
|
|
412
|
+
unlink(path: PathLike$1): Promise<void>;
|
|
413
|
+
rename(oldPath: PathLike$1, newPath: PathLike$1): Promise<void>;
|
|
414
|
+
rmdir(path: PathLike$1, options?: nodeFs.RmDirOptions): Promise<void>;
|
|
415
|
+
symlink(target: PathLike$1, path: PathLike$1, type?: string | null): Promise<void>;
|
|
416
|
+
lookup(filePath: string): Promise<number>;
|
|
417
|
+
close(fh: CompositFsFileHandle): Promise<void>;
|
|
418
|
+
dataSync(fh: CompositFsFileHandle): Promise<void>;
|
|
419
|
+
read(fh: CompositFsFileHandle, buffer: Buffer | Uint8Array, offset: number, length: number, position: number): Promise<TFileHandleReadResult>;
|
|
420
|
+
fchmod(fh: CompositFsFileHandle, mode: TMode): Promise<void>;
|
|
421
|
+
fchown(fh: CompositFsFileHandle, uid: number, gid: number): Promise<void>;
|
|
422
|
+
write(fh: CompositFsFileHandle, buffer: Buffer | ArrayBufferView | DataView, offset?: number, length?: number, position?: number): Promise<TFileHandleWriteResult>;
|
|
423
|
+
ftruncate(fh: CompositFsFileHandle, len?: number): Promise<void>;
|
|
424
|
+
resolvePath(fd: number): string;
|
|
425
|
+
fstat(fh: CompositFsFileHandle, options?: IStatOptions): Promise<IStats>;
|
|
426
|
+
futimes(fh: CompositFsFileHandle, atime: TTime, mtime: TTime): Promise<void>;
|
|
427
|
+
writev(fh: CompositFsFileHandle, buffers: ArrayBufferView[], position?: number | null): Promise<TFileHandleWritevResult>;
|
|
428
|
+
readv(fh: CompositFsFileHandle, buffers: ArrayBufferView[], position?: number | null): Promise<TFileHandleReadvResult>;
|
|
429
|
+
readFile(path: PathLike$1 | IFileHandle, options?: IReadFileOptions | string): Promise<TDataOut>;
|
|
430
|
+
writeFile(filePath: string, data: TData, options: IWriteFileOptions | string): Promise<void>;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* FS utilized to provide pass-through access to the underlying filesystem
|
|
435
|
+
*/
|
|
436
|
+
declare class PassThroughSubFs extends BaseCompositeSubFs {
|
|
437
|
+
private openFh;
|
|
438
|
+
private memFs;
|
|
439
|
+
private targetFs;
|
|
440
|
+
constructor({ parentFs, gitRoot, }: {
|
|
441
|
+
parentFs: CompositeFs;
|
|
442
|
+
gitRoot: string;
|
|
443
|
+
});
|
|
444
|
+
responsible(filePath: string): Promise<boolean>;
|
|
445
|
+
fileType(): number;
|
|
446
|
+
open(filePath: string, flags: string, mode?: number): Promise<CompositFsFileHandle>;
|
|
447
|
+
access(filePath: PathLike$1, mode?: number): Promise<void>;
|
|
448
|
+
stat(path: PathLike$1, opts?: {
|
|
449
|
+
bigint?: false;
|
|
450
|
+
}): Promise<nodeFs.Stats>;
|
|
451
|
+
stat(path: PathLike$1, opts: {
|
|
452
|
+
bigint: true;
|
|
453
|
+
}): Promise<nodeFs.BigIntStats>;
|
|
454
|
+
stat(path: PathLike$1, opts?: {
|
|
455
|
+
bigint?: boolean;
|
|
456
|
+
}): Promise<nodeFs.Stats | nodeFs.BigIntStats>;
|
|
457
|
+
lstat(path: PathLike$1, opts?: {
|
|
458
|
+
bigint?: false;
|
|
459
|
+
}): Promise<nodeFs.Stats>;
|
|
460
|
+
lstat(path: PathLike$1, opts: {
|
|
461
|
+
bigint: true;
|
|
462
|
+
}): Promise<nodeFs.BigIntStats>;
|
|
463
|
+
lstat(path: PathLike$1, opts?: {
|
|
464
|
+
bigint?: boolean;
|
|
465
|
+
}): Promise<nodeFs.Stats | nodeFs.BigIntStats>;
|
|
466
|
+
opendir(folderPath: nodeFs.PathLike, options?: nodeFs.OpenDirOptions): Promise<CompositeFsDir>;
|
|
467
|
+
link(existingPath: PathLike$1, newPath: PathLike$1): Promise<void>;
|
|
468
|
+
mkdir(dirPath: PathLike$1, options?: nodeFs.MakeDirectoryOptions | nodeFs.Mode | null): Promise<void>;
|
|
469
|
+
readdir(path: PathLike$1, ...args: any[]): Promise<any>;
|
|
470
|
+
readlink(path: PathLike$1, ...args: any[]): Promise<any>;
|
|
471
|
+
unlink(path: PathLike$1): Promise<void>;
|
|
472
|
+
rename(oldPath: PathLike$1, newPath: PathLike$1): Promise<void>;
|
|
473
|
+
rmdir(path: PathLike$1, options?: nodeFs.RmDirOptions): Promise<void>;
|
|
474
|
+
symlink(target: PathLike$1, path: PathLike$1, type?: string | null): Promise<void>;
|
|
475
|
+
lookup(filePath: string): Promise<number>;
|
|
476
|
+
close(fh: CompositFsFileHandle): Promise<void>;
|
|
477
|
+
dataSync(fh: CompositFsFileHandle): Promise<void>;
|
|
478
|
+
read(fh: CompositFsFileHandle, buffer: Buffer | Uint8Array, offset: number, length: number, position: number): Promise<TFileHandleReadResult>;
|
|
479
|
+
fchmod(fh: CompositFsFileHandle, mode: TMode): Promise<void>;
|
|
480
|
+
fchown(fh: CompositFsFileHandle, uid: number, gid: number): Promise<void>;
|
|
481
|
+
write(fh: CompositFsFileHandle, buffer: Buffer | ArrayBufferView | DataView, offset?: number, length?: number, position?: number): Promise<TFileHandleWriteResult>;
|
|
482
|
+
ftruncate(fh: CompositFsFileHandle, len?: number): Promise<void>;
|
|
483
|
+
resolvePath(fd: number): string;
|
|
484
|
+
fstat(fh: CompositFsFileHandle, options?: IStatOptions): Promise<IStats>;
|
|
485
|
+
futimes(fh: CompositFsFileHandle, atime: TTime, mtime: TTime): Promise<void>;
|
|
486
|
+
writev(fh: CompositFsFileHandle, buffers: ArrayBufferView[], position?: number | null): Promise<TFileHandleWritevResult>;
|
|
487
|
+
readv(fh: CompositFsFileHandle, buffers: ArrayBufferView[], position?: number | null): Promise<TFileHandleReadvResult>;
|
|
488
|
+
readFile(path: PathLike$1 | IFileHandle, options?: IReadFileOptions | string): Promise<TDataOut>;
|
|
489
|
+
writeFile(path: string, data: TData, options: IWriteFileOptions | string): Promise<void>;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
type VirtualFile = {
|
|
493
|
+
type: 'file';
|
|
494
|
+
content?: string | Buffer;
|
|
495
|
+
oid?: string | undefined;
|
|
496
|
+
mode?: number;
|
|
497
|
+
size?: number;
|
|
498
|
+
} | {
|
|
499
|
+
type: 'directory';
|
|
500
|
+
content: string[];
|
|
501
|
+
oid?: string | undefined;
|
|
502
|
+
mode?: number;
|
|
503
|
+
};
|
|
504
|
+
interface VirtualFileArgs {
|
|
505
|
+
cacheFs: IFs;
|
|
506
|
+
filePath: string;
|
|
507
|
+
fs: CompositeFs;
|
|
508
|
+
gitRoot: string;
|
|
509
|
+
nodeFs?: any;
|
|
510
|
+
pathParams: any;
|
|
511
|
+
}
|
|
512
|
+
type VirtualFileDefinition = {
|
|
513
|
+
type: string;
|
|
514
|
+
getFile: (args: VirtualFileArgs) => Promise<VirtualFile | undefined>;
|
|
515
|
+
getStats: (args: VirtualFileArgs) => Promise<nodeFs.Stats>;
|
|
516
|
+
onFileChanged?: (args: VirtualFileArgs) => Promise<void>;
|
|
517
|
+
writeFile?: (args: VirtualFileArgs & {
|
|
518
|
+
content: Buffer | string;
|
|
519
|
+
}) => Promise<void>;
|
|
520
|
+
unlink?: (args: VirtualFileArgs) => Promise<void>;
|
|
521
|
+
rename: (args: VirtualFileArgs & {
|
|
522
|
+
newPath: string;
|
|
523
|
+
newPathParams: any;
|
|
524
|
+
}) => Promise<void>;
|
|
525
|
+
mkdir: (args: VirtualFileArgs & {
|
|
526
|
+
options?: nodeFs.MakeDirectoryOptions | nodeFs.Mode | null;
|
|
527
|
+
}) => Promise<void>;
|
|
528
|
+
};
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* 1. Path Structure Complexity
|
|
532
|
+
- Your nested .legit paths (e.g., /.legit/branch/my-branch-name/.legit/head) create redundancy
|
|
533
|
+
- Consider flattening: /.legit/branches/my-branch-name/head vs /.legit/branch/my-branch-name/.legit/head
|
|
534
|
+
|
|
535
|
+
Reason for the concept: i need to distinguish .legit files from other folders, therefore i wanted to introduce .letgit as a reserved folder independent from the depth or if repeated
|
|
536
|
+
Any problems you see with this?
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
2. Write Operations on Historical Data
|
|
540
|
+
- Writing to /.legit/history/commits/... paths is conceptually problematic - commits are immutable
|
|
541
|
+
- Consider read-only for historical data, write-only for branch operations
|
|
542
|
+
|
|
543
|
+
100% with you commits should be read only folders
|
|
544
|
+
|
|
545
|
+
3. Branch Head Management
|
|
546
|
+
- Using git tags for head tracking (my-branch-name_legithead) pollutes the tag namespace
|
|
547
|
+
- Alternative: Use a dedicated ref namespace like refs/legit/heads/my-branch-name
|
|
548
|
+
|
|
549
|
+
Reason for the concept: i see the point with pollution of tag namespace BUT this will help existing tools to display the concept - i would start with tags and move refs to a later point in time
|
|
550
|
+
- what speaks against this?
|
|
551
|
+
|
|
552
|
+
4. Conflict with Existing Virtual Files
|
|
553
|
+
- Current implementation has .status.gitbox, .branch.gitbox files
|
|
554
|
+
- Need strategy to migrate or maintain compatibility
|
|
555
|
+
|
|
556
|
+
Context: the hole thing is a non published poc so no need to migrate - just an implementation change needed
|
|
557
|
+
|
|
558
|
+
Architectural Challenges
|
|
559
|
+
|
|
560
|
+
1. Performance
|
|
561
|
+
- Git operations (especially history traversal) can be expensive
|
|
562
|
+
- Current memfs caching might not scale for large repos
|
|
563
|
+
- Consider lazy loading and bounded caches
|
|
564
|
+
|
|
565
|
+
Future problem - lets not premature optimation or clear doubts?
|
|
566
|
+
|
|
567
|
+
2. Consistency
|
|
568
|
+
- Multiple write paths (working copy, branches) need careful coordination
|
|
569
|
+
- Race conditions between git operations and filesystem operations
|
|
570
|
+
|
|
571
|
+
Lets postpone this for now
|
|
572
|
+
|
|
573
|
+
3. Error Handling
|
|
574
|
+
- Git operations can fail (conflicts, invalid commits)
|
|
575
|
+
- Need clear error propagation through the FS layer
|
|
576
|
+
|
|
577
|
+
Lets discuss this deeper - dont understand the problem here.
|
|
578
|
+
|
|
579
|
+
Implementation Approach
|
|
580
|
+
|
|
581
|
+
Phase 1: Read-Only Git Views
|
|
582
|
+
// Start with immutable views
|
|
583
|
+
/.legit/status // Current git status
|
|
584
|
+
/.legit/commits/{sha}/path/to/file // Historical file access
|
|
585
|
+
/.legit/branches/ // List branches
|
|
586
|
+
/.legit/refs/heads/{branch}/path // Branch file access
|
|
587
|
+
|
|
588
|
+
Phase 2: Branch Operations
|
|
589
|
+
// Add write capabilities
|
|
590
|
+
/.legit/refs/heads/{branch}/.meta/head // Track branch head
|
|
591
|
+
/.legit/refs/heads/{branch}/path // Write to branch
|
|
592
|
+
|
|
593
|
+
Phase 3: Advanced Features
|
|
594
|
+
// Commit creation, branch management
|
|
595
|
+
/.legit/stage/ // Staging area
|
|
596
|
+
/.legit/commit // Trigger commit
|
|
597
|
+
|
|
598
|
+
Plan sounds good!
|
|
599
|
+
|
|
600
|
+
|
|
601
|
+
Next Steps
|
|
602
|
+
|
|
603
|
+
1. Refine the path structure - Simplify and avoid nested .legit directories
|
|
604
|
+
- no please take my points into consideratio
|
|
605
|
+
|
|
606
|
+
2. Create a proof-of-concept - Start with read-only status and commit access
|
|
607
|
+
- sounds good
|
|
608
|
+
|
|
609
|
+
3. Build test infrastructure - Set up git fixture creation and FS testing utilities
|
|
610
|
+
- absolutly
|
|
611
|
+
|
|
612
|
+
4. Implement incrementally - Phase approach to reduce complexity
|
|
613
|
+
|
|
614
|
+
alreight
|
|
615
|
+
|
|
616
|
+
The architecture supports your vision, but consider starting simpler and evolving based on real usage patterns.
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
/.legit/status // Git status info
|
|
621
|
+
/.legit/commits/{sha(0,1)}/{sha(2..20)}/path/to/file // Historical files
|
|
622
|
+
/.legit/branches/ // List branches
|
|
623
|
+
/.legit/branches/{name}/path/to/file // Branch files (read/write)
|
|
624
|
+
/.legit/branches/{name}/.legit/head // read/write of the head commit of the branch {name}
|
|
625
|
+
/.legit/branches/{name}/.legit/tip // read/write of the tip of the branch {name} - keeping this allows undo redo ops
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
*/
|
|
629
|
+
declare class GitSubFs extends BaseCompositeSubFs implements CompositeSubFs {
|
|
630
|
+
private static readonly LEGIT_DIR;
|
|
631
|
+
private static pathRouter;
|
|
632
|
+
private memFs;
|
|
633
|
+
private openFh;
|
|
634
|
+
private virtualFiles;
|
|
635
|
+
private legitFileNames;
|
|
636
|
+
constructor({ parentFs, gitRoot, virtualFiles, }: {
|
|
637
|
+
parentFs: CompositeFs;
|
|
638
|
+
gitRoot: string;
|
|
639
|
+
virtualFiles?: VirtualFileDefinition[];
|
|
640
|
+
});
|
|
641
|
+
responsible(filePath: string): Promise<boolean>;
|
|
642
|
+
private isLegitPath;
|
|
643
|
+
private getRouteHandler;
|
|
644
|
+
/**
|
|
645
|
+
* Opens a virtual file from the Git-based virtual file system.
|
|
646
|
+
*
|
|
647
|
+
* This method retrieves a virtual file descriptor for the given `filePath`, checks if the file is writable
|
|
648
|
+
* based on its type and the provided `flags`, and ensures that write operations are only allowed for
|
|
649
|
+
* certain file types (e.g., "branch-file", "branch-head", "branch-tip"). It then loads the file's content
|
|
650
|
+
* into the in-memory file system (`memFs`), ensures parent directories exist, and finally opens the file,
|
|
651
|
+
* returning a `CompositFsFileHandle` for further operations.
|
|
652
|
+
*
|
|
653
|
+
* @param filePath - The path to the virtual file to open.
|
|
654
|
+
* @param flags - The file system flags indicating the desired open mode (e.g., "r" for read, "w" for write, "a" for append, "x" for exclusive creation).
|
|
655
|
+
* - "r": Open file for reading. An exception occurs if the file does not exist.
|
|
656
|
+
* - "w": Open file for writing. The file is created (if it does not exist) or truncated (if it exists).
|
|
657
|
+
* - "a": Open file for appending. The file is created if it does not exist.
|
|
658
|
+
* - "x": Exclusive flag. Used with "w" or "a" to fail if the file exists.
|
|
659
|
+
* - Combinations like "wx", "ax", etc., are also supported.
|
|
660
|
+
* @param mode - Optional file mode (permission and sticky bits) to use if creating a file.
|
|
661
|
+
* @returns A promise that resolves to a `CompositFsFileHandle` for the opened file.
|
|
662
|
+
* @throws If the file is not a virtual legit file, if write operations are not allowed for the file type,
|
|
663
|
+
* or if the file does not exist.
|
|
664
|
+
*/
|
|
665
|
+
open(filePath: string, flags: string, mode?: number): Promise<CompositFsFileHandle>;
|
|
666
|
+
mkdir(path: PathLike, options?: nodeFs.MakeDirectoryOptions | nodeFs.Mode | null): Promise<void>;
|
|
667
|
+
access(path: PathLike, mode?: number): Promise<void>;
|
|
668
|
+
futimes(fh: CompositFsFileHandle, atime: TTime, mtime: TTime): Promise<void>;
|
|
669
|
+
fstat(fh: CompositFsFileHandle, options?: IStatOptions): Promise<IStats>;
|
|
670
|
+
ftruncate(fh: CompositFsFileHandle, len?: number): Promise<void>;
|
|
671
|
+
stat(path: PathLike, opts?: {
|
|
672
|
+
bigint?: false;
|
|
673
|
+
}): Promise<nodeFs.Stats>;
|
|
674
|
+
stat(path: PathLike, opts: {
|
|
675
|
+
bigint: true;
|
|
676
|
+
}): Promise<nodeFs.BigIntStats>;
|
|
677
|
+
stat(path: PathLike, opts?: {
|
|
678
|
+
bigint?: boolean;
|
|
679
|
+
}): Promise<nodeFs.Stats | nodeFs.BigIntStats>;
|
|
680
|
+
lstat(path: PathLike, opts?: {
|
|
681
|
+
bigint?: false;
|
|
682
|
+
}): Promise<nodeFs.Stats>;
|
|
683
|
+
lstat(path: PathLike, opts: {
|
|
684
|
+
bigint: true;
|
|
685
|
+
}): Promise<nodeFs.BigIntStats>;
|
|
686
|
+
lstat(path: PathLike, opts?: {
|
|
687
|
+
bigint?: boolean;
|
|
688
|
+
}): Promise<nodeFs.Stats | nodeFs.BigIntStats>;
|
|
689
|
+
readdir(path: PathLike, options?: (nodeFs.ObjectEncodingOptions & {
|
|
690
|
+
withFileTypes?: false | undefined;
|
|
691
|
+
recursive?: boolean | undefined;
|
|
692
|
+
}) | BufferEncoding | null): Promise<string[]>;
|
|
693
|
+
readdir(path: PathLike, options?: {
|
|
694
|
+
encoding: 'buffer';
|
|
695
|
+
withFileTypes?: false | undefined;
|
|
696
|
+
recursive?: boolean | undefined;
|
|
697
|
+
} | 'buffer' | null): Promise<Buffer[]>;
|
|
698
|
+
readdir(path: PathLike, options?: (nodeFs.ObjectEncodingOptions & {
|
|
699
|
+
withFileTypes?: false | undefined;
|
|
700
|
+
recursive?: boolean | undefined;
|
|
701
|
+
}) | BufferEncoding | null): Promise<string[] | Buffer[]>;
|
|
702
|
+
readdir(path: PathLike, options: nodeFs.ObjectEncodingOptions & {
|
|
703
|
+
withFileTypes: true;
|
|
704
|
+
recursive?: boolean | undefined;
|
|
705
|
+
}): Promise<nodeFs.Dirent[]>;
|
|
706
|
+
read(fh: CompositFsFileHandle, buffer: Buffer | Uint8Array, offset: number, length: number, position: number): Promise<TFileHandleReadResult>;
|
|
707
|
+
/**
|
|
708
|
+
*
|
|
709
|
+
* Writes (parts) of a buffer to a specific position in the file
|
|
710
|
+
*
|
|
711
|
+
* - a write leads to a new commit and on flush since the point in time a flush may occur may vary a read operation may
|
|
712
|
+
* not see changed done on the read lays.
|
|
713
|
+
*
|
|
714
|
+
*
|
|
715
|
+
* @param fh
|
|
716
|
+
* @param buffer
|
|
717
|
+
* @param offset
|
|
718
|
+
* @param length
|
|
719
|
+
* @param position
|
|
720
|
+
* @returns
|
|
721
|
+
*/
|
|
722
|
+
write(fh: CompositFsFileHandle, buffer: Buffer | ArrayBufferView | DataView, offset?: number, length?: number, position?: number): Promise<TFileHandleWriteResult>;
|
|
723
|
+
close(fh: CompositFsFileHandle): Promise<void>;
|
|
724
|
+
dataSync(fh: CompositFsFileHandle): Promise<void>;
|
|
725
|
+
readFile(path: PathLike | IFileHandle, options?: IReadFileOptions | string): Promise<TDataOut>;
|
|
726
|
+
writeFile(path: string, data: TData, options: IWriteFileOptions | string): Promise<void>;
|
|
727
|
+
rename(oldPath: PathLike, newPath: PathLike): Promise<void>;
|
|
728
|
+
fchmod(fh: CompositFsFileHandle, mode: TMode): Promise<void>;
|
|
729
|
+
unlink(path: PathLike): Promise<void>;
|
|
730
|
+
fileType(): number;
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
type Operation = {
|
|
734
|
+
oid: string;
|
|
735
|
+
parentOids: string[];
|
|
736
|
+
message: string;
|
|
737
|
+
};
|
|
738
|
+
declare const gitBranchOperationsVirtualFile: VirtualFileDefinition;
|
|
739
|
+
|
|
740
|
+
declare function initLegitFs(storageFs: typeof nodeFs, gitRoot: string): Promise<CompositeFs>;
|
|
741
|
+
/**
|
|
742
|
+
* Creates and configures a LegitFs instance with CompositeFs, GitSubFs, HiddenFileSubFs, and EphemeralSubFs.
|
|
743
|
+
*/
|
|
744
|
+
declare function openLegitFs(storageFs: typeof nodeFs, gitRoot: string): CompositeFs;
|
|
745
|
+
|
|
746
|
+
declare const createGitSyncService: ({ fs, gitRepoPath, originPrefix, corsProxy, user, password, }: {
|
|
747
|
+
fs: FsClient;
|
|
748
|
+
gitRepoPath: string;
|
|
749
|
+
originPrefix: string;
|
|
750
|
+
corsProxy?: string | undefined;
|
|
751
|
+
user: string;
|
|
752
|
+
password: string;
|
|
753
|
+
}) => {
|
|
754
|
+
clone: (url: string) => Promise<void>;
|
|
755
|
+
start: () => void;
|
|
756
|
+
stop: () => void;
|
|
757
|
+
};
|
|
758
|
+
|
|
759
|
+
type FileAccess = {
|
|
760
|
+
fileSave: typeof fileSave;
|
|
761
|
+
};
|
|
762
|
+
declare function getLegitFsAccess(legitFs: ReturnType<typeof openLegitFs>): Promise<FileAccess & {
|
|
763
|
+
openFile: (filePath: string) => Promise<FileWithHandle>;
|
|
764
|
+
}>;
|
|
765
|
+
|
|
766
|
+
type User = {
|
|
767
|
+
name: string;
|
|
768
|
+
email: string;
|
|
769
|
+
timestamp: number;
|
|
770
|
+
};
|
|
771
|
+
|
|
772
|
+
type HistoryItem = {
|
|
773
|
+
oid: string;
|
|
774
|
+
message: string;
|
|
775
|
+
parent: string[];
|
|
776
|
+
author: User;
|
|
777
|
+
};
|
|
778
|
+
|
|
779
|
+
export { CompositeFs, EphemeralSubFs, GitSubFs, HiddenFileSubFs, PassThroughSubFs, createGitSyncService, getLegitFsAccess, gitBranchOperationsVirtualFile, initLegitFs, openLegitFs };
|
|
780
|
+
export type { HistoryItem, Operation, User };
|