UNPKG

strava-api-handler

Version:
220 lines (188 loc) 5.68 kB
'use strict'; var FormData = require('form-data'); var restApiHandler = require('rest-api-handler'); var Activity = require('./Activity.js'); var StravaException = require('./StravaException.js'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var FormData__default = /*#__PURE__*/_interopDefaultLegacy(FormData); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore global.FormData = FormData__default["default"]; function base64Encode(string) { if (typeof btoa !== 'undefined') { // eslint-disable-next-line no-undef return btoa(string); } return Buffer.from(string).toString('base64'); } class Api extends restApiHandler.Api { constructor(clientId, secret) { super('https://www.strava.com', [new restApiHandler.DefaultResponseProcessor(restApiHandler.DefaultApiException)], { 'content-Type': 'application/json' }); this.clientId = clientId; this.secret = secret; } setAccessToken(token) { this.accessToken = token; this.setDefaultHeader('Authorization', `Bearer ${token}`); } getAccessToken() { return this.accessToken; } // eslint-disable-next-line default-param-last getLoginUrl(redirectUri, scope = ['read'], approvalPrompt, state) { const parameters = { client_id: this.clientId, redirect_uri: redirectUri, response_type: 'code', scope: scope.join(','), ...(state ? { state } : {}), ...(approvalPrompt ? { approval_prompt: approvalPrompt } : {}) }; return `https://www.strava.com/oauth/authorize${restApiHandler.Api.convertParametersToUrl(parameters)}`; } async requestToken(parameters) { const { data } = await this.request(`oauth/token${restApiHandler.Api.convertParametersToUrl({ client_id: this.clientId, client_secret: this.secret, ...parameters })}`, 'POST', {}, { 'content-type': 'application/x-www-form-urlencoded', 'Authorization': `Basic ${base64Encode(`${this.clientId}:${this.secret}`)}` }); this.setAccessToken(data.access_token); return data; } requestAccessToken(code) { return this.requestToken({ code }); } refreshToken(token) { return this.requestToken({ grant_type: 'refresh_token', refresh_token: token }); } async getActivity(id) { const { data } = await this.get(`api/v3/activities/${id}`); return Activity.getFromApi(data); } async getStream(id, streams = []) { const { data } = await this.get(`api/v3/activities/${id}/streams`, { keys: streams.join(','), key_by_type: false }); const points = []; Object.keys(data).forEach(item => { data[item].data.forEach((value, key) => { if (!points[key]) { points[key] = {}; } points[key][item] = value; }); }); return points; } async getActivities(parameters) { const { after, before } = parameters; const { data } = await this.get(`api/v3/athlete/activities${restApiHandler.Api.convertParametersToUrl({ ...parameters, ...(after ? { after: typeof after === 'number' ? after : after.valueOf() / 1000 } : {}), ...(before ? { before: typeof before === 'number' ? before : before.valueOf() / 1000 } : {}) })}`); return data.map(activity => { return Activity.getFromApi(activity); }); } async processActivities( // eslint-disable-next-line default-param-last filter = {}, processor) { const activities = await this.getActivities(filter); const processorPromises = activities.map(activity => { return processor(activity); }); if (activities.length > 0) { const { page } = filter; processorPromises.push(...(await this.processActivities({ ...filter, page: page ? page + 1 : 2 }, processor))); } return Promise.all(processorPromises); } // eslint-disable-next-line complexity async uploadActivity(activity, fileContent, externalId, dataType = 'gpx') { const body = Api.convertData({ data_type: dataType, ...(activity.getTitle() != null ? { name: activity.getTitle() } : {}), ...(activity.getDescription() != null ? { description: activity.getDescription() } : {}), ...(activity.isCommute != null ? { commute: activity.isCommute ? 1 : 0 } : {}) }, Api.FORMATS.FORM_DATA); body.append('file', fileContent, { filename: `${externalId}.${dataType}` }); const contentType = this.getDefaultHeaders()['content-Type']; this.removeDefaultHeader('content-Type'); const { data } = await this.request('api/v3/uploads', 'POST', { body: body }); this.setDefaultHeader('content-Type', contentType); return data; } async getUploadStatus(uploadId) { const { data } = await this.get(`api/v3/uploads/${uploadId}`); if (data.error) { throw new StravaException(data.error); } return data; } async createActivity(activity) { const { data } = await this.post('api/v3/activities', activity.toApiObject()); return Activity.getFromApi(data); } async updateActivity(activity) { const { data } = await this.put(`api/v3/activities/${activity.getId()}`, activity.toApiObject()); return Activity.getFromApi(data); } async updateWeight(weight) { const { data } = await this.put('api/v3/athlete', { weight }); return data; } } module.exports = Api;