tabletcommand-location 2.4.1 → 2.4.3

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.
Files changed (65) hide show
  1. package/.claude/worktrees/sc-36275/.buildkite/pipeline.yml +5 -0
  2. package/.claude/worktrees/sc-36275/README.md +3 -0
  3. package/.claude/worktrees/sc-36275/build/audience.js +38 -0
  4. package/.claude/worktrees/sc-36275/build/audience.js.map +1 -0
  5. package/.claude/worktrees/sc-36275/build/index.js +95 -0
  6. package/.claude/worktrees/sc-36275/build/index.js.map +1 -0
  7. package/.claude/worktrees/sc-36275/build/location.js +278 -0
  8. package/.claude/worktrees/sc-36275/build/location.js.map +1 -0
  9. package/.claude/worktrees/sc-36275/build/query.js +378 -0
  10. package/.claude/worktrees/sc-36275/build/query.js.map +1 -0
  11. package/.claude/worktrees/sc-36275/build/store.js +182 -0
  12. package/.claude/worktrees/sc-36275/build/store.js.map +1 -0
  13. package/.claude/worktrees/sc-36275/build/test/location.js +522 -0
  14. package/.claude/worktrees/sc-36275/build/test/location.js.map +1 -0
  15. package/.claude/worktrees/sc-36275/build/test/mock.js +165 -0
  16. package/.claude/worktrees/sc-36275/build/test/mock.js.map +1 -0
  17. package/.claude/worktrees/sc-36275/build/test/query.js +174 -0
  18. package/.claude/worktrees/sc-36275/build/test/query.js.map +1 -0
  19. package/.claude/worktrees/sc-36275/build/types.js +8 -0
  20. package/.claude/worktrees/sc-36275/build/types.js.map +1 -0
  21. package/.claude/worktrees/sc-36275/cspell.json +64 -0
  22. package/.claude/worktrees/sc-36275/definitions/audience.d.ts +18 -0
  23. package/.claude/worktrees/sc-36275/definitions/audience.d.ts.map +1 -0
  24. package/.claude/worktrees/sc-36275/definitions/index.d.ts +11 -0
  25. package/.claude/worktrees/sc-36275/definitions/index.d.ts.map +1 -0
  26. package/.claude/worktrees/sc-36275/definitions/location.d.ts +32 -0
  27. package/.claude/worktrees/sc-36275/definitions/location.d.ts.map +1 -0
  28. package/.claude/worktrees/sc-36275/definitions/query.d.ts +36 -0
  29. package/.claude/worktrees/sc-36275/definitions/query.d.ts.map +1 -0
  30. package/.claude/worktrees/sc-36275/definitions/store.d.ts +64 -0
  31. package/.claude/worktrees/sc-36275/definitions/store.d.ts.map +1 -0
  32. package/.claude/worktrees/sc-36275/definitions/test/location.d.ts +2 -0
  33. package/.claude/worktrees/sc-36275/definitions/test/location.d.ts.map +1 -0
  34. package/.claude/worktrees/sc-36275/definitions/test/mock.d.ts +346 -0
  35. package/.claude/worktrees/sc-36275/definitions/test/mock.d.ts.map +1 -0
  36. package/.claude/worktrees/sc-36275/definitions/test/query.d.ts +2 -0
  37. package/.claude/worktrees/sc-36275/definitions/test/query.d.ts.map +1 -0
  38. package/.claude/worktrees/sc-36275/definitions/types.d.ts +53 -0
  39. package/.claude/worktrees/sc-36275/definitions/types.d.ts.map +1 -0
  40. package/.claude/worktrees/sc-36275/eslint.config.mjs +95 -0
  41. package/.claude/worktrees/sc-36275/gulpfile.js +23 -0
  42. package/.claude/worktrees/sc-36275/package-lock.json +9404 -0
  43. package/.claude/worktrees/sc-36275/package.json +54 -0
  44. package/.claude/worktrees/sc-36275/src/audience.ts +54 -0
  45. package/.claude/worktrees/sc-36275/src/index.ts +81 -0
  46. package/.claude/worktrees/sc-36275/src/location.ts +315 -0
  47. package/.claude/worktrees/sc-36275/src/query.ts +497 -0
  48. package/.claude/worktrees/sc-36275/src/store.ts +204 -0
  49. package/.claude/worktrees/sc-36275/src/test/location.ts +485 -0
  50. package/.claude/worktrees/sc-36275/src/test/mock.ts +186 -0
  51. package/.claude/worktrees/sc-36275/src/test/query.ts +209 -0
  52. package/.claude/worktrees/sc-36275/src/tsconfig.json +30 -0
  53. package/.claude/worktrees/sc-36275/src/types.ts +74 -0
  54. package/.claude/worktrees/sc-36275/test.sh +32 -0
  55. package/build/query.js +6 -1
  56. package/build/query.js.map +1 -1
  57. package/build/test/query.js +2 -2
  58. package/build/test/query.js.map +1 -1
  59. package/cspell.json +1 -0
  60. package/definitions/query.d.ts.map +1 -1
  61. package/definitions/test/mock.d.ts +5 -0
  62. package/definitions/test/mock.d.ts.map +1 -1
  63. package/package.json +7 -7
  64. package/src/query.ts +6 -1
  65. package/src/test/query.ts +2 -2
