@vulog/aima-vehicle 1.2.29 → 1.2.31
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/index.cjs +252 -0
- package/dist/index.d.cts +273 -0
- package/dist/index.d.mts +211 -218
- package/dist/index.mjs +201 -261
- package/package.json +20 -7
- package/src/createVehicle.test.ts +88 -0
- package/src/createVehicle.ts +49 -0
- package/src/getModelVehicles.test.ts +4 -4
- package/src/index.ts +1 -0
- package/{tsup.config.ts → tsdown.config.ts} +1 -1
- package/dist/index.d.ts +0 -280
- package/dist/index.js +0 -324
- /package/{.eslintrc.js → .eslintrc.cjs} +0 -0
package/dist/index.mjs
CHANGED
|
@@ -1,276 +1,216 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import z$1, { z } from "zod";
|
|
2
|
+
import { createPaginableOptionsSchema } from "@vulog/aima-core";
|
|
3
|
+
//#region src/getModel.ts
|
|
4
|
+
const getModelsById = async (client, id) => {
|
|
5
|
+
return client.get(`boapi/proxy/user/vehicle/fleets/${client.clientOptions.fleetId}/vehicles/models/${id}`).then(({ data }) => data);
|
|
4
6
|
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
const result = schema.safeParse({ id });
|
|
13
|
-
if (!result.success) {
|
|
14
|
-
throw new TypeError("Invalid args", {
|
|
15
|
-
cause: result.error.issues
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
return client.get(`boapi/proxy/eds/rest_pub/rest/fleets/${client.clientOptions.fleetId}/models/${id}/`).then(({ data }) => data);
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region src/getModelAssets.ts
|
|
9
|
+
const schema$5 = z.object({ id: z.number().int().positive() });
|
|
10
|
+
const getModelByIdAssets = async (client, id) => {
|
|
11
|
+
const result = schema$5.safeParse({ id });
|
|
12
|
+
if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues });
|
|
13
|
+
return client.get(`boapi/proxy/eds/rest_pub/rest/fleets/${client.clientOptions.fleetId}/models/${id}/`).then(({ data }) => data);
|
|
19
14
|
};
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/getModels.ts
|
|
17
|
+
const getModels = async (client) => {
|
|
18
|
+
return client.get(`boapi/proxy/user/vehicle/fleets/${client.clientOptions.fleetId}/vehicles/models`).then(({ data }) => data);
|
|
24
19
|
};
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
cause: result.error.issues
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
return client.get(`boapi/proxy/user/vehicle/fleets/${client.clientOptions.fleetId}/vehicles/${result.data.id}`).then(({ data }) => data).catch((error) => {
|
|
39
|
-
if (error.formattedError?.status === 404) {
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
throw error;
|
|
43
|
-
});
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/getVehicle.ts
|
|
22
|
+
const schema$4 = z.object({ id: z.string().trim().min(1).uuid() });
|
|
23
|
+
const getVehicleById = async (client, id) => {
|
|
24
|
+
const result = schema$4.safeParse({ id });
|
|
25
|
+
if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues });
|
|
26
|
+
return client.get(`boapi/proxy/user/vehicle/fleets/${client.clientOptions.fleetId}/vehicles/${result.data.id}`).then(({ data }) => data).catch((error) => {
|
|
27
|
+
if (error.formattedError?.status === 404) return null;
|
|
28
|
+
throw error;
|
|
29
|
+
});
|
|
44
30
|
};
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return client.get(
|
|
53
|
-
`boapi/proxy/fleetmanager/public/fleets/${client.clientOptions.fleetId}/vehicles/${result.data.id}`
|
|
54
|
-
).then(({ data }) => data).catch((error) => {
|
|
55
|
-
if (error.formattedError?.status === 404) {
|
|
56
|
-
return null;
|
|
57
|
-
}
|
|
58
|
-
throw error;
|
|
59
|
-
});
|
|
31
|
+
const getVehicleRealTimeById = async (client, id) => {
|
|
32
|
+
const result = schema$4.safeParse({ id });
|
|
33
|
+
if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues });
|
|
34
|
+
return client.get(`boapi/proxy/fleetmanager/public/fleets/${client.clientOptions.fleetId}/vehicles/${result.data.id}`).then(({ data }) => data).catch((error) => {
|
|
35
|
+
if (error.formattedError?.status === 404) return null;
|
|
36
|
+
throw error;
|
|
37
|
+
});
|
|
60
38
|
};
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
const result = schema3.safeParse({ id });
|
|
69
|
-
if (!result.success) {
|
|
70
|
-
throw new TypeError("Invalid args", {
|
|
71
|
-
cause: result.error.issues
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
return client.get(`boapi/proxy/eds/rest_pub/rest/fleets/${client.clientOptions.fleetId}/vehicles/${id}/`).then(({ data }) => data);
|
|
39
|
+
//#endregion
|
|
40
|
+
//#region src/getVehicleAssets.ts
|
|
41
|
+
const schema$3 = z.object({ id: z.string().uuid() });
|
|
42
|
+
const getVehicleByIdAssets = async (client, id) => {
|
|
43
|
+
const result = schema$3.safeParse({ id });
|
|
44
|
+
if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues });
|
|
45
|
+
return client.get(`boapi/proxy/eds/rest_pub/rest/fleets/${client.clientOptions.fleetId}/vehicles/${id}/`).then(({ data }) => data);
|
|
75
46
|
};
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region src/getVehicles.ts
|
|
49
|
+
/**
|
|
50
|
+
* Fetches a single page of vehicles from the API
|
|
51
|
+
* @param client - The AIMA client instance
|
|
52
|
+
* @param page - The page number to fetch
|
|
53
|
+
* @param pageSize - Number of vehicles per page
|
|
54
|
+
* @returns Promise that resolves to an array of vehicles for the requested page
|
|
55
|
+
*/
|
|
56
|
+
const getVehiclesPage = async (client, page, pageSize) => {
|
|
57
|
+
return (await client.get(`boapi/proxy/user/vehicle/fleets/${client.clientOptions.fleetId}/vehicles?page=${page}&size=${pageSize}`)).data;
|
|
84
58
|
};
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
hasMorePages = vehicles.length === result.data.pageSize;
|
|
108
|
-
currentPage += 1;
|
|
109
|
-
}
|
|
110
|
-
return allVehicles;
|
|
59
|
+
/**
|
|
60
|
+
* Fetches all vehicles from the API using pagination
|
|
61
|
+
* @param client - The AIMA client instance
|
|
62
|
+
* @param pageSize - Number of vehicles per page (default: 500)
|
|
63
|
+
* @returns Promise that resolves to an array of all vehicles
|
|
64
|
+
* @throws Error if more than 50 pages are required to fetch all vehicles
|
|
65
|
+
*/
|
|
66
|
+
const getVehicles = async (client, pageSize = 500) => {
|
|
67
|
+
const result = z.object({ pageSize: z.number().min(1).default(500) }).safeParse({ pageSize });
|
|
68
|
+
if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues });
|
|
69
|
+
const allVehicles = [];
|
|
70
|
+
let currentPage = 0;
|
|
71
|
+
let hasMorePages = true;
|
|
72
|
+
const MAX_PAGES = 50;
|
|
73
|
+
while (hasMorePages) {
|
|
74
|
+
if (currentPage >= MAX_PAGES) throw new Error(`Maximum page limit (${MAX_PAGES}) reached. This might indicate an issue with the pagination or a very large dataset.`);
|
|
75
|
+
const vehicles = await getVehiclesPage(client, currentPage, result.data.pageSize);
|
|
76
|
+
allVehicles.push(...vehicles);
|
|
77
|
+
hasMorePages = vehicles.length === result.data.pageSize;
|
|
78
|
+
currentPage += 1;
|
|
79
|
+
}
|
|
80
|
+
return allVehicles;
|
|
111
81
|
};
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
82
|
+
/**
|
|
83
|
+
* Fetches a single page of real-time vehicle data from the API
|
|
84
|
+
* @param client - The AIMA client instance
|
|
85
|
+
* @param page - The page number to fetch
|
|
86
|
+
* @param pageSize - Number of vehicles per page
|
|
87
|
+
* @param lastUpdatedMillis - Optional timestamp in UTC milliseconds
|
|
88
|
+
* @returns Promise that resolves to an array of real-time vehicle data for the requested page
|
|
89
|
+
*/
|
|
90
|
+
const getVehiclesRealTimePage = async (client, page, pageSize, lastUpdatedMillis) => {
|
|
91
|
+
const queryParams = new URLSearchParams({
|
|
92
|
+
page: page.toString(),
|
|
93
|
+
size: pageSize.toString()
|
|
94
|
+
});
|
|
95
|
+
if (lastUpdatedMillis !== void 0) queryParams.append("lastUpdatedMillis", lastUpdatedMillis.toString());
|
|
96
|
+
return (await client.get(`boapi/proxy/fleetmanager/public/fleets/${client.clientOptions.fleetId}/vehicles?${queryParams.toString()}`)).data;
|
|
124
97
|
};
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
allVehicles.push(...vehicles);
|
|
159
|
-
hasMorePages = vehicles.length === result.data.pageSize;
|
|
160
|
-
currentPage += 1;
|
|
161
|
-
}
|
|
162
|
-
return allVehicles;
|
|
98
|
+
/**
|
|
99
|
+
* Fetches all real-time vehicle data from the API using pagination
|
|
100
|
+
* @param client - The AIMA client instance
|
|
101
|
+
* @param pageSize - Number of vehicles per page (default: 500)
|
|
102
|
+
* @param lastUpdatedMillis - Optional timestamp in UTC milliseconds. If provided, only vehicles updated after this timestamp will be returned.
|
|
103
|
+
* @returns Promise that resolves to an array of all real-time vehicle data
|
|
104
|
+
* @throws Error if more than 50 pages are required to fetch all vehicles
|
|
105
|
+
* @throws Error if lastUpdatedMillis is in the future
|
|
106
|
+
*/
|
|
107
|
+
const getVehiclesRealTime = async (client, pageSize = 500, lastUpdatedMillis) => {
|
|
108
|
+
const result = z.object({
|
|
109
|
+
pageSize: z.number().min(1).default(500),
|
|
110
|
+
lastUpdatedMillis: z.number().positive().optional()
|
|
111
|
+
}).safeParse({
|
|
112
|
+
pageSize,
|
|
113
|
+
lastUpdatedMillis
|
|
114
|
+
});
|
|
115
|
+
if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues });
|
|
116
|
+
const allVehicles = [];
|
|
117
|
+
let currentPage = 0;
|
|
118
|
+
let hasMorePages = true;
|
|
119
|
+
const MAX_PAGES = 50;
|
|
120
|
+
if (lastUpdatedMillis !== void 0) {
|
|
121
|
+
if (lastUpdatedMillis > Date.now()) throw new Error("lastUpdatedMillis must be in the past");
|
|
122
|
+
}
|
|
123
|
+
while (hasMorePages) {
|
|
124
|
+
if (currentPage >= MAX_PAGES) throw new Error(`Maximum page limit (${MAX_PAGES}) reached. This might indicate an issue with the pagination or a very large dataset.`);
|
|
125
|
+
const vehicles = await getVehiclesRealTimePage(client, currentPage, result.data.pageSize, result.data.lastUpdatedMillis);
|
|
126
|
+
allVehicles.push(...vehicles);
|
|
127
|
+
hasMorePages = vehicles.length === result.data.pageSize;
|
|
128
|
+
currentPage += 1;
|
|
129
|
+
}
|
|
130
|
+
return allVehicles;
|
|
163
131
|
};
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
} catch (error) {
|
|
183
|
-
if (error?.response?.data?.codeStr === "carConnectionProblem" && error?.response?.data?.code === 410) {
|
|
184
|
-
return false;
|
|
185
|
-
}
|
|
186
|
-
throw error;
|
|
187
|
-
}
|
|
132
|
+
//#endregion
|
|
133
|
+
//#region src/pingVehicle.ts
|
|
134
|
+
const schema$2 = z.object({ id: z.string().trim().min(1).uuid() });
|
|
135
|
+
/**
|
|
136
|
+
* Pings a vehicle to check if it is alive (box connected).
|
|
137
|
+
* Returns true if alive (HTTP 200), false if box not connected (code 410, codeStr 'carConnectionProblem'),
|
|
138
|
+
* throws for other errors or invalid id.
|
|
139
|
+
*/
|
|
140
|
+
const pingVehicleById = async (client, id) => {
|
|
141
|
+
const result = schema$2.safeParse({ id });
|
|
142
|
+
if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues });
|
|
143
|
+
try {
|
|
144
|
+
await client.get(`boapi/proxy/fleetmanager/public/v2/fleets/${client.clientOptions.fleetId}/vehicles/${result.data.id}/ping`);
|
|
145
|
+
return true;
|
|
146
|
+
} catch (error) {
|
|
147
|
+
if (error?.response?.data?.codeStr === "carConnectionProblem" && error?.response?.data?.code === 410) return false;
|
|
148
|
+
throw error;
|
|
149
|
+
}
|
|
188
150
|
};
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
const result = schema5.safeParse(payload);
|
|
197
|
-
if (!result.success) {
|
|
198
|
-
throw new TypeError("Invalid args", {
|
|
199
|
-
cause: result.error.issues
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
return client.post(
|
|
203
|
-
`boapi/proxy/fleetmanager/public/fleets/${client.clientOptions.fleetId}/vehicles/${vehicleId}/enable`,
|
|
204
|
-
payload
|
|
205
|
-
).then(({ data }) => data);
|
|
151
|
+
//#endregion
|
|
152
|
+
//#region src/enableVehicle.ts
|
|
153
|
+
const schema$1 = z$1.object({ subStatus: z$1.string() });
|
|
154
|
+
const enableVehicle = async (client, vehicleId, payload) => {
|
|
155
|
+
const result = schema$1.safeParse(payload);
|
|
156
|
+
if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues });
|
|
157
|
+
return client.post(`boapi/proxy/fleetmanager/public/fleets/${client.clientOptions.fleetId}/vehicles/${vehicleId}/enable`, payload).then(({ data }) => data);
|
|
206
158
|
};
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
const result = schema6.safeParse(payload);
|
|
215
|
-
if (!result.success) {
|
|
216
|
-
throw new TypeError("Invalid args", {
|
|
217
|
-
cause: result.error.issues
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
return client.post(
|
|
221
|
-
`boapi/proxy/fleetmanager/public/fleets/${client.clientOptions.fleetId}/vehicles/${vehicleId}/disable`,
|
|
222
|
-
payload
|
|
223
|
-
).then(({ data }) => data);
|
|
159
|
+
//#endregion
|
|
160
|
+
//#region src/disableVehicle.ts
|
|
161
|
+
const schema = z$1.object({ subStatus: z$1.string() });
|
|
162
|
+
const disableVehicle = async (client, vehicleId, payload) => {
|
|
163
|
+
const result = schema.safeParse(payload);
|
|
164
|
+
if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues });
|
|
165
|
+
return client.post(`boapi/proxy/fleetmanager/public/fleets/${client.clientOptions.fleetId}/vehicles/${vehicleId}/disable`, payload).then(({ data }) => data);
|
|
224
166
|
};
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
const basePath = `boapi/proxy/user/vehicle/fleets/${client.clientOptions.fleetId}/vehicles/models/modelvehicles`;
|
|
252
|
-
const urlWithParams = `${basePath}?${searchParams.toString()}`;
|
|
253
|
-
return client.get(urlWithParams).then(({ data, headers }) => {
|
|
254
|
-
return {
|
|
255
|
-
data,
|
|
256
|
-
page: headers.number,
|
|
257
|
-
pageSize: headers.size,
|
|
258
|
-
total: headers.totalelements,
|
|
259
|
-
totalPages: headers.totalpages
|
|
260
|
-
};
|
|
261
|
-
});
|
|
167
|
+
//#endregion
|
|
168
|
+
//#region src/getModelVehicles.ts
|
|
169
|
+
const getModelVehicles = async (client, options) => {
|
|
170
|
+
const resultOptions = createPaginableOptionsSchema().default({}).safeParse(options);
|
|
171
|
+
if (!resultOptions.success) throw new TypeError("Invalid options", { cause: resultOptions.error.issues });
|
|
172
|
+
const finalOptions = resultOptions.data;
|
|
173
|
+
const searchParams = new URLSearchParams();
|
|
174
|
+
searchParams.append("page", finalOptions.page.toString());
|
|
175
|
+
searchParams.append("size", finalOptions.pageSize.toString());
|
|
176
|
+
if (finalOptions.sort) searchParams.append("sort", `${finalOptions.sort.toString()},${finalOptions.sortDirection.toString()}`);
|
|
177
|
+
if (finalOptions.filters) Object.entries(finalOptions.filters).forEach(([key, value]) => {
|
|
178
|
+
if (value === void 0) return;
|
|
179
|
+
searchParams.append(key, value);
|
|
180
|
+
});
|
|
181
|
+
const urlWithParams = `${`boapi/proxy/user/vehicle/fleets/${client.clientOptions.fleetId}/vehicles/models/modelvehicles`}?${searchParams.toString()}`;
|
|
182
|
+
return client.get(urlWithParams).then(({ data, headers }) => {
|
|
183
|
+
return {
|
|
184
|
+
data,
|
|
185
|
+
page: headers.number,
|
|
186
|
+
pageSize: headers.size,
|
|
187
|
+
total: headers.totalelements,
|
|
188
|
+
totalPages: headers.totalpages
|
|
189
|
+
};
|
|
190
|
+
});
|
|
262
191
|
};
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
192
|
+
//#endregion
|
|
193
|
+
//#region src/createVehicle.ts
|
|
194
|
+
const createVehicleBodySchema = z.object({
|
|
195
|
+
vin: z.string().trim().min(1).max(20),
|
|
196
|
+
plate: z.string().trim().min(1).max(16),
|
|
197
|
+
name: z.string().trim().min(1).max(64),
|
|
198
|
+
model: z.object({ id: z.number().int().positive() }),
|
|
199
|
+
vuboxId: z.string().optional(),
|
|
200
|
+
externalId: z.string().max(32).optional(),
|
|
201
|
+
wakeupProvider: z.string().max(16).optional(),
|
|
202
|
+
noBox: z.boolean().optional(),
|
|
203
|
+
published: z.boolean().optional(),
|
|
204
|
+
archived: z.boolean().optional(),
|
|
205
|
+
msisdn: z.string().max(32).optional(),
|
|
206
|
+
iccid: z.string().max(32).optional(),
|
|
207
|
+
imsi: z.string().max(32).optional(),
|
|
208
|
+
residualValue: z.number().optional()
|
|
209
|
+
});
|
|
210
|
+
const createVehicle = async (client, body) => {
|
|
211
|
+
const result = createVehicleBodySchema.safeParse(body);
|
|
212
|
+
if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues });
|
|
213
|
+
return client.post(`/boapi/proxy/vehicle/fleets/${client.clientOptions.fleetId}/vehicles`, result.data).then(({ data }) => data);
|
|
276
214
|
};
|
|
215
|
+
//#endregion
|
|
216
|
+
export { createVehicle, disableVehicle, enableVehicle, getModelByIdAssets, getModelVehicles, getModels, getModelsById, getVehicleById, getVehicleByIdAssets, getVehicleRealTimeById, getVehicles, getVehiclesRealTime, pingVehicleById };
|
package/package.json
CHANGED
|
@@ -1,12 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vulog/aima-vehicle",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "1.2.31",
|
|
5
|
+
"main": "dist/index.cjs",
|
|
5
6
|
"module": "dist/index.mjs",
|
|
6
|
-
"types": "dist/index.d.
|
|
7
|
+
"types": "dist/index.d.cts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": {
|
|
11
|
+
"types": "./dist/index.d.mts",
|
|
12
|
+
"default": "./dist/index.mjs"
|
|
13
|
+
},
|
|
14
|
+
"require": {
|
|
15
|
+
"types": "./dist/index.d.cts",
|
|
16
|
+
"default": "./dist/index.cjs"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
7
20
|
"scripts": {
|
|
8
|
-
"build": "
|
|
9
|
-
"dev": "
|
|
21
|
+
"build": "tsdown",
|
|
22
|
+
"dev": "tsdown --watch",
|
|
10
23
|
"test": "vitest run",
|
|
11
24
|
"test:watch": "vitest",
|
|
12
25
|
"lint": "eslint src/**/* --ext .ts"
|
|
@@ -19,8 +32,8 @@
|
|
|
19
32
|
"author": "Vulog",
|
|
20
33
|
"license": "MIT",
|
|
21
34
|
"dependencies": {
|
|
22
|
-
"@vulog/aima-client": "1.2.
|
|
23
|
-
"@vulog/aima-core": "1.2.
|
|
35
|
+
"@vulog/aima-client": "1.2.31",
|
|
36
|
+
"@vulog/aima-core": "1.2.31"
|
|
24
37
|
},
|
|
25
38
|
"peerDependencies": {
|
|
26
39
|
"zod": "^3.25.76"
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { describe, test, vi, expect, beforeEach } from 'vitest';
|
|
2
|
+
import { Client } from '@vulog/aima-client';
|
|
3
|
+
import { createVehicle, CreateVehicleBody } from './createVehicle';
|
|
4
|
+
|
|
5
|
+
describe('createVehicle', () => {
|
|
6
|
+
const postMock = vi.fn();
|
|
7
|
+
const client = {
|
|
8
|
+
post: postMock,
|
|
9
|
+
clientOptions: {
|
|
10
|
+
fleetId: 'FLEET_ID',
|
|
11
|
+
},
|
|
12
|
+
} as unknown as Client;
|
|
13
|
+
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
vi.clearAllMocks();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const validBody: CreateVehicleBody = {
|
|
19
|
+
vin: '1HGBH41JXMN109186',
|
|
20
|
+
plate: 'AB-123-CD',
|
|
21
|
+
name: 'Test Vehicle',
|
|
22
|
+
model: { id: 1 },
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
test('should create a vehicle with required fields only', async () => {
|
|
26
|
+
const mockResponse = { id: 'vehicle-uuid', ...validBody };
|
|
27
|
+
postMock.mockResolvedValueOnce({ data: mockResponse });
|
|
28
|
+
|
|
29
|
+
const result = await createVehicle(client, validBody);
|
|
30
|
+
|
|
31
|
+
expect(result).toEqual(mockResponse);
|
|
32
|
+
expect(postMock).toHaveBeenCalledWith(
|
|
33
|
+
'/boapi/proxy/vehicle/fleets/FLEET_ID/vehicles',
|
|
34
|
+
validBody
|
|
35
|
+
);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test('should create a vehicle with optional fields', async () => {
|
|
39
|
+
const fullBody: CreateVehicleBody = {
|
|
40
|
+
...validBody,
|
|
41
|
+
vuboxId: 'vubox-123',
|
|
42
|
+
externalId: 'ext-123',
|
|
43
|
+
wakeupProvider: 'provider',
|
|
44
|
+
noBox: true,
|
|
45
|
+
published: true,
|
|
46
|
+
archived: false,
|
|
47
|
+
msisdn: '33600000000',
|
|
48
|
+
iccid: '8933000000000000000',
|
|
49
|
+
imsi: '208000000000000',
|
|
50
|
+
residualValue: 15000,
|
|
51
|
+
};
|
|
52
|
+
const mockResponse = { id: 'vehicle-uuid', ...fullBody };
|
|
53
|
+
postMock.mockResolvedValueOnce({ data: mockResponse });
|
|
54
|
+
|
|
55
|
+
const result = await createVehicle(client, fullBody);
|
|
56
|
+
|
|
57
|
+
expect(result).toEqual(mockResponse);
|
|
58
|
+
expect(postMock).toHaveBeenCalledWith(
|
|
59
|
+
'/boapi/proxy/vehicle/fleets/FLEET_ID/vehicles',
|
|
60
|
+
fullBody
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test('should throw for missing vin', async () => {
|
|
65
|
+
const body = { ...validBody, vin: '' };
|
|
66
|
+
await expect(createVehicle(client, body)).rejects.toThrow(TypeError);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test('should throw for missing plate', async () => {
|
|
70
|
+
const body = { ...validBody, plate: '' };
|
|
71
|
+
await expect(createVehicle(client, body)).rejects.toThrow(TypeError);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('should throw for missing name', async () => {
|
|
75
|
+
const body = { ...validBody, name: '' };
|
|
76
|
+
await expect(createVehicle(client, body)).rejects.toThrow(TypeError);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test('should throw for invalid model id', async () => {
|
|
80
|
+
const body = { ...validBody, model: { id: -1 } };
|
|
81
|
+
await expect(createVehicle(client, body)).rejects.toThrow(TypeError);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test('should throw for missing model', async () => {
|
|
85
|
+
const body = { vin: 'VIN123', plate: 'AB-123', name: 'Test' } as CreateVehicleBody;
|
|
86
|
+
await expect(createVehicle(client, body)).rejects.toThrow(TypeError);
|
|
87
|
+
});
|
|
88
|
+
});
|