feat: Enhance API client integration across web and CLI
- Added typedRequestInterfaces import to plugins.ts for better type handling. - Updated CLI client to utilize environment variables for Cloudly API credentials and improved authentication flow. - Refactored appstate.ts to use a shared API client instance, reducing redundancy in API calls for various actions. - Simplified external registry actions in appstate.ts by leveraging the shared API client. - Updated CloudlyDashboard and CloudlyViewSettings components to utilize the shared API client for fetching settings and managing connections. - Removed redundant TypedRequest instances in favor of direct API client calls for improved performance and maintainability. - Exposed the API client in plugins.ts for easier access in UI components.
This commit is contained in:
		| @@ -54,6 +54,21 @@ export class CloudlyApiClient { | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   // Helper: resolve HTTP typedrequest endpoint | ||||
|   private get httpEndpoint() { | ||||
|     const base = (this.cloudlyUrl || '').replace(/\/$/, ''); | ||||
|     return `${base}/typedrequest`; | ||||
|   } | ||||
|  | ||||
|   // Helper: choose transport (WS if available, else HTTP) | ||||
|   private createWsRequest<T extends plugins.typedRequestInterfaces.ITypedRequest>(operation: string) { | ||||
|     return this.typedsocketClient?.createTypedRequest<T>(operation); | ||||
|   } | ||||
|  | ||||
|   private createHttpRequest<T extends plugins.typedRequestInterfaces.ITypedRequest>(operation: string) { | ||||
|     return new plugins.typedrequest.TypedRequest<T>(this.httpEndpoint, operation); | ||||
|   } | ||||
|  | ||||
|   public async start() { | ||||
|     this.typedsocketClient = await plugins.typedsocket.TypedSocket.createClient( | ||||
|       this.typedrouter, | ||||
| @@ -170,7 +185,33 @@ export class CloudlyApiClient { | ||||
|     }, | ||||
|     createRegistry: async (optionsArg: Parameters<typeof ExternalRegistry.createExternalRegistry>[1]) => { | ||||
|       return ExternalRegistry.createExternalRegistry(this, optionsArg); | ||||
|     }, | ||||
|     verifyRegistry: async (registryId: string): Promise<{ success: boolean; message: string; registry?: ExternalRegistry }> => { | ||||
|       const op = 'verifyExternalRegistry'; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.externalRegistry.IReq_VerifyRegistry>(op); | ||||
|       const payload = { identity: this.identity, registryId } as any; | ||||
|       const resp = wsReq ? await wsReq.fire(payload) : await this.createHttpRequest<plugins.servezoneInterfaces.requests.externalRegistry.IReq_VerifyRegistry>(op).fire(payload); | ||||
|       let registryInstance: ExternalRegistry | undefined; | ||||
|       if (resp.registry) { | ||||
|         registryInstance = new ExternalRegistry(this); | ||||
|         Object.assign(registryInstance, resp.registry); | ||||
|       } | ||||
|       return { success: resp.success, message: resp.message, registry: registryInstance }; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Auth helpers | ||||
|   public async loginWithUsernameAndPassword(username: string, password: string): Promise<plugins.servezoneInterfaces.data.IIdentity> { | ||||
|     const op = 'adminLoginWithUsernameAndPassword'; | ||||
|     // Login endpoint is exposed via HTTP typedrequest | ||||
|     const httpReq = this.createHttpRequest<plugins.servezoneInterfaces.requests.admin.IReq_Admin_LoginWithUsernameAndPassword>(op); | ||||
|     const response = await httpReq.fire({ username, password }); | ||||
|     this.identity = response.identity; | ||||
|     // If WS connection is available, tag it with identity for server-side guards | ||||
|     if (this.typedsocketClient) { | ||||
|       try { this.typedsocketClient.addTag('identity', this.identity); } catch {} | ||||
|     } | ||||
|     return this.identity; | ||||
|   } | ||||
|  | ||||
|   public image = { | ||||
| @@ -183,6 +224,13 @@ export class CloudlyApiClient { | ||||
|     }, | ||||
|     createImage: async (optionsArg: Parameters<typeof Image.createImage>[1]) => { | ||||
|       return Image.createImage(this, optionsArg); | ||||
|     }, | ||||
|     deleteImage: async (imageId: string): Promise<void> => { | ||||
|       const op = 'deleteImage'; | ||||
|       const payload = { identity: this.identity, imageId } as any; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.image.IRequest_DeleteImage>(op); | ||||
|       if (wsReq) { await wsReq.fire(payload); return; } | ||||
|       await this.createHttpRequest<plugins.servezoneInterfaces.requests.image.IRequest_DeleteImage>(op).fire(payload); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -196,6 +244,20 @@ export class CloudlyApiClient { | ||||
|     }, | ||||
|     createService: async (optionsArg: Parameters<typeof Service.createService>[1]) => { | ||||
|       return Service.createService(this, optionsArg); | ||||
|     }, | ||||
|     updateService: async (serviceId: string, serviceData: plugins.servezoneInterfaces.data.IService['data']): Promise<{ service: plugins.servezoneInterfaces.data.IService }> => { | ||||
|       const op = 'updateService'; | ||||
|       const payload = { identity: this.identity, serviceId, serviceData } as any; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.service.IRequest_Any_Cloudly_UpdateService>(op); | ||||
|       if (wsReq) return wsReq.fire(payload); | ||||
|       return this.createHttpRequest<plugins.servezoneInterfaces.requests.service.IRequest_Any_Cloudly_UpdateService>(op).fire(payload); | ||||
|     }, | ||||
|     deleteService: async (serviceId: string): Promise<void> => { | ||||
|       const op = 'deleteServiceById'; | ||||
|       const payload = { identity: this.identity, serviceId } as any; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.service.IRequest_Any_Cloudly_DeleteServiceById>(op); | ||||
|       if (wsReq) { await wsReq.fire(payload); return; } | ||||
|       await this.createHttpRequest<plugins.servezoneInterfaces.requests.service.IRequest_Any_Cloudly_DeleteServiceById>(op).fire(payload); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -237,4 +299,251 @@ export class CloudlyApiClient { | ||||
|       return SecretGroup.createSecretGroup(this, optionsArg); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Settings API | ||||
|   public settings = { | ||||
|     getSettings: async (): Promise<{ | ||||
|       settings: plugins.servezoneInterfaces.data.ICloudlySettingsMasked | ||||
|     }> => { | ||||
|       const op = 'getSettings'; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.settings.IRequest_GetSettings>(op); | ||||
|       if (wsReq) { | ||||
|         return wsReq.fire({ identity: this.identity }); | ||||
|       } | ||||
|       const httpReq = this.createHttpRequest<plugins.servezoneInterfaces.requests.settings.IRequest_GetSettings>(op); | ||||
|       return httpReq.fire({ identity: this.identity }); | ||||
|     }, | ||||
|     updateSettings: async (updates: Partial<plugins.servezoneInterfaces.data.ICloudlySettings>): Promise<{ | ||||
|       success: boolean; | ||||
|       message: string; | ||||
|     }> => { | ||||
|       const op = 'updateSettings'; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.settings.IRequest_UpdateSettings>(op); | ||||
|       if (wsReq) { | ||||
|         return wsReq.fire({ identity: this.identity, updates }); | ||||
|       } | ||||
|       const httpReq = this.createHttpRequest<plugins.servezoneInterfaces.requests.settings.IRequest_UpdateSettings>(op); | ||||
|       return httpReq.fire({ identity: this.identity, updates }); | ||||
|     }, | ||||
|     testProviderConnection: async (provider: string): Promise<{ | ||||
|       connectionValid: boolean; | ||||
|       message: string; | ||||
|     }> => { | ||||
|       const op = 'testProviderConnection'; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.settings.IRequest_TestProviderConnection>(op); | ||||
|       if (wsReq) { | ||||
|         return wsReq.fire({ identity: this.identity, provider: provider as any }); | ||||
|       } | ||||
|       const httpReq = this.createHttpRequest<plugins.servezoneInterfaces.requests.settings.IRequest_TestProviderConnection>(op); | ||||
|       return httpReq.fire({ identity: this.identity, provider: provider as any }); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Task API | ||||
|   public tasks = { | ||||
|     getTasks: async (): Promise<{ | ||||
|       tasks: Array<{ | ||||
|         name: string; | ||||
|         description: string; | ||||
|         category: 'maintenance' | 'deployment' | 'backup' | 'monitoring' | 'cleanup' | 'system' | 'security'; | ||||
|         schedule?: string; | ||||
|         lastRun?: number; | ||||
|         enabled: boolean; | ||||
|       }> | ||||
|     }> => { | ||||
|       const op = 'getTasks'; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.task.IRequest_Any_Cloudly_GetTasks>(op); | ||||
|       if (wsReq) { | ||||
|         return wsReq.fire({ identity: this.identity }); | ||||
|       } | ||||
|       const httpReq = this.createHttpRequest<plugins.servezoneInterfaces.requests.task.IRequest_Any_Cloudly_GetTasks>(op); | ||||
|       return httpReq.fire({ identity: this.identity }); | ||||
|     }, | ||||
|     getTaskExecutions: async (filter?: any): Promise<{ | ||||
|       executions: plugins.servezoneInterfaces.data.ITaskExecution[]; | ||||
|     }> => { | ||||
|       const op = 'getTaskExecutions'; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.task.IRequest_Any_Cloudly_GetTaskExecutions>(op); | ||||
|       if (wsReq) { | ||||
|         return wsReq.fire({ identity: this.identity, filter }); | ||||
|       } | ||||
|       const httpReq = this.createHttpRequest<plugins.servezoneInterfaces.requests.task.IRequest_Any_Cloudly_GetTaskExecutions>(op); | ||||
|       return httpReq.fire({ identity: this.identity, filter }); | ||||
|     }, | ||||
|     getTaskExecutionById: async (executionId: string): Promise<{ | ||||
|       execution: plugins.servezoneInterfaces.data.ITaskExecution | ||||
|     }> => { | ||||
|       const op = 'getTaskExecutionById'; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.task.IRequest_Any_Cloudly_GetTaskExecutionById>(op); | ||||
|       if (wsReq) { | ||||
|         return wsReq.fire({ identity: this.identity, executionId }); | ||||
|       } | ||||
|       const httpReq = this.createHttpRequest<plugins.servezoneInterfaces.requests.task.IRequest_Any_Cloudly_GetTaskExecutionById>(op); | ||||
|       return httpReq.fire({ identity: this.identity, executionId }); | ||||
|     }, | ||||
|     triggerTask: async (taskName: string, userId?: string): Promise<{ | ||||
|       execution: plugins.servezoneInterfaces.data.ITaskExecution | ||||
|     }> => { | ||||
|       const op = 'triggerTask'; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.task.IRequest_Any_Cloudly_TriggerTask>(op); | ||||
|       if (wsReq) { | ||||
|         return wsReq.fire({ identity: this.identity, taskName, userId }); | ||||
|       } | ||||
|       const httpReq = this.createHttpRequest<plugins.servezoneInterfaces.requests.task.IRequest_Any_Cloudly_TriggerTask>(op); | ||||
|       return httpReq.fire({ identity: this.identity, taskName, userId }); | ||||
|     }, | ||||
|     cancelTask: async (executionId: string): Promise<{ success: boolean }> => { | ||||
|       const op = 'cancelTask'; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.task.IRequest_Any_Cloudly_CancelTask>(op); | ||||
|       if (wsReq) { | ||||
|         return wsReq.fire({ identity: this.identity, executionId }); | ||||
|       } | ||||
|       const httpReq = this.createHttpRequest<plugins.servezoneInterfaces.requests.task.IRequest_Any_Cloudly_CancelTask>(op); | ||||
|       return httpReq.fire({ identity: this.identity, executionId }); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Domain API | ||||
|   public domains = { | ||||
|     getDomains: async (): Promise<{ domains: plugins.servezoneInterfaces.data.IDomain[] }> => { | ||||
|       const op = 'getDomains'; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.domain.IRequest_Any_Cloudly_GetDomains>(op); | ||||
|       if (wsReq) return wsReq.fire({ identity: this.identity }); | ||||
|       return this.createHttpRequest<plugins.servezoneInterfaces.requests.domain.IRequest_Any_Cloudly_GetDomains>(op).fire({ identity: this.identity }); | ||||
|     }, | ||||
|     getDomainById: async (domainId: string): Promise<{ domain: plugins.servezoneInterfaces.data.IDomain }> => { | ||||
|       const op = 'getDomainById'; | ||||
|       const payload = { identity: this.identity, domainId } as any; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.domain.IRequest_Any_Cloudly_GetDomainById>(op); | ||||
|       if (wsReq) return wsReq.fire(payload); | ||||
|       return this.createHttpRequest<plugins.servezoneInterfaces.requests.domain.IRequest_Any_Cloudly_GetDomainById>(op).fire(payload); | ||||
|     }, | ||||
|     createDomain: async (domainData: plugins.servezoneInterfaces.data.IDomain['data']): Promise<{ domain: plugins.servezoneInterfaces.data.IDomain }> => { | ||||
|       const op = 'createDomain'; | ||||
|       const payload = { identity: this.identity, domainData } as any; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.domain.IRequest_Any_Cloudly_CreateDomain>(op); | ||||
|       if (wsReq) return wsReq.fire(payload); | ||||
|       return this.createHttpRequest<plugins.servezoneInterfaces.requests.domain.IRequest_Any_Cloudly_CreateDomain>(op).fire(payload); | ||||
|     }, | ||||
|     updateDomain: async (domainId: string, domainData: Partial<plugins.servezoneInterfaces.data.IDomain['data']>): Promise<{ domain: plugins.servezoneInterfaces.data.IDomain }> => { | ||||
|       const op = 'updateDomain'; | ||||
|       const payload = { identity: this.identity, domainId, domainData } as any; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.domain.IRequest_Any_Cloudly_UpdateDomain>(op); | ||||
|       if (wsReq) return wsReq.fire(payload); | ||||
|       return this.createHttpRequest<plugins.servezoneInterfaces.requests.domain.IRequest_Any_Cloudly_UpdateDomain>(op).fire(payload); | ||||
|     }, | ||||
|     deleteDomain: async (domainId: string): Promise<{ success: boolean }> => { | ||||
|       const op = 'deleteDomain'; | ||||
|       const payload = { identity: this.identity, domainId } as any; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.domain.IRequest_Any_Cloudly_DeleteDomain>(op); | ||||
|       if (wsReq) return wsReq.fire(payload); | ||||
|       return this.createHttpRequest<plugins.servezoneInterfaces.requests.domain.IRequest_Any_Cloudly_DeleteDomain>(op).fire(payload); | ||||
|     }, | ||||
|     verifyDomain: async (domainId: string, verificationMethod?: 'dns' | 'http' | 'email' | 'manual'): Promise<{ domain: plugins.servezoneInterfaces.data.IDomain; verificationResult: any }> => { | ||||
|       const op = 'verifyDomain'; | ||||
|       const payload = { identity: this.identity, domainId, verificationMethod } as any; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.domain.IRequest_Any_Cloudly_VerifyDomain>(op); | ||||
|       if (wsReq) return wsReq.fire(payload); | ||||
|       return this.createHttpRequest<plugins.servezoneInterfaces.requests.domain.IRequest_Any_Cloudly_VerifyDomain>(op).fire(payload); | ||||
|     }, | ||||
|   }; | ||||
|  | ||||
|   // DNS API | ||||
|   public dns = { | ||||
|     getDnsEntries: async (zone?: string): Promise<{ dnsEntries: plugins.servezoneInterfaces.data.IDnsEntry[] }> => { | ||||
|       const op = 'getDnsEntries'; | ||||
|       const payload = { identity: this.identity, zone } as any; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.dns.IRequest_Any_Cloudly_GetDnsEntries>(op); | ||||
|       if (wsReq) return wsReq.fire(payload); | ||||
|       return this.createHttpRequest<plugins.servezoneInterfaces.requests.dns.IRequest_Any_Cloudly_GetDnsEntries>(op).fire(payload); | ||||
|     }, | ||||
|     getDnsEntryById: async (dnsEntryId: string): Promise<{ dnsEntry: plugins.servezoneInterfaces.data.IDnsEntry }> => { | ||||
|       const op = 'getDnsEntryById'; | ||||
|       const payload = { identity: this.identity, dnsEntryId } as any; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.dns.IRequest_Any_Cloudly_GetDnsEntryById>(op); | ||||
|       if (wsReq) return wsReq.fire(payload); | ||||
|       return this.createHttpRequest<plugins.servezoneInterfaces.requests.dns.IRequest_Any_Cloudly_GetDnsEntryById>(op).fire(payload); | ||||
|     }, | ||||
|     createDnsEntry: async (dnsEntryData: plugins.servezoneInterfaces.data.IDnsEntry['data']): Promise<{ dnsEntry: plugins.servezoneInterfaces.data.IDnsEntry }> => { | ||||
|       const op = 'createDnsEntry'; | ||||
|       const payload = { identity: this.identity, dnsEntryData } as any; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.dns.IRequest_Any_Cloudly_CreateDnsEntry>(op); | ||||
|       if (wsReq) return wsReq.fire(payload); | ||||
|       return this.createHttpRequest<plugins.servezoneInterfaces.requests.dns.IRequest_Any_Cloudly_CreateDnsEntry>(op).fire(payload); | ||||
|     }, | ||||
|     updateDnsEntry: async (dnsEntryId: string, dnsEntryData: plugins.servezoneInterfaces.data.IDnsEntry['data']): Promise<{ dnsEntry: plugins.servezoneInterfaces.data.IDnsEntry }> => { | ||||
|       const op = 'updateDnsEntry'; | ||||
|       const payload = { identity: this.identity, dnsEntryId, dnsEntryData } as any; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.dns.IRequest_Any_Cloudly_UpdateDnsEntry>(op); | ||||
|       if (wsReq) return wsReq.fire(payload); | ||||
|       return this.createHttpRequest<plugins.servezoneInterfaces.requests.dns.IRequest_Any_Cloudly_UpdateDnsEntry>(op).fire(payload); | ||||
|     }, | ||||
|     deleteDnsEntry: async (dnsEntryId: string): Promise<{ success: boolean }> => { | ||||
|       const op = 'deleteDnsEntry'; | ||||
|       const payload = { identity: this.identity, dnsEntryId } as any; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.dns.IRequest_Any_Cloudly_DeleteDnsEntry>(op); | ||||
|       if (wsReq) return wsReq.fire(payload); | ||||
|       return this.createHttpRequest<plugins.servezoneInterfaces.requests.dns.IRequest_Any_Cloudly_DeleteDnsEntry>(op).fire(payload); | ||||
|     }, | ||||
|     getDnsZones: async (): Promise<{ zones: string[] }> => { | ||||
|       const op = 'getDnsZones'; | ||||
|       const payload = { identity: this.identity } as any; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.dns.IRequest_Any_Cloudly_GetDnsZones>(op); | ||||
|       if (wsReq) return wsReq.fire(payload); | ||||
|       return this.createHttpRequest<plugins.servezoneInterfaces.requests.dns.IRequest_Any_Cloudly_GetDnsZones>(op).fire(payload); | ||||
|     }, | ||||
|   }; | ||||
|  | ||||
|   // Deployment API | ||||
|   public deployments = { | ||||
|     getDeployments: async (): Promise<{ deployments: plugins.servezoneInterfaces.data.IDeployment[] }> => { | ||||
|       const op = 'getDeployments'; | ||||
|       const payload = { identity: this.identity } as any; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.deployment.IReq_Any_Cloudly_GetDeployments>(op); | ||||
|       if (wsReq) return wsReq.fire(payload); | ||||
|       return this.createHttpRequest<plugins.servezoneInterfaces.requests.deployment.IReq_Any_Cloudly_GetDeployments>(op).fire(payload); | ||||
|     }, | ||||
|     getDeploymentById: async (deploymentId: string): Promise<{ deployment: plugins.servezoneInterfaces.data.IDeployment }> => { | ||||
|       const op = 'getDeploymentById'; | ||||
|       const payload = { identity: this.identity, deploymentId } as any; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.deployment.IReq_Any_Cloudly_GetDeploymentById>(op); | ||||
|       if (wsReq) return wsReq.fire(payload); | ||||
|       return this.createHttpRequest<plugins.servezoneInterfaces.requests.deployment.IReq_Any_Cloudly_GetDeploymentById>(op).fire(payload); | ||||
|     }, | ||||
|     createDeployment: async (deploymentData: Partial<plugins.servezoneInterfaces.data.IDeployment>): Promise<{ deployment: plugins.servezoneInterfaces.data.IDeployment }> => { | ||||
|       const op = 'createDeployment'; | ||||
|       const payload = { identity: this.identity, deploymentData } as any; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.deployment.IReq_Any_Cloudly_CreateDeployment>(op); | ||||
|       if (wsReq) return wsReq.fire(payload); | ||||
|       return this.createHttpRequest<plugins.servezoneInterfaces.requests.deployment.IReq_Any_Cloudly_CreateDeployment>(op).fire(payload); | ||||
|     }, | ||||
|     updateDeployment: async (deploymentId: string, deploymentData: Partial<plugins.servezoneInterfaces.data.IDeployment>): Promise<{ deployment: plugins.servezoneInterfaces.data.IDeployment }> => { | ||||
|       const op = 'updateDeployment'; | ||||
|       const payload = { identity: this.identity, deploymentId, deploymentData } as any; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.deployment.IReq_Any_Cloudly_UpdateDeployment>(op); | ||||
|       if (wsReq) return wsReq.fire(payload); | ||||
|       return this.createHttpRequest<plugins.servezoneInterfaces.requests.deployment.IReq_Any_Cloudly_UpdateDeployment>(op).fire(payload); | ||||
|     }, | ||||
|     deleteDeployment: async (deploymentId: string): Promise<{ success: boolean }> => { | ||||
|       const op = 'deleteDeploymentById'; | ||||
|       const payload = { identity: this.identity, deploymentId } as any; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.deployment.IReq_Any_Cloudly_DeleteDeploymentById>(op); | ||||
|       if (wsReq) return wsReq.fire(payload); | ||||
|       return this.createHttpRequest<plugins.servezoneInterfaces.requests.deployment.IReq_Any_Cloudly_DeleteDeploymentById>(op).fire(payload); | ||||
|     }, | ||||
|     restartDeployment: async (deploymentId: string): Promise<{ success: boolean; deployment: plugins.servezoneInterfaces.data.IDeployment }> => { | ||||
|       const op = 'restartDeployment'; | ||||
|       const payload = { identity: this.identity, deploymentId } as any; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.deployment.IReq_Any_Cloudly_RestartDeployment>(op); | ||||
|       if (wsReq) return wsReq.fire(payload); | ||||
|       return this.createHttpRequest<plugins.servezoneInterfaces.requests.deployment.IReq_Any_Cloudly_RestartDeployment>(op).fire(payload); | ||||
|     }, | ||||
|     scaleDeployment: async (deploymentId: string, replicas: number): Promise<{ success: boolean; deployment: plugins.servezoneInterfaces.data.IDeployment }> => { | ||||
|       const op = 'scaleDeployment'; | ||||
|       const payload = { identity: this.identity, deploymentId, replicas } as any; | ||||
|       const wsReq = this.createWsRequest<plugins.servezoneInterfaces.requests.deployment.IReq_Any_Cloudly_ScaleDeployment>(op); | ||||
|       if (wsReq) return wsReq.fire(payload); | ||||
|       return this.createHttpRequest<plugins.servezoneInterfaces.requests.deployment.IReq_Any_Cloudly_ScaleDeployment>(op).fire(payload); | ||||
|     }, | ||||
|   }; | ||||
| } | ||||
|   | ||||
| @@ -21,10 +21,12 @@ export { | ||||
| // @api.global scope | ||||
| import * as typedrequest from '@api.global/typedrequest'; | ||||
| import * as typedsocket from '@api.global/typedsocket'; | ||||
| import * as typedRequestInterfaces from '@api.global/typedrequest-interfaces'; | ||||
|  | ||||
| export { | ||||
|   typedrequest, | ||||
|   typedsocket | ||||
|   typedsocket, | ||||
|   typedRequestInterfaces, | ||||
| } | ||||
|  | ||||
| // @tsclass scope | ||||
|   | ||||
| @@ -1,11 +1,28 @@ | ||||
| import * as plugins from './plugins.js'; | ||||
| import { CliClient } from "./classes.cliclient.js"; | ||||
| import { CliClient } from './classes.cliclient.js'; | ||||
|  | ||||
| export const runCli = async () => { | ||||
|   const cliQenv = new plugins.qenv.Qenv(); | ||||
|   const cloudlyUrl = await cliQenv.getEnvVarOnDemand('CLOUDLY_URL'); | ||||
|   const token = process.env.CLOUDLY_TOKEN; | ||||
|   const username = process.env.CLOUDLY_USERNAME; | ||||
|   const password = process.env.CLOUDLY_PASSWORD; | ||||
|  | ||||
|   const apiClient = new plugins.servezoneApi.CloudlyApiClient({ | ||||
|     registerAs: 'cli', | ||||
|     cloudlyUrl: await cliQenv.getEnvVarOnDemand('CLOUDLY_URL'), | ||||
|     cloudlyUrl, | ||||
|   }); | ||||
|   await apiClient.start(); | ||||
|  | ||||
|   if (token) { | ||||
|     await apiClient.getIdentityByToken(token, { tagConnection: true, statefullIdentity: true }); | ||||
|   } else if (username && password) { | ||||
|     await apiClient.loginWithUsernameAndPassword(username, password); | ||||
|   } else { | ||||
|     console.log('No credentials provided. Set CLOUDLY_TOKEN or CLOUDLY_USERNAME/CLOUDLY_PASSWORD.'); | ||||
|   } | ||||
|  | ||||
|   const cliClient = new CliClient(apiClient); | ||||
|   // Default action example: list clusters when invoked without subcommands | ||||
|   await cliClient.getClusters(); | ||||
| }; | ||||
| @@ -28,10 +28,21 @@ export const loginAction = loginStatePart.createAction<{ username: string; passw | ||||
|         ...statePartArg.getState(), | ||||
|       } | ||||
|     }); | ||||
|     return { | ||||
|     const newState = { | ||||
|       ...currentState, | ||||
|       ...(response.identity ? { identity: response.identity } : {}), | ||||
|     }; | ||||
|     try { | ||||
|       // Keep shared API client in sync and establish WS for modules using sockets | ||||
|       apiClient.identity = (response as any)?.identity || null; | ||||
|       if (apiClient.identity) { | ||||
|         if (!apiClient['typedsocketClient']) { | ||||
|           await apiClient.start(); | ||||
|         } | ||||
|         try { apiClient.typedsocketClient.addTag('identity', apiClient.identity); } catch {} | ||||
|       } | ||||
|     } catch {} | ||||
|     return newState; | ||||
|   } | ||||
| ); | ||||
|  | ||||
| @@ -84,6 +95,12 @@ export const dataState = await appstate.getStatePart<IDataState>( | ||||
|   'soft' | ||||
| ); | ||||
|  | ||||
| // Shared API client instance (used by UI actions) | ||||
| export const apiClient = new plugins.servezoneApi.CloudlyApiClient({ | ||||
|   registerAs: 'api', | ||||
|   cloudlyUrl: (typeof window !== 'undefined' && window.location?.origin) ? window.location.origin : undefined, | ||||
| }); | ||||
|  | ||||
| // Getting data | ||||
| export const getAllDataAction = dataState.createAction(async (statePartArg) => { | ||||
|   let currentState = statePartArg.getState(); | ||||
| @@ -144,19 +161,13 @@ export const getAllDataAction = dataState.createAction(async (statePartArg) => { | ||||
|     clusters: responseClusters.clusters, | ||||
|   } | ||||
|  | ||||
|   // External Registries | ||||
|   const trGetExternalRegistries = | ||||
|     new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.externalRegistry.IReq_GetRegistries>( | ||||
|       '/typedrequest', | ||||
|       'getExternalRegistries' | ||||
|     ); | ||||
|   // External Registries via shared API client | ||||
|   try { | ||||
|     const responseExternalRegistries = await trGetExternalRegistries.fire({ | ||||
|       identity: loginStatePart.getState().identity, | ||||
|     }); | ||||
|     apiClient.identity = loginStatePart.getState().identity; | ||||
|     const registries = await apiClient.externalRegistry.getRegistries(); | ||||
|     currentState = { | ||||
|       ...currentState, | ||||
|       externalRegistries: responseExternalRegistries?.registries || [], | ||||
|       externalRegistries: registries as any, | ||||
|     }; | ||||
|   } catch (error) { | ||||
|     console.error('Failed to fetch external registries:', error); | ||||
| @@ -210,16 +221,10 @@ export const getAllDataAction = dataState.createAction(async (statePartArg) => { | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   // Domains | ||||
|   const trGetDomains = | ||||
|     new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.domain.IRequest_Any_Cloudly_GetDomains>( | ||||
|       '/typedrequest', | ||||
|       'getDomains' | ||||
|     ); | ||||
|   // Domains via API client | ||||
|   try { | ||||
|     const responseDomains = await trGetDomains.fire({ | ||||
|       identity: loginStatePart.getState().identity, | ||||
|     }); | ||||
|     apiClient.identity = loginStatePart.getState().identity; | ||||
|     const responseDomains = await apiClient.domains.getDomains(); | ||||
|     currentState = { | ||||
|       ...currentState, | ||||
|       domains: responseDomains?.domains || [], | ||||
| @@ -232,16 +237,10 @@ export const getAllDataAction = dataState.createAction(async (statePartArg) => { | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   // DNS Entries | ||||
|   const trGetDnsEntries = | ||||
|     new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.dns.IRequest_Any_Cloudly_GetDnsEntries>( | ||||
|       '/typedrequest', | ||||
|       'getDnsEntries' | ||||
|     ); | ||||
|   // DNS Entries via API client | ||||
|   try { | ||||
|     const responseDnsEntries = await trGetDnsEntries.fire({ | ||||
|       identity: loginStatePart.getState().identity, | ||||
|     }); | ||||
|     apiClient.identity = loginStatePart.getState().identity; | ||||
|     const responseDnsEntries = await apiClient.dns.getDnsEntries(); | ||||
|     currentState = { | ||||
|       ...currentState, | ||||
|       dnsEntries: responseDnsEntries?.dnsEntries || [], | ||||
| @@ -261,15 +260,8 @@ export const getAllDataAction = dataState.createAction(async (statePartArg) => { | ||||
| export const createServiceAction = dataState.createAction( | ||||
|   async (statePartArg, payloadArg: { serviceData: plugins.interfaces.data.IService['data'] }) => { | ||||
|     let currentState = statePartArg.getState(); | ||||
|     const trCreateService = | ||||
|       new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.service.IRequest_Any_Cloudly_CreateService>( | ||||
|         '/typedrequest', | ||||
|         'createService' | ||||
|       ); | ||||
|     const response = await trCreateService.fire({ | ||||
|       identity: loginStatePart.getState().identity, | ||||
|       serviceData: payloadArg.serviceData, | ||||
|     }); | ||||
|     apiClient.identity = loginStatePart.getState().identity; | ||||
|     await apiClient.services.createService(payloadArg.serviceData); | ||||
|     currentState = await dataState.dispatchAction(getAllDataAction, null); | ||||
|     return currentState; | ||||
|   } | ||||
| @@ -278,16 +270,8 @@ export const createServiceAction = dataState.createAction( | ||||
| export const updateServiceAction = dataState.createAction( | ||||
|   async (statePartArg, payloadArg: { serviceId: string; serviceData: plugins.interfaces.data.IService['data'] }) => { | ||||
|     let currentState = statePartArg.getState(); | ||||
|     const trUpdateService = | ||||
|       new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.service.IRequest_Any_Cloudly_UpdateService>( | ||||
|         '/typedrequest', | ||||
|         'updateService' | ||||
|       ); | ||||
|     const response = await trUpdateService.fire({ | ||||
|       identity: loginStatePart.getState().identity, | ||||
|       serviceId: payloadArg.serviceId, | ||||
|       serviceData: payloadArg.serviceData, | ||||
|     }); | ||||
|     apiClient.identity = loginStatePart.getState().identity; | ||||
|     await apiClient.services.updateService(payloadArg.serviceId, payloadArg.serviceData); | ||||
|     currentState = await dataState.dispatchAction(getAllDataAction, null); | ||||
|     return currentState; | ||||
|   } | ||||
| @@ -296,15 +280,8 @@ export const updateServiceAction = dataState.createAction( | ||||
| export const deleteServiceAction = dataState.createAction( | ||||
|   async (statePartArg, payloadArg: { serviceId: string }) => { | ||||
|     let currentState = statePartArg.getState(); | ||||
|     const trDeleteService = | ||||
|       new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.service.IRequest_Any_Cloudly_DeleteServiceById>( | ||||
|         '/typedrequest', | ||||
|         'deleteServiceById' | ||||
|       ); | ||||
|     const response = await trDeleteService.fire({ | ||||
|       identity: loginStatePart.getState().identity, | ||||
|       serviceId: payloadArg.serviceId, | ||||
|     }); | ||||
|     apiClient.identity = loginStatePart.getState().identity; | ||||
|     await apiClient.services.deleteService(payloadArg.serviceId); | ||||
|     currentState = await dataState.dispatchAction(getAllDataAction, null); | ||||
|     return currentState; | ||||
|   } | ||||
| @@ -368,22 +345,9 @@ export const deleteSecretBundleAction = dataState.createAction( | ||||
| export const createImageAction = dataState.createAction( | ||||
|   async (statePartArg, payloadArg: { imageName: string, description: string }) => { | ||||
|     let currentState = statePartArg.getState(); | ||||
|     const trCreateImage = | ||||
|       new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.image.IRequest_CreateImage>( | ||||
|         '/typedrequest', | ||||
|         'createImage' | ||||
|       ); | ||||
|     const response = await trCreateImage.fire({ | ||||
|       identity: loginStatePart.getState().identity, | ||||
|       name: payloadArg.imageName, | ||||
|       description: payloadArg.description, | ||||
|     }); | ||||
|     currentState = { | ||||
|       ...currentState, | ||||
|       ...{ | ||||
|         images: [...currentState.images, response.image], | ||||
|       }, | ||||
|     }; | ||||
|     apiClient.identity = loginStatePart.getState().identity; | ||||
|     await apiClient.image.createImage({ name: payloadArg.imageName, description: payloadArg.description } as any); | ||||
|     currentState = await dataState.dispatchAction(getAllDataAction, null); | ||||
|     return currentState; | ||||
|   } | ||||
| ); | ||||
| @@ -391,21 +355,9 @@ export const createImageAction = dataState.createAction( | ||||
| export const deleteImageAction = dataState.createAction( | ||||
|   async (statePartArg, payloadArg: { imageId: string }) => { | ||||
|     let currentState = statePartArg.getState(); | ||||
|     const trDeleteImage = | ||||
|       new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.image.IRequest_DeleteImage>( | ||||
|         '/typedrequest', | ||||
|         'deleteImage' | ||||
|       ); | ||||
|     const response = await trDeleteImage.fire({ | ||||
|       identity: loginStatePart.getState().identity, | ||||
|       imageId: payloadArg.imageId, | ||||
|     }); | ||||
|     currentState = { | ||||
|       ...currentState, | ||||
|       ...{ | ||||
|         images: currentState.images.filter((image) => image.id !== payloadArg.imageId), | ||||
|       }, | ||||
|     }; | ||||
|     apiClient.identity = loginStatePart.getState().identity; | ||||
|     await apiClient.image.deleteImage(payloadArg.imageId); | ||||
|     currentState = await dataState.dispatchAction(getAllDataAction, null); | ||||
|     return currentState; | ||||
|   } | ||||
| ); | ||||
| @@ -414,15 +366,8 @@ export const deleteImageAction = dataState.createAction( | ||||
| export const createDeploymentAction = dataState.createAction( | ||||
|   async (statePartArg, payloadArg: { deploymentData: Partial<plugins.interfaces.data.IDeployment> }) => { | ||||
|     let currentState = statePartArg.getState(); | ||||
|     const trCreateDeployment = | ||||
|       new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.deployment.IReq_Any_Cloudly_CreateDeployment>( | ||||
|         '/typedrequest', | ||||
|         'createDeployment' | ||||
|       ); | ||||
|     const response = await trCreateDeployment.fire({ | ||||
|       identity: loginStatePart.getState().identity, | ||||
|       deploymentData: payloadArg.deploymentData, | ||||
|     }); | ||||
|     apiClient.identity = loginStatePart.getState().identity; | ||||
|     await apiClient.deployments.createDeployment(payloadArg.deploymentData); | ||||
|     currentState = await dataState.dispatchAction(getAllDataAction, null); | ||||
|     return currentState; | ||||
|   } | ||||
| @@ -431,16 +376,8 @@ export const createDeploymentAction = dataState.createAction( | ||||
| export const updateDeploymentAction = dataState.createAction( | ||||
|   async (statePartArg, payloadArg: { deploymentId: string; deploymentData: Partial<plugins.interfaces.data.IDeployment> }) => { | ||||
|     let currentState = statePartArg.getState(); | ||||
|     const trUpdateDeployment = | ||||
|       new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.deployment.IReq_Any_Cloudly_UpdateDeployment>( | ||||
|         '/typedrequest', | ||||
|         'updateDeployment' | ||||
|       ); | ||||
|     const response = await trUpdateDeployment.fire({ | ||||
|       identity: loginStatePart.getState().identity, | ||||
|       deploymentId: payloadArg.deploymentId, | ||||
|       deploymentData: payloadArg.deploymentData, | ||||
|     }); | ||||
|     apiClient.identity = loginStatePart.getState().identity; | ||||
|     await apiClient.deployments.updateDeployment(payloadArg.deploymentId, payloadArg.deploymentData); | ||||
|     currentState = await dataState.dispatchAction(getAllDataAction, null); | ||||
|     return currentState; | ||||
|   } | ||||
| @@ -449,15 +386,8 @@ export const updateDeploymentAction = dataState.createAction( | ||||
| export const deleteDeploymentAction = dataState.createAction( | ||||
|   async (statePartArg, payloadArg: { deploymentId: string }) => { | ||||
|     let currentState = statePartArg.getState(); | ||||
|     const trDeleteDeployment = | ||||
|       new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.deployment.IReq_Any_Cloudly_DeleteDeploymentById>( | ||||
|         '/typedrequest', | ||||
|         'deleteDeploymentById' | ||||
|       ); | ||||
|     const response = await trDeleteDeployment.fire({ | ||||
|       identity: loginStatePart.getState().identity, | ||||
|       deploymentId: payloadArg.deploymentId, | ||||
|     }); | ||||
|     apiClient.identity = loginStatePart.getState().identity; | ||||
|     await apiClient.deployments.deleteDeployment(payloadArg.deploymentId); | ||||
|     currentState = await dataState.dispatchAction(getAllDataAction, null); | ||||
|     return currentState; | ||||
|   } | ||||
| @@ -467,15 +397,8 @@ export const deleteDeploymentAction = dataState.createAction( | ||||
| export const createDnsEntryAction = dataState.createAction( | ||||
|   async (statePartArg, payloadArg: { dnsEntryData: plugins.interfaces.data.IDnsEntry['data'] }) => { | ||||
|     let currentState = statePartArg.getState(); | ||||
|     const trCreateDnsEntry = | ||||
|       new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.dns.IRequest_Any_Cloudly_CreateDnsEntry>( | ||||
|         '/typedrequest', | ||||
|         'createDnsEntry' | ||||
|       ); | ||||
|     const response = await trCreateDnsEntry.fire({ | ||||
|       identity: loginStatePart.getState().identity, | ||||
|       dnsEntryData: payloadArg.dnsEntryData, | ||||
|     }); | ||||
|     apiClient.identity = loginStatePart.getState().identity; | ||||
|     await apiClient.dns.createDnsEntry(payloadArg.dnsEntryData); | ||||
|     currentState = await dataState.dispatchAction(getAllDataAction, null); | ||||
|     return currentState; | ||||
|   } | ||||
| @@ -484,16 +407,8 @@ export const createDnsEntryAction = dataState.createAction( | ||||
| export const updateDnsEntryAction = dataState.createAction( | ||||
|   async (statePartArg, payloadArg: { dnsEntryId: string; dnsEntryData: plugins.interfaces.data.IDnsEntry['data'] }) => { | ||||
|     let currentState = statePartArg.getState(); | ||||
|     const trUpdateDnsEntry = | ||||
|       new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.dns.IRequest_Any_Cloudly_UpdateDnsEntry>( | ||||
|         '/typedrequest', | ||||
|         'updateDnsEntry' | ||||
|       ); | ||||
|     const response = await trUpdateDnsEntry.fire({ | ||||
|       identity: loginStatePart.getState().identity, | ||||
|       dnsEntryId: payloadArg.dnsEntryId, | ||||
|       dnsEntryData: payloadArg.dnsEntryData, | ||||
|     }); | ||||
|     apiClient.identity = loginStatePart.getState().identity; | ||||
|     await apiClient.dns.updateDnsEntry(payloadArg.dnsEntryId, payloadArg.dnsEntryData); | ||||
|     currentState = await dataState.dispatchAction(getAllDataAction, null); | ||||
|     return currentState; | ||||
|   } | ||||
| @@ -502,15 +417,8 @@ export const updateDnsEntryAction = dataState.createAction( | ||||
| export const deleteDnsEntryAction = dataState.createAction( | ||||
|   async (statePartArg, payloadArg: { dnsEntryId: string }) => { | ||||
|     let currentState = statePartArg.getState(); | ||||
|     const trDeleteDnsEntry = | ||||
|       new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.dns.IRequest_Any_Cloudly_DeleteDnsEntry>( | ||||
|         '/typedrequest', | ||||
|         'deleteDnsEntry' | ||||
|       ); | ||||
|     const response = await trDeleteDnsEntry.fire({ | ||||
|       identity: loginStatePart.getState().identity, | ||||
|       dnsEntryId: payloadArg.dnsEntryId, | ||||
|     }); | ||||
|     apiClient.identity = loginStatePart.getState().identity; | ||||
|     await apiClient.dns.deleteDnsEntry(payloadArg.dnsEntryId); | ||||
|     currentState = await dataState.dispatchAction(getAllDataAction, null); | ||||
|     return currentState; | ||||
|   } | ||||
| @@ -520,15 +428,8 @@ export const deleteDnsEntryAction = dataState.createAction( | ||||
| export const createDomainAction = dataState.createAction( | ||||
|   async (statePartArg, payloadArg: { domainData: plugins.interfaces.data.IDomain['data'] }) => { | ||||
|     let currentState = statePartArg.getState(); | ||||
|     const trCreateDomain = | ||||
|       new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.domain.IRequest_Any_Cloudly_CreateDomain>( | ||||
|         '/typedrequest', | ||||
|         'createDomain' | ||||
|       ); | ||||
|     const response = await trCreateDomain.fire({ | ||||
|       identity: loginStatePart.getState().identity, | ||||
|       domainData: payloadArg.domainData, | ||||
|     }); | ||||
|     apiClient.identity = loginStatePart.getState().identity; | ||||
|     await apiClient.domains.createDomain(payloadArg.domainData); | ||||
|     currentState = await dataState.dispatchAction(getAllDataAction, null); | ||||
|     return currentState; | ||||
|   } | ||||
| @@ -537,16 +438,8 @@ export const createDomainAction = dataState.createAction( | ||||
| export const updateDomainAction = dataState.createAction( | ||||
|   async (statePartArg, payloadArg: { domainId: string; domainData: plugins.interfaces.data.IDomain['data'] }) => { | ||||
|     let currentState = statePartArg.getState(); | ||||
|     const trUpdateDomain = | ||||
|       new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.domain.IRequest_Any_Cloudly_UpdateDomain>( | ||||
|         '/typedrequest', | ||||
|         'updateDomain' | ||||
|       ); | ||||
|     const response = await trUpdateDomain.fire({ | ||||
|       identity: loginStatePart.getState().identity, | ||||
|       domainId: payloadArg.domainId, | ||||
|       domainData: payloadArg.domainData, | ||||
|     }); | ||||
|     apiClient.identity = loginStatePart.getState().identity; | ||||
|     await apiClient.domains.updateDomain(payloadArg.domainId, payloadArg.domainData); | ||||
|     currentState = await dataState.dispatchAction(getAllDataAction, null); | ||||
|     return currentState; | ||||
|   } | ||||
| @@ -555,15 +448,8 @@ export const updateDomainAction = dataState.createAction( | ||||
| export const deleteDomainAction = dataState.createAction( | ||||
|   async (statePartArg, payloadArg: { domainId: string }) => { | ||||
|     let currentState = statePartArg.getState(); | ||||
|     const trDeleteDomain = | ||||
|       new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.domain.IRequest_Any_Cloudly_DeleteDomain>( | ||||
|         '/typedrequest', | ||||
|         'deleteDomain' | ||||
|       ); | ||||
|     const response = await trDeleteDomain.fire({ | ||||
|       identity: loginStatePart.getState().identity, | ||||
|       domainId: payloadArg.domainId, | ||||
|     }); | ||||
|     apiClient.identity = loginStatePart.getState().identity; | ||||
|     await apiClient.domains.deleteDomain(payloadArg.domainId); | ||||
|     currentState = await dataState.dispatchAction(getAllDataAction, null); | ||||
|     return currentState; | ||||
|   } | ||||
| @@ -572,16 +458,8 @@ export const deleteDomainAction = dataState.createAction( | ||||
| export const verifyDomainAction = dataState.createAction( | ||||
|   async (statePartArg, payloadArg: { domainId: string; verificationMethod?: 'dns' | 'http' | 'email' | 'manual' }) => { | ||||
|     let currentState = statePartArg.getState(); | ||||
|     const trVerifyDomain = | ||||
|       new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.domain.IRequest_Any_Cloudly_VerifyDomain>( | ||||
|         '/typedrequest', | ||||
|         'verifyDomain' | ||||
|       ); | ||||
|     const response = await trVerifyDomain.fire({ | ||||
|       identity: loginStatePart.getState().identity, | ||||
|       domainId: payloadArg.domainId, | ||||
|       verificationMethod: payloadArg.verificationMethod, | ||||
|     }); | ||||
|     apiClient.identity = loginStatePart.getState().identity; | ||||
|     await apiClient.domains.verifyDomain(payloadArg.domainId, payloadArg.verificationMethod); | ||||
|     currentState = await dataState.dispatchAction(getAllDataAction, null); | ||||
|     return currentState; | ||||
|   } | ||||
| @@ -591,15 +469,8 @@ export const verifyDomainAction = dataState.createAction( | ||||
| export const createExternalRegistryAction = dataState.createAction( | ||||
|   async (statePartArg, payloadArg: { registryData: plugins.interfaces.data.IExternalRegistry['data'] }) => { | ||||
|     let currentState = statePartArg.getState(); | ||||
|     const trCreateRegistry = | ||||
|       new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.externalRegistry.IReq_CreateRegistry>( | ||||
|         '/typedrequest', | ||||
|         'createExternalRegistry' | ||||
|       ); | ||||
|     const response = await trCreateRegistry.fire({ | ||||
|       identity: loginStatePart.getState().identity, | ||||
|       registryData: payloadArg.registryData, | ||||
|     }); | ||||
|     apiClient.identity = loginStatePart.getState().identity; | ||||
|     await apiClient.externalRegistry.createRegistry(payloadArg.registryData); | ||||
|     currentState = await dataState.dispatchAction(getAllDataAction, null); | ||||
|     return currentState; | ||||
|   } | ||||
| @@ -608,17 +479,17 @@ export const createExternalRegistryAction = dataState.createAction( | ||||
| export const updateExternalRegistryAction = dataState.createAction( | ||||
|   async (statePartArg, payloadArg: { registryId: string; registryData: plugins.interfaces.data.IExternalRegistry['data'] }) => { | ||||
|     let currentState = statePartArg.getState(); | ||||
|     const trUpdateRegistry = | ||||
|       new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.externalRegistry.IReq_UpdateRegistry>( | ||||
|         '/typedrequest', | ||||
|         'updateExternalRegistry' | ||||
|       ); | ||||
|     const response = await trUpdateRegistry.fire({ | ||||
|       identity: loginStatePart.getState().identity, | ||||
|       registryId: payloadArg.registryId, | ||||
|       registryData: payloadArg.registryData, | ||||
|     }); | ||||
|     try { | ||||
|       apiClient.identity = loginStatePart.getState().identity; | ||||
|       const reg = (currentState.externalRegistries as any[])?.find(r => r.id === payloadArg.registryId); | ||||
|       if (reg) { | ||||
|         reg.data = payloadArg.registryData; | ||||
|         await reg.update(); | ||||
|       } | ||||
|       currentState = await dataState.dispatchAction(getAllDataAction, null); | ||||
|     } catch (err) { | ||||
|       console.error('Failed to update external registry:', err); | ||||
|     } | ||||
|     return currentState; | ||||
|   } | ||||
| ); | ||||
| @@ -626,16 +497,16 @@ export const updateExternalRegistryAction = dataState.createAction( | ||||
| export const deleteExternalRegistryAction = dataState.createAction( | ||||
|   async (statePartArg, payloadArg: { registryId: string }) => { | ||||
|     let currentState = statePartArg.getState(); | ||||
|     const trDeleteRegistry = | ||||
|       new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.externalRegistry.IReq_DeleteRegistryById>( | ||||
|         '/typedrequest', | ||||
|         'deleteExternalRegistryById' | ||||
|       ); | ||||
|     const response = await trDeleteRegistry.fire({ | ||||
|       identity: loginStatePart.getState().identity, | ||||
|       registryId: payloadArg.registryId, | ||||
|     }); | ||||
|     try { | ||||
|       apiClient.identity = loginStatePart.getState().identity; | ||||
|       const reg = (currentState.externalRegistries as any[])?.find(r => r.id === payloadArg.registryId); | ||||
|       if (reg) { | ||||
|         await reg.delete(apiClient as any, reg.id); | ||||
|       } | ||||
|       currentState = await dataState.dispatchAction(getAllDataAction, null); | ||||
|     } catch (err) { | ||||
|       console.error('Failed to delete external registry:', err); | ||||
|     } | ||||
|     return currentState; | ||||
|   } | ||||
| ); | ||||
| @@ -643,26 +514,27 @@ export const deleteExternalRegistryAction = dataState.createAction( | ||||
| export const verifyExternalRegistryAction = dataState.createAction( | ||||
|   async (statePartArg, payloadArg: { registryId: string }) => { | ||||
|     let currentState = statePartArg.getState(); | ||||
|     const trVerifyRegistry = | ||||
|       new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.externalRegistry.IReq_VerifyRegistry>( | ||||
|         '/typedrequest', | ||||
|         'verifyExternalRegistry' | ||||
|       ); | ||||
|     const response = await trVerifyRegistry.fire({ | ||||
|       identity: loginStatePart.getState().identity, | ||||
|       registryId: payloadArg.registryId, | ||||
|     }); | ||||
|      | ||||
|     if (response.success && response.registry) { | ||||
|       // Update the registry in the state with the verified status | ||||
|     try { | ||||
|       apiClient.identity = loginStatePart.getState().identity; | ||||
|       const result = await apiClient.externalRegistry.verifyRegistry(payloadArg.registryId); | ||||
|       if (result.success && result.registry) { | ||||
|         const regs = (currentState.externalRegistries || []).slice(); | ||||
|         const idx = regs.findIndex(r => r.id === payloadArg.registryId); | ||||
|         if (idx >= 0) { | ||||
|           // Preserve instance; update its data + shallow props | ||||
|           const instance: any = regs[idx]; | ||||
|           instance.data = result.registry.data; | ||||
|           instance.id = result.registry.id; | ||||
|           regs[idx] = instance; | ||||
|         } | ||||
|         currentState = { | ||||
|           ...currentState, | ||||
|         externalRegistries: currentState.externalRegistries?.map(reg =>  | ||||
|           reg.id === payloadArg.registryId ? response.registry : reg | ||||
|         ) || [], | ||||
|           externalRegistries: regs, | ||||
|         }; | ||||
|       } | ||||
|      | ||||
|     } catch (err) { | ||||
|       console.error('Failed to verify external registry:', err); | ||||
|     } | ||||
|     return currentState; | ||||
|   } | ||||
| ); | ||||
| @@ -672,14 +544,8 @@ export const taskActions = { | ||||
|   getTasks: dataState.createAction( | ||||
|     async (statePartArg, payloadArg: {}) => { | ||||
|       const currentState = statePartArg.getState(); | ||||
|       const trGetTasks = | ||||
|         new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.task.IRequest_Any_Cloudly_GetTasks>( | ||||
|           '/typedrequest', | ||||
|           'getTasks' | ||||
|         ); | ||||
|       const response = await trGetTasks.fire({ | ||||
|         identity: loginStatePart.getState().identity, | ||||
|       }); | ||||
|       apiClient.identity = loginStatePart.getState().identity; | ||||
|       const response = await apiClient.tasks.getTasks(); | ||||
|       return { | ||||
|         ...currentState, | ||||
|         tasks: response.tasks, | ||||
| @@ -690,15 +556,8 @@ export const taskActions = { | ||||
|   getTaskExecutions: dataState.createAction( | ||||
|     async (statePartArg, payloadArg: { filter?: any }) => { | ||||
|       const currentState = statePartArg.getState(); | ||||
|       const trGetTaskExecutions = | ||||
|         new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.task.IRequest_Any_Cloudly_GetTaskExecutions>( | ||||
|           '/typedrequest', | ||||
|           'getTaskExecutions' | ||||
|         ); | ||||
|       const response = await trGetTaskExecutions.fire({ | ||||
|         identity: loginStatePart.getState().identity, | ||||
|         filter: payloadArg.filter, | ||||
|       }); | ||||
|       apiClient.identity = loginStatePart.getState().identity; | ||||
|       const response = await apiClient.tasks.getTaskExecutions(payloadArg.filter); | ||||
|       return { | ||||
|         ...currentState, | ||||
|         taskExecutions: response.executions, | ||||
| @@ -709,15 +568,8 @@ export const taskActions = { | ||||
|   getTaskExecutionById: dataState.createAction( | ||||
|     async (statePartArg, payloadArg: { executionId: string }) => { | ||||
|       const currentState = statePartArg.getState(); | ||||
|       const trGetTaskExecutionById = | ||||
|         new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.task.IRequest_Any_Cloudly_GetTaskExecutionById>( | ||||
|           '/typedrequest', | ||||
|           'getTaskExecutionById' | ||||
|         ); | ||||
|       const response = await trGetTaskExecutionById.fire({ | ||||
|         identity: loginStatePart.getState().identity, | ||||
|         executionId: payloadArg.executionId, | ||||
|       }); | ||||
|       apiClient.identity = loginStatePart.getState().identity; | ||||
|       await apiClient.tasks.getTaskExecutionById(payloadArg.executionId); | ||||
|       return currentState; | ||||
|     } | ||||
|   ), | ||||
| @@ -725,16 +577,8 @@ export const taskActions = { | ||||
|   triggerTask: dataState.createAction( | ||||
|     async (statePartArg, payloadArg: { taskName: string; userId?: string }) => { | ||||
|       const currentState = statePartArg.getState(); | ||||
|       const trTriggerTask = | ||||
|         new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.task.IRequest_Any_Cloudly_TriggerTask>( | ||||
|           '/typedrequest', | ||||
|           'triggerTask' | ||||
|         ); | ||||
|       const response = await trTriggerTask.fire({ | ||||
|         identity: loginStatePart.getState().identity, | ||||
|         taskName: payloadArg.taskName, | ||||
|         userId: payloadArg.userId, | ||||
|       }); | ||||
|       apiClient.identity = loginStatePart.getState().identity; | ||||
|       await apiClient.tasks.triggerTask(payloadArg.taskName, payloadArg.userId); | ||||
|       return currentState; | ||||
|     } | ||||
|   ), | ||||
| @@ -742,15 +586,8 @@ export const taskActions = { | ||||
|   cancelTask: dataState.createAction( | ||||
|     async (statePartArg, payloadArg: { executionId: string }) => { | ||||
|       const currentState = statePartArg.getState(); | ||||
|       const trCancelTask = | ||||
|         new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.task.IRequest_Any_Cloudly_CancelTask>( | ||||
|           '/typedrequest', | ||||
|           'cancelTask' | ||||
|         ); | ||||
|       const response = await trCancelTask.fire({ | ||||
|         identity: loginStatePart.getState().identity, | ||||
|         executionId: payloadArg.executionId, | ||||
|       }); | ||||
|       apiClient.identity = loginStatePart.getState().identity; | ||||
|       await apiClient.tasks.cancelTask(payloadArg.executionId); | ||||
|       return currentState; | ||||
|     } | ||||
|   ), | ||||
|   | ||||
| @@ -217,6 +217,13 @@ export class CloudlyDashboard extends DeesElement { | ||||
|     console.log(loginState); | ||||
|     if (loginState.identity) { | ||||
|       this.identity = loginState.identity; | ||||
|       try { | ||||
|         appstate.apiClient.identity = loginState.identity; | ||||
|         if (!appstate.apiClient['typedsocketClient']) { | ||||
|           await appstate.apiClient.start(); | ||||
|         } | ||||
|         try { appstate.apiClient.typedsocketClient.addTag('identity', appstate.apiClient.identity); } catch {} | ||||
|       } catch (e) { console.warn('Failed to initialize API client WS', e); } | ||||
|       await simpleLogin.switchToSlottedContent(); | ||||
|       await appstate.dataState.dispatchAction(appstate.getAllDataAction, null); | ||||
|     } | ||||
|   | ||||
| @@ -93,13 +93,8 @@ export class CloudlyViewSettings extends DeesElement { | ||||
|   private async loadSettings() { | ||||
|     this.isLoading = true; | ||||
|     try { | ||||
|       const trRequest = new plugins.deesDomtools.plugins.typedrequest.TypedRequest< | ||||
|         plugins.interfaces.requests.settings.IRequest_GetSettings | ||||
|       >( | ||||
|         '/typedrequest', | ||||
|         'getSettings' | ||||
|       ); | ||||
|       const response = await trRequest.fire({}); | ||||
|       // Use shared API client | ||||
|       const response = await appstate.apiClient.settings.getSettings(); | ||||
|       this.settings = response.settings; | ||||
|     } catch (error) { | ||||
|       console.error('Failed to load settings:', error); | ||||
| @@ -128,13 +123,7 @@ export class CloudlyViewSettings extends DeesElement { | ||||
|       } | ||||
|       console.log('Updates to send:', updates); | ||||
|  | ||||
|       const trRequest = new plugins.deesDomtools.plugins.typedrequest.TypedRequest< | ||||
|         plugins.interfaces.requests.settings.IRequest_UpdateSettings | ||||
|       >( | ||||
|         '/typedrequest', | ||||
|         'updateSettings' | ||||
|       ); | ||||
|       const response = await trRequest.fire({ updates }); | ||||
|       const response = await appstate.apiClient.settings.updateSettings(updates); | ||||
|  | ||||
|       if (response.success) { | ||||
|         plugins.deesCatalog.DeesToast.createAndShow({ | ||||
| @@ -159,13 +148,7 @@ export class CloudlyViewSettings extends DeesElement { | ||||
|   private async testConnection(provider: string) { | ||||
|     this.isLoading = true; | ||||
|     try { | ||||
|       const trRequest = new plugins.deesDomtools.plugins.typedrequest.TypedRequest< | ||||
|         plugins.interfaces.requests.settings.IRequest_TestProviderConnection | ||||
|       >( | ||||
|         '/typedrequest', | ||||
|         'testProviderConnection' | ||||
|       ); | ||||
|       const response = await trRequest.fire({ provider: provider as any }); | ||||
|       const response = await appstate.apiClient.settings.testProviderConnection(provider); | ||||
|  | ||||
|       this.testResults = { | ||||
|         ...this.testResults, | ||||
|   | ||||
| @@ -19,3 +19,7 @@ export { | ||||
|   webjwt, | ||||
|   smartstate, | ||||
| } | ||||
|  | ||||
| // Expose API client so UI can share it with CLI | ||||
| import * as servezoneApi from '@serve.zone/api'; | ||||
| export { servezoneApi }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user