UNPKG

@etsoo/appscript

Version:

Applications shared TypeScript framework

755 lines (754 loc) 22.5 kB
import { INotifier, NotificationAlign, NotificationCallProps, NotificationContent, NotificationReturn } from "@etsoo/notificationbase"; import { ApiDataError, IApi, IPData } from "@etsoo/restclient"; import { DataTypes, DateUtils, ErrorData, ErrorType, IActionResult, IStorage, ListType, ListType1 } from "@etsoo/shared"; import { AddressRegion } from "../address/AddressRegion"; import { EntityStatus } from "../business/EntityStatus"; import { InitCallDto } from "../api/dto/InitCallDto"; import { InitCallResult, InitCallResultData } from "../result/InitCallResult"; import { IUser } from "../state/User"; import { IAppSettings } from "./AppSettings"; import { AppLoginParams, AppTryLoginParams, FormatResultCustomCallback, IApp, IAppFields, IDetectIPCallback, NavigateOptions, RefreshTokenProps } from "./IApp"; import { UserRole } from "./UserRole"; import { ExternalEndpoint } from "./ExternalSettings"; import { ApiRefreshTokenDto } from "../api/dto/ApiRefreshTokenDto"; import { ApiRefreshTokenRQ } from "../api/rq/ApiRefreshTokenRQ"; import { AuthApi } from "../api/AuthApi"; type ApiRefreshTokenFunction = (api: IApi, rq: ApiRefreshTokenRQ) => Promise<[string, number] | undefined>; type ApiTaskData = [IApi, number, number, ApiRefreshTokenFunction, string?]; /** * Core application interface */ export interface ICoreApp<U extends IUser, S extends IAppSettings, N, C extends NotificationCallProps> extends IApp { /** * Settings */ readonly settings: S; /** * Notifier */ readonly notifier: INotifier<N, C>; /** * User data */ userData?: U; } /** * Core application */ export declare abstract class CoreApp<U extends IUser, S extends IAppSettings, N, C extends NotificationCallProps> implements ICoreApp<U, S, N, C> { /** * Settings */ readonly settings: S; /** * Default region */ readonly defaultRegion: AddressRegion; /** * Fields */ readonly fields: IAppFields; /** * API, not recommend to use it directly in code, wrap to separate methods */ readonly api: IApi; /** * Application name */ readonly name: string; /** * Notifier */ readonly notifier: INotifier<N, C>; /** * Storage */ readonly storage: IStorage; /** * Pending actions */ readonly pendings: (() => any)[]; /** * Debug mode */ readonly debug: boolean; private _culture; /** * Culture, like zh-CN */ get culture(): string; private _currency; /** * Currency, like USD for US dollar */ get currency(): "AUD" | "CAD" | "CNY" | "EUR" | "GBP" | "HKD" | "JPY" | "NZD" | "SGD" | "USD"; private _region; /** * Country or region, like CN */ get region(): string; private _deviceId; /** * Device id, randome string from ServiceBase.InitCallAsync */ get deviceId(): string; protected set deviceId(value: string); /** * Label delegate */ get labelDelegate(): <T = string>(key: string) => T | undefined; private _ipData?; /** * IP data */ get ipData(): IPData | undefined; protected set ipData(value: IPData | undefined); private _userData?; /** * User data */ get userData(): U | undefined; protected set userData(value: U | undefined); private ipDetectCallbacks?; /** * Search input element */ searchInput?: HTMLInputElement; private _authorized; /** * Is current authorized */ get authorized(): boolean; private set authorized(value); private _isReady; /** * Is the app ready */ get isReady(): boolean; private set isReady(value); /** * Current cached URL */ get cachedUrl(): string | undefined | null; set cachedUrl(value: string | undefined | null); /** * Keep login or not */ get keepLogin(): boolean; set keepLogin(value: boolean); private _embedded; /** * Is embedded */ get embedded(): boolean; private _isTryingLogin; /** * Is trying login */ get isTryingLogin(): boolean; protected set isTryingLogin(value: boolean); /** * Get core API name */ protected get coreName(): string; /** * Last called with token refresh */ protected lastCalled: boolean; /** * Init call Api URL */ protected initCallApi: string; /** * Passphrase for encryption */ protected passphrase: string; private apis; private tasks; private clearInterval?; /** * Get persisted fields */ protected readonly persistedFields: string[]; /** * Protected constructor * @param settings Settings * @param api API * @param notifier Notifier * @param storage Storage * @param name Application name * @param debug Debug mode */ protected constructor(settings: S, api: IApi | undefined | null, notifier: INotifier<N, C>, storage: IStorage, name: string, debug?: boolean); /** * Format settings * @param settings Original settings * @returns Result */ protected formatSettings(settings: S): S; private getDeviceId; private resetKeys; /** * Add app name as identifier * @param field Field * @returns Result */ protected addIdentifier(field: string): string; /** * Add root (homepage) to the URL * @param url URL to add * @returns Result */ addRootUrl(url: string): string; /** * Check current app is in same session * @param callback Callback */ checkSession(callback: (isSame: boolean) => Promise<void | false>): Promise<void>; /** * Clear user session */ clearSession(): void; /** * Create Auth API * @param api Specify the API to use * @returns Result */ protected createAuthApi(api?: IApi): AuthApi; /** * Restore settings from persisted source */ protected restore(): Promise<boolean>; /** * Dispose the application */ dispose(): void; /** * Is valid password, override to implement custom check * @param password Input password */ isValidPassword(password: string): boolean; /** * Persist settings to source when application exit */ persist(): void; /** * Add scheduled task * @param task Task, return false to stop * @param seconds Interval in seconds */ addTask(task: () => PromiseLike<void | false>, seconds: number): void; /** * Create API client, override to implement custom client creation by name * @param name Client name * @param item External endpoint item * @returns Result */ createApi(name: string, item: ExternalEndpoint, refresh?: (api: IApi, rq: ApiRefreshTokenRQ) => Promise<[string, number] | undefined>): IApi<any>; /** * Reset all APIs */ protected resetApis(): void; /** * Update API token and expires * @param name Api name * @param token Refresh token * @param seconds Access token expires in seconds */ updateApi(name: string, token: string | undefined, seconds: number): void; updateApi(data: ApiTaskData, token: string | undefined, seconds: number): void; /** * Setup Api * @param api Api */ protected setApi(api: IApi, refresh?: ApiRefreshTokenFunction): void; /** * Setup Api error handler * @param api Api * @param handlerFor401 Handler for 401 error */ setApiErrorHandler(api: IApi, handlerFor401?: boolean | (() => Promise<void>)): void; /** * Setup Api loading * @param api Api */ setApiLoading(api: IApi): void; /** * Setup frontend logging * @param action Custom action * @param preventDefault Is prevent default action */ setupLogging(action?: (data: ErrorData) => void | Promise<void>, preventDefault?: ((type: ErrorType) => boolean) | boolean): void; /** * Api init call * @param data Data * @returns Result */ protected apiInitCall(data: InitCallDto): Promise<InitCallResult | undefined>; /** * Check the action result is about device invalid * @param result Action result * @returns true means device is invalid */ checkDeviceResult(result: IActionResult): boolean; /** * Clear device id */ clearDeviceId(): void; /** * Init call * @param callback Callback * @param resetKeys Reset all keys first * @returns Result */ initCall(callback?: (result: boolean) => void, resetKeys?: boolean): Promise<void>; /** * Update passphrase * @param passphrase Secret passphrase */ protected updatePassphrase(passphrase: string): void; /** * Init call update * @param data Result data * @param timestamp Timestamp */ protected initCallUpdate(data: InitCallResultData, timestamp: number): Promise<boolean>; /** * Init call encrypted fields update * @returns Fields */ protected initCallEncryptedUpdateFields(): string[]; /** * Alert result * @param result Result message * @param callback Callback */ alertResult(result: string, callback?: NotificationReturn<void>): void; /** * Alert action result * @param result Action result * @param callback Callback * @param forceToLocal Force to local labels */ alertResult(result: IActionResult, callback?: NotificationReturn<void>, forceToLocal?: FormatResultCustomCallback): void; /** * Authorize * @param token New access token * @param schema Access token schema * @param refreshToken Refresh token */ authorize(token?: string, schema?: string, refreshToken?: string): void; /** * On authorized or not callback * @param success Success or not */ protected onAuthorized(success: boolean): void; /** * Change country or region * @param regionId New country or region */ changeRegion(region: string | AddressRegion): void; /** * Change culture * @param culture New culture definition * @param onReady On ready callback */ changeCulture(culture: DataTypes.CultureDefinition): Promise<DataTypes.StringRecord>; /** * Load custom resources, override to implement custom resources * @param resources Resources * @param culture Culture name */ protected loadCustomResources(resources: DataTypes.StringRecord, culture: string): Promise<void> | void; /** * Update current region label */ protected updateRegionLabel(): void; /** * Check language is supported or not, return a valid language when supported * @param language Language * @returns Result */ checkLanguage(language?: string): string; /** * Clear cache data */ clearCacheData(): void; /** * Clear cached token */ clearCacheToken(): void; /** * Decrypt message * @param messageEncrypted Encrypted message * @param passphrase Secret passphrase * @returns Pure text */ decrypt(messageEncrypted: string, passphrase?: string): string | undefined; /** * Enhanced decrypt message * @param messageEncrypted Encrypted message * @param passphrase Secret passphrase * @param durationSeconds Duration seconds, <= 12 will be considered as month * @returns Pure text */ decryptEnhanced(messageEncrypted: string, passphrase?: string, durationSeconds?: number): string | undefined; /** * Detect IP data, call only one time * @param callback Callback will be called when the IP is ready */ detectIP(callback?: IDetectIPCallback): void; private detectIPCallbacks; /** * Download file * @param stream File stream * @param filename File name * @param callback callback */ download(stream: ReadableStream, filename?: string, callback?: (success: boolean | undefined) => void): Promise<void>; /** * Encrypt message * @param message Message * @param passphrase Secret passphrase * @param iterations Iterations, 1000 times, 1 - 99 * @returns Result */ encrypt(message: string, passphrase?: string, iterations?: number): string; /** * Enhanced encrypt message * @param message Message * @param passphrase Secret passphrase * @param iterations Iterations, 1000 times, 1 - 99 * @returns Result */ encryptEnhanced(message: string, passphrase?: string, iterations?: number): string; /** * Enchance secret passphrase * @param passphrase Secret passphrase * @param timestamp Timestamp * @returns Enhanced passphrase */ protected encryptionEnhance(passphrase: string, timestamp: string): string; /** * Format action * @param action Action * @param target Target name or title * @param items More items * @returns Result */ formatAction(action: string, target: string, ...items: string[]): string; /** * Format date to string * @param input Input date * @param options Options * @param timeZone Time zone * @returns string */ formatDate(input?: Date | string, options?: DateUtils.FormatOptions, timeZone?: string): string | undefined; /** * Format money number * @param input Input money number * @param isInteger Is integer * @param options Options * @returns Result */ formatMoney(input: number | bigint, isInteger?: boolean, options?: Intl.NumberFormatOptions): string; /** * Format number * @param input Input number * @param options Options * @returns Result */ formatNumber(input: number | bigint, options?: Intl.NumberFormatOptions): string; /** * Format error * @param error Error * @returns Error message */ formatError(error: ApiDataError): string; /** * Format as full name * @param familyName Family name * @param givenName Given name */ formatFullName(familyName: string | undefined | null, givenName: string | undefined | null): string; private getFieldLabel; /** * Format result text * @param result Action result * @param forceToLocal Force to local labels */ formatResult(result: IActionResult, forceToLocal?: FormatResultCustomCallback): string; /** * Get culture resource * @param key key * @returns Resource */ get<T = string>(key: string): T | undefined; /** * Get multiple culture labels * @param keys Keys */ getLabels<T extends string>(...keys: T[]): { [K in T]: string; }; /** * Get bool items * @returns Bool items */ getBools(): ListType1[]; /** * Get cached token * @returns Cached token */ getCacheToken(): string | undefined; /** * Get data privacies * @returns Result */ getDataPrivacies(): ListType[]; /** * Get enum item number id list * @param em Enum * @param prefix Label prefix or callback * @param filter Filter * @returns List */ getEnumList<E extends DataTypes.EnumBase = DataTypes.EnumBase>(em: E, prefix: string | ((key: string) => string), filter?: ((id: E[keyof E], key: keyof E & string) => E[keyof E] | undefined) | E[keyof E][]): ListType[]; /** * Get enum item string id list * @param em Enum * @param prefix Label prefix or callback * @param filter Filter * @returns List */ getEnumStrList<E extends DataTypes.EnumBase = DataTypes.EnumBase>(em: E, prefix: string | ((key: string) => string), filter?: (id: E[keyof E], key: keyof E & string) => E[keyof E] | undefined): ListType1[]; /** * Get region label * @param id Region id * @returns Label */ getRegionLabel(id: string): string; /** * Get all regions * @returns Regions */ getRegions(): AddressRegion[]; /** * Get role label * @param role Role value * @param joinChar Join char * @returns Label(s) */ getRoleLabel(role: number | null | undefined, joinChar?: string): string; /** * Get roles * @param role Combination role value, null for all roles */ getRoles(role?: number): ListType[]; /** * Get status list * @param ids Limited ids * @returns list */ getStatusList(ids?: EntityStatus[]): ListType[]; /** * Get status label * @param status Status value */ getStatusLabel(status: number | null | undefined): string; /** * Get refresh token from response headers * @param rawResponse Raw response from API call * @param tokenKey Refresh token key * @returns response refresh token */ getResponseToken(rawResponse: any, tokenKey: string): string | null; /** * Get time zone * @returns Time zone */ getTimeZone(): string; /** * Hash message, SHA3 or HmacSHA512, 512 as Base64 * https://cryptojs.gitbook.io/docs/ * @param message Message * @param passphrase Secret passphrase */ hash(message: string, passphrase?: string): string; /** * Hash message Hex, SHA3 or HmacSHA512, 512 as Base64 * https://cryptojs.gitbook.io/docs/ * @param message Message * @param passphrase Secret passphrase */ hashHex(message: string, passphrase?: string): string; /** * Check user has the minimum role permission or not * @param role Minumum role * @returns Result */ hasMinPermission(role: UserRole): boolean; /** * Check user has the specific role permission or not * @param roles Roles to check * @returns Result */ hasPermission(roles: number | UserRole | number[] | UserRole[]): boolean; /** * Is admin roles * @returns Result */ isAdminUser(): boolean; /** * Is Finance roles * @returns Result */ isFinanceUser(): boolean; /** * Is HR manager roles * @returns Result */ isHRUser(): boolean; /** * Is Manager roles, exclude API user from frontend * @returns Result */ isManagerUser(): boolean; /** * Is user roles * @returns Result */ isUser(): boolean; /** * Load URL * @param url URL * @param targetOrigin Target origin */ loadUrl(url: string, targetOrigin?: string): void; /** * Navigate to Url or delta * @param url Url or delta * @param options Options */ navigate<T extends number | string | URL>(to: T, options?: T extends number ? never : NavigateOptions): void; /** * Notify user with success message * @param callback Popup close callback * @param message Success message */ ok(callback?: NotificationReturn<void>, message?: NotificationContent<N>): void; /** * Callback where exit a page */ pageExit(): void; /** * Fresh countdown UI * @param callback Callback */ abstract freshCountdownUI(callback?: () => PromiseLike<unknown>): void; /** * Refresh token * @param props Props * @param callback Callback */ refreshToken(props?: RefreshTokenProps, callback?: (result?: boolean | IActionResult) => boolean | void): Promise<void>; /** * Refresh token with success * @param user User data * @param token Refresh token * @param callback Callback */ protected refreshTokenSucceed(user: U, token: string, callback?: (result?: boolean | IActionResult) => boolean | void): Promise<void>; /** * Setup callback */ setup(): void; /** * Exchange token data * @param api API * @param token Core system's refresh token to exchange * @returns Result */ exchangeToken(api: IApi, token: string): Promise<void>; /** * Exchange token update, override to get the new token * @param api API * @param data API refresh token data */ protected exchangeTokenUpdate(api: IApi, data: ApiRefreshTokenDto): void; /** * Exchange intergration tokens for all APIs * @param coreData Core system's token data to exchange */ exchangeTokenAll(coreData: ApiRefreshTokenDto): void; /** * API refresh token data * @param api Current API * @param rq Request data * @returns Result */ protected apiRefreshTokenData(api: IApi, rq: ApiRefreshTokenRQ): Promise<ApiRefreshTokenDto | undefined>; /** * API refresh token * @param api Current API * @param rq Request data * @returns Result */ protected apiRefreshToken(api: IApi, rq: ApiRefreshTokenRQ): Promise<[string, number] | undefined>; /** * Save refresh token to cache * @param token Refresh token */ saveCacheToken(token: string | undefined): void; /** * Setup tasks */ protected setupTasks(): void; /** * Signout, with userLogout and toLoginPage * @param action Callback */ signout(action?: () => void | boolean): Promise<void>; /** * Go to the login page * @param data Login parameters */ toLoginPage(data?: AppLoginParams): void; /** * Try login, returning false means is loading * UI get involved while refreshToken not intended * @param data Login parameters */ tryLogin(data?: AppTryLoginParams): Promise<boolean>; /** * Update embedded status * @param embedded New embedded status * @param isWeb Is web or not */ updateEmbedded(embedded: boolean | undefined | null, isWeb?: boolean): void; /** * User login * @param user User data * @param refreshToken Refresh token */ userLogin(user: U, refreshToken: string): void; /** * User logout * @param clearToken Clear refresh token or not * @param noTrigger No trigger for state change */ userLogout(clearToken?: boolean, noTrigger?: boolean): void; /** * User unauthorized */ userUnauthorized(): void; private lastWarning?; /** * Show warning message * @param message Message * @param align Align, default as TopRight */ warning(message: NotificationContent<N>, align?: NotificationAlign): void; } export {};