Skip to content

Commit

Permalink
Simplify types
Browse files Browse the repository at this point in the history
to avoid duplicates (and for clarity), by using additional types and interfaces
  • Loading branch information
Adrien LESÉNÉCHAL committed Jan 29, 2024
1 parent b9c1463 commit b39860e
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 74 deletions.
22 changes: 11 additions & 11 deletions jquery/client.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,18 +119,14 @@ interface Client {
* }
* ```
*
* @param {Object} map Browser support map
* @param {ClientSupportMap} map Browser support map
* @param {ClientProfile} [profile] A client-profile object
* @param {boolean} [exactMatchOnly=false] Only return true if the browser is matched,
* otherwise returns true if the browser is not found.
* @returns {boolean} The current browser is in the support map
* @see https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/jQuery.client-method-test
*/
test(
map: ClientSupportMap | { ltr: ClientSupportMap; rtl: ClientSupportMap },
profile?: ClientProfile,
exactMatchOnly?: boolean
): boolean;
test(map: ClientSupportMap, profile?: ClientProfile, exactMatchOnly?: boolean): boolean;
}

export interface ClientNavigator {
Expand All @@ -152,11 +148,15 @@ type ClientProfileName =
| "safari"
| "silk";

type ClientSupportMap = Partial<Record<ClientProfileName, false | null | ClientSupportCondition[]>>;
type ClientSupportCondition = [
"==" | "===" | "!=" | "!==" | "<" | "<=" | ">" | ">=",
string | number
];
type ComparisonOperator = "==" | "===" | "!=" | "!==" | "<" | "<=" | ">" | ">=";
type ClientSupportCondition = [ComparisonOperator, string | number];

type UndirectedClientSupportMap = Partial<
Record<ClientProfileName, false | null | ClientSupportCondition[]>
>;
type ClientSupportMap =
| UndirectedClientSupportMap
| Record<"ltr" | "rtl", UndirectedClientSupportMap>;

interface ClientProfile {
name: ClientProfileName;
Expand Down
58 changes: 34 additions & 24 deletions mw/Api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,28 @@ type ReplaceValue<T extends U | U[], U, V> = T extends U[] ? V[] : V;
type ApiParams = Record<string, string | string[] | boolean | number | number[]>;
type ApiResponse = Record<string, any>; // it will always be a JSON object, the rest is uncertain ...

interface Revision {
content: string;
timestamp: string;
}

interface AssertUser {
assert: "anon" | "user";
assertUser: string;
}

interface WatchStatus {
title: string;
watched: boolean;
}

interface FinishUpload {
/**
* Call this function to finish the upload.
*/
(data?: ApiUploadParams): JQuery.Promise<ApiResponse>;
}

/**
* Default options for {@link jQuery.ajax} calls. Can be overridden by passing
* `options` to {@link mw.Api} constructor.
Expand Down Expand Up @@ -319,16 +341,13 @@ declare global {
* ```
*
* @param {TitleLike} title Page title
* @param {function({ timestamp: string, content: string }):string|ApiEditPageParams} transform Callback that prepares the edit
* @param {function(Revision):string|ApiEditPageParams} transform Callback that prepares the edit
* @returns {JQuery.Promise<any>}
* @see https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw.Api.plugin.edit-method-edit
*/
edit(
title: TitleLike,
transform: (data: {
timestamp: string;
content: string;
}) => string | ApiEditPageParams
transform: (revision: Revision) => string | ApiEditPageParams
): JQuery.Promise<any>;

/**
Expand Down Expand Up @@ -367,15 +386,10 @@ declare global {
* * `apierror-assertnameduserfailed`: when both the client-side logic and the server thinks the user is logged in but they see it logged in under a different username.
*
* @param {ApiParams} query Query parameters. The object will not be changed
* @returns {JQuery.Promise<{ assert: "anon" | "user", assertUser: string }>}
* @returns {JQuery.Promise<AssertUser>}
* @see https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw.Api.plugin.user-method-assertCurrentUser
*/
assertCurrentUser(
query: ApiParams
): JQuery.Promise<{
assert: "anon" | "user";
assertUser: string;
}>;
assertCurrentUser(query: ApiParams): JQuery.Promise<AssertUser>;

