chore: organize config, validation, decorators (#8118)

* refactor: validation

* refactor: utilities

* refactor: config
This commit is contained in:
Jason Rasmussen 2024-03-20 15:04:03 -05:00 committed by GitHub
parent 92cc647cf6
commit 81f0265095
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
119 changed files with 666 additions and 684 deletions

View file

@ -1,16 +1,7 @@
import _ from 'lodash';
import {
Paginated,
PaginatedBuilderOptions,
PaginationMode,
PaginationOptions,
PaginationResult,
chunks,
setUnion,
} from 'src/domain/domain.util';
import { AssetSearchBuilderOptions } from 'src/domain/repositories/search.repository';
import { AssetEntity } from 'src/infra/entities/asset.entity';
import { DATABASE_PARAMETER_CHUNK_SIZE } from 'src/infra/infra.util';
import { Paginated, PaginatedBuilderOptions, PaginationMode, PaginationOptions, PaginationResult } from 'src/utils';
import {
Between,
FindManyOptions,
@ -37,11 +28,6 @@ export function OptionalBetween<T>(from?: T, to?: T) {
}
}
export const isValidInteger = (value: number, options: { min?: number; max?: number }): value is number => {
const { min = Number.MIN_SAFE_INTEGER, max = Number.MAX_SAFE_INTEGER } = options;
return Number.isInteger(value) && value >= min && value <= max;
};
function paginationHelper<Entity extends ObjectLiteral>(items: Entity[], take: number): PaginationResult<Entity> {
const hasNextPage = items.length > take;
items.splice(take);
@ -86,70 +72,6 @@ export async function paginatedBuilder<Entity extends ObjectLiteral>(
export const asVector = (embedding: number[], quote = false) =>
quote ? `'[${embedding.join(',')}]'` : `[${embedding.join(',')}]`;
/**
* Wraps a method that takes a collection of parameters and sequentially calls it with chunks of the collection,
* to overcome the maximum number of parameters allowed by the database driver.
*
* @param options.paramIndex The index of the function parameter to chunk. Defaults to 0.
* @param options.flatten Whether to flatten the results. Defaults to false.
*/
export function Chunked(options: { paramIndex?: number; mergeFn?: (results: any) => any } = {}): MethodDecorator {
return (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
const originalMethod = descriptor.value;
const parameterIndex = options.paramIndex ?? 0;
descriptor.value = async function (...arguments_: any[]) {
const argument = arguments_[parameterIndex];
// Early return if argument length is less than or equal to the chunk size.
if (
(Array.isArray(argument) && argument.length <= DATABASE_PARAMETER_CHUNK_SIZE) ||
(argument instanceof Set && argument.size <= DATABASE_PARAMETER_CHUNK_SIZE)
) {
return await originalMethod.apply(this, arguments_);
}
return Promise.all(
chunks(argument, DATABASE_PARAMETER_CHUNK_SIZE).map(async (chunk) => {
await Reflect.apply(originalMethod, this, [
...arguments_.slice(0, parameterIndex),
chunk,
...arguments_.slice(parameterIndex + 1),
]);
}),
).then((results) => (options.mergeFn ? options.mergeFn(results) : results));
};
};
}
export function ChunkedArray(options?: { paramIndex?: number }): MethodDecorator {
return Chunked({ ...options, mergeFn: _.flatten });
}
export function ChunkedSet(options?: { paramIndex?: number }): MethodDecorator {
return Chunked({ ...options, mergeFn: setUnion });
}
// https://stackoverflow.com/a/74898678
export function DecorateAll(
decorator: <T>(
target: any,
propertyKey: string,
descriptor: TypedPropertyDescriptor<T>,
) => TypedPropertyDescriptor<T> | void,
) {
return (target: any) => {
const descriptors = Object.getOwnPropertyDescriptors(target.prototype);
for (const [propName, descriptor] of Object.entries(descriptors)) {
const isMethod = typeof descriptor.value == 'function' && propName !== 'constructor';
if (!isMethod) {
continue;
}
decorator({ ...target, constructor: { ...target.constructor, name: target.name } as any }, propName, descriptor);
Object.defineProperty(target.prototype, propName, descriptor);
}
};
}
export function searchAssetBuilder(
builder: SelectQueryBuilder<AssetEntity>,
options: AssetSearchBuilderOptions,