🤖 Merge PR #62153 [FireMonkey] Add types for non-npm package by @DrakeTDL

* [FireMonkey] Add types for non-npm package

* FIX: Index.d.ts

* Fix: Changed FetchResponse json from JSON to any
This commit is contained in:
everyone
2022-09-09 23:24:27 -07:00
committed by GitHub
parent b233e4da46
commit 2ec14292a7
4 changed files with 803 additions and 0 deletions

View File

@@ -0,0 +1,328 @@
// unsafeWindow
const title: string = unsafeWindow.document.title;
//#region Async APIs
async () => {
const download = await GM.download('http://example.com');
const downloadFilename = await GM_download('http://example.com', 'download.html');
await GM.setValue('a', 'foobar');
await GM.setValue('b', 123);
await GM.setValue('c', true);
await GM.setValue('d', { key: 'value' });
// @ts-expect-error
await GM.setValue('d', null);
await GM.setValue('x', new Date());
const a: string = await GM.getValue('a', 'foobar');
const b: number = await GM.getValue('b', 123);
// @ts-expect-error
const x: string = GM.getValue('x', 123);
// @ts-expect-error
const c: boolean = await GM.getValue('c');
const d: object = await GM.getValue('d', { key: 'value' });
const e = (await GM.getValue('e')) as string;
const f = (await GM.getValue('f')) as number;
const g = (await GM.getValue('g')) as boolean;
const h = (await GM.getValue('h')) as object;
const i: string | number | boolean | object | undefined = await GM.getValue('i');
await GM.listValues().then(values =>
values.forEach(async (name: string) => {
console.log(name + ':', await GM.getValue(name));
}),
);
await GM.deleteValue('d').then(() => {
console.log('Success');
});
await GM.getResourceUrl('some_res').then(url => {
console.log('Resource url:', url);
});
await GM.getResourceText('some_res').then(text => {
console.log('Resource text:', text);
});
await GM.notification('A new widget is available at the frobber.');
await GM.notification({
text: 'A new widget is available at the frobber.',
image: 'https://wiki.greasespot.net/images/f/f3/Book.png',
});
await GM.openInTab('https://erosman.github.io/support/content/help.html#openInTab');
await GM.openInTab('https://erosman.github.io/support/content/help.html#openInTab', true);
await GM.setClipboard('Text to clipboard');
await GM.fetch('https://example.com').then(response => alert(response.text));
await GM.fetch('https://example.com', {
method: 'GET',
headers: { 'User-Agent': 'Mozilla/5.0', Accept: 'text/xml' },
}).then(res => console.log([res.status, res.statusText, res.ok, res.headers, res.url, res.text].join('\n')));
await GM.fetch('http://example.net/login', {
method: 'POST',
body: new URLSearchParams('username=johndoe&password=xyz123'),
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
}).then(res => {
location.href = 'http://www.example.net/dashboard';
});
const res = await GM.fetch('https://example.com', { method: 'HEAD' });
console.log(res.text);
await GM.fetch('https://example.com', {
anonymous: false,
body: 'asd',
cache: 'default',
credentials: 'omit',
headers: { 'User-Agent': 'FireMonkey' },
integrity: 'md5-123456==',
keepalive: true,
method: 'TRACE',
mode: 'cors',
redirect: 'error',
referrer: 'client',
referrerPolicy: 'no-referrer-when-downgrade',
responseType: 'json',
signal: '',
});
};
//#endregion
//#region Callback APIs
GM.addValueChangeListener('test-key1', (...arg) => {
console.log(...arg);
});
GM_addValueChangeListener('test-key2', (key, oldValue, newValue, remote) => {
console.log(key, oldValue, newValue, remote);
});
GM.registerMenuCommand('Do the thing', () => {});
GM_registerMenuCommand('Do thee thing', () => {});
// Bare Minimum
GM.xmlHttpRequest({
method: 'GET',
url: 'http://www.example.com/',
onload(response) {
alert(response.responseText);
},
});
// GET request
GM.xmlHttpRequest({
method: 'GET',
url: 'http://www.example.net/',
headers: {
'User-Agent': 'Mozilla/5.0',
Accept: 'text/xml',
},
onload(response) {
let responseXML = null;
if (!response.responseXML) {
responseXML = new DOMParser().parseFromString(response.responseText, 'text/xml');
}
console.log(
[
response.status,
response.statusText,
response.readyState,
response.responseHeaders,
response.responseText,
response.finalUrl,
responseXML,
].join('\n'),
);
},
});
// POST request
GM.xmlHttpRequest({
method: 'POST',
url: 'http://www.example.net/login',
data: 'username=johndoe&password=xyz123',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
onload(response) {
if (response.responseText.indexOf('Logged in as') > -1) {
location.href = 'http://www.example.net/dashboard';
}
},
});
// HEAD request
GM.xmlHttpRequest({
url: 'http://www.example.com',
method: 'HEAD',
onload(response) {
console.log(response.responseHeaders);
},
});
interface MyRequestContext {
userId: string;
}
// All options
GM.xmlHttpRequest({
data: 'foo=1&bar=2',
headers: { 'User-Agent': 'greasemonkey' },
method: 'POST',
onabort: (response: GM.XMLResponse<MyRequestContext>) => {},
onerror: (response: GM.XMLResponse<MyRequestContext>) => {},
onload: (response: GM.XMLResponse<MyRequestContext>) => {},
ontimeout: (response: GM.XMLResponse<MyRequestContext>) => {},
overrideMimeType: 'text/plain',
password: 'abc123',
responseType: 'arraybuffer',
timeout: 10,
url: 'http://example.com/',
user: 'guest',
});
// Response
GM.xmlHttpRequest({
method: 'GET',
url: 'http://example.com/',
onload: (response: GM.XMLResponse<MyRequestContext>) => {
const readyState: number = response.readyState;
const responseHeaders: string = response.responseHeaders;
const responseText: string = response.responseText;
const status: number = response.status;
const statusText: string = response.statusText;
const finalUrl: string = response.finalUrl;
},
});
//#endregion
//#region Sync APIs
GM_setValue('a', 'foobar');
GM_setValue('b', 123);
GM_setValue('c', true);
GM_setValue('d', { key: 'value' });
// @ts-expect-error
GM_setValue('d', null);
GM_setValue('x', new Date());
const a: string = GM_getValue('a', 'foobar');
const b: number = GM_getValue('b', 123);
// @ts-expect-error
const x: string = GM_getValue('x', 123);
const c: boolean = GM_getValue('c', true);
const d: object = GM_getValue('d', { key: 'value' });
const e = GM_getValue('e') as string;
const f = GM_getValue('f') as number;
const g = GM_getValue('g') as boolean;
const h = GM_getValue('h') as object;
const i: string | number | boolean | object | undefined = GM_getValue('i');
const listValues: string[] = GM_listValues();
listValues.forEach(async (name: string) => {
console.log(name + ':', GM_getValue(name));
});
GM_deleteValue('d');
const resourceURL = GM_getResourceUrl('some_res');
console.log('Resource url:', resourceURL);
const resourceText = GM_getResourceText('some_res');
console.log('Resource text:', resourceText);
const element1 = document.querySelector('addelement1');
const element2 = document.querySelector('addelement2');
GM.addElement('addelement1', { style: 'backgound-color: black;' }) === element1;
GM_addElement('div', 'addelement2', { style: 'backgound-color: red;' }) === element2;
function someFunc() {
console.log('success');
}
GM.addScript(`(' + ${someFunc} + ')();`);
const js = `function sum(x, y) {
return x + y;
}`;
GM_addScript(js);
const css1 = `body {border-top: 10px solid grey;}`;
GM.addStyle(css1);
const css2 = `body {background-color:black;}`;
GM_addStyle(css2);
GM.unregisterMenuCommand('Do the thing');
GM_unregisterMenuCommand('Do thee thing');
GM.removeValueChangeListener('test-key1');
GM_removeValueChangeListener('test-key2');
GM.log('Do this thing');
GM_log('Or that');
GM.popup;
GM_popup;
const scriptDescription: string = GM.info.script.description;
const scriptExcludes: string[] = GM.info.script.excludes;
const scriptIncludes: string[] = GM.info.script.includes;
const scriptMatches: string[] = GM.info.script.matches;
const scriptName: string = GM.info.script.name;
const scriptNamespace: string | null = GM.info.script.namespace;
const scriptResources = GM.info.script.resources['foo'];
const scriptResourceName: string = scriptResources.name;
const scriptResourceMimeType: string = scriptResources.mimetype;
const scriptResourceURL: string = scriptResources.url;
const scriptRunAt: string = GM.info.script['run-at'];
const scriptVersion: string = GM.info.script.version;
const scriptMetaStr: string | null = GM.info.scriptMetaStr;
const scriptHandler: string = GM.info.scriptHandler;
const platformOS: 'mac' | 'win' | 'android' | 'cros' | 'linux' | 'openbsd' | 'fuchsia' = GM.info.platform.os;
const platformarch: 'arm' | 'x86-32' | 'x86-64' = GM.info.platform.arch;
const browserName: string = GM.info.browser.name;
const browserVendor: string = GM.info.browser.vendor;
const browserVersion: string = GM.info.browser.version;
const browserBuildID: string = GM.info.browser.buildID;
const gmVersion: string = GM.info.version;
//#endregion

