mirror of
https://github.com/flarum/framework.git
synced 2025-01-26 14:51:00 +08:00
Convert extend util to TypeScript (#2928)
* Allow using file extension in core compat imports Necessary for extend imports to have proper typings as we also have an unrelated extend/index.js file * Add .ts file extension to extend imports for typings * Fix changes to proxifyCompat regex breaking non-core import paths * Move utility types to global types Co-authored-by: David Wheatley <hi@davwheat.dev>
This commit is contained in:
parent
a07171cf1f
commit
1a695dee2c
18
framework/core/js/src/@types/global.d.ts
vendored
18
framework/core/js/src/@types/global.d.ts
vendored
|
@ -1,3 +1,21 @@
|
|||
/**
|
||||
* UTILITY TYPES
|
||||
*/
|
||||
|
||||
/**
|
||||
* Type that returns an array of all keys of a provided object that are of
|
||||
* of the provided type, or a subtype of the type.
|
||||
*/
|
||||
declare type KeysOfType<Type extends object, Match> = {
|
||||
[Key in keyof Type]-?: Type[Key] extends Match ? Key : never;
|
||||
};
|
||||
|
||||
/**
|
||||
* Type that matches one of the keys of an object that is of the provided
|
||||
* type, or a subtype of it.
|
||||
*/
|
||||
declare type KeyOfType<Type extends object, Match> = KeysOfType<Type, Match>[keyof Type];
|
||||
|
||||
/**
|
||||
* @deprecated Please import `app` from a namespace instead of using it as a global variable.
|
||||
*
|
||||
|
|
|
@ -14,7 +14,7 @@ import mapRoutes from './utils/mapRoutes';
|
|||
import RequestError from './utils/RequestError';
|
||||
import ScrollListener from './utils/ScrollListener';
|
||||
import liveHumanTimes from './utils/liveHumanTimes';
|
||||
import { extend } from './extend';
|
||||
import { extend } from './extend.ts';
|
||||
|
||||
import Forum from './models/Forum';
|
||||
import User from './models/User';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as extend from './extend';
|
||||
import * as extend from './extend.ts';
|
||||
import Session from './Session';
|
||||
import Store from './Store';
|
||||
import BasicEditorDriver from './utils/BasicEditorDriver';
|
||||
|
|
|
@ -19,23 +19,27 @@
|
|||
* // something that needs to be run on creation and update
|
||||
* });
|
||||
*
|
||||
* @param {object} object The object that owns the method
|
||||
* @param {string|string[]} methods The name or names of the method(s) to extend
|
||||
* @param {function} callback A callback which mutates the method's output
|
||||
* @param object The object that owns the method
|
||||
* @param methods The name or names of the method(s) to extend
|
||||
* @param callback A callback which mutates the method's output
|
||||
*/
|
||||
export function extend(object, methods, callback) {
|
||||
export function extend<T extends object, K extends KeyOfType<T, Function>>(
|
||||
object: T,
|
||||
methods: K | K[],
|
||||
callback: (this: T, val: ReturnType<T[K]>, ...args: Parameters<T[K]>) => void
|
||||
) {
|
||||
const allMethods = Array.isArray(methods) ? methods : [methods];
|
||||
|
||||
allMethods.forEach((method) => {
|
||||
const original = object[method];
|
||||
allMethods.forEach((method: K) => {
|
||||
const original: Function | undefined = object[method];
|
||||
|
||||
object[method] = function (...args) {
|
||||
object[method] = function (this: T, ...args: Parameters<T[K]>) {
|
||||
const value = original ? original.apply(this, args) : undefined;
|
||||
|
||||
callback.apply(this, [value].concat(args));
|
||||
callback.apply(this, [value, ...args]);
|
||||
|
||||
return value;
|
||||
};
|
||||
} as T[K];
|
||||
|
||||
Object.assign(object[method], original);
|
||||
});
|
||||
|
@ -64,19 +68,23 @@ export function extend(object, methods, callback) {
|
|||
* // something that needs to be run on creation and update
|
||||
* });
|
||||
*
|
||||
* @param {object} object The object that owns the method
|
||||
* @param {string|string[]} method The name or names of the method(s) to override
|
||||
* @param {function} newMethod The method to replace it with
|
||||
* @param object The object that owns the method
|
||||
* @param methods The name or names of the method(s) to override
|
||||
* @param newMethod The method to replace it with
|
||||
*/
|
||||
export function override(object, methods, newMethod) {
|
||||
export function override<T extends object, K extends KeyOfType<T, Function>>(
|
||||
object: T,
|
||||
methods: K | K[],
|
||||
newMethod: (this: T, orig: T[K], ...args: Parameters<T[K]>) => void
|
||||
) {
|
||||
const allMethods = Array.isArray(methods) ? methods : [methods];
|
||||
|
||||
allMethods.forEach((method) => {
|
||||
const original = object[method];
|
||||
const original: Function = object[method];
|
||||
|
||||
object[method] = function (...args) {
|
||||
return newMethod.apply(this, [original.bind(this)].concat(args));
|
||||
};
|
||||
object[method] = function (this: T, ...args: Parameters<T[K]>) {
|
||||
return newMethod.apply(this, [original.bind(this), ...args]);
|
||||
} as T[K];
|
||||
|
||||
Object.assign(object[method], original);
|
||||
});
|
|
@ -1,10 +1,12 @@
|
|||
export default (compat: { [key: string]: any }, namespace: string) => {
|
||||
export default function proxifyCompat(compat: Record<string, unknown>, namespace: string) {
|
||||
// regex to replace common/ and NAMESPACE/ for core & core extensions
|
||||
// and remove .js, .ts and .tsx extensions
|
||||
// e.g. admin/utils/extract --> utils/extract
|
||||
// e.g. tags/common/utils/sortTags --> tags/utils/sortTags
|
||||
const regex = new RegExp(`(\\w+\\/)?(${namespace}|common)\\/`);
|
||||
const regex = new RegExp(String.raw`(\w+\/)?(${namespace}|common)\/`);
|
||||
const fileExt = /(\.js|\.tsx?)$/;
|
||||
|
||||
return new Proxy(compat, {
|
||||
get: (obj, prop: string) => obj[prop] || obj[prop.replace(regex, '$1')],
|
||||
get: (obj, prop: string) => obj[prop] || obj[prop.replace(regex, '$1').replace(fileExt, '')],
|
||||
});
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user