Setup eslint and enforce rules
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2021-06-02 22:36:25 -05:00
parent 82e7a1f299
commit 1d5056b753
149 changed files with 6104 additions and 3114 deletions

View File

@@ -1,10 +1,10 @@
import {UniversalPath} from "../path"
import * as path from "path"
import * as os from "os"
import {uuid_v4} from "../data"
import {UniversalPath} from '../path'
import * as path from 'path'
import * as os from 'os'
import {uuid4} from '../data'
import ReadableStream = NodeJS.ReadableStream;
import WritableStream = NodeJS.WritableStream;
import {ErrorWithContext} from "../../error/ErrorWithContext";
import {ErrorWithContext} from '../../error/ErrorWithContext'
/**
* Error thrown when an operation is attempted on a non-existent file.
@@ -77,12 +77,12 @@ export abstract class Filesystem {
/**
* Called when the Filesystem driver is initialized. Do any standup here.
*/
public open(): void | Promise<void> {}
public open(): void | Promise<void> {} // eslint-disable-line @typescript-eslint/no-empty-function
/**
* Called when the Filesystem driver is destroyed. Do any cleanup here.
*/
public close(): void | Promise<void> {}
public close(): void | Promise<void> {} // eslint-disable-line @typescript-eslint/no-empty-function
/**
* Get the URI prefix for this filesystem.
@@ -184,9 +184,13 @@ export abstract class Filesystem {
* @param tags
* @protected
*/
protected _normalizeTags(tag?: string, tags?: string[]): string[] {
if ( !tags ) tags = []
if ( tag ) tags.push(tag)
protected normalizeTags(tag?: string, tags?: string[]): string[] {
if ( !tags ) {
tags = []
}
if ( tag ) {
tags.push(tag)
}
return tags
}
@@ -195,6 +199,6 @@ export abstract class Filesystem {
* @protected
*/
protected tempName(): string {
return path.resolve(os.tmpdir(), uuid_v4())
return path.resolve(os.tmpdir(), uuid4())
}
}

View File

@@ -1,9 +1,9 @@
import {FileMetadata, FileNotFoundError, Filesystem, Stat} from "./Filesystem"
import * as fs from "fs"
import * as path from "path"
import {UniversalPath} from "../path"
import * as rimraf from "rimraf"
import * as mkdirp from "mkdirp"
import {FileMetadata, FileNotFoundError, Filesystem, Stat} from './Filesystem'
import * as fs from 'fs'
import * as path from 'path'
import {UniversalPath} from '../path'
import * as rimraf from 'rimraf'
import * as mkdirp from 'mkdirp'
export interface LocalFilesystemConfig {
baseDir: string
@@ -15,8 +15,10 @@ export interface LocalFilesystemConfig {
*/
export class LocalFilesystem extends Filesystem {
constructor(
protected readonly baseConfig: LocalFilesystemConfig
) { super() }
protected readonly baseConfig: LocalFilesystemConfig,
) {
super()
}
async open(): Promise<void> {
// Make sure the base directory exists
@@ -26,14 +28,14 @@ export class LocalFilesystem extends Filesystem {
}
public getPrefix(): string {
return 'local://'
return 'file://'
}
public async putLocalFile({localPath, storePath, ...args}: {localPath: string, storePath: string, mimeType?: string, tags?: string[], tag?: string}) {
public async putLocalFile({localPath, storePath, ...args}: {localPath: string, storePath: string, mimeType?: string, tags?: string[], tag?: string}): Promise<void> {
await fs.promises.copyFile(localPath, this.storePath(storePath))
await fs.promises.writeFile(this.metadataPath(storePath), JSON.stringify({
mimeType: args.mimeType,
tags: this._normalizeTags(args.tag, args.tags),
tags: this.normalizeTags(args.tag, args.tags),
}))
}
@@ -51,13 +53,13 @@ export class LocalFilesystem extends Filesystem {
return fs.createWriteStream(this.storePath(args.storePath))
}
public async getMetadata(storePath: string) {
public async getMetadata(storePath: string): Promise<FileMetadata> {
try {
const json = (await fs.promises.readFile(this.metadataPath(storePath))).toString('utf-8')
return JSON.parse(json)
} catch (e) {
return {
tags: []
tags: [],
}
}
}
@@ -81,7 +83,7 @@ export class LocalFilesystem extends Filesystem {
exists: true,
sizeInBytes: stat.size,
mimeType: meta.mimeType,
tags: meta.tags,
tags: meta.tags ?? [],
accessed: stat.atime,
modified: stat.mtime,
created: stat.ctime,
@@ -92,7 +94,7 @@ export class LocalFilesystem extends Filesystem {
path: new UniversalPath(args.storePath, this),
exists: false,
sizeInBytes: 0,
tags: []
tags: [],
}
}
@@ -107,9 +109,13 @@ export class LocalFilesystem extends Filesystem {
fs.utimes(storePath, time, time, err => {
if ( err ) {
fs.open(storePath, 'w', (err2, fd) => {
if ( err2 ) return rej(err2)
if ( err2 ) {
return rej(err2)
}
fs.close(fd, err3 => {
if ( err3 ) return rej(err3)
if ( err3 ) {
return rej(err3)
}
res()
})
})
@@ -127,9 +133,11 @@ export class LocalFilesystem extends Filesystem {
} else {
await new Promise<void>((res, rej) => {
rimraf(this.storePath(args.storePath), err => {
if ( err ) return rej(err)
else {
fs.promises.unlink(this.metadataPath(args.storePath)).then(() => res()).catch(rej)
if ( err ) {
return rej(err)
} else {
fs.promises.unlink(this.metadataPath(args.storePath)).then(() => res())
.catch(rej)
}
})
})

View File

@@ -1,19 +1,21 @@
import {FileMetadata, Filesystem, Stat} from "./Filesystem"
import * as ssh2 from "ssh2"
import * as path from "path"
import * as fs from "fs"
import {FileMetadata, Filesystem, Stat} from './Filesystem'
import * as ssh2 from 'ssh2'
import * as path from 'path'
import * as fs from 'fs'
import ReadableStream = NodeJS.ReadableStream
import {UniversalPath} from "../path"
import {UniversalPath} from '../path'
/**
* A Filesystem implementation that stores files on remote hosts via SFTP/SSH.
*/
export class SSHFilesystem extends Filesystem {
private _ssh?: ssh2.Client
private sshClient?: ssh2.Client
constructor(
protected readonly baseConfig: { ssh: ssh2.ConnectConfig, baseDir: string },
) { super() }
) {
super()
}
getPrefix(): string {
return `sftp+${this.baseConfig.ssh.host}://`
@@ -48,7 +50,7 @@ export class SSHFilesystem extends Filesystem {
const sftp = await this.getSFTP()
await sftp.writeFile(this.metadataPath(args.storePath), JSON.stringify({
mimeType: args.mimeType,
tags: this._normalizeTags(args.tag, args.tags)
tags: this.normalizeTags(args.tag, args.tags),
}))
// pipe the local file to the store
@@ -69,8 +71,11 @@ export class SSHFilesystem extends Filesystem {
const sftp = await this.getSFTP()
await new Promise<void>((res, rej) => {
sftp.mkdir(this.storePath(args.storePath), err => {
if ( err ) rej(err)
else res()
if ( err ) {
rej(err)
} else {
res()
}
})
})
}
@@ -80,11 +85,15 @@ export class SSHFilesystem extends Filesystem {
await new Promise<void>((res, rej) => {
sftp.unlink(this.storePath(args.storePath), err => {
if ( err ) return rej(err)
else {
if ( err ) {
return rej(err)
} else {
sftp.unlink(this.metadataPath(args.storePath), err2 => {
if ( err2 ) rej(err2)
else res()
if ( err2 ) {
rej(err2)
} else {
res()
}
})
}
})
@@ -96,9 +105,11 @@ export class SSHFilesystem extends Filesystem {
try {
const stat = await new Promise<any>((res, rej) => {
sftp.stat(this.storePath(args.storePath), (err, stat) => {
if ( err ) return rej(err)
res(stat)
sftp.stat(this.storePath(args.storePath), (err, sftpStats) => {
if ( err ) {
return rej(err)
}
res(sftpStats)
})
})
@@ -121,7 +132,7 @@ export class SSHFilesystem extends Filesystem {
path: new UniversalPath(args.storePath, this),
exists: false,
sizeInBytes: 0,
tags: []
tags: [],
}
}
}
@@ -135,9 +146,13 @@ export class SSHFilesystem extends Filesystem {
sftp.utimes(storePath, time, time, err => {
if ( err ) {
sftp.open(storePath, 'w', (err2, fd) => {
if ( err2 ) return rej(err2)
if ( err2 ) {
return rej(err2)
}
sftp.close(fd, err3 => {
if ( err3 ) return rej(err3)
if ( err3 ) {
return rej(err3)
}
res()
})
})
@@ -153,13 +168,15 @@ export class SSHFilesystem extends Filesystem {
const sftp = await this.getSFTP()
return new Promise((res, rej) => {
sftp.readFile(this.metadataPath(storePath), (err, buffer) => {
if ( err ) rej(err)
if ( err ) {
rej(err)
}
res(JSON.parse(buffer.toString('utf-8')))
})
})
} catch (e) {
return {
tags: []
tags: [],
}
}
}
@@ -169,14 +186,17 @@ export class SSHFilesystem extends Filesystem {
const metaPath = this.metadataPath(storePath)
await new Promise<void>((res, rej) => {
sftp.writeFile(metaPath, JSON.stringify(meta), err => {
if ( err ) rej(err)
else res()
if ( err ) {
rej(err)
} else {
res()
}
})
})
}
async close(): Promise<void> {
await this._ssh?.end()
await this.sshClient?.end()
}
/**
@@ -184,13 +204,15 @@ export class SSHFilesystem extends Filesystem {
* If a connection already exists, re-use it.
*/
async getSSH(): Promise<ssh2.Client> {
if ( this._ssh ) return this._ssh
if ( this.sshClient ) {
return this.sshClient
}
return new Promise((res, rej) => {
const client = new ssh2.Client()
client.on('ready', () => {
this._ssh = client
this.sshClient = client
res(client)
}).connect(this.baseConfig.ssh)
@@ -206,8 +228,11 @@ export class SSHFilesystem extends Filesystem {
return new Promise((res, rej) => {
ssh.sftp((err, sftp) => {
if ( err ) rej(err)
else res(sftp)
if ( err ) {
rej(err)
} else {
res(sftp)
}
})
})
}
@@ -236,7 +261,7 @@ export class SSHFilesystem extends Filesystem {
* @protected
*/
protected streamToString(stream: NodeJS.ReadableStream): Promise<string> {
const chunks: Buffer[] = [];
const chunks: Buffer[] = []
return new Promise((resolve, reject) => {
stream.on('data', (chunk) => chunks.push(Buffer.from(chunk)))
stream.on('error', (err) => reject(err))