@wandelbots/nova-js 3.13.0 → 4.0.0-pr.309.02b99fd
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AutoReconnectingWebsocket-1K2J1NA4.d.cts → AutoReconnectingWebsocket-BSt-vnzX.d.mts} +4 -16
- package/dist/AutoReconnectingWebsocket-BSt-vnzX.d.mts.map +1 -0
- package/dist/{context-ffr5Q2dc.mjs → LoginWithAuth0-D92HnzHq.mjs} +3 -13
- package/dist/LoginWithAuth0-D92HnzHq.mjs.map +1 -0
- package/dist/{Nova--8gozkLR.d.mts → Nova-C8nDNSCa.d.mts} +2 -2
- package/dist/{Nova--8gozkLR.d.mts.map → Nova-C8nDNSCa.d.mts.map} +1 -1
- package/dist/experimental/nats/index.d.mts +1 -1
- package/dist/index.d.mts +2 -7
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -3
- package/dist/v2/index.d.mts +2 -130
- package/dist/v2/index.mjs +4 -231
- package/dist/v2/index.mjs.map +1 -1
- package/package.json +13 -17
- package/src/index.ts +0 -2
- package/src/lib/AutoReconnectingWebsocket.ts +3 -4
- package/src/lib/LoginWithAuth0.ts +1 -1
- package/src/lib/context.ts +1 -1
- package/src/lib/errorHandling.ts +0 -7
- package/src/v2/index.ts +0 -3
- package/dist/AutoReconnectingWebsocket-1K2J1NA4.d.cts.map +0 -1
- package/dist/AutoReconnectingWebsocket-1K2J1NA4.d.mts +0 -69
- package/dist/AutoReconnectingWebsocket-1K2J1NA4.d.mts.map +0 -1
- package/dist/Nova-B1o5iTQ6.d.cts +0 -85
- package/dist/Nova-B1o5iTQ6.d.cts.map +0 -1
- package/dist/context-BZELA2eh.cjs +0 -348
- package/dist/context-BZELA2eh.cjs.map +0 -1
- package/dist/context-ffr5Q2dc.mjs.map +0 -1
- package/dist/converters-EYS27XJE.cjs +0 -146
- package/dist/converters-EYS27XJE.cjs.map +0 -1
- package/dist/experimental/nats/index.cjs +0 -158
- package/dist/experimental/nats/index.cjs.map +0 -1
- package/dist/experimental/nats/index.d.cts +0 -3235
- package/dist/experimental/nats/index.d.cts.map +0 -1
- package/dist/index.cjs +0 -24
- package/dist/index.d.cts +0 -110
- package/dist/index.d.cts.map +0 -1
- package/dist/v1/index.cjs +0 -201
- package/dist/v1/index.cjs.map +0 -1
- package/dist/v1/index.d.cts +0 -67
- package/dist/v1/index.d.cts.map +0 -1
- package/dist/v1/index.d.mts +0 -67
- package/dist/v1/index.d.mts.map +0 -1
- package/dist/v1/index.mjs +0 -184
- package/dist/v1/index.mjs.map +0 -1
- package/dist/v2/index.cjs +0 -1038
- package/dist/v2/index.cjs.map +0 -1
- package/dist/v2/index.d.cts +0 -131
- package/dist/v2/index.d.cts.map +0 -1
- package/dist/v2/index.d.mts.map +0 -1
- package/dist/wandelscriptUtils-CpUXdLVc.mjs +0 -2062
- package/dist/wandelscriptUtils-CpUXdLVc.mjs.map +0 -1
- package/dist/wandelscriptUtils-DY3WsiuB.d.cts +0 -356
- package/dist/wandelscriptUtils-DY3WsiuB.d.cts.map +0 -1
- package/dist/wandelscriptUtils-DcY1aLWu.cjs +0 -2099
- package/dist/wandelscriptUtils-DcY1aLWu.cjs.map +0 -1
- package/dist/wandelscriptUtils-YHTxn_p9.d.mts +0 -356
- package/dist/wandelscriptUtils-YHTxn_p9.d.mts.map +0 -1
- package/src/lib/deprecated/v1/ConnectedMotionGroup.ts +0 -449
- package/src/lib/deprecated/v1/JoggerConnection.ts +0 -491
- package/src/lib/deprecated/v1/MotionStreamConnection.ts +0 -215
- package/src/lib/deprecated/v1/NovaCellAPIClient.ts +0 -208
- package/src/lib/deprecated/v1/NovaClient.ts +0 -260
- package/src/lib/deprecated/v1/ProgramStateConnection.ts +0 -277
- package/src/lib/deprecated/v1/getLatestTrajectories.ts +0 -37
- package/src/lib/deprecated/v1/mock/MockNovaInstance.ts +0 -1303
- package/src/lib/deprecated/v1/motionStateUpdate.ts +0 -58
- package/src/lib/deprecated/v1/wandelscriptUtils.ts +0 -23
- package/src/lib/deprecated/v2/NovaCellAPIClient.ts +0 -215
- package/src/lib/deprecated/v2/NovaClient.ts +0 -218
- package/src/lib/deprecated/v2/wandelscriptUtils.ts +0 -28
- package/src/v1/index.ts +0 -14
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
/** biome-ignore-all lint/style/noNonNullAssertion: legacy code */
|
|
2
|
-
/** biome-ignore-all lint/suspicious/noExplicitAny: legacy code */
|
|
3
|
-
import type {
|
|
4
|
-
BaseAPI,
|
|
5
|
-
Configuration as BaseConfiguration,
|
|
6
|
-
} from "@wandelbots/nova-api/v1"
|
|
7
|
-
import {
|
|
8
|
-
ApplicationApi,
|
|
9
|
-
CellApi,
|
|
10
|
-
ControllerApi,
|
|
11
|
-
ControllerIOsApi,
|
|
12
|
-
CoordinateSystemsApi,
|
|
13
|
-
DeviceConfigurationApi,
|
|
14
|
-
LibraryProgramApi,
|
|
15
|
-
LibraryProgramMetadataApi,
|
|
16
|
-
LibraryRecipeApi,
|
|
17
|
-
LibraryRecipeMetadataApi,
|
|
18
|
-
MotionApi,
|
|
19
|
-
MotionGroupApi,
|
|
20
|
-
MotionGroupInfosApi,
|
|
21
|
-
MotionGroupJoggingApi,
|
|
22
|
-
MotionGroupKinematicApi,
|
|
23
|
-
ProgramApi,
|
|
24
|
-
ProgramValuesApi,
|
|
25
|
-
StoreCollisionComponentsApi,
|
|
26
|
-
StoreCollisionScenesApi,
|
|
27
|
-
StoreObjectApi,
|
|
28
|
-
SystemApi,
|
|
29
|
-
VirtualRobotApi,
|
|
30
|
-
VirtualRobotBehaviorApi,
|
|
31
|
-
VirtualRobotModeApi,
|
|
32
|
-
VirtualRobotSetupApi,
|
|
33
|
-
} from "@wandelbots/nova-api/v1"
|
|
34
|
-
import type { AxiosInstance } from "axios"
|
|
35
|
-
import axios from "axios"
|
|
36
|
-
|
|
37
|
-
type OmitFirstArg<F> = F extends (x: any, ...args: infer P) => infer R
|
|
38
|
-
? (...args: P) => R
|
|
39
|
-
: never
|
|
40
|
-
|
|
41
|
-
type UnwrapAxiosResponseReturn<T> = T extends (...a: any) => any
|
|
42
|
-
? (
|
|
43
|
-
...a: Parameters<T>
|
|
44
|
-
) => Promise<Awaited<ReturnType<T>> extends { data: infer D } ? D : never>
|
|
45
|
-
: never
|
|
46
|
-
|
|
47
|
-
/** @deprecated Use `NovaAPIClient` instead. */
|
|
48
|
-
export type WithCellId<T> = {
|
|
49
|
-
[P in keyof T]: UnwrapAxiosResponseReturn<OmitFirstArg<T[P]>>
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/** @deprecated Use `NovaAPIClient` instead. */
|
|
53
|
-
export type WithUnwrappedAxiosResponse<T> = {
|
|
54
|
-
[P in keyof T]: UnwrapAxiosResponseReturn<T[P]>
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* API client providing type-safe access to all the Nova API REST endpoints
|
|
59
|
-
* associated with a specific cell id.
|
|
60
|
-
* @deprecated Use `NovaAPIClient` from `@wandelbots/nova-js/v2` instead.
|
|
61
|
-
*/
|
|
62
|
-
export class NovaCellAPIClient {
|
|
63
|
-
readonly system: WithUnwrappedAxiosResponse<SystemApi>
|
|
64
|
-
readonly cell: WithUnwrappedAxiosResponse<CellApi>
|
|
65
|
-
readonly deviceConfig: WithCellId<DeviceConfigurationApi>
|
|
66
|
-
readonly motionGroup: WithCellId<MotionGroupApi>
|
|
67
|
-
readonly motionGroupInfos: WithCellId<MotionGroupInfosApi>
|
|
68
|
-
readonly controller: WithCellId<ControllerApi>
|
|
69
|
-
readonly program: WithCellId<ProgramApi>
|
|
70
|
-
readonly programValues: WithCellId<ProgramValuesApi>
|
|
71
|
-
readonly controllerIOs: WithCellId<ControllerIOsApi>
|
|
72
|
-
readonly motionGroupKinematic: WithCellId<MotionGroupKinematicApi>
|
|
73
|
-
readonly motion: WithCellId<MotionApi>
|
|
74
|
-
readonly coordinateSystems: WithCellId<CoordinateSystemsApi>
|
|
75
|
-
readonly application: WithCellId<ApplicationApi>
|
|
76
|
-
readonly applicationGlobal: WithUnwrappedAxiosResponse<ApplicationApi>
|
|
77
|
-
readonly motionGroupJogging: WithCellId<MotionGroupJoggingApi>
|
|
78
|
-
readonly virtualRobot: WithCellId<VirtualRobotApi>
|
|
79
|
-
readonly virtualRobotSetup: WithCellId<VirtualRobotSetupApi>
|
|
80
|
-
readonly virtualRobotMode: WithCellId<VirtualRobotModeApi>
|
|
81
|
-
readonly virtualRobotBehavior: WithCellId<VirtualRobotBehaviorApi>
|
|
82
|
-
readonly libraryProgramMetadata: WithCellId<LibraryProgramMetadataApi>
|
|
83
|
-
readonly libraryProgram: WithCellId<LibraryProgramApi>
|
|
84
|
-
readonly libraryRecipeMetadata: WithCellId<LibraryRecipeMetadataApi>
|
|
85
|
-
readonly libraryRecipe: WithCellId<LibraryRecipeApi>
|
|
86
|
-
readonly storeObject: WithCellId<StoreObjectApi>
|
|
87
|
-
readonly storeCollisionComponents: WithCellId<StoreCollisionComponentsApi>
|
|
88
|
-
readonly storeCollisionScenes: WithCellId<StoreCollisionScenesApi>
|
|
89
|
-
|
|
90
|
-
readonly cellId: string
|
|
91
|
-
readonly opts: BaseConfiguration & {
|
|
92
|
-
axiosInstance?: AxiosInstance
|
|
93
|
-
mock?: boolean
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
constructor(
|
|
97
|
-
cellId: string,
|
|
98
|
-
opts: BaseConfiguration & {
|
|
99
|
-
axiosInstance?: AxiosInstance
|
|
100
|
-
mock?: boolean
|
|
101
|
-
},
|
|
102
|
-
) {
|
|
103
|
-
this.cellId = cellId
|
|
104
|
-
this.opts = opts
|
|
105
|
-
this.system = this.withUnwrappedResponsesOnly(SystemApi)
|
|
106
|
-
this.cell = this.withUnwrappedResponsesOnly(CellApi)
|
|
107
|
-
this.deviceConfig = this.withCellId(DeviceConfigurationApi)
|
|
108
|
-
this.motionGroup = this.withCellId(MotionGroupApi)
|
|
109
|
-
this.motionGroupInfos = this.withCellId(MotionGroupInfosApi)
|
|
110
|
-
this.controller = this.withCellId(ControllerApi)
|
|
111
|
-
this.program = this.withCellId(ProgramApi)
|
|
112
|
-
this.programValues = this.withCellId(ProgramValuesApi)
|
|
113
|
-
this.controllerIOs = this.withCellId(ControllerIOsApi)
|
|
114
|
-
this.motionGroupKinematic = this.withCellId(MotionGroupKinematicApi)
|
|
115
|
-
this.motion = this.withCellId(MotionApi)
|
|
116
|
-
this.coordinateSystems = this.withCellId(CoordinateSystemsApi)
|
|
117
|
-
this.application = this.withCellId(ApplicationApi)
|
|
118
|
-
this.applicationGlobal = this.withUnwrappedResponsesOnly(ApplicationApi)
|
|
119
|
-
this.motionGroupJogging = this.withCellId(MotionGroupJoggingApi)
|
|
120
|
-
this.virtualRobot = this.withCellId(VirtualRobotApi)
|
|
121
|
-
this.virtualRobotSetup = this.withCellId(VirtualRobotSetupApi)
|
|
122
|
-
this.virtualRobotMode = this.withCellId(VirtualRobotModeApi)
|
|
123
|
-
this.virtualRobotBehavior = this.withCellId(VirtualRobotBehaviorApi)
|
|
124
|
-
this.libraryProgramMetadata = this.withCellId(LibraryProgramMetadataApi)
|
|
125
|
-
this.libraryProgram = this.withCellId(LibraryProgramApi)
|
|
126
|
-
this.libraryRecipeMetadata = this.withCellId(LibraryRecipeMetadataApi)
|
|
127
|
-
this.libraryRecipe = this.withCellId(LibraryRecipeApi)
|
|
128
|
-
this.storeObject = this.withCellId(StoreObjectApi)
|
|
129
|
-
this.storeCollisionComponents = this.withCellId(StoreCollisionComponentsApi)
|
|
130
|
-
this.storeCollisionScenes = this.withCellId(StoreCollisionScenesApi)
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Some TypeScript sorcery which alters the API class methods so you don't
|
|
135
|
-
* have to pass the cell id to every single one, and de-encapsulates the
|
|
136
|
-
* response data
|
|
137
|
-
*/
|
|
138
|
-
private withCellId<T extends BaseAPI>(
|
|
139
|
-
ApiConstructor: new (
|
|
140
|
-
config: BaseConfiguration,
|
|
141
|
-
basePath: string,
|
|
142
|
-
axios: AxiosInstance,
|
|
143
|
-
) => T,
|
|
144
|
-
) {
|
|
145
|
-
const apiClient = new ApiConstructor(
|
|
146
|
-
{
|
|
147
|
-
...this.opts,
|
|
148
|
-
isJsonMime: (mime: string) => {
|
|
149
|
-
return mime === "application/json"
|
|
150
|
-
},
|
|
151
|
-
},
|
|
152
|
-
this.opts.basePath ?? "",
|
|
153
|
-
this.opts.axiosInstance ?? axios.create(),
|
|
154
|
-
) as {
|
|
155
|
-
[key: string | symbol]: any
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
for (const key of Reflect.ownKeys(Reflect.getPrototypeOf(apiClient)!)) {
|
|
159
|
-
if (key !== "constructor" && typeof apiClient[key] === "function") {
|
|
160
|
-
const originalFunction = apiClient[key]
|
|
161
|
-
apiClient[key] = (...args: any[]) => {
|
|
162
|
-
return originalFunction
|
|
163
|
-
.apply(apiClient, [this.cellId, ...args])
|
|
164
|
-
.then((res: any) => res.data)
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
return apiClient as WithCellId<T>
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* As withCellId, but only does the response unwrapping
|
|
174
|
-
*/
|
|
175
|
-
private withUnwrappedResponsesOnly<T extends BaseAPI>(
|
|
176
|
-
ApiConstructor: new (
|
|
177
|
-
config: BaseConfiguration,
|
|
178
|
-
basePath: string,
|
|
179
|
-
axios: AxiosInstance,
|
|
180
|
-
) => T,
|
|
181
|
-
) {
|
|
182
|
-
const apiClient = new ApiConstructor(
|
|
183
|
-
{
|
|
184
|
-
...this.opts,
|
|
185
|
-
isJsonMime: (mime: string) => {
|
|
186
|
-
return mime === "application/json"
|
|
187
|
-
},
|
|
188
|
-
},
|
|
189
|
-
this.opts.basePath ?? "",
|
|
190
|
-
this.opts.axiosInstance ?? axios.create(),
|
|
191
|
-
) as {
|
|
192
|
-
[key: string | symbol]: any
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
for (const key of Reflect.ownKeys(Reflect.getPrototypeOf(apiClient)!)) {
|
|
196
|
-
if (key !== "constructor" && typeof apiClient[key] === "function") {
|
|
197
|
-
const originalFunction = apiClient[key]
|
|
198
|
-
apiClient[key] = (...args: any[]) => {
|
|
199
|
-
return originalFunction
|
|
200
|
-
.apply(apiClient, args)
|
|
201
|
-
.then((res: any) => res.data)
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
return apiClient as WithUnwrappedAxiosResponse<T>
|
|
207
|
-
}
|
|
208
|
-
}
|
|
@@ -1,260 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview
|
|
3
|
-
* @deprecated The nova v1 client is deprecated. Please use the v2 client from `@wandelbots/nova-js/v2` instead.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { Configuration as BaseConfiguration } from "@wandelbots/nova-api/v1"
|
|
7
|
-
import type { AxiosRequestConfig } from "axios"
|
|
8
|
-
import axios, { isAxiosError } from "axios"
|
|
9
|
-
import { AutoReconnectingWebsocket } from "../../AutoReconnectingWebsocket.ts"
|
|
10
|
-
import { loginWithAuth0 } from "../../LoginWithAuth0.ts"
|
|
11
|
-
import { availableStorage } from "../../availableStorage.ts"
|
|
12
|
-
import { parseNovaInstanceUrl } from "../../converters.ts"
|
|
13
|
-
import { guardedPageReload } from "../../errorHandling.ts"
|
|
14
|
-
|
|
15
|
-
import { isBrowser, isLocalhostDev } from "../../context.ts"
|
|
16
|
-
import { ConnectedMotionGroup } from "./ConnectedMotionGroup.ts"
|
|
17
|
-
import { JoggerConnection } from "./JoggerConnection.ts"
|
|
18
|
-
import { MotionStreamConnection } from "./MotionStreamConnection.ts"
|
|
19
|
-
import { NovaCellAPIClient } from "./NovaCellAPIClient.ts"
|
|
20
|
-
import { MockNovaInstance } from "./mock/MockNovaInstance.ts"
|
|
21
|
-
|
|
22
|
-
/** @deprecated Use `NovaConfig` from `@wandelbots/nova-js/v2` instead. */
|
|
23
|
-
export type NovaClientConfig = {
|
|
24
|
-
/**
|
|
25
|
-
* Url of the deployed Nova instance to connect to
|
|
26
|
-
* e.g. https://saeattii.instance.wandelbots.io
|
|
27
|
-
*/
|
|
28
|
-
instanceUrl: string | "https://mock.example.com"
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Identifier of the cell on the Nova instance to connect this client to.
|
|
32
|
-
* If omitted, the default identifier "cell" is used.
|
|
33
|
-
**/
|
|
34
|
-
cellId?: string
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Username for basic auth to the Nova instance.
|
|
38
|
-
* @deprecated use accessToken instead
|
|
39
|
-
*/
|
|
40
|
-
username?: string
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Password for basic auth to the Nova instance.
|
|
44
|
-
* @deprecated use accessToken instead
|
|
45
|
-
*/
|
|
46
|
-
password?: string
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Access token for Bearer authentication.
|
|
50
|
-
*/
|
|
51
|
-
accessToken?: string
|
|
52
|
-
} & Omit<BaseConfiguration, "isJsonMime" | "basePath">
|
|
53
|
-
|
|
54
|
-
type NovaClientConfigWithDefaults = NovaClientConfig & { cellId: string }
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Client for connecting to a Nova instance and controlling robots.
|
|
58
|
-
* @deprecated The nova v1 client is deprecated. Please use the v2 client from `@wandelbots/nova-js/v2` instead.
|
|
59
|
-
*/
|
|
60
|
-
export class NovaClient {
|
|
61
|
-
readonly api: NovaCellAPIClient
|
|
62
|
-
readonly config: NovaClientConfigWithDefaults
|
|
63
|
-
readonly mock?: MockNovaInstance
|
|
64
|
-
readonly instanceUrl: URL
|
|
65
|
-
authPromise: Promise<string | null> | null = null
|
|
66
|
-
accessToken: string | null = null
|
|
67
|
-
|
|
68
|
-
constructor(config: NovaClientConfig) {
|
|
69
|
-
const cellId = config.cellId ?? "cell"
|
|
70
|
-
this.config = {
|
|
71
|
-
cellId,
|
|
72
|
-
...config,
|
|
73
|
-
}
|
|
74
|
-
this.accessToken =
|
|
75
|
-
config.accessToken ||
|
|
76
|
-
availableStorage.getString("wbjs.access_token") ||
|
|
77
|
-
null
|
|
78
|
-
|
|
79
|
-
if (this.config.instanceUrl === "https://mock.example.com") {
|
|
80
|
-
this.mock = new MockNovaInstance()
|
|
81
|
-
}
|
|
82
|
-
this.instanceUrl = parseNovaInstanceUrl(this.config.instanceUrl)
|
|
83
|
-
|
|
84
|
-
// Set up Axios instance with interceptor for token fetching
|
|
85
|
-
const axiosInstance = axios.create({
|
|
86
|
-
baseURL: new URL("/api/v1", this.config.instanceUrl).href,
|
|
87
|
-
// TODO - backend needs to set proper CORS headers for this
|
|
88
|
-
headers: isLocalhostDev
|
|
89
|
-
? {}
|
|
90
|
-
: {
|
|
91
|
-
// Identify the client to the backend for logging purposes
|
|
92
|
-
"X-Wandelbots-Client": "Wandelbots-Nova-JS-SDK",
|
|
93
|
-
},
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
axiosInstance.interceptors.request.use(async (request) => {
|
|
97
|
-
if (!request.headers.Authorization) {
|
|
98
|
-
if (this.accessToken) {
|
|
99
|
-
request.headers.Authorization = `Bearer ${this.accessToken}`
|
|
100
|
-
} else if (this.config.username && this.config.password) {
|
|
101
|
-
request.headers.Authorization = `Basic ${btoa(`${config.username}:${config.password}`)}`
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
return request
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
if (isBrowser) {
|
|
108
|
-
axiosInstance.interceptors.response.use(
|
|
109
|
-
(r) => r,
|
|
110
|
-
async (error) => {
|
|
111
|
-
if (isAxiosError(error)) {
|
|
112
|
-
if (error.response?.status === 401) {
|
|
113
|
-
// If we hit a 401, attempt to login the user and retry with
|
|
114
|
-
// a new access token
|
|
115
|
-
try {
|
|
116
|
-
await this.renewAuthentication()
|
|
117
|
-
|
|
118
|
-
if (error.config) {
|
|
119
|
-
if (this.accessToken) {
|
|
120
|
-
error.config.headers.Authorization = `Bearer ${this.accessToken}`
|
|
121
|
-
} else {
|
|
122
|
-
delete error.config.headers.Authorization
|
|
123
|
-
}
|
|
124
|
-
return axiosInstance.request(error.config)
|
|
125
|
-
}
|
|
126
|
-
} catch (err) {
|
|
127
|
-
return Promise.reject(err)
|
|
128
|
-
}
|
|
129
|
-
} else if (error.response?.status === 503) {
|
|
130
|
-
// Check if the server as a whole is down
|
|
131
|
-
const res = await fetch(window.location.href)
|
|
132
|
-
if (res.status === 503) {
|
|
133
|
-
// Go to 503 page
|
|
134
|
-
return guardedPageReload("503_server_unavailable")
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return Promise.reject(error)
|
|
140
|
-
},
|
|
141
|
-
)
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
this.api = new NovaCellAPIClient(cellId, {
|
|
145
|
-
...config,
|
|
146
|
-
basePath: new URL("/api/v1", this.instanceUrl).href,
|
|
147
|
-
isJsonMime: (mime: string) => {
|
|
148
|
-
return mime === "application/json"
|
|
149
|
-
},
|
|
150
|
-
baseOptions: {
|
|
151
|
-
...(this.mock
|
|
152
|
-
? ({
|
|
153
|
-
adapter: (config) => {
|
|
154
|
-
// biome-ignore lint/style/noNonNullAssertion: legacy code
|
|
155
|
-
return this.mock!.handleAPIRequest(config)
|
|
156
|
-
},
|
|
157
|
-
} satisfies AxiosRequestConfig)
|
|
158
|
-
: {}),
|
|
159
|
-
...config.baseOptions,
|
|
160
|
-
},
|
|
161
|
-
axiosInstance,
|
|
162
|
-
})
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
async renewAuthentication(): Promise<void> {
|
|
166
|
-
if (this.authPromise) {
|
|
167
|
-
// Don't double up
|
|
168
|
-
return
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const storedToken = availableStorage.getString("wbjs.access_token")
|
|
172
|
-
if (storedToken && this.accessToken !== storedToken) {
|
|
173
|
-
// Might be newer than the one we have
|
|
174
|
-
this.accessToken = storedToken
|
|
175
|
-
return
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// Otherwise, perform login flow
|
|
179
|
-
this.authPromise = loginWithAuth0(this.instanceUrl)
|
|
180
|
-
try {
|
|
181
|
-
this.accessToken = await this.authPromise
|
|
182
|
-
if (this.accessToken) {
|
|
183
|
-
// Cache access token so we don't need to log in every refresh
|
|
184
|
-
availableStorage.setString("wbjs.access_token", this.accessToken)
|
|
185
|
-
} else {
|
|
186
|
-
availableStorage.delete("wbjs.access_token")
|
|
187
|
-
}
|
|
188
|
-
} finally {
|
|
189
|
-
this.authPromise = null
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
makeWebsocketURL(path: string): string {
|
|
194
|
-
const url = new URL(
|
|
195
|
-
new URL(
|
|
196
|
-
`/api/v1/cells/${this.config.cellId}/${path.replace(/^\/+/, "")}`,
|
|
197
|
-
this.instanceUrl,
|
|
198
|
-
).href,
|
|
199
|
-
)
|
|
200
|
-
url.protocol = url.protocol.replace("http", "ws")
|
|
201
|
-
url.protocol = url.protocol.replace("https", "wss")
|
|
202
|
-
|
|
203
|
-
// If provided, add basic auth credentials to the URL
|
|
204
|
-
// NOTE - basic auth is deprecated on websockets and doesn't work in Safari
|
|
205
|
-
// use tokens instead
|
|
206
|
-
if (this.accessToken) {
|
|
207
|
-
url.searchParams.append("token", this.accessToken)
|
|
208
|
-
} else if (this.config.username && this.config.password) {
|
|
209
|
-
url.username = this.config.username
|
|
210
|
-
url.password = this.config.password
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
return url.toString()
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* Retrieve an AutoReconnectingWebsocket to the given path on the Nova instance.
|
|
218
|
-
* If you explicitly want to reconnect an existing websocket, call `reconnect`
|
|
219
|
-
* on the returned object.
|
|
220
|
-
*/
|
|
221
|
-
openReconnectingWebsocket(path: string) {
|
|
222
|
-
return new AutoReconnectingWebsocket(this.makeWebsocketURL(path), {
|
|
223
|
-
mock: this.mock,
|
|
224
|
-
})
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Connect to the motion state websocket(s) for a given motion group
|
|
229
|
-
*/
|
|
230
|
-
async connectMotionStream(motionGroupId: string) {
|
|
231
|
-
return await MotionStreamConnection.open(this, motionGroupId)
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Connect to the jogging websocket(s) for a given motion group
|
|
236
|
-
*/
|
|
237
|
-
async connectJogger(motionGroupId: string) {
|
|
238
|
-
return await JoggerConnection.open(this, motionGroupId)
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
async connectMotionGroups(
|
|
242
|
-
motionGroupIds: string[],
|
|
243
|
-
): Promise<ConnectedMotionGroup[]> {
|
|
244
|
-
const { instances } = await this.api.controller.listControllers()
|
|
245
|
-
|
|
246
|
-
return Promise.all(
|
|
247
|
-
motionGroupIds.map((motionGroupId) =>
|
|
248
|
-
ConnectedMotionGroup.connect(this, motionGroupId, instances),
|
|
249
|
-
),
|
|
250
|
-
)
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
async connectMotionGroup(
|
|
254
|
-
motionGroupId: string,
|
|
255
|
-
): Promise<ConnectedMotionGroup> {
|
|
256
|
-
const motionGroups = await this.connectMotionGroups([motionGroupId])
|
|
257
|
-
// biome-ignore lint/style/noNonNullAssertion: legacy code
|
|
258
|
-
return motionGroups[0]!
|
|
259
|
-
}
|
|
260
|
-
}
|