lisonge / vite-plugin-monkey

A vite plugin server and build your.user.js for userscript engine like Tampermonkey, Violentmonkey, Greasemonkey, ScriptCat
MIT License
1.31k stars 70 forks source link

完善 GM API 类型 #96

Closed Sec-ant closed 1 year ago

Sec-ant commented 1 year ago

目前 GM_xmlhttpRequestonload 等回调函数中 response 的类型是 any,希望能直接利用 responseType 的值来限定 response 的类型,大概这个意思:

interface ResponseTypeMap {
  arraybuffer: ArrayBuffer;
  blob: Blob;
  json: object;
  stream: ReadableStream<Uint8Array>;
  document: Document;
  text: string;
}

export type ResponseType = keyof ResponseTypeMap;

/**
 * @see https://www.tampermonkey.net/documentation.php#GM_xmlhttpRequest
 * @see https://violentmonkey.github.io/api/gm/#gm_xmlhttprequest
 */
GM_xmlhttpRequest: <
  TContext = object,
  TResponseType extends ResponseType = "text"
>(
  details: XhrRequest<TContext, TResponseType>
) => AbortHandle;

export type XhrRequest<TContext, TResponseType extends ResponseType> = {
  /**
   * @tampermonkey arraybuffer, blob, json, stream
   * @violentmonkey arraybuffer, blob, json, text, document
   * @default 'text' // violentmonkey
   */
  responseType?: TResponseType;
  /** Callback to be executed if the request was loaded */
  onload?: RequestEventListener<TResponse<TContext, TResponseType>>;
};

type ResponseBase<TResponseType extends ResponseType> = {
  readonly responseHeaders: string;
  /**
   * Unsent = 0,
   * Opened = 1,
   * HeadersReceived = 2,
   * Loading = 3,
   * Done = 4
   */
  readonly readyState: 0 | 1 | 2 | 3 | 4;
  readonly response: ResponseTypeMap[TResponseType];
  readonly responseText: string;
  readonly responseXML: Document | null;
  readonly status: number;
  readonly statusText: string;
};

type TResponse<
  TContext,
  TResponseType extends ResponseType
> = ResponseBase<TResponseType> & {
  readonly finalUrl: string;
  readonly context: TContext;
};
Sec-ant commented 1 year ago

还有一点,Tampermonkey 加了 stream 类型的 responseType 后,作者提供了一种方法来判断 Gm_xmlhttpRequest 是否支持这种响应类型:

You can check streaming support this way:

console.log('streaming ' + (GM_xmlhttpRequest.RESPONSE_TYPE_STREAM === 'stream' ? 'supported' : 'not supported');

vite-plugin-monkey 提供的 responseType 类型中包含了 stream,所以能否也让类型支持 GM_xmlhttpRequest.RESPONSE_TYPE_STREAM

我不太确定这样实现是不是对的:

diff --git a/packages/vite-plugin-monkey/src/client/types/index.ts b/packages/vite-plugin-monkey/src/client/types/index.ts
index c90c953..442ac91 100644
--- a/packages/vite-plugin-monkey/src/client/types/index.ts
+++ b/packages/vite-plugin-monkey/src/client/types/index.ts
@@ -339,6 +339,14 @@ export type GmXhrRequest<TContext, TResponseType extends GmResponseType> = {
   onload?: GmRequestEventListener<GmResponseEvent<TContext, TResponseType>>;
 };

+declare function GmXhr<TContext, TResponseType extends GmResponseType = 'text'>(
+  details: GmXhrRequest<TContext, TResponseType>,
+): GmAbortHandle;
+
+declare namespace GmXhr {
+  export const RESPONSE_TYPE_STREAM: "stream" | undefined;
+}
+
 export type MonkeyWindow = typeof window & {
   unsafeWindow: typeof window;

@@ -589,9 +597,7 @@ export type MonkeyWindow = typeof window & {
    * @see https://www.tampermonkey.net/documentation.php#GM_xmlhttpRequest
    * @see https://violentmonkey.github.io/api/gm/#gm_xmlhttprequest
    */
-  GM_xmlhttpRequest: <TContext, TResponseType extends GmResponseType = 'text'>(
-    details: GmXhrRequest<TContext, TResponseType>,
-  ) => GmAbortHandle;
+  GM_xmlhttpRequest: typeof GmXhr

   /**
    * @see https://www.tampermonkey.net/documentation.php#GM_download
lisonge commented 1 year ago

released by v3.4.0