@wandelbots/nova-js 3.9.0-pr.280.2a86180 → 3.9.0-pr.280.2b62f3c
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/lib/v2/index.cjs +28 -45
- package/dist/lib/v2/index.cjs.map +1 -1
- package/dist/lib/v2/index.d.cts +33 -42
- package/dist/lib/v2/index.d.cts.map +1 -1
- package/dist/lib/v2/index.d.mts +33 -42
- package/dist/lib/v2/index.d.mts.map +1 -1
- package/dist/lib/v2/index.mjs +28 -45
- package/dist/lib/v2/index.mjs.map +1 -1
- package/package.json +5 -3
- package/src/lib/v2/Nova.ts +3 -14
- package/src/lib/v2/NovaAPIClient.ts +131 -127
|
@@ -1,43 +1,12 @@
|
|
|
1
|
-
/** biome-ignore-all lint/suspicious/noExplicitAny: legacy code */
|
|
2
|
-
/** biome-ignore-all lint/style/noNonNullAssertion: legacy code */
|
|
3
1
|
import type {
|
|
4
2
|
BaseAPI,
|
|
5
3
|
Configuration as BaseConfiguration,
|
|
6
4
|
} from "@wandelbots/nova-api/v2"
|
|
7
|
-
import
|
|
8
|
-
ApplicationApi,
|
|
9
|
-
BUSInputsOutputsApi,
|
|
10
|
-
CellApi,
|
|
11
|
-
ControllerApi,
|
|
12
|
-
ControllerInputsOutputsApi,
|
|
13
|
-
JoggingApi,
|
|
14
|
-
KinematicsApi,
|
|
15
|
-
LicenseApi,
|
|
16
|
-
MotionGroupApi,
|
|
17
|
-
MotionGroupModelsApi,
|
|
18
|
-
NOVACloudApi,
|
|
19
|
-
ProgramApi,
|
|
20
|
-
RobotConfigurationsApi,
|
|
21
|
-
StoreCollisionComponentsApi,
|
|
22
|
-
StoreCollisionSetupsApi,
|
|
23
|
-
StoreObjectApi,
|
|
24
|
-
SystemApi,
|
|
25
|
-
TrajectoryCachingApi,
|
|
26
|
-
TrajectoryExecutionApi,
|
|
27
|
-
TrajectoryPlanningApi,
|
|
28
|
-
VersionApi,
|
|
29
|
-
VirtualControllerApi,
|
|
30
|
-
VirtualControllerBehaviorApi,
|
|
31
|
-
VirtualControllerInputsOutputsApi,
|
|
32
|
-
} from "@wandelbots/nova-api/v2"
|
|
5
|
+
import * as novaApiV2 from "@wandelbots/nova-api/v2"
|
|
33
6
|
import type { AxiosInstance } from "axios"
|
|
34
7
|
import axios from "axios"
|
|
35
8
|
|
|
36
|
-
type
|
|
37
|
-
? (...args: P) => R
|
|
38
|
-
: never
|
|
39
|
-
|
|
40
|
-
type UnwrapAxiosResponseReturn<T> = T extends (...a: any) => any
|
|
9
|
+
type UnwrapAxiosResponseReturn<T> = T extends (...a: unknown[]) => unknown[]
|
|
41
10
|
? (
|
|
42
11
|
...a: Parameters<T>
|
|
43
12
|
) => Promise<Awaited<ReturnType<T>> extends { data: infer D } ? D : never>
|
|
@@ -48,107 +17,142 @@ type WithUnwrappedAxiosResponse<T> = {
|
|
|
48
17
|
}
|
|
49
18
|
|
|
50
19
|
/**
|
|
51
|
-
*
|
|
52
|
-
*
|
|
20
|
+
* Filters nova-api/v2 exports to just the API class constructors,
|
|
21
|
+
* excluding helper factories and param creators.
|
|
53
22
|
*/
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
ApiConstructor: new (
|
|
65
|
-
config: BaseConfiguration,
|
|
66
|
-
basePath: string,
|
|
67
|
-
axios: AxiosInstance,
|
|
68
|
-
) => T,
|
|
69
|
-
) {
|
|
70
|
-
const apiClient = new ApiConstructor(
|
|
71
|
-
{
|
|
72
|
-
...this.opts,
|
|
73
|
-
isJsonMime: (mime: string) => {
|
|
74
|
-
return mime === "application/json"
|
|
75
|
-
},
|
|
76
|
-
},
|
|
77
|
-
this.opts.basePath ?? "",
|
|
78
|
-
this.opts.axiosInstance ?? axios.create(),
|
|
79
|
-
) as {
|
|
80
|
-
[key: string | symbol]: any
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
for (const key of Reflect.ownKeys(Reflect.getPrototypeOf(apiClient)!)) {
|
|
84
|
-
if (key !== "constructor" && typeof apiClient[key] === "function") {
|
|
85
|
-
const originalFunction = apiClient[key]
|
|
86
|
-
apiClient[key] = (...args: any[]) => {
|
|
87
|
-
return originalFunction
|
|
88
|
-
.apply(apiClient, args)
|
|
89
|
-
.then((res: any) => res.data)
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return apiClient as WithUnwrappedAxiosResponse<T>
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
readonly system = this.withUnwrappedResponsesOnly(SystemApi)
|
|
98
|
-
readonly cell = this.withUnwrappedResponsesOnly(CellApi)
|
|
99
|
-
|
|
100
|
-
readonly motionGroup = this.withUnwrappedResponsesOnly(MotionGroupApi)
|
|
101
|
-
readonly motionGroupModels =
|
|
102
|
-
this.withUnwrappedResponsesOnly(MotionGroupModelsApi)
|
|
103
|
-
|
|
104
|
-
readonly controller = this.withUnwrappedResponsesOnly(ControllerApi)
|
|
105
|
-
|
|
106
|
-
readonly controllerIOs = this.withUnwrappedResponsesOnly(
|
|
107
|
-
ControllerInputsOutputsApi,
|
|
108
|
-
)
|
|
109
|
-
|
|
110
|
-
readonly trajectoryPlanning = this.withUnwrappedResponsesOnly(
|
|
111
|
-
TrajectoryPlanningApi,
|
|
112
|
-
)
|
|
113
|
-
readonly trajectoryExecution = this.withUnwrappedResponsesOnly(
|
|
114
|
-
TrajectoryExecutionApi,
|
|
115
|
-
)
|
|
116
|
-
readonly trajectoryCaching =
|
|
117
|
-
this.withUnwrappedResponsesOnly(TrajectoryCachingApi)
|
|
118
|
-
|
|
119
|
-
readonly application = this.withUnwrappedResponsesOnly(ApplicationApi)
|
|
120
|
-
readonly applicationGlobal = this.withUnwrappedResponsesOnly(ApplicationApi)
|
|
23
|
+
type ApiConstructors = {
|
|
24
|
+
[K in keyof typeof novaApiV2 as K extends `${string}Api`
|
|
25
|
+
? K extends
|
|
26
|
+
| `${string}Factory${string}`
|
|
27
|
+
| `${string}Fp${string}`
|
|
28
|
+
| `${string}ParamCreator${string}`
|
|
29
|
+
? never
|
|
30
|
+
: K
|
|
31
|
+
: never]: (typeof novaApiV2)[K]
|
|
32
|
+
}
|
|
121
33
|
|
|
122
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Lowercases leading uppercase characters to produce a camelCase property name.
|
|
36
|
+
* e.g. "BUSInputsOutputs" -> "busInputsOutputs", "NOVACloud" -> "novaCloud",
|
|
37
|
+
* "Application" -> "application"
|
|
38
|
+
*/
|
|
39
|
+
type CamelCase<S extends string> =
|
|
40
|
+
S extends `${Uppercase<infer A>}${Uppercase<infer B>}${infer Rest}`
|
|
41
|
+
? Rest extends `${Lowercase<string>}${string}`
|
|
42
|
+
? `${Lowercase<A>}${CamelCase<`${Uppercase<B>}${Rest}`>}`
|
|
43
|
+
: `${Lowercase<A>}${CamelCase<`${Uppercase<B>}${Rest}`>}`
|
|
44
|
+
: Uncapitalize<S>
|
|
123
45
|
|
|
124
|
-
|
|
46
|
+
/**
|
|
47
|
+
* Maps API class names to property names by stripping "Api" and converting
|
|
48
|
+
* the leading acronym to lowercase camelCase.
|
|
49
|
+
*
|
|
50
|
+
* Properties are auto-discovered from the upstream package at runtime,
|
|
51
|
+
* so new API sections are available immediately without code changes.
|
|
52
|
+
*/
|
|
53
|
+
type ApiProperties = {
|
|
54
|
+
readonly [K in keyof ApiConstructors as K extends `${infer P}Api`
|
|
55
|
+
? CamelCase<P>
|
|
56
|
+
: never]: ApiConstructors[K] extends new (
|
|
57
|
+
...args: unknown[]
|
|
58
|
+
) => infer I
|
|
59
|
+
? WithUnwrappedAxiosResponse<I>
|
|
60
|
+
: never
|
|
61
|
+
}
|
|
125
62
|
|
|
126
|
-
|
|
127
|
-
|
|
63
|
+
type NovaAPIClientOpts = BaseConfiguration & {
|
|
64
|
+
axiosInstance?: AxiosInstance
|
|
65
|
+
mock?: boolean
|
|
66
|
+
}
|
|
128
67
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
68
|
+
function isApiClass(
|
|
69
|
+
name: string,
|
|
70
|
+
value: unknown,
|
|
71
|
+
): value is new (
|
|
72
|
+
config: BaseConfiguration,
|
|
73
|
+
basePath: string,
|
|
74
|
+
axios: AxiosInstance,
|
|
75
|
+
) => BaseAPI {
|
|
76
|
+
return (
|
|
77
|
+
name.endsWith("Api") &&
|
|
78
|
+
typeof value === "function" &&
|
|
79
|
+
!name.includes("Factory") &&
|
|
80
|
+
!name.includes("Fp") &&
|
|
81
|
+
!name.includes("ParamCreator")
|
|
136
82
|
)
|
|
83
|
+
}
|
|
137
84
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
85
|
+
function wrapApi<T extends BaseAPI>(
|
|
86
|
+
ApiConstructor: new (
|
|
87
|
+
config: BaseConfiguration,
|
|
88
|
+
basePath: string,
|
|
89
|
+
axios: AxiosInstance,
|
|
90
|
+
) => T,
|
|
91
|
+
opts: NovaAPIClientOpts,
|
|
92
|
+
): WithUnwrappedAxiosResponse<T> {
|
|
93
|
+
const apiClient = new ApiConstructor(
|
|
94
|
+
{
|
|
95
|
+
...opts,
|
|
96
|
+
isJsonMime: (mime: string) => mime === "application/json",
|
|
97
|
+
},
|
|
98
|
+
opts.basePath ?? "",
|
|
99
|
+
opts.axiosInstance ?? axios.create(),
|
|
100
|
+
) as Record<string | symbol, unknown>
|
|
101
|
+
|
|
102
|
+
for (const key of Reflect.ownKeys(
|
|
103
|
+
Reflect.getPrototypeOf(apiClient) as object,
|
|
104
|
+
)) {
|
|
105
|
+
if (key !== "constructor" && typeof apiClient[key] === "function") {
|
|
106
|
+
const originalFunction = apiClient[key] as (
|
|
107
|
+
...args: unknown[]
|
|
108
|
+
) => Promise<{ data: unknown }>
|
|
109
|
+
apiClient[key] = (...args: unknown[]) =>
|
|
110
|
+
originalFunction.apply(apiClient, args).then((res) => res.data)
|
|
111
|
+
}
|
|
112
|
+
}
|
|
145
113
|
|
|
146
|
-
|
|
114
|
+
return apiClient as WithUnwrappedAxiosResponse<T>
|
|
115
|
+
}
|
|
147
116
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
117
|
+
/**
|
|
118
|
+
* API client providing type-safe access to all the endpoints of a NOVA
|
|
119
|
+
* instance. API sections are auto-discovered from @wandelbots/nova-api/v2
|
|
120
|
+
* at runtime, so new sections added upstream are exposed automatically.
|
|
121
|
+
*/
|
|
122
|
+
export const NovaAPIClient = class NovaAPIClient {
|
|
123
|
+
readonly opts: NovaAPIClientOpts
|
|
124
|
+
|
|
125
|
+
constructor(opts: NovaAPIClientOpts) {
|
|
126
|
+
this.opts = opts
|
|
127
|
+
|
|
128
|
+
for (const [name, value] of Object.entries(novaApiV2)) {
|
|
129
|
+
if (isApiClass(name, value)) {
|
|
130
|
+
const stripped = name.slice(0, -3)
|
|
131
|
+
// Lowercase leading acronym run: "BUSInputsOutputs" -> "busInputsOutputs"
|
|
132
|
+
let i = 0
|
|
133
|
+
while (
|
|
134
|
+
i < stripped.length &&
|
|
135
|
+
stripped[i] === stripped[i].toUpperCase() &&
|
|
136
|
+
stripped[i] !== stripped[i].toLowerCase()
|
|
137
|
+
) {
|
|
138
|
+
i++
|
|
139
|
+
}
|
|
140
|
+
// If multiple uppercase chars, keep the last one uppercase (it starts the next word)
|
|
141
|
+
const boundary = i > 1 ? i - 1 : i
|
|
142
|
+
const propName =
|
|
143
|
+
stripped.slice(0, boundary).toLowerCase() + stripped.slice(boundary)
|
|
144
|
+
// biome-ignore lint/suspicious/noExplicitAny: dynamically assigning discovered API properties
|
|
145
|
+
;(this as any)[propName] = wrapApi(value, opts)
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
} as {
|
|
150
|
+
new (
|
|
151
|
+
opts: NovaAPIClientOpts,
|
|
152
|
+
): ApiProperties & {
|
|
153
|
+
readonly cellId: string
|
|
154
|
+
readonly opts: NovaAPIClientOpts
|
|
155
|
+
}
|
|
154
156
|
}
|
|
157
|
+
|
|
158
|
+
export type NovaAPIClient = InstanceType<typeof NovaAPIClient>
|