@miguelmorales13/nestkit 0.9.0 → 0.10.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/README.md +15 -6
- package/dist/index.cjs +9 -9
- package/dist/index.js +12 -12
- package/dist/tiktok/index.cjs +29 -6
- package/dist/tiktok/index.js +29 -6
- package/dist/tiktok/tiktok.service.d.ts +24 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -580,10 +580,8 @@ descripciones a 800, que son los límites del API — pasarse devuelve un 400.
|
|
|
580
580
|
|
|
581
581
|
### `tiktok` — publicar videos, y el modo que evita la auditoría
|
|
582
582
|
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
requisito de sus guías, no una cortesía: la API rechaza publicar si no se
|
|
586
|
-
consultó antes qué admite la cuenta.
|
|
583
|
+
Publicar son dos llamadas: inicializar la subida y sondear hasta que TikTok
|
|
584
|
+
termine de procesar.
|
|
587
585
|
|
|
588
586
|
```ts
|
|
589
587
|
import { TikTokModule, TikTokService } from '@miguelmorales13/nestkit/tiktok';
|
|
@@ -593,11 +591,18 @@ export class AppModule {}
|
|
|
593
591
|
```
|
|
594
592
|
|
|
595
593
|
```ts
|
|
596
|
-
await tiktok.
|
|
594
|
+
await tiktok.userInfo(); // comprueba el token sin publicar
|
|
597
595
|
const id = await tiktok.publish({ data, title }); // sin privacyLevel: a borradores
|
|
598
596
|
await tiktok.status(id); // hasta PUBLISH_COMPLETE
|
|
599
597
|
```
|
|
600
598
|
|
|
599
|
+
**Cuidado con `creatorInfo()`.** Parece el paso previo obligatorio —así lo
|
|
600
|
+
sugiere la documentación— pero solo lo es para publicar **en directo**, y
|
|
601
|
+
además exige `video.publish`. Llamarlo con un token de borradores devuelve
|
|
602
|
+
`scope_not_authorized`, o sea que falla justo en la configuración más común.
|
|
603
|
+
Para comprobar que el token vive, `userInfo()`, que se conforma con
|
|
604
|
+
`user.info.basic`.
|
|
605
|
+
|
|
601
606
|
**La diferencia entre los dos modos importa mucho al principio.** En *Direct
|
|
602
607
|
Post* el video sale en vivo, pero exige el permiso `video.publish`, que solo se
|
|
603
608
|
consigue pasando una auditoría de TikTok de varias semanas —y hasta aprobarla
|
|
@@ -1072,9 +1077,13 @@ trae los datos.
|
|
|
1072
1077
|
| `@miguelmorales13/nestkit/i18n` | `I18nModule` (wrapper de `nestjs-i18n`), `translateOr` |
|
|
1073
1078
|
| `@miguelmorales13/nestkit/bootstrap` | `applyNestKitDefaults` |
|
|
1074
1079
|
|
|
1080
|
+
## Cambios recientes
|
|
1081
|
+
|
|
1082
|
+
Qué se añadió en cada versión y por qué está hecho así: [CAMBIOS.md](./CAMBIOS.md).
|
|
1083
|
+
|
|
1075
1084
|
## Estado del paquete
|
|
1076
1085
|
|
|
1077
|
-
`0.
|
|
1086
|
+
`0.10.0`. Sin adaptador Mongo real. Sin tests unitarios propios.
|
|
1078
1087
|
|
|
1079
1088
|
`auth/oauth` y `umami` sí tienen un consumidor real: **nutrimx** corre su acceso con Google y
|
|
1080
1089
|
Facebook sobre este módulo en producción. El resto sigue sin ejercitarse de verdad.
|
package/dist/index.cjs
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var _chunkSPTDXUEDcjs = require('./chunk-SPTDXUED.cjs');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
var
|
|
11
|
+
var _chunkRF75KC63cjs = require('./chunk-RF75KC63.cjs');
|
|
12
12
|
require('./chunk-MR2IFCZE.cjs');
|
|
13
13
|
|
|
14
14
|
|
|
@@ -25,30 +25,30 @@ var _chunkTJHRABMLcjs = require('./chunk-TJHRABML.cjs');
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
var _chunk3CLYZC3Tcjs = require('./chunk-3CLYZC3T.cjs');
|
|
28
|
-
require('./chunk-7SOM7EZP.cjs');
|
|
29
28
|
|
|
30
29
|
|
|
30
|
+
var _chunkQS2W5XCQcjs = require('./chunk-QS2W5XCQ.cjs');
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
|
|
34
|
+
var _chunkM3EL5O6Tcjs = require('./chunk-M3EL5O6T.cjs');
|
|
35
|
+
require('./chunk-7SOM7EZP.cjs');
|
|
34
36
|
|
|
35
|
-
var _chunkFDNGAYTZcjs = require('./chunk-FDNGAYTZ.cjs');
|
|
36
37
|
|
|
37
38
|
|
|
38
|
-
var _chunkJ7TURDALcjs = require('./chunk-J7TURDAL.cjs');
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
var _chunkZA56XBCKcjs = require('./chunk-ZA56XBCK.cjs');
|
|
42
41
|
|
|
42
|
+
var _chunkFDNGAYTZcjs = require('./chunk-FDNGAYTZ.cjs');
|
|
43
43
|
|
|
44
|
-
var _chunkR7BVS6CIcjs = require('./chunk-R7BVS6CI.cjs');
|
|
45
44
|
|
|
45
|
+
var _chunkJ7TURDALcjs = require('./chunk-J7TURDAL.cjs');
|
|
46
46
|
|
|
47
|
-
var _chunkQS2W5XCQcjs = require('./chunk-QS2W5XCQ.cjs');
|
|
48
47
|
|
|
48
|
+
var _chunkZA56XBCKcjs = require('./chunk-ZA56XBCK.cjs');
|
|
49
49
|
|
|
50
50
|
|
|
51
|
-
var
|
|
51
|
+
var _chunkR7BVS6CIcjs = require('./chunk-R7BVS6CI.cjs');
|
|
52
52
|
require('./chunk-2REOCMUD.cjs');
|
|
53
53
|
|
|
54
54
|
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import "./chunk-EPVKCBPT.js";
|
|
2
|
-
import {
|
|
3
|
-
PG_POOL,
|
|
4
|
-
PgModule,
|
|
5
|
-
withTenantScope
|
|
6
|
-
} from "./chunk-VKOPDDCC.js";
|
|
7
2
|
import {
|
|
8
3
|
SUPABASE_ANON_CLIENT,
|
|
9
4
|
SUPABASE_SERVICE_ROLE_CLIENT,
|
|
10
5
|
SupabaseModule
|
|
11
6
|
} from "./chunk-PA24P76K.js";
|
|
7
|
+
import {
|
|
8
|
+
PG_POOL,
|
|
9
|
+
PgModule,
|
|
10
|
+
withTenantScope
|
|
11
|
+
} from "./chunk-VKOPDDCC.js";
|
|
12
12
|
import "./chunk-NAK4WDKS.js";
|
|
13
13
|
import {
|
|
14
14
|
REQUEST_ID_HEADER,
|
|
@@ -25,6 +25,13 @@ import {
|
|
|
25
25
|
BaseCrudService,
|
|
26
26
|
createCrudController
|
|
27
27
|
} from "./chunk-JOVBJDJ2.js";
|
|
28
|
+
import {
|
|
29
|
+
BaseResponseDto
|
|
30
|
+
} from "./chunk-XX2HPTRU.js";
|
|
31
|
+
import {
|
|
32
|
+
I18nModule,
|
|
33
|
+
translateOr
|
|
34
|
+
} from "./chunk-IYUUYCP5.js";
|
|
28
35
|
import "./chunk-DQYAIQQ5.js";
|
|
29
36
|
import {
|
|
30
37
|
ConflictAppException,
|
|
@@ -42,13 +49,6 @@ import {
|
|
|
42
49
|
import {
|
|
43
50
|
AppException
|
|
44
51
|
} from "./chunk-YFYHLYHN.js";
|
|
45
|
-
import {
|
|
46
|
-
BaseResponseDto
|
|
47
|
-
} from "./chunk-XX2HPTRU.js";
|
|
48
|
-
import {
|
|
49
|
-
I18nModule,
|
|
50
|
-
translateOr
|
|
51
|
-
} from "./chunk-IYUUYCP5.js";
|
|
52
52
|
import "./chunk-4MGIQFAJ.js";
|
|
53
53
|
export {
|
|
54
54
|
AppException,
|
package/dist/tiktok/index.cjs
CHANGED
|
@@ -13,9 +13,13 @@ var TikTokService = class {
|
|
|
13
13
|
return Boolean(this.credentials.accessToken);
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
|
-
* Datos de la cuenta
|
|
17
|
-
*
|
|
18
|
-
*
|
|
16
|
+
* Datos de la cuenta: qué niveles de privacidad admite —varían según si es
|
|
17
|
+
* privada, de empresa o de un menor— y cuánto puede durar el video.
|
|
18
|
+
*
|
|
19
|
+
* **Obligatorio solo para publicar en directo.** Para el modo borrador no
|
|
20
|
+
* hace falta, y llamarlo con un token que solo tiene `video.upload` falla
|
|
21
|
+
* con `scope_not_authorized`, porque este endpoint pide `video.publish`.
|
|
22
|
+
* De ahí que `publish()` solo lo consulte cuando va a publicar directo.
|
|
19
23
|
*/
|
|
20
24
|
async creatorInfo() {
|
|
21
25
|
return this.request("/post/publish/creator_info/query/", {});
|
|
@@ -65,6 +69,19 @@ var TikTokService = class {
|
|
|
65
69
|
}
|
|
66
70
|
return inicio.publish_id;
|
|
67
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Quién es el dueño del token.
|
|
74
|
+
*
|
|
75
|
+
* Sirve para comprobar que el token vive sin publicar nada: `creatorInfo`
|
|
76
|
+
* no vale para eso porque pide un permiso que un token de borradores no
|
|
77
|
+
* tiene. Solo necesita `user.info.basic`.
|
|
78
|
+
*/
|
|
79
|
+
async userInfo() {
|
|
80
|
+
const datos = await this.get(
|
|
81
|
+
"/user/info/?fields=open_id,display_name"
|
|
82
|
+
);
|
|
83
|
+
return datos.user;
|
|
84
|
+
}
|
|
68
85
|
/** En qué va el procesado. Termina en `PUBLISH_COMPLETE` o en un fallo. */
|
|
69
86
|
async status(publishId) {
|
|
70
87
|
return this.request(
|
|
@@ -72,17 +89,23 @@ var TikTokService = class {
|
|
|
72
89
|
{ publish_id: publishId }
|
|
73
90
|
);
|
|
74
91
|
}
|
|
75
|
-
|
|
92
|
+
get(path) {
|
|
93
|
+
return this.llamar(path, "GET");
|
|
94
|
+
}
|
|
95
|
+
request(path, body) {
|
|
96
|
+
return this.llamar(path, "POST", body);
|
|
97
|
+
}
|
|
98
|
+
async llamar(path, method, body) {
|
|
76
99
|
if (!this.credentials.accessToken) {
|
|
77
100
|
throw new Error("TikTokService: no access token configured");
|
|
78
101
|
}
|
|
79
102
|
const response = await fetch(`${API}${path}`, {
|
|
80
|
-
method
|
|
103
|
+
method,
|
|
81
104
|
headers: {
|
|
82
105
|
Authorization: `Bearer ${this.credentials.accessToken}`,
|
|
83
106
|
"Content-Type": "application/json; charset=UTF-8"
|
|
84
107
|
},
|
|
85
|
-
body: JSON.stringify(body)
|
|
108
|
+
...method === "POST" ? { body: JSON.stringify(body) } : {}
|
|
86
109
|
});
|
|
87
110
|
const text = await response.text();
|
|
88
111
|
let json;
|
package/dist/tiktok/index.js
CHANGED
|
@@ -13,9 +13,13 @@ var TikTokService = class {
|
|
|
13
13
|
return Boolean(this.credentials.accessToken);
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
|
-
* Datos de la cuenta
|
|
17
|
-
*
|
|
18
|
-
*
|
|
16
|
+
* Datos de la cuenta: qué niveles de privacidad admite —varían según si es
|
|
17
|
+
* privada, de empresa o de un menor— y cuánto puede durar el video.
|
|
18
|
+
*
|
|
19
|
+
* **Obligatorio solo para publicar en directo.** Para el modo borrador no
|
|
20
|
+
* hace falta, y llamarlo con un token que solo tiene `video.upload` falla
|
|
21
|
+
* con `scope_not_authorized`, porque este endpoint pide `video.publish`.
|
|
22
|
+
* De ahí que `publish()` solo lo consulte cuando va a publicar directo.
|
|
19
23
|
*/
|
|
20
24
|
async creatorInfo() {
|
|
21
25
|
return this.request("/post/publish/creator_info/query/", {});
|
|
@@ -65,6 +69,19 @@ var TikTokService = class {
|
|
|
65
69
|
}
|
|
66
70
|
return inicio.publish_id;
|
|
67
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Quién es el dueño del token.
|
|
74
|
+
*
|
|
75
|
+
* Sirve para comprobar que el token vive sin publicar nada: `creatorInfo`
|
|
76
|
+
* no vale para eso porque pide un permiso que un token de borradores no
|
|
77
|
+
* tiene. Solo necesita `user.info.basic`.
|
|
78
|
+
*/
|
|
79
|
+
async userInfo() {
|
|
80
|
+
const datos = await this.get(
|
|
81
|
+
"/user/info/?fields=open_id,display_name"
|
|
82
|
+
);
|
|
83
|
+
return datos.user;
|
|
84
|
+
}
|
|
68
85
|
/** En qué va el procesado. Termina en `PUBLISH_COMPLETE` o en un fallo. */
|
|
69
86
|
async status(publishId) {
|
|
70
87
|
return this.request(
|
|
@@ -72,17 +89,23 @@ var TikTokService = class {
|
|
|
72
89
|
{ publish_id: publishId }
|
|
73
90
|
);
|
|
74
91
|
}
|
|
75
|
-
|
|
92
|
+
get(path) {
|
|
93
|
+
return this.llamar(path, "GET");
|
|
94
|
+
}
|
|
95
|
+
request(path, body) {
|
|
96
|
+
return this.llamar(path, "POST", body);
|
|
97
|
+
}
|
|
98
|
+
async llamar(path, method, body) {
|
|
76
99
|
if (!this.credentials.accessToken) {
|
|
77
100
|
throw new Error("TikTokService: no access token configured");
|
|
78
101
|
}
|
|
79
102
|
const response = await fetch(`${API}${path}`, {
|
|
80
|
-
method
|
|
103
|
+
method,
|
|
81
104
|
headers: {
|
|
82
105
|
Authorization: `Bearer ${this.credentials.accessToken}`,
|
|
83
106
|
"Content-Type": "application/json; charset=UTF-8"
|
|
84
107
|
},
|
|
85
|
-
body: JSON.stringify(body)
|
|
108
|
+
...method === "POST" ? { body: JSON.stringify(body) } : {}
|
|
86
109
|
});
|
|
87
110
|
const text = await response.text();
|
|
88
111
|
let json;
|
|
@@ -29,10 +29,10 @@ export interface TikTokVideo {
|
|
|
29
29
|
/**
|
|
30
30
|
* Publica vídeos con la Content Posting API de TikTok.
|
|
31
31
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
32
|
+
* Publicar son dos llamadas: inicializar la subida y sondear hasta que TikTok
|
|
33
|
+
* termine de procesar. Hay una tercera, `creatorInfo`, que es obligatoria
|
|
34
|
+
* **solo** para publicar en directo —y que además exige `video.publish`, así
|
|
35
|
+
* que llamarla con un token de borradores falla.
|
|
36
36
|
*
|
|
37
37
|
* **Dos modos, y la diferencia importa mucho al principio.** En *Direct Post*
|
|
38
38
|
* el vídeo sale en vivo, pero exige el permiso `video.publish`, que solo se
|
|
@@ -54,9 +54,13 @@ export declare class TikTokService {
|
|
|
54
54
|
constructor(credentials: TikTokCredentials);
|
|
55
55
|
get configured(): boolean;
|
|
56
56
|
/**
|
|
57
|
-
* Datos de la cuenta
|
|
58
|
-
*
|
|
59
|
-
*
|
|
57
|
+
* Datos de la cuenta: qué niveles de privacidad admite —varían según si es
|
|
58
|
+
* privada, de empresa o de un menor— y cuánto puede durar el video.
|
|
59
|
+
*
|
|
60
|
+
* **Obligatorio solo para publicar en directo.** Para el modo borrador no
|
|
61
|
+
* hace falta, y llamarlo con un token que solo tiene `video.upload` falla
|
|
62
|
+
* con `scope_not_authorized`, porque este endpoint pide `video.publish`.
|
|
63
|
+
* De ahí que `publish()` solo lo consulte cuando va a publicar directo.
|
|
60
64
|
*/
|
|
61
65
|
creatorInfo(): Promise<TikTokCreatorInfo>;
|
|
62
66
|
/**
|
|
@@ -66,10 +70,23 @@ export declare class TikTokService {
|
|
|
66
70
|
* hace falta que la aplicación haya pasado la auditoría.
|
|
67
71
|
*/
|
|
68
72
|
publish(video: TikTokVideo): Promise<string>;
|
|
73
|
+
/**
|
|
74
|
+
* Quién es el dueño del token.
|
|
75
|
+
*
|
|
76
|
+
* Sirve para comprobar que el token vive sin publicar nada: `creatorInfo`
|
|
77
|
+
* no vale para eso porque pide un permiso que un token de borradores no
|
|
78
|
+
* tiene. Solo necesita `user.info.basic`.
|
|
79
|
+
*/
|
|
80
|
+
userInfo(): Promise<{
|
|
81
|
+
open_id: string;
|
|
82
|
+
display_name: string;
|
|
83
|
+
}>;
|
|
69
84
|
/** En qué va el procesado. Termina en `PUBLISH_COMPLETE` o en un fallo. */
|
|
70
85
|
status(publishId: string): Promise<{
|
|
71
86
|
status: string;
|
|
72
87
|
fail_reason?: string;
|
|
73
88
|
}>;
|
|
89
|
+
private get;
|
|
74
90
|
private request;
|
|
91
|
+
private llamar;
|
|
75
92
|
}
|