Add browser implementation
This commit is contained in:
parent
26f8485761
commit
28c910c9d7
@ -24,6 +24,7 @@
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"@types/sinon": "^10.0.4",
|
||||
"@types/sinon-chai": "^3.2.5",
|
||||
"@types/wicg-file-system-access": "^2020.9.4",
|
||||
"@typescript-eslint/eslint-plugin": "4.33.0",
|
||||
"@typescript-eslint/parser": "4.33.0",
|
||||
"chai": "^4.3.4",
|
||||
@ -66,6 +67,7 @@
|
||||
"trailingComma": "es5"
|
||||
},
|
||||
"dependencies": {
|
||||
"buffer": "^6.0.3",
|
||||
"tiny-invariant": "1.1.0",
|
||||
"tslib": "2.3.1"
|
||||
}
|
||||
|
11
pnpm-lock.yaml
generated
11
pnpm-lock.yaml
generated
@ -13,8 +13,10 @@ specifiers:
|
||||
'@types/react-dom': ^17.0.9
|
||||
'@types/sinon': ^10.0.4
|
||||
'@types/sinon-chai': ^3.2.5
|
||||
'@types/wicg-file-system-access': ^2020.9.4
|
||||
'@typescript-eslint/eslint-plugin': 4.33.0
|
||||
'@typescript-eslint/parser': 4.33.0
|
||||
buffer: ^6.0.3
|
||||
chai: ^4.3.4
|
||||
chai-as-promised: ^7.1.1
|
||||
chalk: ^4.1.2
|
||||
@ -49,6 +51,7 @@ specifiers:
|
||||
typescript: ^4.4.3
|
||||
|
||||
dependencies:
|
||||
buffer: 6.0.3
|
||||
tiny-invariant: 1.1.0
|
||||
tslib: 2.3.1
|
||||
|
||||
@ -65,6 +68,7 @@ devDependencies:
|
||||
'@types/react-dom': 17.0.9
|
||||
'@types/sinon': 10.0.4
|
||||
'@types/sinon-chai': 3.2.5
|
||||
'@types/wicg-file-system-access': 2020.9.4
|
||||
'@typescript-eslint/eslint-plugin': 4.33.0_d753869925cce96d3eb2141eeedafe57
|
||||
'@typescript-eslint/parser': 4.33.0_eslint@7.32.0+typescript@4.4.3
|
||||
chai: 4.3.4
|
||||
@ -1591,6 +1595,10 @@ packages:
|
||||
resolution: {integrity: sha512-N1rW+njavs70y2cApeIw1vLMYXRwfBy+7trgavGuuTfOd7j1Yh7QTRc/yqsPl6ncokt72ZXuxEU0PiCp9bSwNQ==}
|
||||
dev: true
|
||||
|
||||
/@types/wicg-file-system-access/2020.9.4:
|
||||
resolution: {integrity: sha512-o43jUljwP0ZrQ927mPjGdJaBMfS12nf3VPj6Z52fMucxILrSs8tnfLbMDSn6cP3hrrLChc3SYneeEvecknNVtA==}
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/eslint-plugin/4.33.0_d753869925cce96d3eb2141eeedafe57:
|
||||
resolution: {integrity: sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==}
|
||||
engines: {node: ^10.12.0 || >=12.0.0}
|
||||
@ -1920,7 +1928,6 @@ packages:
|
||||
|
||||
/base64-js/1.5.1:
|
||||
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
||||
dev: true
|
||||
|
||||
/binary-extensions/2.2.0:
|
||||
resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
|
||||
@ -2074,7 +2081,6 @@ packages:
|
||||
dependencies:
|
||||
base64-js: 1.5.1
|
||||
ieee754: 1.2.1
|
||||
dev: true
|
||||
|
||||
/builtin-status-codes/3.0.0:
|
||||
resolution: {integrity: sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=}
|
||||
@ -3514,7 +3520,6 @@ packages:
|
||||
|
||||
/ieee754/1.2.1:
|
||||
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
|
||||
dev: true
|
||||
|
||||
/ignore/4.0.6:
|
||||
resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==}
|
||||
|
@ -0,0 +1,89 @@
|
||||
import { promises as fs, existsSync } from "fs"
|
||||
import { Buffer } from "buffer"
|
||||
|
||||
import type { IAdapter, IFileSystem } from "./index"
|
||||
|
||||
function splitPath(path: string) {
|
||||
const segments = path.split("/")
|
||||
const filename = segments.pop()!
|
||||
return [segments, filename] as const
|
||||
}
|
||||
|
||||
export class BrowserAdapter implements IFileSystem {
|
||||
constructor(private handle: FileSystemDirectoryHandle) {}
|
||||
|
||||
static async create() {
|
||||
const handle = await showDirectoryPicker()
|
||||
return new BrowserAdapter(handle)
|
||||
}
|
||||
|
||||
private async getDirectoryHandle([first, ...pathSegments]: string[]) {
|
||||
const handle = await pathSegments.reduce(
|
||||
async (accum, next) => (await accum).getDirectoryHandle(next),
|
||||
this.handle.getDirectoryHandle(first)
|
||||
)
|
||||
return handle
|
||||
}
|
||||
|
||||
private async getFileHandle(path: string) {
|
||||
const [segments, filename] = splitPath(path)
|
||||
const dirHandle = await this.getDirectoryHandle(segments)
|
||||
const fileHandle = await dirHandle.getFileHandle(filename)
|
||||
return fileHandle
|
||||
}
|
||||
|
||||
async readFile(path: string) {
|
||||
const handle = await this.getFileHandle(path)
|
||||
const file = await handle.getFile()
|
||||
return file.text()
|
||||
}
|
||||
|
||||
async existsSync(path: string): Promise<boolean> {
|
||||
const [segments, filename] = splitPath(path)
|
||||
let handle = this.handle
|
||||
for (const segment of segments) {
|
||||
handle.values()
|
||||
const next = await handle.getDirectoryHandle()
|
||||
}
|
||||
|
||||
throw new Error("Method not implemented.")
|
||||
}
|
||||
|
||||
async readBuffer(path: string): Promise<Buffer> {
|
||||
const handle = await this.getFileHandle(path)
|
||||
const file = await handle.getFile()
|
||||
return Buffer.from(await file.arrayBuffer())
|
||||
}
|
||||
|
||||
async writeFile(path: string, data: string): Promise<void> {
|
||||
const handle = await this.getFileHandle(path)
|
||||
const writable = await handle.createWritable()
|
||||
await writable.write(data)
|
||||
await writable.close()
|
||||
}
|
||||
|
||||
readdir(path: string): Promise<string[]> {
|
||||
throw new Error("Method not implemented.")
|
||||
}
|
||||
|
||||
stat(path: string): Promise<{ isDirectory(): boolean }> {
|
||||
throw new Error("Method not implemented.")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default Node.js adapter. This can be used while using `opvault.js`
|
||||
* in a Node.js environment.
|
||||
*/
|
||||
const nodeAdapter: IAdapter = {
|
||||
fs: {
|
||||
readFile: path => fs.readFile(path, "utf-8"),
|
||||
readBuffer: path => fs.readFile(path),
|
||||
writeFile: fs.writeFile,
|
||||
readdir: fs.readdir,
|
||||
stat: fs.stat,
|
||||
existsSync,
|
||||
},
|
||||
}
|
||||
|
||||
export default nodeAdapter
|
Loading…
x
Reference in New Issue
Block a user