@miguelmorales13/nestkit 0.8.0 → 0.9.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
@@ -578,6 +578,44 @@ El token se saca en developers.pinterest.com con los permisos `boards:read`,
578
578
  `pins:read` y `pins:write`. Los títulos se recortan a 100 caracteres y las
579
579
  descripciones a 800, que son los límites del API — pasarse devuelve un 400.
580
580
 
581
+ ### `tiktok` — publicar videos, y el modo que evita la auditoría
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.
587
+
588
+ ```ts
589
+ import { TikTokModule, TikTokService } from '@miguelmorales13/nestkit/tiktok';
590
+
591
+ @Module({ imports: [TikTokModule.forRoot()] }) // lee TIKTOK_ACCESS_TOKEN
592
+ export class AppModule {}
593
+ ```
594
+
595
+ ```ts
596
+ await tiktok.creatorInfo(); // obligatorio antes de publicar
597
+ const id = await tiktok.publish({ data, title }); // sin privacyLevel: a borradores
598
+ await tiktok.status(id); // hasta PUBLISH_COMPLETE
599
+ ```
600
+
601
+ **La diferencia entre los dos modos importa mucho al principio.** En *Direct
602
+ Post* el video sale en vivo, pero exige el permiso `video.publish`, que solo se
603
+ consigue pasando una auditoría de TikTok de varias semanas —y hasta aprobarla
604
+ todo lo publicado queda en `SELF_ONLY`, o sea que no lo ve nadie—. En modo
605
+ **borrador**, que es el de por defecto aquí, el video cae en la bandeja de la
606
+ cuenta y una persona le da publicar desde el teléfono: llega con todo su
607
+ alcance y solo necesita `video.upload`.
608
+
609
+ Dicho de otro modo: publicar en directo antes de la auditoría es peor que no
610
+ publicar, porque gastas la pieza sin que la vea nadie.
611
+
612
+ Sube el binario en vez de pasar una URL a propósito. La otra vía,
613
+ `PULL_FROM_URL`, obliga a verificar el dominio en el portal de TikTok, y
614
+ cambiar un trámite por otro no compensa cuando el archivo ya está en disco.
615
+
616
+ El video tiene que ir en **MP4 H.264**. Límite de **6 peticiones por minuto**
617
+ por token, así que el sondeo del estado va espaciado.
618
+
581
619
  ### `stripe` — cliente de la SDK oficial
582
620
 