/**
* Asynchronously save the value of a single user option using the API. See `saveOptions()`.
Expand Down Expand Up @@ -409,29 +423,25 @@ declare global {
*
* @param {TypeOrArray<TitleLike>} pages
* @param {string} [expiry]
* @returns {JQuery.Promise<{ watch: TypeOrArray<{ title: string, watched: boolean }> }>}
* @returns {JQuery.Promise<{ watch: TypeOrArray<WatchStatus> }>}
* @since 1.35: expiry parameter can be passed when watchlist expiry is enabled
* @see https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw.Api.plugin.watch-method-watch
*/
watch<P extends TypeOrArray<TitleLike>>(
pages: P,
expiry?: string
): JQuery.Promise<{
watch: ReplaceValue<P, TitleLike, { title: string; watched: boolean }>;
}>;
): JQuery.Promise<{ watch: ReplaceValue<P, TitleLike, WatchStatus> }>;

/**
* Convenience method for `action=watch&unwatch=1`.
*
* @param {TypeOrArray<TitleLike>} pages
* @returns {JQuery.Promise<{ watch: TypeOrArray<{ title: string, watched: boolean }> }>}
* @returns {JQuery.Promise<{ watch: TypeOrArray<WatchStatus> }>}
* @see https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw.Api.plugin.watch-method-unwatch
*/
unwatch<P extends TypeOrArray<TitleLike>>(
pages: P
): JQuery.Promise<{
watch: ReplaceValue<P, TitleLike, { title: string; watched: boolean }>;
}>;
): JQuery.Promise<{ watch: ReplaceValue<P, TitleLike, WatchStatus> }>;

/**
* Convenience method for `action=parse`.
Expand Down Expand Up @@ -553,15 +563,15 @@ declare global {
* @param {ApiUploadParams} [data]
* @param {number} [chunkSize] Size (in bytes) per chunk (default: 5MB)
* @param {number} [chunkRetries] Amount of times to retry a failed chunk (default: 1)
* @returns {JQuery.Promise<(data?: ApiUploadParams) => JQuery.Promise<ApiResponse>>} Call this function to finish the upload
* @returns {JQuery.Promise<FinishUpload>}
* @see https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw.Api.plugin.upload-method-chunkedUploadToStash
*/
chunkedUploadToStash(
file: File | HTMLInputElement,
data?: ApiUploadParams,
chunkSize?: number,
chunkRetries?: number
): JQuery.Promise<(data?: ApiUploadParams) => JQuery.Promise<ApiResponse>>;
): JQuery.Promise<FinishUpload>;

/**
* Upload a file to MediaWiki.
Expand Down Expand Up @@ -606,13 +616,13 @@ declare global {
*
* @param {File|HTMLInputElement} file
* @param {ApiUploadParams} [data]
* @returns {JQuery.Promise<(data?: ApiUploadParams) => JQuery.Promise<ApiResponse>>} Call this function to finish the upload
* @returns {JQuery.Promise<FinishUpload>}
* @see https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw.Api.plugin.upload-method-uploadToStash
*/
uploadToStash(
file: File | HTMLInputElement,
data?: ApiUploadParams
): JQuery.Promise<(data?: ApiUploadParams) => JQuery.Promise<ApiResponse>>;
): JQuery.Promise<FinishUpload>;

/**
* @param {string} username
Expand Down
11 changes: 6 additions & 5 deletions mw/Uri.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ interface UriOptions {
arrayParams: boolean;
}

interface UriParser {
strict: RegExp;
loose: RegExp;
}

declare global {
namespace mw {
/**
Expand Down Expand Up @@ -134,13 +139,9 @@ declare global {
* file where they make use of named capture groups. That syntax isn't valid in JavaScript ES5,
* so the server-side strips these before delivering to the client.
*
* @property {Object} parser
* @see https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw.Uri-static-property-parser
*/
private static parser: {
strict: RegExp;
loose: RegExp;
};
private static parser: UriParser;

/**
* The order here matches the order of captured matches in the `parser` property regexes.
Expand Down
34 changes: 23 additions & 11 deletions mw/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,24 @@ import "./Uri";
import "./user";
import "./util";

type ObjectAnalyticEventData = Record<string, any>;
type AnalyticEventData = ObjectAnalyticEventData | number | string | undefined;

interface ErrorAnalyticEventData extends ObjectAnalyticEventData {
exception?: any;
module?: string;
source: string;
}

interface AnalyticEvent {
topic: string;
data: AnalyticEventData;
}

interface AnalyticEventCallback {
(topic: string, data: AnalyticEventData): void;
}

declare global {
/**
* Base library for MediaWiki.
Expand Down Expand Up @@ -128,7 +146,7 @@ declare global {
* @param {Object|number|string} [data] Data describing the event.
* @see https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw-method-track
*/
function track(topic: string, data?: object | number | string): void;
function track(topic: string, data?: AnalyticEventData): void;

