@volant-autonomy/via-sdk 1.0.1
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/LICENSE +21 -0
- package/README.md +67 -0
- package/dist/client.d.ts +7 -0
- package/dist/client.js +21 -0
- package/dist/composite.d.ts +150 -0
- package/dist/composite.js +92 -0
- package/dist/direct.d.ts +967 -0
- package/dist/direct.js +300 -0
- package/dist/docstringTransformer.d.ts +3 -0
- package/dist/docstringTransformer.js +189 -0
- package/dist/fetch.d.ts +123 -0
- package/dist/fetch.js +197 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +22 -0
- package/dist/types.d.ts +54 -0
- package/dist/types.js +19 -0
- package/dist/utils.d.ts +16 -0
- package/dist/utils.js +59 -0
- package/dist/volant-schema.d.ts +4000 -0
- package/dist/volant-schema.js +6 -0
- package/package.json +56 -0
package/dist/fetch.js
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.Fetcher = void 0;
|
|
13
|
+
exports.default = createFetcher;
|
|
14
|
+
const openapi_fetch_1 = require("openapi-fetch");
|
|
15
|
+
const types_1 = require("./types");
|
|
16
|
+
const querySerializer = (0, openapi_fetch_1.createQuerySerializer)();
|
|
17
|
+
class Fetcher {
|
|
18
|
+
constructor(args) {
|
|
19
|
+
var _a, _b, _c, _d;
|
|
20
|
+
this.opts = {
|
|
21
|
+
url: (_a = args.url) !== null && _a !== void 0 ? _a : 'https://via.volantautonomy.com/api/v1.0',
|
|
22
|
+
fetchFn: (_b = args.fetchFn) !== null && _b !== void 0 ? _b : undefined,
|
|
23
|
+
authFetchFn: (_c = args.authFetchFn) !== null && _c !== void 0 ? _c : globalThis.fetch,
|
|
24
|
+
username: args.username,
|
|
25
|
+
password: args.password,
|
|
26
|
+
ignoreAuth: (_d = args.ignoreAuth) !== null && _d !== void 0 ? _d : false
|
|
27
|
+
};
|
|
28
|
+
this.aborts = {};
|
|
29
|
+
this.accessToken = undefined;
|
|
30
|
+
this.expiry = Date.now() - 5;
|
|
31
|
+
}
|
|
32
|
+
doAuth() {
|
|
33
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
34
|
+
// NOTE: THIS REQUEST IS NOT TYPE CHECKED PROPERLY AS paths IS NOT KNOWN HERE!
|
|
35
|
+
if (this.opts.username === undefined || this.opts.password === undefined) {
|
|
36
|
+
throw new types_1.UnauthenticatedError('ignoreAuth is not true and either username or password is missing');
|
|
37
|
+
}
|
|
38
|
+
const resp = yield this.opts.authFetchFn(this.opts.url + '/login', {
|
|
39
|
+
body: JSON.stringify({
|
|
40
|
+
username: this.opts.username,
|
|
41
|
+
password: this.opts.password
|
|
42
|
+
}),
|
|
43
|
+
redirect: 'follow'
|
|
44
|
+
});
|
|
45
|
+
if (resp.ok) {
|
|
46
|
+
const data = (yield resp.json());
|
|
47
|
+
this.expiry = Date.now() + data.expires_in - 10;
|
|
48
|
+
this.accessToken = data.access_token;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
throw new types_1.UnauthenticatedError('Invalid credentials');
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/** Takes in an abort key to determine what abort signals should be fired and a new signal */
|
|
56
|
+
handleAbortKey(abortKey) {
|
|
57
|
+
var _a;
|
|
58
|
+
if (abortKey) {
|
|
59
|
+
(_a = this.aborts[abortKey]) === null || _a === void 0 ? void 0 : _a.abort();
|
|
60
|
+
const abortController = new AbortController();
|
|
61
|
+
this.aborts[abortKey] = abortController;
|
|
62
|
+
return abortController.signal;
|
|
63
|
+
}
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
/** Transforms an error from the api into an {@link SdkErrorModel} */
|
|
67
|
+
parseError(response) {
|
|
68
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
69
|
+
var _a;
|
|
70
|
+
const error = (yield response.json());
|
|
71
|
+
// NOTE: throws away the status codes inside of the individual errors
|
|
72
|
+
if (((_a = error === null || error === void 0 ? void 0 : error.errors) === null || _a === void 0 ? void 0 : _a.length) === 0) {
|
|
73
|
+
return {
|
|
74
|
+
status: String(response.status),
|
|
75
|
+
errors: [
|
|
76
|
+
{
|
|
77
|
+
status: String(response.status),
|
|
78
|
+
detail: ''
|
|
79
|
+
}
|
|
80
|
+
]
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
return {
|
|
85
|
+
status: String(response.status),
|
|
86
|
+
errors: error === null || error === void 0 ? void 0 : error.errors.map((err) => {
|
|
87
|
+
return {
|
|
88
|
+
status: String(err.status),
|
|
89
|
+
detail: err.detail
|
|
90
|
+
};
|
|
91
|
+
})
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
// source: https://github.com/openapi-ts/openapi-typescript/blob/f21c05b9afcc89ee6ef73edab4045620b410eb01/packages/openapi-fetch/src/index.js#L447
|
|
97
|
+
createFinalURL(path, options) {
|
|
98
|
+
var _a;
|
|
99
|
+
let finalURL = `${this.opts.url}${path}`;
|
|
100
|
+
if (options === null || options === void 0 ? void 0 : options.path) {
|
|
101
|
+
finalURL = (0, openapi_fetch_1.defaultPathSerializer)(finalURL, options.path);
|
|
102
|
+
}
|
|
103
|
+
const search = querySerializer((_a = options.query) !== null && _a !== void 0 ? _a : {});
|
|
104
|
+
if (search) {
|
|
105
|
+
finalURL += `?${search}`;
|
|
106
|
+
}
|
|
107
|
+
return finalURL;
|
|
108
|
+
}
|
|
109
|
+
/** The actual fetch wrapper. It is type inference blind, beyond the parseAs type */
|
|
110
|
+
fetcher(method, path, data, opts) {
|
|
111
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
112
|
+
var _a, _b, _c;
|
|
113
|
+
if (!this.opts.ignoreAuth) {
|
|
114
|
+
if (!this.accessToken || this.expiry <= Date.now()) {
|
|
115
|
+
yield this.doAuth();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const fetchFn = (_b = (_a = opts === null || opts === void 0 ? void 0 : opts.fetch) !== null && _a !== void 0 ? _a : this.opts.fetchFn) !== null && _b !== void 0 ? _b : globalThis.fetch;
|
|
119
|
+
const parseAs = (_c = opts === null || opts === void 0 ? void 0 : opts.parseAs) !== null && _c !== void 0 ? _c : 'json';
|
|
120
|
+
const request = new Request(this.createFinalURL(path, { query: data === null || data === void 0 ? void 0 : data.query, path: data === null || data === void 0 ? void 0 : data.path }), {
|
|
121
|
+
redirect: 'follow',
|
|
122
|
+
signal: this.handleAbortKey(opts === null || opts === void 0 ? void 0 : opts.abortKey),
|
|
123
|
+
body: JSON.stringify(data === null || data === void 0 ? void 0 : data.body),
|
|
124
|
+
headers: Object.assign({ 'Content-Type': 'application/json' }, data === null || data === void 0 ? void 0 : data.header),
|
|
125
|
+
method
|
|
126
|
+
});
|
|
127
|
+
if (!this.opts.ignoreAuth) {
|
|
128
|
+
request.headers.set('Authorization', `Bearer ${this.accessToken}`);
|
|
129
|
+
}
|
|
130
|
+
let response;
|
|
131
|
+
try {
|
|
132
|
+
response = yield fetchFn(request);
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
if (err.name === 'AbortError') {
|
|
136
|
+
return { aborted: true };
|
|
137
|
+
}
|
|
138
|
+
throw err;
|
|
139
|
+
}
|
|
140
|
+
if (response.status === 401) {
|
|
141
|
+
throw new types_1.UnauthenticatedError('Unauthenticated');
|
|
142
|
+
}
|
|
143
|
+
// handle empty content
|
|
144
|
+
// note: we return `{}` because we want user truthy checks for `.data` or `.error` to succeed
|
|
145
|
+
// NOTE: this does lie to the user, as we say it is undefined
|
|
146
|
+
if (response.status === 204 || response.headers.get('Content-Length') === '0') {
|
|
147
|
+
return response.ok
|
|
148
|
+
? { data: {}, aborted: false, response }
|
|
149
|
+
: { error: {}, aborted: false, response };
|
|
150
|
+
}
|
|
151
|
+
if (response.ok) {
|
|
152
|
+
// if "stream", skip parsing entirely
|
|
153
|
+
if (parseAs === 'stream') {
|
|
154
|
+
return { data: response.body, aborted: false, response };
|
|
155
|
+
}
|
|
156
|
+
return { data: yield response[parseAs](), aborted: false, response };
|
|
157
|
+
}
|
|
158
|
+
return { error: yield this.parseError(response), aborted: false };
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
GET(path, data, opts) {
|
|
162
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
163
|
+
return this.fetcher('get', path, data, opts);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
PUT(path, data, opts) {
|
|
167
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
168
|
+
return this.fetcher('put', path, data, opts);
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
POST(path, data, opts) {
|
|
172
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
173
|
+
return this.fetcher('post', path, data, opts);
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
DELETE(path, data, opts) {
|
|
177
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
178
|
+
return this.fetcher('delete', path, data, opts);
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
OPTIONS(path, data, opts) {
|
|
182
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
183
|
+
return this.fetcher('options', path, data, opts);
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
HEAD(path, data, opts) {
|
|
187
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
188
|
+
return this.fetcher('post', path, data, opts);
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
exports.Fetcher = Fetcher;
|
|
193
|
+
// indirection is required to get ts to accept the type magic
|
|
194
|
+
//* * `paths` MUST be passed in as a generic type arg or type inference falls apart */
|
|
195
|
+
function createFetcher(...args) {
|
|
196
|
+
return new Fetcher(...args);
|
|
197
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { createSDK } from './client';
|
|
2
|
+
export * from './utils';
|
|
3
|
+
export { SdkErrorModel } from './fetch';
|
|
4
|
+
export { schemas, UnauthenticatedError } from './types';
|
|
5
|
+
export type { paths } from './volant-schema';
|
|
6
|
+
export type { Direct } from './direct';
|
|
7
|
+
export type { Composite } from './composite';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.UnauthenticatedError = exports.createSDK = void 0;
|
|
18
|
+
var client_1 = require("./client");
|
|
19
|
+
Object.defineProperty(exports, "createSDK", { enumerable: true, get: function () { return client_1.createSDK; } });
|
|
20
|
+
__exportStar(require("./utils"), exports);
|
|
21
|
+
var types_1 = require("./types");
|
|
22
|
+
Object.defineProperty(exports, "UnauthenticatedError", { enumerable: true, get: function () { return types_1.UnauthenticatedError; } });
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { components } from './volant-schema';
|
|
2
|
+
export declare const sleep: (ms: number) => Promise<unknown>;
|
|
3
|
+
/**
|
|
4
|
+
* Coerces typescript into more fully evaluating a type to make it more readable
|
|
5
|
+
* @example
|
|
6
|
+
* type X = {
|
|
7
|
+
* a: string | number
|
|
8
|
+
* } & {
|
|
9
|
+
* a: string
|
|
10
|
+
* }
|
|
11
|
+
* Expand<X> == {a: string}
|
|
12
|
+
* // without expand it is not simplified by TS when being shown,
|
|
13
|
+
* // even though it is equivalent to just {a: string}
|
|
14
|
+
*/
|
|
15
|
+
export type Expand<T> = T extends infer O ? {
|
|
16
|
+
[K in keyof O]: O[K];
|
|
17
|
+
} : never;
|
|
18
|
+
/** The raw API schemas from openapi.json */
|
|
19
|
+
export type schemas = components['schemas'];
|
|
20
|
+
export type Waypoint = schemas['StartWaypoint'] | schemas['GotoWaypoint-Input'];
|
|
21
|
+
export type Checkpoint = schemas['GotoPathingCheckpoint'] | schemas['StartPathingCheckpoint'];
|
|
22
|
+
export declare class UnauthenticatedError extends Error {
|
|
23
|
+
name: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Gets the type of the body input for an endpoint
|
|
27
|
+
* @example
|
|
28
|
+
* bodyOf<paths["/login"]["post"]> = {username: string, password: string}
|
|
29
|
+
*/
|
|
30
|
+
export type bodyOf<T> = T extends {
|
|
31
|
+
requestBody: {
|
|
32
|
+
content: {
|
|
33
|
+
'application/json': infer P;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
} ? P : never;
|
|
37
|
+
/** Gets the type of the query input for an endpoint */
|
|
38
|
+
export type queryOf<T> = T extends {
|
|
39
|
+
parameters: {
|
|
40
|
+
query: infer P;
|
|
41
|
+
};
|
|
42
|
+
} ? P : never;
|
|
43
|
+
/** Gets the type of the path input for an endpoint */
|
|
44
|
+
export type pathOf<T> = T extends {
|
|
45
|
+
parameters: {
|
|
46
|
+
path: infer P;
|
|
47
|
+
};
|
|
48
|
+
} ? P : never;
|
|
49
|
+
/** Gets the type of the header input for an endpoint */
|
|
50
|
+
export type headerOf<T> = T extends {
|
|
51
|
+
parameters: {
|
|
52
|
+
header: infer P;
|
|
53
|
+
};
|
|
54
|
+
} ? P : never;
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UnauthenticatedError = exports.sleep = void 0;
|
|
4
|
+
// eslint-disable-next-line promise/param-names
|
|
5
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
6
|
+
exports.sleep = sleep;
|
|
7
|
+
class UnauthenticatedError extends Error {
|
|
8
|
+
constructor() {
|
|
9
|
+
super(...arguments);
|
|
10
|
+
// Both properties are needed to allow for errors to be identified when used in scenarios such
|
|
11
|
+
// as 'PromiseRejectionEvent' such as:
|
|
12
|
+
// `if (errorEvent.reason.name === UnauthenticatedError.name)`
|
|
13
|
+
// In the above, the first is the instance property and the latter a class property
|
|
14
|
+
this.name = 'Unauthenticated';
|
|
15
|
+
// FIXME: this was valid in the via codebase for some reason.
|
|
16
|
+
// public static override name = 'Unauthenticated'
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.UnauthenticatedError = UnauthenticatedError;
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { schemas, Checkpoint, Waypoint } from './types';
|
|
2
|
+
/** Takes in an array of coordinates and flight options, and returns an array of checkpoints for use in the other functions */
|
|
3
|
+
export declare function generateCheckpointsFromCoordinates(args: {
|
|
4
|
+
coordinates: Array<schemas['Wgs84Position']>;
|
|
5
|
+
options: schemas['PathingCheckpointParameters'];
|
|
6
|
+
}): Checkpoint[];
|
|
7
|
+
/** Takes in an array of coordinates and flight options, and returns an array of waypoints for use in the other functions */
|
|
8
|
+
export declare function generateWaypointsFromCoordinates(args: {
|
|
9
|
+
coordinates: Array<schemas['Wgs84Position']>;
|
|
10
|
+
options: {
|
|
11
|
+
flight_parameters: schemas['FlightParameters'];
|
|
12
|
+
wind_parameters?: schemas['WindParameters'];
|
|
13
|
+
};
|
|
14
|
+
}): Waypoint[];
|
|
15
|
+
/** Converts from seconds since epoch to a RFC3339-formatted datetime string */
|
|
16
|
+
export declare function rfcDateTime(secondsEpoch: EpochTimeStamp): string;
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateCheckpointsFromCoordinates = generateCheckpointsFromCoordinates;
|
|
4
|
+
exports.generateWaypointsFromCoordinates = generateWaypointsFromCoordinates;
|
|
5
|
+
exports.rfcDateTime = rfcDateTime;
|
|
6
|
+
/** Takes in an array of coordinates and flight options, and returns an array of checkpoints for use in the other functions */
|
|
7
|
+
function generateCheckpointsFromCoordinates(args) {
|
|
8
|
+
const { coordinates, options } = args;
|
|
9
|
+
if (coordinates.length <= 2) {
|
|
10
|
+
throw Error('Must have at least two coordinates');
|
|
11
|
+
}
|
|
12
|
+
const waypoints = [
|
|
13
|
+
{
|
|
14
|
+
type: 'start',
|
|
15
|
+
position: coordinates[0] // first coord exists because of length check above
|
|
16
|
+
}
|
|
17
|
+
];
|
|
18
|
+
for (const position of coordinates.slice(1)) {
|
|
19
|
+
waypoints.push({
|
|
20
|
+
type: 'goto',
|
|
21
|
+
position,
|
|
22
|
+
parameters: options
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
return waypoints;
|
|
26
|
+
}
|
|
27
|
+
/** Takes in an array of coordinates and flight options, and returns an array of waypoints for use in the other functions */
|
|
28
|
+
function generateWaypointsFromCoordinates(args) {
|
|
29
|
+
const { coordinates, options } = args;
|
|
30
|
+
if (coordinates.length <= 2) {
|
|
31
|
+
throw Error('Must have at least two coordinates');
|
|
32
|
+
}
|
|
33
|
+
const waypoints = [
|
|
34
|
+
{
|
|
35
|
+
type: 'start',
|
|
36
|
+
position: coordinates[0] // first coord exists because of length check above
|
|
37
|
+
}
|
|
38
|
+
];
|
|
39
|
+
for (const position of coordinates.slice(1)) {
|
|
40
|
+
if (options.wind_parameters)
|
|
41
|
+
waypoints.push({
|
|
42
|
+
type: 'goto',
|
|
43
|
+
position,
|
|
44
|
+
flight_parameters: options.flight_parameters,
|
|
45
|
+
wind_parameters: options.wind_parameters
|
|
46
|
+
});
|
|
47
|
+
else
|
|
48
|
+
waypoints.push({
|
|
49
|
+
type: 'goto',
|
|
50
|
+
position,
|
|
51
|
+
flight_parameters: options.flight_parameters
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return waypoints;
|
|
55
|
+
}
|
|
56
|
+
/** Converts from seconds since epoch to a RFC3339-formatted datetime string */
|
|
57
|
+
function rfcDateTime(secondsEpoch) {
|
|
58
|
+
return new Date(secondsEpoch * 1000).toISOString().slice(0, 16) + 'Z';
|
|
59
|
+
}
|