diff --git a/libs/Universal-PicGo-Core/src/core/UniversalPicGo.ts b/libs/Universal-PicGo-Core/src/core/UniversalPicGo.ts
index f868dd6..98c9648 100644
--- a/libs/Universal-PicGo-Core/src/core/UniversalPicGo.ts
+++ b/libs/Universal-PicGo-Core/src/core/UniversalPicGo.ts
@@ -17,6 +17,7 @@ import {
IPicGo,
IPicGoPlugin,
IPicGoPluginInterface,
+ IPicGoRequest,
IPluginLoader,
IStringKeyMap,
} from "../types"
@@ -36,6 +37,7 @@ import { I18nManager } from "../i18n"
import { browserPathJoin, getBrowserDirectoryPath } from "../utils/browserUtils"
import { isConfigKeyInBlackList, isInputConfigValid } from "../utils/common"
import { eventBus } from "../utils/eventBus"
+import { PicGoRequest } from "../lib/PicGoRequest"
/*
* 通用 PicGO 对象定义
@@ -56,6 +58,7 @@ class UniversalPicGo extends EventEmitter implements IPicGo {
output: IImgInfo[]
input: any[]
pluginHandler: PluginHandler
+ request: IPicGoRequest
i18n!: II18nManager
VERSION: string = process.env.PICGO_VERSION ?? "unknown"
private readonly isDev: boolean
@@ -87,6 +90,7 @@ class UniversalPicGo extends EventEmitter implements IPicGo {
this.initConfigPath()
// this.cmd = new Commander(this)
this.pluginHandler = new PluginHandler(this)
+ this.request = PicGoRequest
this.initConfig()
this.init()
diff --git a/libs/Universal-PicGo-Core/src/lib/PicGoRequest.ts b/libs/Universal-PicGo-Core/src/lib/PicGoRequest.ts
new file mode 100644
index 0000000..e118cc2
--- /dev/null
+++ b/libs/Universal-PicGo-Core/src/lib/PicGoRequest.ts
@@ -0,0 +1,25 @@
+/*
+ * GNU GENERAL PUBLIC LICENSE
+ * Version 3, 29 June 2007
+ *
+ * Copyright (C) 2022-2024 Terwer, Inc.
+ * Everyone is permitted to copy and distribute verbatim copies
+ * of this license document, but changing it is not allowed.
+ *
+ */
+
+import { AxiosRequestConfig } from "axios"
+import { IResponse } from "../types"
+
+// #64 dynamic get proxy value
+/**
+ * PicGo 统一请求封装,基于 axios
+ *
+ * @param options
+ * @constructor
+ */
+function PicGoRequest(options: U): Promise> {
+ throw new Error("PicGoRequest is not implemented")
+}
+
+export { PicGoRequest }
diff --git a/libs/Universal-PicGo-Core/src/plugins/uploader/smms.ts b/libs/Universal-PicGo-Core/src/plugins/uploader/smms.ts
index 5fb2e42..83c1bc9 100644
--- a/libs/Universal-PicGo-Core/src/plugins/uploader/smms.ts
+++ b/libs/Universal-PicGo-Core/src/plugins/uploader/smms.ts
@@ -10,26 +10,25 @@
import { ILocalesKey } from "../../i18n/zh-CN"
import { IPicGo, IPluginConfig, ISmmsConfig } from "../../types"
import { IBuildInEvent } from "../../utils/enums"
+import { AxiosRequestConfig } from "axios"
-const postOptions = (fileName: string, image: Buffer, apiToken: string, backupDomain = ""): IOldReqOptions => {
+const postOptions = (fileName: string, image: Buffer, apiToken: string, backupDomain = ""): AxiosRequestConfig => {
const domain = backupDomain || "sm.ms"
+
+ const formData = new FormData()
+ formData.append("smfile", new Blob([image], { type: "image/png" }), fileName)
+ formData.append("ssl", "true")
+
return {
method: "POST",
url: `https://${domain}/api/v2/upload`,
headers: {
- contentType: "multipart/form-data",
+ "Content-Type": "multipart/form-data",
"User-Agent": "PicGo",
Authorization: apiToken,
},
- formData: {
- smfile: {
- value: image,
- options: {
- filename: fileName,
- },
- },
- ssl: "true",
- },
+ data: formData,
+ responseType: "json",
}
}
diff --git a/libs/Universal-PicGo-Core/src/types/index.d.ts b/libs/Universal-PicGo-Core/src/types/index.d.ts
index 7c8bd0b..fd71452 100644
--- a/libs/Universal-PicGo-Core/src/types/index.d.ts
+++ b/libs/Universal-PicGo-Core/src/types/index.d.ts
@@ -10,6 +10,7 @@
import { EventEmitter, Buffer } from "../utils/nodePolyfill"
import { ILogger } from "zhi-lib-base"
+import {AxiosRequestConfig} from "axios";
export interface IPicGo extends EventEmitter {
/**
@@ -46,6 +47,10 @@ export interface IPicGo extends EventEmitter {
* install\uninstall\update picgo's plugin via npm
*/
pluginHandler: IPluginHandler
+ /**
+ * request based on axios
+ */
+ request: IPicGoRequest
/**
* plugin system core part transformer\uploader\beforeTransformPlugins...
*/
@@ -454,3 +459,59 @@ export interface IImgSize {
export interface IPathTransformedImgInfo extends IImgInfo {
success: boolean
}
+
+// =====================================================================================================================
+// request start
+
+export type IPicGoRequest = (config: U) => Promise>
+
+/**
+ * for PicGo new request api, the response will be json format
+ */
+export type IReqOptions = AxiosRequestConfig & {
+ resolveWithFullResponse: true
+}
+
+/**
+ * for PicGo new request api, the response will be Buffer
+ */
+export type IReqOptionsWithArrayBufferRes = IReqOptions & {
+ responseType: 'arraybuffer'
+}
+
+/**
+ * for PicGo new request api, the response will be just response data. (not statusCode, headers, etc.)
+ */
+export type IReqOptionsWithBodyResOnly = AxiosRequestConfig
+
+export type IFullResponse = AxiosResponse & {
+ statusCode: number
+ body: T
+}
+
+type AxiosResponse = import('axios').AxiosResponse
+
+type AxiosRequestConfig = import('axios').AxiosRequestConfig
+
+interface IRequestOptionsWithFullResponse {
+ resolveWithFullResponse: true
+}
+
+interface IRequestOptionsWithJSON {
+ json: true
+}
+
+interface IRequestOptionsWithResponseTypeArrayBuffer {
+ responseType: 'arraybuffer'
+}
+
+/**
+ * T is the response data type
+ * U is the config type
+ */
+export type IResponse = U extends IRequestOptionsWithFullResponse ? IFullResponse
+ : U extends IRequestOptionsWithJSON ? T
+ : U extends IRequestOptionsWithResponseTypeArrayBuffer ? Buffer
+ : U extends IReqOptionsWithBodyResOnly ? T
+ : string
+// request end
\ No newline at end of file
diff --git a/libs/Universal-PicGo-Core/src/utils/common.ts b/libs/Universal-PicGo-Core/src/utils/common.ts
index f6f569a..2722b48 100644
--- a/libs/Universal-PicGo-Core/src/utils/common.ts
+++ b/libs/Universal-PicGo-Core/src/utils/common.ts
@@ -50,63 +50,67 @@ export const getFSFile = async (filePath: string): Promise => {
url = handleUrlEncode(url)
- const isImage = false
- const extname = ""
+ let isImage = false
+ let extname = ""
let timeoutId: any
- throw new Error("getURLFile is not implemented")
- // const requestFn = new Promise((resolve, reject) => {
- // ;(async () => {
- // try {
- // const res = await ctx
- // .request({
- // method: "get",
- // url,
- // resolveWithFullResponse: true,
- // responseType: "arraybuffer",
- // })
- // .then((resp: any) => {
- // const contentType = resp.headers["content-type"]
- // if (contentType?.includes("image")) {
- // isImage = true
- // extname = `.${contentType.split("image/")[1]}`
- // }
- // return resp.data as Buffer
- // })
- // clearTimeout(timeoutId)
- // if (isImage) {
- // const urlPath = new URL(url).pathname
- // resolve({
- // buffer: res,
- // fileName: path.basename(urlPath),
- // extname,
- // success: true,
- // })
- // } else {
- // resolve({
- // success: false,
- // reason: `${url} is not image`,
- // })
- // }
- // } catch (error: any) {
- // clearTimeout(timeoutId)
- // resolve({
- // success: false,
- // // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
- // reason: `request ${url} error, ${error?.message ?? ""}`,
- // })
- // }
- // })().catch(reject)
- // })
- // const timeoutPromise = new Promise((resolve): void => {
- // timeoutId = setTimeout(() => {
- // resolve({
- // success: false,
- // reason: `request ${url} timeout`,
- // })
- // }, 10000)
- // })
- // return Promise.race([requestFn, timeoutPromise])
+ const requestFn = new Promise((resolve, reject) => {
+ ;(async () => {
+ try {
+ const res = await ctx
+ .request({
+ method: "get",
+ url,
+ resolveWithFullResponse: true,
+ responseType: "arraybuffer",
+ })
+ .then((resp: any) => {
+ const contentType = resp.headers["content-type"]
+ if (contentType?.includes("image")) {
+ isImage = true
+ extname = `.${contentType.split("image/")[1]}`
+ }
+ return resp.data as Buffer
+ })
+ clearTimeout(timeoutId)
+ if (isImage) {
+ const urlPath = new URL(url).pathname
+ const fileName = urlPath.split("/").pop()
+ // if (hasNodeEnv) {
+ // const path = win.require("path")
+ // fileName = path.basename(urlPath)
+ // }
+ resolve({
+ buffer: res,
+ fileName: fileName,
+ extname,
+ success: true,
+ })
+ } else {
+ resolve({
+ success: false,
+ reason: `${url} is not image`,
+ })
+ }
+ } catch (error: any) {
+ clearTimeout(timeoutId)
+ resolve({
+ success: false,
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+ reason: `request ${url} error, ${error?.message ?? ""}`,
+ })
+ }
+ })().catch(reject)
+ })
+ const timeoutPromise = new Promise((resolve): void => {
+ timeoutId = setTimeout(() => {
+ resolve({
+ success: false,
+ reason: `request ${url} timeout`,
+ })
+ }, 10000)
+ })
+ return Promise.race([requestFn, timeoutPromise])
}
/**