/**
* Track an early error event via mw.track and send it to the window console.
Expand All @@ -138,7 +156,7 @@ declare global {
* @param {Object} data Data describing the event, encoded as an object; see {@link errorLogger.logError}
* @see https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw-method-trackError
*/
function trackError(topic: string, data: object): void;
function trackError(topic: string, data: ErrorAnalyticEventData): void;

/**
* Register a handler for subset of analytic events, specified by topic.
Expand All @@ -165,17 +183,14 @@ declare global {
* @param {string} callback.topic
* @param {Object} [callback.data]
*/
function trackSubscribe(
topic: string,
callback: (topic: string, data: object) => void
): void;
function trackSubscribe(topic: string, callback: AnalyticEventCallback): void;

/**
* Stop handling events for a particular handler
*
* @param {Function} callback
*/
function trackUnsubscribe(callback: (topic: string, data: object) => void): void;
function trackUnsubscribe(callback: AnalyticEventCallback): void;

/**
* List of all analytic events emitted so far.
Expand All @@ -185,10 +200,7 @@ declare global {
* @private
* @see https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw-property-trackQueue
*/
const trackQueue: Array<{
topic: string;
data: Record<string, any> | number | string | undefined;
}>;
const trackQueue: AnalyticEvent[];
}
}

Expand Down
12 changes: 7 additions & 5 deletions mw/user.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ export interface UserInfo {
rights: string[];
}

interface UserTokens extends Record<string, string> {
csrfToken: string;
patrolToken: string;
watchToken: string;
}

export interface User {
/**
* @see https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw.user-property-options
Expand All @@ -19,11 +25,7 @@ export interface User {
/**
* @see https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw.user-property-tokens
*/
tokens: mw.Map<{
csrfToken: string;
patrolToken: string;
watchToken: string;
}>;
tokens: mw.Map<UserTokens>;

/**
* Acquire a temporary user username and stash it in the current session, if temp account creation
Expand Down
42 changes: 24 additions & 18 deletions mw/util.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,28 @@ type NoReturn<T extends (...args: any[]) => any> = T extends (
: (this: U, ...args: V) => void
: never;

interface ImageUrlData {
/**
* File name (same format as {@link mw.Title.getMainText()}).
*/
name: string;

/**
* Thumbnail width, in pixels. Null when the file is not a thumbnail.
*/
width: number | null;

/**
* @param w Width, which must be smaller than the width of the original image (or equal to it; that
* only works if `MediaHandler::mustRender` returns true for the file). Null when the
* file in the original URL is not a thumbnail.
* On wikis with `$wgGenerateThumbnailOnParse` set to true, this will fall back to using
* `Special:Redirect` which is less efficient. Otherwise, it is a direct thumbnail URL.
* @returns A thumbnail URL (URL-encoded) with that width.
*/
resizeUrl: (w: number) => string | null;
}

declare global {
namespace mw {
/**
Expand Down Expand Up @@ -403,27 +425,11 @@ declare global {
* the image.
*
* @param {string} url URL to parse (URL-encoded)
* @returns {Object|null} URL data, or null if the URL is not a valid MediaWiki
* @returns {ImageUrlData|null} URL data, or null if the URL is not a valid MediaWiki
* image/thumbnail URL.
* @returns {string} return.name File name (same format as Title.getMainText()).
* @returns {number} [return.width] Thumbnail width, in pixels. Null when the file is not
* a thumbnail.
* @returns {function(number):string} [return.resizeUrl] A function that takes a width
* parameter and returns a thumbnail URL (URL-encoded) with that width. The width
* parameter must be smaller than the width of the original image (or equal to it; that
* only works if MediaHandler::mustRender returns true for the file). Null when the
* file in the original URL is not a thumbnail.
* On wikis with $wgGenerateThumbnailOnParse set to true, this will fall back to using
* Special:Redirect which is less efficient. Otherwise, it is a direct thumbnail URL.
* @see https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw.util-method-parseImageUrl
*/
function parseImageUrl(
url: string
): {
name: string;
width?: number | null;
resizeUrl(w: number): string;
} | null;
function parseImageUrl(url: string): ImageUrlData | null;

/**
* Percent-decode a string, as found in a URL hash fragment
Expand Down

0 comments on commit b39860e

Please sign in to comment.