@runnerpro/backend 1.31.0 → 1.31.1
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/lib/cjs/image/generateShareMap.js +29 -1
- package/lib/cjs/types/image/generateShareMap.d.ts +16 -0
- package/lib/cjs/types/image/generateShareMap.d.ts.map +1 -1
- package/lib/cjs/types/workout/saveWorkoutAplication.d.ts.map +1 -1
- package/lib/cjs/workout/saveWorkoutAplication.js +11 -1
- package/package.json +2 -1
|
@@ -25,12 +25,40 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
25
25
|
// install fonts
|
|
26
26
|
canvas_1.GlobalFonts.registerFromPath(path_1.default.join(__dirname, '../../..', 'static/fonts', 'SofiaSans-Bold.ttf'), 'SofiaSansBold');
|
|
27
27
|
canvas_1.GlobalFonts.registerFromPath(path_1.default.join(__dirname, '../../..', 'static/fonts', 'SofiaSans-Regular.ttf'), 'SofiaSans');
|
|
28
|
+
/**
|
|
29
|
+
* Genera la imagen cuadrada (1080x1080) para compartir un entreno: la foto/mapa
|
|
30
|
+
* de fondo con los datos del entreno (distancia, tiempo, ritmo o desnivel) superpuestos.
|
|
31
|
+
*
|
|
32
|
+
* @param image - Buffer de la imagen de fondo (mapa del entreno o foto por defecto).
|
|
33
|
+
* @param idWorkout - ID del entreno del que se leen los datos y el idioma de su cliente.
|
|
34
|
+
* @param options - `useDefaultPhoto: true` cuando el fondo es la foto genérica (invierte el degradado superior).
|
|
35
|
+
* @returns Buffer JPEG con la imagen, o `null` si no se pudieron leer el entreno o su cliente.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* const shareMap = await generateShareMap(image, idWorkout, { useDefaultPhoto: true });
|
|
40
|
+
* if (!shareMap) return; // ⚠️ SIEMPRE comprobar el null antes de subirla
|
|
41
|
+
* await bucket.file(`Workout/${idWorkout}-share`).save(shareMap);
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
28
44
|
const generateShareMap = (image, idWorkout, options = {}) => __awaiter(void 0, void 0, void 0, function* () {
|
|
29
45
|
const useDefaultPhoto = (options === null || options === void 0 ? void 0 : options.useDefaultPhoto) || false;
|
|
30
46
|
const [workout] = yield (0, index_1.query)('SELECT [ID], [ID CLIENTE], [TYPE], [DISTANCE], [DURATION], [DESNIVEL] FROM [WORKOUT] WHERE [ID] = ?', [idWorkout]);
|
|
47
|
+
// ⚠️ El guard va ANTES de usar `workout`: `query` devuelve [] tanto si el entreno
|
|
48
|
+
// no existe como si la consulta falló (se traga el error y loguea 'PG query error',
|
|
49
|
+
// p.ej. client_login_timeout del pool). Leer `workout.idCliente` sin comprobarlo
|
|
50
|
+
// rompía el webhook con TypeError.
|
|
51
|
+
if (!workout) {
|
|
52
|
+
// eslint-disable-next-line no-console
|
|
53
|
+
console.error(`generateShareMap: sin fila de WORKOUT para idWorkout=${idWorkout}; el entreno no existe o la consulta falló (ver 'PG query error' justo antes). No se genera la imagen de compartir.`);
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
31
56
|
const [cliente] = yield (0, index_1.query)('SELECT [PREFERRED LANGUAGE] FROM [CLIENTE] WHERE [ID] = ?', [workout.idCliente]);
|
|
32
|
-
if (!
|
|
57
|
+
if (!cliente) {
|
|
58
|
+
// eslint-disable-next-line no-console
|
|
59
|
+
console.error(`generateShareMap: sin fila de CLIENTE idCliente=${workout.idCliente} del idWorkout=${idWorkout}; el cliente no existe o la consulta falló. No se genera la imagen de compartir.`);
|
|
33
60
|
return null;
|
|
61
|
+
}
|
|
34
62
|
const width = 1080;
|
|
35
63
|
const height = 1080;
|
|
36
64
|
const canvas = (0, canvas_1.createCanvas)(width, height);
|
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/**
|
|
3
|
+
* Genera la imagen cuadrada (1080x1080) para compartir un entreno: la foto/mapa
|
|
4
|
+
* de fondo con los datos del entreno (distancia, tiempo, ritmo o desnivel) superpuestos.
|
|
5
|
+
*
|
|
6
|
+
* @param image - Buffer de la imagen de fondo (mapa del entreno o foto por defecto).
|
|
7
|
+
* @param idWorkout - ID del entreno del que se leen los datos y el idioma de su cliente.
|
|
8
|
+
* @param options - `useDefaultPhoto: true` cuando el fondo es la foto genérica (invierte el degradado superior).
|
|
9
|
+
* @returns Buffer JPEG con la imagen, o `null` si no se pudieron leer el entreno o su cliente.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const shareMap = await generateShareMap(image, idWorkout, { useDefaultPhoto: true });
|
|
14
|
+
* if (!shareMap) return; // ⚠️ SIEMPRE comprobar el null antes de subirla
|
|
15
|
+
* await bucket.file(`Workout/${idWorkout}-share`).save(shareMap);
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
2
18
|
declare const generateShareMap: (image: any, idWorkout: any, options?: {}) => Promise<Buffer>;
|
|
3
19
|
export { generateShareMap };
|
|
4
20
|
//# sourceMappingURL=generateShareMap.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateShareMap.d.ts","sourceRoot":"","sources":["../../../../src/image/generateShareMap.ts"],"names":[],"mappings":";AAcA,QAAA,MAAM,gBAAgB,+
|
|
1
|
+
{"version":3,"file":"generateShareMap.d.ts","sourceRoot":"","sources":["../../../../src/image/generateShareMap.ts"],"names":[],"mappings":";AAcA;;;;;;;;;;;;;;;GAeG;AACH,QAAA,MAAM,gBAAgB,+DA+BrB,CAAC;AA0HF,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"saveWorkoutAplication.d.ts","sourceRoot":"","sources":["../../../../src/workout/saveWorkoutAplication.ts"],"names":[],"mappings":"AAuTA;;;;;;;;;;GAUG;AACH,QAAA,MAAM,qBAAqB,SACnB,GAAG,UAED,GAAG,KACV,QAAQ,MAAM,GAAG,IAAI,CA6EvB,CAAC;
|
|
1
|
+
{"version":3,"file":"saveWorkoutAplication.d.ts","sourceRoot":"","sources":["../../../../src/workout/saveWorkoutAplication.ts"],"names":[],"mappings":"AAuTA;;;;;;;;;;GAUG;AACH,QAAA,MAAM,qBAAqB,SACnB,GAAG,UAED,GAAG,KACV,QAAQ,MAAM,GAAG,IAAI,CA6EvB,CAAC;AA+EF,OAAO,EAAE,qBAAqB,EAAE,CAAC"}
|
|
@@ -384,7 +384,13 @@ const postHooks = (idWorkout, opts) => __awaiter(void 0, void 0, void 0, functio
|
|
|
384
384
|
catch (_) {
|
|
385
385
|
// Un fallo de Mapbox no debe romper la ingesta (estado ya persistido).
|
|
386
386
|
}
|
|
387
|
-
|
|
387
|
+
try {
|
|
388
|
+
yield saveShareWorkoutImage(idWorkout, opts.type);
|
|
389
|
+
}
|
|
390
|
+
catch (_) {
|
|
391
|
+
// La imagen de compartir es accesoria: si falla (Storage, canvas, BD) no debe
|
|
392
|
+
// romper la ingesta ni escapar como unhandled rejection (así llegaba a Sentry).
|
|
393
|
+
}
|
|
388
394
|
yield (0, estructuraWorkout_1.saveDoneStructuraWorkout)(idWorkout);
|
|
389
395
|
// Logros: evaluar al completar el entreno (este es el embudo de los entrenos
|
|
390
396
|
// sincronizados). Se pasa el idWorkout para calcular el PR solo de ESTE entreno
|
|
@@ -438,6 +444,10 @@ const saveShareWorkoutImage = (id, type) => __awaiter(void 0, void 0, void 0, fu
|
|
|
438
444
|
else
|
|
439
445
|
[image] = yield storage.bucket(process.env.CLOUD_STORAGE_BUCKET_PUBLIC).file(`Workout/${id}`).download();
|
|
440
446
|
const shareMap = yield (0, generateShareMap_1.generateShareMap)(image, id);
|
|
447
|
+
// generateShareMap devuelve null si no pudo leer el entreno o su cliente (ya deja
|
|
448
|
+
// traza del motivo): sin imagen no hay nada que subir ni URL que guardar.
|
|
449
|
+
if (!shareMap)
|
|
450
|
+
return;
|
|
441
451
|
// @ts-ignore
|
|
442
452
|
yield storage.bucket(process.env.CLOUD_STORAGE_BUCKET_PUBLIC).file(`Workout/${id}-share`).save(shareMap);
|
|
443
453
|
const urlShare = `https://storage.googleapis.com/${process.env.CLOUD_STORAGE_BUCKET_PUBLIC}/Workout/${id}-share`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runnerpro/backend",
|
|
3
|
-
"version": "1.31.
|
|
3
|
+
"version": "1.31.1",
|
|
4
4
|
"description": "A collection of common backend functions",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./lib/cjs/index.js"
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"semantic-release": "semantic-release",
|
|
18
18
|
"lint": "eslint --ext .ts --ignore-path .gitignore .",
|
|
19
19
|
"test:translate-workout-garmin": "ts-node --transpile-only scripts/translateWorkoutGarmin.ts",
|
|
20
|
+
"test:generate-share-map-guard": "ts-node --transpile-only -P configs/tsconfig.cjs.json scripts/testGenerateShareMapGuard.ts",
|
|
20
21
|
"format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,json,css,scss,md}\"",
|
|
21
22
|
"prepare": "husky"
|
|
22
23
|
},
|