untiktok-api 1.0.3 → 1.0.4
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/LICENSE +20 -20
- package/LICENSE.txt +20 -20
- package/README.md +83 -83
- package/dist/stealth/js/chrome_app.js +23 -23
- package/dist/stealth/js/chrome_csi.js +10 -10
- package/dist/stealth/js/chrome_hairline.js +12 -12
- package/dist/stealth/js/chrome_load_times.js +24 -24
- package/dist/stealth/js/chrome_runtime_script.js +80 -80
- package/dist/stealth/js/generate_magic_arrays.js +24 -24
- package/dist/stealth/js/iframe_contentWindow.js +18 -18
- package/dist/stealth/js/media_codecs.js +12 -12
- package/dist/stealth/js/navigator_hardwareConcurrency.js +2 -2
- package/dist/stealth/js/navigator_languages.js +2 -2
- package/dist/stealth/js/navigator_permissions.js +7 -7
- package/dist/stealth/js/navigator_platform.js +4 -4
- package/dist/stealth/js/navigator_plugins_script.js +33 -33
- package/dist/stealth/js/navigator_userAgent_script.js +4 -4
- package/dist/stealth/js/navigator_vendor_script.js +2 -2
- package/dist/stealth/js/utils_script.js +115 -115
- package/dist/stealth/js/webgl_vendor_script.js +12 -12
- package/dist/stealth/js/window_outerdimensions.js +5 -5
- package/package.json +49 -49
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2019 David Teather
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2019 David Teather
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
SOFTWARE.
|
package/LICENSE.txt
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2019 David Teather
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2019 David Teather
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,83 +1,83 @@
|
|
|
1
|
-
# UnTikTok-Api
|
|
2
|
-
|
|
3
|
-
> An unofficial TikTok API wrapper in TypeScript, originally ported from the [TikTok-Api](https://github.com/davidteather/TikTok-Api) Python library.
|
|
4
|
-
>
|
|
5
|
-
> **Disclaimer:** This project is not affiliated with, endorsed by, or connected to TikTok, ByteDance, or the original author of the Python TikTok-Api. It is an independent, open-source TypeScript port designed for integration into Node.js applications and AI tools.
|
|
6
|
-
|
|
7
|
-
[](https://www.npmjs.com/package/untiktok-api)
|
|
8
|
-
[](https://www.typescriptlang.org/)
|
|
9
|
-
[](https://playwright.dev/)
|
|
10
|
-
[](https://nodejs.org/)
|
|
11
|
-
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
## Table of Contents
|
|
15
|
-
|
|
16
|
-
- [Features](#features)
|
|
17
|
-
- [Installation](#installation)
|
|
18
|
-
- [Quick Start](#quick-start)
|
|
19
|
-
- [API Reference](#api-reference)
|
|
20
|
-
- [Examples](#examples)
|
|
21
|
-
- [Common Issues](#common-issues)
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## Features
|
|
26
|
-
|
|
27
|
-
This API allows you to extract and automate interactions with TikTok data without requiring an official developer API key. It achieves this by using Playwright and stealth scripts to interface directly with TikTok's web endpoints.
|
|
28
|
-
|
|
29
|
-
**Capabilities include:**
|
|
30
|
-
- **Trending Feeds:** Fetch the most viral and trending videos on the platform.
|
|
31
|
-
- **User Profiles:** Retrieve a user's uploaded videos, liked videos, **favorited videos**, **reposted videos**, **pinned videos**, **followers/following lists**, profile information, and **live stream status**.
|
|
32
|
-
- **Hashtags:** Fetch videos under specific hashtags.
|
|
33
|
-
- **Search:** Search for specific users or videos by keyword.
|
|
34
|
-
- **Comments:** Extract comments and replies from specific videos, including support for **TikTok Stickers**.
|
|
35
|
-
- **Sounds/Music:** Retrieve videos associated with a specific audio track or sound.
|
|
36
|
-
- **Downloads:** Download raw video bytes (without watermarks) and audio streams directly.
|
|
37
|
-
|
|
38
|
-
---
|
|
39
|
-
|
|
40
|
-
## Installation
|
|
41
|
-
|
|
42
|
-
Install the package directly from NPM:
|
|
43
|
-
```bash
|
|
44
|
-
npm install untiktok-api
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
Since this wrapper relies on Playwright to interface with TikTok, you must also install the required Playwright browsers (specifically Chromium):
|
|
48
|
-
```bash
|
|
49
|
-
npx playwright install chromium
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### Building from Source
|
|
53
|
-
|
|
54
|
-
If you want to contribute, modify, or build the project locally:
|
|
55
|
-
```bash
|
|
56
|
-
git clone https://github.com/AlGhozaliRamadhan/UnTikTok-Api.git
|
|
57
|
-
cd UnTikTok-Api
|
|
58
|
-
npm install
|
|
59
|
-
npm run build
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
---
|
|
63
|
-
|
|
64
|
-
## Quick Start
|
|
65
|
-
Looking to get started immediately? Check out the [Quick Start Guide](./docs/quick_start.md).
|
|
66
|
-
|
|
67
|
-
---
|
|
68
|
-
|
|
69
|
-
## API Reference
|
|
70
|
-
For a full list of classes, methods, and constructor options, check out the [API Reference](./docs/api_reference.md).
|
|
71
|
-
|
|
72
|
-
---
|
|
73
|
-
|
|
74
|
-
## Examples & Guides
|
|
75
|
-
|
|
76
|
-
For detailed examples and tutorials on how to use specific features, check out the dedicated guides in the `docs/` folder:
|
|
77
|
-
|
|
78
|
-
- [Trending Videos](./docs/trending.md)
|
|
79
|
-
- [User Data (Videos, Likes, Reposts) 🆕](./docs/user.md)
|
|
80
|
-
- [Hashtag Videos](./docs/hashtag.md)
|
|
81
|
-
- [Search Users](./docs/search.md)
|
|
82
|
-
- [Download Videos](./docs/download.md)
|
|
83
|
-
- [Session Caching (Bot evasion)](./docs/session_caching.md)
|
|
1
|
+
# UnTikTok-Api
|
|
2
|
+
|
|
3
|
+
> An unofficial TikTok API wrapper in TypeScript, originally ported from the [TikTok-Api](https://github.com/davidteather/TikTok-Api) Python library.
|
|
4
|
+
>
|
|
5
|
+
> **Disclaimer:** This project is not affiliated with, endorsed by, or connected to TikTok, ByteDance, or the original author of the Python TikTok-Api. It is an independent, open-source TypeScript port designed for integration into Node.js applications and AI tools.
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/untiktok-api)
|
|
8
|
+
[](https://www.typescriptlang.org/)
|
|
9
|
+
[](https://playwright.dev/)
|
|
10
|
+
[](https://nodejs.org/)
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Table of Contents
|
|
15
|
+
|
|
16
|
+
- [Features](#features)
|
|
17
|
+
- [Installation](#installation)
|
|
18
|
+
- [Quick Start](#quick-start)
|
|
19
|
+
- [API Reference](#api-reference)
|
|
20
|
+
- [Examples](#examples)
|
|
21
|
+
- [Common Issues](#common-issues)
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Features
|
|
26
|
+
|
|
27
|
+
This API allows you to extract and automate interactions with TikTok data without requiring an official developer API key. It achieves this by using Playwright and stealth scripts to interface directly with TikTok's web endpoints.
|
|
28
|
+
|
|
29
|
+
**Capabilities include:**
|
|
30
|
+
- **Trending Feeds:** Fetch the most viral and trending videos on the platform.
|
|
31
|
+
- **User Profiles:** Retrieve a user's uploaded videos, liked videos, **favorited videos**, **reposted videos**, **pinned videos**, **followers/following lists**, profile information, and **live stream status**.
|
|
32
|
+
- **Hashtags:** Fetch videos under specific hashtags.
|
|
33
|
+
- **Search:** Search for specific users or videos by keyword.
|
|
34
|
+
- **Comments:** Extract comments and replies from specific videos, including support for **TikTok Stickers**.
|
|
35
|
+
- **Sounds/Music:** Retrieve videos associated with a specific audio track or sound.
|
|
36
|
+
- **Downloads:** Download raw video bytes (without watermarks) and audio streams directly.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
Install the package directly from NPM:
|
|
43
|
+
```bash
|
|
44
|
+
npm install untiktok-api
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Since this wrapper relies on Playwright to interface with TikTok, you must also install the required Playwright browsers (specifically Chromium):
|
|
48
|
+
```bash
|
|
49
|
+
npx playwright install chromium
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Building from Source
|
|
53
|
+
|
|
54
|
+
If you want to contribute, modify, or build the project locally:
|
|
55
|
+
```bash
|
|
56
|
+
git clone https://github.com/AlGhozaliRamadhan/UnTikTok-Api.git
|
|
57
|
+
cd UnTikTok-Api
|
|
58
|
+
npm install
|
|
59
|
+
npm run build
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Quick Start
|
|
65
|
+
Looking to get started immediately? Check out the [Quick Start Guide](./docs/quick_start.md).
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## API Reference
|
|
70
|
+
For a full list of classes, methods, and constructor options, check out the [API Reference](./docs/api_reference.md).
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Examples & Guides
|
|
75
|
+
|
|
76
|
+
For detailed examples and tutorials on how to use specific features, check out the dedicated guides in the `docs/` folder:
|
|
77
|
+
|
|
78
|
+
- [Trending Videos](./docs/trending.md)
|
|
79
|
+
- [User Data (Videos, Likes, Reposts) 🆕](./docs/user.md)
|
|
80
|
+
- [Hashtag Videos](./docs/hashtag.md)
|
|
81
|
+
- [Search Users](./docs/search.md)
|
|
82
|
+
- [Download Videos](./docs/download.md)
|
|
83
|
+
- [Session Caching (Bot evasion)](./docs/session_caching.md)
|
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.chrome_app = void 0;
|
|
4
|
-
exports.chrome_app = `
|
|
5
|
-
if (!window.chrome) {
|
|
6
|
-
Object.defineProperty(window, 'chrome', {
|
|
7
|
-
writable: true, enumerable: true, configurable: false, value: {}
|
|
8
|
-
})
|
|
9
|
-
}
|
|
10
|
-
if (!('app' in window.chrome)) {
|
|
11
|
-
const makeError = {
|
|
12
|
-
ErrorInInvocation: fn => {
|
|
13
|
-
const err = new TypeError(\`Error in invocation of app.\${fn}()\`)
|
|
14
|
-
return utils.stripErrorWithAnchor(err, \`at \${fn} (eval at <anonymous>\`)
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
const APP_STATIC_DATA = JSON.parse(\`{"isInstalled":false,"InstallState":{"DISABLED":"disabled","INSTALLED":"installed","NOT_INSTALLED":"not_installed"},"RunningState":{"CANNOT_RUN":"cannot_run","READY_TO_RUN":"ready_to_run","RUNNING":"running"}}\`)
|
|
18
|
-
window.chrome.app = {
|
|
19
|
-
...APP_STATIC_DATA,
|
|
20
|
-
get isInstalled() { return false },
|
|
21
|
-
getDetails: function getDetails() { if (arguments.length) throw makeError.ErrorInInvocation('getDetails'); return null },
|
|
22
|
-
getIsInstalled: function getIsInstalled() { if (arguments.length) throw makeError.ErrorInInvocation('getIsInstalled'); return false },
|
|
23
|
-
runningState: function runningState() { if (arguments.length) throw makeError.ErrorInInvocation('runningState'); return 'cannot_run' }
|
|
24
|
-
}
|
|
25
|
-
utils.patchToStringNested(window.chrome.app)
|
|
26
|
-
}
|
|
4
|
+
exports.chrome_app = `
|
|
5
|
+
if (!window.chrome) {
|
|
6
|
+
Object.defineProperty(window, 'chrome', {
|
|
7
|
+
writable: true, enumerable: true, configurable: false, value: {}
|
|
8
|
+
})
|
|
9
|
+
}
|
|
10
|
+
if (!('app' in window.chrome)) {
|
|
11
|
+
const makeError = {
|
|
12
|
+
ErrorInInvocation: fn => {
|
|
13
|
+
const err = new TypeError(\`Error in invocation of app.\${fn}()\`)
|
|
14
|
+
return utils.stripErrorWithAnchor(err, \`at \${fn} (eval at <anonymous>\`)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const APP_STATIC_DATA = JSON.parse(\`{"isInstalled":false,"InstallState":{"DISABLED":"disabled","INSTALLED":"installed","NOT_INSTALLED":"not_installed"},"RunningState":{"CANNOT_RUN":"cannot_run","READY_TO_RUN":"ready_to_run","RUNNING":"running"}}\`)
|
|
18
|
+
window.chrome.app = {
|
|
19
|
+
...APP_STATIC_DATA,
|
|
20
|
+
get isInstalled() { return false },
|
|
21
|
+
getDetails: function getDetails() { if (arguments.length) throw makeError.ErrorInInvocation('getDetails'); return null },
|
|
22
|
+
getIsInstalled: function getIsInstalled() { if (arguments.length) throw makeError.ErrorInInvocation('getIsInstalled'); return false },
|
|
23
|
+
runningState: function runningState() { if (arguments.length) throw makeError.ErrorInInvocation('runningState'); return 'cannot_run' }
|
|
24
|
+
}
|
|
25
|
+
utils.patchToStringNested(window.chrome.app)
|
|
26
|
+
}
|
|
27
27
|
`;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.chrome_csi = void 0;
|
|
4
|
-
exports.chrome_csi = `
|
|
5
|
-
if (!window.chrome) {
|
|
6
|
-
Object.defineProperty(window, 'chrome', { writable: true, enumerable: true, configurable: false, value: {} })
|
|
7
|
-
}
|
|
8
|
-
if (!('csi' in window.chrome)) {
|
|
9
|
-
window.chrome.csi = function() {
|
|
10
|
-
return { onloadT: Date.now(), startE: Date.now(), pageT: Date.now() - performance.timing.navigationStart, tran: 15 }
|
|
11
|
-
}
|
|
12
|
-
utils.patchToString(window.chrome.csi)
|
|
13
|
-
}
|
|
4
|
+
exports.chrome_csi = `
|
|
5
|
+
if (!window.chrome) {
|
|
6
|
+
Object.defineProperty(window, 'chrome', { writable: true, enumerable: true, configurable: false, value: {} })
|
|
7
|
+
}
|
|
8
|
+
if (!('csi' in window.chrome)) {
|
|
9
|
+
window.chrome.csi = function() {
|
|
10
|
+
return { onloadT: Date.now(), startE: Date.now(), pageT: Date.now() - performance.timing.navigationStart, tran: 15 }
|
|
11
|
+
}
|
|
12
|
+
utils.patchToString(window.chrome.csi)
|
|
13
|
+
}
|
|
14
14
|
`;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.chrome_hairline = void 0;
|
|
4
|
-
exports.chrome_hairline = `
|
|
5
|
-
const canvasContext = document.createElement('canvas').getContext('webgl')
|
|
6
|
-
if (canvasContext) {
|
|
7
|
-
const nativeGetParameter = WebGLRenderingContext.prototype.getParameter
|
|
8
|
-
utils.replaceWithProxy(WebGLRenderingContext.prototype, 'getParameter', {
|
|
9
|
-
apply: function(target, ctx, args) {
|
|
10
|
-
const param = (args || [])[0]
|
|
11
|
-
if (param === 37446) { return 0 }
|
|
12
|
-
return utils.cache.Reflect.apply(target, ctx, args)
|
|
13
|
-
}
|
|
14
|
-
})
|
|
15
|
-
}
|
|
4
|
+
exports.chrome_hairline = `
|
|
5
|
+
const canvasContext = document.createElement('canvas').getContext('webgl')
|
|
6
|
+
if (canvasContext) {
|
|
7
|
+
const nativeGetParameter = WebGLRenderingContext.prototype.getParameter
|
|
8
|
+
utils.replaceWithProxy(WebGLRenderingContext.prototype, 'getParameter', {
|
|
9
|
+
apply: function(target, ctx, args) {
|
|
10
|
+
const param = (args || [])[0]
|
|
11
|
+
if (param === 37446) { return 0 }
|
|
12
|
+
return utils.cache.Reflect.apply(target, ctx, args)
|
|
13
|
+
}
|
|
14
|
+
})
|
|
15
|
+
}
|
|
16
16
|
`;
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.chrome_load_times = void 0;
|
|
4
|
-
exports.chrome_load_times = `
|
|
5
|
-
if (!window.chrome) {
|
|
6
|
-
Object.defineProperty(window, 'chrome', { writable: true, enumerable: true, configurable: false, value: {} })
|
|
7
|
-
}
|
|
8
|
-
if (!('loadTimes' in window.chrome)) {
|
|
9
|
-
const loadTime = Date.now() / 1000 - Math.random() * 20
|
|
10
|
-
const startLoadTime = loadTime - Math.random() * 2
|
|
11
|
-
const data = {
|
|
12
|
-
get commitLoadTime() { return startLoadTime },
|
|
13
|
-
get finishDocumentLoadTime() { return loadTime },
|
|
14
|
-
get finishLoadTime() { return loadTime + Math.random() },
|
|
15
|
-
get firstPaintAfterLoadTime() { return 0 },
|
|
16
|
-
get firstPaintTime() { return startLoadTime + Math.random() * 2 },
|
|
17
|
-
get navigationType() { return 'Other' },
|
|
18
|
-
get npnNegotiatedProtocol() { return 'unknown' },
|
|
19
|
-
get requestTime() { return startLoadTime - 0.01 },
|
|
20
|
-
get startLoadTime() { return startLoadTime },
|
|
21
|
-
get wasAlternateProtocolAvailable() { return false },
|
|
22
|
-
get wasFetchedViaSpdy() { return false },
|
|
23
|
-
get wasNpnNegotiated() { return false }
|
|
24
|
-
}
|
|
25
|
-
utils.replaceProperty(window.chrome, 'loadTimes', { value: function loadTimes() { return data } })
|
|
26
|
-
utils.patchToString(window.chrome.loadTimes)
|
|
27
|
-
}
|
|
4
|
+
exports.chrome_load_times = `
|
|
5
|
+
if (!window.chrome) {
|
|
6
|
+
Object.defineProperty(window, 'chrome', { writable: true, enumerable: true, configurable: false, value: {} })
|
|
7
|
+
}
|
|
8
|
+
if (!('loadTimes' in window.chrome)) {
|
|
9
|
+
const loadTime = Date.now() / 1000 - Math.random() * 20
|
|
10
|
+
const startLoadTime = loadTime - Math.random() * 2
|
|
11
|
+
const data = {
|
|
12
|
+
get commitLoadTime() { return startLoadTime },
|
|
13
|
+
get finishDocumentLoadTime() { return loadTime },
|
|
14
|
+
get finishLoadTime() { return loadTime + Math.random() },
|
|
15
|
+
get firstPaintAfterLoadTime() { return 0 },
|
|
16
|
+
get firstPaintTime() { return startLoadTime + Math.random() * 2 },
|
|
17
|
+
get navigationType() { return 'Other' },
|
|
18
|
+
get npnNegotiatedProtocol() { return 'unknown' },
|
|
19
|
+
get requestTime() { return startLoadTime - 0.01 },
|
|
20
|
+
get startLoadTime() { return startLoadTime },
|
|
21
|
+
get wasAlternateProtocolAvailable() { return false },
|
|
22
|
+
get wasFetchedViaSpdy() { return false },
|
|
23
|
+
get wasNpnNegotiated() { return false }
|
|
24
|
+
}
|
|
25
|
+
utils.replaceProperty(window.chrome, 'loadTimes', { value: function loadTimes() { return data } })
|
|
26
|
+
utils.patchToString(window.chrome.loadTimes)
|
|
27
|
+
}
|
|
28
28
|
`;
|
|
@@ -1,84 +1,84 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.chrome_runtime_script = void 0;
|
|
4
|
-
exports.chrome_runtime_script = `
|
|
5
|
-
const STATIC_DATA = {"OnInstalledReason":{"CHROME_UPDATE":"chrome_update","INSTALL":"install","SHARED_MODULE_UPDATE":"shared_module_update","UPDATE":"update"},"OnRestartRequiredReason":{"APP_UPDATE":"app_update","OS_UPDATE":"os_update","PERIODIC":"periodic"},"PlatformArch":{"ARM":"arm","ARM64":"arm64","MIPS":"mips","MIPS64":"mips64","X86_32":"x86-32","X86_64":"x86-64"},"PlatformNaclArch":{"ARM":"arm","MIPS":"mips","MIPS64":"mips64","X86_32":"x86-32","X86_64":"x86-64"},"PlatformOs":{"ANDROID":"android","CROS":"cros","LINUX":"linux","MAC":"mac","OPENBSD":"openbsd","WIN":"win"},"RequestUpdateCheckStatus":{"NO_UPDATE":"no_update","THROTTLED":"throttled","UPDATE_AVAILABLE":"update_available"}}
|
|
6
|
-
if (!window.chrome) {
|
|
7
|
-
Object.defineProperty(window, 'chrome', { writable: true, enumerable: true, configurable: false, value: {} })
|
|
8
|
-
}
|
|
9
|
-
const existsAlready = 'runtime' in window.chrome
|
|
10
|
-
const isNotSecure = !window.location.protocol.startsWith('https')
|
|
11
|
-
if (!(existsAlready || (isNotSecure && !opts.runOnInsecureOrigins))) {
|
|
12
|
-
window.chrome.runtime = {
|
|
13
|
-
...STATIC_DATA,
|
|
14
|
-
get id() { return undefined },
|
|
15
|
-
connect: null,
|
|
16
|
-
sendMessage: null
|
|
17
|
-
}
|
|
18
|
-
const makeCustomRuntimeErrors = (preamble, method, extensionId) => ({
|
|
19
|
-
NoMatchingSignature: new TypeError(preamble + 'No matching signature.'),
|
|
20
|
-
MustSpecifyExtensionID: new TypeError(preamble + method + ' called from a webpage must specify an Extension ID (string) for its first argument.'),
|
|
21
|
-
InvalidExtensionID: new TypeError(preamble + "Invalid extension id: '" + extensionId + "'")
|
|
22
|
-
})
|
|
23
|
-
const isValidExtensionID = str => str.length === 32 && str.toLowerCase().match(/^[a-p]+$/)
|
|
24
|
-
const sendMessageHandler = {
|
|
25
|
-
apply: function(target, ctx, args) {
|
|
26
|
-
const [extensionId, options, responseCallback] = args || []
|
|
27
|
-
const errorPreamble = 'Error in invocation of runtime.sendMessage(optional string extensionId, any message, optional object options, optional function responseCallback): '
|
|
28
|
-
const Errors = makeCustomRuntimeErrors(errorPreamble, 'chrome.runtime.sendMessage()', extensionId)
|
|
29
|
-
const noArguments = args.length === 0, tooManyArguments = args.length > 4
|
|
30
|
-
const incorrectOptions = options && typeof options !== 'object'
|
|
31
|
-
const incorrectResponseCallback = responseCallback && typeof responseCallback !== 'function'
|
|
32
|
-
if (noArguments || tooManyArguments || incorrectOptions || incorrectResponseCallback) throw Errors.NoMatchingSignature
|
|
33
|
-
if (args.length < 2) throw Errors.MustSpecifyExtensionID
|
|
34
|
-
if (typeof extensionId !== 'string') throw Errors.NoMatchingSignature
|
|
35
|
-
if (!isValidExtensionID(extensionId)) throw Errors.InvalidExtensionID
|
|
36
|
-
return undefined
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
utils.mockWithProxy(window.chrome.runtime, 'sendMessage', function sendMessage() {}, sendMessageHandler)
|
|
40
|
-
const connectHandler = {
|
|
41
|
-
apply: function(target, ctx, args) {
|
|
42
|
-
const [extensionId, connectInfo] = args || []
|
|
43
|
-
const errorPreamble = 'Error in invocation of runtime.connect(optional string extensionId, optional object connectInfo): '
|
|
44
|
-
const Errors = makeCustomRuntimeErrors(errorPreamble, 'chrome.runtime.connect()', extensionId)
|
|
45
|
-
const noArguments = args.length === 0, emptyStringArgument = args.length === 1 && extensionId === ''
|
|
46
|
-
if (noArguments || emptyStringArgument) throw Errors.MustSpecifyExtensionID
|
|
47
|
-
const tooManyArguments = args.length > 2, incorrectConnectInfoType = connectInfo && typeof connectInfo !== 'object'
|
|
48
|
-
if (tooManyArguments || incorrectConnectInfoType) throw Errors.NoMatchingSignature
|
|
49
|
-
const extensionIdIsString = typeof extensionId === 'string'
|
|
50
|
-
if (extensionIdIsString && extensionId === '') throw Errors.MustSpecifyExtensionID
|
|
51
|
-
if (extensionIdIsString && !isValidExtensionID(extensionId)) throw Errors.InvalidExtensionID
|
|
52
|
-
const validateConnectInfo = ci => {
|
|
53
|
-
if (args.length > 1) throw Errors.NoMatchingSignature
|
|
54
|
-
if (Object.keys(ci).length === 0) throw Errors.MustSpecifyExtensionID
|
|
55
|
-
Object.entries(ci).forEach(([k, v]) => {
|
|
56
|
-
const isExpected = ['name', 'includeTlsChannelId'].includes(k)
|
|
57
|
-
if (!isExpected) throw new TypeError(errorPreamble + "Unexpected property: '" + k + "'.")
|
|
58
|
-
if (k === 'name' && typeof v !== 'string') throw TypeError(errorPreamble + "Error at property '" + k + "': Invalid type: expected string, found " + typeof v + ".")
|
|
59
|
-
if (k === 'includeTlsChannelId' && typeof v !== 'boolean') throw TypeError(errorPreamble + "Error at property '" + k + "': Invalid type: expected boolean, found " + typeof v + ".")
|
|
60
|
-
})
|
|
61
|
-
}
|
|
62
|
-
if (typeof extensionId === 'object') { validateConnectInfo(extensionId); throw Errors.MustSpecifyExtensionID }
|
|
63
|
-
return utils.patchToStringNested(makeConnectResponse())
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
utils.mockWithProxy(window.chrome.runtime, 'connect', function connect() {}, connectHandler)
|
|
67
|
-
function makeConnectResponse() {
|
|
68
|
-
const onSomething = () => ({
|
|
69
|
-
addListener: function addListener() {}, dispatch: function dispatch() {},
|
|
70
|
-
hasListener: function hasListener() {}, hasListeners: function hasListeners() { return false },
|
|
71
|
-
removeListener: function removeListener() {}
|
|
72
|
-
})
|
|
73
|
-
return {
|
|
74
|
-
name: '', sender: undefined,
|
|
75
|
-
disconnect: function disconnect() {},
|
|
76
|
-
onDisconnect: onSomething(), onMessage: onSomething(),
|
|
77
|
-
postMessage: function postMessage() {
|
|
78
|
-
if (!arguments.length) throw new TypeError('Insufficient number of arguments.')
|
|
79
|
-
throw new Error('Attempting to use a disconnected port object')
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
4
|
+
exports.chrome_runtime_script = `
|
|
5
|
+
const STATIC_DATA = {"OnInstalledReason":{"CHROME_UPDATE":"chrome_update","INSTALL":"install","SHARED_MODULE_UPDATE":"shared_module_update","UPDATE":"update"},"OnRestartRequiredReason":{"APP_UPDATE":"app_update","OS_UPDATE":"os_update","PERIODIC":"periodic"},"PlatformArch":{"ARM":"arm","ARM64":"arm64","MIPS":"mips","MIPS64":"mips64","X86_32":"x86-32","X86_64":"x86-64"},"PlatformNaclArch":{"ARM":"arm","MIPS":"mips","MIPS64":"mips64","X86_32":"x86-32","X86_64":"x86-64"},"PlatformOs":{"ANDROID":"android","CROS":"cros","LINUX":"linux","MAC":"mac","OPENBSD":"openbsd","WIN":"win"},"RequestUpdateCheckStatus":{"NO_UPDATE":"no_update","THROTTLED":"throttled","UPDATE_AVAILABLE":"update_available"}}
|
|
6
|
+
if (!window.chrome) {
|
|
7
|
+
Object.defineProperty(window, 'chrome', { writable: true, enumerable: true, configurable: false, value: {} })
|
|
8
|
+
}
|
|
9
|
+
const existsAlready = 'runtime' in window.chrome
|
|
10
|
+
const isNotSecure = !window.location.protocol.startsWith('https')
|
|
11
|
+
if (!(existsAlready || (isNotSecure && !opts.runOnInsecureOrigins))) {
|
|
12
|
+
window.chrome.runtime = {
|
|
13
|
+
...STATIC_DATA,
|
|
14
|
+
get id() { return undefined },
|
|
15
|
+
connect: null,
|
|
16
|
+
sendMessage: null
|
|
17
|
+
}
|
|
18
|
+
const makeCustomRuntimeErrors = (preamble, method, extensionId) => ({
|
|
19
|
+
NoMatchingSignature: new TypeError(preamble + 'No matching signature.'),
|
|
20
|
+
MustSpecifyExtensionID: new TypeError(preamble + method + ' called from a webpage must specify an Extension ID (string) for its first argument.'),
|
|
21
|
+
InvalidExtensionID: new TypeError(preamble + "Invalid extension id: '" + extensionId + "'")
|
|
22
|
+
})
|
|
23
|
+
const isValidExtensionID = str => str.length === 32 && str.toLowerCase().match(/^[a-p]+$/)
|
|
24
|
+
const sendMessageHandler = {
|
|
25
|
+
apply: function(target, ctx, args) {
|
|
26
|
+
const [extensionId, options, responseCallback] = args || []
|
|
27
|
+
const errorPreamble = 'Error in invocation of runtime.sendMessage(optional string extensionId, any message, optional object options, optional function responseCallback): '
|
|
28
|
+
const Errors = makeCustomRuntimeErrors(errorPreamble, 'chrome.runtime.sendMessage()', extensionId)
|
|
29
|
+
const noArguments = args.length === 0, tooManyArguments = args.length > 4
|
|
30
|
+
const incorrectOptions = options && typeof options !== 'object'
|
|
31
|
+
const incorrectResponseCallback = responseCallback && typeof responseCallback !== 'function'
|
|
32
|
+
if (noArguments || tooManyArguments || incorrectOptions || incorrectResponseCallback) throw Errors.NoMatchingSignature
|
|
33
|
+
if (args.length < 2) throw Errors.MustSpecifyExtensionID
|
|
34
|
+
if (typeof extensionId !== 'string') throw Errors.NoMatchingSignature
|
|
35
|
+
if (!isValidExtensionID(extensionId)) throw Errors.InvalidExtensionID
|
|
36
|
+
return undefined
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
utils.mockWithProxy(window.chrome.runtime, 'sendMessage', function sendMessage() {}, sendMessageHandler)
|
|
40
|
+
const connectHandler = {
|
|
41
|
+
apply: function(target, ctx, args) {
|
|
42
|
+
const [extensionId, connectInfo] = args || []
|
|
43
|
+
const errorPreamble = 'Error in invocation of runtime.connect(optional string extensionId, optional object connectInfo): '
|
|
44
|
+
const Errors = makeCustomRuntimeErrors(errorPreamble, 'chrome.runtime.connect()', extensionId)
|
|
45
|
+
const noArguments = args.length === 0, emptyStringArgument = args.length === 1 && extensionId === ''
|
|
46
|
+
if (noArguments || emptyStringArgument) throw Errors.MustSpecifyExtensionID
|
|
47
|
+
const tooManyArguments = args.length > 2, incorrectConnectInfoType = connectInfo && typeof connectInfo !== 'object'
|
|
48
|
+
if (tooManyArguments || incorrectConnectInfoType) throw Errors.NoMatchingSignature
|
|
49
|
+
const extensionIdIsString = typeof extensionId === 'string'
|
|
50
|
+
if (extensionIdIsString && extensionId === '') throw Errors.MustSpecifyExtensionID
|
|
51
|
+
if (extensionIdIsString && !isValidExtensionID(extensionId)) throw Errors.InvalidExtensionID
|
|
52
|
+
const validateConnectInfo = ci => {
|
|
53
|
+
if (args.length > 1) throw Errors.NoMatchingSignature
|
|
54
|
+
if (Object.keys(ci).length === 0) throw Errors.MustSpecifyExtensionID
|
|
55
|
+
Object.entries(ci).forEach(([k, v]) => {
|
|
56
|
+
const isExpected = ['name', 'includeTlsChannelId'].includes(k)
|
|
57
|
+
if (!isExpected) throw new TypeError(errorPreamble + "Unexpected property: '" + k + "'.")
|
|
58
|
+
if (k === 'name' && typeof v !== 'string') throw TypeError(errorPreamble + "Error at property '" + k + "': Invalid type: expected string, found " + typeof v + ".")
|
|
59
|
+
if (k === 'includeTlsChannelId' && typeof v !== 'boolean') throw TypeError(errorPreamble + "Error at property '" + k + "': Invalid type: expected boolean, found " + typeof v + ".")
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
if (typeof extensionId === 'object') { validateConnectInfo(extensionId); throw Errors.MustSpecifyExtensionID }
|
|
63
|
+
return utils.patchToStringNested(makeConnectResponse())
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
utils.mockWithProxy(window.chrome.runtime, 'connect', function connect() {}, connectHandler)
|
|
67
|
+
function makeConnectResponse() {
|
|
68
|
+
const onSomething = () => ({
|
|
69
|
+
addListener: function addListener() {}, dispatch: function dispatch() {},
|
|
70
|
+
hasListener: function hasListener() {}, hasListeners: function hasListeners() { return false },
|
|
71
|
+
removeListener: function removeListener() {}
|
|
72
|
+
})
|
|
73
|
+
return {
|
|
74
|
+
name: '', sender: undefined,
|
|
75
|
+
disconnect: function disconnect() {},
|
|
76
|
+
onDisconnect: onSomething(), onMessage: onSomething(),
|
|
77
|
+
postMessage: function postMessage() {
|
|
78
|
+
if (!arguments.length) throw new TypeError('Insufficient number of arguments.')
|
|
79
|
+
throw new Error('Attempting to use a disconnected port object')
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
84
|
`;
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generate_magic_arrays = void 0;
|
|
4
|
-
exports.generate_magic_arrays = `
|
|
5
|
-
function generateMagicArray(dataArray = [], proto = MimeTypeArray.prototype, itemProto = MimeType.prototype, itemMainProp = 'type') {
|
|
6
|
-
const arr = []
|
|
7
|
-
arr.__proto__ = proto
|
|
8
|
-
for (const item of dataArray) {
|
|
9
|
-
const obj = {}
|
|
10
|
-
obj.__proto__ = itemProto
|
|
11
|
-
for (const [key, value] of Object.entries(item)) {
|
|
12
|
-
if (!key.startsWith('__')) { obj[key] = value }
|
|
13
|
-
}
|
|
14
|
-
Object.defineProperty(obj, itemMainProp, { configurable: true, enumerable: true, get: () => item[itemMainProp] })
|
|
15
|
-
arr.push(obj)
|
|
16
|
-
arr[item[itemMainProp]] = obj
|
|
17
|
-
}
|
|
18
|
-
const proxy = new Proxy(arr, {
|
|
19
|
-
get(target, key) {
|
|
20
|
-
if (key === 'length') { return target.length }
|
|
21
|
-
if (key === Symbol.toStringTag) { return Object.getPrototypeOf(target)[Symbol.toStringTag] }
|
|
22
|
-
if (key in target) { return target[key] }
|
|
23
|
-
return undefined
|
|
24
|
-
}
|
|
25
|
-
})
|
|
26
|
-
return proxy
|
|
27
|
-
}
|
|
4
|
+
exports.generate_magic_arrays = `
|
|
5
|
+
function generateMagicArray(dataArray = [], proto = MimeTypeArray.prototype, itemProto = MimeType.prototype, itemMainProp = 'type') {
|
|
6
|
+
const arr = []
|
|
7
|
+
arr.__proto__ = proto
|
|
8
|
+
for (const item of dataArray) {
|
|
9
|
+
const obj = {}
|
|
10
|
+
obj.__proto__ = itemProto
|
|
11
|
+
for (const [key, value] of Object.entries(item)) {
|
|
12
|
+
if (!key.startsWith('__')) { obj[key] = value }
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(obj, itemMainProp, { configurable: true, enumerable: true, get: () => item[itemMainProp] })
|
|
15
|
+
arr.push(obj)
|
|
16
|
+
arr[item[itemMainProp]] = obj
|
|
17
|
+
}
|
|
18
|
+
const proxy = new Proxy(arr, {
|
|
19
|
+
get(target, key) {
|
|
20
|
+
if (key === 'length') { return target.length }
|
|
21
|
+
if (key === Symbol.toStringTag) { return Object.getPrototypeOf(target)[Symbol.toStringTag] }
|
|
22
|
+
if (key in target) { return target[key] }
|
|
23
|
+
return undefined
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
return proxy
|
|
27
|
+
}
|
|
28
28
|
`;
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.iframe_contentWindow = void 0;
|
|
4
|
-
exports.iframe_contentWindow = `
|
|
5
|
-
try {
|
|
6
|
-
const getContentWindowProxy = {
|
|
7
|
-
apply: function(target, ctx, args) {
|
|
8
|
-
const iframe = args[0]
|
|
9
|
-
if (!iframe || iframe.nodeName !== 'IFRAME') { return utils.cache.Reflect.apply(target, ctx, args) }
|
|
10
|
-
const win = utils.cache.Reflect.apply(target, ctx, args)
|
|
11
|
-
win.Object = window.Object
|
|
12
|
-
win.Reflect = window.Reflect
|
|
13
|
-
return win
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
Object.defineProperty(HTMLIFrameElement.prototype, 'contentWindow', {
|
|
17
|
-
get() {
|
|
18
|
-
return new Proxy(HTMLIFrameElement.prototype.contentWindow, getContentWindowProxy)
|
|
19
|
-
}
|
|
20
|
-
})
|
|
21
|
-
} catch (err) { /* noop */ }
|
|
4
|
+
exports.iframe_contentWindow = `
|
|
5
|
+
try {
|
|
6
|
+
const getContentWindowProxy = {
|
|
7
|
+
apply: function(target, ctx, args) {
|
|
8
|
+
const iframe = args[0]
|
|
9
|
+
if (!iframe || iframe.nodeName !== 'IFRAME') { return utils.cache.Reflect.apply(target, ctx, args) }
|
|
10
|
+
const win = utils.cache.Reflect.apply(target, ctx, args)
|
|
11
|
+
win.Object = window.Object
|
|
12
|
+
win.Reflect = window.Reflect
|
|
13
|
+
return win
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
Object.defineProperty(HTMLIFrameElement.prototype, 'contentWindow', {
|
|
17
|
+
get() {
|
|
18
|
+
return new Proxy(HTMLIFrameElement.prototype.contentWindow, getContentWindowProxy)
|
|
19
|
+
}
|
|
20
|
+
})
|
|
21
|
+
} catch (err) { /* noop */ }
|
|
22
22
|
`;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.media_codecs = void 0;
|
|
4
|
-
exports.media_codecs = `
|
|
5
|
-
const makeCanPlayType = (supported, fn) => {
|
|
6
|
-
utils.replaceWithProxy(HTMLMediaElement.prototype, 'canPlayType', {
|
|
7
|
-
apply: function(target, ctx, args) {
|
|
8
|
-
const type = (args || [])[0]
|
|
9
|
-
const result = utils.cache.Reflect.apply(target, ctx, args)
|
|
10
|
-
if (type === supported) { return 'probably' }
|
|
11
|
-
return result
|
|
12
|
-
}
|
|
13
|
-
})
|
|
14
|
-
}
|
|
15
|
-
makeCanPlayType('video/ogg; codecs="theora"', fn => fn)
|
|
4
|
+
exports.media_codecs = `
|
|
5
|
+
const makeCanPlayType = (supported, fn) => {
|
|
6
|
+
utils.replaceWithProxy(HTMLMediaElement.prototype, 'canPlayType', {
|
|
7
|
+
apply: function(target, ctx, args) {
|
|
8
|
+
const type = (args || [])[0]
|
|
9
|
+
const result = utils.cache.Reflect.apply(target, ctx, args)
|
|
10
|
+
if (type === supported) { return 'probably' }
|
|
11
|
+
return result
|
|
12
|
+
}
|
|
13
|
+
})
|
|
14
|
+
}
|
|
15
|
+
makeCanPlayType('video/ogg; codecs="theora"', fn => fn)
|
|
16
16
|
`;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.navigator_hardwareConcurrency = void 0;
|
|
4
|
-
exports.navigator_hardwareConcurrency = `
|
|
5
|
-
utils.replaceProperty(Object.getPrototypeOf(navigator), 'hardwareConcurrency', { get: () => opts.navigator_hardware_concurrency || 4 })
|
|
4
|
+
exports.navigator_hardwareConcurrency = `
|
|
5
|
+
utils.replaceProperty(Object.getPrototypeOf(navigator), 'hardwareConcurrency', { get: () => opts.navigator_hardware_concurrency || 4 })
|
|
6
6
|
`;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.navigator_languages = void 0;
|
|
4
|
-
exports.navigator_languages = `
|
|
5
|
-
utils.replaceProperty(Object.getPrototypeOf(navigator), 'languages', { get: () => opts.languages || ['en-US', 'en'] })
|
|
4
|
+
exports.navigator_languages = `
|
|
5
|
+
utils.replaceProperty(Object.getPrototypeOf(navigator), 'languages', { get: () => opts.languages || ['en-US', 'en'] })
|
|
6
6
|
`;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.navigator_permissions = void 0;
|
|
4
|
-
exports.navigator_permissions = `
|
|
5
|
-
const originalQuery = window.navigator.permissions.query
|
|
6
|
-
window.navigator.permissions.__proto__.query = parameters =>
|
|
7
|
-
parameters.name === 'notifications'
|
|
8
|
-
? Promise.resolve({ state: Notification.permission })
|
|
9
|
-
: originalQuery(parameters)
|
|
10
|
-
utils.patchToString(window.navigator.permissions.__proto__.query)
|
|
4
|
+
exports.navigator_permissions = `
|
|
5
|
+
const originalQuery = window.navigator.permissions.query
|
|
6
|
+
window.navigator.permissions.__proto__.query = parameters =>
|
|
7
|
+
parameters.name === 'notifications'
|
|
8
|
+
? Promise.resolve({ state: Notification.permission })
|
|
9
|
+
: originalQuery(parameters)
|
|
10
|
+
utils.patchToString(window.navigator.permissions.__proto__.query)
|
|
11
11
|
`;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.navigator_platform = void 0;
|
|
4
|
-
exports.navigator_platform = `
|
|
5
|
-
if (opts.navigator_platform) {
|
|
6
|
-
utils.replaceProperty(Object.getPrototypeOf(navigator), 'platform', { get: () => opts.navigator_platform })
|
|
7
|
-
}
|
|
4
|
+
exports.navigator_platform = `
|
|
5
|
+
if (opts.navigator_platform) {
|
|
6
|
+
utils.replaceProperty(Object.getPrototypeOf(navigator), 'platform', { get: () => opts.navigator_platform })
|
|
7
|
+
}
|
|
8
8
|
`;
|
|
@@ -1,37 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.navigator_plugins_script = void 0;
|
|
4
|
-
exports.navigator_plugins_script = `
|
|
5
|
-
const data = {
|
|
6
|
-
mimeTypes: [
|
|
7
|
-
{ type: 'application/pdf', suffixes: 'pdf', description: '', __pluginName: 'Chrome PDF Viewer' },
|
|
8
|
-
{ type: 'application/x-google-chrome-pdf', suffixes: 'pdf', description: 'Portable Document Format', __pluginName: 'Chrome PDF Plugin' },
|
|
9
|
-
{ type: 'application/x-nacl', suffixes: '', description: 'Native Client Executable', __pluginName: 'Native Client' },
|
|
10
|
-
{ type: 'application/x-pnacl', suffixes: '', description: 'Portable Native Client Executable', __pluginName: 'Native Client' }
|
|
11
|
-
],
|
|
12
|
-
plugins: [
|
|
13
|
-
{ name: 'Chrome PDF Plugin', filename: 'internal-pdf-viewer', description: 'Portable Document Format', __mimeTypes: ['application/x-google-chrome-pdf'] },
|
|
14
|
-
{ name: 'Chrome PDF Viewer', filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai', description: '', __mimeTypes: ['application/pdf'] },
|
|
15
|
-
{ name: 'Native Client', filename: 'internal-nacl-plugin', description: '', __mimeTypes: ['application/x-nacl', 'application/x-pnacl'] }
|
|
16
|
-
]
|
|
17
|
-
}
|
|
18
|
-
const hasPlugins = 'plugins' in navigator && navigator.plugins.length
|
|
19
|
-
if (!hasPlugins) {
|
|
20
|
-
const mimeTypes = generateMagicArray(data.mimeTypes, MimeTypeArray.prototype, MimeType.prototype, 'type')
|
|
21
|
-
const plugins = generateMagicArray(data.plugins, PluginArray.prototype, Plugin.prototype, 'name')
|
|
22
|
-
for (const pluginData of data.plugins) {
|
|
23
|
-
pluginData.__mimeTypes.forEach((type, index) => {
|
|
24
|
-
plugins[pluginData.name][index] = mimeTypes[type]
|
|
25
|
-
plugins[type] = mimeTypes[type]
|
|
26
|
-
Object.defineProperty(mimeTypes[type], 'enabledPlugin', {
|
|
27
|
-
value: JSON.parse(JSON.stringify(plugins[pluginData.name])),
|
|
28
|
-
writable: false, enumerable: false, configurable: false
|
|
29
|
-
})
|
|
30
|
-
})
|
|
31
|
-
}
|
|
32
|
-
const patchNavigator = (name, value) =>
|
|
33
|
-
utils.replaceProperty(Object.getPrototypeOf(navigator), name, { get() { return value } })
|
|
34
|
-
patchNavigator('mimeTypes', mimeTypes)
|
|
35
|
-
patchNavigator('plugins', plugins)
|
|
36
|
-
}
|
|
4
|
+
exports.navigator_plugins_script = `
|
|
5
|
+
const data = {
|
|
6
|
+
mimeTypes: [
|
|
7
|
+
{ type: 'application/pdf', suffixes: 'pdf', description: '', __pluginName: 'Chrome PDF Viewer' },
|
|
8
|
+
{ type: 'application/x-google-chrome-pdf', suffixes: 'pdf', description: 'Portable Document Format', __pluginName: 'Chrome PDF Plugin' },
|
|
9
|
+
{ type: 'application/x-nacl', suffixes: '', description: 'Native Client Executable', __pluginName: 'Native Client' },
|
|
10
|
+
{ type: 'application/x-pnacl', suffixes: '', description: 'Portable Native Client Executable', __pluginName: 'Native Client' }
|
|
11
|
+
],
|
|
12
|
+
plugins: [
|
|
13
|
+
{ name: 'Chrome PDF Plugin', filename: 'internal-pdf-viewer', description: 'Portable Document Format', __mimeTypes: ['application/x-google-chrome-pdf'] },
|
|
14
|
+
{ name: 'Chrome PDF Viewer', filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai', description: '', __mimeTypes: ['application/pdf'] },
|
|
15
|
+
{ name: 'Native Client', filename: 'internal-nacl-plugin', description: '', __mimeTypes: ['application/x-nacl', 'application/x-pnacl'] }
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
const hasPlugins = 'plugins' in navigator && navigator.plugins.length
|
|
19
|
+
if (!hasPlugins) {
|
|
20
|
+
const mimeTypes = generateMagicArray(data.mimeTypes, MimeTypeArray.prototype, MimeType.prototype, 'type')
|
|
21
|
+
const plugins = generateMagicArray(data.plugins, PluginArray.prototype, Plugin.prototype, 'name')
|
|
22
|
+
for (const pluginData of data.plugins) {
|
|
23
|
+
pluginData.__mimeTypes.forEach((type, index) => {
|
|
24
|
+
plugins[pluginData.name][index] = mimeTypes[type]
|
|
25
|
+
plugins[type] = mimeTypes[type]
|
|
26
|
+
Object.defineProperty(mimeTypes[type], 'enabledPlugin', {
|
|
27
|
+
value: JSON.parse(JSON.stringify(plugins[pluginData.name])),
|
|
28
|
+
writable: false, enumerable: false, configurable: false
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
const patchNavigator = (name, value) =>
|
|
33
|
+
utils.replaceProperty(Object.getPrototypeOf(navigator), name, { get() { return value } })
|
|
34
|
+
patchNavigator('mimeTypes', mimeTypes)
|
|
35
|
+
patchNavigator('plugins', plugins)
|
|
36
|
+
}
|
|
37
37
|
`;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.navigator_userAgent_script = void 0;
|
|
4
|
-
exports.navigator_userAgent_script = `
|
|
5
|
-
if (opts.navigator_user_agent) {
|
|
6
|
-
utils.replaceProperty(Object.getPrototypeOf(navigator), 'userAgent', { get: () => opts.navigator_user_agent })
|
|
7
|
-
}
|
|
4
|
+
exports.navigator_userAgent_script = `
|
|
5
|
+
if (opts.navigator_user_agent) {
|
|
6
|
+
utils.replaceProperty(Object.getPrototypeOf(navigator), 'userAgent', { get: () => opts.navigator_user_agent })
|
|
7
|
+
}
|
|
8
8
|
`;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.navigator_vendor_script = void 0;
|
|
4
|
-
exports.navigator_vendor_script = `
|
|
5
|
-
utils.replaceProperty(Object.getPrototypeOf(navigator), 'vendor', { get: () => opts.navigator_vendor || 'Google Inc.' })
|
|
4
|
+
exports.navigator_vendor_script = `
|
|
5
|
+
utils.replaceProperty(Object.getPrototypeOf(navigator), 'vendor', { get: () => opts.navigator_vendor || 'Google Inc.' })
|
|
6
6
|
`;
|
|
@@ -1,119 +1,119 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
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
|
-
}
|
|
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
119
|
`;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
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)
|
|
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
16
|
`;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
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 */ }
|
|
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
9
|
`;
|
package/package.json
CHANGED
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "untiktok-api",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Unofficial TikTok API wrapper in TypeScript (ported from Python)",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"types": "dist/index.d.ts",
|
|
7
|
-
"scripts": {
|
|
8
|
-
"build": "tsc -p tsconfig.build.json",
|
|
9
|
-
"dev": "ts-node src/index.ts",
|
|
10
|
-
"typecheck": "tsc --noEmit",
|
|
11
|
-
"lint": "eslint src",
|
|
12
|
-
"clean": "rimraf dist",
|
|
13
|
-
"prepublishOnly": "npm run clean && npm run build"
|
|
14
|
-
},
|
|
15
|
-
"files": [
|
|
16
|
-
"dist"
|
|
17
|
-
],
|
|
18
|
-
"keywords": [
|
|
19
|
-
"tiktok",
|
|
20
|
-
"api",
|
|
21
|
-
"scraper",
|
|
22
|
-
"typescript",
|
|
23
|
-
"playwright"
|
|
24
|
-
],
|
|
25
|
-
"author": "AlGhozaliRamadhan",
|
|
26
|
-
"license": "MIT",
|
|
27
|
-
"repository": {
|
|
28
|
-
"type": "git",
|
|
29
|
-
"url": "git+https://github.com/AlGhozaliRamadhan/UnTikTok-Api.git"
|
|
30
|
-
},
|
|
31
|
-
"bugs": {
|
|
32
|
-
"url": "https://github.com/AlGhozaliRamadhan/UnTikTok-Api/issues"
|
|
33
|
-
},
|
|
34
|
-
"homepage": "https://github.com/AlGhozaliRamadhan/UnTikTok-Api#readme",
|
|
35
|
-
"dependencies": {
|
|
36
|
-
"axios": "^1.17.0",
|
|
37
|
-
"https-proxy-agent": "^9.1.0",
|
|
38
|
-
"playwright": "^1.44.0"
|
|
39
|
-
},
|
|
40
|
-
"devDependencies": {
|
|
41
|
-
"@eslint/js": "^10.0.1",
|
|
42
|
-
"@types/node": "^25.9.3",
|
|
43
|
-
"eslint": "^10.5.0",
|
|
44
|
-
"rimraf": "^6.1.3",
|
|
45
|
-
"ts-node": "^10.9.2",
|
|
46
|
-
"typescript": "^6.0.3",
|
|
47
|
-
"typescript-eslint": "^8.61.0"
|
|
48
|
-
}
|
|
49
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "untiktok-api",
|
|
3
|
+
"version": "1.0.4",
|
|
4
|
+
"description": "Unofficial TikTok API wrapper in TypeScript (ported from Python)",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc -p tsconfig.build.json",
|
|
9
|
+
"dev": "ts-node src/index.ts",
|
|
10
|
+
"typecheck": "tsc --noEmit",
|
|
11
|
+
"lint": "eslint src",
|
|
12
|
+
"clean": "rimraf dist",
|
|
13
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"keywords": [
|
|
19
|
+
"tiktok",
|
|
20
|
+
"api",
|
|
21
|
+
"scraper",
|
|
22
|
+
"typescript",
|
|
23
|
+
"playwright"
|
|
24
|
+
],
|
|
25
|
+
"author": "AlGhozaliRamadhan",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "git+https://github.com/AlGhozaliRamadhan/UnTikTok-Api.git"
|
|
30
|
+
},
|
|
31
|
+
"bugs": {
|
|
32
|
+
"url": "https://github.com/AlGhozaliRamadhan/UnTikTok-Api/issues"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://github.com/AlGhozaliRamadhan/UnTikTok-Api#readme",
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"axios": "^1.17.0",
|
|
37
|
+
"https-proxy-agent": "^9.1.0",
|
|
38
|
+
"playwright": "^1.44.0"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@eslint/js": "^10.0.1",
|
|
42
|
+
"@types/node": "^25.9.3",
|
|
43
|
+
"eslint": "^10.5.0",
|
|
44
|
+
"rimraf": "^6.1.3",
|
|
45
|
+
"ts-node": "^10.9.2",
|
|
46
|
+
"typescript": "^6.0.3",
|
|
47
|
+
"typescript-eslint": "^8.61.0"
|
|
48
|
+
}
|
|
49
|
+
}
|