n8n-nodes-tiktok-bigboss 1.0.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.
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TikTokOAuth2Api = void 0;
4
+ class TikTokOAuth2Api {
5
+ constructor() {
6
+ this.name = 'tiktokOAuth2Api';
7
+ this.displayName = 'TikTok OAuth2 API';
8
+ this.documentationUrl = 'https://developers.tiktok.com/';
9
+ this.extends = [
10
+ 'oAuth2Api',
11
+ ];
12
+ this.properties = [
13
+ {
14
+ displayName: 'Grant Type',
15
+ name: 'grantType',
16
+ type: 'hidden',
17
+ default: 'authorizationCode',
18
+ },
19
+ {
20
+ displayName: 'Authorization URL',
21
+ name: 'authUrl',
22
+ type: 'hidden',
23
+ default: 'https://www.tiktok.com/v2/auth/authorize/',
24
+ },
25
+ {
26
+ displayName: 'Access Token URL',
27
+ name: 'accessTokenUrl',
28
+ type: 'hidden',
29
+ default: 'https://open.tiktokapis.com/v2/oauth/token/',
30
+ },
31
+ {
32
+ displayName: 'Scope',
33
+ name: 'scope',
34
+ type: 'hidden',
35
+ default: 'user.info.basic,user.info.stats,video.list,video.upload',
36
+ },
37
+ {
38
+ displayName: 'Auth URI Query Parameters',
39
+ name: 'authQueryParameters',
40
+ type: 'hidden',
41
+ default: '',
42
+ },
43
+ {
44
+ displayName: 'Authentication',
45
+ name: 'authentication',
46
+ type: 'hidden',
47
+ default: 'body',
48
+ },
49
+ ];
50
+ }
51
+ }
52
+ exports.TikTokOAuth2Api = TikTokOAuth2Api;
@@ -0,0 +1,606 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TikTokBigBoss = void 0;
4
+ exports.tiktokApiRequest = tiktokApiRequest;
5
+ const n8n_workflow_1 = require("n8n-workflow");
6
+ async function tiktokApiRequest(method, resource, body = {}, qs = {}, fullOutput, uri, option = {}) {
7
+ let options = {
8
+ method,
9
+ body,
10
+ qs,
11
+ url: uri || `https://open.tiktokapis.com/v2${resource}`,
12
+ json: true,
13
+ };
14
+ try {
15
+ if (Object.keys(option).length !== 0) {
16
+ options = Object.assign({}, options, option);
17
+ }
18
+ if (Object.keys(body).length === 0) {
19
+ delete options.body;
20
+ }
21
+ if (Object.keys(qs).length === 0) {
22
+ delete options.qs;
23
+ }
24
+ if (fullOutput) {
25
+ return await this.helpers.requestOAuth2.call(this, 'tiktokOAuth2Api', options);
26
+ }
27
+ else {
28
+ const { data } = await this.helpers.requestOAuth2.call(this, 'tiktokOAuth2Api', options);
29
+ return data;
30
+ }
31
+ }
32
+ catch (error) {
33
+ const errObject = error instanceof Error ? { message: error.message } : { message: String(error) };
34
+ throw new n8n_workflow_1.NodeApiError(this.getNode(), errObject);
35
+ }
36
+ }
37
+ class TikTokBigBoss {
38
+ constructor() {
39
+ this.description = {
40
+ displayName: 'TikTok BigBoss',
41
+ name: 'tiktokBigBoss',
42
+ icon: 'fa:tiktok',
43
+ group: ['transform'],
44
+ version: 1,
45
+ description: 'Upload and manage TikTok videos and photos, stats, and search (BigBoss Edition)',
46
+ defaults: {
47
+ name: 'TikTok BigBoss',
48
+ },
49
+ inputs: ['main'],
50
+ outputs: ['main'],
51
+ credentials: [
52
+ {
53
+ name: 'tiktokOAuth2Api',
54
+ required: true,
55
+ },
56
+ ],
57
+ properties: [
58
+ {
59
+ displayName: 'Resource',
60
+ name: 'resource',
61
+ type: 'options',
62
+ noDataExpression: true,
63
+ options: [
64
+ {
65
+ name: 'Video Post',
66
+ value: 'videoPost',
67
+ description: 'Upload a video to TikTok',
68
+ },
69
+ {
70
+ name: 'Photo Post',
71
+ value: 'photoPost',
72
+ description: 'Upload a photo to TikTok',
73
+ },
74
+ {
75
+ name: 'User Profile',
76
+ value: 'userProfile',
77
+ description: 'Retrieve profile data & Analytics',
78
+ },
79
+ {
80
+ name: 'Search',
81
+ value: 'search',
82
+ description: 'Search for hashtags or sounds',
83
+ },
84
+ {
85
+ name: 'Post Status',
86
+ value: 'postStatus',
87
+ description: 'Check the status of a post',
88
+ },
89
+ ],
90
+ default: 'videoPost',
91
+ },
92
+ {
93
+ displayName: 'Operation',
94
+ name: 'operation',
95
+ type: 'options',
96
+ noDataExpression: true,
97
+ displayOptions: {
98
+ show: {
99
+ resource: ['videoPost'],
100
+ },
101
+ },
102
+ options: [
103
+ {
104
+ name: 'Upload',
105
+ value: 'upload',
106
+ description: 'Upload a video to TikTok',
107
+ action: 'Upload video',
108
+ },
109
+ ],
110
+ default: 'upload',
111
+ },
112
+ {
113
+ displayName: 'Source',
114
+ name: 'source',
115
+ type: 'options',
116
+ options: [
117
+ {
118
+ name: 'Upload From URL',
119
+ value: 'PULL_FROM_URL',
120
+ },
121
+ {
122
+ name: 'Upload File (Binary)',
123
+ value: 'FILE_UPLOAD',
124
+ },
125
+ ],
126
+ default: 'PULL_FROM_URL',
127
+ displayOptions: {
128
+ show: {
129
+ resource: ['videoPost'],
130
+ operation: ['upload'],
131
+ },
132
+ },
133
+ },
134
+ {
135
+ displayName: 'Video URL',
136
+ name: 'videoUrl',
137
+ type: 'string',
138
+ default: '',
139
+ required: true,
140
+ displayOptions: {
141
+ show: {
142
+ resource: ['videoPost'],
143
+ operation: ['upload'],
144
+ source: ['PULL_FROM_URL'],
145
+ },
146
+ },
147
+ description: 'Publicly accessible URL from which TikTok will pull the video',
148
+ },
149
+ {
150
+ displayName: 'Binary Property',
151
+ name: 'binaryProperty',
152
+ type: 'string',
153
+ default: 'data',
154
+ required: true,
155
+ displayOptions: {
156
+ show: {
157
+ resource: ['videoPost'],
158
+ operation: ['upload'],
159
+ source: ['FILE_UPLOAD'],
160
+ },
161
+ },
162
+ description: 'Name of the binary property containing the video file to upload',
163
+ },
164
+ {
165
+ displayName: 'Privacy Level',
166
+ name: 'privacyLevel',
167
+ type: 'options',
168
+ options: [
169
+ { name: 'Everyone', value: 'PUBLIC_TO_EVERYONE' },
170
+ { name: 'Mutual Followers', value: 'MUTUAL_FOLLOW_FRIENDS' },
171
+ { name: 'Followers of Creator', value: 'FOLLOWER_OF_CREATOR' },
172
+ { name: 'Only Me', value: 'SELF_ONLY' },
173
+ ],
174
+ default: 'PUBLIC_TO_EVERYONE',
175
+ required: true,
176
+ displayOptions: {
177
+ show: {
178
+ resource: ['videoPost'],
179
+ operation: ['upload'],
180
+ },
181
+ },
182
+ description: 'Who can view this post',
183
+ },
184
+ {
185
+ displayName: 'Additional Fields',
186
+ name: 'additionalFields',
187
+ type: 'collection',
188
+ placeholder: 'Add Field',
189
+ default: {},
190
+ displayOptions: {
191
+ show: {
192
+ resource: ['videoPost'],
193
+ operation: ['upload'],
194
+ },
195
+ },
196
+ options: [
197
+ {
198
+ displayName: 'Title',
199
+ name: 'title',
200
+ type: 'string',
201
+ default: '',
202
+ description: 'Caption for the video',
203
+ },
204
+ {
205
+ displayName: 'Disable Comment',
206
+ name: 'disableComment',
207
+ type: 'boolean',
208
+ default: false,
209
+ },
210
+ {
211
+ displayName: 'Disable Duet',
212
+ name: 'disableDuet',
213
+ type: 'boolean',
214
+ default: false,
215
+ },
216
+ {
217
+ displayName: 'Disable Stitch',
218
+ name: 'disableStitch',
219
+ type: 'boolean',
220
+ default: false,
221
+ },
222
+ {
223
+ displayName: 'Is AI Generated',
224
+ name: 'isAigc',
225
+ type: 'boolean',
226
+ default: false,
227
+ },
228
+ {
229
+ displayName: 'Brand Content Toggle',
230
+ name: 'brandContentToggle',
231
+ type: 'boolean',
232
+ default: false,
233
+ },
234
+ {
235
+ displayName: 'Brand Organic Toggle',
236
+ name: 'brandOrganicToggle',
237
+ type: 'boolean',
238
+ default: false,
239
+ },
240
+ ],
241
+ },
242
+ {
243
+ displayName: 'Operation',
244
+ name: 'operation',
245
+ type: 'options',
246
+ noDataExpression: true,
247
+ displayOptions: {
248
+ show: {
249
+ resource: ['photoPost'],
250
+ },
251
+ },
252
+ options: [
253
+ {
254
+ name: 'Upload',
255
+ value: 'upload',
256
+ description: 'Upload photos to TikTok',
257
+ action: 'Upload photos',
258
+ },
259
+ ],
260
+ default: 'upload',
261
+ },
262
+ {
263
+ displayName: 'Photo URLs',
264
+ name: 'photoUrls',
265
+ type: 'string',
266
+ default: '',
267
+ required: true,
268
+ displayOptions: {
269
+ show: {
270
+ resource: ['photoPost'],
271
+ operation: ['upload'],
272
+ },
273
+ },
274
+ description: 'Publicly accessible URLs of the photos. Comma-separated or single URL.',
275
+ },
276
+ {
277
+ displayName: 'Post Mode',
278
+ name: 'postMode',
279
+ type: 'options',
280
+ options: [
281
+ { name: 'Direct Post', value: 'DIRECT_POST' },
282
+ { name: 'Media Upload', value: 'MEDIA_UPLOAD' },
283
+ ],
284
+ default: 'MEDIA_UPLOAD',
285
+ displayOptions: {
286
+ show: {
287
+ resource: ['photoPost'],
288
+ operation: ['upload'],
289
+ },
290
+ },
291
+ },
292
+ {
293
+ displayName: 'Additional Fields',
294
+ name: 'additionalFieldsPhoto',
295
+ type: 'collection',
296
+ placeholder: 'Add Field',
297
+ default: {},
298
+ displayOptions: {
299
+ show: {
300
+ resource: ['photoPost'],
301
+ operation: ['upload'],
302
+ },
303
+ },
304
+ options: [
305
+ {
306
+ displayName: 'Title',
307
+ name: 'title',
308
+ type: 'string',
309
+ default: '',
310
+ },
311
+ {
312
+ displayName: 'Description',
313
+ name: 'description',
314
+ type: 'string',
315
+ default: '',
316
+ },
317
+ {
318
+ displayName: 'Privacy Level',
319
+ name: 'privacyLevel',
320
+ type: 'options',
321
+ options: [
322
+ { name: 'Everyone', value: 'PUBLIC_TO_EVERYONE' },
323
+ { name: 'Mutual Followers', value: 'MUTUAL_FOLLOW_FRIENDS' },
324
+ { name: 'Followers of Creator', value: 'FOLLOWER_OF_CREATOR' },
325
+ { name: 'Only Me', value: 'SELF_ONLY' },
326
+ ],
327
+ default: 'PUBLIC_TO_EVERYONE',
328
+ },
329
+ {
330
+ displayName: 'Auto Add Music',
331
+ name: 'autoAddMusic',
332
+ type: 'boolean',
333
+ default: false,
334
+ },
335
+ ],
336
+ },
337
+ {
338
+ displayName: 'Operation',
339
+ name: 'operation',
340
+ type: 'options',
341
+ noDataExpression: true,
342
+ displayOptions: {
343
+ show: {
344
+ resource: ['userProfile'],
345
+ },
346
+ },
347
+ options: [
348
+ {
349
+ name: 'Get Info',
350
+ value: 'get',
351
+ action: 'Get user info',
352
+ },
353
+ {
354
+ name: 'Analytics',
355
+ value: 'analytics',
356
+ action: 'Get analytics',
357
+ },
358
+ ],
359
+ default: 'get',
360
+ },
361
+ {
362
+ displayName: 'Fields',
363
+ name: 'fields',
364
+ type: 'multiOptions',
365
+ default: [],
366
+ displayOptions: {
367
+ show: {
368
+ resource: ['userProfile'],
369
+ operation: ['get'],
370
+ },
371
+ },
372
+ options: [
373
+ { name: 'Avatar URL', value: 'avatar_url' },
374
+ { name: 'Display Name', value: 'display_name' },
375
+ { name: 'Username', value: 'username' },
376
+ { name: 'Follower Count', value: 'follower_count' },
377
+ { name: 'Bio Description', value: 'bio_description' },
378
+ { name: 'Likes Count', value: 'likes_count' },
379
+ ],
380
+ },
381
+ {
382
+ displayName: 'Metrics',
383
+ name: 'metrics',
384
+ type: 'multiOptions',
385
+ default: [],
386
+ displayOptions: {
387
+ show: {
388
+ resource: ['userProfile'],
389
+ operation: ['analytics'],
390
+ },
391
+ },
392
+ options: [
393
+ { name: 'Followers', value: 'followers' },
394
+ { name: 'Likes', value: 'likes' },
395
+ { name: 'Views', value: 'views' },
396
+ ],
397
+ },
398
+ {
399
+ displayName: 'Operation',
400
+ name: 'operation',
401
+ type: 'options',
402
+ noDataExpression: true,
403
+ displayOptions: { show: { resource: ['search'] } },
404
+ options: [
405
+ { name: 'Search Hashtags', value: 'hashtag' },
406
+ { name: 'Search Sounds', value: 'sound' },
407
+ ],
408
+ default: 'hashtag',
409
+ },
410
+ {
411
+ displayName: 'Query',
412
+ name: 'query',
413
+ type: 'string',
414
+ default: '',
415
+ required: true,
416
+ displayOptions: { show: { resource: ['search'] } },
417
+ },
418
+ {
419
+ displayName: 'Limit',
420
+ name: 'limit',
421
+ type: 'number',
422
+ default: 20,
423
+ displayOptions: { show: { resource: ['search'] } },
424
+ },
425
+ {
426
+ displayName: 'Operation',
427
+ name: 'operation',
428
+ type: 'options',
429
+ noDataExpression: true,
430
+ displayOptions: { show: { resource: ['postStatus'] } },
431
+ options: [
432
+ { name: 'Get', value: 'get' },
433
+ ],
434
+ default: 'get',
435
+ },
436
+ {
437
+ displayName: 'Publish ID',
438
+ name: 'publishId',
439
+ type: 'string',
440
+ default: '',
441
+ required: true,
442
+ displayOptions: { show: { resource: ['postStatus'] } },
443
+ },
444
+ ],
445
+ };
446
+ }
447
+ async execute() {
448
+ var _a, _b, _c, _d, _e;
449
+ const items = this.getInputData();
450
+ const returnData = [];
451
+ const length = items.length;
452
+ let responseData;
453
+ const resource = this.getNodeParameter('resource', 0);
454
+ const operation = this.getNodeParameter('operation', 0);
455
+ for (let i = 0; i < length; i++) {
456
+ try {
457
+ if (resource === 'videoPost') {
458
+ if (operation === 'upload') {
459
+ const source = this.getNodeParameter('source', i);
460
+ const privacyLevel = this.getNodeParameter('privacyLevel', i);
461
+ const additionalFields = this.getNodeParameter('additionalFields', i, {});
462
+ const postInfo = {
463
+ privacy_level: privacyLevel,
464
+ ...additionalFields,
465
+ };
466
+ if (additionalFields.title)
467
+ postInfo.title = additionalFields.title;
468
+ if (additionalFields.disableComment)
469
+ postInfo.disable_comment = additionalFields.disableComment;
470
+ if (additionalFields.disableDuet)
471
+ postInfo.disable_duet = additionalFields.disableDuet;
472
+ if (additionalFields.disableStitch)
473
+ postInfo.disable_stitch = additionalFields.disableStitch;
474
+ if (additionalFields.isAigc)
475
+ postInfo.is_aigc = additionalFields.isAigc;
476
+ if (additionalFields.brandContentToggle)
477
+ postInfo.brand_content_toggle = additionalFields.brandContentToggle;
478
+ if (additionalFields.brandOrganicToggle)
479
+ postInfo.brand_organic_toggle = additionalFields.brandOrganicToggle;
480
+ const sourceInfo = { source };
481
+ if (source === 'PULL_FROM_URL') {
482
+ const videoUrl = this.getNodeParameter('videoUrl', i);
483
+ sourceInfo.video_url = videoUrl;
484
+ const body = { post_info: postInfo, source_info: sourceInfo };
485
+ responseData = await tiktokApiRequest.call(this, 'POST', '/post/publish/video/init/', body);
486
+ }
487
+ if (source === 'FILE_UPLOAD') {
488
+ const binaryProperty = this.getNodeParameter('binaryProperty', i);
489
+ const item = (_a = items[i].binary) === null || _a === void 0 ? void 0 : _a[binaryProperty];
490
+ if (!item)
491
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `No binary data property "${binaryProperty}" set`);
492
+ const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryProperty);
493
+ sourceInfo.video_size = dataBuffer.length;
494
+ sourceInfo.chunk_size = dataBuffer.length;
495
+ sourceInfo.total_chunk_count = 1;
496
+ const body = { post_info: postInfo, source_info: sourceInfo };
497
+ responseData = await tiktokApiRequest.call(this, 'POST', '/post/publish/video/init/', body);
498
+ const uploadUrl = responseData.upload_url;
499
+ if (!uploadUrl)
500
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Upload URL not returned from TikTok');
501
+ await this.helpers.httpRequest({
502
+ method: 'PUT',
503
+ url: uploadUrl,
504
+ body: dataBuffer,
505
+ headers: {
506
+ 'Content-Type': item.mimeType || 'video/mp4',
507
+ 'Content-Length': dataBuffer.length,
508
+ 'Content-Range': `bytes 0-${dataBuffer.length - 1}/${dataBuffer.length}`,
509
+ },
510
+ json: false,
511
+ });
512
+ }
513
+ }
514
+ }
515
+ if (resource === 'photoPost') {
516
+ if (operation === 'upload') {
517
+ let photoUrls = this.getNodeParameter('photoUrls', i);
518
+ if (typeof photoUrls === 'string') {
519
+ photoUrls = photoUrls.split(',').map((url) => url.trim()).filter((url) => url);
520
+ }
521
+ const postMode = this.getNodeParameter('postMode', i);
522
+ const additionalFields = this.getNodeParameter('additionalFieldsPhoto', i, {});
523
+ const postInfo = {};
524
+ if (additionalFields.title)
525
+ postInfo.title = additionalFields.title;
526
+ if (additionalFields.description)
527
+ postInfo.description = additionalFields.description;
528
+ if (additionalFields.privacyLevel)
529
+ postInfo.privacy_level = additionalFields.privacyLevel;
530
+ if (additionalFields.autoAddMusic)
531
+ postInfo.auto_add_music = additionalFields.autoAddMusic;
532
+ if (postMode === 'DIRECT_POST' && !postInfo.privacy_level) {
533
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Privacy Level must be set for Direct Post');
534
+ }
535
+ const body = {
536
+ post_info: postInfo,
537
+ source_info: {
538
+ source: 'PULL_FROM_URL',
539
+ photo_images: photoUrls,
540
+ },
541
+ post_mode: postMode,
542
+ media_type: 'PHOTO',
543
+ };
544
+ responseData = await tiktokApiRequest.call(this, 'POST', '/post/publish/content/init/', body);
545
+ }
546
+ }
547
+ if (resource === 'postStatus') {
548
+ const publishId = this.getNodeParameter('publishId', i);
549
+ responseData = await tiktokApiRequest.call(this, 'POST', '/post/publish/status/fetch/', { publish_id: publishId });
550
+ }
551
+ if (resource === 'search') {
552
+ const query = this.getNodeParameter('query', i);
553
+ const limit = this.getNodeParameter('limit', i, 20);
554
+ const qs = { query, max_count: limit };
555
+ if (operation === 'hashtag') {
556
+ const res = await tiktokApiRequest.call(this, 'GET', '/hashtag/search/', {}, qs);
557
+ responseData = (_c = (_b = res.hashtags) !== null && _b !== void 0 ? _b : res.results) !== null && _c !== void 0 ? _c : res;
558
+ }
559
+ if (operation === 'sound') {
560
+ const res = await tiktokApiRequest.call(this, 'GET', '/sound/search/', {}, qs);
561
+ responseData = (_e = (_d = res.sounds) !== null && _d !== void 0 ? _d : res.results) !== null && _e !== void 0 ? _e : res;
562
+ }
563
+ }
564
+ if (resource === 'userProfile') {
565
+ if (operation === 'get') {
566
+ const fields = this.getNodeParameter('fields', i);
567
+ if (!(fields === null || fields === void 0 ? void 0 : fields.length))
568
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Select at least one field');
569
+ responseData = await tiktokApiRequest.call(this, 'GET', '/user/info/', {}, { fields: fields.join(',') });
570
+ }
571
+ if (operation === 'analytics') {
572
+ const selectedMetrics = this.getNodeParameter('metrics', i);
573
+ if (!(selectedMetrics === null || selectedMetrics === void 0 ? void 0 : selectedMetrics.length))
574
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Select at least one metric');
575
+ const metricMap = {
576
+ followers: 'follower_count',
577
+ likes: 'likes_count',
578
+ views: 'video_count',
579
+ };
580
+ const apiFields = selectedMetrics.map(m => metricMap[m]).filter(Boolean).join(',');
581
+ const res = await tiktokApiRequest.call(this, 'GET', '/user/info/', {}, { fields: apiFields });
582
+ const user = res.user || {};
583
+ const results = {};
584
+ selectedMetrics.forEach(m => {
585
+ const key = metricMap[m];
586
+ if (user[key] !== undefined)
587
+ results[m] = user[key];
588
+ });
589
+ responseData = results;
590
+ }
591
+ }
592
+ const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } });
593
+ returnData.push(...executionData);
594
+ }
595
+ catch (error) {
596
+ if (this.continueOnFail()) {
597
+ returnData.push({ json: { error: error.message } });
598
+ continue;
599
+ }
600
+ throw error;
601
+ }
602
+ }
603
+ return [returnData];
604
+ }
605
+ }
606
+ exports.TikTokBigBoss = TikTokBigBoss;
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "n8n-nodes-tiktok-bigboss",
3
+ "version": "1.0.0",
4
+ "description": "TikTok BigBoss node for n8n - Upload, Analytics, and Search",
5
+ "keywords": [
6
+ "n8n-community-node-package",
7
+ "n8n",
8
+ "tiktok",
9
+ "social",
10
+ "upload",
11
+ "analytics"
12
+ ],
13
+ "license": "MIT",
14
+ "author": "isemo007",
15
+ "main": "index.js",
16
+ "scripts": {
17
+ "build": "tsc && gulp build:icons",
18
+ "dev": "tsc --watch",
19
+ "format": "prettier nodes credentials --write",
20
+ "lint": "eslint nodes credentials package.json",
21
+ "lintfix": "eslint nodes credentials package.json --fix"
22
+ },
23
+ "files": [
24
+ "dist"
25
+ ],
26
+ "n8n": {
27
+ "n8nNodesApiVersion": 1,
28
+ "credentials": [
29
+ "dist/credentials/TikTokOAuth2Api.credentials.js"
30
+ ],
31
+ "nodes": [
32
+ "dist/nodes/TikTokBigBoss/TikTokBigBoss.node.js"
33
+ ]
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "^22.13.0",
37
+ "@typescript-eslint/parser": "~5.45",
38
+ "eslint-plugin-n8n-nodes-base": "^1.11.0",
39
+ "gulp": "^4.0.2",
40
+ "n8n-workflow": "^1.70.0",
41
+ "prettier": "^2.7.1",
42
+ "typescript": "^5.0.0"
43
+ },
44
+ "peerDependencies": {
45
+ "n8n-workflow": "*"
46
+ },
47
+ "dependencies": {
48
+ "n8n-core": "^1.75.0"
49
+ }
50
+ }