UNPKG

@wandelbots/nova-js

Version:

Official JS client for the Wandelbots API

175 lines (152 loc) 5.08 kB
/** biome-ignore-all lint/suspicious/noExplicitAny: legacy code */ /** biome-ignore-all lint/style/noNonNullAssertion: legacy code */ import type { BaseAPI, Configuration as BaseConfiguration, } from "@wandelbots/nova-api/v2" import { ApplicationApi, BUSInputsOutputsApi, CellApi, ControllerApi, ControllerInputsOutputsApi, JoggingApi, KinematicsApi, MotionGroupApi, MotionGroupModelsApi, StoreCollisionComponentsApi, StoreCollisionSetupsApi, StoreObjectApi, SystemApi, TrajectoryCachingApi, TrajectoryExecutionApi, TrajectoryPlanningApi, VirtualControllerApi, VirtualControllerBehaviorApi, VirtualControllerInputsOutputsApi, } from "@wandelbots/nova-api/v2" import type { AxiosInstance } from "axios" import axios from "axios" type OmitFirstArg<F> = F extends (x: any, ...args: infer P) => infer R ? (...args: P) => R : never type UnwrapAxiosResponseReturn<T> = T extends (...a: any) => any ? ( ...a: Parameters<T> ) => Promise<Awaited<ReturnType<T>> extends { data: infer D } ? D : never> : never export type WithCellId<T> = { [P in keyof T]: UnwrapAxiosResponseReturn<OmitFirstArg<T[P]>> } export type WithUnwrappedAxiosResponse<T> = { [P in keyof T]: UnwrapAxiosResponseReturn<T[P]> } /** * API client providing type-safe access to all the Nova API REST endpoints * associated with a specific cell id. */ export class NovaCellAPIClient { constructor( readonly cellId: string, readonly opts: BaseConfiguration & { axiosInstance?: AxiosInstance mock?: boolean }, ) {} /** * Some TypeScript sorcery which alters the API class methods so you don't * have to pass the cell id to every single one, and de-encapsulates the * response data */ private withCellId<T extends BaseAPI>( ApiConstructor: new ( config: BaseConfiguration, basePath: string, axios: AxiosInstance, ) => T, ) { const apiClient = new ApiConstructor( { ...this.opts, isJsonMime: (mime: string) => { return mime === "application/json" }, }, this.opts.basePath ?? "", this.opts.axiosInstance ?? axios.create(), ) as { [key: string | symbol]: any } for (const key of Reflect.ownKeys(Reflect.getPrototypeOf(apiClient)!)) { if (key !== "constructor" && typeof apiClient[key] === "function") { const originalFunction = apiClient[key] apiClient[key] = (...args: any[]) => { return originalFunction .apply(apiClient, [this.cellId, ...args]) .then((res: any) => res.data) } } } return apiClient as WithCellId<T> } /** * As withCellId, but only does the response unwrapping */ private withUnwrappedResponsesOnly<T extends BaseAPI>( ApiConstructor: new ( config: BaseConfiguration, basePath: string, axios: AxiosInstance, ) => T, ) { const apiClient = new ApiConstructor( { ...this.opts, isJsonMime: (mime: string) => { return mime === "application/json" }, }, this.opts.basePath ?? "", this.opts.axiosInstance ?? axios.create(), ) as { [key: string | symbol]: any } for (const key of Reflect.ownKeys(Reflect.getPrototypeOf(apiClient)!)) { if (key !== "constructor" && typeof apiClient[key] === "function") { const originalFunction = apiClient[key] apiClient[key] = (...args: any[]) => { return originalFunction .apply(apiClient, args) .then((res: any) => res.data) } } } return apiClient as WithUnwrappedAxiosResponse<T> } readonly system = this.withUnwrappedResponsesOnly(SystemApi) readonly cell = this.withUnwrappedResponsesOnly(CellApi) readonly motionGroup = this.withCellId(MotionGroupApi) readonly motionGroupModels = this.withCellId(MotionGroupModelsApi) readonly controller = this.withCellId(ControllerApi) readonly controllerIOs = this.withCellId(ControllerInputsOutputsApi) readonly trajectoryPlanning = this.withCellId(TrajectoryPlanningApi) readonly trajectoryExecution = this.withCellId(TrajectoryExecutionApi) readonly trajectoryCaching = this.withCellId(TrajectoryCachingApi) readonly application = this.withCellId(ApplicationApi) readonly applicationGlobal = this.withUnwrappedResponsesOnly(ApplicationApi) readonly jogging = this.withCellId(JoggingApi) readonly kinematics = this.withCellId(KinematicsApi) readonly busInputsOutputs = this.withCellId(BUSInputsOutputsApi) readonly virtualController = this.withCellId(VirtualControllerApi) readonly virtualControllerBehavior = this.withCellId( VirtualControllerBehaviorApi, ) readonly virtualControllerIOs = this.withCellId( VirtualControllerInputsOutputsApi, ) readonly storeObject = this.withCellId(StoreObjectApi) readonly storeCollisionComponents = this.withCellId( StoreCollisionComponentsApi, ) readonly storeCollisionSetups = this.withCellId(StoreCollisionSetupsApi) }