diff --git a/src/core/Lifecycle.ts b/src/core/Lifecycle.ts index f823142..9366dd0 100644 --- a/src/core/Lifecycle.ts +++ b/src/core/Lifecycle.ts @@ -2,9 +2,10 @@ import { EventEmitter } from 'events' import { ILifecyclePlugins, IPicGo, IPlugin, Undefinable } from '../types' import { handleUrlEncode } from '../utils/common' import { IBuildInEvent } from '../utils/enum' +import { createContext } from '../utils/createContext' class Lifecycle extends EventEmitter { - private ctx: IPicGo + private readonly ctx: IPicGo constructor (ctx: IPicGo) { super() @@ -12,115 +13,117 @@ class Lifecycle extends EventEmitter { } async start (input: any[]): Promise { + // ensure every upload process has an unique context + const ctx = createContext(this.ctx) try { // images input if (!Array.isArray(input)) { throw new Error('Input must be an array.') } - this.ctx.input = input - this.ctx.output = [] + ctx.input = input + ctx.output = [] // lifecycle main - await this.beforeTransform() - await this.doTransform() - await this.beforeUpload() - await this.doUpload() - await this.afterUpload() - return this.ctx + await this.beforeTransform(ctx) + await this.doTransform(ctx) + await this.beforeUpload(ctx) + await this.doUpload(ctx) + await this.afterUpload(ctx) + return ctx } catch (e) { - this.ctx.log.warn('failed') - this.ctx.emit(IBuildInEvent.UPLOAD_PROGRESS, -1) - this.ctx.emit(IBuildInEvent.FAILED, e) - this.ctx.log.error(e) - if (this.ctx.getConfig>('debug')) { + ctx.log.warn('failed') + ctx.emit(IBuildInEvent.UPLOAD_PROGRESS, -1) + ctx.emit(IBuildInEvent.FAILED, e) + ctx.log.error(e) + if (ctx.getConfig>('debug')) { throw e } - return this.ctx + return ctx } } - private async beforeTransform (): Promise { - this.ctx.emit(IBuildInEvent.UPLOAD_PROGRESS, 0) - this.ctx.emit(IBuildInEvent.BEFORE_TRANSFORM, this.ctx) - this.ctx.log.info('Before transform') - await this.handlePlugins(this.ctx.helper.beforeTransformPlugins) - return this.ctx + private async beforeTransform (ctx: IPicGo): Promise { + ctx.emit(IBuildInEvent.UPLOAD_PROGRESS, 0) + ctx.emit(IBuildInEvent.BEFORE_TRANSFORM, ctx) + ctx.log.info('Before transform') + await this.handlePlugins(ctx.helper.beforeTransformPlugins, ctx) + return ctx } - private async doTransform (): Promise { - this.ctx.emit(IBuildInEvent.UPLOAD_PROGRESS, 30) - const type = this.ctx.getConfig>('picBed.transformer') || 'path' + private async doTransform (ctx: IPicGo): Promise { + ctx.emit(IBuildInEvent.UPLOAD_PROGRESS, 30) + const type = ctx.getConfig>('picBed.transformer') || 'path' let currentTransformer = type - let transformer = this.ctx.helper.transformer.get(type) + let transformer = ctx.helper.transformer.get(type) if (!transformer) { - transformer = this.ctx.helper.transformer.get('path') + transformer = ctx.helper.transformer.get('path') currentTransformer = 'path' - this.ctx.log.warn(`Can't find transformer - ${type}, switch to default transformer - path`) + ctx.log.warn(`Can't find transformer - ${type}, switch to default transformer - path`) } - this.ctx.log.info(`Transforming... Current transformer is [${currentTransformer}]`) - await transformer?.handle(this.ctx) - return this.ctx + ctx.log.info(`Transforming... Current transformer is [${currentTransformer}]`) + await transformer?.handle(ctx) + return ctx } - private async beforeUpload (): Promise { - this.ctx.emit(IBuildInEvent.UPLOAD_PROGRESS, 60) - this.ctx.log.info('Before upload') - this.ctx.emit(IBuildInEvent.BEFORE_UPLOAD, this.ctx) - await this.handlePlugins(this.ctx.helper.beforeUploadPlugins) - return this.ctx + private async beforeUpload (ctx: IPicGo): Promise { + ctx.emit(IBuildInEvent.UPLOAD_PROGRESS, 60) + ctx.log.info('Before upload') + ctx.emit(IBuildInEvent.BEFORE_UPLOAD, ctx) + await this.handlePlugins(ctx.helper.beforeUploadPlugins, ctx) + return ctx } - private async doUpload (): Promise { - let type = this.ctx.getConfig>('picBed.uploader') || this.ctx.getConfig>('picBed.current') || 'smms' - let uploader = this.ctx.helper.uploader.get(type) + private async doUpload (ctx: IPicGo): Promise { + let type = ctx.getConfig>('picBed.uploader') || ctx.getConfig>('picBed.current') || 'smms' + let uploader = ctx.helper.uploader.get(type) let currentTransformer = type if (!uploader) { type = 'smms' currentTransformer = 'smms' - uploader = this.ctx.helper.uploader.get('smms') - this.ctx.log.warn(`Can't find uploader - ${type}, switch to default uploader - smms`) + uploader = ctx.helper.uploader.get('smms') + ctx.log.warn(`Can't find uploader - ${type}, switch to default uploader - smms`) } - this.ctx.log.info(`Uploading... Current uploader is [${currentTransformer}]`) - await uploader?.handle(this.ctx) - for (const outputImg of this.ctx.output) { + ctx.log.info(`Uploading... Current uploader is [${currentTransformer}]`) + await uploader?.handle(ctx) + for (const outputImg of ctx.output) { outputImg.type = type } - return this.ctx + return ctx } - private async afterUpload (): Promise { - this.ctx.emit(IBuildInEvent.AFTER_UPLOAD, this.ctx) - this.ctx.emit(IBuildInEvent.UPLOAD_PROGRESS, 100) - await this.handlePlugins(this.ctx.helper.afterUploadPlugins) + private async afterUpload (ctx: IPicGo): Promise { + ctx.emit(IBuildInEvent.AFTER_UPLOAD, ctx) + ctx.emit(IBuildInEvent.UPLOAD_PROGRESS, 100) + await this.handlePlugins(ctx.helper.afterUploadPlugins, ctx) let msg = '' - const length = this.ctx.output.length + const length = ctx.output.length for (let i = 0; i < length; i++) { - msg += handleUrlEncode(this.ctx.output[i].imgUrl) + msg += handleUrlEncode(ctx.output[i].imgUrl) if (i !== length - 1) { msg += '\n' } - delete this.ctx.output[i].base64Image - delete this.ctx.output[i].buffer + delete ctx.output[i].base64Image + delete ctx.output[i].buffer } - this.ctx.emit(IBuildInEvent.FINISHED, this.ctx) - this.ctx.log.success(`\n${msg}`) - return this.ctx + ctx.emit(IBuildInEvent.FINISHED, ctx) + ctx.log.success(`\n${msg}`) + return ctx } - private async handlePlugins (lifeCyclePlugins: ILifecyclePlugins): Promise { + private async handlePlugins (lifeCyclePlugins: ILifecyclePlugins, ctx: IPicGo): Promise { const plugins = lifeCyclePlugins.getList() const pluginNames = lifeCyclePlugins.getIdList() const lifeCycleName = lifeCyclePlugins.getName() await Promise.all(plugins.map(async (plugin: IPlugin, index: number) => { try { - this.ctx.log.info(`${lifeCycleName}: ${pluginNames[index]} running`) - await plugin.handle(this.ctx) + ctx.log.info(`${lifeCycleName}: ${pluginNames[index]} running`) + await plugin.handle(ctx) } catch (e) { - this.ctx.log.error(`${lifeCycleName}: ${pluginNames[index]} error`) + ctx.log.error(`${lifeCycleName}: ${pluginNames[index]} error`) throw e } })) - return this.ctx + return ctx } } diff --git a/src/core/PicGo.ts b/src/core/PicGo.ts index 9880a06..8a1a315 100644 --- a/src/core/PicGo.ts +++ b/src/core/PicGo.ts @@ -115,6 +115,7 @@ class PicGo extends EventEmitter implements IPicGo { getConfig (name?: string): T { if (!name) { + console.log(this._config) return this._config as unknown as T } else { return get(this._config, name) diff --git a/src/utils/createContext.ts b/src/utils/createContext.ts new file mode 100644 index 0000000..f60ce88 --- /dev/null +++ b/src/utils/createContext.ts @@ -0,0 +1,44 @@ +import { IPicGo } from '../types' + +/** + * create an unique context for each upload process + * @param ctx + */ +export const createContext = (ctx: IPicGo): IPicGo => { + return { + configPath: ctx.configPath, + baseDir: ctx.baseDir, + log: ctx.log, + cmd: ctx.cmd, + output: [], + input: [], + pluginLoader: ctx.pluginLoader, + pluginHandler: ctx.pluginHandler, + Request: ctx.Request, + helper: ctx.helper, + VERSION: ctx.VERSION, + GUI_VERSION: ctx.GUI_VERSION, + request: ctx.request, + getConfig: ctx.getConfig.bind(ctx), + saveConfig: ctx.saveConfig.bind(ctx), + removeConfig: ctx.removeConfig.bind(ctx), + setConfig: ctx.setConfig.bind(ctx), + unsetConfig: ctx.unsetConfig.bind(ctx), + upload: ctx.upload.bind(ctx), + addListener: ctx.addListener.bind(ctx), + on: ctx.on.bind(ctx), + once: ctx.once.bind(ctx), + removeListener: ctx.removeListener.bind(ctx), + off: ctx.off.bind(ctx), + removeAllListeners: ctx.removeAllListeners.bind(ctx), + setMaxListeners: ctx.setMaxListeners.bind(ctx), + getMaxListeners: ctx.getMaxListeners.bind(ctx), + listeners: ctx.listeners.bind(ctx), + rawListeners: ctx.rawListeners.bind(ctx), + emit: ctx.emit.bind(ctx), + listenerCount: ctx.listenerCount.bind(ctx), + prependListener: ctx.prependListener.bind(ctx), + prependOnceListener: ctx.prependOnceListener.bind(ctx), + eventNames: ctx.eventNames.bind(ctx) + } +}