hevy-shared 1.0.960 → 1.0.962

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.
Files changed (88) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc +21 -0
  3. package/.github/workflows/ci.yml +15 -0
  4. package/.github/workflows/npm-publish.yml +59 -0
  5. package/.github/workflows/pr-auto-assign.yml +15 -0
  6. package/.prettierrc.js +5 -0
  7. package/README.md +2 -17
  8. package/built/chat.d.ts +23 -25
  9. package/built/coachPlans.d.ts +1 -2
  10. package/built/coachPlans.js +2 -2
  11. package/built/filterExercises.d.ts +3 -19
  12. package/built/filterExercises.js +60 -72
  13. package/built/index.d.ts +304 -1140
  14. package/built/index.js +75 -269
  15. package/built/setIndicatorUtils.d.ts +3 -4
  16. package/built/setIndicatorUtils.js +1 -15
  17. package/built/tests/utils.test.js +0 -748
  18. package/built/tests/workoutVolume.test.js +49 -165
  19. package/built/units.d.ts +7 -14
  20. package/built/units.js +14 -24
  21. package/built/utils.d.ts +5 -192
  22. package/built/utils.js +85 -598
  23. package/built/websocket.d.ts +2 -14
  24. package/built/workoutVolume.d.ts +5 -24
  25. package/built/workoutVolume.js +34 -25
  26. package/jest.config.js +4 -0
  27. package/package.json +10 -32
  28. package/src/chat.ts +130 -0
  29. package/src/coachPlans.ts +57 -0
  30. package/src/constants.ts +14 -0
  31. package/src/filterExercises.ts +222 -0
  32. package/src/index.ts +1576 -0
  33. package/src/setIndicatorUtils.ts +137 -0
  34. package/src/tests/utils.test.ts +156 -0
  35. package/src/tests/workoutVolume.test.ts +93 -0
  36. package/src/units.ts +41 -0
  37. package/src/utils.ts +516 -0
  38. package/src/websocket.ts +36 -0
  39. package/src/workoutVolume.ts +175 -0
  40. package/tsconfig.json +70 -0
  41. package/built/API/APIClient.d.ts +0 -157
  42. package/built/API/APIClient.js +0 -381
  43. package/built/API/index.d.ts +0 -2
  44. package/built/API/index.js +0 -18
  45. package/built/API/types.d.ts +0 -38
  46. package/built/API/types.js +0 -18
  47. package/built/adjustEventTokens.d.ts +0 -16
  48. package/built/adjustEventTokens.js +0 -18
  49. package/built/adminPermissions.d.ts +0 -4
  50. package/built/adminPermissions.js +0 -22
  51. package/built/async.d.ts +0 -50
  52. package/built/async.js +0 -170
  53. package/built/cue.d.ts +0 -12
  54. package/built/cue.js +0 -22
  55. package/built/exerciseLocaleUtils.d.ts +0 -17
  56. package/built/exerciseLocaleUtils.js +0 -62
  57. package/built/hevyTrainer.d.ts +0 -250
  58. package/built/hevyTrainer.js +0 -676
  59. package/built/muscleHeatmaps.d.ts +0 -31
  60. package/built/muscleHeatmaps.js +0 -68
  61. package/built/muscleSplits.d.ts +0 -36
  62. package/built/muscleSplits.js +0 -100
  63. package/built/normalizedWorkoutUtils.d.ts +0 -88
  64. package/built/normalizedWorkoutUtils.js +0 -112
  65. package/built/notifications.d.ts +0 -215
  66. package/built/notifications.js +0 -9
  67. package/built/routineUtils.d.ts +0 -14
  68. package/built/routineUtils.js +0 -186
  69. package/built/schemas.d.ts +0 -6
  70. package/built/schemas.js +0 -12
  71. package/built/tests/async.test.d.ts +0 -1
  72. package/built/tests/async.test.js +0 -49
  73. package/built/tests/hevyTrainer.test.d.ts +0 -1
  74. package/built/tests/hevyTrainer.test.js +0 -1199
  75. package/built/tests/muscleSplit.test.d.ts +0 -1
  76. package/built/tests/muscleSplit.test.js +0 -153
  77. package/built/tests/routineUtils.test.d.ts +0 -1
  78. package/built/tests/routineUtils.test.js +0 -745
  79. package/built/tests/testUtils.d.ts +0 -85
  80. package/built/tests/testUtils.js +0 -319
  81. package/built/translations/index.d.ts +0 -2
  82. package/built/translations/index.js +0 -18
  83. package/built/translations/translationUtils.d.ts +0 -2
  84. package/built/translations/translationUtils.js +0 -61
  85. package/built/translations/types.d.ts +0 -8
  86. package/built/translations/types.js +0 -20
  87. package/built/typeUtils.d.ts +0 -70
  88. package/built/typeUtils.js +0 -55
