UNPKG

acontplus-core

Version:

Domain-Driven Design (DDD) core library for Angular applications with repository patterns, use cases, JWT authentication, multi-tenant support, pricing calculations, and HTTP interceptors

1,263 lines (1,227 loc) 88.2 kB
import * as i0 from '@angular/core'; import { InjectionToken, Type } from '@angular/core'; import { HttpInterceptorFn, HttpContext, HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { IndividualConfig } from 'ngx-toastr'; import Decimal from 'decimal.js'; import * as acontplus_core from 'acontplus-core'; interface Environment { apiBaseUrl: string; isProduction: boolean; tokenKey: string; refreshTokenKey: string; clientId: string; } /** * @const ENVIRONMENT * Injection token for the environment interface to be provided by the applications. */ declare const ENVIRONMENT: InjectionToken<Environment>; declare const apiInterceptor: HttpInterceptorFn; declare function customUrl(): HttpContext; declare function skipContextHeaders(): HttpContext; declare function withCustomHeaders(headers: Record<string, string>): HttpContext; interface HttpContextConfig { enableCorrelationTracking?: boolean; enableRequestLogging?: boolean; enableErrorLogging?: boolean; customHeaders?: Record<string, string | (() => string)>; clientVersion?: string; tenantIdHeader?: string; correlationIdHeader?: string; requestIdHeader?: string; timestampHeader?: string; excludeUrls?: string[]; includeAuthToken?: boolean; baseUrlInjection?: boolean; } declare const HTTP_CONTEXT_CONFIG: InjectionToken<HttpContextConfig>; declare const httpContextInterceptor: HttpInterceptorFn; interface HttpRequestLog { method: string; url: string; originalUrl: string; requestId: string; correlationId: string; tenantId: string; timestamp: string; headers: string[]; isCustomUrl: boolean; } interface HttpErrorLog extends HttpRequestLog { status: number; statusText: string; message: string; errorDetails: any; environment: string; } declare function createHttpContextConfig(overrides?: Partial<HttpContextConfig>): HttpContextConfig; declare function provideHttpContext(config?: Partial<HttpContextConfig>): { provide: InjectionToken<HttpContextConfig>; useValue: HttpContextConfig; }[]; interface ApiResponse<T = any> { status: 'success' | 'error' | 'warning'; code: string; message?: string; errors?: ApiError[]; data?: T; metadata?: Record<string, any>; timestamp: string; correlationId?: string; traceId?: string; } interface ApiError { code: string; message: string; target?: string; details?: Record<string, any>; severity?: string; category?: string; } interface ApiSuccessResponse<T = any> extends Omit<ApiResponse<T>, 'status'> { status: 'success'; data: T; } interface ApiSuccessMessageResponse extends Omit<ApiResponse, 'status' | 'data'> { status: 'success'; message: string; } interface ApiWarningResponse<T = any> extends Omit<ApiResponse<T>, 'status'> { status: 'warning'; data?: T; message: string; } interface ApiErrorResponse extends Omit<ApiResponse, 'status' | 'data'> { status: 'error'; errors: ApiError[]; } declare function isApiSuccessResponse<T>(response: any): response is ApiSuccessResponse<T>; declare function isApiSuccessMessageResponse(response: any): response is ApiSuccessMessageResponse; declare function isApiWarningResponse<T>(response: any): response is ApiWarningResponse<T>; declare function isApiErrorResponse(response: any): response is ApiErrorResponse; interface BaseEntity { id: number; createdAt?: string; createdByUserId?: number; updatedAt?: string; updatedByUserId?: number; isActive?: boolean; } interface FilterParams { search?: string; role?: string; isActive?: boolean; dateFrom?: string; dateTo?: string; } declare class LegacyApiResponse<T = unknown> { code: string; message: string; payload: T | null; constructor(code?: string, message?: string, payload?: T | null); } interface PaginatedResult<T> { items: T[]; totalCount: number; pageNumber: number; pageSize: number; hasNextPage: boolean; hasPreviousPage: boolean; } interface PaginationParams { page: number; pageSize: number; sortBy?: string; sortDirection?: 'asc' | 'desc'; } interface UseCase<TRequest = void, TResponse = void> { execute(request: TRequest): Observable<TResponse>; } interface UseCaseResult<T> { status: 'success' | 'error' | 'warning'; code: string; message?: string; data?: T; errors?: ApiError[]; metadata?: Record<string, any>; timestamp: string; correlationId?: string; traceId?: string; } declare enum ErrorCategory { BUSINESS = "business", VALIDATION = "validation", INFRASTRUCTURE = "infrastructure", AUTHORIZATION = "authorization", NOT_FOUND = "not_found", CONFLICT = "conflict", TIMEOUT = "timeout", NETWORK = "network", UNKNOWN = "unknown" } interface DomainError extends ApiError { type: ErrorCategory; recoverable?: boolean; retryable?: boolean; userActionable?: boolean; } interface BusinessRuleError extends DomainError { type: ErrorCategory.BUSINESS; ruleId: string; businessContext?: string; } interface ValidationError { field: string; message: string; code: string; } interface ValidationError extends DomainError { type: ErrorCategory.VALIDATION; field: string; constraint?: string; value?: any; } interface AuthorizationError extends DomainError { type: ErrorCategory.AUTHORIZATION; requiredPermissions?: string[]; userRole?: string; resource?: string; } interface NotFoundError extends DomainError { type: ErrorCategory.NOT_FOUND; resourceType: string; resourceId: string | number; } interface ConflictError extends DomainError { type: ErrorCategory.CONFLICT; conflictingResource?: string; conflictReason?: string; } interface PricingConfig { defaultDecimals?: number; roundingMode?: 'round' | 'ceil' | 'floor'; errorHandling?: 'throw' | 'return-null' | 'return-default'; } interface TaxCalculation { baseAmount: number; taxRate: number; taxAmount: number; totalAmount: number; } interface DiscountCalculation { originalPrice: number; discountRate: number; discountAmount: number; finalPrice: number; } interface ProfitMarginCalculation { salePrice: number; cost: number; profitAmount: number; profitMargin: number; } interface LineItemCalculation { unitPrice: number; quantity: number; subtotal: number; discountAmount: number; subtotalAfterDiscount: number; taxAmount: number; total: number; } type HOUR_OF_DAY = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23; type MINUTE_OF_DAY = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59; type SECOND_OF_DAY = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59; /** * 24 hour clock */ type TIME_OF_DAY = { /** * 0 - 23 */ hour: HOUR_OF_DAY; /** * 0 - 59 */ minute: MINUTE_OF_DAY; /** * 0 - 59 */ second: SECOND_OF_DAY; }; declare class PricingCalculationError extends Error { constructor(operation: string, originalError?: Error); } declare class InvalidParameterError extends Error { constructor(parameter: string, value: any); } declare abstract class BaseRepository<T extends BaseEntity> { protected http: HttpClient; protected abstract entityName: string; protected abstract baseUrl: string; getAll?(_pagination: PaginationParams, _filters?: FilterParams): Observable<PaginatedResult<T>>; getById?(_id: number): Observable<T>; create?(_entity: Omit<T, 'id'>): Observable<T>; update?(_id: number, _entity: Partial<T>): Observable<T>; delete?(_id: number): Observable<boolean>; search?(_query: string, _pagination: PaginationParams): Observable<PaginatedResult<T>>; protected get<R>(url: string, params?: any): Observable<R>; protected post<R>(url: string, body: any): Observable<R>; protected put<R>(url: string, body: any): Observable<R>; protected patch<R>(url: string, body: any): Observable<R>; protected deleteHttp<R>(url: string): Observable<R>; protected buildUrl(endpoint: string): string; protected buildEntityUrl(endpoint?: string): string; protected buildQueryParams(pagination: PaginationParams, filters?: FilterParams): any; private handleHttpError; static ɵfac: i0.ɵɵFactoryDeclaration<BaseRepository<any>, never>; static ɵprov: i0.ɵɵInjectableDeclaration<BaseRepository<any>>; } declare abstract class ReadOnlyRepository<T extends BaseEntity> extends BaseRepository<T> { abstract getAll(pagination: PaginationParams, filters?: FilterParams): Observable<PaginatedResult<T>>; abstract getById(id: number): Observable<T>; abstract search(query: string, pagination: PaginationParams): Observable<PaginatedResult<T>>; create(): never; update(): never; delete(): never; } declare abstract class WriteOnlyRepository<T extends BaseEntity> extends BaseRepository<T> { abstract create(entity: Omit<T, 'id'>): Observable<T>; abstract update(id: number, entity: Partial<T>): Observable<T>; abstract delete(id: number): Observable<boolean>; getAll(): never; getById(): never; search(): never; } declare class CorrelationService { private correlationId; private readonly CORRELATION_KEY; readonly currentCorrelationId: i0.Signal<string | null>; getOrCreateCorrelationId(): string; setCorrelationId(correlationId: string): void; resetCorrelationId(): void; getId(): string; static ɵfac: i0.ɵɵFactoryDeclaration<CorrelationService, never>; static ɵprov: i0.ɵɵInjectableDeclaration<CorrelationService>; } declare class JwtTokenService { private environment; private router; getToken(): string | null; getRefreshToken(): string | null; setToken(token: string, rememberMe?: boolean): void; setRefreshToken(refreshToken: string, rememberMe?: boolean): void; removeTokens(): void; isTokenValid(): boolean; getTokenPayload(): any; handleUnauthorized(): void; getUserId(): string | null; getUserRoles(): string[]; getTenantFromToken(): string | null; static ɵfac: i0.ɵɵFactoryDeclaration<JwtTokenService, never>; static ɵprov: i0.ɵɵInjectableDeclaration<JwtTokenService>; } declare class LoggingService { private environment; log(level: 'info' | 'warn' | 'error', message: string, context?: any): void; info(message: string, context?: any): void; warn(message: string, context?: any): void; error(message: string, context?: any): void; logHttpRequest(log: HttpRequestLog): void; logHttpError(error: HttpErrorLog): void; logNetworkError(correlationId: string): void; logRateLimitError(correlationId: string, url: string): void; private logToExternalService; static ɵfac: i0.ɵɵFactoryDeclaration<LoggingService, never>; static ɵprov: i0.ɵɵInjectableDeclaration<LoggingService>; } interface ResponseResult<T> { data?: T; message?: string; metadata?: Record<string, any>; correlationId?: string; traceId?: string; } declare class ResponseHandlerService { /** * Handles API responses and extracts the appropriate data/message * @param response The response from the API (already processed by interceptor) * @returns A structured result with data and/or message */ handleResponse<T>(response: any): ResponseResult<T>; /** * Extracts only the data from a response (for operations that should return entities) * @param response The response from the API * @returns The extracted data */ extractData<T>(response: any): T; /** * Extracts only the message from a response (for operations that return success messages) * @param response The response from the API * @returns The success message */ extractMessage(response: any): string | undefined; /** * Checks if the response contains data * @param response The response from the API * @returns True if the response contains data */ hasData(response: any): boolean; /** * Checks if the response contains a success message * @param response The response from the API * @returns True if the response contains a success message */ hasMessage(response: any): boolean; static ɵfac: i0.ɵɵFactoryDeclaration<ResponseHandlerService, never>; static ɵprov: i0.ɵɵInjectableDeclaration<ResponseHandlerService>; } declare class TenantService { private tenantId; getTenantId(): string; getCurrentTenant(): string | null; setTenantId(tenantId: string): void; setTenant(tenantId: string): void; handleForbidden(): void; private extractTenantFromToken; clearTenant(): void; static ɵfac: i0.ɵɵFactoryDeclaration<TenantService, never>; static ɵprov: i0.ɵɵInjectableDeclaration<TenantService>; } type ToastrType = 'success' | 'error' | 'warning' | 'info'; type ToastrNotificationConfig = Partial<IndividualConfig>; declare const TOASTR_NOTIFICATION_CONFIG: InjectionToken<Partial<IndividualConfig<any>>>; interface ToastrCallProps { readonly message: string; readonly title?: string; readonly options?: Partial<IndividualConfig>; } interface ToastrShowProps extends ToastrCallProps { readonly type: ToastrType; } declare class ToastrNotificationService { private readonly toastrService; private readonly config; /** * Generic show method for dynamic toast types */ show(props: ToastrShowProps): void; /** * Ergonomic helper methods for specific types */ success(props: ToastrCallProps): void; error(props: ToastrCallProps): void; warning(props: ToastrCallProps): void; info(props: ToastrCallProps): void; static ɵfac: i0.ɵɵFactoryDeclaration<ToastrNotificationService, never>; static ɵprov: i0.ɵɵInjectableDeclaration<ToastrNotificationService>; } interface CoreConfig { apiBaseUrl?: string; apiTimeout?: number; retryAttempts?: number; retryDelay?: number; enableCorrelationTracking?: boolean; enableRequestLogging?: boolean; enableErrorLogging?: boolean; enableToastNotifications?: boolean; includeAuthToken?: boolean; authTokenHeader?: string; enableMultiTenancy?: boolean; tenantIdHeader?: string; logLevel?: 'debug' | 'info' | 'warn' | 'error'; enableConsoleLogging?: boolean; customHeaders?: Record<string, string | (() => string)>; excludeUrls?: string[]; excludeMethods?: string[]; } declare const CORE_CONFIG: InjectionToken<CoreConfig>; declare class CoreConfigService { private config; private environment; constructor(); /** * Initialize configuration with defaults and environment overrides */ private initializeConfig; /** * Get the current configuration */ getConfig(): Required<CoreConfig>; /** * Update configuration at runtime */ updateConfig(updates: Partial<CoreConfig>): void; /** * Get a specific configuration value */ get<K extends keyof CoreConfig>(key: K): CoreConfig[K]; /** * Check if a feature is enabled */ isFeatureEnabled(feature: keyof CoreConfig): boolean; /** * Get API URL for a specific entity */ getApiUrl(entityName?: string): string; /** * Check if a URL should be excluded from processing */ shouldExcludeUrl(url: string): boolean; /** * Check if a method should be excluded from processing */ shouldExcludeMethod(method: string): boolean; /** * Get custom headers with dynamic values resolved */ getCustomHeaders(): Record<string, string>; /** * Reset configuration to defaults */ resetConfig(): void; static ɵfac: i0.ɵɵFactoryDeclaration<CoreConfigService, never>; static ɵprov: i0.ɵɵInjectableDeclaration<CoreConfigService>; } declare function provideCoreConfig(config?: Partial<CoreConfig>): { provide: InjectionToken<CoreConfig>; useValue: Partial<CoreConfig>; }[]; declare function createCoreConfig(overrides?: Partial<CoreConfig>): CoreConfig; interface RepositoryConfig<T extends BaseRepository<any>> { type: Type<T>; entityName: string; baseUrl: string; options?: { enableCaching?: boolean; enableAuditing?: boolean; customInterceptors?: any[]; }; } declare class RepositoryFactoryService { private http; private repositories; /** Inserted by Angular inject() migration for backwards compatibility */ constructor(...args: unknown[]); /** * Create a full CRUD repository */ createFullRepository<T extends BaseRepository<any>>(config: RepositoryConfig<T>): T; /** * Create a read-only repository */ createReadOnlyRepository<T extends BaseEntity>(entityName: string, baseUrl: string): ReadOnlyRepository<T>; /** * Create a write-only repository */ createWriteOnlyRepository<T extends BaseEntity>(entityName: string, baseUrl: string): WriteOnlyRepository<T>; /** * Create a custom repository with specific operations */ createCustomRepository<T extends BaseEntity>(entityName: string, baseUrl: string, operations: Partial<BaseRepository<T>>): BaseRepository<T>; /** * Get an existing repository by key */ getRepository<T extends BaseRepository<any>>(key: string): T | undefined; /** * Clear all repositories (useful for testing) */ clearRepositories(): void; static ɵfac: i0.ɵɵFactoryDeclaration<RepositoryFactoryService, never>; static ɵprov: i0.ɵɵInjectableDeclaration<RepositoryFactoryService>; } declare abstract class BaseUseCase<TRequest = void, TResponse = void> implements UseCase<TRequest, TResponse> { protected responseHandler: ResponseHandlerService; protected loggingService: LoggingService; execute(request: TRequest): Observable<TResponse>; protected abstract executeInternal(request: TRequest): Observable<TResponse>; protected validate(request: TRequest): ValidationError[]; protected checkAuthorization(request: TRequest): Promise<boolean>; protected createSuccessResult<T>(data: T, message?: string, code?: string, metadata?: Record<string, any>): UseCaseResult<T>; protected createWarningResult<T>(data: T, code: string, message: string, metadata?: Record<string, any>): UseCaseResult<T>; protected createErrorResult<T>(code: string, message: string, errors?: ApiError[], metadata?: Record<string, any>): UseCaseResult<T>; protected createValidationErrorResult<T>(validationErrors: ValidationError[]): UseCaseResult<T>; protected executeWithValidation(request: TRequest): Observable<TResponse>; protected handleError(error: any): UseCaseResult<any>; protected extractFromApiResponse<T>(response: ApiResponse<T>): T; protected extractMessageFromApiResponse(response: any): string | undefined; protected hasDataInResponse(response: any): boolean; protected hasMessageInResponse(response: any): boolean; } declare abstract class Command<TRequest, TResponse = void> extends BaseUseCase<TRequest, TResponse> { protected validate(request: TRequest): ValidationError[]; protected checkAuthorization(request: TRequest): Promise<boolean>; execute(request: TRequest): Observable<TResponse>; protected shouldValidate(): boolean; } declare abstract class CreateCommand<TEntity, TResponse = TEntity> extends Command<Omit<TEntity, 'id'>, TResponse> { protected validate(request: Omit<TEntity, 'id'>): ValidationError[]; protected validateForCreation(request: Omit<TEntity, 'id'>): ValidationError[]; } declare abstract class UpdateCommand<TEntity, TResponse = TEntity> extends Command<{ id: number; data: Partial<TEntity>; }, TResponse> { protected validate(request: { id: number; data: Partial<TEntity>; }): ValidationError[]; protected validateForUpdate(request: { id: number; data: Partial<TEntity>; }): ValidationError[]; } declare abstract class DeleteCommand extends Command<{ id: number; }, boolean> { protected validate(request: { id: number; }): ValidationError[]; protected validateForDeletion(request: { id: number; }): ValidationError[]; } declare abstract class BulkCommand<TRequest, TResponse> extends Command<TRequest, TResponse> { protected abstract executeBulk(request: TRequest): Observable<TResponse>; } declare abstract class ConditionalCommand<TRequest, TResponse> extends Command<TRequest, TResponse> { protected abstract checkConditions(request: TRequest): Observable<boolean>; execute(request: TRequest): Observable<TResponse>; } declare abstract class Queries<TRequest, TResponse> extends BaseUseCase<TRequest, TResponse> { protected shouldValidate(): boolean; protected checkAuthorization(): Promise<boolean>; } declare abstract class GetByIdQuery<TEntity> extends Queries<{ id: number; }, TEntity> { protected validate(request: { id: number; }): ValidationError[]; } declare abstract class GetAllQuery<TEntity> extends Queries<{ pagination: PaginationParams; filters?: FilterParams; }, PaginatedResult<TEntity>> { protected validate(request: { pagination: PaginationParams; filters?: FilterParams; }): ValidationError[]; } declare abstract class SearchQuery<TEntity> extends Queries<{ query: string; pagination: PaginationParams; }, PaginatedResult<TEntity>> { protected validate(request: { query: string; pagination: PaginationParams; }): ValidationError[]; private validatePagination; } declare abstract class CachedQuery<TRequest, TResponse> extends Queries<TRequest, TResponse> { protected abstract getCacheKey(request: TRequest): string; protected abstract getCacheDuration(): number; execute(request: TRequest): Observable<TResponse>; } declare abstract class StreamingQuery<TRequest, TResponse> extends Queries<TRequest, TResponse> { protected abstract executeStreaming(request: TRequest): Observable<TResponse>; execute(request: TRequest): Observable<TResponse>; } interface CompositeUseCaseContext { correlationId?: string; userId?: string; timestamp?: string; metadata?: Record<string, any>; } declare abstract class CompositeUseCase<TRequest = void, TResponse = void> extends BaseUseCase<TRequest, TResponse> { protected context?: CompositeUseCaseContext; withContext(context: CompositeUseCaseContext): this; protected combineOperations<T1, T2>(op1: Observable<T1>, op2: Observable<T2>): Observable<[T1, T2]>; protected chainOperations<T1, T2>(op1: Observable<T1>, op2: (result: T1) => Observable<T2>): Observable<T2>; protected executeParallel<T extends readonly unknown[]>(operations: { [K in keyof T]: Observable<T[K]>; }): Observable<T>; protected executeSequential<T extends readonly unknown[]>(operations: { [K in keyof T]: Observable<T[K]>; }): Observable<T>; protected withRollback<T>(operation: Observable<T>, rollback: () => Observable<void>): Observable<T>; protected createAuditTrail(action: string, resource: string, details?: any): void; } declare function getRandomColor(opacity: number): string; declare function getRandomHexColor(): string; declare class ArrayUtils { /** * check whether current array is empty or null/undefined. * @param array * @returns true if array is empty or null/undefined; otherwise, false. * @throws if input parameter is not array type or null/undefined * @example ArrayUtils.isEmpty([]) = true; * @example ArrayUtils.isEmpty(null) = true; * @example ArrayUtils.isEmpty(undefined) = true; * @example ArrayUtils.isEmtpy([1]) = false; * @example ArrayUtils.isEmtpy("string") throw error; * @example ArrayUtils.isEmtpy(123) throw error; */ static isEmpty<T>(array: T[] | undefined | null): boolean; /** * check whether current array is not empty or null/undefined. * @param array * @returns false if array is empty or null/undefined; otherwise, true. * @throws if input parameter is not array type or null/undefined * @example ArrayUtils.isNotEmpty([]) = false; * @example ArrayUtils.isNotEmpty(null) = false; * @example ArrayUtils.isNotEmpty(undefined) = false; * @example ArrayUtils.isNotEmpty([1]) = true; * @example ArrayUtils.isNotEmpty("string") throw error; * @example ArrayUtils.isNotEmpty(123) throw error; */ static isNotEmpty<T>(array: T[] | undefined | null): boolean; /** * Determines whether an element is in the array. * @param array * @param item * @returns true if item is in the array; otherwise, false. * @example ArrayUtils.contains(null, 1) = false * @example ArrayUtils.contains(undefined, 1) = false * @example ArrayUtils.contains([], 1) = false * @example ArrayUtils.contains([1,2,3], 1) = true * @example ArrayUtils.contains([1,2,3], 5) = false * @example ArrayUtils.contains([1,2,3], null) = false * @example ArrayUtils.contains([1,2,3], undefined) = false */ static contains<T>(array: T[], item: T): boolean; /** * Determines whether any of candidates is in the array. * @param array * @param candidates * @returns true if item is in the array; otherwise, false. * @example ArrayUtils.containsAny(null, [1, 2]) = false * @example ArrayUtils.containsAny(undefined, [1, 2]) = false * @example ArrayUtils.containsAny([1, 3, 5], [1, 2]) = true * @example ArrayUtils.containsAny([1, 3, 5], [2, 4, 6]) = false * @example ArrayUtils.containsAny([1, 3, 5], null) = false * @example ArrayUtils.containsAny([1, 3, 5], undefined) = false */ static containsAny<T>(array: T[], candidates: T[]): boolean; /** * Determines whether all of candidates is in the array. * @param array * @param candidates * @returns true if item is in the array; otherwise, false. * @example ArrayUtils.containsAll(null, [1, 2]) = false * @example ArrayUtils.containsAll(undefined, [1, 2]) = false * @example ArrayUtils.containsAll([1, 3, 5], [1, 2]) = false * @example ArrayUtils.containsAll([1, 3, 5], [1, 3]) = true **/ static containsAll<T>(array: T[], candidates: T[]): boolean; /** * Inserts an element into the array at the specified index. * @param array * @param index The zero-based index at which item should be inserted. * @param item The object to insert. The value can be null for reference types. * @returns true if insert successfully, otherwise false. * @example ArrayUtils.insert([1, 3], 1, 2) ==> [1, 2, 3] * @example ArrayUtils.insert([1, 2], 100, 4) = false // greater than array.length. */ static insert<T>(array: T[], index: number, item: T): boolean; /** * Removes the first occurrence of a specific object from the array. * @param array * @param item * @returns true if item is successfully removed; otherwise, false. * @example ArrayUtils.remove([1, 2, 3], 2) = true * @example ArrayUtils.remove([1, 2, 3], 5) = false */ static remove<T>(array: T[], item: T): boolean; /** * Find the max number value from array. * @param array * @returns the max value of the number array. * @example ArrayUtils.max([1,5,3,2,4]) = 5 */ static max(array: number[]): number; /** * Find the min number value from array. * @param array * @returns the max value of the number array. * @example ArrayUtils.min([1,5,3,2,4]) = 1 */ static min(array: number[]): number; static take<T>(array: T[], n?: number | undefined | null): T[]; /** * Creates a slice of array with n items taken from the end. * @param array * @param n * @returns Array - The slice of the array. * @example ArrayUtils.takeRight([1, 2, 3, 4, 5]) = [5] * @example ArrayUtils.takeRight([1, 2, 3, 4, 5], null) = [5] * @example ArrayUtils.takeRight([1, 2, 3, 4, 5], NaN) = [5] * @example ArrayUtils.takeRight([1, 2, 3, 4, 5], 3) = [3, 4, 5] * @example ArrayUtils.takeRight([1, 2, 3, 4, 5], 0) = [] * @example ArrayUtils.takeRight([1, 2, 3, 4, 5], -2) = [] * @example ArrayUtils.takeRight([1, 2, 3, 4, 5], 10) = [1, 2, 3, 4, 5] * @example ArrayUtils.takeRight([1, 2, 3, 4, 5], Number.MAX_VALUE) = [1, 2, 3, 4, 5] */ static takeRight<T>(array: T[], n?: number | undefined | null): T[]; } declare class DateUtils { private static timeFormatRegex; /** * Adds a number of years to a date returning a new object. The original Date is unchanged. * * @param date the date, not null * @param years the years to add, may be negative * @returns the new Date with the amount added * @example DateUtils.addYears(new Date(2018, 5, 1), 1) = new Date(2019, 5, 1) */ static addYears(date: Date, years: number): Date; /** * Adds a number of months to a date returning a new object. The original Date is unchanged. * * @param date the date, not null * @param months the months to add, may be negative * @returns the new Date with the months added * @example DateUtils.addMonths(new Date(2018, 5, 1), 1) = new Date(2018, 6, 1) */ static addMonths(date: Date, months: number): Date; /** * Adds a number of days to a date returning a new object. The original Date is unchanged. * * @param date the date, not null * @param days the days to add, may be negative * @returns the new Date with the days added * @example DateUtils.addDays(new Date(2018, 5, 1), 1) = new Date(2018, 5, 2) */ static addDays(date: Date, days: number): Date; /** * Adds a number of hours to a date returning a new object. The original Date is unchanged. * * @param date the date, not null * @param hours the hours to add, may be negative * @returns the new Date with the hours added * @example DateUtils.addHours(new Date(2018, 5, 1), 1) = new Date(2018, 5, 1, 1) */ static addHours(date: Date, hours: number): Date; /** * Adds a number of minutes to a date returning a new object. The original Date is unchanged. * * @param date date – the date, not null * @param minutes the minutes to add, may be negative * @returns the new Date with the minutes added * @example DateUtils.addMinutes(new Date(2018, 5, 1), 1) = new Date(2018, 5, 1, 0, 1) */ static addMinutes(date: Date, minutes: number): Date; /** * Adds a number of seconds to a date returning a new object. The original Date is unchanged. * * @param date the date, not null * @param seconds the seconds to add, may be negative * @returns the new Date with the seconds added * @example DateUtils.addSeconds(new Date(2018, 5, 1), 1) = new Date(2018, 5, 1, 0, 0, 1) */ static addSeconds(date: Date, seconds: number): Date; /** * The day of week. * * @param date the date, not null * @returns the day of week. * @example DateUtils.getDayOfWeek(new Date(2024, 11, 23)) = 6 */ static getDayOfWeek(date: Date): number; /** * The day of month * * @param date the date, not null. * @returns the day of month. * @example DateUtils.getDayOfMonth(new Date(2024, 11, 23)) = 23 */ static getDaysInMonth(date: Date): number; /** * Returns the number of milliseconds that have elapsed since 1970-01-01T00:00:00.000Z. * @param date * @example DateUtils.dateToTimestamp(null) = 0 * @example DateUtils.dateToTimestamp(undefined) = 0 * @example DateUtils.dateToTimestamp(new Date("Tue, 19 Jun 2018 00:00:00 GMT")) = 1529366400000 */ static dateToTimestamp(date: Date): number; /** * Get date from the number of milliseconds that have elapsed since 1970-01-01T00:00:00.000Z. * @param timestamp * @example DateUtils.timestampToDate(1529366400) = new Date("Tue, 19 Jun 2018 00:00:00 GMT") */ static timestampToDate(timestamp: number): Date; /** * Get currnet date without hours, minutes and seconds. */ static getToday(): Date; /** * Converts the value of the current date to its equivalent string representation * using the specified format. * @param date * @param format * "yyyy" Year represented by four digits. * "yy" Year as last two digits; leading zero for years less than 10. * "MM" Month as digits; leading zero for single-digit months. * "M" Month as digits; no leading zero for single-digit months. * "dd" Day of the month as digits; leading zero for single-digit days. * "d" Day of the month as digits; no leading zero for single-digit days. * "HH" Hours; leading zero for single-digit hours (24-hour clock). * "H" Hours; no leading zero for single-digit hours (24-hour clock). * "mm" Minutes; leading zero for single-digit minutes. * "m" Minutes; no leading zero for single-digit minutes. * "ss" Seconds; leading zero for single-digit seconds. * "s" Seconds; no leading zero for single-digit seconds. * "SSS" Milliseconds; leading zero for single-digit seconds. * "S" Milliseconds; no leading zero for single-digit seconds. */ static toString(date: Date, format?: string): string; /** * Converts the value of the current UTC date to its equivalent string representation * using the specified format. * @param date * @param format * "yyyy" Year represented by four digits. * "yy" Year as last two digits; leading zero for years less than 10. * "MM" Month as digits; leading zero for single-digit months. * "M" Month as digits; no leading zero for single-digit months. * "dd" Day of the month as digits; leading zero for single-digit days. * "d" Day of the month as digits; no leading zero for single-digit days. * "HH" Hours; leading zero for single-digit hours (24-hour clock). * "H" Hours; no leading zero for single-digit hours (24-hour clock). * "mm" Minutes; leading zero for single-digit minutes. * "m" Minutes; no leading zero for single-digit minutes. * "ss" Seconds; leading zero for single-digit seconds. * "s" Seconds; no leading zero for single-digit seconds. * "SSS" Milliseconds; leading zero for single-digit seconds. * "S" Milliseconds; no leading zero for single-digit seconds. */ static toUTCString(date: Date, format?: string): string; /** * Compares two date and returns a value indicating whether one is less than, equal to, or greater than the other. * @param date1 * @param date2 * @returns * - If less than 0, date1 is less than date2. * - If 0, date1 equals date2. * - If greater than 0, date1 is greater than date2. */ static compare(date1: Date, date2: Date): number; /** * Checks if a given date falls within a specified time range (comparing only hours, minutes, and seconds) * @param timestamp The timestamp to check (in milliseconds) * @param startTime Start time containing hour, minute, second * @param endTime End time containing hour, minute, second * @returns true if the timestamp is within the specified range, false otherwise * @example TimestampUtils.isInTimeRange(new Date(2023, 0, 1, 10, 30, 0), { hour: 9, minute: 0, second: 0 }, { hour: 11, minute: 0, second: 0 }) = true * @example TimestampUtils.isInTimeRange(new Date(2023, 0, 1, 23, 30, 0), { hour: 23, minute: 0, second: 0 }, { hour: 1, minute: 0, second: 0 }) = true */ static isInTimeRange<T extends TIME_OF_DAY>(date: Date, startTime: T, endTime: T): boolean; /** * Checks if two dates are the same at the specified unit of granularity. * * @param date1 The first date to compare * @param date2 The second date to compare * @param unit The unit to compare ('year' | 'month' | 'day' | 'hour' | 'minute' | 'second' | 'millisecond') * @returns true if the dates are the same at the specified unit, false otherwise * @example DateUtils.isSame(new Date(2024, 0, 1), new Date(2024, 0, 1), 'day') = true * @example DateUtils.isSame(new Date(2024, 0, 1), new Date(2024, 0, 2), 'year') = true */ static isSame(date1: Date, date2: Date, unit?: 'year' | 'month' | 'day' | 'hour' | 'minute' | 'second' | 'millisecond'): boolean; /** * Checks if a Date object is valid. * * @param date The date to check * @returns true if the date is valid, false otherwise * @example DateUtils.isValid(new Date()) = true * @example DateUtils.isValid(new Date('Invalid Date')) = false * @example DateUtils.isValid(DateUtils.invalid()) = false * @example DateUtils.isValid(null) = false * @example DateUtils.isValid(undefined) = false */ static isValid(date: Date): boolean; private static getTimeFormat; } declare class NumberUtils { static readonly MAX_SAFE_INTEGER: number; static readonly MIN_SAFE_INTEGER: number; /** * check whether current value is integer * @param value * @example Number.isInteger(0); // true * @example Number.isInteger(1); // true * @example Number.isInteger(-100000); // true * @example Number.isInteger(99999999999999999999999); // true * @example Number.isInteger(0.1); // false * @example Number.isInteger(Math.PI); // false * @example Number.isInteger(NaN); // false * @example Number.isInteger(Infinity); // false * @example Number.isInteger(-Infinity); // false * @example Number.isInteger('10'); // false * @example Number.isInteger(true); // false * @example Number.isInteger(false); // false * @example Number.isInteger([1]); // false */ static isInteger(value: any): boolean; /** * check whether current value is safe integer * @param value * @example Number.isSafeInteger(3); // true * @example Number.isSafeInteger(Math.pow(2, 53)); // false * @example Number.isSafeInteger(Math.pow(2, 53) - 1); // true * @example Number.isSafeInteger(NaN); // false * @example Number.isSafeInteger(Infinity); // false * @example Number.isSafeInteger('3'); // false * @example Number.isSafeInteger(3.1); // false * @example Number.isSafeInteger(3.0); // true */ static isSafeInteger(value: any): boolean; /** * Returns a string representing a number in fixed-point notation. * @param value target value. * @param fractionDigits Number of digits after the decimal point. Must be in the range 0 - 20, inclusive. * @param defaultValue default value if value is empty. */ static toFixed(value: number | null | undefined, fractionDigits: number, defaultValue?: string): string; /** * compare two numbers * @param num1 number 1 * @param num2 number 2 * @returns 0: num1 === num2, -1: num1 < num2, 1: num1 > num2 */ static compare(num1: number, num2: number): number; static isNumber(value: any): boolean; static isPositive(value: number): boolean; static isPercentage(value: number): boolean; } declare class ObjectUtils { /** * check whether value is null. * @param value * @example ObjectUtils.isNull(null) = true * @example ObjectUtils.isNull(undefinend) = false * @example ObjectUtils.isNull({}) = false * @example ObjectUtils.isNull(1) = false */ static isNull(value: unknown): value is null; /** * check whether value is undefined. * @param value * @example ObjectUtils.isUndefined(undefinend) = true * @example ObjectUtils.isUndefined(null) = false * @example ObjectUtils.isUndefined({}) = false * @example ObjectUtils.isUndefined(1) = false */ static isUndefined(value: unknown): value is undefined; /** * check whether value is null or undefined. * @param value * @example ObjectUtils.isNullOrUndefined(undefinend) = true * @example ObjectUtils.isNullOrUndefined(null) = true * @example ObjectUtils.isNullOrUndefined({}) = false * @example ObjectUtils.isNullOrUndefined(1) = false */ static isNullOrUndefined(value: unknown): value is null | undefined; /** * check whether value is array. * @param value * @example ObjectUtils.isArray([]) = true * @example ObjectUtils.isArray(null) = false * @example ObjectUtils.isArray(undefinend) = false * @example ObjectUtils.isArray(1) = false */ static isArray(value: unknown): value is any[]; /** * check whether value is date. * @param value * @example ObjectUtils.isDate(new Date()) = true * @example ObjectUtils.isDate(null) = false * @example ObjectUtils.isDate(undefinend) = false * @example ObjectUtils.isDate(1) = false */ static isDate(value: unknown): value is Date; /** * check whether value is string. * @param value * @example ObjectUtils.isString("test") = true * @example ObjectUtils.isString(null) = false * @example ObjectUtils.isString(undefinend) = false * @example ObjectUtils.isString(1) = false */ static isString(value: unknown): value is string; /** * check whether value is number. * @param value * @example ObjectUtils.isNumber(1) = true * @example ObjectUtils.isNumber(null) = false * @example ObjectUtils.isNumber(undefinend) = false * @example ObjectUtils.isNumber("test") = false */ static isNumber(value: unknown): value is number; /** * check whether value is boolean. * @param value * @example ObjectUtils.isBoolean(false) = true * @example ObjectUtils.isBoolean(null) = false * @example ObjectUtils.isBoolean(undefinend) = false * @example ObjectUtils.isBoolean("test") = false */ static isBoolean(value: unknown): value is boolean; /** * Returns a string representation of an object even if value is null or undefined. * @param value * @param defaultValue * @example ObjectUtils.toSafeString(null) = "" * @example ObjectUtils.toSafeString(undefined) = "" * @example ObjectUtils.toSafeString("test") = "test" * @example ObjectUtils.toSafeString(null, "--") = "--" * @example ObjectUtils.toSafeString(undefined, "--") = "--" */ static toSafeString(value: any, defaultValue?: string): string; /** * get property value of object by key. * @param obj * @param key * @param defaultValue */ static getProperty<T, K extends keyof T>(obj: T, key: K, defaultValue?: T[K]): T[K] | undefined; /** * get property value of object by key1 key2. * @param obj * @param key1 * @param key2 * @param defaultValue * @returns */ static getProperty2<T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2, defaultValue?: T[K1][K2]): T[K1][K2] | undefined; static getProperty3<T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3, defaultValue?: T[K1][K2][K3]): T[K1][K2][K3] | undefined; /** * set property to object. * @param obj * @param key * @param value */ static setProperty<T, K extends keyof T>(obj: T, key: K, value: T[K]): void; /** * Create object by type. * @param type - constructor function */ static createObject<T>(type: (new () => T) | null | undefined): T | null; /** * get name of property. * @param key */ static getPropertyName<T>(key: keyof T): string; static values<T extends object>(obj: T): any[]; /** * get matching descendant property. * @param obj * @param descendantPaths * @example ObjectUtils.getDescendantProperty({p1: {p2 : 1}}) = {p1: {p2 : 1}} * @example ObjectUtils.getDescendantProperty({p1: {p2 : 1}}, "p1") = {p2 : 1} * @example ObjectUtils.getDescendantProperty({p1: {p2 : 1}}, "p1", "p2") = 1 * @example ObjectUtils.getDescendantProperty({p1: {p2 : 1}}, "p1", "p3") = undefined * @example ObjectUtils.getDescendantProperty(undefined) = undefined * @example ObjectUtils.getDescendantProperty(null) = undefined */ static getDescendantProperty(obj: any, ...descendantPaths: string[]): NonNullable<any> | undefined; /** * If value is null or undefined, return the first non-null/undefined default value provided. * If all are null/undefined, return undefined. * * @param value1 First value to check * @param value2 Second value to check (optional) * @param value3 Third value to check (optional) * @param defaultValue Value to return if all others are null or undefined (optional) * * @example ObjectUtils.getOrDefault<number | undefined>(1, 0) = 1 * @example ObjectUtils.getOrDefault<number | undefined>(undefined, 0) = 0 * @example ObjectUtils.getOrDefault<number | null>(1, 0) = 1 * @example ObjectUtils.getOrDefault<number | null>(null, 0) = 0 * @example ObjectUtils.getOrDefault<number | null>(1, 2, 3) = 1 * @example ObjectUtils.getOrDefault<number | null>(null, 2, 3) = 2 * @example ObjectUtils.getOrDefault<number | null>(null, null, 3) = 3 * @example ObjectUtils.getOrDefault<number | null>(null, null, null) = undefined * @example ObjectUtils.getOrDefault<number | null>(null, null, null, 3)= 3 */ static getOrDefault<T>(value1: T, value2?: T, value3?: T, defaultValue?: NonNullable<T>): NonNullable<T> | undefined; /** * Indicating whether the current object has a value. * @param object * @returns true if current object is not null or undefined, else return false. * @example ObjectUtils.hasValue(1) = true * @example ObjectUtils.hasValue("str") = true * @example ObjectUtils.hasValue(undefined) = false * @example ObjectUtils.hasValue(null) = false */ static hasValue<T>(object: T): object is NonNullable<T>; } declare class RegexUtils { /** * Escapes all reserved characters for regular expressions by preceding them with a backslash. * @param str target string * @example * => \* * @example ? => \? * @example { => \{ * @example } => \} */ static escapeRegExp(str: string): string; /** * 3 to 16 letters, numbers, underscores, or hyphens * @param username */ static validateUsername(username: string): boolean; /** * Minimum eight characters, at least one letter and one number: * @param password */ static validatePassword(password: string): boolean; /** * valid current input is email format. */ static validateEmail(email: string): boolean; } type NullableString = string | undefined | null; declare class StringUtils { static readonly EMPTY: string; static readonly INDEX_NOT_FOUND: number; /** * check current string is empty. * @param str * @example StringUtils.isEmpty(null) = true * @example StringUtils.isEmpty(undefined) = true * @example StringUtils.isEmpty("") = true * @example StringUtils.isEmpty(" ") = false * @example StringUtils.isEmpty("bob") = false * @example StringUtils.isEmpty(" bob ") = false */ static isEmpty(str: NullableString): boolean; /** * check current string is not empty. * @param str * @example StringUtils.isNotEmpty(null) = false * @example StringUtils.isNotEmpty(undefined) = false * @example StringUtils.isNotEmpty("") = false * @example StringUtils.isNotEmpty(" ") = true * @example StringUtils.isNotEmpty("bob") = true * @example StringUtils.isNotEmpty(" bob ") = true */ static isNotEmpty(str: NullableString): str is NonNullable<NullableString>; /** * check current string is blank. * @param str * @example StringUtils.isBlank(null) = true * @example StringUtils.isBlank(undefined) = true * @example StringUtils.isBlank("") = true * @example StringUtils.isBlank(" ") = true * @example StringUtils.isBlank("bob") = false * @example StringUtils.isBlank(" bob ") = false */ static isBlank(str: NullableString): boolean; /** * check current string is not blank. * @param str * @example StringUtils.isNotBlank(null) = false * @example StringUtils.isNotBlank(undefined) = false * @example StringUtils.isNotBlank("") = false * @example