From 073f36dcd4121bd657eb5b1595f9b318fd938474 Mon Sep 17 00:00:00 2001 From: mdwriter-09idI Date: Fri, 14 Jul 2023 23:54:29 +0800 Subject: [PATCH] chore: minor --- src/preload/sdk/ali.ts | 123 --------------------------------------- src/preload/sdk/index.ts | 106 --------------------------------- src/preload/sdk/ssh.ts | 71 ---------------------- 3 files changed, 300 deletions(-) delete mode 100644 src/preload/sdk/ali.ts delete mode 100644 src/preload/sdk/index.ts delete mode 100644 src/preload/sdk/ssh.ts diff --git a/src/preload/sdk/ali.ts b/src/preload/sdk/ali.ts deleted file mode 100644 index 40f43f56..00000000 --- a/src/preload/sdk/ali.ts +++ /dev/null @@ -1,123 +0,0 @@ -import {createHmac} from 'crypto' -import got from 'got' -import {parseString} from 'xml2js' -import {createReadStream} from 'fs' -import {ServerSdk} from './index' -import mime from 'mime-types' -interface Config { - accessKeyId: string - accessKeySecret: string - region: string - bucket: string - domain: string -} -const toJson = (str: string) => new Promise((resolve, reject) => { - parseString(str, (err, result) => { - if (err) return reject(err) - resolve(result) - }) -}) - -const http = got.extend({ - hooks: { - afterResponse: [async response => { - if (response.headers['content-type'] === 'application/xml') { - response.body = await toJson(response.body as string) - } - return response - }], - beforeError: [async e => { - if (e.response && e.response.headers['content-type'] === 'application/xml') { - e.response.body = await toJson(e.response.body as string) - return e - } - return e - }] - } -}) -export class AliApi implements ServerSdk { - constructor( - private readonly config: Config - ) {} - - async connect() { - const header = this.getHeaders({ - method: 'GET', - bucket: this.config.bucket, - headers: {}, - object: 'index.html' - }) - const res = await http.get(`https://${this.config.bucket}.${this.config.region}.aliyuncs.com/index.html`, { - headers: header - }).catch(e => { - if (!e.response.body) throw new Error('链接失败,请检查链接参数') - return e.response?.body - }) - if (res?.Error?.Code?.[0] === 'SignatureDoesNotMatch') { - throw new Error('链接失败,请检查链接参数') - } - return res - } - - async removeFile(name: string) { - const header = this.getHeaders({ - method: 'DELETE', - bucket: this.config.bucket, - object: name - }) - return http.delete(`https://${this.config.bucket}.${this.config.region}.aliyuncs.com/${name}`, { - headers: header - }).catch(() => {}) - } - - uploadFile(name: string, filePath: string, contentType?: string) { - const header = this.getHeaders({ - method: 'PUT', - bucket: this.config.bucket, - headers: { - 'Content-Type': contentType || mime.lookup(filePath) || '' - }, - object: name - }) - return http.put(`https://${this.config.bucket}.${this.config.region}.aliyuncs.com/${name}`, { - headers: header, - body: createReadStream(filePath) - }) - } - - uploadFileByText(name: string, content: string): Promise { - const header = this.getHeaders({ - method: 'PUT', - bucket: this.config.bucket, - headers: { - 'Content-Type': mime.lookup(name) || '' - }, - object: name - }) - return http.put(`https://${this.config.bucket}.${this.config.region}.aliyuncs.com/${name}`, { - headers: header, - body: content - }) - } - - private getHeaders(options: { - headers?: Record, - method: 'PUT' | 'GET' | 'DELETE' | 'POST' | 'HEAD' - bucket?: string - object?: string - }) { - const date = (new Date).toUTCString() - const headers: any = { - Host: `${this.config.bucket}.${this.config.region}.aliyuncs.com`, - Date: date, - // 'Cache-Control': 'private', - ...options.headers - } - const ossHeaders = Object.keys(options.headers || {}).filter(key => key.startsWith('x-oss-')).sort().map(k => `${k}:${options.headers?.[k]}`).join('\n') - const sign = createHmac('sha1', this.config.accessKeySecret) - .update(`${options.method}\n\n${options.headers?.['Content-Type'] ?? ''}\n${date}\n${ossHeaders ? ossHeaders + '\n' : ''}/${options.bucket ?? ''}${options.bucket ? `/` : ''}${options.object ?? ''}`) - .digest().toString('base64') - headers['Authorization'] = `OSS ${this.config.accessKeyId}:${sign}` - return headers - } -} diff --git a/src/preload/sdk/index.ts b/src/preload/sdk/index.ts deleted file mode 100644 index 8b4675a2..00000000 --- a/src/preload/sdk/index.ts +++ /dev/null @@ -1,106 +0,0 @@ -import {ipcRenderer, app} from 'electron' -import {AliApi} from './ali' -import {readdirSync, readFileSync} from 'fs' -import {join} from 'path' -import {SshApi} from './ssh' -import {of} from 'rxjs' -export abstract class ServerSdk { - abstract connect(): Promise - abstract getSdk?(): Promise - abstract uploadFile(name: string, filePath: string, contentType?: string): Promise - abstract removeFile(name: string): Promise - abstract dispose?(): any - abstract uploadFileByText(name: string, content: string): Promise -} -export class Sdk implements ServerSdk { - targetSdk!: ServerSdk - private async getConfig() { - return ipcRenderer.invoke('getServerConfig') - } - private async uploadMultiple(files: {name: string, filePath: string, contentType?: string}[]) { - let offset = 0 - let stack = files.slice(offset, offset + 5) - while (stack.length) { - await Promise.all(stack.map(f => this.uploadFile(f.name, f.filePath, f.contentType))) - offset += 5 - stack = files.slice(offset, offset + 5) - } - } - async getSdk() { - if (this.targetSdk) return - const config = await this.getConfig() - switch (config.server) { - case 'ali': - this.targetSdk = new AliApi(config) - break - case 'ssh': - this.targetSdk = new SshApi(config) - break - } - } - async connect(): Promise { - await this.getSdk() - return this.targetSdk.connect() - } - - async uploadFileByText(name, content) { - await this.getSdk() - return this.targetSdk.uploadFileByText(name, content) - } - async getWebPath():Promise<{webPath: string, isPackaged: boolean}> { - return ipcRenderer.invoke('get-env') - } - async reset() { - await this.getSdk() - const env = await this.getWebPath() - const filesName = readdirSync(join(env.webPath, 'lib')) - const files:{name: string, filePath: string, contentType?: string}[] = [ - {name: 'index.html', filePath: join(env.webPath, 'index.html')} - ] - files.push(...filesName.map(n => { - return {name: `lib/${n}`, filePath: join(env.webPath, 'lib', n)} - })) - - await this.uploadMultiple(files) - this.targetSdk.dispose?.() - } - async initial() { - await this.getSdk() - const env = await this.getWebPath() - const shikiPath = env.isPackaged ? join(env.webPath, 'shiki') : join(env.webPath, '../node_modules/shiki') - const languages = readdirSync(join(shikiPath, 'languages')) - const themes = readdirSync(join(shikiPath, 'themes')) - const filesName = readdirSync(join(env.webPath, 'lib')) - const files:{name: string, filePath: string, contentType?: string}[] = [ - {name: 'index.html', filePath: join(env.webPath, 'index.html')}, - {name: 'icon.png', filePath: join(env.webPath, 'icon.png')}, - {name: 'lib/shiki/onig.wasm', filePath: join(shikiPath, 'dist/onig.wasm'), contentType: 'application/wasm'}, - ] - - files.push(...filesName.map(n => { - return {name: `lib/${n}`, filePath: join(env.webPath, 'lib', n)} - })) - - files.push(...languages.map(l => { - return {name: `lib/shiki/languages/${l}`, filePath: join(shikiPath, `languages/${l}`), contentType: 'application/json'} - })) - files.push(...themes.map(l => { - return {name: `lib/shiki/themes/${l}`, filePath: join(shikiPath, `themes/${l}`), contentType: 'application/json'} - })) - await this.uploadMultiple(files) - this.targetSdk.dispose?.() - } - async uploadFile(name, filePath, contentType?) { - await this.getSdk() - return this.targetSdk.uploadFile(name, filePath, contentType) - } - - dispose() { - if (this.targetSdk) this.targetSdk.dispose?.() - } - - async removeFile(name: string): Promise { - await this.getSdk() - return this.targetSdk.removeFile(name) - } -} diff --git a/src/preload/sdk/ssh.ts b/src/preload/sdk/ssh.ts deleted file mode 100644 index a29575d2..00000000 --- a/src/preload/sdk/ssh.ts +++ /dev/null @@ -1,71 +0,0 @@ -import {NodeSSH} from 'node-ssh' -import {ServerSdk} from './index' -import {join, sep} from 'path' -import {SFTPWrapper} from 'ssh2' - -const ssh = new NodeSSH() - -interface Config { - host: string - username: string - password: string - target: string - domain: string - port?: number -} -export class SshApi implements ServerSdk { - ssh: NodeSSH | null = null - constructor( - private readonly config: Config - ) {} - - async connect() { - this.ssh = await ssh.connect({ - host: this.config.host, - username: this.config.username, - password: this.config.password, - port: this.config.port - }) - return this.ssh - } - - async uploadFile(name: string, filePath: string, contentType?: string): Promise { - if (!this.ssh) this.ssh = await this.connect() - await this.ssh!.putFile(filePath, join(this.config.target, name)) - } - async removeFile(name: string): Promise { - if (!this.ssh) this.ssh = await this.connect() - await this.ssh!.execCommand(`rm -rf ${join(this.config.target, name)}`) - } - - dispose() { - if (this.ssh) { - this.ssh.dispose() - this.ssh = null - } - } - private remoteExists(sftp: SFTPWrapper, filePath: string) { - return new Promise((resolve, reject) => { - sftp.exists(filePath, (res) => { - resolve(res) - }) - }) - } - async uploadFileByText(name, content) { - if (!this.ssh) this.ssh = await this.connect() - const dir = name.split(sep).slice(0, -1).join(sep) - return this.ssh.withSFTP(async sftp => { - return new Promise(async (resolve, reject) => { - const exist = await this.remoteExists(sftp, join(this.config.target, dir)) - if (!exist) await this.ssh!.mkdir(join(this.config.target, dir)) - sftp.writeFile(join(this.config.target, name), content, res => { - if (res instanceof Error) { - reject(res) - } else { - resolve() - } - }) - }) - }) - } -}