untiktok-api 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.
Files changed (68) hide show
  1. package/LICENSE +21 -0
  2. package/LICENSE.txt +21 -0
  3. package/README.md +80 -0
  4. package/dist/api/comment.d.ts +42 -0
  5. package/dist/api/comment.js +84 -0
  6. package/dist/api/hashtag.d.ts +52 -0
  7. package/dist/api/hashtag.js +118 -0
  8. package/dist/api/playlist.d.ts +53 -0
  9. package/dist/api/playlist.js +112 -0
  10. package/dist/api/search.d.ts +38 -0
  11. package/dist/api/search.js +98 -0
  12. package/dist/api/sound.d.ts +57 -0
  13. package/dist/api/sound.js +133 -0
  14. package/dist/api/trending.d.ts +21 -0
  15. package/dist/api/trending.js +52 -0
  16. package/dist/api/user.d.ts +187 -0
  17. package/dist/api/user.js +498 -0
  18. package/dist/api/video.d.ts +119 -0
  19. package/dist/api/video.js +399 -0
  20. package/dist/exceptions.d.ts +24 -0
  21. package/dist/exceptions.js +61 -0
  22. package/dist/helpers.d.ts +23 -0
  23. package/dist/helpers.js +66 -0
  24. package/dist/index.d.ts +13 -0
  25. package/dist/index.js +35 -0
  26. package/dist/stealth/index.d.ts +70 -0
  27. package/dist/stealth/index.js +128 -0
  28. package/dist/stealth/js/chrome_app.d.ts +1 -0
  29. package/dist/stealth/js/chrome_app.js +27 -0
  30. package/dist/stealth/js/chrome_csi.d.ts +1 -0
  31. package/dist/stealth/js/chrome_csi.js +14 -0
  32. package/dist/stealth/js/chrome_hairline.d.ts +1 -0
  33. package/dist/stealth/js/chrome_hairline.js +16 -0
  34. package/dist/stealth/js/chrome_load_times.d.ts +1 -0
  35. package/dist/stealth/js/chrome_load_times.js +28 -0
  36. package/dist/stealth/js/chrome_runtime_script.d.ts +1 -0
  37. package/dist/stealth/js/chrome_runtime_script.js +84 -0
  38. package/dist/stealth/js/generate_magic_arrays.d.ts +1 -0
  39. package/dist/stealth/js/generate_magic_arrays.js +28 -0
  40. package/dist/stealth/js/iframe_contentWindow.d.ts +1 -0
  41. package/dist/stealth/js/iframe_contentWindow.js +22 -0
  42. package/dist/stealth/js/media_codecs.d.ts +1 -0
  43. package/dist/stealth/js/media_codecs.js +16 -0
  44. package/dist/stealth/js/navigator_hardwareConcurrency.d.ts +1 -0
  45. package/dist/stealth/js/navigator_hardwareConcurrency.js +6 -0
  46. package/dist/stealth/js/navigator_languages.d.ts +1 -0
  47. package/dist/stealth/js/navigator_languages.js +6 -0
  48. package/dist/stealth/js/navigator_permissions.d.ts +1 -0
  49. package/dist/stealth/js/navigator_permissions.js +11 -0
  50. package/dist/stealth/js/navigator_platform.d.ts +1 -0
  51. package/dist/stealth/js/navigator_platform.js +8 -0
  52. package/dist/stealth/js/navigator_plugins_script.d.ts +1 -0
  53. package/dist/stealth/js/navigator_plugins_script.js +37 -0
  54. package/dist/stealth/js/navigator_userAgent_script.d.ts +1 -0
  55. package/dist/stealth/js/navigator_userAgent_script.js +8 -0
  56. package/dist/stealth/js/navigator_vendor_script.d.ts +1 -0
  57. package/dist/stealth/js/navigator_vendor_script.js +6 -0
  58. package/dist/stealth/js/utils_script.d.ts +1 -0
  59. package/dist/stealth/js/utils_script.js +119 -0
  60. package/dist/stealth/js/webgl_vendor_script.d.ts +1 -0
  61. package/dist/stealth/js/webgl_vendor_script.js +16 -0
  62. package/dist/stealth/js/window_outerdimensions.d.ts +1 -0
  63. package/dist/stealth/js/window_outerdimensions.js +9 -0
  64. package/dist/tiktok.d.ts +96 -0
  65. package/dist/tiktok.js +758 -0
  66. package/dist/types.d.ts +58 -0
  67. package/dist/types.js +6 -0
  68. package/package.json +41 -0
