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
TypeScript
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