ts-watches 0.1.0
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/LICENSE.md +21 -0
- package/README.md +358 -0
- package/dist/analysis/index.d.ts +5 -0
- package/dist/analysis/personal-records.d.ts +58 -0
- package/dist/analysis/race-predictor.d.ts +53 -0
- package/dist/analysis/running-dynamics.d.ts +66 -0
- package/dist/analysis/training-load.d.ts +40 -0
- package/dist/analysis/zones.d.ts +69 -0
- package/dist/bin/cli.js +52 -0
- package/dist/chunk-gsgt8r0z.js +2 -0
- package/dist/cloud/garmin-activity-api.d.ts +129 -0
- package/dist/cloud/garmin-connect.d.ts +67 -0
- package/dist/cloud/index.d.ts +4 -0
- package/dist/cloud/strava.d.ts +88 -0
- package/dist/cloud/trainingpeaks.d.ts +48 -0
- package/dist/config.d.ts +4 -0
- package/dist/drivers/apple.d.ts +17 -0
- package/dist/drivers/coros.d.ts +13 -0
- package/dist/drivers/garmin.d.ts +12 -0
- package/dist/drivers/index.d.ts +6 -0
- package/dist/drivers/polar.d.ts +14 -0
- package/dist/drivers/suunto.d.ts +13 -0
- package/dist/drivers/wahoo.d.ts +13 -0
- package/dist/export/csv.d.ts +15 -0
- package/dist/export/geojson.d.ts +23 -0
- package/dist/export/gpx.d.ts +10 -0
- package/dist/export/index.d.ts +4 -0
- package/dist/export/tcx.d.ts +10 -0
- package/dist/fit/constants.d.ts +606 -0
- package/dist/fit/decoder.d.ts +16 -0
- package/dist/fit/index.d.ts +3 -0
- package/dist/fit/parser.d.ts +21 -0
- package/dist/index.d.ts +40 -0
- package/dist/realtime/ant-plus.d.ts +201 -0
- package/dist/realtime/bluetooth.d.ts +153 -0
- package/dist/realtime/index.d.ts +3 -0
- package/dist/realtime/live-tracking.d.ts +70 -0
- package/dist/src/index.js +324 -0
- package/dist/types.d.ts +307 -0
- package/dist/workouts/builder.d.ts +184 -0
- package/dist/workouts/course.d.ts +74 -0
- package/dist/workouts/index.d.ts +3 -0
- package/dist/workouts/training-plan.d.ts +77 -0
- package/package.json +92 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Configuration Types
|
|
3
|
+
// ============================================================================
|
|
4
|
+
export declare interface WatchConfig {
|
|
5
|
+
verbose: boolean
|
|
6
|
+
outputDir: string
|
|
7
|
+
watchPaths: string[]
|
|
8
|
+
}
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Device Types
|
|
11
|
+
// ============================================================================
|
|
12
|
+
export declare interface WatchDevice {
|
|
13
|
+
name: string
|
|
14
|
+
path: string
|
|
15
|
+
type: 'garmin' | 'apple' | 'samsung' | 'fitbit' | 'wahoo' | 'coros' | 'polar' | 'suunto' | 'unknown'
|
|
16
|
+
serial?: string
|
|
17
|
+
model?: string
|
|
18
|
+
firmware?: string
|
|
19
|
+
}
|
|
20
|
+
export declare interface GarminDevice extends WatchDevice {
|
|
21
|
+
type: 'garmin'
|
|
22
|
+
unitId?: string
|
|
23
|
+
partNumber?: string
|
|
24
|
+
isGarminExpress?: boolean
|
|
25
|
+
garminExpressPath?: string
|
|
26
|
+
}
|
|
27
|
+
// ============================================================================
|
|
28
|
+
// FIT File Types (Garmin's Flexible and Interoperable Data Transfer protocol)
|
|
29
|
+
// ============================================================================
|
|
30
|
+
export declare interface FitFileHeader {
|
|
31
|
+
headerSize: number
|
|
32
|
+
protocolVersion: number
|
|
33
|
+
profileVersion: number
|
|
34
|
+
dataSize: number
|
|
35
|
+
dataType: string
|
|
36
|
+
crc?: number
|
|
37
|
+
}
|
|
38
|
+
export declare interface FitField {
|
|
39
|
+
fieldDefNum: number
|
|
40
|
+
size: number
|
|
41
|
+
baseType: number
|
|
42
|
+
}
|
|
43
|
+
export declare interface FitDefinitionMessage {
|
|
44
|
+
reserved: number
|
|
45
|
+
arch: 'little' | 'big'
|
|
46
|
+
globalMsgNum: number
|
|
47
|
+
numFields: number
|
|
48
|
+
fields: FitField[]
|
|
49
|
+
}
|
|
50
|
+
export declare interface FitDataMessage {
|
|
51
|
+
globalMsgNum: number
|
|
52
|
+
fields: Map<number, unknown>
|
|
53
|
+
}
|
|
54
|
+
export declare interface FitRecord {
|
|
55
|
+
type: 'definition' | 'data'
|
|
56
|
+
localMsgType: number
|
|
57
|
+
message: FitDefinitionMessage | FitDataMessage
|
|
58
|
+
}
|
|
59
|
+
export declare interface GeoPosition {
|
|
60
|
+
lat: number
|
|
61
|
+
lng: number
|
|
62
|
+
altitude?: number
|
|
63
|
+
}
|
|
64
|
+
export declare interface HeartRateZone {
|
|
65
|
+
zone: number
|
|
66
|
+
min: number
|
|
67
|
+
max: number
|
|
68
|
+
timeInZone: number
|
|
69
|
+
}
|
|
70
|
+
export declare interface ActivityLap {
|
|
71
|
+
startTime: Date
|
|
72
|
+
endTime: Date
|
|
73
|
+
totalElapsedTime: number
|
|
74
|
+
totalTimerTime: number
|
|
75
|
+
totalDistance: number
|
|
76
|
+
totalCalories: number
|
|
77
|
+
avgHeartRate?: number
|
|
78
|
+
maxHeartRate?: number
|
|
79
|
+
avgSpeed?: number
|
|
80
|
+
maxSpeed?: number
|
|
81
|
+
avgCadence?: number
|
|
82
|
+
maxCadence?: number
|
|
83
|
+
avgPower?: number
|
|
84
|
+
maxPower?: number
|
|
85
|
+
totalAscent?: number
|
|
86
|
+
totalDescent?: number
|
|
87
|
+
startPosition?: GeoPosition
|
|
88
|
+
endPosition?: GeoPosition
|
|
89
|
+
}
|
|
90
|
+
export declare interface ActivityRecord {
|
|
91
|
+
timestamp: Date
|
|
92
|
+
position?: GeoPosition
|
|
93
|
+
heartRate?: number
|
|
94
|
+
cadence?: number
|
|
95
|
+
speed?: number
|
|
96
|
+
power?: number
|
|
97
|
+
altitude?: number
|
|
98
|
+
distance?: number
|
|
99
|
+
temperature?: number
|
|
100
|
+
grade?: number
|
|
101
|
+
calories?: number
|
|
102
|
+
}
|
|
103
|
+
export declare interface Activity {
|
|
104
|
+
id: string
|
|
105
|
+
name?: string
|
|
106
|
+
sport: SportType
|
|
107
|
+
subSport?: SubSportType
|
|
108
|
+
startTime: Date
|
|
109
|
+
endTime: Date
|
|
110
|
+
totalElapsedTime: number
|
|
111
|
+
totalTimerTime: number
|
|
112
|
+
totalDistance: number
|
|
113
|
+
totalCalories: number
|
|
114
|
+
avgHeartRate?: number
|
|
115
|
+
maxHeartRate?: number
|
|
116
|
+
avgSpeed?: number
|
|
117
|
+
maxSpeed?: number
|
|
118
|
+
avgCadence?: number
|
|
119
|
+
maxCadence?: number
|
|
120
|
+
avgPower?: number
|
|
121
|
+
maxPower?: number
|
|
122
|
+
normalizedPower?: number
|
|
123
|
+
totalAscent?: number
|
|
124
|
+
totalDescent?: number
|
|
125
|
+
trainingStressScore?: number
|
|
126
|
+
intensityFactor?: number
|
|
127
|
+
heartRateZones?: HeartRateZone[]
|
|
128
|
+
laps: ActivityLap[]
|
|
129
|
+
records: ActivityRecord[]
|
|
130
|
+
source: 'garmin' | 'manual' | 'import'
|
|
131
|
+
rawFilePath?: string
|
|
132
|
+
}
|
|
133
|
+
// ============================================================================
|
|
134
|
+
// Health & Monitoring Types
|
|
135
|
+
// ============================================================================
|
|
136
|
+
export declare interface DailyHeartRate {
|
|
137
|
+
date: Date
|
|
138
|
+
restingHeartRate?: number
|
|
139
|
+
minHeartRate?: number
|
|
140
|
+
maxHeartRate?: number
|
|
141
|
+
avgHeartRate?: number
|
|
142
|
+
samples: Array<{
|
|
143
|
+
timestamp: Date
|
|
144
|
+
heartRate: number
|
|
145
|
+
}>
|
|
146
|
+
}
|
|
147
|
+
export declare interface SleepStage {
|
|
148
|
+
stage: 'awake' | 'light' | 'deep' | 'rem'
|
|
149
|
+
startTime: Date
|
|
150
|
+
endTime: Date
|
|
151
|
+
}
|
|
152
|
+
export declare interface SleepData {
|
|
153
|
+
date: Date
|
|
154
|
+
startTime: Date
|
|
155
|
+
endTime: Date
|
|
156
|
+
totalSleepTime: number
|
|
157
|
+
deepSleepTime: number
|
|
158
|
+
lightSleepTime: number
|
|
159
|
+
remSleepTime: number
|
|
160
|
+
awakeTime: number
|
|
161
|
+
sleepScore?: number
|
|
162
|
+
stages: SleepStage[]
|
|
163
|
+
avgHeartRate?: number
|
|
164
|
+
avgSpO2?: number
|
|
165
|
+
avgRespirationRate?: number
|
|
166
|
+
}
|
|
167
|
+
export declare interface StressData {
|
|
168
|
+
date: Date
|
|
169
|
+
avgStressLevel: number
|
|
170
|
+
maxStressLevel: number
|
|
171
|
+
restStressDuration: number
|
|
172
|
+
lowStressDuration: number
|
|
173
|
+
mediumStressDuration: number
|
|
174
|
+
highStressDuration: number
|
|
175
|
+
samples: Array<{
|
|
176
|
+
timestamp: Date
|
|
177
|
+
stressLevel: number
|
|
178
|
+
}>
|
|
179
|
+
}
|
|
180
|
+
export declare interface BodyBattery {
|
|
181
|
+
date: Date
|
|
182
|
+
startLevel: number
|
|
183
|
+
endLevel: number
|
|
184
|
+
chargedValue: number
|
|
185
|
+
drainedValue: number
|
|
186
|
+
samples: Array<{
|
|
187
|
+
timestamp: Date
|
|
188
|
+
level: number
|
|
189
|
+
}>
|
|
190
|
+
}
|
|
191
|
+
export declare interface DailySteps {
|
|
192
|
+
date: Date
|
|
193
|
+
totalSteps: number
|
|
194
|
+
goal: number
|
|
195
|
+
distance: number
|
|
196
|
+
calories: number
|
|
197
|
+
activeMinutes: number
|
|
198
|
+
floorsClimbed?: number
|
|
199
|
+
}
|
|
200
|
+
export declare interface SpO2Data {
|
|
201
|
+
date: Date
|
|
202
|
+
avgSpO2: number
|
|
203
|
+
minSpO2: number
|
|
204
|
+
maxSpO2: number
|
|
205
|
+
samples: Array<{
|
|
206
|
+
timestamp: Date
|
|
207
|
+
spO2: number
|
|
208
|
+
}>
|
|
209
|
+
}
|
|
210
|
+
export declare interface RespirationData {
|
|
211
|
+
date: Date
|
|
212
|
+
avgRespirationRate: number
|
|
213
|
+
minRespirationRate: number
|
|
214
|
+
maxRespirationRate: number
|
|
215
|
+
samples: Array<{
|
|
216
|
+
timestamp: Date
|
|
217
|
+
respirationRate: number
|
|
218
|
+
}>
|
|
219
|
+
}
|
|
220
|
+
export declare interface HRVData {
|
|
221
|
+
date: Date
|
|
222
|
+
weeklyAverage?: number
|
|
223
|
+
lastNightAverage?: number
|
|
224
|
+
status?: 'low' | 'unbalanced' | 'balanced' | 'high'
|
|
225
|
+
baseline?: number
|
|
226
|
+
samples: Array<{
|
|
227
|
+
timestamp: Date
|
|
228
|
+
hrv: number
|
|
229
|
+
}>
|
|
230
|
+
}
|
|
231
|
+
export declare interface WeightData {
|
|
232
|
+
date: Date
|
|
233
|
+
weight: number
|
|
234
|
+
bmi?: number
|
|
235
|
+
bodyFatPercentage?: number
|
|
236
|
+
bodyWater?: number
|
|
237
|
+
boneMass?: number
|
|
238
|
+
muscleMass?: number
|
|
239
|
+
visceralFat?: number
|
|
240
|
+
metabolicAge?: number
|
|
241
|
+
}
|
|
242
|
+
// ============================================================================
|
|
243
|
+
// Aggregate Types
|
|
244
|
+
// ============================================================================
|
|
245
|
+
export declare interface MonitoringData {
|
|
246
|
+
heartRate?: DailyHeartRate
|
|
247
|
+
sleep?: SleepData
|
|
248
|
+
stress?: StressData
|
|
249
|
+
bodyBattery?: BodyBattery
|
|
250
|
+
steps?: DailySteps
|
|
251
|
+
spO2?: SpO2Data
|
|
252
|
+
respiration?: RespirationData
|
|
253
|
+
hrv?: HRVData
|
|
254
|
+
}
|
|
255
|
+
export declare interface DownloadResult {
|
|
256
|
+
device: WatchDevice
|
|
257
|
+
activities: Activity[]
|
|
258
|
+
monitoring: Map<string, MonitoringData>
|
|
259
|
+
rawFiles: string[]
|
|
260
|
+
errors: Error[]
|
|
261
|
+
}
|
|
262
|
+
// ============================================================================
|
|
263
|
+
// Driver Interface
|
|
264
|
+
// ============================================================================
|
|
265
|
+
export declare interface WatchDriver {
|
|
266
|
+
readonly name: string
|
|
267
|
+
readonly type: WatchDevice['type']
|
|
268
|
+
detectDevices(): Promise<WatchDevice[]>
|
|
269
|
+
downloadData(device: WatchDevice, options?: DownloadOptions): Promise<DownloadResult>
|
|
270
|
+
parseActivityFile(filePath: string): Promise<Activity | null>
|
|
271
|
+
parseMonitoringFile(filePath: string): Promise<MonitoringData>
|
|
272
|
+
}
|
|
273
|
+
export declare interface DownloadOptions {
|
|
274
|
+
outputDir?: string
|
|
275
|
+
includeActivities?: boolean
|
|
276
|
+
includeMonitoring?: boolean
|
|
277
|
+
since?: Date
|
|
278
|
+
until?: Date
|
|
279
|
+
copyRawFiles?: boolean
|
|
280
|
+
}
|
|
281
|
+
export type WatchOptions = Partial<WatchConfig>;
|
|
282
|
+
// ============================================================================
|
|
283
|
+
// Activity Types
|
|
284
|
+
// ============================================================================
|
|
285
|
+
export type SportType = | 'running'
|
|
286
|
+
| 'cycling'
|
|
287
|
+
| 'swimming'
|
|
288
|
+
| 'hiking'
|
|
289
|
+
| 'walking'
|
|
290
|
+
| 'strength_training'
|
|
291
|
+
| 'cardio'
|
|
292
|
+
| 'yoga'
|
|
293
|
+
| 'other'
|
|
294
|
+
| 'generic';
|
|
295
|
+
export type SubSportType = | 'generic'
|
|
296
|
+
| 'treadmill'
|
|
297
|
+
| 'street'
|
|
298
|
+
| 'trail'
|
|
299
|
+
| 'track'
|
|
300
|
+
| 'spin'
|
|
301
|
+
| 'indoor_cycling'
|
|
302
|
+
| 'road'
|
|
303
|
+
| 'mountain'
|
|
304
|
+
| 'gravel'
|
|
305
|
+
| 'lap_swimming'
|
|
306
|
+
| 'open_water'
|
|
307
|
+
| 'other';
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import type { SportType } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Create a new workout builder
|
|
4
|
+
*/
|
|
5
|
+
export declare function createWorkout(name: string, sport: SportType): WorkoutBuilder;
|
|
6
|
+
/**
|
|
7
|
+
* Format workout duration for display
|
|
8
|
+
*/
|
|
9
|
+
export declare function formatWorkoutDuration(duration: WorkoutDuration): string;
|
|
10
|
+
/**
|
|
11
|
+
* Format workout target for display
|
|
12
|
+
*/
|
|
13
|
+
export declare function formatWorkoutTarget(workoutTarget: WorkoutTarget): string;
|
|
14
|
+
/**
|
|
15
|
+
* Helper functions for common durations
|
|
16
|
+
* @defaultValue
|
|
17
|
+
* ```ts
|
|
18
|
+
* {
|
|
19
|
+
* time: (seconds: number) => WorkoutDuration,
|
|
20
|
+
* minutes: (minutes: number) => WorkoutDuration,
|
|
21
|
+
* distance: (meters: number) => WorkoutDuration,
|
|
22
|
+
* km: (km: number) => WorkoutDuration,
|
|
23
|
+
* miles: (miles: number) => WorkoutDuration,
|
|
24
|
+
* calories: (cal: number) => WorkoutDuration,
|
|
25
|
+
* open: () => WorkoutDuration,
|
|
26
|
+
* lapButton: () => WorkoutDuration,
|
|
27
|
+
* untilHrBelow: (hr: number) => WorkoutDuration,
|
|
28
|
+
* untilHrAbove: (hr: number) => WorkoutDuration
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare const duration: {
|
|
33
|
+
time: (seconds: number) => WorkoutDuration;
|
|
34
|
+
minutes: (minutes: number) => WorkoutDuration;
|
|
35
|
+
distance: (meters: number) => WorkoutDuration;
|
|
36
|
+
km: (km: number) => WorkoutDuration;
|
|
37
|
+
miles: (miles: number) => WorkoutDuration;
|
|
38
|
+
calories: (cal: number) => WorkoutDuration;
|
|
39
|
+
open: () => WorkoutDuration;
|
|
40
|
+
lapButton: () => WorkoutDuration;
|
|
41
|
+
untilHrBelow: (hr: number) => WorkoutDuration;
|
|
42
|
+
untilHrAbove: (hr: number) => WorkoutDuration
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Helper functions for common targets
|
|
46
|
+
* @defaultValue
|
|
47
|
+
* ```ts
|
|
48
|
+
* {
|
|
49
|
+
* open: () => WorkoutTarget,
|
|
50
|
+
* hrZone: (zone: number) => WorkoutTarget,
|
|
51
|
+
* hrRange: (low: number, high: number) => WorkoutTarget,
|
|
52
|
+
* hr: (bpm: number) => WorkoutTarget,
|
|
53
|
+
* powerZone: (zone: number) => WorkoutTarget,
|
|
54
|
+
* powerRange: (low: number, high: number) => WorkoutTarget,
|
|
55
|
+
* power: (watts: number) => WorkoutTarget,
|
|
56
|
+
* paceZone: (zone: number) => WorkoutTarget,
|
|
57
|
+
* paceRange: (slowSecPerKm: number, fastSecPerKm: number) => WorkoutTarget,
|
|
58
|
+
* pace: (secPerKm: number) => WorkoutTarget,
|
|
59
|
+
* cadence: (spm: number) => WorkoutTarget,
|
|
60
|
+
* cadenceRange: (low: number, high: number) => WorkoutTarget
|
|
61
|
+
* }
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export declare const target: {
|
|
65
|
+
open: () => WorkoutTarget;
|
|
66
|
+
hrZone: (zone: number) => WorkoutTarget;
|
|
67
|
+
hrRange: (low: number, high: number) => WorkoutTarget;
|
|
68
|
+
hr: (bpm: number) => WorkoutTarget;
|
|
69
|
+
powerZone: (zone: number) => WorkoutTarget;
|
|
70
|
+
powerRange: (low: number, high: number) => WorkoutTarget;
|
|
71
|
+
power: (watts: number) => WorkoutTarget;
|
|
72
|
+
paceZone: (zone: number) => WorkoutTarget;
|
|
73
|
+
paceRange: (slowSecPerKm: number, fastSecPerKm: number) => WorkoutTarget;
|
|
74
|
+
pace: (secPerKm: number) => WorkoutTarget;
|
|
75
|
+
cadence: (spm: number) => WorkoutTarget;
|
|
76
|
+
cadenceRange: (low: number, high: number) => WorkoutTarget
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Common workout templates
|
|
80
|
+
* @defaultValue
|
|
81
|
+
* ```ts
|
|
82
|
+
* {
|
|
83
|
+
* fiveByOneK: () => Workout,
|
|
84
|
+
* thirtyThirty: (sets?: number) => Workout,
|
|
85
|
+
* tempoRun: (tempoMinutes?: number) => Workout,
|
|
86
|
+
* sweetSpot: (intervals?: number, minutes?: number) => Workout,
|
|
87
|
+
* vo2maxIntervals: () => Workout
|
|
88
|
+
* }
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
export declare const workoutTemplates: {
|
|
92
|
+
/**
|
|
93
|
+
* Classic 5x1km intervals for running
|
|
94
|
+
*/
|
|
95
|
+
fiveByOneK: () => Workout;
|
|
96
|
+
/**
|
|
97
|
+
* 30/30 intervals
|
|
98
|
+
*/
|
|
99
|
+
thirtyThirty: (sets?: number) => Workout;
|
|
100
|
+
/**
|
|
101
|
+
* Tempo run
|
|
102
|
+
*/
|
|
103
|
+
tempoRun: (tempoMinutes?: number) => Workout;
|
|
104
|
+
/**
|
|
105
|
+
* Cycling sweet spot
|
|
106
|
+
*/
|
|
107
|
+
sweetSpot: (intervals?: number, minutes?: number) => Workout;
|
|
108
|
+
/**
|
|
109
|
+
* VO2max intervals for cycling
|
|
110
|
+
*/
|
|
111
|
+
vo2maxIntervals: () => Workout
|
|
112
|
+
};
|
|
113
|
+
export declare interface WorkoutTarget {
|
|
114
|
+
type: WorkoutTargetType
|
|
115
|
+
value?: number
|
|
116
|
+
low?: number
|
|
117
|
+
high?: number
|
|
118
|
+
zone?: number
|
|
119
|
+
}
|
|
120
|
+
export declare interface WorkoutDuration {
|
|
121
|
+
type: WorkoutDurationType
|
|
122
|
+
value?: number
|
|
123
|
+
}
|
|
124
|
+
export declare interface WorkoutStep {
|
|
125
|
+
type: WorkoutStepType
|
|
126
|
+
name?: string
|
|
127
|
+
notes?: string
|
|
128
|
+
duration: WorkoutDuration
|
|
129
|
+
target: WorkoutTarget
|
|
130
|
+
secondaryTarget?: WorkoutTarget
|
|
131
|
+
}
|
|
132
|
+
export declare interface WorkoutRepeatGroup {
|
|
133
|
+
type: 'repeat'
|
|
134
|
+
repeatCount: number
|
|
135
|
+
steps: WorkoutStep[]
|
|
136
|
+
}
|
|
137
|
+
export declare interface Workout {
|
|
138
|
+
id?: string
|
|
139
|
+
name: string
|
|
140
|
+
sport: SportType
|
|
141
|
+
description?: string
|
|
142
|
+
steps: (WorkoutStep | WorkoutRepeatGroup)[]
|
|
143
|
+
estimatedDuration?: number
|
|
144
|
+
estimatedDistance?: number
|
|
145
|
+
createdAt?: Date
|
|
146
|
+
updatedAt?: Date
|
|
147
|
+
}
|
|
148
|
+
export type WorkoutStepType = | 'warmup'
|
|
149
|
+
| 'cooldown'
|
|
150
|
+
| 'interval'
|
|
151
|
+
| 'recovery'
|
|
152
|
+
| 'rest'
|
|
153
|
+
| 'active'
|
|
154
|
+
| 'repeat';
|
|
155
|
+
export type WorkoutTargetType = | 'open'
|
|
156
|
+
| 'heart_rate_zone'
|
|
157
|
+
| 'heart_rate'
|
|
158
|
+
| 'power_zone'
|
|
159
|
+
| 'power'
|
|
160
|
+
| 'pace_zone'
|
|
161
|
+
| 'pace'
|
|
162
|
+
| 'cadence'
|
|
163
|
+
| 'speed';
|
|
164
|
+
export type WorkoutDurationType = | 'time'
|
|
165
|
+
| 'distance'
|
|
166
|
+
| 'calories'
|
|
167
|
+
| 'open'
|
|
168
|
+
| 'lap_button'
|
|
169
|
+
| 'heart_rate_less_than'
|
|
170
|
+
| 'heart_rate_greater_than'
|
|
171
|
+
| 'power_less_than'
|
|
172
|
+
| 'power_greater_than';
|
|
173
|
+
export declare class WorkoutBuilder {
|
|
174
|
+
constructor(name: string, sport: SportType);
|
|
175
|
+
setDescription(description: string): this;
|
|
176
|
+
warmup(duration: WorkoutDuration, target?: WorkoutTarget): this;
|
|
177
|
+
cooldown(duration: WorkoutDuration, target?: WorkoutTarget): this;
|
|
178
|
+
interval(duration: WorkoutDuration, target: WorkoutTarget, name?: string): this;
|
|
179
|
+
recovery(duration: WorkoutDuration, target?: WorkoutTarget): this;
|
|
180
|
+
rest(duration: WorkoutDuration): this;
|
|
181
|
+
active(duration: WorkoutDuration, target: WorkoutTarget, name?: string): this;
|
|
182
|
+
repeat(count: number, builderFn: (builder: WorkoutBuilder) => void): this;
|
|
183
|
+
build(): Workout;
|
|
184
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { GeoPosition, Activity } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Create a new course builder
|
|
4
|
+
*/
|
|
5
|
+
export declare function createCourse(name: string, sport?: Course['sport']): CourseBuilder;
|
|
6
|
+
/**
|
|
7
|
+
* Export course to GPX format
|
|
8
|
+
*/
|
|
9
|
+
export declare function courseToGpx(course: Course): string;
|
|
10
|
+
/**
|
|
11
|
+
* Export course to TCX course format
|
|
12
|
+
*/
|
|
13
|
+
export declare function courseToTcx(course: Course): string;
|
|
14
|
+
export declare interface CoursePoint {
|
|
15
|
+
position: GeoPosition
|
|
16
|
+
distance: number
|
|
17
|
+
name?: string
|
|
18
|
+
type?: CoursePointType
|
|
19
|
+
notes?: string
|
|
20
|
+
}
|
|
21
|
+
export declare interface Course {
|
|
22
|
+
id?: string
|
|
23
|
+
name: string
|
|
24
|
+
description?: string
|
|
25
|
+
sport: 'running' | 'cycling' | 'hiking' | 'walking'
|
|
26
|
+
trackPoints: GeoPosition[]
|
|
27
|
+
coursePoints: CoursePoint[]
|
|
28
|
+
totalDistance: number
|
|
29
|
+
totalAscent: number
|
|
30
|
+
totalDescent: number
|
|
31
|
+
createdAt?: Date
|
|
32
|
+
updatedAt?: Date
|
|
33
|
+
}
|
|
34
|
+
export type CoursePointType = | 'generic'
|
|
35
|
+
| 'summit'
|
|
36
|
+
| 'valley'
|
|
37
|
+
| 'water'
|
|
38
|
+
| 'food'
|
|
39
|
+
| 'danger'
|
|
40
|
+
| 'left'
|
|
41
|
+
| 'right'
|
|
42
|
+
| 'straight'
|
|
43
|
+
| 'first_aid'
|
|
44
|
+
| 'fourth_category'
|
|
45
|
+
| 'third_category'
|
|
46
|
+
| 'second_category'
|
|
47
|
+
| 'first_category'
|
|
48
|
+
| 'hors_category'
|
|
49
|
+
| 'sprint';
|
|
50
|
+
export declare class CourseBuilder {
|
|
51
|
+
constructor(name: string, sport?: Course['sport']);
|
|
52
|
+
setDescription(description: string): this;
|
|
53
|
+
setSport(sport: Course['sport']): this;
|
|
54
|
+
addPoint(lat: number, lng: number, altitude?: number): this;
|
|
55
|
+
addPoints(points: Array<{
|
|
56
|
+
lat: number
|
|
57
|
+
lng: number
|
|
58
|
+
altitude?: number
|
|
59
|
+
}>): this;
|
|
60
|
+
addCoursePoint(lat: number, lng: number, type: CoursePointType, name?: string, notes?: string): this;
|
|
61
|
+
addWaterStation(lat: number, lng: number, name?: string): this;
|
|
62
|
+
addFoodStation(lat: number, lng: number, name?: string): this;
|
|
63
|
+
addTurn(lat: number, lng: number, direction: 'left' | 'right' | 'straight', notes?: string): this;
|
|
64
|
+
addClimbCategory(lat: number, lng: number, category: 1 | 2 | 3 | 4 | 'hors', name?: string): this;
|
|
65
|
+
addSprint(lat: number, lng: number, name?: string): this;
|
|
66
|
+
addSummit(lat: number, lng: number, name?: string): this;
|
|
67
|
+
fromActivity(activity: Activity): this;
|
|
68
|
+
fromGeoJson(geoJson: {
|
|
69
|
+
type: string
|
|
70
|
+
coordinates: number[][]
|
|
71
|
+
}): this;
|
|
72
|
+
reverse(): this;
|
|
73
|
+
build(): Course;
|
|
74
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { SportType } from '../types';
|
|
2
|
+
import type { Workout } from './builder';
|
|
3
|
+
/**
|
|
4
|
+
* Generate a marathon training plan
|
|
5
|
+
*/
|
|
6
|
+
export declare function generateMarathonPlan(config: MarathonPlanConfig): TrainingPlan;
|
|
7
|
+
/**
|
|
8
|
+
* Generate a 5K training plan
|
|
9
|
+
*/
|
|
10
|
+
export declare function generate5kPlan(config: FiveKPlanConfig): TrainingPlan;
|
|
11
|
+
/**
|
|
12
|
+
* Export training plan to iCal format
|
|
13
|
+
*/
|
|
14
|
+
export declare function planToIcal(plan: TrainingPlan): string;
|
|
15
|
+
export declare function createTrainingPlan(config: TrainingPlanConfig): TrainingPlanBuilder;
|
|
16
|
+
export declare interface TrainingWeek {
|
|
17
|
+
weekNumber: number
|
|
18
|
+
phase: TrainingPhase
|
|
19
|
+
description?: string
|
|
20
|
+
workouts: ScheduledWorkout[]
|
|
21
|
+
targetTSS?: number
|
|
22
|
+
targetDistance?: number
|
|
23
|
+
targetDuration?: number
|
|
24
|
+
}
|
|
25
|
+
export declare interface ScheduledWorkout {
|
|
26
|
+
dayOfWeek: 0 | 1 | 2 | 3 | 4 | 5 | 6
|
|
27
|
+
workout: Workout
|
|
28
|
+
notes?: string
|
|
29
|
+
}
|
|
30
|
+
export declare interface TrainingPlan {
|
|
31
|
+
id?: string
|
|
32
|
+
name: string
|
|
33
|
+
description?: string
|
|
34
|
+
sport: SportType
|
|
35
|
+
goalRace?: {
|
|
36
|
+
name: string
|
|
37
|
+
date: Date
|
|
38
|
+
distance: number
|
|
39
|
+
}
|
|
40
|
+
weeks: TrainingWeek[]
|
|
41
|
+
startDate: Date
|
|
42
|
+
endDate: Date
|
|
43
|
+
createdAt?: Date
|
|
44
|
+
updatedAt?: Date
|
|
45
|
+
}
|
|
46
|
+
export declare interface TrainingPlanConfig {
|
|
47
|
+
name: string
|
|
48
|
+
sport: SportType
|
|
49
|
+
goalRaceDate: Date
|
|
50
|
+
goalRaceDistance: number
|
|
51
|
+
currentFitness: 'beginner' | 'intermediate' | 'advanced'
|
|
52
|
+
weeklyHours: number
|
|
53
|
+
longRunDay?: 0 | 1 | 2 | 3 | 4 | 5 | 6
|
|
54
|
+
restDays?: Array<0 | 1 | 2 | 3 | 4 | 5 | 6>
|
|
55
|
+
}
|
|
56
|
+
export declare interface MarathonPlanConfig {
|
|
57
|
+
raceDate: Date
|
|
58
|
+
name?: string
|
|
59
|
+
currentWeeklyMileage: number
|
|
60
|
+
fitness: 'beginner' | 'intermediate' | 'advanced'
|
|
61
|
+
}
|
|
62
|
+
export declare interface FiveKPlanConfig {
|
|
63
|
+
raceDate: Date
|
|
64
|
+
name?: string
|
|
65
|
+
fitness: 'beginner' | 'intermediate' | 'advanced'
|
|
66
|
+
}
|
|
67
|
+
export type TrainingPhase = | 'base'
|
|
68
|
+
| 'build'
|
|
69
|
+
| 'peak'
|
|
70
|
+
| 'taper'
|
|
71
|
+
| 'recovery';
|
|
72
|
+
export declare class TrainingPlanBuilder {
|
|
73
|
+
constructor(config: TrainingPlanConfig);
|
|
74
|
+
addWeek(week: TrainingWeek): this;
|
|
75
|
+
setDescription(description: string): this;
|
|
76
|
+
build(): TrainingPlan;
|
|
77
|
+
}
|