mirror of https://github.com/nocodb/nocodb
Browse Source
* feat: backblaze migrate * feat: scaleway migrate * feat: digital ocean * chore: migrate to aws-sdk v3 * fix: refactor storagePlugins * fix: handle error inside callback * fix: return data as Buffer * fix: backblaze handle * feat: acl support for storage plugins * feat: minio refactor * feat: R2 plugin * fix: lock file * fix: use buffer only for images * fix: update fileCreateByUrl * fix: upocloud case * fix: upocloud case * chore: sync dependenciespull/9139/head
Anbarasu
4 months ago
committed by
GitHub
29 changed files with 2270 additions and 2216 deletions
After Width: | Height: | Size: 10 KiB |
@ -0,0 +1,199 @@
|
||||
import fs from 'fs'; |
||||
import { promisify } from 'util'; |
||||
import axios from 'axios'; |
||||
import { useAgent } from 'request-filtering-agent'; |
||||
import { |
||||
GetObjectCommand, |
||||
type PutObjectCommandInput, |
||||
} from '@aws-sdk/client-s3'; |
||||
import { getSignedUrl } from '@aws-sdk/s3-request-presigner'; |
||||
|
||||
import { Upload } from '@aws-sdk/lib-storage'; |
||||
import type { PutObjectRequest, S3 as S3Client } from '@aws-sdk/client-s3'; |
||||
import type { IStorageAdapterV2, XcFile } from 'nc-plugin'; |
||||
import type { Readable } from 'stream'; |
||||
import { generateTempFilePath, waitForStreamClose } from '~/utils/pluginUtils'; |
||||
|
||||
interface GenerocObjectStorageInput { |
||||
bucket: string; |
||||
region?: string; |
||||
access_key: string; |
||||
access_secret: string; |
||||
} |
||||
|
||||
export default class GenericS3 implements IStorageAdapterV2 { |
||||
protected s3Client: S3Client; |
||||
protected input: GenerocObjectStorageInput; |
||||
|
||||
constructor(input: unknown) { |
||||
this.input = input as GenerocObjectStorageInput; |
||||
} |
||||
|
||||
protected get defaultParams() { |
||||
return { |
||||
Bucket: this.input.bucket, |
||||
}; |
||||
} |
||||
|
||||
public async init(): Promise<any> { |
||||
// Placeholder, should be initalized in child class
|
||||
} |
||||
|
||||
public async test(): Promise<boolean> { |
||||
try { |
||||
const tempFile = generateTempFilePath(); |
||||
const createStream = fs.createWriteStream(tempFile); |
||||
await waitForStreamClose(createStream); |
||||
await this.fileCreate('nc-test-file.txt', { |
||||
path: tempFile, |
||||
mimetype: 'text/plain', |
||||
originalname: 'temp.txt', |
||||
size: '', |
||||
}); |
||||
await promisify(fs.unlink)(tempFile); |
||||
return true; |
||||
} catch (e) { |
||||
throw e; |
||||
} |
||||
} |
||||
|
||||
public async fileRead(key: string): Promise<any> { |
||||
const command = new GetObjectCommand({ |
||||
Key: key, |
||||
Bucket: this.input.bucket, |
||||
}); |
||||
|
||||
const { Body } = await this.s3Client.send(command); |
||||
|
||||
const fileStream = Body as Readable; |
||||
|
||||
return new Promise((resolve, reject) => { |
||||
const chunks: any[] = []; |
||||
fileStream.on('data', (chunk) => { |
||||
chunks.push(chunk); |
||||
}); |
||||
|
||||
fileStream.on('end', () => { |
||||
const buffer = Buffer.concat(chunks); |
||||
resolve(buffer); |
||||
}); |
||||
|
||||
fileStream.on('error', (err) => { |
||||
reject(err); |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
async fileCreate(key: string, file: XcFile): Promise<any> { |
||||
const fileStream = fs.createReadStream(file.path); |
||||
|
||||
return this.fileCreateByStream(key, fileStream, { |
||||
mimetype: file?.mimetype, |
||||
}); |
||||
} |
||||
|
||||
async fileCreateByStream( |
||||
key: string, |
||||
stream: Readable, |
||||
options?: { |
||||
mimetype?: string; |
||||
}, |
||||
): Promise<void> { |
||||
try { |
||||
const streamError = new Promise<void>((_, reject) => { |
||||
stream.on('error', (err) => { |
||||
reject(err); |
||||
}); |
||||
}); |
||||
|
||||
const uploadParams = { |
||||
...this.defaultParams, |
||||
Body: stream, |
||||
Key: key, |
||||
ContentType: options?.mimetype || 'application/octet-stream', |
||||
}; |
||||
|
||||
const upload = this.upload(uploadParams); |
||||
|
||||
return await Promise.race([upload, streamError]); |
||||
} catch (error) { |
||||
throw error; |
||||
} |
||||
} |
||||
|
||||
async fileCreateByUrl( |
||||
key: string, |
||||
url: string, |
||||
{ fetchOptions: { buffer } = { buffer: false } }, |
||||
): Promise<any> { |
||||
try { |
||||
const response = await axios.get(url, { |
||||
httpAgent: useAgent(url, { stopPortScanningByUrlRedirection: true }), |
||||
httpsAgent: useAgent(url, { stopPortScanningByUrlRedirection: true }), |
||||
responseType: buffer ? 'arraybuffer' : 'stream', |
||||
}); |
||||
const uploadParams: PutObjectRequest = { |
||||
...this.defaultParams, |
||||
Body: response.data, |
||||
Key: key, |
||||
ContentType: response.headers['content-type'], |
||||
}; |
||||
|
||||
const data = await this.upload(uploadParams); |
||||
return { |
||||
url: data, |
||||
data: response.data, |
||||
}; |
||||
} catch (error) { |
||||
throw error; |
||||
} |
||||
} |
||||
|
||||
public async getSignedUrl( |
||||
key, |
||||
expiresInSeconds = 7200, |
||||
pathParameters?: { [key: string]: string }, |
||||
) { |
||||
const command = new GetObjectCommand({ |
||||
Key: key, |
||||
Bucket: this.input.bucket, |
||||
...pathParameters, |
||||
}); |
||||
return getSignedUrl(this.s3Client, command, { |
||||
expiresIn: expiresInSeconds, |
||||
}); |
||||
} |
||||
|
||||
protected async upload(uploadParams: PutObjectCommandInput): Promise<any> { |
||||
try { |
||||
const upload = new Upload({ |
||||
client: this.s3Client, |
||||
params: { |
||||
ACL: 'public-read', |
||||
...uploadParams, |
||||
}, |
||||
}); |
||||
|
||||
const data = await upload.done(); |
||||
|
||||
return data.Location; |
||||
} catch (error) { |
||||
console.error('Error uploading file', error); |
||||
throw error; |
||||
} |
||||
} |
||||
|
||||
// TODO - implement
|
||||
fileReadByStream(_key: string): Promise<Readable> { |
||||
return Promise.resolve(undefined); |
||||
} |
||||
|
||||
// TODO - implement
|
||||
getDirectoryList(_path: string): Promise<string[]> { |
||||
return Promise.resolve(undefined); |
||||
} |
||||
|
||||
public async fileDelete(_path: string): Promise<any> { |
||||
return Promise.resolve(undefined); |
||||
} |
||||
} |
@ -1,151 +1,42 @@
|
||||
import fs from 'fs'; |
||||
import { promisify } from 'util'; |
||||
import AWS from 'aws-sdk'; |
||||
import axios from 'axios'; |
||||
import { useAgent } from 'request-filtering-agent'; |
||||
import type { IStorageAdapterV2, XcFile } from 'nc-plugin'; |
||||
import type { Readable } from 'stream'; |
||||
import { generateTempFilePath, waitForStreamClose } from '~/utils/pluginUtils'; |
||||
|
||||
export default class LinodeObjectStorage implements IStorageAdapterV2 { |
||||
private s3Client: AWS.S3; |
||||
private input: any; |
||||
|
||||
constructor(input: any) { |
||||
this.input = input; |
||||
} |
||||
|
||||
async fileCreate(key: string, file: XcFile): Promise<any> { |
||||
const fileStream = fs.createReadStream(file.path); |
||||
|
||||
return this.fileCreateByStream(key, fileStream, { |
||||
mimetype: file?.mimetype, |
||||
}); |
||||
} |
||||
|
||||
async fileCreateByUrl(key: string, url: string): Promise<any> { |
||||
const uploadParams: any = { |
||||
ACL: 'public-read', |
||||
}; |
||||
return new Promise((resolve, reject) => { |
||||
axios |
||||
.get(url, { |
||||
httpAgent: useAgent(url, { stopPortScanningByUrlRedirection: true }), |
||||
httpsAgent: useAgent(url, { stopPortScanningByUrlRedirection: true }), |
||||
// TODO - use stream instead of buffer
|
||||
responseType: 'arraybuffer', |
||||
}) |
||||
.then((response) => { |
||||
uploadParams.Body = response.data; |
||||
uploadParams.Key = key; |
||||
uploadParams.ContentType = response.headers['content-type']; |
||||
|
||||
// call S3 to retrieve upload file to specified bucket
|
||||
this.s3Client.upload(uploadParams, (err1, data) => { |
||||
if (err1) { |
||||
console.log('Error', err1); |
||||
reject(err1); |
||||
} |
||||
if (data) { |
||||
resolve({ |
||||
url: data.Location, |
||||
data: response.data, |
||||
}); |
||||
} |
||||
}); |
||||
}) |
||||
.catch((error) => { |
||||
reject(error); |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
public async fileCreateByStream( |
||||
key: string, |
||||
stream: Readable, |
||||
options?: { |
||||
mimetype?: string; |
||||
}, |
||||
): Promise<any> { |
||||
const uploadParams: any = { |
||||
ACL: 'public-read', |
||||
Body: stream, |
||||
Key: key, |
||||
ContentType: options?.mimetype || 'application/octet-stream', |
||||
import { S3 as S3Client } from '@aws-sdk/client-s3'; |
||||
import type { S3ClientConfig } from '@aws-sdk/client-s3'; |
||||
import type { IStorageAdapterV2 } from 'nc-plugin'; |
||||
import GenericS3 from '~/plugins/GenericS3/GenericS3'; |
||||
|
||||
interface LinodeObjectStorageInput { |
||||
bucket: string; |
||||
region: string; |
||||
access_key: string; |
||||
access_secret: string; |
||||
acl?: string; |
||||
} |
||||
|
||||
export default class LinodeObjectStorage |
||||
extends GenericS3 |
||||
implements IStorageAdapterV2 |
||||
{ |
||||
protected input: LinodeObjectStorageInput; |
||||
constructor(input: unknown) { |
||||
super(input as LinodeObjectStorageInput); |
||||
} |
||||
|
||||
protected get defaultParams() { |
||||
return { |
||||
Bucket: this.input.bucket, |
||||
ACL: this.input?.acl || 'public-read', |
||||
}; |
||||
return new Promise((resolve, reject) => { |
||||
// call S3 to retrieve upload file to specified bucket
|
||||
this.s3Client.upload(uploadParams, (err, data) => { |
||||
if (err) { |
||||
console.log('Error', err); |
||||
reject(err); |
||||
} |
||||
if (data) { |
||||
resolve(data.Location); |
||||
} |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
// TODO - implement
|
||||
fileReadByStream(_key: string): Promise<Readable> { |
||||
return Promise.resolve(undefined); |
||||
} |
||||
|
||||
// TODO - implement
|
||||
getDirectoryList(_path: string): Promise<string[]> { |
||||
return Promise.resolve(undefined); |
||||
} |
||||
|
||||
public async fileDelete(_path: string): Promise<any> { |
||||
return Promise.resolve(undefined); |
||||
} |
||||
|
||||
public async fileRead(key: string): Promise<any> { |
||||
return new Promise((resolve, reject) => { |
||||
this.s3Client.getObject({ Key: key } as any, (err, data) => { |
||||
if (err) { |
||||
return reject(err); |
||||
} |
||||
if (!data?.Body) { |
||||
return reject(data); |
||||
} |
||||
return resolve(data.Body); |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
public async init(): Promise<any> { |
||||
const s3Options: any = { |
||||
params: { Bucket: this.input.bucket }, |
||||
const s3Options: S3ClientConfig = { |
||||
region: this.input.region, |
||||
credentials: { |
||||
accessKeyId: this.input.access_key, |
||||
secretAccessKey: this.input.access_secret, |
||||
}, |
||||
endpoint: `https://${this.input.region}.linodeobjects.com`, |
||||
}; |
||||
|
||||
s3Options.accessKeyId = this.input.access_key; |
||||
s3Options.secretAccessKey = this.input.access_secret; |
||||
|
||||
s3Options.endpoint = new AWS.Endpoint( |
||||
`${this.input.region}.linodeobjects.com`, |
||||
); |
||||
|
||||
this.s3Client = new AWS.S3(s3Options); |
||||
} |
||||
|
||||
public async test(): Promise<boolean> { |
||||
try { |
||||
const tempFile = generateTempFilePath(); |
||||
const createStream = fs.createWriteStream(tempFile); |
||||
await waitForStreamClose(createStream); |
||||
await this.fileCreate('nc-test-file.txt', { |
||||
path: tempFile, |
||||
mimetype: 'text/plain', |
||||
originalname: 'temp.txt', |
||||
size: '', |
||||
}); |
||||
await promisify(fs.unlink)(tempFile); |
||||
return true; |
||||
} catch (e) { |
||||
throw e; |
||||
} |
||||
this.s3Client = new S3Client(s3Options); |
||||
} |
||||
} |
||||
|
@ -1,156 +1,42 @@
|
||||
import fs from 'fs'; |
||||
import { promisify } from 'util'; |
||||
import AWS from 'aws-sdk'; |
||||
import axios from 'axios'; |
||||
import { useAgent } from 'request-filtering-agent'; |
||||
import type { IStorageAdapterV2, XcFile } from 'nc-plugin'; |
||||
import type { Readable } from 'stream'; |
||||
import { generateTempFilePath, waitForStreamClose } from '~/utils/pluginUtils'; |
||||
import { S3 as S3Client } from '@aws-sdk/client-s3'; |
||||
import type { S3ClientConfig } from '@aws-sdk/client-s3'; |
||||
import type { IStorageAdapterV2 } from 'nc-plugin'; |
||||
import GenericS3 from '~/plugins/GenericS3/GenericS3'; |
||||
|
||||
export default class OvhCloud implements IStorageAdapterV2 { |
||||
private s3Client: AWS.S3; |
||||
private input: any; |
||||
|
||||
constructor(input: any) { |
||||
this.input = input; |
||||
interface OvhCloudStorageInput { |
||||
bucket: string; |
||||
region: string; |
||||
access_key: string; |
||||
access_secret: string; |
||||
acl?: string; |
||||
} |
||||
|
||||
async fileCreate(key: string, file: XcFile): Promise<any> { |
||||
const fileStream = fs.createReadStream(file.path); |
||||
|
||||
return this.fileCreateByStream(key, fileStream, { |
||||
mimetype: file?.mimetype, |
||||
}); |
||||
} |
||||
export default class OvhCloud extends GenericS3 implements IStorageAdapterV2 { |
||||
protected input: OvhCloudStorageInput; |
||||
|
||||
async fileCreateByUrl(key: string, url: string): Promise<any> { |
||||
const uploadParams: any = { |
||||
ACL: 'public-read', |
||||
}; |
||||
return new Promise((resolve, reject) => { |
||||
axios |
||||
.get(url, { |
||||
httpAgent: useAgent(url, { stopPortScanningByUrlRedirection: true }), |
||||
httpsAgent: useAgent(url, { stopPortScanningByUrlRedirection: true }), |
||||
// TODO - use stream instead of buffer
|
||||
responseType: 'arraybuffer', |
||||
}) |
||||
.then((response) => { |
||||
uploadParams.Body = response.data; |
||||
uploadParams.Key = key; |
||||
uploadParams.ContentType = response.headers['content-type']; |
||||
|
||||
// call S3 to retrieve upload file to specified bucket
|
||||
this.s3Client.upload(uploadParams, (err1, data) => { |
||||
if (err1) { |
||||
console.log('Error', err1); |
||||
reject(err1); |
||||
} |
||||
if (data) { |
||||
resolve({ |
||||
url: data.Location, |
||||
data: response.data, |
||||
}); |
||||
} |
||||
}); |
||||
}) |
||||
.catch((error) => { |
||||
reject(error); |
||||
}); |
||||
}); |
||||
constructor(input: unknown) { |
||||
super(input as OvhCloudStorageInput); |
||||
} |
||||
|
||||
async fileCreateByStream( |
||||
key: string, |
||||
stream: Readable, |
||||
options?: { |
||||
mimetype?: string; |
||||
}, |
||||
): Promise<void> { |
||||
const uploadParams: any = { |
||||
ACL: 'public-read', |
||||
// ContentType: file.mimetype,
|
||||
protected get defaultParams() { |
||||
return { |
||||
Bucket: this.input.bucket, |
||||
ACL: this.input?.acl || 'public-read', |
||||
}; |
||||
return new Promise((resolve, reject) => { |
||||
// Configure the file stream and obtain the upload parameters
|
||||
|
||||
uploadParams.Body = stream; |
||||
uploadParams.Key = key; |
||||
uploadParams.ContentType = |
||||
options?.mimetype || 'application/octet-stream'; |
||||
|
||||
// call S3 to retrieve upload file to specified bucket
|
||||
this.s3Client.upload(uploadParams, (err, data) => { |
||||
if (err) { |
||||
console.log('Error', err); |
||||
reject(err); |
||||
} |
||||
if (data) { |
||||
resolve(data.Location); |
||||
} |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
// TODO - implement
|
||||
fileReadByStream(_key: string): Promise<Readable> { |
||||
return Promise.resolve(undefined); |
||||
} |
||||
|
||||
// TODO - implement
|
||||
getDirectoryList(_path: string): Promise<string[]> { |
||||
return Promise.resolve(undefined); |
||||
} |
||||
|
||||
public async fileDelete(_path: string): Promise<any> { |
||||
return Promise.resolve(undefined); |
||||
} |
||||
|
||||
public async fileRead(key: string): Promise<any> { |
||||
return new Promise((resolve, reject) => { |
||||
this.s3Client.getObject({ Key: key } as any, (err, data) => { |
||||
if (err) { |
||||
return reject(err); |
||||
} |
||||
if (!data?.Body) { |
||||
return reject(data); |
||||
} |
||||
return resolve(data.Body); |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
public async init(): Promise<any> { |
||||
const s3Options: any = { |
||||
params: { Bucket: this.input.bucket }, |
||||
const s3Options: S3ClientConfig = { |
||||
region: this.input.region, |
||||
credentials: { |
||||
accessKeyId: this.input.access_key, |
||||
secretAccessKey: this.input.access_secret, |
||||
}, |
||||
// TODO: Need to verify
|
||||
// DOCS s3.<region_in_lowercase>.io.cloud.ovh.net
|
||||
endpoint: `https://s3.${this.input.region}.cloud.ovh.net`, |
||||
}; |
||||
|
||||
s3Options.accessKeyId = this.input.access_key; |
||||
s3Options.secretAccessKey = this.input.access_secret; |
||||
|
||||
s3Options.endpoint = new AWS.Endpoint( |
||||
`s3.${this.input.region}.cloud.ovh.net`, |
||||
); |
||||
|
||||
this.s3Client = new AWS.S3(s3Options); |
||||
} |
||||
|
||||
public async test(): Promise<boolean> { |
||||
try { |
||||
const tempFile = generateTempFilePath(); |
||||
const createStream = fs.createWriteStream(tempFile); |
||||
await waitForStreamClose(createStream); |
||||
await this.fileCreate('nc-test-file.txt', { |
||||
path: tempFile, |
||||
mimetype: 'text/plain', |
||||
originalname: 'temp.txt', |
||||
size: '', |
||||
}); |
||||
await promisify(fs.unlink)(tempFile); |
||||
return true; |
||||
} catch (e) { |
||||
throw e; |
||||
} |
||||
this.s3Client = new S3Client(s3Options); |
||||
} |
||||
} |
||||
|
@ -0,0 +1,42 @@
|
||||
import { S3 as S3Client } from '@aws-sdk/client-s3'; |
||||
|
||||
import type { S3ClientConfigType } from '@aws-sdk/client-s3'; |
||||
import type { IStorageAdapterV2 } from 'nc-plugin'; |
||||
import GenericS3 from '~/plugins/GenericS3/GenericS3'; |
||||
|
||||
interface R2ObjectStorageInput { |
||||
bucket: string; |
||||
access_key: string; |
||||
access_secret: string; |
||||
hostname: string; |
||||
region: string; |
||||
} |
||||
|
||||
export default class R2 extends GenericS3 implements IStorageAdapterV2 { |
||||
protected input: R2ObjectStorageInput; |
||||
|
||||
constructor(input: unknown) { |
||||
super(input as R2ObjectStorageInput); |
||||
} |
||||
|
||||
protected get defaultParams() { |
||||
return { |
||||
Bucket: this.input.bucket, |
||||
// R2 does not support ACL
|
||||
ACL: 'private', |
||||
}; |
||||
} |
||||
|
||||
public async init(): Promise<any> { |
||||
const s3Options: S3ClientConfigType = { |
||||
region: 'auto', |
||||
endpoint: this.input.hostname, |
||||
credentials: { |
||||
accessKeyId: this.input.access_key, |
||||
secretAccessKey: this.input.access_secret, |
||||
}, |
||||
}; |
||||
|
||||
this.s3Client = new S3Client(s3Options); |
||||
} |
||||
} |
@ -0,0 +1,18 @@
|
||||
import { XcStoragePlugin } from 'nc-plugin'; |
||||
import R2 from './R2'; |
||||
import type { IStorageAdapterV2 } from 'nc-plugin'; |
||||
|
||||
class R2Plugin extends XcStoragePlugin { |
||||
private static storageAdapter: R2; |
||||
|
||||
public getAdapter(): IStorageAdapterV2 { |
||||
return R2Plugin.storageAdapter; |
||||
} |
||||
|
||||
public async init(config: any): Promise<any> { |
||||
R2Plugin.storageAdapter = new R2(config); |
||||
await R2Plugin.storageAdapter.init(); |
||||
} |
||||
} |
||||
|
||||
export default R2Plugin; |
@ -0,0 +1,68 @@
|
||||
import { XcActionType, XcType } from 'nocodb-sdk'; |
||||
import R2Plugin from './R2Plugin'; |
||||
import type { XcPluginConfig } from 'nc-plugin'; |
||||
|
||||
const config: XcPluginConfig = { |
||||
builder: R2Plugin, |
||||
title: 'Cloudflare R2 Storage', |
||||
version: '0.0.1', |
||||
logo: 'plugins/r2.png', |
||||
description: |
||||
'Cloudflare R2 is an S3-compatible, zero egress-fee, globally distributed object storage.', |
||||
tags: 'Storage', |
||||
inputs: { |
||||
title: 'Configure Cloudflare R2 Storage', |
||||
items: [ |
||||
{ |
||||
key: 'bucket', |
||||
label: 'Bucket Name', |
||||
placeholder: 'Bucket Name', |
||||
type: XcType.SingleLineText, |
||||
required: true, |
||||
}, |
||||
{ |
||||
key: 'hostname', |
||||
label: 'Host Name', |
||||
placeholder: 'e.g.: *****.r2.cloudflarestorage.com', |
||||
type: XcType.SingleLineText, |
||||
required: true, |
||||
}, |
||||
{ |
||||
key: 'access_key', |
||||
label: 'Access Key', |
||||
placeholder: 'Access Key', |
||||
type: XcType.SingleLineText, |
||||
required: true, |
||||
}, |
||||
{ |
||||
key: 'access_secret', |
||||
label: 'Access Secret', |
||||
placeholder: 'Access Secret', |
||||
type: XcType.Password, |
||||
required: true, |
||||
}, |
||||
], |
||||
actions: [ |
||||
{ |
||||
label: 'Test', |
||||
placeholder: 'Test', |
||||
key: 'test', |
||||
actionType: XcActionType.TEST, |
||||
type: XcType.Button, |
||||
}, |
||||
{ |
||||
label: 'Save', |
||||
placeholder: 'Save', |
||||
key: 'save', |
||||
actionType: XcActionType.SUBMIT, |
||||
type: XcType.Button, |
||||
}, |
||||
], |
||||
msgOnInstall: |
||||
'Successfully installed and attachment will be stored in Cloudflare R2 Storage', |
||||
msgOnUninstall: '', |
||||
}, |
||||
category: 'Storage', |
||||
}; |
||||
|
||||
export default config; |
@ -1,149 +1,44 @@
|
||||
import fs from 'fs'; |
||||
import { promisify } from 'util'; |
||||
import AWS from 'aws-sdk'; |
||||
import axios from 'axios'; |
||||
import { useAgent } from 'request-filtering-agent'; |
||||
import type { IStorageAdapterV2, XcFile } from 'nc-plugin'; |
||||
import type { Readable } from 'stream'; |
||||
import { generateTempFilePath, waitForStreamClose } from '~/utils/pluginUtils'; |
||||
import { S3 as S3Client } from '@aws-sdk/client-s3'; |
||||
import type { S3ClientConfig } from '@aws-sdk/client-s3'; |
||||
|
||||
export default class ScalewayObjectStorage implements IStorageAdapterV2 { |
||||
private s3Client: AWS.S3; |
||||
private input: any; |
||||
import type { IStorageAdapterV2 } from 'nc-plugin'; |
||||
import GenericS3 from '~/plugins/GenericS3/GenericS3'; |
||||
|
||||
constructor(input: any) { |
||||
this.input = input; |
||||
interface ScalewayObjectStorageInput { |
||||
bucket: string; |
||||
region: string; |
||||
access_key: string; |
||||
access_secret: string; |
||||
acl?: string; |
||||
} |
||||
|
||||
public async fileRead(key: string): Promise<any> { |
||||
return new Promise((resolve, reject) => { |
||||
this.s3Client.getObject({ Key: key } as any, (err, data) => { |
||||
if (err) { |
||||
return reject(err); |
||||
} |
||||
if (!data?.Body) { |
||||
return reject(data); |
||||
} |
||||
return resolve(data.Body); |
||||
}); |
||||
}); |
||||
} |
||||
export default class ScalewayObjectStorage |
||||
extends GenericS3 |
||||
implements IStorageAdapterV2 |
||||
{ |
||||
protected input: ScalewayObjectStorageInput; |
||||
|
||||
public async test(): Promise<boolean> { |
||||
try { |
||||
const tempFile = generateTempFilePath(); |
||||
const createStream = fs.createWriteStream(tempFile); |
||||
await waitForStreamClose(createStream); |
||||
await this.fileCreate('nc-test-file.txt', { |
||||
path: tempFile, |
||||
mimetype: 'text/plain', |
||||
originalname: 'temp.txt', |
||||
size: '', |
||||
}); |
||||
await promisify(fs.unlink)(tempFile); |
||||
return true; |
||||
} catch (e) { |
||||
throw e; |
||||
} |
||||
constructor(input: unknown) { |
||||
super(input as ScalewayObjectStorageInput); |
||||
} |
||||
|
||||
public async fileDelete(_path: string): Promise<any> { |
||||
return Promise.resolve(undefined); |
||||
protected get defaultParams() { |
||||
return { |
||||
Bucket: this.input.bucket, |
||||
ACL: this.input?.acl || 'public-read', |
||||
}; |
||||
} |
||||
|
||||
public async init(): Promise<any> { |
||||
const s3Options: any = { |
||||
params: { Bucket: this.input.bucket }, |
||||
const s3Options: S3ClientConfig = { |
||||
region: this.input.region, |
||||
}; |
||||
|
||||
s3Options.accessKeyId = this.input.access_key; |
||||
s3Options.secretAccessKey = this.input.access_secret; |
||||
|
||||
s3Options.endpoint = new AWS.Endpoint(`s3.${this.input.region}.scw.cloud`); |
||||
|
||||
this.s3Client = new AWS.S3(s3Options); |
||||
} |
||||
|
||||
async fileCreate(key: string, file: XcFile): Promise<any> { |
||||
const fileStream = fs.createReadStream(file.path); |
||||
|
||||
return this.fileCreateByStream(key, fileStream, { |
||||
mimetype: file?.mimetype, |
||||
}); |
||||
} |
||||
|
||||
async fileCreateByUrl(key: string, url: string): Promise<any> { |
||||
const uploadParams: any = { |
||||
ACL: 'public-read', |
||||
}; |
||||
return new Promise((resolve, reject) => { |
||||
axios |
||||
.get(url, { |
||||
httpAgent: useAgent(url, { stopPortScanningByUrlRedirection: true }), |
||||
httpsAgent: useAgent(url, { stopPortScanningByUrlRedirection: true }), |
||||
// TODO - use stream instead of buffer
|
||||
responseType: 'arraybuffer', |
||||
}) |
||||
.then((response) => { |
||||
uploadParams.Body = response.data; |
||||
uploadParams.Key = key; |
||||
uploadParams.ContentType = response.headers['content-type']; |
||||
|
||||
// call S3 to retrieve upload file to specified bucket
|
||||
this.s3Client.upload(uploadParams, (err1, data) => { |
||||
if (err1) { |
||||
console.log('Error', err1); |
||||
reject(err1); |
||||
} |
||||
if (data) { |
||||
resolve({ |
||||
url: data.Location, |
||||
data: response.data, |
||||
}); |
||||
} |
||||
}); |
||||
}) |
||||
.catch((error) => { |
||||
reject(error); |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
async fileCreateByStream( |
||||
key: string, |
||||
stream: Readable, |
||||
options?: { |
||||
mimetype?: string; |
||||
credentials: { |
||||
accessKeyId: this.input.access_key, |
||||
secretAccessKey: this.input.access_secret, |
||||
}, |
||||
): Promise<any> { |
||||
const uploadParams: any = { |
||||
ACL: 'public-read', |
||||
Body: stream, |
||||
Key: key, |
||||
ContentType: options?.mimetype || 'application/octet-stream', |
||||
endpoint: `https://s3.${this.input.region}.scw.cloud`, |
||||
}; |
||||
return new Promise((resolve, reject) => { |
||||
// call S3 to retrieve upload file to specified bucket
|
||||
this.s3Client.upload(uploadParams, (err, data) => { |
||||
if (err) { |
||||
console.log('Error', err); |
||||
reject(err); |
||||
} |
||||
if (data) { |
||||
resolve(data.Location); |
||||
} |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
// TODO - implement
|
||||
fileReadByStream(_key: string): Promise<Readable> { |
||||
return Promise.resolve(undefined); |
||||
} |
||||
|
||||
// TODO - implement
|
||||
getDirectoryList(_path: string): Promise<string[]> { |
||||
return Promise.resolve(undefined); |
||||
this.s3Client = new S3Client(s3Options); |
||||
} |
||||
} |
||||
|
@ -1,159 +1,41 @@
|
||||
import fs from 'fs'; |
||||
import { promisify } from 'util'; |
||||
import AWS from 'aws-sdk'; |
||||
import axios from 'axios'; |
||||
import { useAgent } from 'request-filtering-agent'; |
||||
import type { IStorageAdapterV2, XcFile } from 'nc-plugin'; |
||||
import type { Readable } from 'stream'; |
||||
import { generateTempFilePath, waitForStreamClose } from '~/utils/pluginUtils'; |
||||
import { S3 as S3Client } from '@aws-sdk/client-s3'; |
||||
import type { S3ClientConfig } from '@aws-sdk/client-s3'; |
||||
import type { IStorageAdapterV2 } from 'nc-plugin'; |
||||
import GenericS3 from '~/plugins/GenericS3/GenericS3'; |
||||
|
||||
export default class Spaces implements IStorageAdapterV2 { |
||||
private s3Client: AWS.S3; |
||||
private input: any; |
||||
|
||||
constructor(input: any) { |
||||
this.input = input; |
||||
interface SpacesObjectStorageInput { |
||||
bucket: string; |
||||
region: string; |
||||
access_key: string; |
||||
access_secret: string; |
||||
acl?: string; |
||||
} |
||||
|
||||
async fileCreate(key: string, file: XcFile): Promise<any> { |
||||
const fileStream = fs.createReadStream(file.path); |
||||
|
||||
return this.fileCreateByStream(key, fileStream, { |
||||
mimetype: file?.mimetype, |
||||
}); |
||||
} |
||||
export default class Spaces extends GenericS3 implements IStorageAdapterV2 { |
||||
protected input: SpacesObjectStorageInput; |
||||
|
||||
async fileCreateByUrl(key: string, url: string): Promise<any> { |
||||
const uploadParams: any = { |
||||
ACL: 'public-read', |
||||
}; |
||||
return new Promise((resolve, reject) => { |
||||
axios |
||||
.get(url, { |
||||
httpAgent: useAgent(url, { stopPortScanningByUrlRedirection: true }), |
||||
httpsAgent: useAgent(url, { stopPortScanningByUrlRedirection: true }), |
||||
// TODO - use stream instead of buffer
|
||||
responseType: 'arraybuffer', |
||||
}) |
||||
.then((response) => { |
||||
uploadParams.Body = response.data; |
||||
uploadParams.Key = key; |
||||
uploadParams.ContentType = response.headers['content-type']; |
||||
|
||||
// call S3 to retrieve upload file to specified bucket
|
||||
this.s3Client.upload(uploadParams, (err1, data) => { |
||||
if (err1) { |
||||
console.log('Error', err1); |
||||
reject(err1); |
||||
} |
||||
if (data) { |
||||
resolve({ |
||||
url: data.Location, |
||||
data: response.data, |
||||
}); |
||||
} |
||||
}); |
||||
}) |
||||
.catch((error) => { |
||||
reject(error); |
||||
}); |
||||
}); |
||||
constructor(input: unknown) { |
||||
super(input as SpacesObjectStorageInput); |
||||
} |
||||
|
||||
async fileCreateByStream( |
||||
key: string, |
||||
stream: Readable, |
||||
options?: { |
||||
mimetype?: string; |
||||
}, |
||||
): Promise<void> { |
||||
const uploadParams: any = { |
||||
ACL: 'public-read', |
||||
Body: stream, |
||||
Key: key, |
||||
ContentType: options?.mimetype || 'application/octet-stream', |
||||
protected get defaultParams() { |
||||
return { |
||||
Bucket: this.input.bucket, |
||||
ACL: this.input?.acl || 'public-read', |
||||
}; |
||||
return new Promise((resolve, reject) => { |
||||
// call S3 to retrieve upload file to specified bucket
|
||||
this.s3Client.upload(uploadParams, (err, data) => { |
||||
if (err) { |
||||
console.log('Error', err); |
||||
reject(err); |
||||
} |
||||
if (data) { |
||||
resolve(data.Location); |
||||
} |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
// TODO - implement
|
||||
fileReadByStream(_key: string): Promise<Readable> { |
||||
return Promise.resolve(undefined); |
||||
} |
||||
|
||||
// TODO - implement
|
||||
getDirectoryList(_path: string): Promise<string[]> { |
||||
return Promise.resolve(undefined); |
||||
} |
||||
|
||||
public async fileDelete(_path: string): Promise<any> { |
||||
return Promise.resolve(undefined); |
||||
} |
||||
|
||||
public async fileRead(key: string): Promise<any> { |
||||
return new Promise((resolve, reject) => { |
||||
this.s3Client.getObject({ Key: key } as any, (err, data) => { |
||||
if (err) { |
||||
return reject(err); |
||||
} |
||||
if (!data?.Body) { |
||||
return reject(data); |
||||
} |
||||
return resolve(data.Body); |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
public async init(): Promise<any> { |
||||
// const s3Options: any = {
|
||||
// params: {Bucket: process.env.NC_S3_BUCKET},
|
||||
// region: process.env.NC_S3_REGION
|
||||
// };
|
||||
//
|
||||
// s3Options.accessKeyId = process.env.NC_S3_KEY;
|
||||
// s3Options.secretAccessKey = process.env.NC_S3_SECRET;
|
||||
|
||||
const s3Options: any = { |
||||
params: { Bucket: this.input.bucket }, |
||||
region: this.input.region, |
||||
const s3Options: S3ClientConfig = { |
||||
region: 'us-east-1', |
||||
forcePathStyle: false, |
||||
credentials: { |
||||
accessKeyId: this.input.access_key, |
||||
secretAccessKey: this.input.access_secret, |
||||
}, |
||||
endpoint: `https://${this.input.region || 'nyc3'}.digitaloceanspaces.com`, |
||||
}; |
||||
|
||||
s3Options.accessKeyId = this.input.access_key; |
||||
s3Options.secretAccessKey = this.input.access_secret; |
||||
|
||||
s3Options.endpoint = new AWS.Endpoint( |
||||
`${this.input.region || 'nyc3'}.digitaloceanspaces.com`, |
||||
); |
||||
|
||||
this.s3Client = new AWS.S3(s3Options); |
||||
} |
||||
|
||||
public async test(): Promise<boolean> { |
||||
try { |
||||
const tempFile = generateTempFilePath(); |
||||
const createStream = fs.createWriteStream(tempFile); |
||||
await waitForStreamClose(createStream); |
||||
await this.fileCreate('nc-test-file.txt', { |
||||
path: tempFile, |
||||
mimetype: 'text/plain', |
||||
originalname: 'temp.txt', |
||||
size: '', |
||||
}); |
||||
await promisify(fs.unlink)(tempFile); |
||||
return true; |
||||
} catch (e) { |
||||
throw e; |
||||
} |
||||
this.s3Client = new S3Client(s3Options); |
||||
} |
||||
} |
||||
|
@ -1,149 +1,45 @@
|
||||
import fs from 'fs'; |
||||
import { promisify } from 'util'; |
||||
import AWS from 'aws-sdk'; |
||||
import axios from 'axios'; |
||||
import { useAgent } from 'request-filtering-agent'; |
||||
import type { IStorageAdapterV2, XcFile } from 'nc-plugin'; |
||||
import type { Readable } from 'stream'; |
||||
import { generateTempFilePath, waitForStreamClose } from '~/utils/pluginUtils'; |
||||
import { S3 as S3Client } from '@aws-sdk/client-s3'; |
||||
import type { S3ClientConfig } from '@aws-sdk/client-s3'; |
||||
import type { IStorageAdapterV2 } from 'nc-plugin'; |
||||
import GenericS3 from '~/plugins/GenericS3/GenericS3'; |
||||
|
||||
export default class UpoCloud implements IStorageAdapterV2 { |
||||
private s3Client: AWS.S3; |
||||
private input: any; |
||||
|
||||
constructor(input: any) { |
||||
this.input = input; |
||||
interface UpoCloudStorgeInput { |
||||
bucket: string; |
||||
region: string; |
||||
access_key: string; |
||||
access_secret: string; |
||||
endpoint: string; |
||||
acl?: string; |
||||
} |
||||
|
||||
async fileCreate(key: string, file: XcFile): Promise<any> { |
||||
const fileStream = fs.createReadStream(file.path); |
||||
|
||||
return this.fileCreateByStream(key, fileStream, { |
||||
mimetype: file?.mimetype, |
||||
}); |
||||
} |
||||
export default class UpoCloud extends GenericS3 implements IStorageAdapterV2 { |
||||
protected input: UpoCloudStorgeInput; |
||||
|
||||
async fileCreateByUrl(key: string, url: string): Promise<any> { |
||||
const uploadParams: any = { |
||||
ACL: 'public-read', |
||||
}; |
||||
return new Promise((resolve, reject) => { |
||||
axios |
||||
.get(url, { |
||||
httpAgent: useAgent(url, { stopPortScanningByUrlRedirection: true }), |
||||
httpsAgent: useAgent(url, { stopPortScanningByUrlRedirection: true }), |
||||
// TODO - use stream instead of buffer
|
||||
responseType: 'arraybuffer', |
||||
}) |
||||
.then((response) => { |
||||
uploadParams.Body = response.data; |
||||
uploadParams.Key = key; |
||||
uploadParams.ContentType = response.headers['content-type']; |
||||
|
||||
// call S3 to retrieve upload file to specified bucket
|
||||
this.s3Client.upload(uploadParams, (err1, data) => { |
||||
if (err1) { |
||||
console.log('Error', err1); |
||||
reject(err1); |
||||
} |
||||
if (data) { |
||||
resolve({ |
||||
url: data.Location, |
||||
data: response.data, |
||||
}); |
||||
} |
||||
}); |
||||
}) |
||||
.catch((error) => { |
||||
reject(error); |
||||
}); |
||||
}); |
||||
constructor(input: unknown) { |
||||
super(input as UpoCloudStorgeInput); |
||||
} |
||||
|
||||
async fileCreateByStream( |
||||
key: string, |
||||
stream: Readable, |
||||
options?: { |
||||
mimetype?: string; |
||||
}, |
||||
): Promise<void> { |
||||
const uploadParams: any = { |
||||
ACL: 'public-read', |
||||
Key: key, |
||||
Body: stream, |
||||
ContentType: options?.mimetype || 'application/octet-stream', |
||||
protected get defaultParams() { |
||||
return { |
||||
Bucket: this.input.bucket, |
||||
ACL: this.input?.acl || 'public-read', |
||||
}; |
||||
return new Promise((resolve, reject) => { |
||||
// call S3 to retrieve upload file to specified bucket
|
||||
this.s3Client.upload(uploadParams, (err, data) => { |
||||
if (err) { |
||||
console.log('Error', err); |
||||
reject(err); |
||||
} |
||||
if (data) { |
||||
resolve(data.Location); |
||||
} |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
// TODO - implement
|
||||
fileReadByStream(_key: string): Promise<Readable> { |
||||
return Promise.resolve(undefined); |
||||
} |
||||
|
||||
// TODO - implement
|
||||
getDirectoryList(_path: string): Promise<string[]> { |
||||
return Promise.resolve(undefined); |
||||
} |
||||
|
||||
public async fileDelete(_path: string): Promise<any> { |
||||
return Promise.resolve(undefined); |
||||
} |
||||
|
||||
public async fileRead(key: string): Promise<any> { |
||||
return new Promise((resolve, reject) => { |
||||
this.s3Client.getObject({ Key: key } as any, (err, data) => { |
||||
if (err) { |
||||
return reject(err); |
||||
} |
||||
if (!data?.Body) { |
||||
return reject(data); |
||||
} |
||||
return resolve(data.Body); |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
public async init(): Promise<any> { |
||||
const s3Options: any = { |
||||
params: { Bucket: this.input.bucket }, |
||||
const updatedEndpoint = this.input.endpoint.startsWith('https://') |
||||
? this.input.endpoint |
||||
: `https://${this.input.endpoint}`; |
||||
|
||||
const s3Options: S3ClientConfig = { |
||||
region: this.input.region, |
||||
credentials: { |
||||
accessKeyId: this.input.access_key, |
||||
secretAccessKey: this.input.access_secret, |
||||
}, |
||||
endpoint: updatedEndpoint, |
||||
}; |
||||
|
||||
s3Options.accessKeyId = this.input.access_key; |
||||
s3Options.secretAccessKey = this.input.access_secret; |
||||
|
||||
s3Options.endpoint = new AWS.Endpoint(this.input.endpoint); |
||||
|
||||
this.s3Client = new AWS.S3(s3Options); |
||||
} |
||||
|
||||
public async test(): Promise<boolean> { |
||||
try { |
||||
const tempFile = generateTempFilePath(); |
||||
const createStream = fs.createWriteStream(tempFile); |
||||
await waitForStreamClose(createStream); |
||||
await this.fileCreate('nc-test-file.txt', { |
||||
path: tempFile, |
||||
mimetype: 'text/plain', |
||||
originalname: 'temp.txt', |
||||
size: '', |
||||
}); |
||||
await promisify(fs.unlink)(tempFile); |
||||
return true; |
||||
} catch (e) { |
||||
throw e; |
||||
} |
||||
this.s3Client = new S3Client(s3Options); |
||||
} |
||||
} |
||||
|
@ -1,149 +1,41 @@
|
||||
import fs from 'fs'; |
||||
import { promisify } from 'util'; |
||||
import AWS from 'aws-sdk'; |
||||
import axios from 'axios'; |
||||
import { useAgent } from 'request-filtering-agent'; |
||||
import type { IStorageAdapterV2, XcFile } from 'nc-plugin'; |
||||
import type { Readable } from 'stream'; |
||||
import { generateTempFilePath, waitForStreamClose } from '~/utils/pluginUtils'; |
||||
import { S3 as S3Client } from '@aws-sdk/client-s3'; |
||||
import type { S3ClientConfig } from '@aws-sdk/client-s3'; |
||||
import type { IStorageAdapterV2 } from 'nc-plugin'; |
||||
import GenericS3 from '~/plugins/GenericS3/GenericS3'; |
||||
|
||||
export default class Vultr implements IStorageAdapterV2 { |
||||
private s3Client: AWS.S3; |
||||
private input: any; |
||||
|
||||
constructor(input: any) { |
||||
this.input = input; |
||||
interface VultrObjectStorageInput { |
||||
bucket: string; |
||||
region: string; |
||||
access_key: string; |
||||
hostname: string; |
||||
access_secret: string; |
||||
acl?: string; |
||||
} |
||||
|
||||
async fileCreate(key: string, file: XcFile): Promise<any> { |
||||
const fileStream = fs.createReadStream(file.path); |
||||
export default class Vultr extends GenericS3 implements IStorageAdapterV2 { |
||||
protected input: VultrObjectStorageInput; |
||||
|
||||
return this.fileCreateByStream(key, fileStream, { |
||||
mimetype: file?.mimetype, |
||||
}); |
||||
constructor(input: unknown) { |
||||
super(input as VultrObjectStorageInput); |
||||
} |
||||
|
||||
async fileCreateByUrl(key: string, url: string): Promise<any> { |
||||
const uploadParams: any = { |
||||
ACL: 'public-read', |
||||
protected get defaultParams() { |
||||
return { |
||||
Bucket: this.input.bucket, |
||||
ACL: this.input?.acl || 'public-read', |
||||
}; |
||||
return new Promise((resolve, reject) => { |
||||
axios |
||||
.get(url, { |
||||
httpAgent: useAgent(url, { stopPortScanningByUrlRedirection: true }), |
||||
httpsAgent: useAgent(url, { stopPortScanningByUrlRedirection: true }), |
||||
// TODO - use stream instead of buffer
|
||||
responseType: 'arraybuffer', |
||||
}) |
||||
.then((response) => { |
||||
uploadParams.Body = response.data; |
||||
uploadParams.Key = key; |
||||
uploadParams.ContentType = response.headers['content-type']; |
||||
|
||||
// call S3 to retrieve upload file to specified bucket
|
||||
this.s3Client.upload(uploadParams, (err1, data) => { |
||||
if (err1) { |
||||
console.log('Error', err1); |
||||
reject(err1); |
||||
} |
||||
if (data) { |
||||
resolve({ |
||||
url: data.Location, |
||||
data: response.data, |
||||
}); |
||||
} |
||||
}); |
||||
}) |
||||
.catch((error) => { |
||||
reject(error); |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
async fileCreateByStream( |
||||
key: string, |
||||
stream: Readable, |
||||
options?: { |
||||
mimetype: string; |
||||
}, |
||||
): Promise<void> { |
||||
const uploadParams: any = { |
||||
ACL: 'public-read', |
||||
Body: stream, |
||||
Key: key, |
||||
ContentType: options?.mimetype || 'application/octet-stream', |
||||
}; |
||||
return new Promise((resolve, reject) => { |
||||
// call S3 to retrieve upload file to specified bucket
|
||||
this.s3Client.upload(uploadParams, (err, data) => { |
||||
if (err) { |
||||
console.log('Error', err); |
||||
reject(err); |
||||
} |
||||
if (data) { |
||||
resolve(data.Location); |
||||
} |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
// TODO - implement
|
||||
fileReadByStream(_key: string): Promise<Readable> { |
||||
return Promise.resolve(undefined); |
||||
} |
||||
|
||||
// TODO - implement
|
||||
getDirectoryList(_path: string): Promise<string[]> { |
||||
return Promise.resolve(undefined); |
||||
} |
||||
|
||||
public async fileDelete(_path: string): Promise<any> { |
||||
return Promise.resolve(undefined); |
||||
} |
||||
|
||||
public async fileRead(key: string): Promise<any> { |
||||
return new Promise((resolve, reject) => { |
||||
this.s3Client.getObject({ Key: key } as any, (err, data) => { |
||||
if (err) { |
||||
return reject(err); |
||||
} |
||||
if (!data?.Body) { |
||||
return reject(data); |
||||
} |
||||
return resolve(data.Body); |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
public async init(): Promise<any> { |
||||
const s3Options: any = { |
||||
params: { Bucket: this.input.bucket }, |
||||
const s3Options: S3ClientConfig = { |
||||
region: this.input.region, |
||||
credentials: { |
||||
accessKeyId: this.input.access_key, |
||||
secretAccessKey: this.input.access_secret, |
||||
}, |
||||
endpoint: this.input.hostname, |
||||
}; |
||||
|
||||
s3Options.accessKeyId = this.input.access_key; |
||||
s3Options.secretAccessKey = this.input.access_secret; |
||||
|
||||
s3Options.endpoint = new AWS.Endpoint(this.input.hostname); |
||||
|
||||
this.s3Client = new AWS.S3(s3Options); |
||||
} |
||||
|
||||
public async test(): Promise<boolean> { |
||||
try { |
||||
const tempFile = generateTempFilePath(); |
||||
const createStream = fs.createWriteStream(tempFile); |
||||
await waitForStreamClose(createStream); |
||||
await this.fileCreate('nc-test-file.txt', { |
||||
path: tempFile, |
||||
mimetype: 'text/plain', |
||||
originalname: 'temp.txt', |
||||
size: '', |
||||
}); |
||||
await promisify(fs.unlink)(tempFile); |
||||
return true; |
||||
} catch (e) { |
||||
throw e; |
||||
} |
||||
this.s3Client = new S3Client(s3Options); |
||||
} |
||||
} |
||||
|
Loading…
Reference in new issue