Skip to content

Commit 93aabdd

Browse files
author
Bruno Besson
committed
toutouyoutou
1 parent 7ffd2c4 commit 93aabdd

File tree

5 files changed

+31
-33
lines changed

5 files changed

+31
-33
lines changed

src/repository/activity.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Except, SetOptional, SetRequired } from 'type-fest';
2-
import isISO8601 from 'validator/lib/isISO8601';
2+
import validator from 'validator';
33
import { z } from 'zod';
44

55
import { LineString } from './geojson.js';
@@ -12,7 +12,7 @@ export const Activity = z.object({
1212
userId: z.number().int().positive(),
1313
vendor: Vendor,
1414
vendorId: z.string().min(1),
15-
date: z.string().refine(isISO8601, {
15+
date: z.string().refine(validator.isISO8601, {
1616
message: 'String must be an ISO-8601 date',
1717
}),
1818
name: z.string().min(1).optional(),

src/server/decathlon/decathlon.api.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import axios from 'axios';
2-
import isISO8601 from 'validator/lib/isISO8601';
2+
import validator from 'validator';
33
import { z } from 'zod';
44

55
import config from '../../config.js';
@@ -20,7 +20,7 @@ export const Activity = z.object({
2020
id: z.string().min(5).max(100),
2121
name: z.string().max(100).optional(),
2222
sport: z.string().regex(/^\/v2\/sports\/\d+$/),
23-
startdate: z.string().refine(isISO8601, {
23+
startdate: z.string().refine(validator.isISO8601, {
2424
message: 'String must be an ISO-8601 date',
2525
}),
2626
duration: z.number().nonnegative().optional(),

src/server/polar/polar.api.ts

+7-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import axios from 'axios';
2-
import isISO8601 from 'validator/lib/isISO8601';
3-
import isURL from 'validator/lib/isURL';
4-
import isUUID from 'validator/lib/isUUID';
2+
import validator from 'validator';
53
import { z } from 'zod';
64

75
import config from '../../config.js';
@@ -34,10 +32,10 @@ const CreatedWebhookInfo = z.object({
3432
data: z.object({
3533
id: z.string().min(1).max(50),
3634
events: z.array(WebhookType),
37-
url: z.string().refine(isURL, {
35+
url: z.string().refine(validator.isURL, {
3836
message: 'String must be an URL',
3937
}),
40-
signature_secret_key: z.string().refine(isUUID, {
38+
signature_secret_key: z.string().refine(validator.isUUID, {
4139
message: 'String must be an UUID',
4240
}),
4341
}),
@@ -50,7 +48,7 @@ const WebhookInfo = z.object({
5048
z.object({
5149
id: z.string(),
5250
events: z.array(WebhookType),
53-
url: z.string().refine(isURL, {
51+
url: z.string().refine(validator.isURL, {
5452
message: 'String must be an URL',
5553
}),
5654
}),
@@ -61,7 +59,7 @@ export type WebhookInfo = z.infer<typeof WebhookInfo>;
6159

6260
const WebhookPingEvent = z.object({
6361
event: z.literal('PING'),
64-
timestamp: z.string().refine(isISO8601, {
62+
timestamp: z.string().refine(validator.isISO8601, {
6563
message: 'String must be an ISO-8601 date',
6664
}),
6765
});
@@ -82,7 +80,7 @@ const WebhookExerciseEvent = z.object({
8280
})
8381
.pipe(z.bigint()),
8482
entity_id: z.string().min(1).max(50),
85-
timestamp: z.string().refine(isISO8601, {
83+
timestamp: z.string().refine(validator.isISO8601, {
8684
message: 'String must be an ISO-8601 date',
8785
}),
8886
});
@@ -257,7 +255,7 @@ export type SportType = z.infer<typeof SportType>;
257255

258256
const Exercise = z.object({
259257
id: z.string().min(1).max(50),
260-
start_time: z.string().refine(isISO8601, {
258+
start_time: z.string().refine(validator.isISO8601, {
261259
message: 'String must be an ISO-8601 date',
262260
}),
263261
start_time_utc_offset: z.number().int(),

src/server/polar/polar.service.ts

+15-15
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import { createHmac } from 'crypto';
22

33
import dayjs from 'dayjs';
4-
import duration from 'dayjs/plugin/duration.js';
5-
import { parse } from 'iso8601-duration';
4+
import { parse, toSeconds } from 'iso8601-duration';
65
import invariant from 'tiny-invariant';
76

87
import { NotFoundError } from '../../errors.js';
@@ -19,8 +18,6 @@ import { userService } from '../../user.service.js';
1918

2019
import { WebhookEvent, isWebhookPingEvent, polarApi, type Exercise } from './polar.api.js';
2120

22-
dayjs.extend(duration);
23-
2421
export class PolarService {
2522
public async requestAccessTokenAndSetupUser(c2cId: number, authorizationCode: string): Promise<void> {
2623
const auth = await polarApi.exchangeToken(authorizationCode);
@@ -171,30 +168,33 @@ export class PolarService {
171168
}
172169

173170
private asRepositoryActivity(exercise: Exercise, geojson: LineString): NewActivityWithGeometry {
171+
const startDate = this.localDate(exercise);
174172
return {
175173
vendor: 'polar' as Vendor,
176174
vendorId: exercise.id,
177-
date: this.localDate(exercise),
175+
date: startDate,
178176
type: exercise.sport,
179177
geojson,
180178
...(exercise.distance && { length: Math.round(exercise.distance) }), // float in Polar API, integer in DB
181-
...(exercise.duration && { duration: this.duration(exercise.duration) }), // ISO8601 duration in Polar API
179+
...(exercise.duration && { duration: this.duration(exercise.duration, dayjs(startDate).toDate()) }), // ISO8601 duration in Polar API
182180
};
183181
}
184182

185183
private localDate(exercise: Exercise): string {
186184
const isNegative = exercise.start_time_utc_offset < 0;
187-
const offset = dayjs
188-
.duration({
189-
hours: Math.floor(Math.abs(exercise.start_time_utc_offset) / 60),
190-
minutes: Math.abs(exercise.start_time_utc_offset) % 60,
191-
})
192-
.format('HH:mm');
193-
return exercise.start_time + (isNegative ? '-' : '+') + offset;
185+
const hours = Math.floor(Math.abs(exercise.start_time_utc_offset) / 60);
186+
const minutes = Math.abs(exercise.start_time_utc_offset) % 60;
187+
return (
188+
exercise.start_time +
189+
(isNegative ? '-' : '+') +
190+
hours.toString().padStart(2, '0') +
191+
':' +
192+
minutes.toString().padStart(2, '0')
193+
);
194194
}
195195

196-
private duration(duration: string): number {
197-
return Math.round(dayjs.duration(parse(duration)).asSeconds());
196+
private duration(duration: string, startDate: Date): number {
197+
return Math.round(toSeconds(parse(duration), startDate));
198198
}
199199
}
200200

src/server/strava/strava.api.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import axios from 'axios';
2-
import isISO8601 from 'validator/lib/isISO8601';
2+
import validator from 'validator';
33
import { z } from 'zod';
44

55
import config from '../../config.js';
@@ -87,10 +87,10 @@ export const Activity = z.object({
8787
id: z.number().int().positive(),
8888
name: z.string(),
8989
sport_type: SportType,
90-
start_date: z.string().refine(isISO8601, {
90+
start_date: z.string().refine(validator.isISO8601, {
9191
message: 'String must be an ISO-8601 date',
9292
}),
93-
start_date_local: z.string().refine(isISO8601, {
93+
start_date_local: z.string().refine(validator.isISO8601, {
9494
message: 'String must be an ISO-8601 date',
9595
}),
9696
distance: z.number().nonnegative(), // in meters
@@ -138,10 +138,10 @@ export const Subscription = z.object({
138138
id: z.number().int().positive(),
139139
application_id: z.number().int().positive(),
140140
callback_url: z.string().url(),
141-
created_at: z.string().refine(isISO8601, {
141+
created_at: z.string().refine(validator.isISO8601, {
142142
message: 'String must be an ISO-8601 date',
143143
}),
144-
updated_at: z.string().refine(isISO8601, {
144+
updated_at: z.string().refine(validator.isISO8601, {
145145
message: 'String must be an ISO-8601 date',
146146
}),
147147
});

0 commit comments

Comments
 (0)