-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
296 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { DataDriveConfig } from '@ioc:DataDrive'; | ||
|
||
const dataDriveConfig: DataDriveConfig = { | ||
drives: { | ||
local: { | ||
// Disk refers to an existing disk in Drive's config. | ||
disk: 'local', | ||
// All files will be placed in a location under the prefix. | ||
// prefix must contain two parts separated by a slash. | ||
prefix: 'my/prefix', | ||
}, | ||
}, | ||
}; | ||
|
||
export default dataDriveConfig; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { IocContract } from '@adonisjs/fold'; | ||
|
||
import { DataDriveManager } from '../src/DataDriveManager'; | ||
|
||
export default class DataDriveProvider { | ||
private $container: IocContract; | ||
|
||
public constructor(container: IocContract) { | ||
this.$container = container; | ||
} | ||
|
||
public register(): void { | ||
this.$container.singleton('DataDrive', () => { | ||
const Drive = this.$container.use('Drive'); | ||
const config = this.$container.use('Adonis/Core/Config').get('datadrive'); | ||
return new DataDriveManager(Drive, config); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import { extname } from 'path'; | ||
import { Readable } from 'stream'; | ||
|
||
import { Storage, SignedUrlOptions, StatResponse } from '@slynova/flydrive'; | ||
import { v4 as uuidV4 } from 'uuid'; | ||
|
||
import { | ||
DataDriveFile, | ||
DataDriveFileWithSize, | ||
GraphqlUpload, | ||
} from '@ioc:DataDrive'; | ||
|
||
const goodPrefix = /^[a-zA-Z0-9-]+$/; | ||
|
||
export class DataDrive { | ||
private prefix: string; | ||
private disk: Storage; | ||
|
||
public constructor(prefix: string, disk: Storage) { | ||
if (typeof prefix !== 'string') { | ||
throw new TypeError('prefix must be a string'); | ||
} | ||
const splitted = prefix.split('/'); | ||
if (splitted.length !== 2 || splitted[0] === '' || splitted[0] === '') { | ||
throw new TypeError('prefix must have two parts separated by a slash'); | ||
} | ||
if (!goodPrefix.test(splitted[0]) || !goodPrefix.test(splitted[1])) { | ||
throw new Error(`bad prefix: ${prefix}`); | ||
} | ||
this.prefix = prefix; | ||
this.disk = disk; | ||
} | ||
|
||
private _destPath(file: DataDriveFile): string { | ||
return `${this.prefix}/${file.id.substring(0, 2)}/${file.id.substring( | ||
2, | ||
4, | ||
)}/${file.id + extname(file.filename)}`; | ||
} | ||
|
||
public async copy( | ||
src: DataDriveFile, | ||
dest: string, | ||
): Promise<DataDriveFileWithSize> { | ||
const id = uuidV4(); | ||
const destPath = this._destPath({ id, filename: dest }); | ||
await this.disk.copy(this._destPath(src), destPath, {}); | ||
const { size } = await this.disk.getStat(destPath); | ||
return { id, filename: dest, size }; | ||
} | ||
|
||
public async delete(file: DataDriveFile): Promise<void> { | ||
await this.disk.delete(this._destPath(file)); | ||
} | ||
|
||
public async get(file: DataDriveFile, encoding?: string): Promise<string> { | ||
const result = await this.disk.get(this._destPath(file), encoding); | ||
return result.content; | ||
} | ||
|
||
public async getBuffer(file: DataDriveFile): Promise<Buffer> { | ||
const result = await this.disk.getBuffer(this._destPath(file)); | ||
return result.content; | ||
} | ||
|
||
public async getSignedUrl( | ||
file: DataDriveFile, | ||
options?: SignedUrlOptions, | ||
): Promise<string> { | ||
const result = await this.disk.getSignedUrl(this._destPath(file), options); | ||
return result.signedUrl; | ||
} | ||
|
||
public async getStat(file: DataDriveFile): Promise<StatResponse> { | ||
return this.disk.getStat(this._destPath(file)); | ||
} | ||
|
||
public getStream(file: DataDriveFile): Readable { | ||
return this.disk.getStream(this._destPath(file)); | ||
} | ||
|
||
public async put( | ||
filename: string, | ||
content: Buffer | Readable | string, | ||
): Promise<DataDriveFileWithSize> { | ||
const id = uuidV4(); | ||
const destPath = this._destPath({ id, filename }); | ||
await this.disk.put(destPath, content); | ||
const { size } = await this.disk.getStat(destPath); | ||
return { | ||
id, | ||
filename, | ||
size, | ||
}; | ||
} | ||
|
||
public async storeGraphQLUpload( | ||
upload: Promise<GraphqlUpload>, | ||
): Promise<DataDriveFileWithSize> { | ||
const pdf = await upload; | ||
const id = uuidV4(); | ||
const { createReadStream, filename } = pdf; | ||
const destPath = this._destPath({ id, filename }); | ||
await this.disk.put(destPath, createReadStream()); | ||
const { size } = await this.disk.getStat(destPath); | ||
return { | ||
id, | ||
filename, | ||
size, | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { DataDrive } from './DataDrive'; | ||
|
||
import AdonisDrive from '@ioc:Drive'; | ||
import { DataDriveConfig } from '@ioc:DataDrive'; | ||
|
||
export class DataDriveManager { | ||
private $drives: Record<string, DataDrive>; | ||
|
||
public drive(name: string): DataDrive { | ||
if (this.$drives[name]) { | ||
return this.$drives[name]; | ||
} else { | ||
throw new Error(`unknown drive: ${name}`); | ||
} | ||
} | ||
|
||
public constructor(Drive: typeof AdonisDrive, config: DataDriveConfig) { | ||
this.$drives = {}; | ||
for (const name in config.drives) { | ||
const conf = config.drives[name]; | ||
this.$drives[name] = new DataDrive(conf.prefix, Drive.disk(conf.disk)); | ||
} | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
declare module '@ioc:DataDrive' { | ||
import { Readable } from 'stream'; | ||
|
||
import { | ||
Storage, | ||
Response, | ||
ContentResponse, | ||
SignedUrlOptions, | ||
SignedUrlResponse, | ||
StatResponse, | ||
} from '@slynova/flydrive'; | ||
|
||
import Drive from '@ioc:Drive'; | ||
|
||
export interface GraphqlUpload { | ||
filename: string; | ||
mimetype: string; | ||
encoding: string; | ||
createReadStream: () => Readable; | ||
} | ||
|
||
export interface DataDriveConfig { | ||
drives: { | ||
[key: string]: { | ||
/** | ||
* Name of the disk from adonis-drive to use. | ||
*/ | ||
disk: string; | ||
/** | ||
* All files will be placed in a location under the `prefix`. | ||
* `prefix` must contain two parts separated by a slash. | ||
*/ | ||
prefix: string; | ||
}; | ||
}; | ||
} | ||
|
||
export interface DataDriveFile { | ||
id: string; | ||
filename: string; | ||
} | ||
|
||
export interface DataDriveFileWithSize extends DataDriveFile { | ||
size: number; | ||
} | ||
|
||
export class DataDrive { | ||
public copy( | ||
src: DataDriveFile, | ||
dest: string, | ||
): Promise<DataDriveFileWithSize>; | ||
public delete(file: DataDriveFile): Promise<void>; | ||
public get(file: DataDriveFile, encoding?: string): Promise<string>; | ||
public getBuffer(file: DataDriveFile): Promise<Buffer>; | ||
public getSignedUrl( | ||
file: DataDriveFile, | ||
options?: SignedUrlOptions, | ||
): Promise<string>; | ||
public getStat(file: DataDriveFile): Promise<StatResponse>; | ||
public getStream(file: DataDriveFile): Readable; | ||
public put( | ||
filename: string, | ||
content: Buffer | Readable | string, | ||
): Promise<DataDriveFileWithSize>; | ||
public storeGraphQLUpload( | ||
upload: Promise<GraphqlUpload>, | ||
): Promise<DataDriveFileWithSize>; | ||
} | ||
|
||
class DataDriveManager { | ||
public drive(name: string): DataDrive; | ||
} | ||
|
||
const dataDriveManager: DataDriveManager; | ||
export default dataDriveManager; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters