garmin.js (3769B)
1 import {urlViaCorsProxy} from '~/lib/CORSProxy'; 2 3 import BaseService from './baseService'; 4 5 class GarminBase extends BaseService { 6 urlRe = /NOT IMPLEMENTED/u; 7 8 isOurUrl() { 9 return this.urlRe.test(this.origUrl); 10 } 11 } 12 13 function isResponseSuccess(xhr) { 14 return xhr.status === 200 || xhr.status === 403 || xhr.status === 404; 15 } 16 17 class GarminRoute extends GarminBase { 18 urlRe = /^https?:\/\/connect\.garmin\.com\/(?:modern|app)\/course\/(\d+)/u; 19 20 requestOptions() { 21 const m = this.urlRe.exec(this.origUrl); 22 const trackId = m[1]; 23 this.trackId = trackId; 24 return [ 25 { 26 url: urlViaCorsProxy(`https://connect.garmin.com/gc-api/course-service/course/${trackId}`), 27 options: {responseType: 'json', isResponseSuccess}, 28 }, 29 ]; 30 } 31 32 parseResponse(responses) { 33 const response = responses[0]; 34 if (response.status === 403) { 35 return [{error: 'Garmin Connect user disabled viewing this route'}]; 36 } 37 if (response.status === 404) { 38 return [{error: 'Garmin Connect route does not exist'}]; 39 } 40 let trackName = `Garmin Connect route ${this.trackId}`; 41 const data = response.responseJSON; 42 if (!data) { 43 return [{name: trackName, error: 'UNSUPPORTED'}]; 44 } 45 let points = null; 46 let tracks = []; 47 try { 48 if (data.coursePoints) { 49 points = data.coursePoints.map((pt) => ({name: pt.name, lat: pt.lat, lng: pt.lon})); 50 } 51 if (data.geoPoints) { 52 tracks = [data.geoPoints.map((obj) => ({lat: obj.latitude, lng: obj.longitude}))]; 53 } 54 } catch { 55 return [{name: trackName, error: 'UNSUPPORTED'}]; 56 } 57 trackName = data.courseName ? data.courseName : trackName; 58 return [ 59 { 60 name: trackName, 61 points, 62 tracks, 63 }, 64 ]; 65 } 66 } 67 68 class GarminActivity extends GarminBase { 69 urlRe = /^https?:\/\/connect\.garmin\.com\/(?:modern|app)\/activity\/(\d+)/u; 70 71 requestOptions() { 72 const m = this.urlRe.exec(this.origUrl); 73 const trackId = m[1]; 74 this.trackId = trackId; 75 return [ 76 { 77 url: urlViaCorsProxy(`https://connect.garmin.com/gc-api/activity-service/activity/${trackId}`), 78 options: {responseType: 'json', isResponseSuccess}, 79 }, 80 { 81 url: urlViaCorsProxy(`https://connect.garmin.com/gc-api/activity-service/activity/${trackId}/details`), 82 options: {responseType: 'json', isResponseSuccess}, 83 }, 84 ]; 85 } 86 87 parseResponse(responses) { 88 const [infoResponse, detailsResponse] = responses; 89 if (infoResponse.status === 403) { 90 return [{error: 'Garmin Connect user disabled viewing this activity'}]; 91 } 92 if (infoResponse.status === 404) { 93 return [{error: 'Garmin Connect activity does not exist'}]; 94 } 95 let trackName = `Garmin Connect activity ${this.trackId}`; 96 if (!infoResponse.responseJSON) { 97 return [{name: trackName, error: 'UNSUPPORTED'}]; 98 } 99 trackName = infoResponse.responseJSON.activityName || trackName; 100 let track; 101 try { 102 track = detailsResponse.responseJSON.geoPolylineDTO.polyline.map((obj) => ({lat: obj.lat, lng: obj.lon})); 103 } catch { 104 return [{name: trackName, error: 'UNSUPPORTED'}]; 105 } 106 107 return [ 108 { 109 name: trackName, 110 tracks: [track], 111 }, 112 ]; 113 } 114 } 115 116 export {GarminRoute, GarminActivity};
