mirror of
https://github.com/yt-dlp/ejs.git
synced 2026-06-13 16:52:13 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06d71457ef | ||
|
|
3e76dde153 | ||
|
|
4f1d91dbb1 | ||
|
|
4b4ac2b896 | ||
|
|
2655b1f55f | ||
|
|
877164a326 | ||
|
|
25b77b7310 | ||
|
|
57fe708cf4 |
77
.github/workflows/ci.yml
vendored
77
.github/workflows/ci.yml
vendored
@@ -1,6 +1,8 @@
|
||||
name: CI
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '**'
|
||||
paths-ignore:
|
||||
- 'README.md'
|
||||
- 'LICENSE'
|
||||
@@ -21,7 +23,7 @@ jobs:
|
||||
name: Ruff format check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- uses: astral-sh/ruff-action@v3
|
||||
with:
|
||||
args: "check --output-format github"
|
||||
@@ -30,7 +32,7 @@ jobs:
|
||||
name: Ruff linting check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- uses: astral-sh/ruff-action@v3
|
||||
with:
|
||||
args: "format --check --diff"
|
||||
@@ -39,43 +41,44 @@ jobs:
|
||||
name: Prettier check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install Deno v2.x (latest)
|
||||
uses: denoland/setup-deno@v2
|
||||
with:
|
||||
deno-version: v2.x
|
||||
- name: Install Deno requirements
|
||||
- name: Install requirements
|
||||
run: |
|
||||
deno install
|
||||
python pnpm.py install --frozen-lockfile
|
||||
- name: Run Prettier check
|
||||
run: |
|
||||
deno task fmt:check
|
||||
python pnpm.py fmt:check
|
||||
|
||||
eslint:
|
||||
name: ESLint check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install Deno v2.x (latest)
|
||||
uses: denoland/setup-deno@v2
|
||||
with:
|
||||
deno-version: v2.x
|
||||
- name: Install Deno requirements
|
||||
- name: Install requirements
|
||||
run: |
|
||||
deno install
|
||||
python pnpm.py install --frozen-lockfile
|
||||
- name: Run ESLint check
|
||||
run: |
|
||||
deno task lint
|
||||
python pnpm.py lint
|
||||
|
||||
python_tests:
|
||||
name: Python tests
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ${{ matrix.runner }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
runner: [ubuntu-latest, windows-latest]
|
||||
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14', pypy-3.11]
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install Deno v2.x (latest)
|
||||
@@ -91,7 +94,15 @@ jobs:
|
||||
# `pip install -e` omits the force-included JS, so use `build` instead
|
||||
python -m pip install -U build
|
||||
python -m build
|
||||
- name: Unpack wheel (Linux)
|
||||
if: matrix.runner == 'ubuntu-latest'
|
||||
run: |
|
||||
unzip -u dist/yt_dlp_ejs-*.whl "yt_dlp_ejs/*"
|
||||
- name: Unpack wheel (Windows)
|
||||
if: matrix.runner == 'windows-latest'
|
||||
shell: pwsh
|
||||
run: |
|
||||
Expand-Archive -Path dist/yt_dlp_ejs-*.whl -DestinationPath ./ -Force
|
||||
- name: Run Python tests
|
||||
timeout-minutes: 5
|
||||
run: |
|
||||
@@ -101,17 +112,14 @@ jobs:
|
||||
name: Prepare JS runtime tests
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- name: Install Deno v2.x (latest)
|
||||
uses: denoland/setup-deno@v2
|
||||
with:
|
||||
deno-version: v2.x
|
||||
- name: Install Deno requirements
|
||||
- uses: actions/checkout@v6
|
||||
- uses: pnpm/action-setup@v4 # respects packageManager version in package.json
|
||||
- name: Install requirements
|
||||
run: |
|
||||
deno install
|
||||
python pnpm.py install --frozen-lockfile
|
||||
- name: Build control bundle
|
||||
run: |
|
||||
deno task bundle
|
||||
python pnpm.py run bundle
|
||||
- name: Generate bundle hashes
|
||||
run: |
|
||||
pushd dist
|
||||
@@ -132,6 +140,10 @@ jobs:
|
||||
path: |
|
||||
src/yt/solver/test/players
|
||||
key: test-player-js-${{ hashFiles('src/yt/solver/test/tests.ts') }}
|
||||
- name: Install Deno v2.x (latest)
|
||||
uses: denoland/setup-deno@v2
|
||||
with:
|
||||
deno-version: v2.x
|
||||
- name: Download player JS files
|
||||
run: |
|
||||
deno run \
|
||||
@@ -154,7 +166,7 @@ jobs:
|
||||
needs: [prepare]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install Deno
|
||||
@@ -178,7 +190,7 @@ jobs:
|
||||
grep -q 'yt_dlp_ejs/yt/solver/lib\.min\.js' .wheel_contents
|
||||
- name: Install Deno requirements
|
||||
run: |
|
||||
deno install
|
||||
python pnpm.py install --frozen-lockfile
|
||||
- name: Bundle with Deno
|
||||
run: |
|
||||
deno task bundle
|
||||
@@ -197,14 +209,14 @@ jobs:
|
||||
needs: [prepare]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install Deno
|
||||
uses: denoland/setup-deno@v2
|
||||
with:
|
||||
deno-version: "2.0.0" # minimum supported version
|
||||
- name: Install Deno requirements
|
||||
run: |
|
||||
deno install
|
||||
python pnpm.py install --frozen-lockfile
|
||||
- name: Download player JS artifact
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
@@ -221,7 +233,7 @@ jobs:
|
||||
needs: [prepare]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install Bun
|
||||
@@ -245,7 +257,7 @@ jobs:
|
||||
grep -q 'yt_dlp_ejs/yt/solver/lib\.min\.js' .wheel_contents
|
||||
- name: Install Bun requirements
|
||||
run: |
|
||||
bun install
|
||||
python pnpm.py install --frozen-lockfile
|
||||
- name: Bundle with Bun
|
||||
run: |
|
||||
bun --bun run bundle
|
||||
@@ -264,14 +276,14 @@ jobs:
|
||||
needs: [prepare]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version: "1.2.11" # XXX: We support 1.0.31, but test suite requires 1.2.11+
|
||||
- name: Install Bun requirements
|
||||
run: |
|
||||
bun install
|
||||
python pnpm.py install --frozen-lockfile
|
||||
- name: Download player JS artifact
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
@@ -286,7 +298,7 @@ jobs:
|
||||
needs: [prepare]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install Node
|
||||
@@ -310,7 +322,7 @@ jobs:
|
||||
grep -q 'yt_dlp_ejs/yt/solver/lib\.min\.js' .wheel_contents
|
||||
- name: Install Node requirements
|
||||
run: |
|
||||
npm install
|
||||
python pnpm.py install --frozen-lockfile
|
||||
- name: Bundle with Node
|
||||
run: |
|
||||
npm run bundle
|
||||
@@ -329,14 +341,14 @@ jobs:
|
||||
needs: [prepare]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "22.18" # XXX: We support 20.0, but test suite requires 22.18+
|
||||
- name: Install Node requirements
|
||||
run: |
|
||||
npm install
|
||||
python pnpm.py install --frozen-lockfile
|
||||
- name: Download player JS artifact
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
@@ -352,6 +364,7 @@ jobs:
|
||||
- ruff-lint
|
||||
- prettier
|
||||
- eslint
|
||||
- python_tests
|
||||
- deno_build
|
||||
- deno_tests
|
||||
- bun_build
|
||||
|
||||
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
name: Build artifacts
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: denoland/setup-deno@v2
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
compression-level: 0
|
||||
- name: Build JavaScript artifacts
|
||||
run: |
|
||||
deno install
|
||||
python pnpm.py install --frozen-lockfile
|
||||
deno task bundle
|
||||
- name: Upload JavaScript artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
@@ -73,7 +73,7 @@ jobs:
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/download-artifact@v5
|
||||
|
||||
33
README.md
33
README.md
@@ -12,9 +12,13 @@ pip install -U yt-dlp-ejs
|
||||
|
||||
## Development
|
||||
|
||||
While this project does pin its dependencies,
|
||||
it does not use lockfiles or enforce a particular package manager.
|
||||
You may install dependencies using any compatible package manager.
|
||||
The project uses [`pnpm`](<https://github.com/pnpm/pnpm>) as a package manager with
|
||||
dependencies pinned through `pnpm-lock.yaml`.
|
||||
|
||||
If you only have Python and a JS runtime you may instead invoke `./pnpm.py`,
|
||||
which will transparently invoke one of the supported JS runtimes to call `pnpm`.
|
||||
|
||||
This pure JavaScript approach should be runtime agnostic.
|
||||
If you notice differences between different runtimes' builds
|
||||
please open an issue [here](<https://github.com/yt-dlp/ejs/issues/new>).
|
||||
|
||||
@@ -26,34 +30,27 @@ The build hook will automatically invoke `deno`, `bun` or `node` as required.
|
||||
Alternatively, to only build the JavaScript files you can run the `bundle` script manually:
|
||||
|
||||
```bash
|
||||
# Deno:
|
||||
deno install
|
||||
deno task bundle
|
||||
|
||||
# Bun:
|
||||
bun install
|
||||
bun --bun run bundle
|
||||
|
||||
# Node:
|
||||
npm install
|
||||
npm run bundle
|
||||
python pnpm.py install --frozen-lockfile
|
||||
python pnpm.py run bundle
|
||||
```
|
||||
|
||||
This will automatically select an available runtime and invoke `pnpm` to build it.
|
||||
|
||||
### Tests
|
||||
|
||||
First, make sure the project's dependencies are installed and download the player JS files:
|
||||
|
||||
```bash
|
||||
# Deno:
|
||||
deno install
|
||||
python pnpm.py install --frozen-lockfile
|
||||
deno run src/yt/solver/test/download.ts
|
||||
|
||||
# Bun:
|
||||
bun install
|
||||
python pnpm.py install --frozen-lockfile
|
||||
bun --bun run src/yt/solver/test/download.ts
|
||||
|
||||
# Node 22.6+:
|
||||
npm install
|
||||
python pnpm.py install --frozen-lockfile
|
||||
node --experimental-strip-types src/yt/solver/test/download.ts
|
||||
```
|
||||
|
||||
@@ -74,6 +71,6 @@ node --test
|
||||
|
||||
This code is licensed under [Unlicense](<https://unlicense.org/>).
|
||||
|
||||
An exception to this are the prebuilt wheels, which contain both
|
||||
An exception to this is the prebuilt wheels, which contain both
|
||||
[`meriyah`](<https://github.com/meriyah/meriyah>) and [`astring`](<https://github.com/davidbonnet/astring>),
|
||||
licensed under [`ISC`](<https://github.com/meriyah/meriyah?tab=ISC-1-ov-file>) and [`MIT`](<https://github.com/davidbonnet/astring?tab=MIT-1-ov-file>), respectively.
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
|
||||
|
||||
|
||||
class CustomBuildHook(BuildHookInterface):
|
||||
def initialize(self, version, build_data):
|
||||
if shutil.which("deno"):
|
||||
print("Building with deno...", flush=True)
|
||||
os.environ["DENO_NO_UPDATE_CHECK"] = "1"
|
||||
subprocess.run(["deno", "install"], check=True)
|
||||
subprocess.run(["deno", "task", "bundle"], check=True)
|
||||
|
||||
elif shutil.which("bun"):
|
||||
print("Building with bun...", flush=True)
|
||||
subprocess.run(["bun", "install"], check=True)
|
||||
subprocess.run(["bun", "--bun", "run", "bundle"], check=True)
|
||||
|
||||
elif shutil.which("npm"):
|
||||
print("Building with npm...", flush=True)
|
||||
# npm is a batch file (`npm.cmd`) on windows, which requires `shell=True`
|
||||
requires_shell = os.name == "nt"
|
||||
subprocess.run(["npm", "install"], check=True, shell=requires_shell)
|
||||
subprocess.run(["npm", "run", "bundle"], check=True, shell=requires_shell)
|
||||
|
||||
else:
|
||||
raise RuntimeError(
|
||||
"One of 'deno', 'bun', or 'npm' could not be found. "
|
||||
"Please install one of them to proceed with the build."
|
||||
)
|
||||
|
||||
build_data["force_include"].update(
|
||||
{
|
||||
"dist/yt.solver.core.min.js": "yt_dlp_ejs/yt/solver/core.min.js",
|
||||
"dist/yt.solver.lib.min.js": "yt_dlp_ejs/yt/solver/lib.min.js",
|
||||
}
|
||||
)
|
||||
|
||||
def clean(self, versions):
|
||||
shutil.rmtree("node_modules", ignore_errors=True)
|
||||
@@ -25,5 +25,6 @@
|
||||
"rollup": "4.52.5",
|
||||
"rollup-plugin-license": "3.6.0",
|
||||
"typescript-eslint": "8.46.2"
|
||||
}
|
||||
},
|
||||
"packageManager": "pnpm@10.24.0"
|
||||
}
|
||||
|
||||
1782
pnpm-lock.yaml
generated
Normal file
1782
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
90
pnpm.py
Executable file
90
pnpm.py
Executable file
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env python
|
||||
import json
|
||||
import os
|
||||
import pathlib
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
try:
|
||||
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
|
||||
except ImportError:
|
||||
BuildHookInterface = object
|
||||
|
||||
|
||||
class CustomBuildHook(BuildHookInterface):
|
||||
def initialize(self, version, build_data):
|
||||
name, pnpm = build_pnpm()
|
||||
if pnpm is None:
|
||||
raise RuntimeError(
|
||||
"One of 'deno', 'bun', or 'npm' could not be found. "
|
||||
"Please install one of them to proceed with the build."
|
||||
)
|
||||
print(f"Building with {name}...")
|
||||
|
||||
pnpm(["install", "--frozen-lockfile"])
|
||||
pnpm(["run", "bundle"])
|
||||
|
||||
build_data["force_include"].update(
|
||||
{
|
||||
"dist/yt.solver.core.min.js": "yt_dlp_ejs/yt/solver/core.min.js",
|
||||
"dist/yt.solver.lib.min.js": "yt_dlp_ejs/yt/solver/lib.min.js",
|
||||
}
|
||||
)
|
||||
|
||||
def clean(self, versions):
|
||||
shutil.rmtree("node_modules", ignore_errors=True)
|
||||
|
||||
|
||||
def build_pnpm():
|
||||
package_json = pathlib.Path(__file__).with_name("package.json")
|
||||
with package_json.open("rb") as file:
|
||||
data = json.load(file)
|
||||
|
||||
package_manager = data["packageManager"]
|
||||
env = os.environ.copy()
|
||||
|
||||
if pnpm := shutil.which("pnpm"):
|
||||
name = "pnpm binary"
|
||||
cmd = [pnpm]
|
||||
|
||||
elif deno := shutil.which("deno"):
|
||||
name = "deno"
|
||||
env["DENO_NO_UPDATE_CHECK"] = "1"
|
||||
cmd = [
|
||||
deno,
|
||||
"run",
|
||||
"--allow-all",
|
||||
"--node-modules-dir=none",
|
||||
f"npm:{package_manager}",
|
||||
]
|
||||
|
||||
elif bun := shutil.which("bun"):
|
||||
name = "bun"
|
||||
cmd = [bun, "x", package_manager]
|
||||
|
||||
elif npm := shutil.which("npm"):
|
||||
name = "npm (node)"
|
||||
cmd = [npm, "exec", "--", package_manager]
|
||||
|
||||
else:
|
||||
return None, None
|
||||
|
||||
def run_pnpm(args: list[str]):
|
||||
return subprocess.check_call([*cmd, *args], env=env)
|
||||
|
||||
return name, run_pnpm
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
|
||||
name, pnpm = build_pnpm()
|
||||
if pnpm is None:
|
||||
print("ERROR: No suitable JavaScript runtime found", file=sys.stderr)
|
||||
sys.exit(128)
|
||||
print(f"Calling {name}...", file=sys.stderr)
|
||||
|
||||
try:
|
||||
pnpm(sys.argv[1:])
|
||||
except subprocess.CalledProcessError as error:
|
||||
sys.exit(error.returncode)
|
||||
@@ -47,6 +47,7 @@ source = "vcs"
|
||||
exclude = [
|
||||
"/.github/**",
|
||||
"/src/yt/solver/test/players/*",
|
||||
"!/src/yt/solver/test/players/.gitignore",
|
||||
]
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
@@ -56,6 +57,7 @@ packages = ["yt_dlp_ejs"]
|
||||
version-file = "yt_dlp_ejs/_version.py"
|
||||
|
||||
[tool.hatch.build.targets.wheel.hooks.custom]
|
||||
path = "pnpm.py"
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = [
|
||||
|
||||
21
src/types.ts
21
src/types.ts
@@ -1,7 +1,16 @@
|
||||
export type DeepPartial<T> = T extends object
|
||||
? Or<{
|
||||
[P in keyof T]?: DeepPartial<T[P]>;
|
||||
}>
|
||||
: Or<T>;
|
||||
type DP<T> = T extends (infer U)[]
|
||||
? DeepPartial<U>[]
|
||||
: T extends object
|
||||
? { [P in keyof T]?: DeepPartial<T[P]> }
|
||||
: T;
|
||||
|
||||
type Or<T> = T | { or: T[] };
|
||||
type ValueOf<T> = T extends (infer U)[]
|
||||
? U
|
||||
: T extends object
|
||||
? T[keyof T]
|
||||
: never;
|
||||
|
||||
export type DeepPartial<T> =
|
||||
| DP<T>
|
||||
| { or: DP<T>[] }
|
||||
| { anykey: DP<ValueOf<T>>[] };
|
||||
|
||||
@@ -2,26 +2,50 @@ import { type ESTree } from "meriyah";
|
||||
import { matchesStructure } from "../../utils.ts";
|
||||
import { type DeepPartial } from "../../types.ts";
|
||||
|
||||
const identifier: DeepPartial<ESTree.VariableDeclaration> = {
|
||||
type: "VariableDeclaration",
|
||||
kind: "var",
|
||||
declarations: [
|
||||
const identifier: DeepPartial<ESTree.Node> = {
|
||||
or: [
|
||||
{
|
||||
type: "VariableDeclarator",
|
||||
id: {
|
||||
type: "Identifier",
|
||||
},
|
||||
init: {
|
||||
type: "ArrayExpression",
|
||||
elements: [
|
||||
type: "VariableDeclaration",
|
||||
kind: "var",
|
||||
declarations: {
|
||||
anykey: [
|
||||
{
|
||||
type: "Identifier",
|
||||
type: "VariableDeclarator",
|
||||
id: {
|
||||
type: "Identifier",
|
||||
},
|
||||
init: {
|
||||
type: "ArrayExpression",
|
||||
elements: [
|
||||
{
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "ExpressionStatement",
|
||||
expression: {
|
||||
type: "AssignmentExpression",
|
||||
left: {
|
||||
type: "Identifier",
|
||||
},
|
||||
operator: "=",
|
||||
right: {
|
||||
type: "ArrayExpression",
|
||||
elements: [
|
||||
{
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
} as const;
|
||||
|
||||
const catchBlockBody = [
|
||||
{
|
||||
@@ -92,23 +116,37 @@ export function extract(
|
||||
return null;
|
||||
}
|
||||
|
||||
if (node.type !== "VariableDeclaration") {
|
||||
return null;
|
||||
if (node.type === "VariableDeclaration") {
|
||||
for (const declaration of node.declarations) {
|
||||
if (
|
||||
declaration.type !== "VariableDeclarator" ||
|
||||
!declaration.init ||
|
||||
declaration.init.type !== "ArrayExpression" ||
|
||||
declaration.init.elements.length !== 1
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
const [firstElement] = declaration.init.elements;
|
||||
if (firstElement && firstElement.type === "Identifier") {
|
||||
return makeSolverFuncFromName(firstElement.name);
|
||||
}
|
||||
}
|
||||
} else if (node.type === "ExpressionStatement") {
|
||||
const expr = node.expression;
|
||||
if (
|
||||
expr.type === "AssignmentExpression" &&
|
||||
expr.left.type === "Identifier" &&
|
||||
expr.operator === "=" &&
|
||||
expr.right.type === "ArrayExpression" &&
|
||||
expr.right.elements.length === 1
|
||||
) {
|
||||
const [firstElement] = expr.right.elements;
|
||||
if (firstElement && firstElement.type === "Identifier") {
|
||||
return makeSolverFuncFromName(firstElement.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
const declaration = node.declarations[0];
|
||||
if (
|
||||
declaration.type !== "VariableDeclarator" ||
|
||||
!declaration.init ||
|
||||
declaration.init.type !== "ArrayExpression" ||
|
||||
declaration.init.elements.length !== 1
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
const [firstElement] = declaration.init.elements;
|
||||
if (!firstElement || firstElement.type !== "Identifier") {
|
||||
return null;
|
||||
}
|
||||
return makeSolverFuncFromName(firstElement.name);
|
||||
return null;
|
||||
}
|
||||
|
||||
function makeSolverFuncFromName(name: string): ESTree.ArrowFunctionExpression {
|
||||
|
||||
@@ -62,7 +62,7 @@ const logicalExpression: DeepPartial<ESTree.ExpressionStatement> = {
|
||||
},
|
||||
};
|
||||
|
||||
const identifier = {
|
||||
const identifier: DeepPartial<ESTree.Node> = {
|
||||
or: [
|
||||
{
|
||||
type: "ExpressionStatement",
|
||||
@@ -102,9 +102,7 @@ const identifier = {
|
||||
export function extract(
|
||||
node: ESTree.Node,
|
||||
): ESTree.ArrowFunctionExpression | null {
|
||||
if (
|
||||
!matchesStructure(node, identifier as unknown as DeepPartial<ESTree.Node>)
|
||||
) {
|
||||
if (!matchesStructure(node, identifier)) {
|
||||
return null;
|
||||
}
|
||||
let block: ESTree.BlockStatement | undefined | null;
|
||||
|
||||
@@ -236,9 +236,7 @@ export const tests: {
|
||||
],
|
||||
},
|
||||
{
|
||||
// TODO: es6/tv_es6 variants currently fail
|
||||
player: "2b83d2e0",
|
||||
variants: ["main", "tcc", "tce", "es5", "tv", "phone", "tablet"],
|
||||
n: [
|
||||
// Synthetic test
|
||||
{ input: "0eRGgQWJGfT5rFHFj", expected: "euHbygrCMLksxd" },
|
||||
@@ -254,9 +252,7 @@ export const tests: {
|
||||
],
|
||||
},
|
||||
{
|
||||
// TODO: es6/tv_es6 variants currently fail
|
||||
player: "638ec5c6",
|
||||
variants: ["main", "tcc", "tce", "es5", "tv", "phone", "tablet"],
|
||||
n: [
|
||||
// Synthetic test
|
||||
{ input: "ZdZIqFPQK-Ty8wId", expected: "1qov8-KM-yH" },
|
||||
@@ -271,6 +267,22 @@ export const tests: {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
player: "87644c66",
|
||||
n: [
|
||||
// Synthetic test
|
||||
{ input: "ZdZIqFPQK-Ty8wId", expected: "iF5NxEm1BYk" },
|
||||
],
|
||||
sig: [
|
||||
// Synthetic test
|
||||
{
|
||||
input:
|
||||
"gN7a-hudCuAuPH6fByOk1_GNXN0yNMHShjZXS2VOgsEItAJz0tipeavEOmNdYN-wUtcEqD3bCXjc0iyKfAyZxCBGgIARwsSdQfJ2CJtt",
|
||||
expected:
|
||||
"atJC2JfQdSswRAtgGBCxZyAfKyi0cjXCb3DqEctUw-NYdNmOEvIepit0zJAtIEsgOV2SXZjhSHMNy0NXNG_1kOyBf6HPuAuCduh-a7Ng",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export const players = new Map([
|
||||
|
||||
@@ -7,11 +7,15 @@ def core() -> str:
|
||||
"""
|
||||
Read the contents of the JavaScript core solver bundle as string.
|
||||
"""
|
||||
return (importlib.resources.files(yt_dlp_ejs.yt.solver) / "core.min.js").read_text()
|
||||
return (importlib.resources.files(yt_dlp_ejs.yt.solver) / "core.min.js").read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
|
||||
|
||||
def lib() -> str:
|
||||
"""
|
||||
Read the contents of the JavaScript library solver bundle as string.
|
||||
"""
|
||||
return (importlib.resources.files(yt_dlp_ejs.yt.solver) / "lib.min.js").read_text()
|
||||
return (importlib.resources.files(yt_dlp_ejs.yt.solver) / "lib.min.js").read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user