@@ -1,4 +1,3 @@
1
- import { Program, BaseRoutine } from '.';
2
1
  import { NewMessageChatUpdate, MessageDeletedChatUpdate, NewConversationChatUpdate } from './chat';
3
2
  export interface PingChatUpdate {
4
3
  type: 'websocket-ping';
@@ -6,25 +5,14 @@ export interface PingChatUpdate {
6
5
  export interface PongChatUpdate {
7
6
  type: 'websocket-pong';
8
7
  }
9
- export interface CoachClientsUpdated {
8
+ export interface CoachesClientsUpdated {
10
9
  type: 'coaches-clients-updated';
11
10
  new_client_ids: string[];
12
11
  removed_client_ids: string[];
13
12
  }
14
- export interface CoachProgramUpdated {
15
- type: 'coaches-program-updated';
16
- updated_program: Program;
17
- }
18
- export interface CoachRoutineUpdated {
19
- type: 'coaches-routine-updated';
20
- updated_routine: BaseRoutine;
21
- }
22
- export interface CoachExerciseLibraryUpdated {
23
- type: 'coaches-exercise-library-updated';
24
- }
25
13
  export interface WebsocketMessageRequest {
26
14
  message: HevyWebsocketMessage;
27
15
  recipient_user_ids: string[];
28
16
  }
29
- export type HevyWebsocketMessage = NewMessageChatUpdate | MessageDeletedChatUpdate | NewConversationChatUpdate | PingChatUpdate | PongChatUpdate | CoachClientsUpdated | CoachProgramUpdated | CoachRoutineUpdated | CoachExerciseLibraryUpdated;
17
+ export type HevyWebsocketMessage = NewMessageChatUpdate | MessageDeletedChatUpdate | NewConversationChatUpdate | PingChatUpdate | PongChatUpdate | CoachesClientsUpdated;
30
18
  export declare const isHevyWebsocketMessage: (message?: any) => message is HevyWebsocketMessage;
@@ -1,29 +1,11 @@
1
- import { BodyMeasurement, ExerciseType, BaseExerciseTemplate, WorkoutExerciseSet } from '.';
2
- export declare const isVolumeDoublingSupportableForExerciseTemplate: (exerciseTemplate: Pick<BaseExerciseTemplate, "equipment_category" | "exercise_type">) => boolean;
3
- export interface VolumeCalculableWorkout {
4
- exercises: {
5
- exercise_type: ExerciseType;
6
- exercise_template_id: string;
7
- volume_doubling_enabled: boolean;
8
- hundred_percent_bodyweight_exercise: boolean;
9
- sets: Pick<WorkoutExerciseSet, 'indicator' | 'weight_kg' | 'reps' | 'distance_meters' | 'duration_seconds'>[];
10
- }[];
11
- include_warmup_sets: boolean;
12
- }
13
- export interface TimestampedVolumeCalculableWorkout extends VolumeCalculableWorkout {
14
- start_time: number;
15
- }
1
+ import { BodyMeasurement, ExerciseType, Workout } from '.';
2
+ export declare const is100PercentBodyWeightExercise: (exerciseTemplateId: string) => boolean;
16
3
  interface WorkoutVolumeKgProps {
17
- workout: TimestampedVolumeCalculableWorkout;
18
- measurements: Pick<BodyMeasurement, 'date' | 'weight_kg'>[];
4
+ workout: Workout;
5
+ measurements: BodyMeasurement[];
19
6
  }
20
7
  export type BodyWeightMeasurement = BodyMeasurement & Required<Pick<BodyMeasurement, 'weight_kg'>>;
21
8
  export declare const workoutVolumeKg: ({ workout, measurements, }: WorkoutVolumeKgProps) => number;
22
- interface EstimatedWorkoutVolumeKgProps {
23
- workout: VolumeCalculableWorkout;
24
- bodyweightKg: number;
25
- }
26
- export declare const estimatedWorkoutVolumeKg: ({ workout, bodyweightKg, }: EstimatedWorkoutVolumeKgProps) => number;
27
9
  /**
28
10
  * Given a date, this will return the nearest bodyweight value
29
11
  * that was logged before it.
@@ -33,14 +15,13 @@ export interface WorkoutVolumeSetsVolumeKgProps {
33
15
  bodyweightKg: number;
34
16
  sets: WorkoutVolumeSet[];
35
17
  }
18
+ export declare const workoutVolumeSetsVolumeKg: ({ bodyweightKg, sets, }: WorkoutVolumeSetsVolumeKgProps) => number;
36
19
  export interface WorkoutVolumeSet {
37
20
  type: ExerciseType;
38
21
  exerciseTemplateId: string;
39
22
  weightKg: number;
40
23
  reps: number;
41
24
  distanceMeters: number;
42
- volumeDoublingEnabled?: boolean;
43
- hundredPercentBodyweightExercise: boolean;
44
25
  }
45
26
  export declare const setVolumeKg: (set: WorkoutVolumeSet, bodyweightKg: number) => number;
46
27
  export {};
@@ -1,13 +1,35 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.setVolumeKg = exports.getClosestRelevantBodyWeightKgForDate = exports.estimatedWorkoutVolumeKg = exports.workoutVolumeKg = exports.isVolumeDoublingSupportableForExerciseTemplate = void 0;
3
+ exports.setVolumeKg = exports.workoutVolumeSetsVolumeKg = exports.getClosestRelevantBodyWeightKgForDate = exports.workoutVolumeKg = exports.is100PercentBodyWeightExercise = void 0;
4
4
  const lodash_1 = require("lodash");
5
5
  const _1 = require(".");
6
- const isVolumeDoublingSupportableForExerciseTemplate = (exerciseTemplate) => {
7
- return (exerciseTemplate.equipment_category === 'dumbbell' &&
8
- exerciseTemplate.exercise_type === 'weight_reps');
6
+ const is100PercentBodyWeightExercise = (exerciseTemplateId) => {
7
+ const exerciseTemplateIds = new Set([
8
+ '1B2B1E7C',
9
+ '729237D1',
10
+ '2C37EC5E',
11
+ '56808FD2',
12
+ 'A91838C0',
13
+ 'EE2938D1',
14
+ '7C50F118',
15
+ 'C7AE420A',
16
+ '29083183',
17
+ '023943F1',
18
+ 'D23C609B',
19
+ '28BB4A95',
20
+ '10347BAC',
21
+ '4B4BF8C2',
22
+ '6FCD7755',
23
+ '29472BE1',
24
+ 'E9E4089F',
25
+ '51A0EDAA',
26
+ '9F9C164B',
27
+ '30F03BF0',
28
+ '90B04F96', // Handstand Push Up
29
+ ]);
30
+ return exerciseTemplateIds.has(exerciseTemplateId);
9
31
  };
10
- exports.isVolumeDoublingSupportableForExerciseTemplate = isVolumeDoublingSupportableForExerciseTemplate;
32
+ exports.is100PercentBodyWeightExercise = is100PercentBodyWeightExercise;
11
33
  const workoutVolumeKg = ({ workout, measurements, }) => {
12
34
  var _a, _b;
13
35
  const workoutDate = new Date(workout.start_time * 1000);
@@ -23,19 +45,12 @@ const workoutVolumeKg = ({ workout, measurements, }) => {
23
45
  */
24
46
  const oldestLoggedMeasurement = (_b = (_a = bodyWeightMeasurements[0]) === null || _a === void 0 ? void 0 : _a.weight_kg) !== null && _b !== void 0 ? _b : 0;
25
47
  const bodyweightKg = mostRecentMeasurementBeforeWorkout !== null && mostRecentMeasurementBeforeWorkout !== void 0 ? mostRecentMeasurementBeforeWorkout : oldestLoggedMeasurement;
26
- return workoutVolumeSetsVolumeKg({
48
+ return (0, exports.workoutVolumeSetsVolumeKg)({
27
49
  bodyweightKg,
28
50
  sets: workoutToWorkoutVolumeSets(workout),
29
51
  });
30
52
  };
31
53
  exports.workoutVolumeKg = workoutVolumeKg;
32
- const estimatedWorkoutVolumeKg = ({ workout, bodyweightKg, }) => {
33
- return workoutVolumeSetsVolumeKg({
34
- bodyweightKg,
35
- sets: workoutToWorkoutVolumeSets(workout),
36
- });
37
- };
38
- exports.estimatedWorkoutVolumeKg = estimatedWorkoutVolumeKg;
39
54
  /**
40
55
  * Given a date, this will return the nearest bodyweight value
41
56
  * that was logged before it.
@@ -50,15 +65,15 @@ const workoutVolumeSetsVolumeKg = ({ bodyweightKg, sets, }) => {
50
65
  return accu + (0, exports.setVolumeKg)(s, bodyweightKg);
51
66
  }, 0);
52
67
  };
68
+ exports.workoutVolumeSetsVolumeKg = workoutVolumeSetsVolumeKg;
53
69
  const setVolumeKg = (set, bodyweightKg) => {
54
- const { type, weightKg: originalWeightKg, reps, distanceMeters, volumeDoublingEnabled, } = set;
55
- const weightKg = originalWeightKg * (volumeDoublingEnabled ? 2 : 1);
70
+ const { type, exerciseTemplateId, weightKg, reps, distanceMeters } = set;
56
71
  switch (type) {
57
72
  case 'weight_reps':
58
73
  // eg. Bench Press (Barbell)
59
74
  return weightKg * reps;
60
75
  case 'reps_only':
61
- if (set.hundredPercentBodyweightExercise) {
76
+ if ((0, exports.is100PercentBodyWeightExercise)(exerciseTemplateId)) {
62
77
  // eg. Pull Up
63
78
  return bodyweightKg * reps;
64
79
  }
@@ -67,7 +82,7 @@ const setVolumeKg = (set, bodyweightKg) => {
67
82
  return 0;
68
83
  }
69
84
  case 'bodyweight_reps':
70
- if (set.hundredPercentBodyweightExercise) {
85
+ if ((0, exports.is100PercentBodyWeightExercise)(exerciseTemplateId)) {
71
86
  // eg. Pull Up (Weighted)
72
87
  return (weightKg + bodyweightKg) * reps;
73
88
  }
@@ -76,7 +91,7 @@ const setVolumeKg = (set, bodyweightKg) => {
76
91
  return weightKg * reps;
77
92
  }
78
93
  case 'bodyweight_assisted_reps':
79
- if (set.hundredPercentBodyweightExercise) {
94
+ if ((0, exports.is100PercentBodyWeightExercise)(exerciseTemplateId)) {
80
95
  // eg. Pull Up (Assisted)
81
96
  const bodyweightAssistedRepsVolume = (bodyweightKg - weightKg) * reps;
82
97
  return Math.max(bodyweightAssistedRepsVolume, 0);
@@ -88,8 +103,6 @@ const setVolumeKg = (set, bodyweightKg) => {
88
103
  case 'short_distance_weight':
89
104
  // eg. Farmers Walk
90
105
  return distanceMeters * weightKg;
91
- case 'weight_duration':
92
- return weightKg;
93
106
  default:
94
107
  // `duration` and `distance_duration` exercises
95
108
  return 0;
@@ -98,9 +111,7 @@ const setVolumeKg = (set, bodyweightKg) => {
98
111
  exports.setVolumeKg = setVolumeKg;
99
112
  const workoutToWorkoutVolumeSets = (workout) => {
100
113
  const unflatSets = workout.exercises.map((e) => {
101
- return e.sets
102
- .filter((s) => workout.include_warmup_sets || s.indicator !== 'warmup')
103
- .map((s) => {
114
+ return e.sets.map((s) => {
104
115
  var _a, _b, _c;
105
116
  return {
106
117
  type: e.exercise_type || 'weight_reps',
@@ -108,8 +119,6 @@ const workoutToWorkoutVolumeSets = (workout) => {
108
119
  weightKg: (_a = s.weight_kg) !== null && _a !== void 0 ? _a : 0,
109
120
  reps: (_b = s.reps) !== null && _b !== void 0 ? _b : 0,
110
121
  distanceMeters: (_c = s.distance_meters) !== null && _c !== void 0 ? _c : 0,
111
- volumeDoublingEnabled: e.volume_doubling_enabled,
112
- hundredPercentBodyweightExercise: e.hundred_percent_bodyweight_exercise,
113
122
  };
114
123
  });
115
124
  });
package/jest.config.js ADDED
@@ -0,0 +1,4 @@
1
+ module.exports = {
2
+ preset: "ts-jest",
3
+ testEnvironment: "node",
4
+ };
package/package.json CHANGED
@@ -1,57 +1,35 @@
1
1
  {
2
2
  "name": "hevy-shared",
3
- "version": "1.0.960",
3
+ "version": "1.0.962",
4
4
  "description": "",
5
5
  "main": "built/index.js",
6
6
  "types": "built/index.d.ts",
7
+ "prepare": "tsc",
7
8
  "prepublish": "tsc",
8
9
  "scripts": {
9
- "prepare": "tsc --skipLibCheck",
10
- "build": "tsc --removeComments && tsc --emitDeclarationOnly",
10
+ "build": "tsc",
11
11
  "types": "tsc --skipLibCheck",
12
12
  "p": "npm run test && npm version patch && npm run build && npm publish && git push",
13
- "ci-build": "./scripts/publish.sh",
14
13
  "lint": "eslint . --ext .ts",
15
14
  "lint-fix": "eslint . --ext .ts --fix",
16
15
  "test": "jest"
17
16
  },
18
- "exports": {
19
- ".": "./built/index.js",
20
- "./API": "./built/API/index.js",
21
- "./translations": "./built/translations/index.js"
22
- },
23
- "typesVersions": {
24
- "*": {
25
- "API": [
26
- "built/API/index.d.ts"
27
- ],
28
- "translations": [
29
- "built/translations/index.d.ts"
30
- ]
31
- }
32
- },
33
- "files": [
34
- "built"
35
- ],
36
17
  "keywords": [],
37
18
  "author": "",
38
19
  "license": "ISC",
39
20
  "devDependencies": {
40
- "@types/jest": "^29.5.12",
41
21
  "@types/lodash": "^4.14.168",
42
- "@typescript-eslint/eslint-plugin": "^8.26.0",
43
- "@typescript-eslint/parser": "^8.26.0",
44
- "eslint": "^8.57.0",
22
+ "@typescript-eslint/eslint-plugin": "^5.27.1",
23
+ "@typescript-eslint/parser": "^5.27.1",
24
+ "eslint": "^8.17.0",
45
25
  "eslint-config-prettier": "^8.5.0",
46
26
  "eslint-plugin-prettier": "^4.0.0",
47
- "jest": "^29.7.0",
27
+ "jest": "^26.6.3",
48
28
  "prettier": "^2.6.2",
49
- "ts-jest": "^29.1.2",
50
- "typescript": "5.8.2"
29
+ "ts-jest": "^26.5.0",
30
+ "typescript": "4.9.3"
51
31
  },
52
32
  "dependencies": {
53
- "dayjs": "^1.11.19",
54
- "lodash": "^4.17.21",
55
- "zod": "^4.3.6"
33
+ "lodash": "^4.17.21"
56
34
  }
57
35
  }
package/src/chat.ts ADDED
@@ -0,0 +1,130 @@
1
+ export interface PostCreateConversationRequest {
2
+ conversation_user_ids: string[];
3
+ }
4
+
5
+ export interface PostCreateConversationResponse {
6
+ conversation_id: string;
7
+ }
8
+
9
+ export interface PostMessageRequest {
10
+ conversation_id: string;
11
+ data:
12
+ | CreateTextMessageData
13
+ | CreateNewWorkoutMessageData
14
+ | CreateNewBodyMeasurementMesageData;
15
+ }
16
+
17
+ export interface PostMessageResponse {
18
+ message_id: string;
19
+ }
20
+
21
+ export interface CreateTextMessageData {
22
+ type: 'text';
23
+ text: string;
24
+ }
25
+ export interface CreateNewWorkoutMessageData {
26
+ type: 'new-workout';
27
+ workout_id: string;
28
+ }
29
+ export interface CreateNewBodyMeasurementMesageData {
30
+ type: 'new-body-measurement';
31
+ measurement_id: number;
32
+ }
33
+
34
+ export interface GetLatestMessageFromAllClientsResponse {
35
+ conversations: {
36
+ conversation_id: string;
37
+ latest_message: Message;
38
+ last_read_message_id?: string;
39
+ }[];
40
+ }
41
+ export interface PostGetMessagesRequest {
42
+ conversation_id: string;
43
+ less_than_index?: string;
44
+ limit: number;
45
+ }
46
+ export interface PostGetMessagesResponse {
47
+ messages: Message[];
48
+ last_read_message_id?: string;
49
+ has_more: boolean;
50
+ }
51
+ export interface PostSetConversationReadAtRequest {
52
+ conversation_id: string;
53
+ last_read_message_id: string;
54
+ }
55
+
56
+ export interface Conversation {
57
+ conversation_id: string;
58
+ user_ids: string[];
59
+ }
60
+
61
+ export type MessageType = 'text' | 'new-workout' | 'new-body-measurement';
62
+
63
+ export interface MessageBase {
64
+ id: string;
65
+ sender_user_id: string;
66
+ conversation_id: string;
67
+ type: MessageType;
68
+ created_at: string;
69
+ }
70
+
71
+ export interface TextMessage extends MessageBase {
72
+ type: 'text';
73
+ text: string;
74
+ }
75
+
76
+ export interface NewWorkoutMessageData {
77
+ workout_id: string;
78
+ }
79
+ export interface NewWorkoutMessage extends MessageBase {
80
+ type: 'new-workout';
81
+ data: NewWorkoutMessageData;
82
+ }
83
+
84
+ export interface NewBodyMeasurementMessageData {
85
+ measurement_id: number;
86
+ }
87
+
88
+ export interface NewBodyMeasurementMessage extends MessageBase {
89
+ type: 'new-body-measurement';
90
+ data: NewBodyMeasurementMessageData;
91
+ }
92
+
93
+ export type Message =
94
+ | TextMessage
95
+ | NewWorkoutMessage
96
+ | NewBodyMeasurementMessage;
97
+
98
+ export const isMessage = (message?: any): message is Message => {
99
+ return (
100
+ !!message &&
101
+ !!message.conversation_id &&
102
+ !!message.sender_user_id &&
103
+ !!message.type
104
+ );
105
+ };
106
+
107
+ export interface NewMessageChatUpdate {
108
+ type: 'new-message';
109
+ message: Message;
110
+ }
111
+ export interface MessageDeletedChatUpdate {
112
+ type: 'message-deleted';
113
+ message_id: string;
114
+ }
115
+ export interface NewConversationChatUpdate {
116
+ type: 'new-conversation';
117
+ conversation_id: string;
118
+ conversation_users: string[];
119
+ }
120
+
121
+ export type HevyChatUpdatePush =
122
+ | NewMessageChatUpdate
123
+ | MessageDeletedChatUpdate
124
+ | NewConversationChatUpdate;
125
+
126
+ export const isHevyChatUpdatePush = (
127
+ message?: any,
128
+ ): message is HevyChatUpdatePush => {
129
+ return !!message && typeof message.type === 'string';
130
+ };
@@ -0,0 +1,57 @@
1
+ export const HevyCoachDefaultPlan: Plan = {
2
+ maximum_clients: 3,
3
+ id: 'hevy_coach_free',
4
+ title: 'Free',
5
+ renewal_period: 'lifetime',
6
+ type: 'default',
7
+ };
8
+
9
+ export type PlanType = 'default' | 'paid_paddle' | 'trial' | 'beta';
10
+
11
+ export interface Plan {
12
+ title: string;
13
+ maximum_clients: number;
14
+ id: string;
15
+ paddle_update_payment_url?: string;
16
+ renewal_period: 'monthly' | 'lifetime';
17
+ renewal_price?: string;
18
+ renewal_currency?: string;
19
+ type: PlanType;
20
+ }
21
+ /** https://developer.paddle.com/reference/ZG9jOjI1MzU0MDI2-subscription-status-reference */
22
+ export type CoachPlanStatus =
23
+ | 'active'
24
+ | 'past_due'
25
+ | 'paused'
26
+ | 'will_pause' /** This is one we added that means the subscription will pause at the end of the current billing period */
27
+ | 'deleted';
28
+
29
+ export interface CoachsPlan extends Plan {
30
+ status: CoachPlanStatus;
31
+ renewal_date?: string;
32
+ /** Next bill data from Paddle */
33
+ next_bill?: {
34
+ amount: number;
35
+ currency: string;
36
+ date: string;
37
+ };
38
+ user_previously_started_trial: boolean;
39
+ }
40
+ export interface GetAvailableCoachPlansResponse {
41
+ available_plans: Plan[];
42
+ }
43
+ export interface GetCoachPlanResponse {
44
+ current_plan: CoachsPlan;
45
+ }
46
+ export interface CoachPayment {
47
+ id: number;
48
+ amount: number;
49
+ currency: string;
50
+ is_paid: number;
51
+ is_one_off_charge: boolean;
52
+ receipt_url: string;
53
+ payout_date: string;
54
+ }
55
+ export interface GetCoachPaymentHistoryResponse {
56
+ payments: CoachPayment[];
57
+ }
@@ -0,0 +1,14 @@
1
+ export const MAX_WORKOUT_TITLE_LENGTH = 100;
2
+ export const MAX_WORKOUT_DESCRIPTION_LENGTH = 2000;
3
+ export const MAX_WORKOUT_EXERCISE_NOTES_LENGTH = 2000;
4
+
5
+ export const MAX_ROUTINE_TITLE_LENGTH = 100;
6
+ export const MAX_ROUTINE_EXERCISE_NOTES_LENGTH = 2000;
7
+
8
+ export const MAX_EXERCISE_TITLE_LENGTH = 100;
9
+
10
+ export const MAX_COMMENT_LENGTH = 250;
11
+
12
+ export const MAX_PROFILE_FULL_NAME_LENGTH = 100;
13
+ export const MAX_PROFILE_DESCRIPTION_LENGTH = 200;
14
+ export const MAX_PROFILE_WEBSITE_LENGTH = 100;