@lyxa.ai/core 1.1.92 → 1.1.94-test-01

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.js CHANGED
@@ -76,7 +76,7 @@ async function registerLibraries(options) {
76
76
  const twilioServiceInstance = new twilio_1.TwilioService();
77
77
  typedi_1.Container.set(twilio_1.TwilioService, twilioServiceInstance);
78
78
  const googleMapsKey = await getLibraries().getSecretsService().getKey('GOOGLE_MAPS_API_KEY');
79
- const googleMapService = new map_1.GoogleMapsService(googleMapsKey);
79
+ const googleMapService = new map_1.GoogleMapsService(redisInstance, googleMapsKey);
80
80
  const mapServiceInstance = new map_1.MapService(googleMapService);
81
81
  typedi_1.Container.set(map_1.MapService, mapServiceInstance);
82
82
  const bobUsername = await getLibraries().getSecretsService().getKey('BOB_USER_NAME');
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"/","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["// Apply the soft delete plugin globally before any connections or models\nimport { applySoftDeletePlugin } from './libraries/mongo/plugins/soft-delete-plugin';\n\napplySoftDeletePlugin();\n\nimport { LibraryManager } from './libraries';\nimport { Container } from 'typedi';\nimport { ConfigurationOptions, ConfigurationService } from './libraries/configuration';\nimport { LyxaLogger } from './libraries/logger';\nimport { RedisService } from './libraries/redis';\nimport { initGlobalConnection, initLyxaMongoDbConnection } from './libraries/mongo';\nimport { SecretManagerService } from './libraries/secrets';\nimport { MicroServiceDispatcher } from './libraries/dispatcher';\nimport { TwilioService } from './libraries/twilio';\nimport { FirebaseService } from './libraries/firebase';\nimport { initEventBus, subscribeToEvent } from './libraries/event';\nimport { SubscriptionRegistry } from './libraries/event/registry/SubscriptionRegistry';\nimport { MapService, GoogleMapsService } from './libraries/map';\nimport { CachedSettingsService } from './libraries/cache/settings';\nimport {\n\tFCMService,\n\tFCMServiceForRider,\n\tFCMServiceForShop,\n\tFCMServiceForUser,\n} from './libraries/firebase/fcmService';\nimport { BullMQService } from './libraries/bullmq/bull-mq-service';\nimport { BOBSecrets, BOBService, CashSettlementService } from './libraries/cash-settlement';\nimport { disconnectAllEntitiesFromInstance } from './libraries/socket';\nimport { createFilterSchema } from './utilities/validation/filter-schema.factory';\n\nexport { ConfigurationOptions } from './libraries/configuration';\nexport { EnvironmentConfigurationType } from './libraries/configuration/types/EnvironmentConfigurationType';\nexport { initGlobalConnection } from './libraries/mongo';\n\nexport async function bootstrapCore(options?: ConfigurationOptions) {\n\ttry {\n\t\tawait registerLibraries(options);\n\n\t\tgetLibraries().getLogger().logger.info('Successfully bootstrapped lyxa-core.');\n\n\t\tconst gracefulShutdown = async () => {\n\t\t\tgetLibraries().getLogger().logger.info('Received shutdown signal, shutting down gracefully...');\n\t\t\tif (options?.instanceType == 'socket') await disconnectAllEntitiesFromInstance();\n\t\t\tprocess.exit();\n\t\t};\n\n\t\tprocess.on('SIGTERM', gracefulShutdown);\n\t\tprocess.on('SIGINT', gracefulShutdown);\n\t\tprocess.on('uncaughtException', err => {\n\t\t\tgetLibraries().getLogger().logger.error('Uncaught exception, shutting down...', err);\n\t\t\tgracefulShutdown();\n\t\t});\n\t\tprocess.on('exit', code => {\n\t\t\tgetLibraries().getLogger().logger.info(`Exiting with code: ${code}`);\n\t\t});\n\n\t\tconsole.log('Created hooks.');\n\t} catch (e) {\n\t\tconsole.error(e);\n\t}\n}\n\nexport async function registerLibraries(options?: ConfigurationOptions) {\n\t// Setup configuration.\n\tconst configurationInstance = new ConfigurationService(options);\n\tContainer.set(ConfigurationService, configurationInstance);\n\n\t// Setup redis.\n\tconst redisInstance = new RedisService(configurationInstance.redisURL);\n\tContainer.set(RedisService, redisInstance);\n\n\t// Setup secret\n\tconst secretInstance = new SecretManagerService(configurationInstance, redisInstance);\n\tContainer.set(SecretManagerService, secretInstance);\n\n\t// Setup BullMQ\n\tconst bullMQInstance = new BullMQService(redisInstance);\n\tContainer.set(BullMQService, bullMQInstance);\n\n\tconst mongoUrl = options?.mongoDbUrl\n\t\t? options.mongoDbUrl\n\t\t: await getLibraries().getSecretsService().getKey('MONGO_URL');\n\n\tawait initLyxaMongoDbConnection(mongoUrl!, options);\n\tawait initGlobalConnection(mongoUrl!, options!.environment);\n\n\t// Setup logger\n\tconst loggerInstance = new LyxaLogger(options!.instanceType!, mongoUrl!);\n\tContainer.set(LyxaLogger, loggerInstance);\n\n\t// Setup firebase\n\tconst firebaseInstance = new FirebaseService(configurationInstance!);\n\tContainer.set(FirebaseService, firebaseInstance);\n\n\t// Setup microservice dispatcher\n\tconst microserviceDispatcherInstance = new MicroServiceDispatcher(secretInstance);\n\tContainer.set(MicroServiceDispatcher, microserviceDispatcherInstance);\n\n\t// Setup twilio\n\tconst twilioServiceInstance = new TwilioService();\n\tContainer.set(TwilioService, twilioServiceInstance);\n\n\t// Setup map service\n\tconst googleMapsKey = await getLibraries().getSecretsService().getKey('GOOGLE_MAPS_API_KEY');\n\tconst googleMapService = new GoogleMapsService(googleMapsKey as string);\n\tconst mapServiceInstance = new MapService(googleMapService);\n\tContainer.set(MapService, mapServiceInstance);\n\n\t// Setup cash settlement service\n\tconst bobUsername = await getLibraries().getSecretsService().getKey('BOB_USER_NAME');\n\tconst bobPassword = await getLibraries().getSecretsService().getKey('BOB_PASSWORD');\n\tconst bobURL = await getLibraries().getSecretsService().getKey('BOB_URL');\n\n\tconst bobService = new BOBService({\n\t\tBOB_USER_NAME: bobUsername,\n\t\tBOB_PASSWORD: bobPassword,\n\t\tBOB_URL: bobURL,\n\t} as BOBSecrets);\n\tconst cashSettlementServiceInstance = new CashSettlementService(bobService);\n\tContainer.set(CashSettlementService, cashSettlementServiceInstance);\n\tContainer.set(BOBService, bobService);\n\n\tconst settingsServiceInstance = new CachedSettingsService(redisInstance);\n\tContainer.set(CachedSettingsService, settingsServiceInstance);\n\n\t// Setup fcm service\n\tconst firebaseService = getLibraries().getFirebaseService();\n\tconst fcmServiceInstance = new FCMService(firebaseService.superApp);\n\tconst fcmServiceInstanceForUser = new FCMService(firebaseService.userApp);\n\tconst fcmServiceInstanceForRider = new FCMService(firebaseService.riderApp);\n\tconst fcmServiceInstanceForShop = new FCMService(firebaseService.shopApp);\n\tContainer.set(FCMService, fcmServiceInstance);\n\tContainer.set(FCMServiceForUser, fcmServiceInstanceForUser);\n\tContainer.set(FCMServiceForRider, fcmServiceInstanceForRider);\n\tContainer.set(FCMServiceForShop, fcmServiceInstanceForShop);\n\n\tconsole.log('Initialized everything');\n\n\tawait initEventBus('amqps://adlvedna:oY_X4qH1AphtB83YNcf9DHMO3UVmX23s@dog.lmq.cloudamqp.com/adlvedna');\n\tconst allSubscriptions = SubscriptionRegistry.getAllSubscriptions();\n\n\tconst instantiatedServices = new Map<Function, any>();\n\n\tfor (const { eventId, targetConstructor, methodName } of allSubscriptions) {\n\t\tlet instance = instantiatedServices.get(targetConstructor);\n\t\tif (!instance) {\n\t\t\tinstance = Container.get(targetConstructor as any);\n\t\t\tinstantiatedServices.set(targetConstructor, instance);\n\t\t}\n\n\t\tawait subscribeToEvent(eventId, async payload => {\n\t\t\treturn instance[methodName](payload);\n\t\t});\n\t}\n}\n\nexport function getLibraries(): LibraryManager {\n\treturn Container.get(LibraryManager);\n}"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"/","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["// Apply the soft delete plugin globally before any connections or models\nimport { applySoftDeletePlugin } from './libraries/mongo/plugins/soft-delete-plugin';\n\napplySoftDeletePlugin();\n\nimport { LibraryManager } from './libraries';\nimport { Container } from 'typedi';\nimport { ConfigurationOptions, ConfigurationService } from './libraries/configuration';\nimport { LyxaLogger } from './libraries/logger';\nimport { RedisService } from './libraries/redis';\nimport { initGlobalConnection, initLyxaMongoDbConnection } from './libraries/mongo';\nimport { SecretManagerService } from './libraries/secrets';\nimport { MicroServiceDispatcher } from './libraries/dispatcher';\nimport { TwilioService } from './libraries/twilio';\nimport { FirebaseService } from './libraries/firebase';\nimport { initEventBus, subscribeToEvent } from './libraries/event';\nimport { SubscriptionRegistry } from './libraries/event/registry/SubscriptionRegistry';\nimport { MapService, GoogleMapsService } from './libraries/map';\nimport { CachedSettingsService } from './libraries/cache/settings';\nimport {\n\tFCMService,\n\tFCMServiceForRider,\n\tFCMServiceForShop,\n\tFCMServiceForUser,\n} from './libraries/firebase/fcmService';\nimport { BullMQService } from './libraries/bullmq/bull-mq-service';\nimport { BOBSecrets, BOBService, CashSettlementService } from './libraries/cash-settlement';\nimport { disconnectAllEntitiesFromInstance } from './libraries/socket';\nimport { createFilterSchema } from './utilities/validation/filter-schema.factory';\nimport { EnvironmentConfigurationType } from './libraries/configuration/types/EnvironmentConfigurationType';\n\nexport { ConfigurationOptions } from './libraries/configuration';\nexport { EnvironmentConfigurationType } from './libraries/configuration/types/EnvironmentConfigurationType';\nexport { initGlobalConnection } from './libraries/mongo';\n\nexport async function bootstrapCore(options?: ConfigurationOptions) {\n\ttry {\n\t\tawait registerLibraries(options);\n\n\t\tgetLibraries().getLogger().logger.info('Successfully bootstrapped lyxa-core.');\n\n\t\tconst gracefulShutdown = async () => {\n\t\t\tgetLibraries().getLogger().logger.info('Received shutdown signal, shutting down gracefully...');\n\t\t\tif (options?.instanceType == 'socket') await disconnectAllEntitiesFromInstance();\n\t\t\tprocess.exit();\n\t\t};\n\n\t\tprocess.on('SIGTERM', gracefulShutdown);\n\t\tprocess.on('SIGINT', gracefulShutdown);\n\t\tprocess.on('uncaughtException', err => {\n\t\t\tgetLibraries().getLogger().logger.error('Uncaught exception, shutting down...', err);\n\t\t\tgracefulShutdown();\n\t\t});\n\t\tprocess.on('exit', code => {\n\t\t\tgetLibraries().getLogger().logger.info(`Exiting with code: ${code}`);\n\t\t});\n\n\t\tconsole.log('Created hooks.');\n\t} catch (e) {\n\t\tconsole.error(e);\n\t}\n}\n\nexport async function registerLibraries(options?: ConfigurationOptions) {\n\t// Setup configuration.\n\tconst configurationInstance = new ConfigurationService(options);\n\tContainer.set(ConfigurationService, configurationInstance);\n\n\t// Setup redis.\n\tconst redisInstance = new RedisService(configurationInstance.redisURL);\n\tContainer.set(RedisService, redisInstance);\n\n\t// Setup secret\n\tconst secretInstance = new SecretManagerService(configurationInstance, redisInstance);\n\tContainer.set(SecretManagerService, secretInstance);\n\n\t// Setup BullMQ\n\tconst bullMQInstance = new BullMQService(redisInstance);\n\tContainer.set(BullMQService, bullMQInstance);\n\n\tconst mongoUrl = options?.mongoDbUrl\n\t\t? options.mongoDbUrl\n\t\t: await getLibraries().getSecretsService().getKey('MONGO_URL');\n\n\tawait initLyxaMongoDbConnection(mongoUrl!, options);\n\tawait initGlobalConnection(mongoUrl!, options!.environment);\n\n\t// Setup logger\n\tconst loggerInstance = new LyxaLogger(options!.instanceType!, mongoUrl!);\n\tContainer.set(LyxaLogger, loggerInstance);\n\n\t// Setup firebase\n\tconst firebaseInstance = new FirebaseService(configurationInstance!);\n\tContainer.set(FirebaseService, firebaseInstance);\n\n\t// Setup microservice dispatcher\n\tconst microserviceDispatcherInstance = new MicroServiceDispatcher(secretInstance);\n\tContainer.set(MicroServiceDispatcher, microserviceDispatcherInstance);\n\n\t// Setup twilio\n\tconst twilioServiceInstance = new TwilioService();\n\tContainer.set(TwilioService, twilioServiceInstance);\n\n\t// Setup map service\n\tconst googleMapsKey = await getLibraries().getSecretsService().getKey('GOOGLE_MAPS_API_KEY');\n\tconst googleMapService = new GoogleMapsService(redisInstance, googleMapsKey as string);\n\tconst mapServiceInstance = new MapService(googleMapService);\n\tContainer.set(MapService, mapServiceInstance);\n\n\t// Setup cash settlement service\n\tconst bobUsername = await getLibraries().getSecretsService().getKey('BOB_USER_NAME');\n\tconst bobPassword = await getLibraries().getSecretsService().getKey('BOB_PASSWORD');\n\tconst bobURL = await getLibraries().getSecretsService().getKey('BOB_URL');\n\n\tconst bobService = new BOBService({\n\t\tBOB_USER_NAME: bobUsername,\n\t\tBOB_PASSWORD: bobPassword,\n\t\tBOB_URL: bobURL,\n\t} as BOBSecrets);\n\tconst cashSettlementServiceInstance = new CashSettlementService(bobService);\n\tContainer.set(CashSettlementService, cashSettlementServiceInstance);\n\tContainer.set(BOBService, bobService);\n\n\tconst settingsServiceInstance = new CachedSettingsService(redisInstance);\n\tContainer.set(CachedSettingsService, settingsServiceInstance);\n\n\t// Setup fcm service\n\tconst firebaseService = getLibraries().getFirebaseService();\n\tconst fcmServiceInstance = new FCMService(firebaseService.superApp);\n\tconst fcmServiceInstanceForUser = new FCMService(firebaseService.userApp);\n\tconst fcmServiceInstanceForRider = new FCMService(firebaseService.riderApp);\n\tconst fcmServiceInstanceForShop = new FCMService(firebaseService.shopApp);\n\tContainer.set(FCMService, fcmServiceInstance);\n\tContainer.set(FCMServiceForUser, fcmServiceInstanceForUser);\n\tContainer.set(FCMServiceForRider, fcmServiceInstanceForRider);\n\tContainer.set(FCMServiceForShop, fcmServiceInstanceForShop);\n\n\tconsole.log('Initialized everything');\n\n\tawait initEventBus('amqps://adlvedna:oY_X4qH1AphtB83YNcf9DHMO3UVmX23s@dog.lmq.cloudamqp.com/adlvedna');\n\tconst allSubscriptions = SubscriptionRegistry.getAllSubscriptions();\n\n\tconst instantiatedServices = new Map<Function, any>();\n\n\tfor (const { eventId, targetConstructor, methodName } of allSubscriptions) {\n\t\tlet instance = instantiatedServices.get(targetConstructor);\n\t\tif (!instance) {\n\t\t\tinstance = Container.get(targetConstructor as any);\n\t\t\tinstantiatedServices.set(targetConstructor, instance);\n\t\t}\n\n\t\tawait subscribeToEvent(eventId, async payload => {\n\t\t\treturn instance[methodName](payload);\n\t\t});\n\t}\n}\n\nexport function getLibraries(): LibraryManager {\n\treturn Container.get(LibraryManager);\n}\n"]}
@@ -1,7 +1,18 @@
1
1
  import { IMapService, ICoordinate, IDistanceInfo, IWaypointDistanceInfo } from '../interfaces/IMapService';
2
+ import { RedisService } from '../../redis';
2
3
  export declare class GoogleMapsService implements IMapService {
4
+ private redisService;
3
5
  private _apiKey;
4
- constructor(apiKey: string);
6
+ private logModel;
7
+ constructor(redisService: RedisService, apiKey: string);
8
+ private createCacheKey;
9
+ private acquireDistributedLock;
10
+ private releaseDistributedLock;
11
+ private logApiUsage;
12
+ private clearRouteCache;
13
+ private getCacheStats;
5
14
  getDistanceInfo(origin: ICoordinate, destination: ICoordinate): Promise<IDistanceInfo>;
15
+ private getDistanceInfoFromGoogle;
6
16
  getWaypointsDistanceInfo(origin: ICoordinate, destination: ICoordinate, waypoints: Array<ICoordinate>): Promise<IWaypointDistanceInfo>;
17
+ private getWaypointsDistanceInfoFromGoogle;
7
18
  }
@@ -15,6 +15,12 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
22
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
23
+ };
18
24
  var __importStar = (this && this.__importStar) || (function () {
19
25
  var ownKeys = function(o) {
20
26
  ownKeys = Object.getOwnPropertyNames || function (o) {
@@ -32,6 +38,12 @@ var __importStar = (this && this.__importStar) || (function () {
32
38
  return result;
33
39
  };
34
40
  })();
41
+ var __metadata = (this && this.__metadata) || function (k, v) {
42
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
43
+ };
44
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
45
+ return function (target, key) { decorator(target, key, paramIndex); }
46
+ };
35
47
  var __importDefault = (this && this.__importDefault) || function (mod) {
36
48
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
49
  };
@@ -40,18 +52,142 @@ exports.GoogleMapsService = void 0;
40
52
  const axios_1 = __importDefault(require("axios"));
41
53
  const polyline = __importStar(require("@mapbox/polyline"));
42
54
  const server_1 = require("@trpc/server");
43
- class GoogleMapsService {
55
+ const redis_1 = require("../../redis");
56
+ const crypto_1 = require("crypto");
57
+ const typedi_1 = require("typedi");
58
+ const models_1 = require("../../mongo/models");
59
+ let GoogleMapsService = class GoogleMapsService {
60
+ redisService;
44
61
  _apiKey;
45
- constructor(apiKey) {
62
+ logModel;
63
+ constructor(redisService, apiKey) {
64
+ this.redisService = redisService;
46
65
  this._apiKey = apiKey;
66
+ this.logModel = models_1.GoogleMapsUsageModel;
67
+ }
68
+ createCacheKey(origin, destination, waypoints = []) {
69
+ const originKey = `${origin.latitude},${origin.longitude}`;
70
+ const destinationKey = `${destination.latitude},${destination.longitude}`;
71
+ let keyData = { origin: originKey, destination: destinationKey, waypoints: [] };
72
+ if (waypoints && waypoints.length > 0) {
73
+ keyData.waypoints = waypoints.map(point => `${point.latitude},${point.longitude}`).sort();
74
+ }
75
+ return (0, crypto_1.createHash)('md5').update(JSON.stringify(keyData)).digest('hex');
76
+ }
77
+ async acquireDistributedLock(key, ttl = 10) {
78
+ const token = (0, crypto_1.randomBytes)(16).toString('hex');
79
+ const lockKey = `lock:${key}`;
80
+ const result = await this.redisService.redisClient.set(lockKey, token, 'EX', ttl, 'NX');
81
+ return result ? { token, lockKey } : null;
82
+ }
83
+ async releaseDistributedLock(lockKey, token) {
84
+ const lua = `
85
+ if redis.call("get", KEYS[1]) == ARGV[1] then
86
+ return redis.call("del", KEYS[1])
87
+ else
88
+ return 0
89
+ end
90
+ `;
91
+ return this.redisService.redisClient.eval(lua, 1, lockKey, token);
92
+ }
93
+ async logApiUsage(endpoint, cacheHit = false, metadata = {}, responseTime, error) {
94
+ try {
95
+ await this.logModel.create({
96
+ endpoint,
97
+ cacheHit,
98
+ error: error ? error.message : null,
99
+ responseTime: responseTime,
100
+ metadata: {
101
+ origin: metadata.origin || null,
102
+ destination: metadata.destination || null,
103
+ waypoints: metadata.waypoints || null,
104
+ ipAddress: metadata.ipAddress || null,
105
+ userAgent: metadata.userAgent || null,
106
+ },
107
+ });
108
+ }
109
+ catch (logError) {
110
+ console.error('Failed to log API usage:', logError);
111
+ }
47
112
  }
113
+ clearRouteCache = async (origin, destination, waypoints = []) => {
114
+ const cacheKey = waypoints
115
+ ? `distance_waypoints:${this.createCacheKey(origin, destination, waypoints)}`
116
+ : `distance:${this.createCacheKey(origin, destination)}`;
117
+ return await this.redisService.deleteCachedObject(cacheKey);
118
+ };
119
+ getCacheStats = async () => {
120
+ const keys = await this.redisService.redisClient.keys('distance*');
121
+ return {
122
+ totalCachedRoutes: keys.length,
123
+ cacheKeys: keys,
124
+ };
125
+ };
48
126
  async getDistanceInfo(origin, destination) {
127
+ const startTime = Date.now();
128
+ const cacheKey = `distance:${this.createCacheKey(origin, destination)}`;
129
+ const cacheTTL = 3600;
130
+ try {
131
+ const cachedData = await this.redisService.getCachedObject(cacheKey);
132
+ if (cachedData) {
133
+ const responseTime = Date.now() - startTime;
134
+ await this.logApiUsage('DistanceInfoGoogle', true, {
135
+ origin,
136
+ destination,
137
+ }, responseTime);
138
+ return cachedData;
139
+ }
140
+ const lock = await this.acquireDistributedLock(cacheKey);
141
+ try {
142
+ const cachedDataAfterLock = await this.redisService.getCachedObject(cacheKey);
143
+ if (cachedDataAfterLock) {
144
+ const responseTime = Date.now() - startTime;
145
+ await this.logApiUsage('DistanceInfoGoogle', true, {
146
+ origin,
147
+ destination,
148
+ }, responseTime);
149
+ return cachedDataAfterLock;
150
+ }
151
+ const result = await this.getDistanceInfoFromGoogle(origin, destination);
152
+ await this.redisService.cacheObject(cacheKey, result, cacheTTL);
153
+ const responseTime = Date.now() - startTime;
154
+ await this.logApiUsage('DistanceInfoGoogle', false, {
155
+ origin,
156
+ destination,
157
+ }, responseTime);
158
+ return result;
159
+ }
160
+ finally {
161
+ if (lock) {
162
+ await this.releaseDistributedLock(lock.lockKey, lock.token);
163
+ }
164
+ }
165
+ }
166
+ catch (error) {
167
+ const responseTime = Date.now() - startTime;
168
+ await this.logApiUsage('DistanceInfoGoogle', false, {
169
+ origin,
170
+ destination,
171
+ }, responseTime, error);
172
+ throw new server_1.TRPCError({
173
+ code: 'INTERNAL_SERVER_ERROR',
174
+ message: 'Failed to fetch distance information from Maps API.',
175
+ });
176
+ }
177
+ }
178
+ async getDistanceInfoFromGoogle(origin, destination) {
49
179
  try {
50
180
  const url = `https://maps.googleapis.com/maps/api/directions/json?origin=${origin.latitude}, ${origin.longitude}&destination=${destination.latitude}, ${destination.longitude}&key=${this._apiKey}&mode=DRIVING`;
51
181
  const { data } = await axios_1.default.get(url);
52
182
  const legs = data?.routes[0]?.legs[0];
53
183
  const distance = legs?.distance;
54
184
  const duration = legs?.duration;
185
+ if (!distance || !duration) {
186
+ throw new server_1.TRPCError({
187
+ code: 'INTERNAL_SERVER_ERROR',
188
+ message: 'No path exists from origin to destination.',
189
+ });
190
+ }
55
191
  return { distance, duration };
56
192
  }
57
193
  catch (error) {
@@ -63,6 +199,62 @@ class GoogleMapsService {
63
199
  }
64
200
  }
65
201
  async getWaypointsDistanceInfo(origin, destination, waypoints) {
202
+ const startTime = Date.now();
203
+ const cacheKey = `distance_waypoints:${this.createCacheKey(origin, destination, waypoints)}`;
204
+ const cacheTTL = 3600;
205
+ try {
206
+ const cachedData = await this.redisService.getCachedObject(cacheKey);
207
+ if (cachedData) {
208
+ const responseTime = Date.now() - startTime;
209
+ await this.logApiUsage('DistanceInfoGoogleWithWayPoints', true, {
210
+ origin,
211
+ destination,
212
+ waypoints,
213
+ }, responseTime);
214
+ return cachedData;
215
+ }
216
+ const lock = await this.acquireDistributedLock(cacheKey);
217
+ try {
218
+ const cachedDataAfterLock = await this.redisService.getCachedObject(cacheKey);
219
+ if (cachedDataAfterLock) {
220
+ const responseTime = Date.now() - startTime;
221
+ await this.logApiUsage('DistanceInfoGoogleWithWayPoints', true, {
222
+ origin,
223
+ destination,
224
+ waypoints,
225
+ }, responseTime);
226
+ return cachedDataAfterLock;
227
+ }
228
+ const result = await this.getWaypointsDistanceInfoFromGoogle(origin, destination, waypoints);
229
+ await this.redisService.cacheObject(cacheKey, result, cacheTTL);
230
+ const responseTime = Date.now() - startTime;
231
+ await this.logApiUsage('DistanceInfoGoogleWithWayPoints', false, {
232
+ origin,
233
+ destination,
234
+ waypoints,
235
+ }, responseTime);
236
+ return result;
237
+ }
238
+ finally {
239
+ if (lock) {
240
+ await this.releaseDistributedLock(lock.lockKey, lock.token);
241
+ }
242
+ }
243
+ }
244
+ catch (error) {
245
+ const responseTime = Date.now() - startTime;
246
+ await this.logApiUsage('DistanceInfoGoogleWithWayPoints', false, {
247
+ origin,
248
+ destination,
249
+ waypoints,
250
+ }, responseTime, error);
251
+ throw new server_1.TRPCError({
252
+ code: 'INTERNAL_SERVER_ERROR',
253
+ message: 'Failed to fetch waypoint distance information from Maps API.',
254
+ });
255
+ }
256
+ }
257
+ async getWaypointsDistanceInfoFromGoogle(origin, destination, waypoints) {
66
258
  try {
67
259
  const waypointsStr = waypoints.map(point => `${point.latitude},${point.longitude}`).join('|');
68
260
  const url = `https://maps.googleapis.com/maps/api/directions/json?origin=${origin.latitude},${origin.longitude}&destination=${destination.latitude},${destination.longitude}&waypoints=${waypointsStr}&key=${this._apiKey}&mode=DRIVING`;
@@ -87,6 +279,12 @@ class GoogleMapsService {
87
279
  text: `${Math.round(totalDuration / 60)} mins`,
88
280
  value: totalDuration,
89
281
  };
282
+ if (!distance || !duration) {
283
+ throw new server_1.TRPCError({
284
+ code: 'INTERNAL_SERVER_ERROR',
285
+ message: 'No path exists from origin to destination.',
286
+ });
287
+ }
90
288
  return { distance, duration, legs, overviewPolyline };
91
289
  }
92
290
  catch (error) {
@@ -97,6 +295,10 @@ class GoogleMapsService {
97
295
  });
98
296
  }
99
297
  }
100
- }
298
+ };
101
299
  exports.GoogleMapsService = GoogleMapsService;
300
+ exports.GoogleMapsService = GoogleMapsService = __decorate([
301
+ __param(0, (0, typedi_1.Inject)(() => redis_1.RedisService)),
302
+ __metadata("design:paramtypes", [redis_1.RedisService, String])
303
+ ], GoogleMapsService);
102
304
  //# sourceMappingURL=google-maps.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"google-maps.js","sourceRoot":"/","sources":["libraries/map/providers/google-maps.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kDAA0B;AAU1B,2DAA6C;AAC7C,yCAAyC;AAEzC,MAAa,iBAAiB;IACrB,OAAO,CAAqB;IAEpC,YAAY,MAAc;QACzB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACvB,CAAC;IAEM,KAAK,CAAC,eAAe,CAAC,MAAmB,EAAE,WAAwB;QACzE,IAAI,CAAC;YACJ,MAAM,GAAG,GAAG,+DAA+D,MAAM,CAAC,QAAQ,KAAK,MAAM,CAAC,SAAS,gBAAgB,WAAW,CAAC,QAAQ,KAAK,WAAW,CAAC,SAAS,QAAQ,IAAI,CAAC,OAAO,eAAe,CAAC;YAEjN,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,eAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAEtC,MAAM,IAAI,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;YAEtC,MAAM,QAAQ,GAAG,IAAI,EAAE,QAAQ,CAAC;YAChC,MAAM,QAAQ,GAAG,IAAI,EAAE,QAAQ,CAAC;YAEhC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,OAAO,CAAC,KAAK,CAAC,6BAA6B,KAAK,EAAE,CAAC,CAAC;YACpD,MAAM,IAAI,kBAAS,CAAC;gBACnB,IAAI,EAAE,uBAAuB;gBAC7B,OAAO,EAAE,4DAA4D;aACrE,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;IAEM,KAAK,CAAC,wBAAwB,CACpC,MAAmB,EACnB,WAAwB,EACxB,SAA6B;QAE7B,IAAI,CAAC;YACJ,MAAM,YAAY,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAE9F,MAAM,GAAG,GAAG,+DAA+D,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,SAAS,gBAAgB,WAAW,CAAC,QAAQ,IAAI,WAAW,CAAC,SAAS,cAAc,YAAY,QAAQ,IAAI,CAAC,OAAO,eAAe,CAAC;YAEzO,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,eAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAEtC,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;YAE/B,MAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,EAAE,MAAM,CAAC,CAAC;YAE5E,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAmD,EAAE,EAAE;gBAC7F,MAAM,gBAAgB,GAAG,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;gBAE9F,OAAO;oBACN,QAAQ,EAAE,GAAG,CAAC,QAAQ;oBACtB,QAAQ,EAAE,GAAG,CAAC,QAAQ;oBACtB,gBAAgB;iBAChB,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,MAAM,aAAa,GAAG,IAAI,EAAE,MAAM,CACjC,CAAC,GAAQ,EAAE,IAAkC,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,EAC3E,CAAC,CACD,CAAC;YACF,MAAM,QAAQ,GAAG;gBAChB,IAAI,EAAE,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;gBAC/C,KAAK,EAAE,aAAa;aACpB,CAAC;YAEF,MAAM,aAAa,GAAG,IAAI,EAAE,MAAM,CACjC,CAAC,GAAQ,EAAE,IAAkC,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,EAC3E,CAAC,CACD,CAAC;YACF,MAAM,QAAQ,GAAG;gBAChB,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,EAAE,CAAC,OAAO;gBAC9C,KAAK,EAAE,aAAa;aACpB,CAAC;YAEF,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,OAAO,CAAC,KAAK,CAAC,sCAAsC,KAAK,EAAE,CAAC,CAAC;YAC7D,MAAM,IAAI,kBAAS,CAAC;gBACnB,IAAI,EAAE,uBAAuB;gBAC7B,OAAO,EAAE,qEAAqE;aAC9E,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;CACD;AAjFD,8CAiFC","sourcesContent":["import axios from 'axios';\nimport {\n\tIMapService,\n\tICoordinate,\n\tIDistance,\n\tIDuration,\n\tILeg,\n\tIDistanceInfo,\n\tIWaypointDistanceInfo,\n} from '../interfaces/IMapService';\nimport * as polyline from '@mapbox/polyline';\nimport { TRPCError } from '@trpc/server';\n\nexport class GoogleMapsService implements IMapService {\n\tprivate _apiKey: string | undefined;\n\n\tconstructor(apiKey: string) {\n\t\tthis._apiKey = apiKey;\n\t}\n\n\tpublic async getDistanceInfo(origin: ICoordinate, destination: ICoordinate): Promise<IDistanceInfo> {\n\t\ttry {\n\t\t\tconst url = `https://maps.googleapis.com/maps/api/directions/json?origin=${origin.latitude}, ${origin.longitude}&destination=${destination.latitude}, ${destination.longitude}&key=${this._apiKey}&mode=DRIVING`;\n\n\t\t\tconst { data } = await axios.get(url);\n\n\t\t\tconst legs = data?.routes[0]?.legs[0];\n\n\t\t\tconst distance = legs?.distance;\n\t\t\tconst duration = legs?.duration;\n\n\t\t\treturn { distance, duration };\n\t\t} catch (error) {\n\t\t\tconsole.error(`Error in getDistanceInfo: ${error}`);\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'INTERNAL_SERVER_ERROR',\n\t\t\t\tmessage: 'Failed to fetch distance information from Google Maps API.',\n\t\t\t});\n\t\t}\n\t}\n\n\tpublic async getWaypointsDistanceInfo(\n\t\torigin: ICoordinate,\n\t\tdestination: ICoordinate,\n\t\twaypoints: Array<ICoordinate>\n\t): Promise<IWaypointDistanceInfo> {\n\t\ttry {\n\t\t\tconst waypointsStr = waypoints.map(point => `${point.latitude},${point.longitude}`).join('|');\n\n\t\t\tconst url = `https://maps.googleapis.com/maps/api/directions/json?origin=${origin.latitude},${origin.longitude}&destination=${destination.latitude},${destination.longitude}&waypoints=${waypointsStr}&key=${this._apiKey}&mode=DRIVING`;\n\n\t\t\tconst { data } = await axios.get(url);\n\n\t\t\tconst routes = data?.routes[0];\n\n\t\t\tconst overviewPolyline = polyline.decode(routes?.overview_polyline?.points);\n\n\t\t\tconst legs = (routes?.legs ?? []).map((leg: { steps: any[]; distance: any; duration: any }) => {\n\t\t\t\tconst overviewPolyline = leg?.steps?.flatMap(step => polyline.decode(step?.polyline?.points));\n\n\t\t\t\treturn {\n\t\t\t\t\tdistance: leg.distance,\n\t\t\t\t\tduration: leg.duration,\n\t\t\t\t\toverviewPolyline,\n\t\t\t\t};\n\t\t\t});\n\n\t\t\tconst totalDistance = legs?.reduce(\n\t\t\t\t(acc: any, curr: { distance: { value: any } }) => acc + curr.distance.value,\n\t\t\t\t0\n\t\t\t);\n\t\t\tconst distance = {\n\t\t\t\ttext: `${(totalDistance / 1000).toFixed(2)} km`,\n\t\t\t\tvalue: totalDistance,\n\t\t\t};\n\n\t\t\tconst totalDuration = legs?.reduce(\n\t\t\t\t(acc: any, curr: { duration: { value: any } }) => acc + curr.duration.value,\n\t\t\t\t0\n\t\t\t);\n\t\t\tconst duration = {\n\t\t\t\ttext: `${Math.round(totalDuration / 60)} mins`,\n\t\t\t\tvalue: totalDuration,\n\t\t\t};\n\n\t\t\treturn { distance, duration, legs, overviewPolyline };\n\t\t} catch (error) {\n\t\t\tconsole.error(`Error in getWaypointsDistanceInfo: ${error}`);\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'INTERNAL_SERVER_ERROR',\n\t\t\t\tmessage: 'Failed to fetch waypoint distance information from Google Maps API.',\n\t\t\t});\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"google-maps.js","sourceRoot":"/","sources":["libraries/map/providers/google-maps.ts"],"names":[],"mappings":"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","sourcesContent":["import axios from 'axios';\nimport {\n\tIMapService,\n\tICoordinate,\n\tIDistance,\n\tIDuration,\n\tILeg,\n\tIDistanceInfo,\n\tIWaypointDistanceInfo,\n} from '../interfaces/IMapService';\nimport * as polyline from '@mapbox/polyline';\nimport { TRPCError } from '@trpc/server';\nimport { RedisService } from '../../redis';\nimport { createHash, randomBytes } from 'crypto';\nimport { Inject } from 'typedi';\nimport { GoogleMapsUsageModel } from '../../mongo/models';\n\nexport class GoogleMapsService implements IMapService {\n\tprivate _apiKey: string | undefined;\n\tprivate logModel: typeof GoogleMapsUsageModel;\n\n\tconstructor(\n\t\t@Inject(() => RedisService) private redisService: RedisService,\n\t\tapiKey: string\n\t) {\n\t\tthis._apiKey = apiKey;\n\t\tthis.logModel = GoogleMapsUsageModel as typeof GoogleMapsUsageModel;\n\t}\n\n\tprivate createCacheKey(origin: ICoordinate, destination: ICoordinate, waypoints: ICoordinate[] = []) {\n\t\tconst originKey = `${origin.latitude},${origin.longitude}`;\n\t\tconst destinationKey = `${destination.latitude},${destination.longitude}`;\n\n\t\tlet keyData = { origin: originKey, destination: destinationKey, waypoints: [] as string[] };\n\n\t\tif (waypoints && waypoints.length > 0) {\n\t\t\tkeyData.waypoints = waypoints.map(point => `${point.latitude},${point.longitude}`).sort();\n\t\t}\n\n\t\treturn createHash('md5').update(JSON.stringify(keyData)).digest('hex');\n\t}\n\n\tprivate async acquireDistributedLock(key: string, ttl = 10) {\n\t\tconst token = randomBytes(16).toString('hex');\n\t\tconst lockKey = `lock:${key}`;\n\n\t\tconst result = await this.redisService.redisClient.set(lockKey, token, 'EX', ttl, 'NX');\n\t\treturn result ? { token, lockKey } : null;\n\t}\n\n\tprivate async releaseDistributedLock(lockKey: string, token: string) {\n\t\tconst lua = `\n if redis.call(\"get\", KEYS[1]) == ARGV[1] then\n return redis.call(\"del\", KEYS[1])\n else\n return 0\n end\n `;\n\t\treturn this.redisService.redisClient.eval(lua, 1, lockKey, token);\n\t}\n\n\tprivate async logApiUsage(\n\t\tendpoint: string,\n\t\tcacheHit = false,\n\t\tmetadata: {\n\t\t\torigin?: ICoordinate;\n\t\t\tdestination?: ICoordinate;\n\t\t\twaypoints?: ICoordinate[];\n\t\t\tipAddress?: string;\n\t\t\tuserAgent?: string;\n\t\t} = {},\n\t\tresponseTime: number,\n\t\terror?: Error\n\t) {\n\t\ttry {\n\t\t\tawait this.logModel.create({\n\t\t\t\tendpoint,\n\t\t\t\tcacheHit,\n\t\t\t\terror: error ? error.message : null,\n\t\t\t\tresponseTime: responseTime,\n\t\t\t\tmetadata: {\n\t\t\t\t\torigin: metadata.origin || null,\n\t\t\t\t\tdestination: metadata.destination || null,\n\t\t\t\t\twaypoints: metadata.waypoints || null,\n\t\t\t\t\tipAddress: metadata.ipAddress || null,\n\t\t\t\t\tuserAgent: metadata.userAgent || null,\n\t\t\t\t},\n\t\t\t});\n\t\t} catch (logError) {\n\t\t\tconsole.error('Failed to log API usage:', logError);\n\t\t}\n\t}\n\n\tprivate clearRouteCache = async (origin: ICoordinate, destination: ICoordinate, waypoints = []) => {\n\t\tconst cacheKey = waypoints\n\t\t\t? `distance_waypoints:${this.createCacheKey(origin, destination, waypoints)}`\n\t\t\t: `distance:${this.createCacheKey(origin, destination)}`;\n\n\t\treturn await this.redisService.deleteCachedObject(cacheKey);\n\t};\n\n\tprivate getCacheStats = async () => {\n\t\tconst keys = await this.redisService.redisClient.keys('distance*');\n\t\treturn {\n\t\t\ttotalCachedRoutes: keys.length,\n\t\t\tcacheKeys: keys,\n\t\t};\n\t};\n\n\tpublic async getDistanceInfo(origin: ICoordinate, destination: ICoordinate): Promise<IDistanceInfo> {\n\t\tconst startTime = Date.now();\n\t\tconst cacheKey = `distance:${this.createCacheKey(origin, destination)}`;\n\t\tconst cacheTTL = 3600;\n\n\t\ttry {\n\t\t\tconst cachedData: IDistanceInfo | undefined = await this.redisService.getCachedObject(cacheKey);\n\t\t\tif (cachedData) {\n\t\t\t\tconst responseTime = Date.now() - startTime;\n\t\t\t\tawait this.logApiUsage(\n\t\t\t\t\t'DistanceInfoGoogle',\n\t\t\t\t\ttrue,\n\t\t\t\t\t{\n\t\t\t\t\t\torigin,\n\t\t\t\t\t\tdestination,\n\t\t\t\t\t},\n\t\t\t\t\tresponseTime\n\t\t\t\t);\n\t\t\t\treturn cachedData;\n\t\t\t}\n\n\t\t\tconst lock = await this.acquireDistributedLock(cacheKey);\n\n\t\t\ttry {\n\t\t\t\tconst cachedDataAfterLock: IDistanceInfo | undefined =\n\t\t\t\t\tawait this.redisService.getCachedObject(cacheKey);\n\t\t\t\tif (cachedDataAfterLock) {\n\t\t\t\t\tconst responseTime = Date.now() - startTime;\n\t\t\t\t\tawait this.logApiUsage(\n\t\t\t\t\t\t'DistanceInfoGoogle',\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\torigin,\n\t\t\t\t\t\t\tdestination,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tresponseTime\n\t\t\t\t\t);\n\t\t\t\t\treturn cachedDataAfterLock;\n\t\t\t\t}\n\n\t\t\t\tconst result = await this.getDistanceInfoFromGoogle(origin, destination);\n\n\t\t\t\tawait this.redisService.cacheObject(cacheKey, result, cacheTTL);\n\n\t\t\t\tconst responseTime = Date.now() - startTime;\n\t\t\t\tawait this.logApiUsage(\n\t\t\t\t\t'DistanceInfoGoogle',\n\t\t\t\t\tfalse,\n\t\t\t\t\t{\n\t\t\t\t\t\torigin,\n\t\t\t\t\t\tdestination,\n\t\t\t\t\t},\n\t\t\t\t\tresponseTime\n\t\t\t\t);\n\n\t\t\t\treturn result;\n\t\t\t} finally {\n\t\t\t\tif (lock) {\n\t\t\t\t\tawait this.releaseDistributedLock(lock.lockKey, lock.token);\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error: any) {\n\t\t\tconst responseTime = Date.now() - startTime;\n\t\t\tawait this.logApiUsage(\n\t\t\t\t'DistanceInfoGoogle',\n\t\t\t\tfalse,\n\t\t\t\t{\n\t\t\t\t\torigin,\n\t\t\t\t\tdestination,\n\t\t\t\t},\n\t\t\t\tresponseTime,\n\t\t\t\terror\n\t\t\t);\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'INTERNAL_SERVER_ERROR',\n\t\t\t\tmessage: 'Failed to fetch distance information from Maps API.',\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async getDistanceInfoFromGoogle(\n\t\torigin: ICoordinate,\n\t\tdestination: ICoordinate\n\t): Promise<IDistanceInfo> {\n\t\ttry {\n\t\t\tconst url = `https://maps.googleapis.com/maps/api/directions/json?origin=${origin.latitude}, ${origin.longitude}&destination=${destination.latitude}, ${destination.longitude}&key=${this._apiKey}&mode=DRIVING`;\n\n\t\t\tconst { data } = await axios.get(url);\n\n\t\t\tconst legs = data?.routes[0]?.legs[0];\n\n\t\t\tconst distance = legs?.distance;\n\t\t\tconst duration = legs?.duration;\n\n\t\t\tif (!distance || !duration) {\n\t\t\t\tthrow new TRPCError({\n\t\t\t\t\tcode: 'INTERNAL_SERVER_ERROR',\n\t\t\t\t\tmessage: 'No path exists from origin to destination.',\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn { distance, duration };\n\t\t} catch (error) {\n\t\t\tconsole.error(`Error in getDistanceInfo: ${error}`);\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'INTERNAL_SERVER_ERROR',\n\t\t\t\tmessage: 'Failed to fetch distance information from Google Maps API.',\n\t\t\t});\n\t\t}\n\t}\n\n\tpublic async getWaypointsDistanceInfo(\n\t\torigin: ICoordinate,\n\t\tdestination: ICoordinate,\n\t\twaypoints: Array<ICoordinate>\n\t): Promise<IWaypointDistanceInfo> {\n\t\tconst startTime = Date.now();\n\t\tconst cacheKey = `distance_waypoints:${this.createCacheKey(origin, destination, waypoints)}`;\n\t\tconst cacheTTL = 3600;\n\n\t\ttry {\n\t\t\tconst cachedData: IWaypointDistanceInfo | undefined = await this.redisService.getCachedObject(cacheKey);\n\t\t\tif (cachedData) {\n\t\t\t\tconst responseTime = Date.now() - startTime;\n\t\t\t\tawait this.logApiUsage(\n\t\t\t\t\t'DistanceInfoGoogleWithWayPoints',\n\t\t\t\t\ttrue,\n\t\t\t\t\t{\n\t\t\t\t\t\torigin,\n\t\t\t\t\t\tdestination,\n\t\t\t\t\t\twaypoints,\n\t\t\t\t\t},\n\t\t\t\t\tresponseTime\n\t\t\t\t);\n\t\t\t\treturn cachedData;\n\t\t\t}\n\n\t\t\tconst lock = await this.acquireDistributedLock(cacheKey);\n\n\t\t\ttry {\n\t\t\t\tconst cachedDataAfterLock: IWaypointDistanceInfo | undefined =\n\t\t\t\t\tawait this.redisService.getCachedObject(cacheKey);\n\t\t\t\tif (cachedDataAfterLock) {\n\t\t\t\t\tconst responseTime = Date.now() - startTime;\n\t\t\t\t\tawait this.logApiUsage(\n\t\t\t\t\t\t'DistanceInfoGoogleWithWayPoints',\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\torigin,\n\t\t\t\t\t\t\tdestination,\n\t\t\t\t\t\t\twaypoints,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tresponseTime\n\t\t\t\t\t);\n\t\t\t\t\treturn cachedDataAfterLock;\n\t\t\t\t}\n\n\t\t\t\tconst result = await this.getWaypointsDistanceInfoFromGoogle(origin, destination, waypoints);\n\n\t\t\t\tawait this.redisService.cacheObject(cacheKey, result, cacheTTL);\n\n\t\t\t\tconst responseTime = Date.now() - startTime;\n\t\t\t\tawait this.logApiUsage(\n\t\t\t\t\t'DistanceInfoGoogleWithWayPoints',\n\t\t\t\t\tfalse,\n\t\t\t\t\t{\n\t\t\t\t\t\torigin,\n\t\t\t\t\t\tdestination,\n\t\t\t\t\t\twaypoints,\n\t\t\t\t\t},\n\t\t\t\t\tresponseTime\n\t\t\t\t);\n\n\t\t\t\treturn result;\n\t\t\t} finally {\n\t\t\t\tif (lock) {\n\t\t\t\t\tawait this.releaseDistributedLock(lock.lockKey, lock.token);\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error: any) {\n\t\t\tconst responseTime = Date.now() - startTime;\n\t\t\tawait this.logApiUsage(\n\t\t\t\t'DistanceInfoGoogleWithWayPoints',\n\t\t\t\tfalse,\n\t\t\t\t{\n\t\t\t\t\torigin,\n\t\t\t\t\tdestination,\n\t\t\t\t\twaypoints,\n\t\t\t\t},\n\t\t\t\tresponseTime,\n\t\t\t\terror\n\t\t\t);\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'INTERNAL_SERVER_ERROR',\n\t\t\t\tmessage: 'Failed to fetch waypoint distance information from Maps API.',\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async getWaypointsDistanceInfoFromGoogle(\n\t\torigin: ICoordinate,\n\t\tdestination: ICoordinate,\n\t\twaypoints: Array<ICoordinate>\n\t): Promise<IWaypointDistanceInfo> {\n\t\ttry {\n\t\t\tconst waypointsStr = waypoints.map(point => `${point.latitude},${point.longitude}`).join('|');\n\n\t\t\tconst url = `https://maps.googleapis.com/maps/api/directions/json?origin=${origin.latitude},${origin.longitude}&destination=${destination.latitude},${destination.longitude}&waypoints=${waypointsStr}&key=${this._apiKey}&mode=DRIVING`;\n\n\t\t\tconst { data } = await axios.get(url);\n\n\t\t\tconst routes = data?.routes[0];\n\n\t\t\tconst overviewPolyline = polyline.decode(routes?.overview_polyline?.points);\n\n\t\t\tconst legs = (routes?.legs ?? []).map((leg: { steps: any[]; distance: any; duration: any }) => {\n\t\t\t\tconst overviewPolyline = leg?.steps?.flatMap(step => polyline.decode(step?.polyline?.points));\n\n\t\t\t\treturn {\n\t\t\t\t\tdistance: leg.distance,\n\t\t\t\t\tduration: leg.duration,\n\t\t\t\t\toverviewPolyline,\n\t\t\t\t};\n\t\t\t});\n\n\t\t\tconst totalDistance = legs?.reduce(\n\t\t\t\t(acc: any, curr: { distance: { value: any } }) => acc + curr.distance.value,\n\t\t\t\t0\n\t\t\t);\n\t\t\tconst distance = {\n\t\t\t\ttext: `${(totalDistance / 1000).toFixed(2)} km`,\n\t\t\t\tvalue: totalDistance,\n\t\t\t};\n\n\t\t\tconst totalDuration = legs?.reduce(\n\t\t\t\t(acc: any, curr: { duration: { value: any } }) => acc + curr.duration.value,\n\t\t\t\t0\n\t\t\t);\n\t\t\tconst duration = {\n\t\t\t\ttext: `${Math.round(totalDuration / 60)} mins`,\n\t\t\t\tvalue: totalDuration,\n\t\t\t};\n\n\t\t\tif (!distance || !duration) {\n\t\t\t\tthrow new TRPCError({\n\t\t\t\t\tcode: 'INTERNAL_SERVER_ERROR',\n\t\t\t\t\tmessage: 'No path exists from origin to destination.',\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn { distance, duration, legs, overviewPolyline };\n\t\t} catch (error) {\n\t\t\tconsole.error(`Error in getWaypointsDistanceInfo: ${error}`);\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'INTERNAL_SERVER_ERROR',\n\t\t\t\tmessage: 'Failed to fetch waypoint distance information from Google Maps API.',\n\t\t\t});\n\t\t}\n\t}\n}\n"]}
@@ -0,0 +1,21 @@
1
+ import { TimeStamps } from '@typegoose/typegoose/lib/defaultClasses';
2
+ declare class Coordinate {
3
+ latitude: number;
4
+ longitude: number;
5
+ }
6
+ declare class Metadata {
7
+ origin?: Coordinate;
8
+ destination?: Coordinate;
9
+ waypoints?: Coordinate[];
10
+ ipAddress?: string;
11
+ userAgent?: string;
12
+ }
13
+ export declare class GoogleMapsUsage extends TimeStamps {
14
+ endpoint: string;
15
+ cacheHit: boolean;
16
+ error?: string;
17
+ responseTime?: number;
18
+ metadata?: Metadata;
19
+ }
20
+ declare const GoogleMapsUsageModel: import("@typegoose/typegoose").ReturnModelType<typeof GoogleMapsUsage, import("@typegoose/typegoose/lib/types").BeAnObject>;
21
+ export { GoogleMapsUsageModel };