@openlifelog/sdk 1.0.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/EXAMPLES.md +624 -0
- package/README.md +824 -0
- package/client.ts +190 -0
- package/config.ts +96 -0
- package/constants/metrics.ts +116 -0
- package/dist/index.d.mts +1101 -0
- package/dist/index.d.ts +1101 -0
- package/dist/index.js +2023 -0
- package/dist/index.mjs +1969 -0
- package/index.ts +49 -0
- package/package.json +53 -0
- package/resources/ai.ts +26 -0
- package/resources/auth.ts +98 -0
- package/resources/exercises.ts +112 -0
- package/resources/food-logs.ts +132 -0
- package/resources/foods.ts +185 -0
- package/resources/goals.ts +155 -0
- package/resources/metrics.ts +115 -0
- package/resources/programs.ts +123 -0
- package/resources/sessions.ts +142 -0
- package/resources/users.ts +132 -0
- package/resources/workouts.ts +147 -0
- package/tsconfig.json +27 -0
- package/types/ai.ts +55 -0
- package/types/common.ts +177 -0
- package/types/exercise.ts +75 -0
- package/types/food.ts +208 -0
- package/types/goal.ts +169 -0
- package/types/index.ts +17 -0
- package/types/metric.ts +108 -0
- package/types/program.ts +120 -0
- package/types/session.ts +196 -0
- package/types/user.ts +79 -0
- package/types/workout.ts +97 -0
- package/utils/errors.ts +159 -0
- package/utils/http.ts +313 -0
- package/utils/index.ts +8 -0
- package/utils/pagination.ts +106 -0
- package/utils/units.ts +279 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import type { HttpClient } from '../utils/http';
|
|
2
|
+
import type {
|
|
3
|
+
UserGoal,
|
|
4
|
+
CreateUserGoalRequest,
|
|
5
|
+
UpdateUserGoalRequest,
|
|
6
|
+
DailyGoalProgress,
|
|
7
|
+
UserNutritionGoals,
|
|
8
|
+
CreateNutritionGoalsRequest,
|
|
9
|
+
UpdateNutritionGoalsRequest,
|
|
10
|
+
BulkCreateNutritionGoalsRequest,
|
|
11
|
+
CopyNutritionGoalsRequest,
|
|
12
|
+
DailyNutritionProgress,
|
|
13
|
+
ListNutritionGoalsHistoryParams,
|
|
14
|
+
ListResponse,
|
|
15
|
+
} from '../types';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Goals resource
|
|
19
|
+
* Handles user goals and nutrition goals
|
|
20
|
+
*/
|
|
21
|
+
export class GoalsResource {
|
|
22
|
+
constructor(private http: HttpClient) {}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Get active user goals
|
|
26
|
+
*/
|
|
27
|
+
async list(): Promise<ListResponse<UserGoal>> {
|
|
28
|
+
const response = await this.http.get<ListResponse<UserGoal>>('/v1/goals');
|
|
29
|
+
return response.data;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Get goals effective on a specific date
|
|
34
|
+
*/
|
|
35
|
+
async getByDate(date: string): Promise<ListResponse<UserGoal>> {
|
|
36
|
+
const response = await this.http.get<ListResponse<UserGoal>>(`/v1/goals/date/${date}`);
|
|
37
|
+
return response.data;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Create a new goal
|
|
42
|
+
*/
|
|
43
|
+
async create(request: CreateUserGoalRequest): Promise<UserGoal> {
|
|
44
|
+
const response = await this.http.post<UserGoal>('/v1/goals', request);
|
|
45
|
+
return response.data;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Update a goal
|
|
50
|
+
*/
|
|
51
|
+
async update(goalId: string, request: UpdateUserGoalRequest): Promise<UserGoal> {
|
|
52
|
+
const response = await this.http.put<UserGoal>(`/v1/goals/${goalId}`, request);
|
|
53
|
+
return response.data;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Delete a goal
|
|
58
|
+
*/
|
|
59
|
+
async delete(goalId: string): Promise<void> {
|
|
60
|
+
await this.http.delete(`/v1/goals/${goalId}`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Get today's goal progress
|
|
65
|
+
*/
|
|
66
|
+
async getProgress(): Promise<DailyGoalProgress> {
|
|
67
|
+
const response = await this.http.get<DailyGoalProgress>('/v1/goals/progress');
|
|
68
|
+
return response.data;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Get goal progress for a specific date
|
|
73
|
+
*/
|
|
74
|
+
async getProgressByDate(date: string): Promise<DailyGoalProgress> {
|
|
75
|
+
const response = await this.http.get<DailyGoalProgress>(`/v1/goals/progress/${date}`);
|
|
76
|
+
return response.data;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Get current nutrition goals
|
|
81
|
+
*/
|
|
82
|
+
async getNutritionGoals(): Promise<UserNutritionGoals> {
|
|
83
|
+
const response = await this.http.get<UserNutritionGoals>('/v1/nutrition/goals');
|
|
84
|
+
return response.data;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Get nutrition goals for a specific date
|
|
89
|
+
*/
|
|
90
|
+
async getNutritionGoalsByDate(date: string): Promise<UserNutritionGoals> {
|
|
91
|
+
const response = await this.http.get<UserNutritionGoals>(`/v1/nutrition/goals/date/${date}`);
|
|
92
|
+
return response.data;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Create nutrition goals
|
|
97
|
+
*/
|
|
98
|
+
async createNutritionGoals(request: CreateNutritionGoalsRequest): Promise<UserNutritionGoals> {
|
|
99
|
+
const response = await this.http.post<UserNutritionGoals>('/v1/nutrition/goals', request);
|
|
100
|
+
return response.data;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Update nutrition goals for a specific date
|
|
105
|
+
*/
|
|
106
|
+
async updateNutritionGoals(date: string, request: UpdateNutritionGoalsRequest): Promise<UserNutritionGoals> {
|
|
107
|
+
const response = await this.http.put<UserNutritionGoals>(`/v1/nutrition/goals/date/${date}`, request);
|
|
108
|
+
return response.data;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Delete nutrition goals for a specific date
|
|
113
|
+
*/
|
|
114
|
+
async deleteNutritionGoals(date: string): Promise<void> {
|
|
115
|
+
await this.http.delete(`/v1/nutrition/goals/date/${date}`);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Bulk create nutrition goals for multiple dates
|
|
120
|
+
*/
|
|
121
|
+
async bulkCreateNutritionGoals(request: BulkCreateNutritionGoalsRequest): Promise<void> {
|
|
122
|
+
await this.http.post('/v1/nutrition/goals/bulk', request);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Copy nutrition goals from one date to another
|
|
127
|
+
*/
|
|
128
|
+
async copyNutritionGoals(request: CopyNutritionGoalsRequest): Promise<void> {
|
|
129
|
+
await this.http.post('/v1/nutrition/goals/copy', request);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Get nutrition goals history
|
|
134
|
+
*/
|
|
135
|
+
async getNutritionGoalsHistory(params?: ListNutritionGoalsHistoryParams): Promise<ListResponse<UserNutritionGoals>> {
|
|
136
|
+
const response = await this.http.get<ListResponse<UserNutritionGoals>>('/v1/nutrition/goals/history', params);
|
|
137
|
+
return response.data;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Get today's nutrition progress toward goals
|
|
142
|
+
*/
|
|
143
|
+
async getNutritionProgress(): Promise<DailyNutritionProgress> {
|
|
144
|
+
const response = await this.http.get<DailyNutritionProgress>('/v1/nutrition/progress/today');
|
|
145
|
+
return response.data;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Get nutrition progress for a specific date
|
|
150
|
+
*/
|
|
151
|
+
async getNutritionProgressByDate(date: string): Promise<DailyNutritionProgress> {
|
|
152
|
+
const response = await this.http.get<DailyNutritionProgress>(`/v1/nutrition/progress/date/${date}`);
|
|
153
|
+
return response.data;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import type { HttpClient } from '../utils/http';
|
|
2
|
+
import type {
|
|
3
|
+
Metric,
|
|
4
|
+
MetricEvent,
|
|
5
|
+
CreateMetricEventRequest,
|
|
6
|
+
UpdateMetricEventRequest,
|
|
7
|
+
BulkCreateMetricEventsRequest,
|
|
8
|
+
ListMetricEventsParams,
|
|
9
|
+
DailyMetricAggregate,
|
|
10
|
+
GetDailyMetricParams,
|
|
11
|
+
ListResponse,
|
|
12
|
+
} from '../types';
|
|
13
|
+
import { createPaginatedIterator, type PaginatedIterator } from '../utils/pagination';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Metrics resource
|
|
17
|
+
* Handles metric tracking operations
|
|
18
|
+
*/
|
|
19
|
+
export class MetricsResource {
|
|
20
|
+
constructor(private http: HttpClient) {}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* List available metrics
|
|
24
|
+
*/
|
|
25
|
+
async list(): Promise<ListResponse<Metric>> {
|
|
26
|
+
const response = await this.http.get<ListResponse<Metric>>('/v1/metrics');
|
|
27
|
+
return response.data;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Get specific metric details
|
|
32
|
+
*/
|
|
33
|
+
async get(metricId: string): Promise<Metric> {
|
|
34
|
+
const response = await this.http.get<Metric>(`/v1/metrics/${metricId}`);
|
|
35
|
+
return response.data;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Get metrics by category
|
|
40
|
+
*/
|
|
41
|
+
async getByCategory(category: string): Promise<ListResponse<Metric>> {
|
|
42
|
+
const response = await this.http.get<ListResponse<Metric>>(`/v1/metrics/category/${category}`);
|
|
43
|
+
return response.data;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Get daily aggregated metric value
|
|
48
|
+
*/
|
|
49
|
+
async getDailyMetric(metricKey: string, params?: GetDailyMetricParams): Promise<DailyMetricAggregate> {
|
|
50
|
+
const response = await this.http.get<DailyMetricAggregate>(`/v1/metrics/daily/${metricKey}`, params);
|
|
51
|
+
return response.data;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* List metric events (data points)
|
|
56
|
+
*/
|
|
57
|
+
async listEvents(params?: ListMetricEventsParams): Promise<ListResponse<MetricEvent>> {
|
|
58
|
+
const response = await this.http.get<ListResponse<MetricEvent>>('/v1/metric-events', params);
|
|
59
|
+
return response.data;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* List metric events with automatic pagination
|
|
64
|
+
*/
|
|
65
|
+
listEventsAutoPaginate(params?: ListMetricEventsParams): PaginatedIterator<MetricEvent> {
|
|
66
|
+
return createPaginatedIterator((cursor) =>
|
|
67
|
+
this.listEvents({ ...params, cursor })
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Get specific metric event
|
|
73
|
+
*/
|
|
74
|
+
async getEvent(eventId: string): Promise<MetricEvent> {
|
|
75
|
+
const response = await this.http.get<MetricEvent>(`/v1/metric-events/${eventId}`);
|
|
76
|
+
return response.data;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Log a metric value (convenience method)
|
|
81
|
+
*/
|
|
82
|
+
async log(request: CreateMetricEventRequest): Promise<MetricEvent> {
|
|
83
|
+
const response = await this.http.post<MetricEvent>('/v1/metric-events', request);
|
|
84
|
+
return response.data;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Create a metric event
|
|
89
|
+
*/
|
|
90
|
+
async createEvent(request: CreateMetricEventRequest): Promise<MetricEvent> {
|
|
91
|
+
return this.log(request);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Bulk create metric events
|
|
96
|
+
*/
|
|
97
|
+
async bulkCreateEvents(request: BulkCreateMetricEventsRequest): Promise<void> {
|
|
98
|
+
await this.http.post('/v1/metric-events/bulk', request);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Update a metric event
|
|
103
|
+
*/
|
|
104
|
+
async updateEvent(eventId: string, request: UpdateMetricEventRequest): Promise<MetricEvent> {
|
|
105
|
+
const response = await this.http.put<MetricEvent>(`/v1/metric-events/${eventId}`, request);
|
|
106
|
+
return response.data;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Delete a metric event
|
|
111
|
+
*/
|
|
112
|
+
async deleteEvent(eventId: string): Promise<void> {
|
|
113
|
+
await this.http.delete(`/v1/metric-events/${eventId}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import type { HttpClient } from '../utils/http';
|
|
2
|
+
import type {
|
|
3
|
+
Program,
|
|
4
|
+
CreateProgramRequest,
|
|
5
|
+
UpdateProgramRequest,
|
|
6
|
+
EnrollInProgramRequest,
|
|
7
|
+
ProgramEnrollment,
|
|
8
|
+
UpdateEnrollmentRequest,
|
|
9
|
+
EnrollmentProgress,
|
|
10
|
+
CurrentWeekSchedule,
|
|
11
|
+
ListResponse,
|
|
12
|
+
ListParams,
|
|
13
|
+
} from '../types';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Programs resource
|
|
17
|
+
* Handles training program operations
|
|
18
|
+
*/
|
|
19
|
+
export class ProgramsResource {
|
|
20
|
+
constructor(private http: HttpClient) {}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* List user's programs and enrollments
|
|
24
|
+
*/
|
|
25
|
+
async list(params?: ListParams): Promise<ListResponse<Program>> {
|
|
26
|
+
const response = await this.http.get<ListResponse<Program>>('/v1/programs', params);
|
|
27
|
+
return response.data;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* List available program templates
|
|
32
|
+
*/
|
|
33
|
+
async listTemplates(params?: ListParams): Promise<ListResponse<Program>> {
|
|
34
|
+
const response = await this.http.get<ListResponse<Program>>('/v1/programs/templates', params);
|
|
35
|
+
return response.data;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Create a new program
|
|
40
|
+
*/
|
|
41
|
+
async create(request: CreateProgramRequest): Promise<Program> {
|
|
42
|
+
const response = await this.http.post<Program>('/v1/programs', request);
|
|
43
|
+
return response.data;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Get specific program details
|
|
48
|
+
*/
|
|
49
|
+
async get(programId: string): Promise<Program> {
|
|
50
|
+
const response = await this.http.get<Program>(`/v1/programs/${programId}`);
|
|
51
|
+
return response.data;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Update a program
|
|
56
|
+
*/
|
|
57
|
+
async update(programId: string, request: UpdateProgramRequest): Promise<Program> {
|
|
58
|
+
const response = await this.http.put<Program>(`/v1/programs/${programId}`, request);
|
|
59
|
+
return response.data;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Delete a program
|
|
64
|
+
*/
|
|
65
|
+
async delete(programId: string): Promise<void> {
|
|
66
|
+
await this.http.delete(`/v1/programs/${programId}`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Enroll in a program
|
|
71
|
+
*/
|
|
72
|
+
async enroll(programId: string, request: EnrollInProgramRequest): Promise<ProgramEnrollment> {
|
|
73
|
+
const response = await this.http.post<ProgramEnrollment>(`/v1/programs/${programId}/enroll`, request);
|
|
74
|
+
return response.data;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* List program enrollments
|
|
79
|
+
*/
|
|
80
|
+
async listEnrollments(params?: ListParams): Promise<ListResponse<ProgramEnrollment>> {
|
|
81
|
+
const response = await this.http.get<ListResponse<ProgramEnrollment>>('/v1/enrollments', params);
|
|
82
|
+
return response.data;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Get enrollment details
|
|
87
|
+
*/
|
|
88
|
+
async getEnrollment(enrollmentId: string): Promise<ProgramEnrollment> {
|
|
89
|
+
const response = await this.http.get<ProgramEnrollment>(`/v1/enrollments/${enrollmentId}`);
|
|
90
|
+
return response.data;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Update enrollment (pause, resume, etc.)
|
|
95
|
+
*/
|
|
96
|
+
async updateEnrollment(enrollmentId: string, request: UpdateEnrollmentRequest): Promise<ProgramEnrollment> {
|
|
97
|
+
const response = await this.http.put<ProgramEnrollment>(`/v1/enrollments/${enrollmentId}`, request);
|
|
98
|
+
return response.data;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Unenroll from a program
|
|
103
|
+
*/
|
|
104
|
+
async unenroll(enrollmentId: string): Promise<void> {
|
|
105
|
+
await this.http.delete(`/v1/enrollments/${enrollmentId}`);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Get enrollment progress
|
|
110
|
+
*/
|
|
111
|
+
async getEnrollmentProgress(enrollmentId: string): Promise<EnrollmentProgress> {
|
|
112
|
+
const response = await this.http.get<EnrollmentProgress>(`/v1/enrollments/${enrollmentId}/progress`);
|
|
113
|
+
return response.data;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Get current week schedule for enrollment
|
|
118
|
+
*/
|
|
119
|
+
async getCurrentWeek(enrollmentId: string): Promise<CurrentWeekSchedule> {
|
|
120
|
+
const response = await this.http.get<CurrentWeekSchedule>(`/v1/enrollments/${enrollmentId}/current-week`);
|
|
121
|
+
return response.data;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import type { HttpClient } from '../utils/http';
|
|
2
|
+
import type {
|
|
3
|
+
WorkoutSession,
|
|
4
|
+
CreateWorkoutSessionRequest,
|
|
5
|
+
UpdateWorkoutSessionRequest,
|
|
6
|
+
ListWorkoutSessionsParams,
|
|
7
|
+
ExerciseHistory,
|
|
8
|
+
PersonalRecord,
|
|
9
|
+
PersonalRecordHistory,
|
|
10
|
+
ListResponse,
|
|
11
|
+
AddExerciseItem,
|
|
12
|
+
} from '../types';
|
|
13
|
+
import { createPaginatedIterator, type PaginatedIterator } from '../utils/pagination';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Workout Sessions resource
|
|
17
|
+
* Handles workout performance tracking
|
|
18
|
+
*/
|
|
19
|
+
export class SessionsResource {
|
|
20
|
+
constructor(private http: HttpClient) {}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* List workout sessions with filtering
|
|
24
|
+
*/
|
|
25
|
+
async list(params?: ListWorkoutSessionsParams): Promise<ListResponse<WorkoutSession>> {
|
|
26
|
+
const response = await this.http.get<ListResponse<WorkoutSession>>('/v1/workout-sessions', params);
|
|
27
|
+
return response.data;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* List sessions with automatic pagination
|
|
32
|
+
*/
|
|
33
|
+
listAutoPaginate(params?: ListWorkoutSessionsParams): PaginatedIterator<WorkoutSession> {
|
|
34
|
+
return createPaginatedIterator((cursor) =>
|
|
35
|
+
this.list({ ...params, cursor })
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Create a new workout session
|
|
41
|
+
*/
|
|
42
|
+
async create(request: CreateWorkoutSessionRequest): Promise<WorkoutSession> {
|
|
43
|
+
const response = await this.http.post<WorkoutSession>('/v1/workout-sessions', request);
|
|
44
|
+
return response.data;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Start a workout session (convenience method)
|
|
49
|
+
*/
|
|
50
|
+
async start(request: Omit<CreateWorkoutSessionRequest, 'status'>): Promise<WorkoutSession> {
|
|
51
|
+
return this.create({ ...request, status: 'in_progress' });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Get specific session with all exercise data
|
|
56
|
+
*/
|
|
57
|
+
async get(sessionId: string): Promise<WorkoutSession> {
|
|
58
|
+
const response = await this.http.get<WorkoutSession>(`/v1/workout-sessions/${sessionId}`);
|
|
59
|
+
return response.data;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Update a workout session
|
|
64
|
+
*/
|
|
65
|
+
async update(sessionId: string, request: UpdateWorkoutSessionRequest): Promise<WorkoutSession> {
|
|
66
|
+
const response = await this.http.patch<WorkoutSession>(`/v1/workout-sessions/${sessionId}`, request);
|
|
67
|
+
return response.data;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Complete a workout session (convenience method)
|
|
72
|
+
*/
|
|
73
|
+
async complete(sessionId: string, notes?: string): Promise<WorkoutSession> {
|
|
74
|
+
return this.update(sessionId, {
|
|
75
|
+
status: 'completed',
|
|
76
|
+
completedAt: new Date().toISOString(),
|
|
77
|
+
...(notes && { notes }),
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Add exercises to a session (convenience method)
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* await client.sessions.addExercises('session-123', [
|
|
87
|
+
* { exerciseId: 'ex-1', targetSets: 3 },
|
|
88
|
+
* { exerciseId: 'ex-2', targetSets: 4, notes: 'Focus on form' }
|
|
89
|
+
* ]);
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
async addExercises(sessionId: string, exercises: AddExerciseItem[]): Promise<WorkoutSession> {
|
|
93
|
+
return this.update(sessionId, { addExercises: exercises });
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Delete a workout session
|
|
98
|
+
*/
|
|
99
|
+
async delete(sessionId: string): Promise<void> {
|
|
100
|
+
await this.http.delete(`/v1/workout-sessions/${sessionId}`);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Get all sessions for a specific workout
|
|
105
|
+
*/
|
|
106
|
+
async getSessionsByWorkout(workoutId: string, params?: ListWorkoutSessionsParams): Promise<ListResponse<WorkoutSession>> {
|
|
107
|
+
const response = await this.http.get<ListResponse<WorkoutSession>>(`/v1/workouts/${workoutId}/sessions`, params);
|
|
108
|
+
return response.data;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Get exercise performance history across sessions
|
|
113
|
+
*/
|
|
114
|
+
async getExerciseHistory(exerciseId: string): Promise<ExerciseHistory> {
|
|
115
|
+
const response = await this.http.get<ExerciseHistory>(`/v1/exercises/${exerciseId}/history`);
|
|
116
|
+
return response.data;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Get user's personal records
|
|
121
|
+
*/
|
|
122
|
+
async getPersonalRecords(): Promise<ListResponse<PersonalRecord>> {
|
|
123
|
+
const response = await this.http.get<ListResponse<PersonalRecord>>('/v1/personal-records');
|
|
124
|
+
return response.data;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Get personal records for a specific exercise
|
|
129
|
+
*/
|
|
130
|
+
async getExercisePersonalRecords(exerciseId: string): Promise<ListResponse<PersonalRecord>> {
|
|
131
|
+
const response = await this.http.get<ListResponse<PersonalRecord>>(`/v1/exercises/${exerciseId}/personal-records`);
|
|
132
|
+
return response.data;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Get personal record progression history for an exercise
|
|
137
|
+
*/
|
|
138
|
+
async getPersonalRecordHistory(exerciseId: string): Promise<ListResponse<PersonalRecordHistory>> {
|
|
139
|
+
const response = await this.http.get<ListResponse<PersonalRecordHistory>>(`/v1/exercises/${exerciseId}/personal-records/history`);
|
|
140
|
+
return response.data;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import type { HttpClient } from '../utils/http';
|
|
2
|
+
import type {
|
|
3
|
+
User,
|
|
4
|
+
UserPreferences,
|
|
5
|
+
UpdateUserRequest,
|
|
6
|
+
UpdatePreferencesRequest,
|
|
7
|
+
ListResponse,
|
|
8
|
+
ListParams,
|
|
9
|
+
} from '../types';
|
|
10
|
+
import { createPaginatedIterator, type PaginatedIterator } from '../utils/pagination';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Users resource
|
|
14
|
+
* Handles user profile and preferences operations
|
|
15
|
+
*/
|
|
16
|
+
export class UsersResource {
|
|
17
|
+
constructor(private http: HttpClient) {}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Get current authenticated user
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* const user = await client.users.me();
|
|
25
|
+
* console.log(user.name, user.email);
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
async me(): Promise<User> {
|
|
29
|
+
const response = await this.http.get<User>('/v1/users/me');
|
|
30
|
+
return response.data;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Update current user profile
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* const user = await client.users.update({
|
|
39
|
+
* name: 'Updated Name',
|
|
40
|
+
* isOnboarded: true
|
|
41
|
+
* });
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
async update(request: UpdateUserRequest): Promise<User> {
|
|
45
|
+
const response = await this.http.patch<User>('/v1/users/me', request);
|
|
46
|
+
return response.data;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Get user preferences
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* const prefs = await client.users.getPreferences();
|
|
55
|
+
* console.log(prefs.measurementSystem); // 'metric' or 'imperial'
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
async getPreferences(): Promise<UserPreferences> {
|
|
59
|
+
const response = await this.http.get<UserPreferences>('/v1/users/me/preferences');
|
|
60
|
+
return response.data;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Update user preferences
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* const prefs = await client.users.updatePreferences({
|
|
69
|
+
* measurementSystem: 'imperial'
|
|
70
|
+
* });
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
async updatePreferences(request: UpdatePreferencesRequest): Promise<UserPreferences> {
|
|
74
|
+
const response = await this.http.patch<UserPreferences>('/v1/users/me/preferences', request);
|
|
75
|
+
return response.data;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* List all users (for admin/public lists)
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* const { data, pageInfo } = await client.users.list({ limit: 20 });
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
async list(params?: ListParams): Promise<ListResponse<User>> {
|
|
87
|
+
const response = await this.http.get<ListResponse<User>>('/v1/users', params);
|
|
88
|
+
return response.data;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Search for users by name or email
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```typescript
|
|
96
|
+
* const { data, pageInfo } = await client.users.search({ q: 'john' });
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
async search(params: { q: string; limit?: number; cursor?: string }): Promise<ListResponse<User>> {
|
|
100
|
+
const response = await this.http.get<ListResponse<User>>('/v1/users/search', params);
|
|
101
|
+
return response.data;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* List all users with automatic pagination
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```typescript
|
|
109
|
+
* for await (const user of client.users.listAutoPaginate({ limit: 100 })) {
|
|
110
|
+
* console.log(user.name);
|
|
111
|
+
* }
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
listAutoPaginate(params?: ListParams): PaginatedIterator<User> {
|
|
115
|
+
return createPaginatedIterator((cursor) =>
|
|
116
|
+
this.list({ ...params, cursor })
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Get specific user by ID
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```typescript
|
|
125
|
+
* const user = await client.users.get('user-id');
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
async get(userId: string): Promise<User> {
|
|
129
|
+
const response = await this.http.get<User>(`/v1/users/${userId}`);
|
|
130
|
+
return response.data;
|
|
131
|
+
}
|
|
132
|
+
}
|