feat: add public method utilities and corresponding tests
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { getRandomAvailablePort, isObject, isString, makeId } from "@/utils/utils"
|
||||
import { getRandomAvailablePort, isObject, isPublicMethod, isString, makeId, markAsPublicMethod } from "@/utils/utils"
|
||||
|
||||
test('makeId', () => {
|
||||
const id = makeId();
|
||||
@@ -26,4 +26,29 @@ test('getRandomAvailablePort', async () => {
|
||||
const port = await getRandomAvailablePort();
|
||||
expect(port).toBeGreaterThanOrEqual(1);
|
||||
expect(port).toBeLessThanOrEqual(65535);
|
||||
})
|
||||
|
||||
test('markAsPublick', () => {
|
||||
const shallowObj = {
|
||||
fn1() { },
|
||||
l1: {
|
||||
fn1() { },
|
||||
}
|
||||
};
|
||||
|
||||
const deepObj = {
|
||||
fn1() { },
|
||||
l1: {
|
||||
fn1() { },
|
||||
}
|
||||
};
|
||||
|
||||
markAsPublicMethod(shallowObj);
|
||||
markAsPublicMethod(deepObj, { deep: true });
|
||||
|
||||
expect(isPublicMethod(shallowObj.fn1)).toBeTruthy();
|
||||
expect(isPublicMethod(shallowObj.l1.fn1)).toBeUndefined();
|
||||
|
||||
expect(isPublicMethod(deepObj.fn1)).toBeTruthy();
|
||||
expect(isPublicMethod(deepObj.l1.fn1)).toBeTruthy();
|
||||
})
|
||||
@@ -16,6 +16,8 @@ export { injectSocketClient } from "./core/SocketClient";
|
||||
export { injectSocketServer } from "./core/SocketServer";
|
||||
import { injectSocketIOImplements } from "./implements/socket.io";
|
||||
|
||||
export { publicMethod, isPublicMethod, markAsPublicMethod } from './utils/utils';
|
||||
|
||||
injectSocketIOImplements();
|
||||
|
||||
export {
|
||||
|
||||
@@ -4,8 +4,12 @@ export const makeId = () => md5(`${Date.now()}${Math.random()}`);
|
||||
|
||||
export const isObject = (v: unknown): v is Record<string, any> => typeof v === 'object' && v !== null;
|
||||
|
||||
export const isArray = (v: unknown): v is Array<unknown> => Array.isArray(v);
|
||||
|
||||
export const isString = (v: unknown): v is string => typeof v === 'string';
|
||||
|
||||
export const isFunction = (v: unknown): v is Function => typeof v === 'function';
|
||||
|
||||
export type ObjectType = Record<string, any>;
|
||||
|
||||
export type ToDeepPromise<T> = {
|
||||
@@ -41,4 +45,40 @@ export async function getRandomAvailablePort() {
|
||||
|
||||
server.listen(0);
|
||||
})
|
||||
}
|
||||
|
||||
const publicMethodMap = new WeakMap<Function, boolean>();
|
||||
export function publicMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
||||
publicMethodMap.set(descriptor.value, true);
|
||||
};
|
||||
export function isPublicMethod(target: Function) {
|
||||
return publicMethodMap.get(target);
|
||||
};
|
||||
export function markAsPublicMethod<T extends Function | Record<any, unknown> | unknown>(obj: T, options?: {
|
||||
deep?: boolean
|
||||
}): T {
|
||||
const accessed = new Set();
|
||||
function markAs(obj: Function | Record<any, unknown> | unknown) {
|
||||
if (accessed.has(obj)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isFunction(obj)) {
|
||||
publicMethodMap.set(obj, true);
|
||||
} else if (isObject(obj)) {
|
||||
accessed.add(obj);
|
||||
|
||||
Object.values(obj).forEach(subObj => {
|
||||
if (isFunction(subObj)) {
|
||||
publicMethodMap.set(subObj, true);
|
||||
}
|
||||
if (options?.deep && isObject(subObj)) {
|
||||
markAs(subObj);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
markAs(obj);
|
||||
return obj;
|
||||
}
|
||||
@@ -12,8 +12,8 @@
|
||||
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
||||
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
||||
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
||||
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
||||
"experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
|
||||
"emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
||||
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
|
||||
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
||||
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
|
||||
|
||||
Reference in New Issue
Block a user