450
types/firemonkey-browser/index.d.ts vendored Normal file
View File

@@ -0,0 +1,450 @@
// Type definitions for non-npm package firemonkey-browser 2.60
// Project: https://github.com/erosman/support/tree/FireMonkey
// Definitions by: DrakeTDL <https://github.com/DrakeTDL>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 4.4
//
// This definition is based on the API reference of FireMonkey
// https://erosman.github.io/support/content/help.html#Script-API
declare namespace GM {
interface PlatformInfo {
os: 'mac' | 'win' | 'android' | 'cros' | 'linux' | 'openbsd' | 'fuchsia';
arch: 'arm' | 'x86-32' | 'x86-64';
}
interface BrowserInfo {
name: 'Firefox';
vendor: 'Mozilla';
version: string;
buildID: string;
}
interface ScriptInfo {
name: string;
version: string;
description: string;
matches: string[];
excludeMatches: string[];
includes: string[];
excludes: string[];
includeGlobs: string[];
excludeGlobs: string[];
'run-at': 'document_start' | 'document_end' | 'document_idle';
namespace: string | null;
/**
* An object keyed by resource name.
* Each value is an object with keys `name` and `mimetype` and `url`
* with string values.
*/
resources: {
[resourceName: string]: {
name: string;
mimetype: string;
url: string;
};
};
}
type Value = string | boolean | number | object;
type RequestMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'TRACE' | 'OPTIONS' | 'CONNECT';
interface Headers {
[header: string]: string;
}
interface XMLRequest<TContext = any> {
/**
* The URL to make the request to. Must be an absolute URL, beginning
* with the scheme. May be relative to the current page.
*/
url: string;
/** String type of HTTP request to make (E.G. "GET", "POST") */
method?: RequestMethod;
/** A set of headers to include in the request */
headers?: Headers;
/**
* Data to send in the request body. Usually for POST method requests.
* If the data field contains form-encoded data, you usually must also
* set the header `'Content-Type': 'application/x-www-form-urlencoded'`
* in the `headers` field.
*/
data?: string;
/**
* A MIME type to specify with the request (e.g.
* "text/html; charset=ISO-8859-1")
*/
overrideMimeType?: string;
/** User name to use for authentication purposes. */
user?: string;
/** Password to use for authentication purposes */
password?: string;
/**
* The number of milliseconds to wait before terminating the call. Zero
* (the default) means wait forever.
*/
timeout?: number;
withCredentials?: boolean;
responseType?: XMLHttpRequestResponseType;
anonymous?: boolean;
/** Callback Functions */
/** Will be called when the request has completed successfully */
onload?(response: XMLResponse<TContext>): void;
/** Will be called if an error occurs while processing the request */
onerror?(response: XMLResponse<TContext>): void;
/** Will be called if/when the request times out */
ontimeout?(response: XMLResponse<TContext>): void;
/** Will be called when the request is aborted */
onabort?(response: XMLResponse<TContext>): void;
}
interface XMLResponse<TContext> {
readonly readyState: 1 | 2 | 3 | 4;
readonly response: any;
readonly responseHeaders: string;
readonly responseText: string;
readonly responseType?: string;
readonly responseURL?: string;
readonly responseXML: Document | undefined;
readonly status: number;
readonly statusText: string;
readonly finalUrl: string;
}
interface FetchRequest {
/** The request method */
method?: RequestMethod;
/** A set of headers to include in the request */
headers?: Headers;
/** Any body that you want to add to your request */
body?: XMLHttpRequestBodyInit;
/** The mode you want to use for the request */
mode?: RequestMode;
/** The request credentials you want to use for the request */
credentials?: RequestCredentials;
/** The cache mode you want to use for the request */
cache?: RequestCache;
/** The redirect mode */
redirect?: RequestRedirect;
/** A USVString */
referrer?: 'no-referrer' | 'client' | URL;
/** Specifies the value of the referer HTTP header */
referrerPolicy?: ReferrerPolicy;
/** Contains the subresource integrity value of the request */
integrity?: string;
/** The keepalive option can be used to allow the request to outlive the page. Fetch with the keepalive flag is a replacement for the Navigator.sendBeacon() API. */
keepalive?: boolean;
/** An AbortSignal object instance; allows you to communicate with a fetch request and abort it if desired via an AbortController */
signal?: AbortSignal | string;
/** Any headers you want to add to your request */
responseType?: XMLHttpRequestResponseType;
/** If true, no cookie will be sent with the request. */
anonymous?: boolean;
}
interface FetchResponse {
readonly headers: string;
readonly bodyUsed: boolean;
readonly ok: boolean;
readonly redirected: boolean;
readonly status: number;
readonly statusText: 'OK';
readonly type: 'basic';
readonly url: URL;
// plus one of the following properties based on responseType, if method is not HEAD
readonly text?: string;
readonly json?: any;
readonly blob?: Blob;
readonly arrayBuffer?: ArrayBuffer;
readonly formData?: FormData;
}
}
/**
* Window object of the content page where the user script is running on.
* @see {@link https://erosman.github.io/support/content/help.html#unsafeWindow}
*/
declare var unsafeWindow: Window;
//#region GM3 style APIs
declare var GM: {
/**
* Appends and returns an element with the specified attributes
* @example
* // loading an external script
* const elem = GM.addElement('script', {src: 'https://....'});
* elem.onload = () => console.log(elem, 'loaded');
* @example
* // appending to shadowRoot
* const elem = GM_addElement(parentElement.shadowRoot, 'iframe', {src: 'https://....'});
* @example
* // appending to DOM
* const elem = GM_addElement(parentElement, 'a', {href: 'https://....', title: 'Some title', target: '_blank', textContent: 'Some text'});
* @see {@link https://erosman.github.io/support/content/help.html#addElement}
*/
addElement(tagName: string, attributes: object): HTMLElement | void;
addElement(parentNode: string, tagName: string, attributes: object): HTMLElement | void;
/**
* Utility function to inject script element.
* @example
* const js = `function sum(x, y) {
* return x + y;
* }`;
* GM_addScript(js);
* @example
* function someFunc() {
* ...
* }
* GM.addScript('(' + someFunc + ')();');
* @see {@link https://erosman.github.io/support/content/help.html#addScript}
*/
addScript(js: string): void;
/**
* Utility function to inject style element.
* @example
* const css = `body {
* border-top: 2px solid grey;
* }`;
* GM.addStyle(css);
* @see {@link https://erosman.github.io/support/content/help.html#addStyle}
*/
addStyle(css: string): void;
/**
* Script storage change listener that returns the key as listener ID
* @see {@link https://erosman.github.io/support/content/help.html#addValueChangeListener}
*/
addValueChangeListener(
key: string,
callback: (key?: string, oldValue?: string, newValue?: string, remote?: boolean) => void,
): string;
/**
* Deletes an existing name / value pair from storage.
* @see {@link https://erosman.github.io/support/content/help.html#deleteValue}
*/
deleteValue(key: string): Promise<void>;
/**
* Simple file download from the Internet.
* @see {@link https://erosman.github.io/support/content/help.html#download}
*/
download(url: string, filename?: string): Promise<number | undefined>;
/**
* An API is based on the {@link https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/fetch JavaScript Fetch API}
* which provides the new Promise based interface for fetching resources (including {@link https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy across the network}).
* It will seem familiar to anyone who has used XMLHttpRequest, but it provides a more powerful and flexible feature set
* @see {@link https://erosman.github.io/support/content/help.html#fetch}
*/
fetch(url: string, init?: GM.FetchRequest): Promise<GM.FetchResponse>;
/**
* Given a defined `@resource`, this method fetches and returns the content of the url
* @see {@link https://erosman.github.io/support/content/help.html#getResourceText}
*/
getResourceText(resourceName: string): Promise<string | undefined>;
/**
* Given a defined `@resource`, this method returns it as a URL
* @see {@link https://erosman.github.io/support/content/help.html#getResourceUrl}
*/
getResourceUrl(resourceName: string): Promise<string | undefined>;
/**
* Retrieves a value that was set with `GM.setValue`
* @see {@link https://erosman.github.io/support/content/help.html#getValue}
*/
getValue(key: string): Promise<GM.Value>;
getValue<TValue = GM.Value>(key: string, defaultValue?: TValue): Promise<TValue>;
/**
* An object container info about the running script.
* @see {@link https://erosman.github.io/support/content/help.html#info}
*/
info: {
/**
* The name of the user script engine handling this script's execution.
* The string `FireMonkey`
*/
scriptHandler: string;
/** The version of FireMonkey, a string e.g. `2.60` */
version: string;
/**
* A string, the entire literal Metadata Block (without the delimiters)
* for the currently running script
* In FireMonkey it's always null
*/
scriptMetaStr: string | null;
/** An object containing data about the currently running platform */
platform: GM.PlatformInfo;
/** An object containing data about the currently running browser */
browser: GM.BrowserInfo;
/** An object containing data about the currently running script */
script: GM.ScriptInfo;
};
/**
* Retrieves an array of preference names that this script has stored
* @see {@link https://erosman.github.io/support/content/help.html#listValues}
*/
listValues(): Promise<string[]>;
/**
* The API is added for convenience.
* @see {@link https://erosman.github.io/support/content/help.html#log}
*/
log(...data: any[]): void;
/**
* Displays a notification to the user, using the underlying operating
* system's notification mechanism
* @see {@link https://erosman.github.io/support/content/help.html#notification}
*/
notification(text: string | { text: string; image?: Blob | string }): Promise<string>;
/**
* Opens the specified URL in a new tab.
* @see {@link https://erosman.github.io/support/content/help.html#openInTab}
*/
openInTab(url: string, openInBackground?: boolean): Promise<boolean>;
/**
* A utility to create popups on the webpage.
* @see {@link https://erosman.github.io/support/content/help.html#popup}
*/
popup(options?: {
type?:
| 'center'
| 'slide-left'
| 'slide-right'
| 'slide-top'
| 'slide-bottom'
| 'panel-left'
| 'panel-right'
| 'panel-top'
| 'panel-bottom';
modal?: boolean;
}): {
/** Can be used to add style to the popup */
addStyle(css: string): void;
/** Can be used to add multiple HTML element(s) to the popup */
append(...data: HTMLElement[]): void;
show(): void;
hide(): void;
remove(): void;
host: HTMLElement;
style: HTMLElement;
content: HTMLElement;
close: HTMLElement;
};
/**
* Adds an item to the User Script Commands menu.
* @example
* // anonymous function
* GM_registerMenuCommand('Hello, world (anon)', () => { alert('Hello, world! (anon)')});
* @example
* // named function
* function sayHello() { alert('Hello, world! (named)')}
* GM.registerMenuCommand('Hello, world (named)', sayHello);
* @see {@link https://erosman.github.io/support/content/help.html#registerMenuCommand}
*/
registerMenuCommand(name: string, onClick: () => void): void;
/**
* Remove storage change listener for key
* @see {@link https://erosman.github.io/support/content/help.html#removeValueChangeListener}
*/
removeValueChangeListener(key: string): void;
/**
* Sets the current contents of the operating system's clipboard
* @see {@link https://erosman.github.io/support/content/help.html#setClipboard}
*/
setClipboard(text: string): Promise<void>;
/**
* Allows user script authors to persist simple values across page loads and
* across origins.
* Strings, booleans, and integers are currently the only allowed data types.
* @see {@link https://erosman.github.io/support/content/help.html#setValue}
*/
setValue(key: string, value: GM.Value): Promise<void>;
/**
* removes an item from the User Script Commands menu.
* @see {@link https://erosman.github.io/support/content/help.html#unregisterMenuCommand}
*/
unregisterMenuCommand(name: string): void;
/**
* Performs a similar function to the standard XMLHttpRequest object, but
* allows these requests to cross the {@link https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy same origin policy} boundaries.
* @see {@link https://erosman.github.io/support/content/help.html#xmlHttpRequest}
*/
xmlHttpRequest(init: GM.XMLRequest): Promise<void>;
};
//#endregion
//#region GM4 style APIs
declare var GM_addElement: typeof GM.addElement;
declare var GM_addScript: typeof GM.addScript;
declare var GM_addStyle: typeof GM.addStyle;
declare var GM_addValueChangeListener: typeof GM.addValueChangeListener;
declare var GM_download: typeof GM.download;
declare var GM_fetch: typeof GM.fetch;
declare var GM_info: typeof GM.info;
declare var GM_log: typeof GM.log;
declare var GM_notification: typeof GM.notification;
declare var GM_openInTab: typeof GM.openInTab;
declare var GM_popup: typeof GM.popup;
declare var GM_registerMenuCommand: typeof GM.registerMenuCommand;
declare var GM_removeValueChangeListener: typeof GM.removeValueChangeListener;
declare var GM_setClipboard: typeof GM.setClipboard;
declare var GM_unregisterMenuCommand: typeof GM.unregisterMenuCommand;
declare var GM_xmlHttpRequest: typeof GM.xmlHttpRequest;
/**
* Allows user script authors to persist simple values across page loads and
* across origins.
* Strings, booleans, and integers are currently the only allowed data types.
* @see {@link https://erosman.github.io/support/content/help.html#setValue}
*/
declare function GM_setValue(key: string, value: GM.Value): void;
/**
* Retrieves an array of preference names that this script has stored
* @see {@link https://erosman.github.io/support/content/help.html#listValues}
*/
declare function GM_listValues(): string[];
/**
* Deletes an existing name / value pair from storage.
* @see {@link https://erosman.github.io/support/content/help.html#deleteValue}
*/
declare function GM_deleteValue(key: string): void;
/**
* Retrieves a value that was set with `GM.setValue`
* @see {@link https://erosman.github.io/support/content/help.html#getValue}
*/
declare function GM_getValue(key: string): GM.Value;
declare function GM_getValue<TValue = GM.Value>(key: string, defaultValue?: TValue): TValue;
/**
* Given a defined `@resource`, this method fetches and returns the content of the url
* @see {@link https://erosman.github.io/support/content/help.html#getResourceText}
*/
declare function GM_getResourceText(resourceName: string): string | void;
/**
* Given a defined `@resource`, this method returns it as a URL
* @see {@link https://erosman.github.io/support/content/help.html#getResourceUrl}
*/
declare function GM_getResourceUrl(resourceName: string): string | void;
//#endregion

View File

@@ -0,0 +1,24 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es6",
"DOM"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
},
"files": [
"index.d.ts",
"firemonkey-browser-tests.ts"
]
}

View File

@@ -0,0 +1 @@
{"extends": "@definitelytyped/dtslint/dt.json"}