strava-v3
Advanced tools
Comparing version 2.0.10 to 2.1.0
292
index.d.ts
@@ -1,156 +0,266 @@ | ||
type Callback = (error: any, payload: any) => void; | ||
interface BaseArgs { | ||
access_token?: string; | ||
access_token?: string; | ||
} | ||
interface ApplicationBaseArgs { | ||
client_id: string; | ||
client_secret: string; | ||
} | ||
export interface PushSubscriptionRoutes { | ||
list(done?: Callback): Promise<any>; | ||
create(args: any, done?: Callback): Promise<any>; | ||
delete(args: any, done?: Callback): Promise<any>; | ||
list(done?: Callback): Promise<ListPushSubscriptionResponse[]>; | ||
create( | ||
args: CreatePushSubscriptionRouteArgs, | ||
done?: Callback | ||
): Promise<CreatePushSubscriptionResponse>; | ||
delete(args: DeletePushSubscriptionRouteArgs, done?: Callback): Promise<void>; | ||
} | ||
export interface ListPushSubscriptionResponse { | ||
id: number; | ||
resource_state: number; | ||
application_id: number; | ||
callback_url: string; | ||
created_at: Date; | ||
updated_at: Date; | ||
} | ||
export interface CreatePushSubscriptionResponse { | ||
id: number; | ||
} | ||
export interface CreatePushSubscriptionRouteArgs extends ApplicationBaseArgs { | ||
callback_url: string; | ||
verify_token: string; | ||
} | ||
export interface DeletePushSubscriptionRouteArgs extends ApplicationBaseArgs { | ||
id: string; | ||
} | ||
export interface UploadsRoutes { | ||
post(args: any, done?: Callback): Promise<any>; | ||
post(args: UploadRouteArgs, done?: Callback): Promise<UploadResponse>; | ||
} | ||
export interface UploadRouteArgs { | ||
file: Buffer; | ||
name: string; | ||
description?: string; | ||
trainer?: string; | ||
commute?: string; | ||
data_type: string; | ||
external_id: string; | ||
} | ||
export interface UploadResponse { | ||
id: string; | ||
id_str?: string; | ||
external_id?: string; | ||
error?: string; | ||
status?: string; | ||
activity_id?: string; | ||
} | ||
export interface SegmentsRoutes { | ||
get(args: any, done?: Callback): Promise<any>; | ||
listStarred(args: any, done?: Callback): Promise<any>; | ||
listEfforts(args: any, done?: Callback): Promise<any>; | ||
listLeaderboard(args: any, done?: Callback): Promise<any>; | ||
explore(args: any, done?: Callback): Promise<any>; | ||
get(args: any, done?: Callback): Promise<any>; | ||
listStarred(args: any, done?: Callback): Promise<any>; | ||
listEfforts(args: any, done?: Callback): Promise<any>; | ||
listLeaderboard(args: any, done?: Callback): Promise<any>; | ||
explore(args: any, done?: Callback): Promise<any>; | ||
} | ||
export interface SegmentEffortsRoutes { | ||
get(args: any, done?: Callback): Promise<any>; | ||
get(args: any, done?: Callback): Promise<any>; | ||
} | ||
export interface StreamsRoutes { | ||
activity(args: any, done?: Callback): Promise<any>; | ||
effort(args: any, done?: Callback): Promise<any>; | ||
segment(args: any, done?: Callback): Promise<any>; | ||
activity(args: any, done?: Callback): Promise<any>; | ||
effort(args: any, done?: Callback): Promise<any>; | ||
segment(args: any, done?: Callback): Promise<any>; | ||
} | ||
export interface RoutesRoutes { | ||
get(args: any, done?: Callback): Promise<any>; | ||
get(args: any, done?: Callback): Promise<any>; | ||
getFile(args: RouteFile, done?: Callback): Promise<any>; | ||
} | ||
export interface DetailRoute extends BaseArgs { | ||
id: string; | ||
} | ||
export interface RouteFile extends BaseArgs { | ||
id: string; | ||
file_type: string; | ||
} | ||
export interface GearRoutes { | ||
get(args: any, done?: Callback): Promise<any>; | ||
get(args: any, done?: Callback): Promise<any>; | ||
} | ||
export interface RunningRacesRoutes { | ||
get(args: any, done?: Callback): Promise<any>; | ||
listRaces(args: any, done?: Callback): Promise<any>; | ||
get(args: any, done?: Callback): Promise<any>; | ||
listRaces(args: any, done?: Callback): Promise<any>; | ||
} | ||
export interface ClubsRoutes { | ||
get(args: ClubsRoutesArgs, done?: Callback): Promise<any>; | ||
listMembers(args: ClubsRoutesListArgs, done?: Callback): Promise<any>; | ||
listActivities(args: ClubsRoutesListArgs, done?: Callback): Promise<ClubActivity[]>; | ||
listAnnouncements(args: ClubsRoutesListArgs, done?: Callback): Promise<any>; | ||
listEvents(args: ClubsRoutesListArgs, done?: Callback): Promise<any>; | ||
listAdmins(args: ClubsRoutesListArgs, done?: Callback): Promise<any>; | ||
joinClub(args: ClubsRoutesListArgs, done?: Callback): Promise<any>; | ||
leaveClub(args: ClubsRoutesListArgs, done?: Callback): Promise<any>; | ||
get(args: ClubsRoutesArgs, done?: Callback): Promise<any>; | ||
listMembers(args: ClubsRoutesListArgs, done?: Callback): Promise<any>; | ||
listActivities( | ||
args: ClubsRoutesListArgs, | ||
done?: Callback | ||
): Promise<ClubActivity[]>; | ||
listAnnouncements(args: ClubsRoutesListArgs, done?: Callback): Promise<any>; | ||
listEvents(args: ClubsRoutesListArgs, done?: Callback): Promise<any>; | ||
listAdmins(args: ClubsRoutesListArgs, done?: Callback): Promise<any>; | ||
joinClub(args: ClubsRoutesListArgs, done?: Callback): Promise<any>; | ||
leaveClub(args: ClubsRoutesListArgs, done?: Callback): Promise<any>; | ||
} | ||
export interface ClubsRoutesArgs extends BaseArgs { | ||
id: string; | ||
id: string; | ||
} | ||
export interface ClubsRoutesListArgs extends ClubsRoutesArgs { | ||
page?: number; | ||
per_page?: number; | ||
page?: number; | ||
per_page?: number; | ||
} | ||
export interface ClubActivity { | ||
resource_state: number; | ||
athlete: { | ||
resource_state: number; | ||
athlete: { | ||
resource_state: number; | ||
firstname: string; | ||
lastname: string; | ||
}; | ||
name: string; | ||
distance: number; | ||
moving_time: number; | ||
elapsed_time: number; | ||
total_elevation_gain: number; | ||
type: string; | ||
workout_type?: number | null; | ||
firstname: string; | ||
lastname: string; | ||
}; | ||
name: string; | ||
distance: number; | ||
moving_time: number; | ||
elapsed_time: number; | ||
total_elevation_gain: number; | ||
type: string; | ||
workout_type?: number | null; | ||
} | ||
export interface AthletesRoutes { | ||
get(args: any, done?: Callback): Promise<any>; | ||
stats(args: any, done?: Callback): Promise<any>; | ||
get(args: AthleteRouteArgs, done?: Callback): Promise<AthleteRouteResponse>; | ||
stats(args: any, done?: Callback): Promise<any>; | ||
} | ||
export interface AthleteRouteArgs extends BaseArgs { | ||
athlete_id: string; | ||
page?: number; | ||
offset?: number; | ||
} | ||
export interface AthleteRouteResponse { | ||
athlete: AthleteResponse; | ||
description?: string; | ||
distance?: number; | ||
elevation_gain?: number; | ||
id: string; | ||
id_str?: string; | ||
map?: PolylineMapResponse; | ||
name?: string; | ||
private: boolean; | ||
starred?: boolean; | ||
timestamp?: number; | ||
type?: number; | ||
sub_type?: number; | ||
created_at: Date; | ||
updated_at: Date; | ||
estimated_moving_time?: number; | ||
segments?: any[]; | ||
} | ||
export interface AthleteResponse { | ||
id: string; | ||
resource_state?: number; | ||
firstname?: string; | ||
lastname?: string; | ||
profile_medium?: string; | ||
profile?: string; | ||
city?: string; | ||
state?: string; | ||
country?: string; | ||
sex?: string; | ||
premium?: boolean; | ||
summit?: boolean; | ||
created_at: Date; | ||
updated_at: Date; | ||
} | ||
export interface PolylineMapResponse { | ||
id: string; | ||
polyline: string; | ||
summary_polyline: string; | ||
} | ||
export interface ActivitiesRoutes { | ||
get(args: any, done?: Callback): Promise<any>; | ||
create(args: any, done?: Callback): Promise<any>; | ||
update(args: any, done?: Callback): Promise<any>; | ||
listFriends(args: any, done?: Callback): Promise<any>; | ||
listZones(args: any, done?: Callback): Promise<any>; | ||
listLaps(args: any, done?: Callback): Promise<any>; | ||
listComments(args: any, done?: Callback): Promise<any>; | ||
listKudos(args: any, done?: Callback): Promise<any>; | ||
listPhotos(args: any, done?: Callback): Promise<any>; | ||
listRelated(args: any, done?: Callback): Promise<any>; | ||
get(args: any, done?: Callback): Promise<any>; | ||
create(args: any, done?: Callback): Promise<any>; | ||
update(args: any, done?: Callback): Promise<any>; | ||
listFriends(args: any, done?: Callback): Promise<any>; | ||
listZones(args: any, done?: Callback): Promise<any>; | ||
listLaps(args: any, done?: Callback): Promise<any>; | ||
listComments(args: any, done?: Callback): Promise<any>; | ||
listKudos(args: any, done?: Callback): Promise<any>; | ||
listPhotos(args: any, done?: Callback): Promise<any>; | ||
listRelated(args: any, done?: Callback): Promise<any>; | ||
} | ||
export interface AthleteRoutes { | ||
get(args: any, done?: Callback): Promise<any>; | ||
update(args: any, done?: Callback): Promise<any>; | ||
listActivities(args: any, done?: Callback): Promise<any>; | ||
listRoutes(args: any, done?: Callback): Promise<any>; | ||
listClubs(args: any, done?: Callback): Promise<any>; | ||
listZones(args: any, done?: Callback): Promise<any>; | ||
get(args: any, done?: Callback): Promise<any>; | ||
update(args: any, done?: Callback): Promise<any>; | ||
listActivities(args: any, done?: Callback): Promise<any>; | ||
listRoutes(args: any, done?: Callback): Promise<any>; | ||
listClubs(args: any, done?: Callback): Promise<any>; | ||
listZones(args: any, done?: Callback): Promise<any>; | ||
} | ||
export interface OAuthRoutes { | ||
getRequestAccessURL(args: any): Promise<any>; | ||
getToken(code: string, done?: Callback): Promise<any>; | ||
refreshToken(code: string): Promise<RefreshTokenResponse>; | ||
deauthorize(args: any, done?: Callback): Promise<any>; | ||
getRequestAccessURL(args: any): Promise<any>; | ||
getToken(code: string, done?: Callback): Promise<any>; | ||
refreshToken(code: string): Promise<RefreshTokenResponse>; | ||
deauthorize(args: any, done?: Callback): Promise<any>; | ||
} | ||
export interface RefreshTokenResponse { | ||
token_type: string; | ||
access_token: string; | ||
expires_at: number; | ||
expires_in: number; | ||
refresh_token: string; | ||
token_type: string; | ||
access_token: string; | ||
expires_at: number; | ||
expires_in: number; | ||
refresh_token: string; | ||
} | ||
export interface RateLimiting { | ||
exceeded(): boolean; | ||
fractionReached(): number; | ||
exceeded(): boolean; | ||
fractionReached(): number; | ||
} | ||
export interface AuthenticationConfig { | ||
access_token: string, | ||
client_id: string, | ||
client_secret: string, | ||
redirect_uri: string | ||
access_token: string; | ||
client_id: string; | ||
client_secret: string; | ||
redirect_uri: string; | ||
} | ||
export interface Strava { | ||
config(config: AuthenticationConfig): void; | ||
client(token: string): void; | ||
athlete: AthleteRoutes; | ||
athletes: AthletesRoutes; | ||
activities: ActivitiesRoutes; | ||
clubs: ClubsRoutes; | ||
gear: GearRoutes; | ||
segments: SegmentsRoutes; | ||
segmentEfforts: SegmentEffortsRoutes; | ||
pushSubscriptions: PushSubscriptionRoutes; | ||
streams: StreamsRoutes; | ||
uploads: UploadsRoutes; | ||
rateLimiting: RateLimiting; | ||
runningRaces: RunningRacesRoutes; | ||
routes: RoutesRoutes; | ||
oauth: OAuthRoutes; | ||
config(config: AuthenticationConfig): void; | ||
client(token: string): void; | ||
athlete: AthleteRoutes; | ||
athletes: AthletesRoutes; | ||
activities: ActivitiesRoutes; | ||
clubs: ClubsRoutes; | ||
gear: GearRoutes; | ||
segments: SegmentsRoutes; | ||
segmentEfforts: SegmentEffortsRoutes; | ||
pushSubscriptions: PushSubscriptionRoutes; | ||
streams: StreamsRoutes; | ||
uploads: UploadsRoutes; | ||
rateLimiting: RateLimiting; | ||
runningRaces: RunningRacesRoutes; | ||
routes: RoutesRoutes; | ||
oauth: OAuthRoutes; | ||
} | ||
@@ -157,0 +267,0 @@ |
@@ -9,2 +9,6 @@ const authenticator = require('./authenticator') | ||
oauth.getRequestAccessURL = function (args) { | ||
if (!authenticator.getRedirectUri() || !authenticator.getClientId()) { | ||
throw new Error('The redirect_uri or the client_id was not provided, you must provide both of them!') | ||
} | ||
var url = 'https://www.strava.com/oauth/authorize?' | ||
@@ -11,0 +15,0 @@ var oauthArgs = { |
@@ -12,6 +12,3 @@ var routes = function (client) { | ||
// require route id | ||
if (typeof args.id === 'undefined') { | ||
throw new Error('args must include an route id') | ||
} | ||
_requireRouteId(args) | ||
@@ -21,4 +18,27 @@ endpoint += args.id + '?' + qs | ||
} | ||
routes.prototype.getFile = function (args, done) { | ||
var endpoint = 'routes/' | ||
_requireRouteId(args) | ||
this._getFileHelper(endpoint, args, done) | ||
} | ||
//= ==== routes endpoint ===== | ||
//= ==== helpers ===== | ||
var _requireRouteId = function (args) { | ||
if (!args.id || typeof args.id !== 'string') { | ||
throw new Error('args must include a valid route id') | ||
} | ||
} | ||
routes.prototype._getFileHelper = function (endpoint, args, done) { | ||
var qs = this.client.getQS(_qsAllowedProps, args) | ||
endpoint += args.id + `/export_${args.file_type}` + '?' + qs | ||
return this.client.getEndpoint(endpoint, args, done) | ||
} | ||
//= ==== helpers ===== | ||
module.exports = routes |
{ | ||
"name": "strava-v3", | ||
"version": "2.0.10", | ||
"description": "Simple wrapper for strava v3 API", | ||
"version": "2.1.0", | ||
"description": "Simple wrapper for Strava v3 API", | ||
"main": "index.js", | ||
@@ -37,3 +37,3 @@ "types": "index.d.ts", | ||
"es6-promise": "^3.2.1", | ||
"eslint": "^6.4.0", | ||
"eslint": "^8.3.0", | ||
"eslint-config-standard": "^12.0.0", | ||
@@ -45,3 +45,3 @@ "eslint-plugin-import": "^2.17.3", | ||
"inquirer": "^7.0.0", | ||
"mocha": "^6.1.4", | ||
"mocha": "^9.1.3", | ||
"mock-fs": "^4.10.1", | ||
@@ -51,3 +51,3 @@ "nock": "^11.3.4", | ||
"sinon": "^1.17.4", | ||
"yargs": "^14.0.0" | ||
"yargs": "^17.3.0" | ||
}, | ||
@@ -54,0 +54,0 @@ "mocha": { |
@@ -314,3 +314,3 @@ | ||
* `strava.routes.getFile({ id: routeId, file_type: 'gpx' },done)` *file_type may also be 'tcx'* | ||
* `strava.routes.get(args,done)` | ||
@@ -317,0 +317,0 @@ |
#!/usr/bin/env node | ||
const inquirer = require('inquirer'); | ||
const fs = require('fs'); | ||
const argv = require('yargs').argv; | ||
const stravaConfig = './data/strava_config'; | ||
const stravaConfigTemplate = './strava_config'; | ||
const stravaApiUrl = 'https://www.strava.com/settings/api#_=_'; | ||
const inquirer = require('inquirer') | ||
const fs = require('fs') | ||
const argv = require('yargs').argv | ||
const stravaConfig = './data/strava_config' | ||
const stravaConfigTemplate = './strava_config' | ||
const stravaApiUrl = 'https://www.strava.com/settings/api#_=_' | ||
const strava = require('../index.js'); | ||
const strava = require('../index.js') | ||
@@ -14,76 +14,73 @@ /** | ||
*/ | ||
console.log('Before processing, you shall fill your strava config with client id and secret provided by Strava:\n' + stravaApiUrl); | ||
console.log('Before processing, you shall fill your strava config with client id and secret provided by Strava:\n' + stravaApiUrl) | ||
inquirer | ||
.prompt( | ||
[ | ||
{ | ||
type: 'input', | ||
name: 'clientId', | ||
message: 'What is your strava client id?', | ||
default: argv['client-id'] | ||
}, | ||
{ | ||
type: 'input', | ||
name: 'clientSecret', | ||
message: 'What is your strava client secret?', | ||
default: argv['client-secret'] | ||
} | ||
]) | ||
.then(function (answers) { | ||
// We copy the strava config file | ||
try { | ||
fs.mkdirSync('data') | ||
} catch (e) { | ||
// nothing | ||
} | ||
inquirer | ||
.prompt( | ||
[ | ||
{ | ||
type: 'input', | ||
name: 'clientId', | ||
message: 'What is your strava client id?', | ||
default: argv['client-id'], | ||
}, | ||
{ | ||
type: 'input', | ||
name: 'clientSecret', | ||
message: 'What is your strava client secret?', | ||
default: argv['client-secret'], | ||
} | ||
]) | ||
.then(function (answers) { | ||
var content = fs.readFileSync(stravaConfigTemplate) | ||
fs.writeFileSync(stravaConfig, content) | ||
// We copy the strava config file | ||
try { | ||
fs.mkdirSync('data'); | ||
} catch (e) { | ||
// nothing | ||
} | ||
// We open the default config file and inject the client_id and client secret | ||
// Without these informations in the config file the getRequestAccessURL would fail | ||
content = fs.readFileSync(stravaConfig) | ||
var config = JSON.parse(content) | ||
config.client_id = answers.clientId | ||
config.client_secret = answers.clientSecret | ||
config.access_token = 'to define' | ||
// You may need to make your callback URL | ||
// at Strava /settings/api temporarily match this | ||
config.redirect_uri = 'http://localhost' | ||
var content = fs.readFileSync(stravaConfigTemplate); | ||
fs.writeFileSync(stravaConfig, content); | ||
// We update the config file | ||
fs.writeFileSync(stravaConfig, JSON.stringify(config)) | ||
// We open the default config file and inject the client_id and client secret | ||
// Without these informations in the config file the getRequestAccessURL would fail | ||
content = fs.readFileSync(stravaConfig); | ||
var config = JSON.parse(content); | ||
config.client_id = answers.clientId; | ||
config.client_secret = answers.clientSecret; | ||
config.access_token = 'to define'; | ||
// You may need to make your callback URL | ||
// at Strava /settings/api temporarily match this | ||
config.redirect_uri = 'http://localhost'; | ||
// Generates the url to have full access | ||
var url = strava.oauth.getRequestAccessURL({ | ||
scope: 'activity:write,profile:write,read_all,profile:read_all,activity:read_all' | ||
}) | ||
// We have to grab the code manually in the browser and then copy/paste it into strava_config as "access_token" | ||
console.log('Connect to the following url and copy the code: ' + url) | ||
// We update the config file | ||
fs.writeFileSync(stravaConfig, JSON.stringify(config)); | ||
// Generates the url to have full access | ||
var url = strava.oauth.getRequestAccessURL({ | ||
scope:"activity:write,profile:write,read_all,profile:read_all,activity:read_all" | ||
}); | ||
// We have to grab the code manually in the browser and then copy/paste it into strava_config as "access_token" | ||
console.log('Connect to the following url and copy the code: ' + url); | ||
inquirer.prompt( | ||
[ | ||
{ | ||
type: 'input', | ||
name: 'code', | ||
message: 'Enter the code obtained from previous strava url (the code parameter in redirection url)' | ||
} | ||
]) | ||
.then(function (answers2) { | ||
if (!answers2.code) { | ||
console.log("no code provided") | ||
process.exit() | ||
} | ||
strava.oauth.getToken(answers2.code).then( result => { | ||
// We update the access token in strava conf file | ||
if (result.access_token === undefined) throw 'Problem with provided code: ' + JSON.stringify(result); | ||
config.access_token = result.access_token; | ||
fs.writeFileSync(stravaConfig, JSON.stringify(config)); | ||
}); | ||
}) | ||
.then(done => console.log("Done. Details written to data/strava_config.")) | ||
}); | ||
inquirer.prompt( | ||
[ | ||
{ | ||
type: 'input', | ||
name: 'code', | ||
message: 'Enter the code obtained from previous strava url (the code parameter in redirection url)' | ||
} | ||
]) | ||
.then(function (answers2) { | ||
if (!answers2.code) { | ||
console.log('no code provided') | ||
process.exit() | ||
} | ||
strava.oauth.getToken(answers2.code).then(result => { | ||
// We update the access token in strava conf file | ||
if (result.access_token === undefined) throw new Error('Problem with provided code: ' + JSON.stringify(result)) | ||
config.access_token = result.access_token | ||
fs.writeFileSync(stravaConfig, JSON.stringify(config)) | ||
}) | ||
}) | ||
.then(done => console.log('Done. Details written to data/strava_config.')) | ||
}) |
@@ -29,3 +29,27 @@ var should = require('should') | ||
}) | ||
it('should return the GPX file requested with the route information', function (done) { | ||
strava.routes.getFile({ id: _sampleRoute.id, file_type: 'gpx' }, function (err, payload) { | ||
if (!err) { | ||
should(typeof payload).be.a.String() | ||
} else { | ||
console.log(err) | ||
} | ||
done() | ||
}) | ||
}) | ||
it('should return the TCX file requested with the route information', function (done) { | ||
strava.routes.getFile({ id: _sampleRoute.id, file_type: 'tcx' }, function (err, payload) { | ||
if (!err) { | ||
should(typeof payload).be.a.String() | ||
} else { | ||
console.log(err) | ||
} | ||
done() | ||
}) | ||
}) | ||
}) | ||
}) |
142175
2614