import { Injectable } from '@angular/core' ; import { Environment , Environments , Route , RouteResponse } from '@mockoon/commons' ; import { BehaviorSubject , Observable } from 'rxjs' ; import { distinctUntilChanged , map , pluck } from 'rxjs/operators' ; import { INDENT_SIZE } from 'src/renderer/app/constants/common.constants' ; import { ActiveEnvironmentsLogUUIDs , EnvironmentLog , EnvironmentLogs } from 'src/renderer/app/models/environment-logs.model' ; import { Toast } from 'src/renderer/app/models/toasts.model' ; import { Actions } from 'src/renderer/app/stores/actions' ; import { environmentReducer } from 'src/renderer/app/stores/reducer' ; import { Settings } from 'src/shared/models/settings.model' ; export type ViewsNameType = 'ENV_ROUTES' | 'ENV_HEADERS' | 'ENV_LOGS' | 'ENV_PROXY' | 'ENV_SETTINGS' ; export type TabsNameType = 'RESPONSE' | 'HEADERS' | 'RULES' | 'SETTINGS' ; export type EnvironmentLogsTabsNameType = 'REQUEST' | 'RESPONSE' ; export type EnvironmentStatus = { running : boolean ; needRestart : boolean ; } ; export type EnvironmentStatusProperties = { [ T in keyof EnvironmentStatus ] ? : EnvironmentStatus [ T ] ; } ; export type EnvironmentsStatuses = { [ key ] : EnvironmentStatus ; } ; export type DuplicatedRoutesTypes = { [ key ] : Set < string > ; } ; export type UIState = { closing : boolean ; } ; export type UIStateProperties = { [ T in keyof UIState ] ? : UIState [ T ] ; } ; export type DuplicateRouteToAnotherEnvironment = { moving : boolean ; routeUUID ? : string ; targetEnvironmentUUID ? : string ; } ; export type StoreType = { activeTab : TabsNameType ; activeView : ViewsNameType ; activeEnvironmentLogsTab : EnvironmentLogsTabsNameType ; activeEnvironmentUUID : string ; activeRouteUUID : string ; activeRouteResponseUUID : string ; environments : Environments ; environmentsStatus : EnvironmentsStatuses ; bodyEditorConfig : any ; duplicatedRoutes : DuplicatedRoutesTypes ; environmentsLogs : EnvironmentLogs ; activeEnvironmentLogsUUID : ActiveEnvironmentsLogUUIDs ; toasts : Toast [ ] ; uiState : UIState ; settings : Settings ; duplicateRouteToAnotherEnvironment : DuplicateRouteToAnotherEnvironment ; routesFilter : string ; } ; @ Injectable ( { providedIn : 'root' } ) export class Store { private store$ = new BehaviorSubject < StoreType > ( { activeView : 'ENV_ROUTES' , activeTab : 'RESPONSE' , activeEnvironmentLogsTab : 'REQUEST' , activeEnvironmentLogsUUID : { } , activeEnvironmentUUID : null , activeRouteUUID : null , activeRouteResponseUUID : null , environments : [ ] , environmentsStatus : { } , bodyEditorConfig : { options : { fontSize : '1rem' , wrap : 'free' , showPrintMargin : false , tooltipFollowsMouse : false , useWorker : false , tabSize : INDENT_SIZE } , mode : 'json' , theme : 'editor-theme' } , duplicatedRoutes : { } , environmentsLogs : { } , toasts : [ ] , uiState : { closing : false } , settings : null , duplicateRouteToAnotherEnvironment : { moving : false } , routesFilter : '' } ) ; constructor ( ) { } /**
     * Select store element
     */ public select < T extends keyof StoreType > ( path ) { return this . store$ . asObservable ( ) . pipe ( pluck ( path ) , distinctUntilChanged ( ) ) ; } /**
     * Get any store item
     */ public get < T extends keyof StoreType > ( path ) { return this . store$ . value [ path ] ; } /**
     * Select active environment observable
     */ public selectActiveEnvironment ( ) { return this . store$ . asObservable ( ) . pipe ( map ( ( store ) => store . environments . find ( ( environment ) => environment . uuid === store . activeEnvironmentUUID ) ) ) ; } /**
     * Select active environment property observable
     */ public selectActiveEnvironmentProperty < T extends keyof Environment > ( path ) { return this . selectActiveEnvironment ( ) . pipe ( pluck ( path ) ) ; } /**
     * Select active environment status observable
     */ public selectActiveEnvironmentStatus ( ) { return this . store$ . asObservable ( ) . pipe ( map ( ( store ) => store . environmentsStatus [ store . activeEnvironmentUUID ] ) ) ; } /**
     * Select active environment logs
     */ public selectActiveEnvironmentLogs ( ) { return this . store$ . asObservable ( ) . pipe ( map ( ( store ) => store . environmentsLogs [ store . activeEnvironmentUUID ] ) ) ; } /**
     * Select active environment log UUID for selected environment
     */ public selectActiveEnvironmentLogUUID ( ) { return this . store$ . asObservable ( ) . pipe ( map ( ( store ) => store . activeEnvironmentLogsUUID [ store . activeEnvironmentUUID ] ) ) ; } /**
     * Select last environment log for active route response
     */ public selectActiveRouteResponseLastLog ( ) { return this . store$ . asObservable ( ) . pipe ( map ( ( store ) => store . activeEnvironmentUUID ? store . environmentsLogs [ store . activeEnvironmentUUID ] . find ( ( environmentLog ) => environmentLog . routeUUID === store . activeRouteUUID && environmentLog . routeResponseUUID === store . activeRouteResponseUUID ) : null ) ) ; } /**
     * Select active route observable
     */ public selectActiveRoute ( ) { return this . selectActiveEnvironment ( ) . pipe ( map ( ( environment ) => environment ? environment . routes . find ( ( route ) => route . uuid === this . store$ . value . activeRouteUUID ) : null ) ) ; } /**
     * Select active route response observable
     */ public selectActiveRouteResponse ( ) { return this . selectActiveRoute ( ) . pipe ( map ( ( route ) => route ? route . responses . find ( ( routeResponse ) => routeResponse . uuid === this . store$ . value . activeRouteResponseUUID ) : null ) ) ; } /**
     * Select active route response index observable
     */ public selectActiveRouteResponseIndex ( ) { return this . selectActiveRoute ( ) . pipe ( map ( ( route ) => route ? route . responses . findIndex ( ( routeResponse ) => routeResponse . uuid === this . store$ . value . activeRouteResponseUUID ) + 1 : null ) ) ; } /**
     * Get environment by uuid
     */ public getEnvironmentByUUID ( UUID ) { return this . store$ . value . environments . find ( ( environment ) => environment . uuid === UUID ) ; } /**
     * Get active environment value
     */ public getActiveEnvironment ( ) { return this . store$ . value . environments . find ( ( environment ) => environment . uuid === this . store$ . value . activeEnvironmentUUID ) ; } /**
     * Get environments status value
     */ public getEnvironmentStatus ( ) { return this . store$ . value . environmentsStatus ; } /**
     * Get active route value
     */ public getActiveRoute ( ) { const activeEnvironment = this . store$ . value . environments . find ( ( environment ) => environment . uuid === this . store$ . value . activeEnvironmentUUID ) ; if ( ! activeEnvironment ) { return null ; } return activeEnvironment . routes . find ( ( route ) => route . uuid === this . store$ . value . activeRouteUUID ) ; } /**
     * Get active route response value
     */ public getActiveRouteResponse ( ) { return this . store$ . value . environments . find ( ( environment ) => environment . uuid === this . store$ . value . activeEnvironmentUUID ) . routes . find ( ( route ) => route . uuid === this . store$ . value . activeRouteUUID ) . responses . find ( ( response ) => response . uuid === this . store$ . value . activeRouteResponseUUID ) ; } /**
     * Get route with the supplied UUID from any environment
     */ public getRouteByUUID ( routeUUID ) { let foundRoute ; this . store$ . value . environments . some ( ( environment ) => { foundRoute = environment . routes . find ( ( route ) => route . uuid === routeUUID ) ; return ! ! foundRoute ; } ) ; return foundRoute ; } /**
     * Update the store using the reducer
     */ public update ( action ) { this . store$ . next ( environmentReducer ( this . store$ . value , action ) ) ; } /**
     * Get a list with all environment ports
     */ public getEnvironmentsPorts ( ) { return this . store$ . value . environments . reduce ( ( list , env ) => { list . push ( env . port ) ; return list ; } , [ ] ) ; } }