@@ -0,0 +1 @@
1
+ export declare const utils_script = "\nconst utils = {}\nutils.stripProxyFromErrors = (handler = {}) => {\n const newHandler = {}\n const traps = Object.getOwnPropertyNames(handler)\n traps.forEach(trap => {\n newHandler[trap] = function() {\n try { return handler[trap].apply(this, arguments || []) } catch (err) {\n if (!err || !err.stack || !err.stack.includes('at ')) { throw err }\n const stripWithBlacklist = stack => {\n const blacklist = ['at Reflect.' + trap + ' ', 'at Object.' + trap + ' ', 'at Object.newHandler.<computed> [as ' + trap + '] ']\n return err.stack.split('\\n').filter((line, index) => index !== 1).filter(line => !blacklist.some(bl => line.trim().startsWith(bl))).join('\\n')\n }\n const stripWithAnchor = stack => {\n const stackArr = stack.split('\\n')\n const anchor = 'at Object.newHandler.<computed> [as ' + trap + '] '\n const anchorIndex = stackArr.findIndex(line => line.trim().startsWith(anchor))\n if (anchorIndex === -1) return false\n stackArr.splice(1, anchorIndex)\n return stackArr.join('\\n')\n }\n err.stack = stripWithAnchor(err.stack) || stripWithBlacklist(err.stack)\n throw err\n }\n }\n })\n return newHandler\n}\nutils.stripErrorWithAnchor = (err, anchor) => {\n const stackArr = err.stack.split('\\n')\n const anchorIndex = stackArr.findIndex(line => line.trim().startsWith(anchor))\n if (anchorIndex === -1) return err\n stackArr.splice(1, anchorIndex)\n err.stack = stackArr.join('\\n')\n return err\n}\nutils.replaceProperty = (obj, propName, descriptorOverrides = {}) => {\n return Object.defineProperty(obj, propName, { ...(Object.getOwnPropertyDescriptor(obj, propName) || {}), ...descriptorOverrides })\n}\nutils.preloadCache = () => {\n if (utils.cache) return\n utils.cache = { Reflect: { get: Reflect.get.bind(Reflect), apply: Reflect.apply.bind(Reflect) }, nativeToStringStr: Function.toString + '' }\n}\nutils.makeNativeString = (name = '') => { utils.preloadCache(); return utils.cache.nativeToStringStr.replace('toString', name || '') }\nutils.patchToString = (obj, str = '') => {\n utils.preloadCache()\n const toStringProxy = new Proxy(Function.prototype.toString, {\n apply: function(target, ctx) {\n if (ctx === Function.prototype.toString) return utils.makeNativeString('toString')\n if (ctx === obj) return str || utils.makeNativeString(obj.name)\n const hasSameProto = Object.getPrototypeOf(Function.prototype.toString).isPrototypeOf(ctx.toString)\n if (!hasSameProto) return ctx.toString()\n return target.call(ctx)\n }\n })\n utils.replaceProperty(Function.prototype, 'toString', { value: toStringProxy })\n}\nutils.patchToStringNested = (obj = {}) => { return utils.execRecursively(obj, ['function'], utils.patchToString) }\nutils.redirectToString = (proxyObj, originalObj) => {\n utils.preloadCache()\n const toStringProxy = new Proxy(Function.prototype.toString, {\n apply: function(target, ctx) {\n if (ctx === Function.prototype.toString) return utils.makeNativeString('toString')\n if (ctx === proxyObj) {\n const fallback = () => originalObj && originalObj.name ? utils.makeNativeString(originalObj.name) : utils.makeNativeString(proxyObj.name)\n return originalObj + '' || fallback()\n }\n const hasSameProto = Object.getPrototypeOf(Function.prototype.toString).isPrototypeOf(ctx.toString)\n if (!hasSameProto) return ctx.toString()\n return target.call(ctx)\n }\n })\n utils.replaceProperty(Function.prototype, 'toString', { value: toStringProxy })\n}\nutils.replaceWithProxy = (obj, propName, handler) => {\n utils.preloadCache()\n const originalObj = obj[propName]\n const proxyObj = new Proxy(obj[propName], utils.stripProxyFromErrors(handler))\n utils.replaceProperty(obj, propName, { value: proxyObj })\n utils.redirectToString(proxyObj, originalObj)\n return true\n}\nutils.mockWithProxy = (obj, propName, pseudoTarget, handler) => {\n utils.preloadCache()\n const proxyObj = new Proxy(pseudoTarget, utils.stripProxyFromErrors(handler))\n utils.replaceProperty(obj, propName, { value: proxyObj })\n utils.patchToString(proxyObj)\n return true\n}\nutils.createProxy = (pseudoTarget, handler) => {\n utils.preloadCache()\n const proxyObj = new Proxy(pseudoTarget, utils.stripProxyFromErrors(handler))\n utils.patchToString(proxyObj)\n return proxyObj\n}\nutils.splitObjPath = objPath => ({\n objName: objPath.split('.').slice(0, -1).join('.'),\n propName: objPath.split('.').slice(-1)[0]\n})\nutils.replaceObjPathWithProxy = (objPath, handler) => {\n const { objName, propName } = utils.splitObjPath(objPath)\n const obj = eval(objName)\n return utils.replaceWithProxy(obj, propName, handler)\n}\nutils.execRecursively = (obj = {}, typeFilter = [], fn) => {\n function recurse(obj) {\n for (const key in obj) {\n if (obj[key] === undefined) continue\n if (obj[key] && typeof obj[key] === 'object') recurse(obj[key])\n else if (obj[key] && typeFilter.includes(typeof obj[key])) fn.call(this, obj[key])\n }\n }\n recurse(obj)\n return obj\n}\n";
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.utils_script = void 0;
4
+ exports.utils_script = `
5
+ const utils = {}
6
+ utils.stripProxyFromErrors = (handler = {}) => {
7
+ const newHandler = {}
8
+ const traps = Object.getOwnPropertyNames(handler)
9
+ traps.forEach(trap => {
10
+ newHandler[trap] = function() {
11
+ try { return handler[trap].apply(this, arguments || []) } catch (err) {
12
+ if (!err || !err.stack || !err.stack.includes('at ')) { throw err }
13
+ const stripWithBlacklist = stack => {
14
+ const blacklist = ['at Reflect.' + trap + ' ', 'at Object.' + trap + ' ', 'at Object.newHandler.<computed> [as ' + trap + '] ']
15
+ return err.stack.split('\\n').filter((line, index) => index !== 1).filter(line => !blacklist.some(bl => line.trim().startsWith(bl))).join('\\n')
16
+ }
17
+ const stripWithAnchor = stack => {
18
+ const stackArr = stack.split('\\n')
19
+ const anchor = 'at Object.newHandler.<computed> [as ' + trap + '] '
20
+ const anchorIndex = stackArr.findIndex(line => line.trim().startsWith(anchor))
21
+ if (anchorIndex === -1) return false
22
+ stackArr.splice(1, anchorIndex)
23
+ return stackArr.join('\\n')
24
+ }
25
+ err.stack = stripWithAnchor(err.stack) || stripWithBlacklist(err.stack)
26
+ throw err
27
+ }
28
+ }
29
+ })
30
+ return newHandler
31
+ }
32
+ utils.stripErrorWithAnchor = (err, anchor) => {
33
+ const stackArr = err.stack.split('\\n')
34
+ const anchorIndex = stackArr.findIndex(line => line.trim().startsWith(anchor))
35
+ if (anchorIndex === -1) return err
36
+ stackArr.splice(1, anchorIndex)
37
+ err.stack = stackArr.join('\\n')
38
+ return err
39
+ }
40
+ utils.replaceProperty = (obj, propName, descriptorOverrides = {}) => {
41
+ return Object.defineProperty(obj, propName, { ...(Object.getOwnPropertyDescriptor(obj, propName) || {}), ...descriptorOverrides })
42
+ }
43
+ utils.preloadCache = () => {
44
+ if (utils.cache) return
45
+ utils.cache = { Reflect: { get: Reflect.get.bind(Reflect), apply: Reflect.apply.bind(Reflect) }, nativeToStringStr: Function.toString + '' }
46
+ }
47
+ utils.makeNativeString = (name = '') => { utils.preloadCache(); return utils.cache.nativeToStringStr.replace('toString', name || '') }
48
+ utils.patchToString = (obj, str = '') => {
49
+ utils.preloadCache()
50
+ const toStringProxy = new Proxy(Function.prototype.toString, {
51
+ apply: function(target, ctx) {
52
+ if (ctx === Function.prototype.toString) return utils.makeNativeString('toString')
53
+ if (ctx === obj) return str || utils.makeNativeString(obj.name)
54
+ const hasSameProto = Object.getPrototypeOf(Function.prototype.toString).isPrototypeOf(ctx.toString)
55
+ if (!hasSameProto) return ctx.toString()
56
+ return target.call(ctx)
57
+ }
58
+ })
59
+ utils.replaceProperty(Function.prototype, 'toString', { value: toStringProxy })
60
+ }
61
+ utils.patchToStringNested = (obj = {}) => { return utils.execRecursively(obj, ['function'], utils.patchToString) }
62
+ utils.redirectToString = (proxyObj, originalObj) => {
63
+ utils.preloadCache()
64
+ const toStringProxy = new Proxy(Function.prototype.toString, {
65
+ apply: function(target, ctx) {
66
+ if (ctx === Function.prototype.toString) return utils.makeNativeString('toString')
67
+ if (ctx === proxyObj) {
68
+ const fallback = () => originalObj && originalObj.name ? utils.makeNativeString(originalObj.name) : utils.makeNativeString(proxyObj.name)
69
+ return originalObj + '' || fallback()
70
+ }
71
+ const hasSameProto = Object.getPrototypeOf(Function.prototype.toString).isPrototypeOf(ctx.toString)
72
+ if (!hasSameProto) return ctx.toString()
73
+ return target.call(ctx)
74
+ }
75
+ })
76
+ utils.replaceProperty(Function.prototype, 'toString', { value: toStringProxy })
77
+ }
78
+ utils.replaceWithProxy = (obj, propName, handler) => {
79
+ utils.preloadCache()
80
+ const originalObj = obj[propName]
81
+ const proxyObj = new Proxy(obj[propName], utils.stripProxyFromErrors(handler))
82
+ utils.replaceProperty(obj, propName, { value: proxyObj })
83
+ utils.redirectToString(proxyObj, originalObj)
84
+ return true
85
+ }
86
+ utils.mockWithProxy = (obj, propName, pseudoTarget, handler) => {
87
+ utils.preloadCache()
88
+ const proxyObj = new Proxy(pseudoTarget, utils.stripProxyFromErrors(handler))
89
+ utils.replaceProperty(obj, propName, { value: proxyObj })
90
+ utils.patchToString(proxyObj)
91
+ return true
92
+ }
93
+ utils.createProxy = (pseudoTarget, handler) => {
94
+ utils.preloadCache()
95
+ const proxyObj = new Proxy(pseudoTarget, utils.stripProxyFromErrors(handler))
96
+ utils.patchToString(proxyObj)
97
+ return proxyObj
98
+ }
99
+ utils.splitObjPath = objPath => ({
100
+ objName: objPath.split('.').slice(0, -1).join('.'),
101
+ propName: objPath.split('.').slice(-1)[0]
102
+ })
103
+ utils.replaceObjPathWithProxy = (objPath, handler) => {
104
+ const { objName, propName } = utils.splitObjPath(objPath)
105
+ const obj = eval(objName)
106
+ return utils.replaceWithProxy(obj, propName, handler)
107
+ }
108
+ utils.execRecursively = (obj = {}, typeFilter = [], fn) => {
109
+ function recurse(obj) {
110
+ for (const key in obj) {
111
+ if (obj[key] === undefined) continue
112
+ if (obj[key] && typeof obj[key] === 'object') recurse(obj[key])
113
+ else if (obj[key] && typeFilter.includes(typeof obj[key])) fn.call(this, obj[key])
114
+ }
115
+ }
116
+ recurse(obj)
117
+ return obj
118
+ }
119
+ `;
@@ -0,0 +1 @@
1
+ export declare const webgl_vendor_script = "\nconst getParameterProxy = {\n apply: function(target, ctx, args) {\n const param = (args || [])[0]\n const UNMASKED_VENDOR_WEBGL = 0x9245\n const UNMASKED_RENDERER_WEBGL = 0x9246\n if (param === UNMASKED_VENDOR_WEBGL) { return opts.webgl_vendor || 'Intel Inc.' }\n if (param === UNMASKED_RENDERER_WEBGL) { return opts.webgl_renderer || 'Intel Iris OpenGL Engine' }\n return utils.cache.Reflect.apply(target, ctx, args)\n }\n}\nutils.replaceWithProxy(WebGLRenderingContext.prototype, 'getParameter', getParameterProxy)\n";
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.webgl_vendor_script = void 0;
4
+ exports.webgl_vendor_script = `
5
+ const getParameterProxy = {
6
+ apply: function(target, ctx, args) {
7
+ const param = (args || [])[0]
8
+ const UNMASKED_VENDOR_WEBGL = 0x9245
9
+ const UNMASKED_RENDERER_WEBGL = 0x9246
10
+ if (param === UNMASKED_VENDOR_WEBGL) { return opts.webgl_vendor || 'Intel Inc.' }
11
+ if (param === UNMASKED_RENDERER_WEBGL) { return opts.webgl_renderer || 'Intel Iris OpenGL Engine' }
12
+ return utils.cache.Reflect.apply(target, ctx, args)
13
+ }
14
+ }
15
+ utils.replaceWithProxy(WebGLRenderingContext.prototype, 'getParameter', getParameterProxy)
16
+ `;
@@ -0,0 +1 @@
1
+ export declare const window_outerdimensions = "\ntry {\n if (window.outerWidth === 0) { Object.defineProperty(window, 'outerWidth', { get: () => window.innerWidth }) }\n if (window.outerHeight === 0) { Object.defineProperty(window, 'outerHeight', { get: () => window.innerHeight }) }\n} catch (err) { /* noop */ }\n";
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.window_outerdimensions = void 0;
4
+ exports.window_outerdimensions = `
5
+ try {
6
+ if (window.outerWidth === 0) { Object.defineProperty(window, 'outerWidth', { get: () => window.innerWidth }) }
7
+ if (window.outerHeight === 0) { Object.defineProperty(window, 'outerHeight', { get: () => window.innerHeight }) }
8
+ } catch (err) { /* noop */ }
9
+ `;
@@ -0,0 +1,96 @@
1
+ import { Browser } from "playwright";
2
+ import type { TikTokPlaywrightSession, CreateSessionsOptions, ResourceStats, HealthCheckResult } from "./types";
3
+ import { User, type UserOptions } from "./api/user";
4
+ import { Video, type VideoOptions } from "./api/video";
5
+ import { Sound, type SoundOptions } from "./api/sound";
6
+ import { Hashtag, type HashtagOptions } from "./api/hashtag";
7
+ import { Comment } from "./api/comment";
8
+ import { Trending } from "./api/trending";
9
+ import { Search } from "./api/search";
10
+ import { Playlist, type PlaylistOptions } from "./api/playlist";
11
+ type LogLevel = "debug" | "info" | "warn" | "error";
12
+ export declare class Logger {
13
+ private level;
14
+ private name;
15
+ constructor(name: string, level?: LogLevel);
16
+ private _levels;
17
+ private _log;
18
+ debug(msg: string): void;
19
+ info(msg: string): void;
20
+ warn(msg: string): void;
21
+ error(msg: string): void;
22
+ }
23
+ export interface MakeRequestOptions {
24
+ url: string;
25
+ headers?: Record<string, string> | null;
26
+ params?: Record<string, unknown> | null;
27
+ retries?: number;
28
+ exponentialBackoff?: boolean;
29
+ sessionIndex?: number;
30
+ }
31
+ export declare class TikTokApi {
32
+ readonly trending: Trending;
33
+ readonly search: Search;
34
+ sessions: TikTokPlaywrightSession[];
35
+ browser: Browser | null;
36
+ playwright: {
37
+ stop: () => Promise<void>;
38
+ } | null;
39
+ private _sessionRecoveryEnabled;
40
+ private _sessionCreationLock;
41
+ private _cleanupCalled;
42
+ private _autoCleanupDeadSessions;
43
+ private _playwrightInstance;
44
+ private _userAgent;
45
+ readonly logger: Logger;
46
+ constructor(options?: {
47
+ loggingLevel?: LogLevel;
48
+ loggerName?: string;
49
+ });
50
+ user(options: UserOptions): User;
51
+ video(options: VideoOptions): Video;
52
+ sound(options: SoundOptions): Sound;
53
+ hashtag(options: HashtagOptions): Hashtag;
54
+ comment(options: {
55
+ data?: Record<string, unknown>;
56
+ }): Comment;
57
+ playlist(options: PlaylistOptions): Playlist;
58
+ private _setSessionParams;
59
+ _isSessionValid(session: TikTokPlaywrightSession): Promise<boolean>;
60
+ _markSessionInvalid(session: TikTokPlaywrightSession): Promise<void>;
61
+ _getValidSessionIndex(kwargs?: {
62
+ sessionIndex?: number;
63
+ }): Promise<[number, TikTokPlaywrightSession]>;
64
+ private _recoverSessions;
65
+ _getSession(kwargs?: {
66
+ sessionIndex?: number;
67
+ }): [number, TikTokPlaywrightSession];
68
+ createSessions(options?: CreateSessionsOptions): Promise<void>;
69
+ private _createSession;
70
+ setSessionCookies(session: TikTokPlaywrightSession, cookies: Record<string, unknown>[]): Promise<void>;
71
+ getSessionCookies(session: TikTokPlaywrightSession): Promise<Record<string, string>>;
72
+ runFetchScript(url: string, headers: Record<string, string>, kwargs?: {
73
+ sessionIndex?: number;
74
+ }): Promise<string>;
75
+ generateXBogus(url: string, kwargs?: {
76
+ sessionIndex?: number;
77
+ }): Promise<Record<string, string>>;
78
+ signUrl(url: string, kwargs?: {
79
+ sessionIndex?: number;
80
+ }): Promise<string>;
81
+ /**
82
+ * Saves the current Playwright browser context state (cookies, local storage) to a file.
83
+ * You can load this state back by passing \`contextOptions: { storageState: "path.json" }\` to \`createSessions\`.
84
+ */
85
+ saveSessionState(path: string, sessionIndex?: number): Promise<void>;
86
+ makeRequest(options: MakeRequestOptions): Promise<Record<string, unknown>>;
87
+ closeSessions(): Promise<void>;
88
+ stopPlaywright(): Promise<void>;
89
+ getSessionContent(url: string, kwargs?: {
90
+ sessionIndex?: number;
91
+ }): Promise<string>;
92
+ getResourceStats(): ResourceStats;
93
+ healthCheck(): Promise<HealthCheckResult>;
94
+ [Symbol.asyncDispose](): Promise<void>;
95
+ }
96
+ export {};