@@ -0,0 +1,378 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.metersToRadians = void 0;
4
+ exports.adminListLocations = adminListLocations;
5
+ exports.adminListPersonLocations = adminListPersonLocations;
6
+ exports.adminListUAVLocations = adminListUAVLocations;
7
+ exports.adminListAircraftLocations = adminListAircraftLocations;
8
+ exports.adminListSharedLocations = adminListSharedLocations;
9
+ exports.adminListFocusedLocations = adminListFocusedLocations;
10
+ exports.syncListSharedLocations = syncListSharedLocations;
11
+ exports.syncListLocations = syncListLocations;
12
+ exports.syncListPersonLocations = syncListPersonLocations;
13
+ exports.syncListAircraftLocations = syncListAircraftLocations;
14
+ exports.syncListUAVLocations = syncListUAVLocations;
15
+ exports.metersToRadians = 6378100; // The equatorial radius of the Earth in meters
16
+ function centerSphereFilter(longitude, latitude, diagonal) {
17
+ return {
18
+ $geoWithin: {
19
+ $centerSphere: [
20
+ [longitude, latitude],
21
+ diagonal / exports.metersToRadians,
22
+ ],
23
+ },
24
+ };
25
+ }
26
+ // Transponder-tracked person records carry an empty personnelUUID;
27
+ // they surface via the person/responder feeds, never in unit/vehicle lists
28
+ const excludePersonAndTransponderRecords = [
29
+ {
30
+ $or: [
31
+ { personnelUUID: "" },
32
+ { personnelUUID: { $exists: false } }, // TODO: Remove $exists check once all location services are running the latest
33
+ ],
34
+ },
35
+ {
36
+ $or: [
37
+ { transponderUUID: "" },
38
+ { transponderUUID: { $exists: false } },
39
+ ],
40
+ },
41
+ ];
42
+ // Same fields defined in the frontend
43
+ // api/a1/location/units and api/a1/location/units-shared
44
+ const projectionAdmin = {
45
+ _id: 1,
46
+ active: 1,
47
+ altitude: 1,
48
+ color: 1,
49
+ device_type: 1,
50
+ industry: 1,
51
+ kindType: 1,
52
+ location: 1,
53
+ locationGeoJSON: 1,
54
+ modified: 1,
55
+ movedAt: 1,
56
+ sendToCAD: 1,
57
+ source: 1,
58
+ speed: 1,
59
+ uuid: 1, // Legacy, remove later
60
+ };
61
+ function adminListLocations(params) {
62
+ const { departmentId, movedAt, showAll, } = params;
63
+ const query = {
64
+ // TODO: Replace models.Location active: true with visibility in "visible"
65
+ active: true,
66
+ departmentId,
67
+ $and: excludePersonAndTransponderRecords,
68
+ kindType: {
69
+ $ne: "uav",
70
+ },
71
+ // 03/14/23 (Joe) - Trying movedAt only [sc-11794] - determined modified was being overwritten by cad vehicle status updates
72
+ movedAt: {
73
+ $gte: movedAt,
74
+ },
75
+ };
76
+ if (showAll) {
77
+ delete query.active;
78
+ }
79
+ return {
80
+ list: query,
81
+ projection: projectionAdmin,
82
+ };
83
+ }
84
+ function adminListPersonLocations(params) {
85
+ const { departmentId, movedAt, showAll } = params;
86
+ const query = {
87
+ active: true,
88
+ departmentId,
89
+ kindType: "person",
90
+ movedAt: {
91
+ $gte: movedAt,
92
+ },
93
+ };
94
+ if (showAll) {
95
+ delete query.active;
96
+ }
97
+ // Same fields defined in the frontend
98
+ // api/a1/location/person
99
+ const projection = {
100
+ _id: 1,
101
+ active: 1,
102
+ altitude: 1,
103
+ color: 1,
104
+ device_type: 1,
105
+ industry: 1,
106
+ kindType: 1,
107
+ location: 1,
108
+ locationGeoJSON: 1,
109
+ modified: 1,
110
+ movedAt: 1,
111
+ personnelUUID: 1,
112
+ sendToCAD: 1,
113
+ source: 1,
114
+ speed: 1,
115
+ transponderUUID: 1,
116
+ uuid: 1, // Legacy, remove later
117
+ };
118
+ return {
119
+ list: query,
120
+ projection,
121
+ };
122
+ }
123
+ function adminListUAVLocations(params) {
124
+ const { departmentId, movedAt, showAll, } = params;
125
+ const query = {
126
+ active: true,
127
+ departmentId,
128
+ kindType: "uav",
129
+ movedAt: {
130
+ $gte: movedAt,
131
+ },
132
+ };
133
+ if (showAll) {
134
+ delete query.active;
135
+ }
136
+ const projection = {
137
+ _id: 1,
138
+ active: 1,
139
+ agencyCode: 1,
140
+ agencyName: 1,
141
+ altitude: 1,
142
+ color: 1,
143
+ device_type: 1,
144
+ heading: 1,
145
+ industry: 1,
146
+ kindType: 1,
147
+ locationGeoJSON: 1,
148
+ modified: 1,
149
+ movedAt: 1,
150
+ opAreaCode: 1,
151
+ opAreaName: 1,
152
+ sendToCAD: 1,
153
+ source: 1,
154
+ speed: 1,
155
+ state: 1,
156
+ userId: 1,
157
+ username: 1,
158
+ uuid: 1, // Legacy, remove later
159
+ vehicleId: 1,
160
+ };
161
+ return {
162
+ list: query,
163
+ projection,
164
+ };
165
+ }
166
+ function adminListAircraftLocations(params) {
167
+ const { departmentId, movedAt, longitude, latitude, diagonal } = params;
168
+ const list = {
169
+ shared: true,
170
+ active: true,
171
+ source: "ADSB",
172
+ kindType: {
173
+ $in: ["fixed-wing", "helicopter"],
174
+ },
175
+ departmentId: {
176
+ $ne: departmentId,
177
+ },
178
+ movedAt: {
179
+ $gte: movedAt.toISOString(),
180
+ },
181
+ locationGeoJSON: centerSphereFilter(longitude, latitude, diagonal),
182
+ };
183
+ return {
184
+ list,
185
+ projection: projectionAdmin,
186
+ };
187
+ }
188
+ function adminListSharedLocations(params) {
189
+ const { departmentId, movedAt, longitude, latitude, diagonal } = params;
190
+ const listSharedAVLQuery = {
191
+ shared: true,
192
+ active: true,
193
+ source: {
194
+ $ne: "ADSB"
195
+ },
196
+ departmentId: {
197
+ $ne: departmentId,
198
+ },
199
+ kindType: {
200
+ $ne: "uav",
201
+ },
202
+ movedAt: {
203
+ $gte: movedAt.toISOString(),
204
+ },
205
+ locationGeoJSON: centerSphereFilter(longitude, latitude, diagonal),
206
+ };
207
+ return {
208
+ list: listSharedAVLQuery,
209
+ projection: projectionAdmin,
210
+ };
211
+ }
212
+ function adminListFocusedLocations(params) {
213
+ const { departmentId, movedAt, longitude, latitude, diagonal, showAll } = params;
214
+ const listFocusedAVLQuery = {
215
+ active: true,
216
+ departmentId,
217
+ movedAt: {
218
+ $gte: movedAt.toISOString(),
219
+ },
220
+ locationGeoJSON: centerSphereFilter(longitude, latitude, diagonal),
221
+ };
222
+ if (showAll) {
223
+ delete listFocusedAVLQuery.locationGeoJSON;
224
+ }
225
+ return {
226
+ list: listFocusedAVLQuery,
227
+ projection: projectionAdmin,
228
+ };
229
+ }
230
+ // Sync queries
231
+ const projectionSync = {
232
+ active: 1,
233
+ departmentId: 1,
234
+ device_type: 1, // used in web ui
235
+ location: 1,
236
+ locationGeoJSON: 1,
237
+ modified: 1,
238
+ userId: 1,
239
+ username: 1,
240
+ uuid: 1, // used in iOS
241
+ // both used by AVL sharing
242
+ opAreaName: 1,
243
+ opAreaCode: 1,
244
+ shared: 1,
245
+ state: 1,
246
+ // v3
247
+ altitude: 1,
248
+ speed: 1,
249
+ movedAt: 1,
250
+ agencyName: 1,
251
+ agencyCode: 1,
252
+ // v4
253
+ color: 1,
254
+ colorChangedAt: 1,
255
+ propsChangedAt: 1,
256
+ heading: 1,
257
+ // v4 extra
258
+ kindType: 1,
259
+ source: 1,
260
+ personnelUUID: 1,
261
+ transponderUUID: 1,
262
+ // v4 kind/type/locationType
263
+ kind: 1,
264
+ type: 1,
265
+ locationType: 1,
266
+ kindColor: 1,
267
+ // v4
268
+ industry: 1,
269
+ };
270
+ function syncListSharedLocations(params) {
271
+ const { departmentId, modifiedDate, movedAt, longitude, latitude, diagonal, } = params;
272
+ const list = {
273
+ shared: true,
274
+ source: {
275
+ $nin: ["ADSB", "DroneSense", "Skydio"]
276
+ },
277
+ departmentId: {
278
+ $ne: departmentId,
279
+ },
280
+ modified: {
281
+ $gte: modifiedDate.toISOString(),
282
+ },
283
+ movedAt: {
284
+ $gte: movedAt.toISOString(),
285
+ },
286
+ locationGeoJSON: centerSphereFilter(longitude, latitude, diagonal),
287
+ };
288
+ return {
289
+ list,
290
+ projection: projectionSync,
291
+ };
292
+ }
293
+ function syncListLocations(params) {
294
+ const { departmentId, modifiedDate, movedAt, } = params;
295
+ const list = {
296
+ departmentId,
297
+ $and: excludePersonAndTransponderRecords,
298
+ kindType: {
299
+ $ne: "uav"
300
+ },
301
+ modified: {
302
+ $gte: modifiedDate.toISOString(),
303
+ },
304
+ movedAt: {
305
+ $gte: movedAt.toISOString(),
306
+ }
307
+ };
308
+ return {
309
+ list,
310
+ projection: projectionSync,
311
+ };
312
+ }
313
+ function syncListPersonLocations(params) {
314
+ const { departmentId, modifiedDate, movedAt, } = params;
315
+ const list = {
316
+ departmentId,
317
+ kindType: "person",
318
+ modified: {
319
+ $gte: modifiedDate.toISOString(),
320
+ },
321
+ movedAt: {
322
+ $gte: movedAt.toISOString(),
323
+ },
324
+ };
325
+ return {
326
+ list,
327
+ projection: projectionSync,
328
+ };
329
+ }
330
+ function syncListAircraftLocations(params) {
331
+ const { departmentId, movedAt, modifiedDate,
332
+ // Possibly missing
333
+ longitude, latitude, diagonal } = params;
334
+ const list = {
335
+ shared: true,
336
+ source: "ADSB",
337
+ kindType: {
338
+ $in: ["fixed-wing", "helicopter"]
339
+ },
340
+ departmentId: {
341
+ $ne: departmentId,
342
+ },
343
+ modified: {
344
+ $gte: modifiedDate.toISOString(),
345
+ },
346
+ movedAt: {
347
+ $gte: movedAt.toISOString(),
348
+ }
349
+ };
350
+ const hasCoordinate = Math.abs(latitude) > 0.01 || Math.abs(longitude) > 0.01;
351
+ const validCoordinate = Math.abs(latitude) < 90 && Math.abs(longitude) < 180;
352
+ const filterOnLocation = hasCoordinate && validCoordinate;
353
+ if (filterOnLocation) {
354
+ list.locationGeoJSON = centerSphereFilter(longitude, latitude, diagonal);
355
+ }
356
+ return {
357
+ list,
358
+ projection: projectionSync,
359
+ };
360
+ }
361
+ function syncListUAVLocations(params) {
362
+ const { departmentId, modifiedDate, movedAt, } = params;
363
+ const list = {
364
+ departmentId,
365
+ kindType: "uav",
366
+ modified: {
367
+ $gte: modifiedDate.toISOString(),
368
+ },
369
+ movedAt: {
370
+ $gte: movedAt.toISOString(),
371
+ },
372
+ };
373
+ return {
374
+ list,
375
+ projection: projectionSync,
376
+ };
377
+ }
378
+ //# sourceMappingURL=query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,182 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.store = store;
7
+ const debug_1 = __importDefault(require("debug"));
8
+ const tabletcommand_backend_models_1 = require("tabletcommand-backend-models");
9
+ const lodash_1 = __importDefault(require("lodash"));
10
+ function store(departmentModel, locationModel, cadVehicleModel, deviceMappingModel) {
11
+ const debug = (0, debug_1.default)("tabletcommand-location:location:store");
12
+ async function getVehicle(item, departmentId) {
13
+ const query = {
14
+ vehicleId: item.vehicleId,
15
+ departmentId,
16
+ };
17
+ return cadVehicleModel.findOne(query).lean();
18
+ }
19
+ async function getDeviceMappingGeotab(item, departmentId) {
20
+ const query = {
21
+ deviceId: item.vehicleId,
22
+ departmentId,
23
+ deviceType: "geotab",
24
+ };
25
+ return deviceMappingModel.findOne(query).lean();
26
+ }
27
+ async function updateVehicle(item, departmentId) {
28
+ const query = {
29
+ departmentId,
30
+ vehicleId: item.vehicleId,
31
+ };
32
+ const options = {
33
+ upsert: true,
34
+ setDefaultsOnInsert: true,
35
+ new: true
36
+ };
37
+ return await cadVehicleModel.findOneAndUpdate(query, item, options);
38
+ }
39
+ function isDuplicateKeyError(error) {
40
+ return lodash_1.default.isObject(error) && error.code === 11000;
41
+ }
42
+ async function updateLocation(item, atDate) {
43
+ try {
44
+ await performUpdateLocation(item, atDate);
45
+ }
46
+ catch (error) {
47
+ if (!isDuplicateKeyError(error)) {
48
+ throw error;
49
+ }
50
+ // A concurrent first-write hit the unique (departmentId, session, device_type)
51
+ // index; the record exists now so we can retry once, so this update goes through.
52
+ await performUpdateLocation(item, atDate);
53
+ }
54
+ }
55
+ async function performUpdateLocation(item, atDate) {
56
+ // eslint-disable-next-line new-cap
57
+ const modelItem = new locationModel(item);
58
+ const hasPersonIdentity = (lodash_1.default.isString(modelItem.personnelUUID) && modelItem.personnelUUID !== "") ||
59
+ (lodash_1.default.isString(modelItem.transponderUUID) && modelItem.transponderUUID !== "");
60
+ const isPerson = (modelItem.kindType === tabletcommand_backend_models_1.LocationKindType.Person || modelItem.locationType === tabletcommand_backend_models_1.LocationKindType.Person) &&
61
+ hasPersonIdentity;
62
+ // Person records upsert by session (their stable identity key); username is
63
+ // display-only for transponder stuff, so renames must not create new records from updates
64
+ const query = isPerson
65
+ ? {
66
+ device_type: modelItem.device_type,
67
+ departmentId: modelItem.departmentId,
68
+ session: modelItem.session
69
+ }
70
+ : {
71
+ device_type: modelItem.device_type,
72
+ departmentId: modelItem.departmentId,
73
+ username: modelItem.username
74
+ };
75
+ debug(`Location.findOne: ${JSON.stringify(query)}`);
76
+ const dbItem = await locationModel.findOne(query).lean().exec();
77
+ const cloneItem = { ...dbItem };
78
+ let updatedItem = propagateLocation(modelItem, dbItem);
79
+ debug(`Location.save: ${JSON.stringify(updatedItem)}`);
80
+ if (cloneItem._id) {
81
+ const locationDelta = generateLocationDelta(cloneItem, updatedItem, atDate);
82
+ updatedItem = locationDelta;
83
+ debug(`Location.delta: ${JSON.stringify(locationDelta)}`);
84
+ }
85
+ else {
86
+ // if new location record - Attempt to reconcile agency name and code to resources
87
+ // this is going to be resolved by the bin/cron-cleanup-minute cron
88
+ }
89
+ await locationModel.updateOne(query, {
90
+ $set: updatedItem,
91
+ }, {
92
+ upsert: true,
93
+ });
94
+ }
95
+ function propagateLocation(modelItem, dbItem) {
96
+ if (!lodash_1.default.isObject(dbItem)) {
97
+ return modelItem;
98
+ }
99
+ // We keep the same value for _id, uuid, departmentId
100
+ dbItem.altitude = modelItem.altitude;
101
+ dbItem.device_type = modelItem.device_type;
102
+ dbItem.heading = modelItem.heading;
103
+ dbItem.modified = modelItem.modified;
104
+ dbItem.movedAt = modelItem.movedAt;
105
+ dbItem.session = modelItem.session;
106
+ dbItem.speed = modelItem.speed;
107
+ dbItem.userId = modelItem.userId;
108
+ dbItem.username = modelItem.username;
109
+ dbItem.version = modelItem.version;
110
+ dbItem.locationGeoJSON = modelItem.locationGeoJSON;
111
+ dbItem.source = modelItem.source;
112
+ dbItem.kindType = modelItem.kindType;
113
+ dbItem.industry = modelItem.industry;
114
+ // Carry person/category fields on the update path; only overwrite when the
115
+ // incoming payload actually provides a value, so sources that don't send
116
+ // these fields don't wipe values written by other sources.
117
+ if (lodash_1.default.isString(modelItem.locationType) && modelItem.locationType !== "") {
118
+ dbItem.locationType = modelItem.locationType;
119
+ }
120
+ if (lodash_1.default.isString(modelItem.kind) && modelItem.kind !== "") {
121
+ dbItem.kind = modelItem.kind;
122
+ }
123
+ if (lodash_1.default.isString(modelItem.type) && modelItem.type !== "") {
124
+ dbItem.type = modelItem.type;
125
+ }
126
+ if (lodash_1.default.isString(modelItem.personnelUUID) && modelItem.personnelUUID !== "") {
127
+ dbItem.personnelUUID = modelItem.personnelUUID;
128
+ }
129
+ if (lodash_1.default.isString(modelItem.transponderUUID) && modelItem.transponderUUID !== "") {
130
+ dbItem.transponderUUID = modelItem.transponderUUID;
131
+ }
132
+ // Propagate sharedAVL items
133
+ dbItem.opAreaCode = modelItem.opAreaCode;
134
+ dbItem.opAreaName = modelItem.opAreaName;
135
+ dbItem.state = modelItem.state;
136
+ // Legacy
137
+ dbItem.active = modelItem.active;
138
+ dbItem.shared = modelItem.shared;
139
+ dbItem.sendToCAD = modelItem.sendToCAD;
140
+ //
141
+ dbItem.visibility = modelItem.visibility;
142
+ return dbItem;
143
+ }
144
+ function generateLocationDelta(locationRecord, updateObject, atDate) {
145
+ if (!lodash_1.default.isObject(locationRecord)) {
146
+ return updateObject;
147
+ }
148
+ const locationDelta = {};
149
+ for (const [key, value] of Object.entries(updateObject)) {
150
+ // eslint-disable-next-line security/detect-object-injection
151
+ if (JSON.stringify(value) !== JSON.stringify(locationRecord[key])) {
152
+ // eslint-disable-next-line security/detect-object-injection
153
+ locationDelta[key] = value;
154
+ }
155
+ }
156
+ const updatedKeys = Object.keys(locationDelta);
157
+ const propsKeys = [
158
+ "active",
159
+ "agencyCode",
160
+ "agencyName",
161
+ "device_type",
162
+ "opAreaCode",
163
+ "opAreaName",
164
+ "shared",
165
+ "state",
166
+ "username",
167
+ "industry",
168
+ ];
169
+ if (lodash_1.default.intersection(updatedKeys, propsKeys).length > 0) {
170
+ locationDelta.propsChangedAt = atDate;
171
+ }
172
+ return locationDelta;
173
+ }
174
+ return {
175
+ getVehicle,
176
+ getDeviceMappingGeotab,
177
+ updateVehicle,
178
+ updateLocation,
179
+ };
180
+ }
181
+ exports.default = store;
182
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}