chore: 清理macOS同步产生的重复文件
详细说明: - 删除了352个带数字后缀的重复文件 - 更新.gitignore防止未来产生此类文件 - 这些文件是由iCloud或其他同步服务冲突产生的 - 不影响项目功能,仅清理冗余文件
This commit is contained in:
@@ -1,37 +0,0 @@
|
||||
import debounce from 'lodash/debounce';
|
||||
|
||||
/**
|
||||
* Debounce a class method using `lodash/debounce`.
|
||||
*
|
||||
* @param waitMs - Number of milliseconds to debounce method by.
|
||||
*
|
||||
* @example
|
||||
* ```
|
||||
* class MyClass {
|
||||
* @Debounce(1000)
|
||||
* async myMethod() {
|
||||
* // debounced
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export const Debounce =
|
||||
(waitMs: number): MethodDecorator =>
|
||||
<T>(
|
||||
_: object,
|
||||
methodName: string | symbol,
|
||||
originalDescriptor: PropertyDescriptor,
|
||||
): TypedPropertyDescriptor<T> => ({
|
||||
configurable: true,
|
||||
|
||||
get() {
|
||||
const debouncedFn = debounce(originalDescriptor.value, waitMs);
|
||||
|
||||
Object.defineProperty(this, methodName, {
|
||||
configurable: false,
|
||||
value: debouncedFn,
|
||||
});
|
||||
|
||||
return debouncedFn as T;
|
||||
},
|
||||
});
|
||||
@@ -1,7 +0,0 @@
|
||||
import { UnexpectedError } from 'n8n-workflow';
|
||||
|
||||
export class NonMethodError extends UnexpectedError {
|
||||
constructor(name: string) {
|
||||
super(`${name} must be a method on a class to use this decorator`);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
export * from './controller';
|
||||
export * from './command';
|
||||
export { Debounce } from './debounce';
|
||||
export * from './execution-lifecycle';
|
||||
export { Memoized } from './memoized';
|
||||
export * from './module';
|
||||
export * from './multi-main';
|
||||
export * from './pubsub';
|
||||
export { Redactable } from './redactable';
|
||||
export * from './shutdown';
|
||||
export * from './module/module-metadata';
|
||||
export { Timed, TimedOptions } from './timed';
|
||||
@@ -1,41 +0,0 @@
|
||||
import assert from 'node:assert';
|
||||
|
||||
/**
|
||||
* A decorator that implements memoization for class property getters.
|
||||
*
|
||||
* The decorated getter will only be executed once and its value cached for subsequent access
|
||||
*
|
||||
* @example
|
||||
* class Example {
|
||||
* @Memoized
|
||||
* get computedValue() {
|
||||
* // This will only run once and the result will be cached
|
||||
* return heavyComputation();
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @throws If decorator is used on something other than a getter
|
||||
*/
|
||||
export function Memoized<T = unknown>(
|
||||
target: object,
|
||||
propertyKey: string | symbol,
|
||||
descriptor?: TypedPropertyDescriptor<T>,
|
||||
): TypedPropertyDescriptor<T> {
|
||||
const originalGetter = descriptor?.get;
|
||||
assert(originalGetter, '@Memoized can only be used on getters');
|
||||
|
||||
// Replace the original getter for the first call
|
||||
descriptor.get = function (this: typeof target.constructor): T {
|
||||
const value = originalGetter.call(this);
|
||||
// Add a property on the class instance to stop reading from the getter on class prototype
|
||||
Object.defineProperty(this, propertyKey, {
|
||||
value,
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
});
|
||||
return value;
|
||||
};
|
||||
|
||||
return descriptor;
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
import { UnexpectedError } from 'n8n-workflow';
|
||||
|
||||
type UserLike = {
|
||||
id: string;
|
||||
email?: string;
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
role: string;
|
||||
};
|
||||
|
||||
export class RedactableError extends UnexpectedError {
|
||||
constructor(fieldName: string, args: string) {
|
||||
super(
|
||||
`Failed to find "${fieldName}" property in argument "${args.toString()}". Please set the decorator \`@Redactable()\` only on \`LogStreamingEventRelay\` methods where the argument contains a "${fieldName}" property.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function toRedactable(userLike: UserLike) {
|
||||
return {
|
||||
userId: userLike.id,
|
||||
_email: userLike.email,
|
||||
_firstName: userLike.firstName,
|
||||
_lastName: userLike.lastName,
|
||||
globalRole: userLike.role,
|
||||
};
|
||||
}
|
||||
|
||||
type FieldName = 'user' | 'inviter' | 'invitee';
|
||||
|
||||
/**
|
||||
* Mark redactable properties in a `{ user: UserLike }` field in an `LogStreamingEventRelay`
|
||||
* method arg. These properties will be later redacted by the log streaming
|
||||
* destination based on user prefs. Only for `n8n.audit.*` logs.
|
||||
*
|
||||
* Also transform `id` to `userId` and `role` to `globalRole`.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* { id: '123'; email: 'test@example.com', role: 'some-role' } ->
|
||||
* { userId: '123'; _email: 'test@example.com', globalRole: 'some-role' }
|
||||
*/
|
||||
export const Redactable =
|
||||
(fieldName: FieldName = 'user'): MethodDecorator =>
|
||||
(_target, _propertyName, propertyDescriptor: PropertyDescriptor) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-restricted-types
|
||||
const originalMethod = propertyDescriptor.value as Function;
|
||||
|
||||
type MethodArgs = Array<{ [fieldName: string]: UserLike }>;
|
||||
|
||||
propertyDescriptor.value = function (...args: MethodArgs) {
|
||||
const index = args.findIndex((arg) => arg[fieldName] !== undefined);
|
||||
|
||||
if (index === -1) throw new RedactableError(fieldName, args.toString());
|
||||
|
||||
const userLike = args[index]?.[fieldName];
|
||||
|
||||
// @ts-expect-error Transformation
|
||||
if (userLike) args[index][fieldName] = toRedactable(userLike);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
return originalMethod.apply(this, args);
|
||||
};
|
||||
|
||||
return propertyDescriptor;
|
||||
};
|
||||
@@ -1,42 +0,0 @@
|
||||
export interface TimedOptions {
|
||||
/** Duration (in ms) above which to log a warning. Defaults to `100`. */
|
||||
threshold?: number;
|
||||
/** Whether to include method parameters in the log. Defaults to `false`. */
|
||||
logArgs?: boolean;
|
||||
}
|
||||
|
||||
interface Logger {
|
||||
warn(message: string, meta?: object): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory to create decorators to warn when method calls exceed a duration threshold.
|
||||
*/
|
||||
export const Timed =
|
||||
(logger: Logger, msg = 'Slow method call') =>
|
||||
(options: TimedOptions = {}): MethodDecorator =>
|
||||
(_target, propertyKey, descriptor: PropertyDescriptor) => {
|
||||
const originalMethod = descriptor.value as (...args: unknown[]) => unknown;
|
||||
const thresholdMs = options.threshold ?? 100;
|
||||
const logArgs = options.logArgs ?? false;
|
||||
|
||||
descriptor.value = async function (...args: unknown[]) {
|
||||
const methodName = `${this.constructor.name}.${String(propertyKey)}`;
|
||||
const start = performance.now();
|
||||
const result = await originalMethod.apply(this, args);
|
||||
const durationMs = performance.now() - start;
|
||||
|
||||
if (durationMs > thresholdMs) {
|
||||
logger.warn(msg, {
|
||||
method: methodName,
|
||||
durationMs: Math.round(durationMs),
|
||||
thresholdMs,
|
||||
params: logArgs ? args : '[hidden]',
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
return descriptor;
|
||||
};
|
||||
@@ -1,14 +0,0 @@
|
||||
export type Class<T = object, A extends unknown[] = unknown[]> = new (...args: A) => T;
|
||||
|
||||
type EventHandlerFn = () => Promise<void> | void;
|
||||
export type EventHandlerClass = Class<Record<string, EventHandlerFn>>;
|
||||
export type EventHandler<T extends string> = {
|
||||
/** Class holding the method to call on an event. */
|
||||
eventHandlerClass: EventHandlerClass;
|
||||
|
||||
/** Name of the method to call on an event. */
|
||||
methodName: string;
|
||||
|
||||
/** Name of the event to listen to. */
|
||||
eventName: T;
|
||||
};
|
||||
Reference in New Issue
Block a user