diff --git a/package.json b/package.json index 32dc84a6a1..3f514c2b79 100644 --- a/package.json +++ b/package.json @@ -93,6 +93,7 @@ "markdown-it": "^14.1.0", "node-stream-zip": "^1.15.0", "officeparser": "^4.1.1", + "opendal": "^0.47.11", "os-proxy-config": "^1.1.2", "proxy-agent": "^6.5.0", "react-query": "^3.39.3", diff --git a/src/main/services/RemoteStorage.ts b/src/main/services/RemoteStorage.ts new file mode 100644 index 0000000000..373f7fc31c --- /dev/null +++ b/src/main/services/RemoteStorage.ts @@ -0,0 +1,57 @@ +import Logger from 'electron-log' +import { Operator } from 'opendal' + +export default class RemoteStorage { + public instance: Operator | undefined + + /** + * + * @param scheme is the scheme for opendal services. Available value includes "azblob", "azdls", "cos", "gcs", "obs", "oss", "s3", "webdav", "webhdfs", "aliyun-drive", "alluxio", "azfile", "dropbox", "gdrive", "onedrive", "postgresql", "mysql", "redis", "swift", "mongodb", "alluxio", "b2", "seafile", "upyun", "koofr", "yandex-disk" + * @param options is the options for given opendal services. Valid options depend on the scheme. Checkout https://docs.rs/opendal/latest/opendal/services/index.html for all valid options. + * + * For example, use minio as remote storage: + * + * ```typescript + * const storage = new RemoteStorage('s3', { + * endpoint: 'http://localhost:9000', + * region: 'us-east-1', + * bucket: 'testbucket', + * access_key_id: 'user', + * secret_access_key: 'password', + * root: '/path/to/basepath', + * }) + * ``` + */ + constructor(scheme: string, options?: Record | undefined | null) { + this.instance = new Operator(scheme, options) + + this.putFileContents = this.putFileContents.bind(this) + this.getFileContents = this.getFileContents.bind(this) + } + + public putFileContents = async (filename: string, data: string | Buffer) => { + if (!this.instance) { + return new Error('RemoteStorage client not initialized') + } + + try { + return await this.instance.write(filename, data) + } catch (error) { + Logger.error('[RemoteStorage] Error putting file contents:', error) + throw error + } + } + + public getFileContents = async (filename: string) => { + if (!this.instance) { + throw new Error('RemoteStorage client not initialized') + } + + try { + return await this.instance.read(filename) + } catch (error) { + Logger.error('[RemoteStorage] Error getting file contents:', error) + throw error + } + } +} diff --git a/yarn.lock b/yarn.lock index 854ed8e275..ca65698f5f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2766,6 +2766,55 @@ __metadata: languageName: node linkType: hard +"@opendal/lib-darwin-arm64@npm:0.47.11": + version: 0.47.11 + resolution: "@opendal/lib-darwin-arm64@npm:0.47.11" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@opendal/lib-darwin-x64@npm:0.47.11": + version: 0.47.11 + resolution: "@opendal/lib-darwin-x64@npm:0.47.11" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@opendal/lib-linux-arm64-gnu@npm:0.47.11": + version: 0.47.11 + resolution: "@opendal/lib-linux-arm64-gnu@npm:0.47.11" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@opendal/lib-linux-arm64-musl@npm:0.47.11": + version: 0.47.11 + resolution: "@opendal/lib-linux-arm64-musl@npm:0.47.11" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@opendal/lib-linux-x64-gnu@npm:0.47.11": + version: 0.47.11 + resolution: "@opendal/lib-linux-x64-gnu@npm:0.47.11" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@opendal/lib-win32-arm64-msvc@npm:0.47.11": + version: 0.47.11 + resolution: "@opendal/lib-win32-arm64-msvc@npm:0.47.11" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@opendal/lib-win32-x64-msvc@npm:0.47.11": + version: 0.47.11 + resolution: "@opendal/lib-win32-x64-msvc@npm:0.47.11" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@parcel/watcher-android-arm64@npm:2.5.1": version: 2.5.1 resolution: "@parcel/watcher-android-arm64@npm:2.5.1" @@ -4414,6 +4463,7 @@ __metadata: npx-scope-finder: "npm:^1.2.0" officeparser: "npm:^4.1.1" openai: "patch:openai@npm%3A4.96.0#~/.yarn/patches/openai-npm-4.96.0-0665b05cb9.patch" + opendal: "npm:^0.47.11" os-proxy-config: "npm:^1.1.2" p-queue: "npm:^8.1.0" prettier: "npm:^3.5.3" @@ -12947,6 +12997,36 @@ __metadata: languageName: node linkType: hard +"opendal@npm:^0.47.11": + version: 0.47.11 + resolution: "opendal@npm:0.47.11" + dependencies: + "@opendal/lib-darwin-arm64": "npm:0.47.11" + "@opendal/lib-darwin-x64": "npm:0.47.11" + "@opendal/lib-linux-arm64-gnu": "npm:0.47.11" + "@opendal/lib-linux-arm64-musl": "npm:0.47.11" + "@opendal/lib-linux-x64-gnu": "npm:0.47.11" + "@opendal/lib-win32-arm64-msvc": "npm:0.47.11" + "@opendal/lib-win32-x64-msvc": "npm:0.47.11" + dependenciesMeta: + "@opendal/lib-darwin-arm64": + optional: true + "@opendal/lib-darwin-x64": + optional: true + "@opendal/lib-linux-arm64-gnu": + optional: true + "@opendal/lib-linux-arm64-musl": + optional: true + "@opendal/lib-linux-x64-gnu": + optional: true + "@opendal/lib-win32-arm64-msvc": + optional: true + "@opendal/lib-win32-x64-msvc": + optional: true + checksum: 10c0/0783da2651bb27ac693ce38938d12b00124530fb965364517eef3de17b3ff898cdecf06260a79a7d70745d57c2ba952a753a4bab52e0831aa7232c3a69120225 + languageName: node + linkType: hard + "option@npm:~0.2.1": version: 0.2.4 resolution: "option@npm:0.2.4"