@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 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
- Tres llamadas, ninguna opcional: preguntar por la cuenta, inicializar la
584
- subida y sondear hasta que TikTok termine de procesar. La primera es un
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.creatorInfo(); // obligatorio antes de publicar
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.9.0`. Sin adaptador Mongo real. Sin tests unitarios propios.
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 _chunkRF75KC63cjs = require('./chunk-RF75KC63.cjs');
6
+ var _chunkSPTDXUEDcjs = require('./chunk-SPTDXUED.cjs');
7
7
 
8
8
 
9
9
 
10
10
 
11
- var _chunkSPTDXUEDcjs = require('./chunk-SPTDXUED.cjs');
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 _chunkM3EL5O6Tcjs = require('./chunk-M3EL5O6T.cjs');
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,
@@ -13,9 +13,13 @@ var TikTokService = class {
13
13
  return Boolean(this.credentials.accessToken);
14
14
  }
15
15
  /**
16
- * Datos de la cuenta. Hay que llamarlo antes de publicar: TikTok lo exige
17
- * y además dice qué niveles de privacidad admite, que varían según si la
18
- * cuenta es privada, de empresa o de menor de edad.
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
- async request(path, body) {
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: "POST",
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;
@@ -13,9 +13,13 @@ var TikTokService = class {
13
13
  return Boolean(this.credentials.accessToken);
14
14
  }
15
15
  /**
16
- * Datos de la cuenta. Hay que llamarlo antes de publicar: TikTok lo exige
17
- * y además dice qué niveles de privacidad admite, que varían según si la
18
- * cuenta es privada, de empresa o de menor de edad.
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
- async request(path, body) {
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: "POST",
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
- * El flujo son tres llamadas y ninguna es opcional: preguntar por la cuenta,
33
- * inicializar la subida, y sondear hasta que TikTok termine de procesar. La
34
- * primera es un requisito de sus guías no una cortesía—: la API rechaza
35
- * publicar sin haber consultado antes qué admite la cuenta.
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 directoy 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. Hay que llamarlo antes de publicar: TikTok lo exige
58
- * y además dice qué niveles de privacidad admite, que varían según si la
59
- * cuenta es privada, de empresa o de menor de edad.
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miguelmorales13/nestkit",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "type": "module",