@dgpholdings/greatoak-shared 1.1.15 → 1.1.17
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/dist/types/TApiAuth.d.ts +3 -3
- package/dist/types/TApiExerciseRecord.d.ts +1 -2
- package/dist/types/TApiUser.d.ts +8 -0
- package/dist/types/TApiUser.js +2 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.js +8 -1
- package/dist/utils/isDefined.utils.d.ts +2 -0
- package/dist/utils/isDefined.utils.js +11 -0
- package/dist/utils/record.utils.d.ts +26 -0
- package/dist/utils/record.utils.js +30 -0
- package/dist/utils/scoring.utils.d.ts +16 -0
- package/dist/utils/scoring.utils.js +60 -0
- package/dist/utils/time.util.d.ts +1 -1
- package/dist/utils/time.util.js +2 -3
- package/package.json +1 -1
package/dist/types/TApiAuth.d.ts
CHANGED
|
@@ -81,12 +81,12 @@ export type TUser = {
|
|
|
81
81
|
recoveryIssuedTimeStamp: number;
|
|
82
82
|
recoveryVerifyToken: string;
|
|
83
83
|
authMethod: TAuthType;
|
|
84
|
-
gender?: "male" | "female";
|
|
85
|
-
|
|
84
|
+
gender?: "male" | "female" | "unmentioned";
|
|
85
|
+
dob?: Date;
|
|
86
86
|
weightKg?: number;
|
|
87
87
|
heightCm?: number;
|
|
88
88
|
};
|
|
89
|
-
export type TUserSignInData = Pick<TUser, "email" | "isVerified" | "languageCountryCode" | "billingPlanType" | "billingPlanVersion" | "paymentMethod" | "authMethod">;
|
|
89
|
+
export type TUserSignInData = Pick<TUser, "email" | "isVerified" | "languageCountryCode" | "billingPlanType" | "billingPlanVersion" | "paymentMethod" | "authMethod" | "dob" | "weightKg">;
|
|
90
90
|
export type TApiForgotPasswordReq = {
|
|
91
91
|
email: string;
|
|
92
92
|
captchaToken: string;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { TTemplateData } from "./TApiTemplateData";
|
|
2
1
|
export type TRecord = {
|
|
3
2
|
isDone: boolean;
|
|
4
3
|
rpe?: string;
|
|
@@ -38,6 +37,7 @@ export type TRecordConfig = {
|
|
|
38
37
|
};
|
|
39
38
|
export type TApiExerciseRecordUpdateReq = {
|
|
40
39
|
templateId: string;
|
|
40
|
+
startTime: Date;
|
|
41
41
|
records: {
|
|
42
42
|
exerciseId: string;
|
|
43
43
|
config: TRecordConfig;
|
|
@@ -47,7 +47,6 @@ export type TApiExerciseRecordUpdateReq = {
|
|
|
47
47
|
};
|
|
48
48
|
export type TApiExerciseRecordUpdateRes = {
|
|
49
49
|
status: 201;
|
|
50
|
-
updatedTemplate: TTemplateData;
|
|
51
50
|
} | {
|
|
52
51
|
status: 400;
|
|
53
52
|
};
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
export { toNumber } from "./number.util";
|
|
2
2
|
export { mmssToSecs } from "./time.util";
|
|
3
3
|
export { countryToCurrencyCode } from "./billing.utils";
|
|
4
|
+
export { computeScoreFromRecord } from "./scoring.utils";
|
|
5
|
+
export { isDefined, isDefinedNumber } from "./isDefined.utils";
|
|
6
|
+
export { refineRecordEntry } from "./record.utils";
|
|
7
|
+
export type { TRefinedRecord, TRefinedBodyWeightRecord, TRefinedDurationRecord, TRefinedWeightRecord, } from "./record.utils";
|
package/dist/utils/index.js
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.countryToCurrencyCode = exports.mmssToSecs = exports.toNumber = void 0;
|
|
3
|
+
exports.refineRecordEntry = exports.isDefinedNumber = exports.isDefined = exports.computeScoreFromRecord = exports.countryToCurrencyCode = exports.mmssToSecs = exports.toNumber = void 0;
|
|
4
4
|
var number_util_1 = require("./number.util");
|
|
5
5
|
Object.defineProperty(exports, "toNumber", { enumerable: true, get: function () { return number_util_1.toNumber; } });
|
|
6
6
|
var time_util_1 = require("./time.util");
|
|
7
7
|
Object.defineProperty(exports, "mmssToSecs", { enumerable: true, get: function () { return time_util_1.mmssToSecs; } });
|
|
8
8
|
var billing_utils_1 = require("./billing.utils");
|
|
9
9
|
Object.defineProperty(exports, "countryToCurrencyCode", { enumerable: true, get: function () { return billing_utils_1.countryToCurrencyCode; } });
|
|
10
|
+
var scoring_utils_1 = require("./scoring.utils");
|
|
11
|
+
Object.defineProperty(exports, "computeScoreFromRecord", { enumerable: true, get: function () { return scoring_utils_1.computeScoreFromRecord; } });
|
|
12
|
+
var isDefined_utils_1 = require("./isDefined.utils");
|
|
13
|
+
Object.defineProperty(exports, "isDefined", { enumerable: true, get: function () { return isDefined_utils_1.isDefined; } });
|
|
14
|
+
Object.defineProperty(exports, "isDefinedNumber", { enumerable: true, get: function () { return isDefined_utils_1.isDefinedNumber; } });
|
|
15
|
+
var record_utils_1 = require("./record.utils");
|
|
16
|
+
Object.defineProperty(exports, "refineRecordEntry", { enumerable: true, get: function () { return record_utils_1.refineRecordEntry; } });
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isDefinedNumber = exports.isDefined = void 0;
|
|
4
|
+
const isDefined = (arg) => {
|
|
5
|
+
return arg !== null && arg !== undefined;
|
|
6
|
+
};
|
|
7
|
+
exports.isDefined = isDefined;
|
|
8
|
+
const isDefinedNumber = (value) => {
|
|
9
|
+
return (0, exports.isDefined)(value) && typeof value === "number" && !isNaN(value);
|
|
10
|
+
};
|
|
11
|
+
exports.isDefinedNumber = isDefinedNumber;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { TRecord } from "../types";
|
|
2
|
+
type RefinedBase = {
|
|
3
|
+
isDone: boolean;
|
|
4
|
+
rpe?: number;
|
|
5
|
+
rir?: number;
|
|
6
|
+
restInBetweenDurationSecs?: number;
|
|
7
|
+
setNote?: string;
|
|
8
|
+
};
|
|
9
|
+
export type TRefinedWeightRecord = RefinedBase & {
|
|
10
|
+
type: "weight-reps";
|
|
11
|
+
kg: number;
|
|
12
|
+
reps: number;
|
|
13
|
+
};
|
|
14
|
+
export type TRefinedDurationRecord = RefinedBase & {
|
|
15
|
+
type: "duration";
|
|
16
|
+
durationSecs: string;
|
|
17
|
+
auxWeightKg?: number;
|
|
18
|
+
};
|
|
19
|
+
export type TRefinedBodyWeightRecord = RefinedBase & {
|
|
20
|
+
type: "reps-only";
|
|
21
|
+
reps: number;
|
|
22
|
+
auxWeightKg?: number;
|
|
23
|
+
};
|
|
24
|
+
export type TRefinedRecord = TRefinedWeightRecord | TRefinedDurationRecord | TRefinedBodyWeightRecord;
|
|
25
|
+
export declare const refineRecordEntry: (entry: TRecord) => TRefinedRecord;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.refineRecordEntry = void 0;
|
|
4
|
+
const isDefined_utils_1 = require("./isDefined.utils");
|
|
5
|
+
const number_util_1 = require("./number.util");
|
|
6
|
+
const refineRecordEntry = (entry) => {
|
|
7
|
+
var _a, _b, _c;
|
|
8
|
+
const base = Object.assign(Object.assign(Object.assign({ isDone: entry.isDone }, ((0, isDefined_utils_1.isDefinedNumber)((0, number_util_1.toNumber)(entry.rpe)) && { rpe: (0, number_util_1.toNumber)(entry.rpe) })), ((0, isDefined_utils_1.isDefinedNumber)((0, number_util_1.toNumber)(entry.restInBetweenDurationSecs)) && {
|
|
9
|
+
restInBetweenDurationSecs: (0, number_util_1.toNumber)(entry.restInBetweenDurationSecs),
|
|
10
|
+
})), ((0, isDefined_utils_1.isDefined)(entry.setNote) && { setNote: entry.setNote }));
|
|
11
|
+
if (entry.type === "weight-reps") {
|
|
12
|
+
return Object.assign(Object.assign({}, base), { type: "weight-reps", kg: (_a = (0, number_util_1.toNumber)(entry.kg)) !== null && _a !== void 0 ? _a : 0, rir: (0, isDefined_utils_1.isDefinedNumber)((0, number_util_1.toNumber)(entry.rir))
|
|
13
|
+
? (0, number_util_1.toNumber)(entry.rir)
|
|
14
|
+
: undefined, reps: (_b = (0, number_util_1.toNumber)(entry.reps)) !== null && _b !== void 0 ? _b : 0 });
|
|
15
|
+
}
|
|
16
|
+
if (entry.type === "duration") {
|
|
17
|
+
return Object.assign(Object.assign(Object.assign({}, base), { type: "duration", durationSecs: entry.durationSecs }), ((0, isDefined_utils_1.isDefinedNumber)((0, number_util_1.toNumber)(entry.auxWeightKg)) && {
|
|
18
|
+
auxWeightKg: (0, number_util_1.toNumber)(entry.auxWeightKg),
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
if (entry.type === "reps-only") {
|
|
22
|
+
return Object.assign(Object.assign(Object.assign({}, base), { type: "reps-only", rir: (0, isDefined_utils_1.isDefinedNumber)((0, number_util_1.toNumber)(entry.rir))
|
|
23
|
+
? (0, number_util_1.toNumber)(entry.rir)
|
|
24
|
+
: undefined, reps: (_c = (0, number_util_1.toNumber)(entry.reps)) !== null && _c !== void 0 ? _c : 0 }), ((0, isDefined_utils_1.isDefinedNumber)((0, number_util_1.toNumber)(entry.auxWeightKg)) && {
|
|
25
|
+
auxWeightKg: (0, number_util_1.toNumber)(entry.auxWeightKg),
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
throw new Error(`Unknown record type: ${entry.type}`);
|
|
29
|
+
};
|
|
30
|
+
exports.refineRecordEntry = refineRecordEntry;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type TRecordType = "weight-reps" | "duration" | "body-weight";
|
|
2
|
+
export interface TUserProfile {
|
|
3
|
+
age?: number;
|
|
4
|
+
gender?: "male" | "female" | "non-binary" | "unspecified";
|
|
5
|
+
weightKg?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface TRecordInput {
|
|
8
|
+
isDone: boolean;
|
|
9
|
+
kg?: number;
|
|
10
|
+
reps?: number;
|
|
11
|
+
durationSecs?: string;
|
|
12
|
+
rpe?: number;
|
|
13
|
+
rir?: number;
|
|
14
|
+
auxWeightKg?: number;
|
|
15
|
+
}
|
|
16
|
+
export declare function computeScoreFromRecord(record: TRecordInput, recordType: TRecordType, userProfile?: TUserProfile): number;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.computeScoreFromRecord = computeScoreFromRecord;
|
|
4
|
+
const time_util_1 = require("./time.util");
|
|
5
|
+
function computeScoreFromRecord(record, recordType, userProfile) {
|
|
6
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
7
|
+
if (!record.isDone)
|
|
8
|
+
return 0;
|
|
9
|
+
// Determine load and effortFactor from record based on type
|
|
10
|
+
let load = 0;
|
|
11
|
+
let effortFactor = 0;
|
|
12
|
+
const rpe = (_a = record.rpe) !== null && _a !== void 0 ? _a : undefined;
|
|
13
|
+
const rir = (_b = record.rir) !== null && _b !== void 0 ? _b : undefined;
|
|
14
|
+
// Step 1: Determine effort factor
|
|
15
|
+
if (typeof rpe === "number") {
|
|
16
|
+
effortFactor = rpe;
|
|
17
|
+
}
|
|
18
|
+
else if (typeof rir === "number") {
|
|
19
|
+
effortFactor = 10 - rir; // lower RIR means more effort
|
|
20
|
+
}
|
|
21
|
+
// Step 2: Determine load
|
|
22
|
+
switch (recordType) {
|
|
23
|
+
case "weight-reps": {
|
|
24
|
+
const kg = (_c = record.kg) !== null && _c !== void 0 ? _c : 0;
|
|
25
|
+
const reps = (_d = record.reps) !== null && _d !== void 0 ? _d : 0;
|
|
26
|
+
load = kg * reps;
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
case "duration": {
|
|
30
|
+
const durationSecs = (0, time_util_1.mmssToSecs)((_e = record.durationSecs) !== null && _e !== void 0 ? _e : "00:00");
|
|
31
|
+
const auxWeight = (_f = record.auxWeightKg) !== null && _f !== void 0 ? _f : 0;
|
|
32
|
+
load = auxWeight > 0 ? auxWeight * durationSecs : durationSecs;
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
case "body-weight": {
|
|
36
|
+
const reps = (_g = record.reps) !== null && _g !== void 0 ? _g : 0;
|
|
37
|
+
const auxWeight = (_h = record.auxWeightKg) !== null && _h !== void 0 ? _h : 0;
|
|
38
|
+
load = auxWeight > 0 ? auxWeight * reps : reps;
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
default:
|
|
42
|
+
return 0;
|
|
43
|
+
}
|
|
44
|
+
return computeFinalScore(load, effortFactor, userProfile);
|
|
45
|
+
}
|
|
46
|
+
function computeFinalScore(load, effortFactor, userProfile) {
|
|
47
|
+
const base = Math.log10(1 + Math.max(0, load));
|
|
48
|
+
const effortBoost = 1 + Math.min(effortFactor, 10) * 0.05;
|
|
49
|
+
// Optional scaling
|
|
50
|
+
let adjustment = 1;
|
|
51
|
+
if ((userProfile === null || userProfile === void 0 ? void 0 : userProfile.gender) === "female")
|
|
52
|
+
adjustment *= 1.1;
|
|
53
|
+
if ((userProfile === null || userProfile === void 0 ? void 0 : userProfile.age) && userProfile.age > 50)
|
|
54
|
+
adjustment *= 1.15;
|
|
55
|
+
if ((userProfile === null || userProfile === void 0 ? void 0 : userProfile.weightKg) && userProfile.weightKg > 0) {
|
|
56
|
+
const normalizedWeight = 70;
|
|
57
|
+
adjustment *= normalizedWeight / userProfile.weightKg;
|
|
58
|
+
}
|
|
59
|
+
return base * effortBoost * adjustment;
|
|
60
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const mmssToSecs: (mmss: string) => number
|
|
1
|
+
export declare const mmssToSecs: (mmss: string) => number;
|
package/dist/utils/time.util.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.mmssToSecs = void 0;
|
|
4
|
-
const number_util_1 = require("./number.util");
|
|
5
4
|
const mmssToSecs = (mmss) => {
|
|
6
|
-
const [
|
|
7
|
-
return (0
|
|
5
|
+
const [min, sec] = mmss.split(":").map(Number);
|
|
6
|
+
return (min || 0) * 60 + (sec || 0);
|
|
8
7
|
};
|
|
9
8
|
exports.mmssToSecs = mmssToSecs;
|