| 24 | } |
| 25 | |
| 26 | export class FileDataStore implements IDataStore { |
| 27 | constructor( |
| 28 | private readFile: (uri: URI) => Promise<string>, |
| 29 | private readonly basedir: string |
| 30 | ) {} |
| 31 | |
| 32 | async list(pattern?: string): Promise<URI[]> { |
| 33 | const res = getFiles(this.basedir); |
| 34 | if (!pattern) { |
| 35 | return res.map(URI.file); |
| 36 | } |
| 37 | const absoluteGlob = path.posix.join(this.basedir, pattern); |
| 38 | const matches = micromatch(res, [absoluteGlob]); |
| 39 | return matches.map(URI.file); |
| 40 | } |
| 41 | |
| 42 | async read(uri: URI) { |
| 43 | try { |
| 44 | return await this.readFile(uri); |
| 45 | } catch (e) { |
| 46 | Logger.error( |
| 47 | `FileDataStore: error while reading uri: ${uri.path} - ${e}` |
| 48 | ); |
| 49 | return null; |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | async write(uri: URI, content: string): Promise<void> { |
| 54 | const fsPath = uri.toFsPath(); |
| 55 | fs.mkdirSync(path.dirname(fsPath), { recursive: true }); |
| 56 | fs.writeFileSync(fsPath, content, 'utf8'); |
| 57 | } |
| 58 | |
| 59 | async delete(uri: URI): Promise<void> { |
| 60 | try { |
| 61 | fs.unlinkSync(uri.toFsPath()); |
| 62 | } catch (err: any) { |
| 63 | if (err.code !== 'ENOENT') throw err; |
| 64 | } |
| 65 | } |
| 66 | |
| 67 | async move(from: URI, to: URI): Promise<void> { |
| 68 | const toFs = to.toFsPath(); |
| 69 | fs.mkdirSync(path.dirname(toFs), { recursive: true }); |
| 70 | fs.renameSync(from.toFsPath(), toFs); |
| 71 | } |
| 72 | |
| 73 | async exists(uri: URI): Promise<boolean> { |
| 74 | return fs.existsSync(uri.toFsPath()); |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | export const toMatcherPathFormat = isWindows |
| 79 | ? (uri: URI) => uri.toFsPath().replace(/\\/g, '/') |
nothing calls this directly
no outgoing calls
no test coverage detected