583
621
  ```ts
@@ -1023,6 +1061,7 @@ trae los datos.
1023
1061
  | `@miguelmorales13/nestkit/meta` | `MetaModule`, `MetaService` — publicar en Instagram y Facebook Pages |
1024
1062
  | `@miguelmorales13/nestkit/media` | `MediaModule`, `MediaService` — hosting efímero en memoria |
1025
1063
  | `@miguelmorales13/nestkit/pinterest` | `PinterestModule`, `PinterestService` — publicar pines |
1064
+ | `@miguelmorales13/nestkit/tiktok` | `TikTokModule`, `TikTokService` — publicar videos |
1026
1065
  | `@miguelmorales13/nestkit/stripe` | `StripeModule`, `STRIPE_CLIENT`, `createStripeWebhookController` |
1027
1066
  | `@miguelmorales13/nestkit/auth` | `AuthUserPort`, `BaseAuthService`, `createAuthController`, `TokenService`, `JwtAuthGuard`, `RolesGuard`, `RequireTenantGuard`, `CurrentUser`, `CurrentTenant`, `Roles` |
1028
1067
  | `@miguelmorales13/nestkit/auth/oauth` | `OAuthAuthModule`, `OAuthAuthService`, `createOAuthController`, `googleProvider`, `facebookProvider`, `OAuthStorePort`, `RefreshTokenStorePort` |
@@ -1035,7 +1074,7 @@ trae los datos.
1035
1074
 
1036
1075
  ## Estado del paquete
1037
1076
 
1038
- `0.8.0`. Sin adaptador Mongo real. Sin tests unitarios propios.
1077
+ `0.9.0`. Sin adaptador Mongo real. Sin tests unitarios propios.
1039
1078
 
1040
1079
  `auth/oauth` y `umami` sí tienen un consumidor real: **nutrimx** corre su acceso con Google y
1041
1080
  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 _chunkSPTDXUEDcjs = require('./chunk-SPTDXUED.cjs');
6
+ var _chunkRF75KC63cjs = require('./chunk-RF75KC63.cjs');
7
7
 
8
8
 
9
9
 
10
10
 
11
- var _chunkRF75KC63cjs = require('./chunk-RF75KC63.cjs');
11
+ var _chunkSPTDXUEDcjs = require('./chunk-SPTDXUED.cjs');
12
12
  require('./chunk-MR2IFCZE.cjs');
13
13
 
14
14
 
@@ -25,9 +25,6 @@ var _chunkTJHRABMLcjs = require('./chunk-TJHRABML.cjs');
25
25
 
26
26
 
27
27
  var _chunk3CLYZC3Tcjs = require('./chunk-3CLYZC3T.cjs');
28
-
29
-
30
- var _chunkQS2W5XCQcjs = require('./chunk-QS2W5XCQ.cjs');
31
28
  require('./chunk-7SOM7EZP.cjs');
32
29
 
33
30
 
@@ -47,6 +44,9 @@ var _chunkZA56XBCKcjs = require('./chunk-ZA56XBCK.cjs');
47
44
  var _chunkR7BVS6CIcjs = require('./chunk-R7BVS6CI.cjs');
48
45
 
49
46
 
47
+ var _chunkQS2W5XCQcjs = require('./chunk-QS2W5XCQ.cjs');
48
+
49
+
50
50
 
51
51
  var _chunkM3EL5O6Tcjs = require('./chunk-M3EL5O6T.cjs');
52
52
  require('./chunk-2REOCMUD.cjs');
package/dist/index.js CHANGED
@@ -1,14 +1,14 @@
1
1
  import "./chunk-EPVKCBPT.js";
2
- import {
3
- SUPABASE_ANON_CLIENT,
4
- SUPABASE_SERVICE_ROLE_CLIENT,
5
- SupabaseModule
6
- } from "./chunk-PA24P76K.js";
7
2
  import {
8
3
  PG_POOL,
9
4
  PgModule,
10
5
  withTenantScope
11
6
  } from "./chunk-VKOPDDCC.js";
7
+ import {
8
+ SUPABASE_ANON_CLIENT,
9
+ SUPABASE_SERVICE_ROLE_CLIENT,
10
+ SupabaseModule
11
+ } from "./chunk-PA24P76K.js";
12
12
  import "./chunk-NAK4WDKS.js";
13
13
  import {
14
14
  REQUEST_ID_HEADER,
@@ -25,9 +25,6 @@ import {
25
25
  BaseCrudService,
26
26
  createCrudController
27
27
  } from "./chunk-JOVBJDJ2.js";
28
- import {
29
- BaseResponseDto
30
- } from "./chunk-XX2HPTRU.js";
31
28
  import "./chunk-DQYAIQQ5.js";
32
29
  import {
33
30
  ConflictAppException,
@@ -45,6 +42,9 @@ import {
45
42
  import {
46
43
  AppException
47
44
  } from "./chunk-YFYHLYHN.js";
45
+ import {
46
+ BaseResponseDto
47
+ } from "./chunk-XX2HPTRU.js";
48
48
  import {
49
49
  I18nModule,
50
50
  translateOr
@@ -0,0 +1,142 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
2
+
3
+ var _chunk2REOCMUDcjs = require('../chunk-2REOCMUD.cjs');
4
+
5
+ // src/tiktok/tiktok.service.ts
6
+ var _common = require('@nestjs/common');
7
+ var API = "https://open.tiktokapis.com/v2";
8
+ var TikTokService = class {
9
+ constructor(credentials) {
10
+ this.credentials = credentials;
11
+ }
12
+ get configured() {
13
+ return Boolean(this.credentials.accessToken);
14
+ }
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.
19
+ */
20
+ async creatorInfo() {
21
+ return this.request("/post/publish/creator_info/query/", {});
22
+ }
23
+ /**
24
+ * Sube un vídeo y devuelve el `publish_id` con el que seguir su estado.
25
+ *
26
+ * Sin `privacyLevel` va a borradores; con él, se publica directo —y para eso
27
+ * hace falta que la aplicación haya pasado la auditoría.
28
+ */
29
+ async publish(video) {
30
+ const directo = Boolean(video.privacyLevel);
31
+ const ruta = directo ? "/post/publish/video/init/" : "/post/publish/inbox/video/init/";
32
+ const cuerpo = {
33
+ source_info: {
34
+ source: "FILE_UPLOAD",
35
+ video_size: video.data.byteLength,
36
+ // Una sola parte: estos clips son de unos pocos megas y trocearlos
37
+ // solo añadiría puntos donde fallar.
38
+ chunk_size: video.data.byteLength,
39
+ total_chunk_count: 1
40
+ }
41
+ };
42
+ if (directo) {
43
+ cuerpo.post_info = {
44
+ title: video.title.slice(0, 2200),
45
+ privacy_level: video.privacyLevel
46
+ };
47
+ }
48
+ const inicio = await this.request(
49
+ ruta,
50
+ cuerpo
51
+ );
52
+ const subida = await fetch(inicio.upload_url, {
53
+ method: "PUT",
54
+ headers: {
55
+ "Content-Type": "video/mp4",
56
+ // TikTok exige el rango incluso subiendo el archivo entero de una vez.
57
+ "Content-Range": `bytes 0-${video.data.byteLength - 1}/${video.data.byteLength}`
58
+ },
59
+ body: new Uint8Array(video.data)
60
+ });
61
+ if (!subida.ok) {
62
+ throw new Error(
63
+ `TikTok rechaz\xF3 el archivo (HTTP ${subida.status}): ${(await subida.text()).slice(0, 200)}`
64
+ );
65
+ }
66
+ return inicio.publish_id;
67
+ }
68
+ /** En qué va el procesado. Termina en `PUBLISH_COMPLETE` o en un fallo. */
69
+ async status(publishId) {
70
+ return this.request(
71
+ "/post/publish/status/fetch/",
72
+ { publish_id: publishId }
73
+ );
74
+ }
75
+ async request(path, body) {
76
+ if (!this.credentials.accessToken) {
77
+ throw new Error("TikTokService: no access token configured");
78
+ }
79
+ const response = await fetch(`${API}${path}`, {
80
+ method: "POST",
81
+ headers: {
82
+ Authorization: `Bearer ${this.credentials.accessToken}`,
83
+ "Content-Type": "application/json; charset=UTF-8"
84
+ },
85
+ body: JSON.stringify(body)
86
+ });
87
+ const text = await response.text();
88
+ let json;
89
+ try {
90
+ json = JSON.parse(text);
91
+ } catch (e) {
92
+ throw new Error(`TikTok respondi\xF3 ${response.status} y no era JSON: ${text.slice(0, 200)}`);
93
+ }
94
+ if (json.error && json.error.code && json.error.code !== "ok") {
95
+ throw new Error(`TikTok: ${json.error.code} \u2014 ${_nullishCoalesce(json.error.message, () => ( ""))}`.trim());
96
+ }
97
+ if (!response.ok) {
98
+ throw new Error(`TikTok respondi\xF3 HTTP ${response.status}: ${text.slice(0, 200)}`);
99
+ }
100
+ if (!json.data) {
101
+ throw new Error(`TikTok devolvi\xF3 una respuesta sin datos: ${text.slice(0, 200)}`);
102
+ }
103
+ return json.data;
104
+ }
105
+ };
106
+ TikTokService = exports.TikTokService = _chunk2REOCMUDcjs.__decorateClass.call(void 0, [
107
+ _common.Injectable.call(void 0, )
108
+ ], TikTokService);
109
+
110
+ // src/tiktok/tiktok.module.ts
111
+
112
+ var TikTokModule = class {
113
+ static forRoot(credentials) {
114
+ return {
115
+ module: TikTokModule,
116
+ providers: [
117
+ {
118
+ provide: TikTokService,
119
+ useFactory: () => {
120
+ const resolved = _nullishCoalesce(credentials, () => ( {
121
+ accessToken: _nullishCoalesce(process.env.TIKTOK_ACCESS_TOKEN, () => ( ""))
122
+ }));
123
+ if (!resolved.accessToken) {
124
+ throw new Error(
125
+ "TikTokModule: no access token. Set TIKTOK_ACCESS_TOKEN or pass credentials to forRoot()."
126
+ );
127
+ }
128
+ return new TikTokService(resolved);
129
+ }
130
+ }
131
+ ],
132
+ exports: [TikTokService]
133
+ };
134
+ }
135
+ };
136
+ TikTokModule = exports.TikTokModule = _chunk2REOCMUDcjs.__decorateClass.call(void 0, [
137
+ _common.Module.call(void 0, {})
138
+ ], TikTokModule);
139
+
140
+
141
+
142
+ exports.TikTokModule = TikTokModule; exports.TikTokService = TikTokService;
@@ -0,0 +1,3 @@
1
+ export { TikTokService } from './tiktok.service.js';
2
+ export type { TikTokCredentials, TikTokCreatorInfo, TikTokVideo, } from './tiktok.service.js';
3
+ export { TikTokModule } from './tiktok.module.js';
@@ -0,0 +1,142 @@
1
+ import {
2
+ __decorateClass
3
+ } from "../chunk-4MGIQFAJ.js";
4
+
5
+ // src/tiktok/tiktok.service.ts
6
+ import { Injectable } from "@nestjs/common";
7
+ var API = "https://open.tiktokapis.com/v2";
8
+ var TikTokService = class {
9
+ constructor(credentials) {
10
+ this.credentials = credentials;
11
+ }
12
+ get configured() {
13
+ return Boolean(this.credentials.accessToken);
14
+ }
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.
19
+ */
20
+ async creatorInfo() {
21
+ return this.request("/post/publish/creator_info/query/", {});
22
+ }
23
+ /**
24
+ * Sube un vídeo y devuelve el `publish_id` con el que seguir su estado.
25
+ *
26
+ * Sin `privacyLevel` va a borradores; con él, se publica directo —y para eso
27
+ * hace falta que la aplicación haya pasado la auditoría.
28
+ */
29
+ async publish(video) {
30
+ const directo = Boolean(video.privacyLevel);
31
+ const ruta = directo ? "/post/publish/video/init/" : "/post/publish/inbox/video/init/";
32
+ const cuerpo = {
33
+ source_info: {
34
+ source: "FILE_UPLOAD",
35
+ video_size: video.data.byteLength,
36
+ // Una sola parte: estos clips son de unos pocos megas y trocearlos
37
+ // solo añadiría puntos donde fallar.
38
+ chunk_size: video.data.byteLength,
39
+ total_chunk_count: 1
40
+ }
41
+ };
42
+ if (directo) {
43
+ cuerpo.post_info = {
44
+ title: video.title.slice(0, 2200),
45
+ privacy_level: video.privacyLevel
46
+ };
47
+ }
48
+ const inicio = await this.request(
49
+ ruta,
50
+ cuerpo
51
+ );
52
+ const subida = await fetch(inicio.upload_url, {
53
+ method: "PUT",
54
+ headers: {
55
+ "Content-Type": "video/mp4",
56
+ // TikTok exige el rango incluso subiendo el archivo entero de una vez.
57
+ "Content-Range": `bytes 0-${video.data.byteLength - 1}/${video.data.byteLength}`
58
+ },
59
+ body: new Uint8Array(video.data)
60
+ });
61
+ if (!subida.ok) {
62
+ throw new Error(
63
+ `TikTok rechaz\xF3 el archivo (HTTP ${subida.status}): ${(await subida.text()).slice(0, 200)}`
64
+ );
65
+ }
66
+ return inicio.publish_id;
67
+ }
68
+ /** En qué va el procesado. Termina en `PUBLISH_COMPLETE` o en un fallo. */
69
+ async status(publishId) {
70
+ return this.request(
71
+ "/post/publish/status/fetch/",
72
+ { publish_id: publishId }
73
+ );
74
+ }
75
+ async request(path, body) {
76
+ if (!this.credentials.accessToken) {
77
+ throw new Error("TikTokService: no access token configured");
78
+ }
79
+ const response = await fetch(`${API}${path}`, {
80
+ method: "POST",
81
+ headers: {
82
+ Authorization: `Bearer ${this.credentials.accessToken}`,
83
+ "Content-Type": "application/json; charset=UTF-8"
84
+ },
85
+ body: JSON.stringify(body)
86
+ });
87
+ const text = await response.text();
88
+ let json;
89
+ try {
90
+ json = JSON.parse(text);
91
+ } catch {
92
+ throw new Error(`TikTok respondi\xF3 ${response.status} y no era JSON: ${text.slice(0, 200)}`);
93
+ }
94
+ if (json.error && json.error.code && json.error.code !== "ok") {
95
+ throw new Error(`TikTok: ${json.error.code} \u2014 ${json.error.message ?? ""}`.trim());
96
+ }
97
+ if (!response.ok) {
98
+ throw new Error(`TikTok respondi\xF3 HTTP ${response.status}: ${text.slice(0, 200)}`);
99
+ }
100
+ if (!json.data) {
101
+ throw new Error(`TikTok devolvi\xF3 una respuesta sin datos: ${text.slice(0, 200)}`);
102
+ }
103
+ return json.data;
104
+ }
105
+ };
106
+ TikTokService = __decorateClass([
107
+ Injectable()
108
+ ], TikTokService);
109
+
110
+ // src/tiktok/tiktok.module.ts
111
+ import { Module } from "@nestjs/common";
112
+ var TikTokModule = class {
113
+ static forRoot(credentials) {
114
+ return {
115
+ module: TikTokModule,
116
+ providers: [
117
+ {
118
+ provide: TikTokService,
119
+ useFactory: () => {
120
+ const resolved = credentials ?? {
121
+ accessToken: process.env.TIKTOK_ACCESS_TOKEN ?? ""
122
+ };
123
+ if (!resolved.accessToken) {
124
+ throw new Error(
125
+ "TikTokModule: no access token. Set TIKTOK_ACCESS_TOKEN or pass credentials to forRoot()."
126
+ );
127
+ }
128
+ return new TikTokService(resolved);
129
+ }
130
+ }
131
+ ],
132
+ exports: [TikTokService]
133
+ };
134
+ }
135
+ };
136
+ TikTokModule = __decorateClass([
137
+ Module({})
138
+ ], TikTokModule);
139
+ export {
140
+ TikTokModule,
141
+ TikTokService
142
+ };
@@ -0,0 +1,13 @@
1
+ import { type DynamicModule } from '@nestjs/common';
2
+ import { type TikTokCredentials } from './tiktok.service.js';
3
+ /**
4
+ * Outbound client for TikTok's Content Posting API. See `TikTokService`.
5
+ *
6
+ * Reads `TIKTOK_ACCESS_TOKEN` by default. Like `PinterestService`, the service
7
+ * takes plain credentials and uses nothing but `fetch`, so a script outside
8
+ * Nest can do `new TikTokService({ accessToken })` — which is what the caller
9
+ * holding the rendered video usually is.
10
+ */
11
+ export declare class TikTokModule {
12
+ static forRoot(credentials?: TikTokCredentials): DynamicModule;
13
+ }
@@ -0,0 +1,75 @@
1
+ export interface TikTokCredentials {
2
+ /** Token de usuario con `video.upload` o `video.publish`. */
3
+ accessToken: string;
4
+ }
5
+ /** Lo que TikTok cuenta de la cuenta antes de dejar publicar. */
6
+ export interface TikTokCreatorInfo {
7
+ creator_username: string;
8
+ creator_nickname: string;
9
+ /** Niveles de privacidad que la cuenta admite. Ver `publish`. */
10
+ privacy_level_options: string[];
11
+ max_video_post_duration_sec: number;
12
+ }
13
+ export interface TikTokVideo {
14
+ /** El vídeo, ya en MP4 H.264. */
15
+ data: Buffer;
16
+ /** El texto del post. Hasta 2200 caracteres. */
17
+ title: string;
18
+ /**
19
+ * Cómo queda publicado. Si se omite, va a **borradores**: aparece en la
20
+ * bandeja de TikTok de la cuenta y una persona le da publicar.
21
+ *
22
+ * Ese es el modo que conviene mientras la aplicación no haya pasado la
23
+ * auditoría de TikTok, porque el modo directo publica en `SELF_ONLY` hasta
24
+ * entonces —es decir, no lo ve nadie— mientras que el borrador llega igual
25
+ * y se publica a mano sin perder alcance.
26
+ */
27
+ privacyLevel?: string;
28
+ }
29
+ /**
30
+ * Publica vídeos con la Content Posting API de TikTok.
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.
36
+ *
37
+ * **Dos modos, y la diferencia importa mucho al principio.** En *Direct Post*
38
+ * el vídeo sale en vivo, pero exige el permiso `video.publish`, que solo se
39
+ * consigue pasando una auditoría de TikTok de varias semanas; hasta aprobarla
40
+ * todo lo publicado queda en `SELF_ONLY` y no lo ve nadie. En modo *borrador*
41
+ * —el de por defecto aquí— el vídeo cae en la bandeja de la cuenta y una
42
+ * persona le da publicar desde el teléfono: llega con todo su alcance y solo
43
+ * necesita `video.upload`.
44
+ *
45
+ * Se sube el binario en vez de pasar una URL a propósito. La otra vía,
46
+ * `PULL_FROM_URL`, obliga a verificar el dominio en el portal de TikTok, y
47
+ * cambiar un trámite por otro no compensa cuando el archivo ya está en disco.
48
+ *
49
+ * El límite es de 6 peticiones por minuto y por token, así que el sondeo del
50
+ * estado va espaciado.
51
+ */
52
+ export declare class TikTokService {
53
+ private readonly credentials;
54
+ constructor(credentials: TikTokCredentials);
55
+ get configured(): boolean;
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.
60
+ */
61
+ creatorInfo(): Promise<TikTokCreatorInfo>;
62
+ /**
63
+ * Sube un vídeo y devuelve el `publish_id` con el que seguir su estado.
64
+ *
65
+ * Sin `privacyLevel` va a borradores; con él, se publica directo —y para eso
66
+ * hace falta que la aplicación haya pasado la auditoría.
67
+ */
68
+ publish(video: TikTokVideo): Promise<string>;
69
+ /** En qué va el procesado. Termina en `PUBLISH_COMPLETE` o en un fallo. */
70
+ status(publishId: string): Promise<{
71
+ status: string;
72
+ fail_reason?: string;
73
+ }>;
74
+ private request;
75
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miguelmorales13/nestkit",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -121,6 +121,11 @@
121
121
  "import": "./dist/pinterest/index.js",
122
122
  "require": "./dist/pinterest/index.cjs"
123
123
  },
124
+ "./tiktok": {
125
+ "types": "./dist/tiktok/index.d.ts",
126
+ "import": "./dist/tiktok/index.js",
127
+ "require": "./dist/tiktok/index.cjs"
128
+ },
124
129
  "./media": {
125
130
  "types": "./dist/media/index.d.ts",
126
131
  "import": "./dist/media/index.js",