@wandelbots/nova-js 3.2.0 → 3.3.0
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/README.md +32 -136
- package/dist/AutoReconnectingWebsocket-Qcrbm3Kb.d.cts +69 -0
- package/dist/AutoReconnectingWebsocket-Qcrbm3Kb.d.cts.map +1 -0
- package/dist/AutoReconnectingWebsocket-dHe-kceU.d.mts +69 -0
- package/dist/AutoReconnectingWebsocket-dHe-kceU.d.mts.map +1 -0
- package/dist/LoginWithAuth0-CBD9BXXz.cjs +264 -0
- package/dist/LoginWithAuth0-CBD9BXXz.cjs.map +1 -0
- package/dist/LoginWithAuth0-wQB-Sol1.mjs +217 -0
- package/dist/LoginWithAuth0-wQB-Sol1.mjs.map +1 -0
- package/dist/NovaClient-B8XM3OPO.mjs +2057 -0
- package/dist/NovaClient-B8XM3OPO.mjs.map +1 -0
- package/dist/NovaClient-CV7ooIkD.d.cts +349 -0
- package/dist/NovaClient-CV7ooIkD.d.cts.map +1 -0
- package/dist/NovaClient-D2EItmiH.cjs +2137 -0
- package/dist/NovaClient-D2EItmiH.cjs.map +1 -0
- package/dist/NovaClient-qJnHcx2s.d.mts +349 -0
- package/dist/NovaClient-qJnHcx2s.d.mts.map +1 -0
- package/dist/index.cjs +42 -386
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +73 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +73 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +36 -0
- package/dist/index.mjs.map +1 -0
- package/dist/lib/v1/index.cjs +190 -2940
- package/dist/lib/v1/index.cjs.map +1 -1
- package/dist/lib/v1/index.d.cts +62 -0
- package/dist/lib/v1/index.d.cts.map +1 -0
- package/dist/lib/v1/index.d.mts +62 -0
- package/dist/lib/v1/index.d.mts.map +1 -0
- package/dist/lib/v1/index.mjs +182 -0
- package/dist/lib/v1/index.mjs.map +1 -0
- package/dist/lib/v2/index.cjs +1821 -1468
- package/dist/lib/v2/index.cjs.map +1 -1
- package/dist/lib/v2/index.d.cts +118 -0
- package/dist/lib/v2/index.d.cts.map +1 -0
- package/dist/lib/v2/index.d.mts +118 -0
- package/dist/lib/v2/index.d.mts.map +1 -0
- package/dist/lib/v2/index.mjs +1822 -0
- package/dist/lib/v2/index.mjs.map +1 -0
- package/package.json +21 -19
- package/src/LoginWithAuth0.ts +12 -12
- package/src/index.ts +2 -0
- package/src/lib/converters.ts +5 -23
- package/src/lib/v1/MotionStreamConnection.ts +0 -1
- package/src/lib/v1/NovaClient.ts +18 -0
- package/src/lib/v1/index.ts +6 -0
- package/src/lib/v1/mock/MockNovaInstance.ts +0 -1
- package/src/lib/v1/wandelscriptUtils.ts +22 -0
- package/src/lib/v2/NovaClient.ts +14 -7
- package/src/lib/v2/index.ts +1 -0
- package/src/lib/v2/mock/MockNovaInstance.ts +411 -21
- package/src/lib/v2/wandelscriptUtils.ts +27 -0
- package/dist/LoginWithAuth0.d.ts +0 -7
- package/dist/LoginWithAuth0.d.ts.map +0 -1
- package/dist/chunk-B2C22PTK.js +0 -53
- package/dist/chunk-B2C22PTK.js.map +0 -1
- package/dist/chunk-I3PUV6ZD.js +0 -286
- package/dist/chunk-I3PUV6ZD.js.map +0 -1
- package/dist/index.d.ts +0 -6
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -60
- package/dist/index.js.map +0 -1
- package/dist/lib/AutoReconnectingWebsocket.d.ts +0 -43
- package/dist/lib/AutoReconnectingWebsocket.d.ts.map +0 -1
- package/dist/lib/availableStorage.d.ts +0 -15
- package/dist/lib/availableStorage.d.ts.map +0 -1
- package/dist/lib/converters.d.ts +0 -26
- package/dist/lib/converters.d.ts.map +0 -1
- package/dist/lib/errorHandling.d.ts +0 -15
- package/dist/lib/errorHandling.d.ts.map +0 -1
- package/dist/lib/v1/ConnectedMotionGroup.d.ts +0 -77
- package/dist/lib/v1/ConnectedMotionGroup.d.ts.map +0 -1
- package/dist/lib/v1/JoggerConnection.d.ts +0 -94
- package/dist/lib/v1/JoggerConnection.d.ts.map +0 -1
- package/dist/lib/v1/MotionStreamConnection.d.ts +0 -26
- package/dist/lib/v1/MotionStreamConnection.d.ts.map +0 -1
- package/dist/lib/v1/NovaCellAPIClient.d.ts +0 -68
- package/dist/lib/v1/NovaCellAPIClient.d.ts.map +0 -1
- package/dist/lib/v1/NovaClient.d.ts +0 -67
- package/dist/lib/v1/NovaClient.d.ts.map +0 -1
- package/dist/lib/v1/ProgramStateConnection.d.ts +0 -57
- package/dist/lib/v1/ProgramStateConnection.d.ts.map +0 -1
- package/dist/lib/v1/getLatestTrajectories.d.ts +0 -4
- package/dist/lib/v1/getLatestTrajectories.d.ts.map +0 -1
- package/dist/lib/v1/index.d.ts +0 -9
- package/dist/lib/v1/index.d.ts.map +0 -1
- package/dist/lib/v1/index.js +0 -2653
- package/dist/lib/v1/index.js.map +0 -1
- package/dist/lib/v1/mock/MockNovaInstance.d.ts +0 -13
- package/dist/lib/v1/mock/MockNovaInstance.d.ts.map +0 -1
- package/dist/lib/v1/motionStateUpdate.d.ts +0 -4
- package/dist/lib/v1/motionStateUpdate.d.ts.map +0 -1
- package/dist/lib/v2/NovaCellAPIClient.d.ts +0 -62
- package/dist/lib/v2/NovaCellAPIClient.d.ts.map +0 -1
- package/dist/lib/v2/NovaClient.d.ts +0 -60
- package/dist/lib/v2/NovaClient.d.ts.map +0 -1
- package/dist/lib/v2/index.d.ts +0 -4
- package/dist/lib/v2/index.d.ts.map +0 -1
- package/dist/lib/v2/index.js +0 -1196
- package/dist/lib/v2/index.js.map +0 -1
- package/dist/lib/v2/mock/MockNovaInstance.d.ts +0 -13
- package/dist/lib/v2/mock/MockNovaInstance.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -11,51 +11,61 @@ This library provides an idiomatic TypeScript client for working with the Wandel
|
|
|
11
11
|
npm install @wandelbots/nova-js
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
If you develop
|
|
14
|
+
If you develop a React application we also provide a set of [React components](https://github.com/wandelbotsgmbh/wandelbots-js-react-components). It includes a [Robot Jogging Panel](https://wandelbotsgmbh.github.io/wandelbots-js-react-components/?path=/docs/jogging-joggingpanel--docs), a [Robot Visualization](https://wandelbotsgmbh.github.io/wandelbots-js-react-components/?path=/docs/3d-view-robot--docs) and other useful UI widgets.
|
|
15
15
|
|
|
16
16
|
## Table of contents
|
|
17
17
|
|
|
18
18
|
- [Basic usage](#basic-usage)
|
|
19
|
-
- [API Version Support](#api-version-support)
|
|
20
19
|
- [API calls](#api-calls)
|
|
20
|
+
- [API version support](#api-version-support)
|
|
21
21
|
- [Opening websockets](#opening-websockets)
|
|
22
|
-
- [
|
|
23
|
-
- [Execute Wandelscript](#execute-wandelscript)
|
|
24
|
-
- [Jogging](#jogging)
|
|
25
|
-
- [Stopping the jogger](#stopping-the-jogger)
|
|
26
|
-
- [Rotating a joint](#rotating-a-joint)
|
|
27
|
-
- [Moving a TCP](#moving-the-tcp)
|
|
28
|
-
- [Rotating a TCP](#rotating-the-tcp)
|
|
29
|
-
- [Post-jogging cleanup](#post-jogging-cleanup)
|
|
30
|
-
- [Jogging UI Panel](#jogging-ui-panel)
|
|
22
|
+
- [Execute Wandelscript (V1)](#execute-wandelscript-v1)
|
|
31
23
|
|
|
32
24
|
## Basic usage
|
|
33
25
|
|
|
34
26
|
The core of this package is the `NovaClient`, which represents a connection to a configured robot cell on a given Nova instance:
|
|
35
27
|
|
|
36
28
|
```ts
|
|
37
|
-
import
|
|
29
|
+
// Please make sure you import NovaClient from "@wandelbots/nova-js/v2"
|
|
30
|
+
//
|
|
31
|
+
// The NovaClient from "@wandelbots/nova-js" is still API v1,
|
|
32
|
+
// but it will be removed in the future, use "@wandelbots/nova-js/v1" if
|
|
33
|
+
// you need the API v1 client
|
|
34
|
+
import { NovaClient } from "@wandelbots/nova-js/v2"
|
|
38
35
|
|
|
39
36
|
const nova = new NovaClient({
|
|
40
37
|
instanceUrl: "https://example.instance.wandelbots.io",
|
|
41
38
|
cellId: "cell",
|
|
42
|
-
|
|
43
39
|
// Access token is given in the developer portal UI when you create an instance
|
|
44
40
|
accessToken: "...",
|
|
45
41
|
})
|
|
46
42
|
```
|
|
47
43
|
|
|
48
|
-
|
|
44
|
+
### API calls
|
|
45
|
+
|
|
46
|
+
You can make calls to the REST API via `nova.api`, which contains a bunch of namespaced methods for each endpoint generated from the OpenAPI spec and documentation.
|
|
47
|
+
|
|
48
|
+
For example, to list the controllers configured in your cell:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
const controllerIds = await nova.api.controller.listRobotControllers()
|
|
52
|
+
// -> e.g. ["ur5e", ...]
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Documentation for the various API endpoints is available on your Nova instance at `/api/v2/ui` or on [portal.wandelbots.io](https://portal.wandelbots.io/docs/api/v2/ui/)
|
|
49
56
|
|
|
50
|
-
This library primarily supports **Nova API v1**, which provides full functionality including motion group connections, jogging, program execution, and all the features documented below.
|
|
51
57
|
|
|
52
|
-
|
|
58
|
+
## API version support
|
|
53
59
|
|
|
54
|
-
|
|
60
|
+
This library supports **Nova API v1** and **v2**. Please note that except for Wandelscript execution, usage of **API v1** is deprecated and not recommended.
|
|
61
|
+
|
|
62
|
+
V1 usage:
|
|
55
63
|
|
|
56
64
|
```ts
|
|
57
|
-
//
|
|
58
|
-
|
|
65
|
+
// The NovaClient from "@wandelbots/nova-js" is still API v1,
|
|
66
|
+
// but it will be removed in the future, use "@wandelbots/nova-js/v1" if
|
|
67
|
+
// you need the API v1 client
|
|
68
|
+
import { NovaClient } from "@wandelbots/nova-js/v1"
|
|
59
69
|
|
|
60
70
|
const nova = new NovaClient({
|
|
61
71
|
instanceUrl: "https://example.instance.wandelbots.io",
|
|
@@ -63,24 +73,11 @@ const nova = new NovaClient({
|
|
|
63
73
|
accessToken: "...",
|
|
64
74
|
})
|
|
65
75
|
|
|
66
|
-
//
|
|
67
|
-
const { controllers } = await nova.api.controller.listRobotControllers()
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
We recommend using **v1** for production applications until v2 support is fully implemented.
|
|
71
|
-
|
|
72
|
-
## API calls
|
|
73
|
-
|
|
74
|
-
You can make calls to the REST API via `nova.api`, which contains a bunch of namespaced methods for each endpoint generated from the OpenAPI spec and documentation.
|
|
75
|
-
|
|
76
|
-
For example, to list the controllers configured in your cell:
|
|
77
|
-
|
|
78
|
-
```ts
|
|
76
|
+
// Deprecated API version is still callable
|
|
79
77
|
const { instances } = await nova.api.controller.listControllers()
|
|
80
|
-
// -> e.g. [{ controller: "ur5e", model_name: "UniversalRobots::Controller", ... }, ...]
|
|
81
78
|
```
|
|
82
79
|
|
|
83
|
-
|
|
80
|
+
*Please note*: When using the v1 client, please make sure to add `"three"` to your package.json, since it will be moved to peer dependency in *v4.0* of this library.
|
|
84
81
|
|
|
85
82
|
## Opening websockets
|
|
86
83
|
|
|
@@ -102,24 +99,7 @@ programStateSocket.dispose()
|
|
|
102
99
|
|
|
103
100
|
The reconnecting websocket interface is fairly low-level and you won't get type safety on the messages. So when available, you'll likely want to use one of the following endpoint-specific abstractions instead which are built on top!
|
|
104
101
|
|
|
105
|
-
##
|
|
106
|
-
|
|
107
|
-
The library provides an easy to use way to access properties of a motion group.
|
|
108
|
-
|
|
109
|
-
```ts
|
|
110
|
-
activeRobot = await this.nova.connectMotionGroup(`some-motion-group-id`)
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
This connected motion group opens a websocket and listens to changes of the current joints and the TCP pose. You can read out those values by using the `rapidlyChangingMotionState` of the object. Along other properties it also provides the current `safetySetup` and `tcps`.
|
|
114
|
-
|
|
115
|
-
```ts
|
|
116
|
-
const newJoints =
|
|
117
|
-
activeRobot.rapidlyChangingMotionState.state.joint_position.joints
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
To render a visual representation, you can use the `robot` component of the [react components](https://wandelbotsgmbh.github.io/wandelbots-js-react-components/?path=/docs/3d-view-robot--docs).
|
|
121
|
-
|
|
122
|
-
## Execute Wandelscript
|
|
102
|
+
## Execute Wandelscript (V1)
|
|
123
103
|
|
|
124
104
|
The `ProgramStateConnection` provides an object which allows to execute and stop a given Wandelscript.
|
|
125
105
|
|
|
@@ -131,90 +111,6 @@ programRunner.executeProgram(script)
|
|
|
131
111
|
|
|
132
112
|
You can `stop` the current execution or listen to state updates of your wandelscript code by observing the `programRunner.executionState`.
|
|
133
113
|
|
|
134
|
-
## Jogging
|
|
135
|
-
|
|
136
|
-
Jogging in a robotics context generally refers to the manual movement of the robot via direct human input. The Wandelbots platform provides websocket-based jogging methods which can be used to build similar jogging interfaces to those found on teach pendants.
|
|
137
|
-
|
|
138
|
-
```ts
|
|
139
|
-
const jogger = await nova.connectJogger(`some-motion-group-id`)
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
The jogger has two mutually exclusive modes. You must set the appropriate jogging mode before starting a jogging motion; this ensures that the motion is ready to start immediately when called with minimal delay.
|
|
143
|
-
|
|
144
|
-
```ts
|
|
145
|
-
// Set the jogger to "joint" mode, enabling continuous joint rotations.
|
|
146
|
-
await jogger.setJoggingMode("joint")
|
|
147
|
-
|
|
148
|
-
// Set the jogger to "tcp" mode, enabling continuous translation
|
|
149
|
-
// and rotation movements of the tool center point.
|
|
150
|
-
await jogger.setJoggingMode("tcp", {
|
|
151
|
-
tcpId: "flange",
|
|
152
|
-
coordSystemId: "world",
|
|
153
|
-
})
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
### Stopping the jogger
|
|
157
|
-
|
|
158
|
-
For safety purposes, let's first consider how to stop the jogger. Calling stop will stop all motion types regardless of mode:
|
|
159
|
-
|
|
160
|
-
```ts
|
|
161
|
-
await jogger.stop()
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
As a failsafe, the server will also stop any jogging motions when it detects the relevant websocket has been closed. This means that if e.g. the network connection drops out or the browser tab is closed in the middle of a motion, it will stop automatically.
|
|
165
|
-
|
|
166
|
-
However, you should never totally rely on any software being able to stop the robot: always have the hardware emergency stop button within reach just in case!
|
|
167
|
-
|
|
168
|
-
### Rotating a joint
|
|
169
|
-
|
|
170
|
-
Requires `joint` mode. This example starts joint 0 of the robot rotating in a positive direction at 1 radian per second:
|
|
171
|
-
|
|
172
|
-
```ts
|
|
173
|
-
await jogger.startJointRotation({
|
|
174
|
-
joint: 0,
|
|
175
|
-
direction: "+",
|
|
176
|
-
velocityRadsPerSec: 1,
|
|
177
|
-
})
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
### Moving a TCP
|
|
181
|
-
|
|
182
|
-
Requires `tcp` mode. This example starts moving a TCP in a positive direction along the X axis of the specified coordinate system, at a velocity of 10 millimeters per second:
|
|
183
|
-
|
|
184
|
-
```ts
|
|
185
|
-
await jogger.startTCPTranslation({
|
|
186
|
-
axis: "x",
|
|
187
|
-
direction: "+",
|
|
188
|
-
velocityMmPerSec: 10,
|
|
189
|
-
})
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
### Rotating a TCP
|
|
193
|
-
|
|
194
|
-
Requires `tcp` mode. This example starts rotating the TCP in a positive direction around the X axis of the specified coordinate system, at a velocity of 1 radians per second:
|
|
195
|
-
|
|
196
|
-
```ts
|
|
197
|
-
await jogger.startTCPRotation({
|
|
198
|
-
axis: "x",
|
|
199
|
-
direction: "+",
|
|
200
|
-
velocityRadsPerSec: 1,
|
|
201
|
-
})
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
### Post-jogging cleanup
|
|
205
|
-
|
|
206
|
-
When you are done with a jogger, make sure to call dispose:
|
|
207
|
-
|
|
208
|
-
```ts
|
|
209
|
-
await jogger.dispose()
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
This will close any open websockets and ensure things are left in a good state.
|
|
213
|
-
|
|
214
|
-
### Jogging UI Panel
|
|
215
|
-
|
|
216
|
-
You can use the [Jogging Panel](https://wandelbotsgmbh.github.io/wandelbots-js-react-components/?path=/docs/jogging-joggingpanel--docs) from the [react components](https://github.com/wandelbotsgmbh/wandelbots-js-react-components) library to get a easy to use visualization component.
|
|
217
|
-
|
|
218
114
|
## Contributing
|
|
219
115
|
|
|
220
116
|
If you would like to contribute a change to this repository, see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import ReconnectingWebSocket from "reconnecting-websocket";
|
|
2
|
+
import { AxiosResponse, InternalAxiosRequestConfig } from "axios";
|
|
3
|
+
|
|
4
|
+
//#region src/lib/v1/mock/MockNovaInstance.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Ultra-simplified mock Nova server for testing stuff
|
|
8
|
+
*/
|
|
9
|
+
declare class MockNovaInstance$1 {
|
|
10
|
+
readonly connections: AutoReconnectingWebsocket[];
|
|
11
|
+
handleAPIRequest(config: InternalAxiosRequestConfig): Promise<AxiosResponse>;
|
|
12
|
+
handleWebsocketConnection(socket: AutoReconnectingWebsocket): void;
|
|
13
|
+
handleWebsocketMessage(socket: AutoReconnectingWebsocket, message: string): void;
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/lib/v2/mock/MockNovaInstance.d.ts
|
|
17
|
+
/**
|
|
18
|
+
* Ultra-simplified mock Nova server for testing stuff
|
|
19
|
+
*/
|
|
20
|
+
declare class MockNovaInstance {
|
|
21
|
+
readonly connections: AutoReconnectingWebsocket[];
|
|
22
|
+
handleAPIRequest(config: InternalAxiosRequestConfig): Promise<AxiosResponse>;
|
|
23
|
+
handleWebsocketConnection(socket: AutoReconnectingWebsocket): void;
|
|
24
|
+
handleWebsocketMessage(socket: AutoReconnectingWebsocket, message: string): void;
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region src/lib/AutoReconnectingWebsocket.d.ts
|
|
28
|
+
declare class AutoReconnectingWebsocket extends ReconnectingWebSocket {
|
|
29
|
+
readonly opts: {
|
|
30
|
+
mock?: MockNovaInstance$1 | MockNovaInstance;
|
|
31
|
+
onDispose?: () => void;
|
|
32
|
+
};
|
|
33
|
+
receivedFirstMessage?: MessageEvent;
|
|
34
|
+
targetUrl: string;
|
|
35
|
+
disposed: boolean;
|
|
36
|
+
constructor(targetUrl: string, opts?: {
|
|
37
|
+
mock?: MockNovaInstance$1 | MockNovaInstance;
|
|
38
|
+
onDispose?: () => void;
|
|
39
|
+
});
|
|
40
|
+
changeUrl(targetUrl: string): void;
|
|
41
|
+
sendJson(data: unknown): void;
|
|
42
|
+
/**
|
|
43
|
+
* Permanently close this websocket and indicate that
|
|
44
|
+
* this object should not be used again.
|
|
45
|
+
**/
|
|
46
|
+
dispose(): void;
|
|
47
|
+
/**
|
|
48
|
+
* Returns a promise that resolves once the websocket
|
|
49
|
+
* is in the OPEN state. */
|
|
50
|
+
opened(): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Returns a promise that resolves once the websocket
|
|
53
|
+
* is in the CLOSED state. */
|
|
54
|
+
closed(): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Returns a promise that resolves when the first message
|
|
57
|
+
* is received from the websocket. Resolves immediately if
|
|
58
|
+
* the first message has already been received.
|
|
59
|
+
*/
|
|
60
|
+
firstMessage(): Promise<MessageEvent<any>>;
|
|
61
|
+
/**
|
|
62
|
+
* Returns a promise that resolves when the next message
|
|
63
|
+
* is received from the websocket.
|
|
64
|
+
*/
|
|
65
|
+
nextMessage(): Promise<MessageEvent<any>>;
|
|
66
|
+
}
|
|
67
|
+
//#endregion
|
|
68
|
+
export { MockNovaInstance as n, MockNovaInstance$1 as r, AutoReconnectingWebsocket as t };
|
|
69
|
+
//# sourceMappingURL=AutoReconnectingWebsocket-Qcrbm3Kb.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AutoReconnectingWebsocket-Qcrbm3Kb.d.cts","names":[],"sources":["../src/lib/v1/mock/MockNovaInstance.ts","../src/lib/v2/mock/MockNovaInstance.ts","../src/lib/AutoReconnectingWebsocket.ts"],"sourcesContent":[],"mappings":";;;;;;;AAeA;AACwB,cADX,kBAAA,CACW;EAGZ,SAAA,WAAA,EAHY,yBAGZ,EAAA;EACC,gBAAA,CAAA,MAAA,EADD,0BACC,CAAA,EAAR,OAAQ,CAAA,aAAA,CAAA;EAAR,yBAAA,CAAA,MAAA,EAg8B+B,yBAh8B/B,CAAA,EAAA,IAAA;EAg8B+B,sBAAA,CAAA,MAAA,EAkOH,yBAlOG,EAAA,OAAA,EAAA,MAAA,CAAA,EAAA,IAAA;;;;;;AAr8BpC;AACwB,cCPX,gBAAA,CDOW;EAGZ,SAAA,WAAA,ECTY,yBDSZ,EAAA;EACC,gBAAA,CAAA,MAAA,ECPD,0BDOC,CAAA,ECNR,ODMQ,CCNA,aDMA,CAAA;EAAR,yBAAA,CAAA,MAAA,EC4iC+B,yBD5iC/B,CAAA,EAAA,IAAA;EAg8B+B,sBAAA,CAAA,MAAA,ECwUH,yBDxUG,EAAA,OAAA,EAAA,MAAA,CAAA,EAAA,IAAA;;;;cEh9BvB,yBAAA,SAAkC,qBAAA;EFWlC,SAAA,IAAA,EAAA;IACW,IAAA,CAAA,EEJX,kBFIW,GEJW,gBFIX;IAGZ,SAAA,CAAA,EAAA,GAAA,GAAA,IAAA;EACC,CAAA;EAAR,oBAAA,CAAA,EEfoB,YFepB;EAg8B+B,SAAA,EAAA,MAAA;EAkOH,QAAA,EAAA,OAAA;EAAyB,WAAA,CAAA,SAAA,EAAA,MAAA,EAAA,KAAA,EAAA;WE1qC7C,qBAAsB;;;EDHtB,SAAA,CAAA,SAAgB,EAAA,MAAA,CAAA,EAAA,IAAA;EACL,QAAA,CAAA,IAAA,EAAA,OAAA,CAAA,EAAA,IAAA;EAGZ;;;;EA+wCqB,OAAA,CAAA,CAAA,EAAA,IAAA;EAAyB;;;YCtsC5C;EAlFD;;;EACY,MAAA,CAAA,CAAA,EA+FX,OA/FW,CAAA,IAAA,CAAA;EAOZ;;;;;EAwGO,YAAA,CAAA,CAAA,EAAA,OAAA,CAAA,YAAA,CAAA,GAAA,CAAA,CAAA;EA4BD;;;;iBAAA,QAAA"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import ReconnectingWebSocket from "reconnecting-websocket";
|
|
2
|
+
import { AxiosResponse, InternalAxiosRequestConfig } from "axios";
|
|
3
|
+
|
|
4
|
+
//#region src/lib/v1/mock/MockNovaInstance.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Ultra-simplified mock Nova server for testing stuff
|
|
8
|
+
*/
|
|
9
|
+
declare class MockNovaInstance$1 {
|
|
10
|
+
readonly connections: AutoReconnectingWebsocket[];
|
|
11
|
+
handleAPIRequest(config: InternalAxiosRequestConfig): Promise<AxiosResponse>;
|
|
12
|
+
handleWebsocketConnection(socket: AutoReconnectingWebsocket): void;
|
|
13
|
+
handleWebsocketMessage(socket: AutoReconnectingWebsocket, message: string): void;
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/lib/v2/mock/MockNovaInstance.d.ts
|
|
17
|
+
/**
|
|
18
|
+
* Ultra-simplified mock Nova server for testing stuff
|
|
19
|
+
*/
|
|
20
|
+
declare class MockNovaInstance {
|
|
21
|
+
readonly connections: AutoReconnectingWebsocket[];
|
|
22
|
+
handleAPIRequest(config: InternalAxiosRequestConfig): Promise<AxiosResponse>;
|
|
23
|
+
handleWebsocketConnection(socket: AutoReconnectingWebsocket): void;
|
|
24
|
+
handleWebsocketMessage(socket: AutoReconnectingWebsocket, message: string): void;
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region src/lib/AutoReconnectingWebsocket.d.ts
|
|
28
|
+
declare class AutoReconnectingWebsocket extends ReconnectingWebSocket {
|
|
29
|
+
readonly opts: {
|
|
30
|
+
mock?: MockNovaInstance$1 | MockNovaInstance;
|
|
31
|
+
onDispose?: () => void;
|
|
32
|
+
};
|
|
33
|
+
receivedFirstMessage?: MessageEvent;
|
|
34
|
+
targetUrl: string;
|
|
35
|
+
disposed: boolean;
|
|
36
|
+
constructor(targetUrl: string, opts?: {
|
|
37
|
+
mock?: MockNovaInstance$1 | MockNovaInstance;
|
|
38
|
+
onDispose?: () => void;
|
|
39
|
+
});
|
|
40
|
+
changeUrl(targetUrl: string): void;
|
|
41
|
+
sendJson(data: unknown): void;
|
|
42
|
+
/**
|
|
43
|
+
* Permanently close this websocket and indicate that
|
|
44
|
+
* this object should not be used again.
|
|
45
|
+
**/
|
|
46
|
+
dispose(): void;
|
|
47
|
+
/**
|
|
48
|
+
* Returns a promise that resolves once the websocket
|
|
49
|
+
* is in the OPEN state. */
|
|
50
|
+
opened(): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Returns a promise that resolves once the websocket
|
|
53
|
+
* is in the CLOSED state. */
|
|
54
|
+
closed(): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Returns a promise that resolves when the first message
|
|
57
|
+
* is received from the websocket. Resolves immediately if
|
|
58
|
+
* the first message has already been received.
|
|
59
|
+
*/
|
|
60
|
+
firstMessage(): Promise<MessageEvent<any>>;
|
|
61
|
+
/**
|
|
62
|
+
* Returns a promise that resolves when the next message
|
|
63
|
+
* is received from the websocket.
|
|
64
|
+
*/
|
|
65
|
+
nextMessage(): Promise<MessageEvent<any>>;
|
|
66
|
+
}
|
|
67
|
+
//#endregion
|
|
68
|
+
export { MockNovaInstance as n, MockNovaInstance$1 as r, AutoReconnectingWebsocket as t };
|
|
69
|
+
//# sourceMappingURL=AutoReconnectingWebsocket-dHe-kceU.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AutoReconnectingWebsocket-dHe-kceU.d.mts","names":[],"sources":["../src/lib/v1/mock/MockNovaInstance.ts","../src/lib/v2/mock/MockNovaInstance.ts","../src/lib/AutoReconnectingWebsocket.ts"],"sourcesContent":[],"mappings":";;;;;;;AAeA;AACwB,cADX,kBAAA,CACW;EAGZ,SAAA,WAAA,EAHY,yBAGZ,EAAA;EACC,gBAAA,CAAA,MAAA,EADD,0BACC,CAAA,EAAR,OAAQ,CAAA,aAAA,CAAA;EAAR,yBAAA,CAAA,MAAA,EAg8B+B,yBAh8B/B,CAAA,EAAA,IAAA;EAg8B+B,sBAAA,CAAA,MAAA,EAkOH,yBAlOG,EAAA,OAAA,EAAA,MAAA,CAAA,EAAA,IAAA;;;;;;AAr8BpC;AACwB,cCPX,gBAAA,CDOW;EAGZ,SAAA,WAAA,ECTY,yBDSZ,EAAA;EACC,gBAAA,CAAA,MAAA,ECPD,0BDOC,CAAA,ECNR,ODMQ,CCNA,aDMA,CAAA;EAAR,yBAAA,CAAA,MAAA,EC4iC+B,yBD5iC/B,CAAA,EAAA,IAAA;EAg8B+B,sBAAA,CAAA,MAAA,ECwUH,yBDxUG,EAAA,OAAA,EAAA,MAAA,CAAA,EAAA,IAAA;;;;cEh9BvB,yBAAA,SAAkC,qBAAA;EFWlC,SAAA,IAAA,EAAA;IACW,IAAA,CAAA,EEJX,kBFIW,GEJW,gBFIX;IAGZ,SAAA,CAAA,EAAA,GAAA,GAAA,IAAA;EACC,CAAA;EAAR,oBAAA,CAAA,EEfoB,YFepB;EAg8B+B,SAAA,EAAA,MAAA;EAkOH,QAAA,EAAA,OAAA;EAAyB,WAAA,CAAA,SAAA,EAAA,MAAA,EAAA,KAAA,EAAA;WE1qC7C,qBAAsB;;;EDHtB,SAAA,CAAA,SAAgB,EAAA,MAAA,CAAA,EAAA,IAAA;EACL,QAAA,CAAA,IAAA,EAAA,OAAA,CAAA,EAAA,IAAA;EAGZ;;;;EA+wCqB,OAAA,CAAA,CAAA,EAAA,IAAA;EAAyB;;;YCtsC5C;EAlFD;;;EACY,MAAA,CAAA,CAAA,EA+FX,OA/FW,CAAA,IAAA,CAAA;EAOZ;;;;;EAwGO,YAAA,CAAA,CAAA,EAAA,OAAA,CAAA,YAAA,CAAA,GAAA,CAAA,CAAA;EA4BD;;;;iBAAA,QAAA"}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
//#region rolldown:runtime
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
10
|
+
key = keys[i];
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
+
get: ((k) => from[k]).bind(null, key),
|
|
13
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
+
value: mod,
|
|
20
|
+
enumerable: true
|
|
21
|
+
}) : target, mod));
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
let reconnecting_websocket = require("reconnecting-websocket");
|
|
25
|
+
reconnecting_websocket = __toESM(reconnecting_websocket);
|
|
26
|
+
|
|
27
|
+
//#region src/lib/AutoReconnectingWebsocket.ts
|
|
28
|
+
var AutoReconnectingWebsocket = class extends reconnecting_websocket.default {
|
|
29
|
+
constructor(targetUrl, opts = {}) {
|
|
30
|
+
console.log("Opening websocket to", targetUrl);
|
|
31
|
+
super(() => this.targetUrl || targetUrl, void 0, { startClosed: true });
|
|
32
|
+
this.opts = opts;
|
|
33
|
+
this.disposed = false;
|
|
34
|
+
Object.defineProperty(this, "url", { get() {
|
|
35
|
+
return this.targetUrl;
|
|
36
|
+
} });
|
|
37
|
+
this.targetUrl = targetUrl;
|
|
38
|
+
this.addEventListener("open", () => {
|
|
39
|
+
console.log(`Websocket to ${this.url} opened`);
|
|
40
|
+
});
|
|
41
|
+
this.addEventListener("message", (ev) => {
|
|
42
|
+
if (!this.receivedFirstMessage) this.receivedFirstMessage = ev;
|
|
43
|
+
});
|
|
44
|
+
this.addEventListener("close", () => {
|
|
45
|
+
console.log(`Websocket to ${this.url} closed`);
|
|
46
|
+
});
|
|
47
|
+
const origReconnect = this.reconnect;
|
|
48
|
+
this.reconnect = () => {
|
|
49
|
+
if (this.opts.mock) this.opts.mock.handleWebsocketConnection(this);
|
|
50
|
+
else origReconnect.apply(this);
|
|
51
|
+
};
|
|
52
|
+
this.reconnect();
|
|
53
|
+
}
|
|
54
|
+
changeUrl(targetUrl) {
|
|
55
|
+
this.receivedFirstMessage = void 0;
|
|
56
|
+
this.targetUrl = targetUrl;
|
|
57
|
+
this.reconnect();
|
|
58
|
+
}
|
|
59
|
+
sendJson(data) {
|
|
60
|
+
if (this.opts.mock) this.opts.mock.handleWebsocketMessage(this, JSON.stringify(data));
|
|
61
|
+
else this.send(JSON.stringify(data));
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Permanently close this websocket and indicate that
|
|
65
|
+
* this object should not be used again.
|
|
66
|
+
**/
|
|
67
|
+
dispose() {
|
|
68
|
+
this.close();
|
|
69
|
+
this.disposed = true;
|
|
70
|
+
if (this.opts.onDispose) this.opts.onDispose();
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Returns a promise that resolves once the websocket
|
|
74
|
+
* is in the OPEN state. */
|
|
75
|
+
async opened() {
|
|
76
|
+
return new Promise((resolve, reject) => {
|
|
77
|
+
if (this.readyState === WebSocket.OPEN) resolve();
|
|
78
|
+
else {
|
|
79
|
+
this.addEventListener("open", () => resolve());
|
|
80
|
+
this.addEventListener("error", reject);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Returns a promise that resolves once the websocket
|
|
86
|
+
* is in the CLOSED state. */
|
|
87
|
+
async closed() {
|
|
88
|
+
return new Promise((resolve, reject) => {
|
|
89
|
+
if (this.readyState === WebSocket.CLOSED) resolve();
|
|
90
|
+
else {
|
|
91
|
+
this.addEventListener("close", () => resolve());
|
|
92
|
+
this.addEventListener("error", reject);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Returns a promise that resolves when the first message
|
|
98
|
+
* is received from the websocket. Resolves immediately if
|
|
99
|
+
* the first message has already been received.
|
|
100
|
+
*/
|
|
101
|
+
async firstMessage() {
|
|
102
|
+
if (this.receivedFirstMessage) return this.receivedFirstMessage;
|
|
103
|
+
return new Promise((resolve, reject) => {
|
|
104
|
+
const onMessage = (ev) => {
|
|
105
|
+
this.receivedFirstMessage = ev;
|
|
106
|
+
this.removeEventListener("message", onMessage);
|
|
107
|
+
this.removeEventListener("error", onError);
|
|
108
|
+
resolve(ev);
|
|
109
|
+
};
|
|
110
|
+
const onError = (ev) => {
|
|
111
|
+
this.removeEventListener("message", onMessage);
|
|
112
|
+
this.removeEventListener("error", onError);
|
|
113
|
+
reject(ev);
|
|
114
|
+
};
|
|
115
|
+
this.addEventListener("message", onMessage);
|
|
116
|
+
this.addEventListener("error", onError);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Returns a promise that resolves when the next message
|
|
121
|
+
* is received from the websocket.
|
|
122
|
+
*/
|
|
123
|
+
async nextMessage() {
|
|
124
|
+
return new Promise((resolve, reject) => {
|
|
125
|
+
const onMessage = (ev) => {
|
|
126
|
+
this.removeEventListener("message", onMessage);
|
|
127
|
+
this.removeEventListener("error", onError);
|
|
128
|
+
resolve(ev);
|
|
129
|
+
};
|
|
130
|
+
const onError = (ev) => {
|
|
131
|
+
this.removeEventListener("message", onMessage);
|
|
132
|
+
this.removeEventListener("error", onError);
|
|
133
|
+
reject(ev);
|
|
134
|
+
};
|
|
135
|
+
this.addEventListener("message", onMessage);
|
|
136
|
+
this.addEventListener("error", onError);
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
//#endregion
|
|
142
|
+
//#region src/lib/availableStorage.ts
|
|
143
|
+
/**
|
|
144
|
+
* Safety wrapper around browser localStorage providing context availability
|
|
145
|
+
* checks and JSON parsing
|
|
146
|
+
*/
|
|
147
|
+
var AvailableStorage = class {
|
|
148
|
+
constructor() {
|
|
149
|
+
this.available = typeof window !== "undefined" && !!window.localStorage;
|
|
150
|
+
}
|
|
151
|
+
getJSON(key) {
|
|
152
|
+
if (!this.available) return null;
|
|
153
|
+
const result = window.localStorage.getItem(key);
|
|
154
|
+
if (result === null) return null;
|
|
155
|
+
try {
|
|
156
|
+
return JSON.parse(result);
|
|
157
|
+
} catch (err) {
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
setJSON(key, obj) {
|
|
162
|
+
if (!this.available) return null;
|
|
163
|
+
window.localStorage.setItem(key, JSON.stringify(obj));
|
|
164
|
+
}
|
|
165
|
+
delete(key) {
|
|
166
|
+
if (!this.available) return null;
|
|
167
|
+
window.localStorage.removeItem(key);
|
|
168
|
+
}
|
|
169
|
+
setString(key, value) {
|
|
170
|
+
if (!this.available) return null;
|
|
171
|
+
window.localStorage.setItem(key, value);
|
|
172
|
+
}
|
|
173
|
+
getString(key) {
|
|
174
|
+
if (!this.available) return null;
|
|
175
|
+
return window.localStorage.getItem(key);
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
const availableStorage = new AvailableStorage();
|
|
179
|
+
|
|
180
|
+
//#endregion
|
|
181
|
+
//#region src/LoginWithAuth0.ts
|
|
182
|
+
const DOMAIN_SUFFIX = "wandelbots.io";
|
|
183
|
+
/**
|
|
184
|
+
* Mapping of stages to Auth0 configurations.
|
|
185
|
+
* The client ids are public identifiers for a specific auth0 application
|
|
186
|
+
* and are safe to include in client-side code.
|
|
187
|
+
* https://auth0.com/docs/get-started/applications/application-settings
|
|
188
|
+
*/
|
|
189
|
+
const auth0ConfigMap = {
|
|
190
|
+
dev: {
|
|
191
|
+
domain: `https://auth.portal.dev.${DOMAIN_SUFFIX}`,
|
|
192
|
+
clientId: "fLbJD0RLp5r2Dpucm5j8BjwMR6Hunfha"
|
|
193
|
+
},
|
|
194
|
+
stg: {
|
|
195
|
+
domain: `https://auth.portal.stg.${DOMAIN_SUFFIX}`,
|
|
196
|
+
clientId: "joVDeD9e786WzFNSGCqoVq7HNkWt5j6s"
|
|
197
|
+
},
|
|
198
|
+
prod: {
|
|
199
|
+
domain: `https://auth.portal.${DOMAIN_SUFFIX}`,
|
|
200
|
+
clientId: "J7WJUi38xVQdJAEBNRT9Xw1b0fXDb4J2"
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
/** Determine which Auth0 configuration to use based on instance URL */
|
|
204
|
+
const getAuth0Config = (instanceUrl) => {
|
|
205
|
+
if (instanceUrl.endsWith(`dev.${DOMAIN_SUFFIX}`)) return auth0ConfigMap.dev;
|
|
206
|
+
if (instanceUrl.endsWith(`stg.${DOMAIN_SUFFIX}`)) return auth0ConfigMap.stg;
|
|
207
|
+
if (instanceUrl.endsWith(DOMAIN_SUFFIX)) return auth0ConfigMap.prod;
|
|
208
|
+
throw new Error("Unsupported instance URL. Cannot determine Auth0 configuration.");
|
|
209
|
+
};
|
|
210
|
+
/**
|
|
211
|
+
* Initializes Auth0 login process using redirect if necessary and retrieves an access token.
|
|
212
|
+
* Returns null when an access token should not be needed to authenticate (i.e. cookie auth
|
|
213
|
+
* when deployed on the instance domain)
|
|
214
|
+
*/
|
|
215
|
+
const loginWithAuth0 = async (instanceUrl) => {
|
|
216
|
+
if (typeof window === "undefined") throw new Error(`Access token must be set to use NovaClient when not in a browser environment.`);
|
|
217
|
+
const auth0Config = getAuth0Config(instanceUrl);
|
|
218
|
+
if (new URL(instanceUrl).origin === window.location.origin) {
|
|
219
|
+
window.location.reload();
|
|
220
|
+
throw new Error("Failed to reload page to get auth details, please refresh manually");
|
|
221
|
+
}
|
|
222
|
+
const { Auth0Client } = await import("@auth0/auth0-spa-js");
|
|
223
|
+
const auth0Client = new Auth0Client({
|
|
224
|
+
domain: auth0Config.domain,
|
|
225
|
+
clientId: auth0Config.clientId ?? "",
|
|
226
|
+
useRefreshTokens: false,
|
|
227
|
+
authorizationParams: {
|
|
228
|
+
audience: "nova-api",
|
|
229
|
+
redirect_uri: window.location.origin
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
if (window.location.search.includes("code=") && window.location.search.includes("state=")) {
|
|
233
|
+
const { appState } = await auth0Client.handleRedirectCallback();
|
|
234
|
+
window.history.replaceState({}, document.title, appState?.returnTo || window.location.pathname);
|
|
235
|
+
} else await auth0Client.loginWithRedirect();
|
|
236
|
+
return await auth0Client.getTokenSilently();
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
//#endregion
|
|
240
|
+
Object.defineProperty(exports, 'AutoReconnectingWebsocket', {
|
|
241
|
+
enumerable: true,
|
|
242
|
+
get: function () {
|
|
243
|
+
return AutoReconnectingWebsocket;
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
Object.defineProperty(exports, '__toESM', {
|
|
247
|
+
enumerable: true,
|
|
248
|
+
get: function () {
|
|
249
|
+
return __toESM;
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
Object.defineProperty(exports, 'availableStorage', {
|
|
253
|
+
enumerable: true,
|
|
254
|
+
get: function () {
|
|
255
|
+
return availableStorage;
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
Object.defineProperty(exports, 'loginWithAuth0', {
|
|
259
|
+
enumerable: true,
|
|
260
|
+
get: function () {
|
|
261
|
+
return loginWithAuth0;
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
//# sourceMappingURL=LoginWithAuth0-CBD9BXXz.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LoginWithAuth0-CBD9BXXz.cjs","names":["ReconnectingWebSocket","opts: {\n mock?: v1.MockNovaInstance | v2.MockNovaInstance\n onDispose?: () => void\n }"],"sources":["../src/lib/AutoReconnectingWebsocket.ts","../src/lib/availableStorage.ts","../src/LoginWithAuth0.ts"],"sourcesContent":["import ReconnectingWebSocket, { type ErrorEvent } from \"reconnecting-websocket\"\nimport type * as v1 from \"./v1/mock/MockNovaInstance\"\nimport type * as v2 from \"./v2/mock/MockNovaInstance\"\n\nexport class AutoReconnectingWebsocket extends ReconnectingWebSocket {\n receivedFirstMessage?: MessageEvent\n targetUrl: string\n disposed = false\n\n constructor(\n targetUrl: string,\n readonly opts: {\n mock?: v1.MockNovaInstance | v2.MockNovaInstance\n onDispose?: () => void\n } = {},\n ) {\n console.log(\"Opening websocket to\", targetUrl)\n\n super(() => this.targetUrl || targetUrl, undefined, {\n startClosed: true,\n })\n\n // Reconnecting websocket doesn't set this properly with startClosed\n Object.defineProperty(this, \"url\", {\n get() {\n return this.targetUrl\n },\n })\n\n this.targetUrl = targetUrl\n\n this.addEventListener(\"open\", () => {\n console.log(`Websocket to ${this.url} opened`)\n })\n\n this.addEventListener(\"message\", (ev) => {\n if (!this.receivedFirstMessage) {\n this.receivedFirstMessage = ev\n }\n })\n\n this.addEventListener(\"close\", () => {\n console.log(`Websocket to ${this.url} closed`)\n })\n\n const origReconnect = this.reconnect\n this.reconnect = () => {\n if (this.opts.mock) {\n this.opts.mock.handleWebsocketConnection(this)\n } else {\n origReconnect.apply(this)\n }\n }\n\n this.reconnect()\n }\n\n changeUrl(targetUrl: string) {\n this.receivedFirstMessage = undefined\n this.targetUrl = targetUrl\n this.reconnect()\n }\n\n sendJson(data: unknown) {\n if (this.opts.mock) {\n this.opts.mock.handleWebsocketMessage(this, JSON.stringify(data))\n } else {\n this.send(JSON.stringify(data))\n }\n }\n\n /**\n * Permanently close this websocket and indicate that\n * this object should not be used again.\n **/\n dispose() {\n this.close()\n this.disposed = true\n if (this.opts.onDispose) {\n this.opts.onDispose()\n }\n }\n\n /**\n * Returns a promise that resolves once the websocket\n * is in the OPEN state. */\n async opened() {\n return new Promise<void>((resolve, reject) => {\n if (this.readyState === WebSocket.OPEN) {\n resolve()\n } else {\n this.addEventListener(\"open\", () => resolve())\n this.addEventListener(\"error\", reject)\n }\n })\n }\n\n /**\n * Returns a promise that resolves once the websocket\n * is in the CLOSED state. */\n async closed() {\n return new Promise<void>((resolve, reject) => {\n if (this.readyState === WebSocket.CLOSED) {\n resolve()\n } else {\n this.addEventListener(\"close\", () => resolve())\n this.addEventListener(\"error\", reject)\n }\n })\n }\n\n /**\n * Returns a promise that resolves when the first message\n * is received from the websocket. Resolves immediately if\n * the first message has already been received.\n */\n async firstMessage() {\n if (this.receivedFirstMessage) {\n return this.receivedFirstMessage\n }\n\n return new Promise<MessageEvent>((resolve, reject) => {\n const onMessage = (ev: MessageEvent) => {\n this.receivedFirstMessage = ev\n this.removeEventListener(\"message\", onMessage)\n this.removeEventListener(\"error\", onError)\n resolve(ev)\n }\n\n const onError = (ev: ErrorEvent) => {\n this.removeEventListener(\"message\", onMessage)\n this.removeEventListener(\"error\", onError)\n reject(ev)\n }\n\n this.addEventListener(\"message\", onMessage)\n this.addEventListener(\"error\", onError)\n })\n }\n\n /**\n * Returns a promise that resolves when the next message\n * is received from the websocket.\n */\n async nextMessage() {\n return new Promise<MessageEvent>((resolve, reject) => {\n const onMessage = (ev: MessageEvent) => {\n this.removeEventListener(\"message\", onMessage)\n this.removeEventListener(\"error\", onError)\n resolve(ev)\n }\n\n const onError = (ev: ErrorEvent) => {\n this.removeEventListener(\"message\", onMessage)\n this.removeEventListener(\"error\", onError)\n reject(ev)\n }\n\n this.addEventListener(\"message\", onMessage)\n this.addEventListener(\"error\", onError)\n })\n }\n}\n","/**\n * Safety wrapper around browser localStorage providing context availability\n * checks and JSON parsing\n */\nclass AvailableStorage {\n available = typeof window !== \"undefined\" && !!window.localStorage\n\n getJSON<T>(key: string): Partial<T> | null {\n if (!this.available) return null\n\n const result = window.localStorage.getItem(key)\n if (result === null) return null\n\n try {\n return JSON.parse(result)\n } catch (err) {\n return null\n }\n }\n\n setJSON(key: string, obj: unknown) {\n if (!this.available) return null\n\n window.localStorage.setItem(key, JSON.stringify(obj))\n }\n\n delete(key: string) {\n if (!this.available) return null\n\n window.localStorage.removeItem(key)\n }\n\n setString(key: string, value: string) {\n if (!this.available) return null\n\n window.localStorage.setItem(key, value)\n }\n\n getString(key: string): string | null {\n if (!this.available) return null\n\n return window.localStorage.getItem(key)\n }\n}\n\nexport const availableStorage = new AvailableStorage()\n","const DOMAIN_SUFFIX = \"wandelbots.io\"\n\n/**\n * Mapping of stages to Auth0 configurations.\n * The client ids are public identifiers for a specific auth0 application\n * and are safe to include in client-side code.\n * https://auth0.com/docs/get-started/applications/application-settings\n */\nconst auth0ConfigMap = {\n dev: {\n domain: `https://auth.portal.dev.${DOMAIN_SUFFIX}`,\n clientId: \"fLbJD0RLp5r2Dpucm5j8BjwMR6Hunfha\",\n },\n stg: {\n domain: `https://auth.portal.stg.${DOMAIN_SUFFIX}`,\n clientId: \"joVDeD9e786WzFNSGCqoVq7HNkWt5j6s\",\n },\n prod: {\n domain: `https://auth.portal.${DOMAIN_SUFFIX}`,\n clientId: \"J7WJUi38xVQdJAEBNRT9Xw1b0fXDb4J2\",\n },\n}\n\n/** Determine which Auth0 configuration to use based on instance URL */\nconst getAuth0Config = (instanceUrl: string) => {\n if (instanceUrl.endsWith(`dev.${DOMAIN_SUFFIX}`)) return auth0ConfigMap.dev\n if (instanceUrl.endsWith(`stg.${DOMAIN_SUFFIX}`)) return auth0ConfigMap.stg\n if (instanceUrl.endsWith(DOMAIN_SUFFIX)) return auth0ConfigMap.prod\n throw new Error(\n \"Unsupported instance URL. Cannot determine Auth0 configuration.\",\n )\n}\n\n/**\n * Initializes Auth0 login process using redirect if necessary and retrieves an access token.\n * Returns null when an access token should not be needed to authenticate (i.e. cookie auth\n * when deployed on the instance domain)\n */\nexport const loginWithAuth0 = async (\n instanceUrl: string,\n): Promise<string | null> => {\n if (typeof window === \"undefined\") {\n throw new Error(\n `Access token must be set to use NovaClient when not in a browser environment.`,\n )\n }\n\n const auth0Config = getAuth0Config(instanceUrl)\n\n if (new URL(instanceUrl).origin === window.location.origin) {\n // When deployed on the instance itself, our auth is handled by cookies\n // and no access token is needed-- just need to reload the page and it'll\n // login again / set cookie as needed\n window.location.reload()\n throw new Error(\n \"Failed to reload page to get auth details, please refresh manually\",\n )\n }\n\n // If we're on localhost or another domain, we need to do the full oauth flow\n // Note this will ONLY work for origins which are whitelisted as a redirect_uri\n // in the auth0 config, currently\n const { Auth0Client } = await import(\"@auth0/auth0-spa-js\")\n\n const auth0Client = new Auth0Client({\n domain: auth0Config.domain,\n clientId: auth0Config.clientId ?? \"\",\n useRefreshTokens: false,\n authorizationParams: {\n audience: \"nova-api\",\n redirect_uri: window.location.origin,\n },\n })\n\n // If the URL includes a redirect result, handle it\n if (\n window.location.search.includes(\"code=\") &&\n window.location.search.includes(\"state=\")\n ) {\n const { appState } = await auth0Client.handleRedirectCallback()\n // Return to the URL the user was originally on before the redirect\n window.history.replaceState(\n {},\n document.title,\n appState?.returnTo || window.location.pathname,\n )\n } else {\n // Initiate login with redirect\n await auth0Client.loginWithRedirect()\n }\n\n // Once logged in, retrieve the access token silently\n const accessToken = await auth0Client.getTokenSilently()\n return accessToken\n}\n"],"mappings":"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"}
|