mirror of
https://github.com/yt-dlp/ejs.git
synced 2026-06-25 15:51:57 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2655b1f55f | ||
|
|
877164a326 | ||
|
|
25b77b7310 | ||
|
|
57fe708cf4 |
14
.github/workflows/ci.yml
vendored
14
.github/workflows/ci.yml
vendored
@@ -1,6 +1,8 @@
|
|||||||
name: CI
|
name: CI
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
branches:
|
||||||
|
- '**'
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- 'README.md'
|
- 'README.md'
|
||||||
- 'LICENSE'
|
- 'LICENSE'
|
||||||
@@ -69,10 +71,11 @@ jobs:
|
|||||||
|
|
||||||
python_tests:
|
python_tests:
|
||||||
name: Python tests
|
name: Python tests
|
||||||
runs-on: ubuntu-latest
|
runs-on: ${{ matrix.runner }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
|
runner: [ubuntu-latest, windows-latest]
|
||||||
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14', pypy-3.11]
|
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14', pypy-3.11]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
@@ -91,7 +94,15 @@ jobs:
|
|||||||
# `pip install -e` omits the force-included JS, so use `build` instead
|
# `pip install -e` omits the force-included JS, so use `build` instead
|
||||||
python -m pip install -U build
|
python -m pip install -U build
|
||||||
python -m build
|
python -m build
|
||||||
|
- name: Unpack wheel (Linux)
|
||||||
|
if: matrix.runner == 'ubuntu-latest'
|
||||||
|
run: |
|
||||||
unzip -u dist/yt_dlp_ejs-*.whl "yt_dlp_ejs/*"
|
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
|
- name: Run Python tests
|
||||||
timeout-minutes: 5
|
timeout-minutes: 5
|
||||||
run: |
|
run: |
|
||||||
@@ -352,6 +363,7 @@ jobs:
|
|||||||
- ruff-lint
|
- ruff-lint
|
||||||
- prettier
|
- prettier
|
||||||
- eslint
|
- eslint
|
||||||
|
- python_tests
|
||||||
- deno_build
|
- deno_build
|
||||||
- deno_tests
|
- deno_tests
|
||||||
- bun_build
|
- bun_build
|
||||||
|
|||||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -37,7 +37,7 @@ jobs:
|
|||||||
compression-level: 0
|
compression-level: 0
|
||||||
- name: Build JavaScript artifacts
|
- name: Build JavaScript artifacts
|
||||||
run: |
|
run: |
|
||||||
deno install
|
deno install --frozen
|
||||||
deno task bundle
|
deno task bundle
|
||||||
- name: Upload JavaScript artifacts
|
- name: Upload JavaScript artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,7 +3,6 @@
|
|||||||
/yt_dlp_ejs/_version.py
|
/yt_dlp_ejs/_version.py
|
||||||
/node_modules
|
/node_modules
|
||||||
/bun.lock
|
/bun.lock
|
||||||
/deno.lock
|
|
||||||
/package-lock.json
|
/package-lock.json
|
||||||
/.idea
|
/.idea
|
||||||
/.venv
|
/.venv
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ pip install -U yt-dlp-ejs
|
|||||||
## Development
|
## Development
|
||||||
|
|
||||||
While this project does pin its dependencies,
|
While this project does pin its dependencies,
|
||||||
it does not use lockfiles or enforce a particular package manager.
|
it only provides a lockfile for building with `deno`.
|
||||||
You may install dependencies using any compatible package manager.
|
You may install dependencies using any compatible package manager.
|
||||||
If you notice differences between different runtimes' builds
|
If you notice differences between different runtimes' builds
|
||||||
please open an issue [here](<https://github.com/yt-dlp/ejs/issues/new>).
|
please open an issue [here](<https://github.com/yt-dlp/ejs/issues/new>).
|
||||||
@@ -27,7 +27,7 @@ Alternatively, to only build the JavaScript files you can run the `bundle` scrip
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Deno:
|
# Deno:
|
||||||
deno install
|
deno install --frozen
|
||||||
deno task bundle
|
deno task bundle
|
||||||
|
|
||||||
# Bun:
|
# Bun:
|
||||||
@@ -45,7 +45,7 @@ First, make sure the project's dependencies are installed and download the playe
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Deno:
|
# Deno:
|
||||||
deno install
|
deno install --frozen
|
||||||
deno run src/yt/solver/test/download.ts
|
deno run src/yt/solver/test/download.ts
|
||||||
|
|
||||||
# Bun:
|
# Bun:
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class CustomBuildHook(BuildHookInterface):
|
|||||||
if shutil.which("deno"):
|
if shutil.which("deno"):
|
||||||
print("Building with deno...", flush=True)
|
print("Building with deno...", flush=True)
|
||||||
os.environ["DENO_NO_UPDATE_CHECK"] = "1"
|
os.environ["DENO_NO_UPDATE_CHECK"] = "1"
|
||||||
subprocess.run(["deno", "install"], check=True)
|
subprocess.run(["deno", "install", "--frozen"], check=True)
|
||||||
subprocess.run(["deno", "task", "bundle"], check=True)
|
subprocess.run(["deno", "task", "bundle"], check=True)
|
||||||
|
|
||||||
elif shutil.which("bun"):
|
elif shutil.which("bun"):
|
||||||
|
|||||||
21
src/types.ts
21
src/types.ts
@@ -1,7 +1,16 @@
|
|||||||
export type DeepPartial<T> = T extends object
|
type DP<T> = T extends (infer U)[]
|
||||||
? Or<{
|
? DeepPartial<U>[]
|
||||||
[P in keyof T]?: DeepPartial<T[P]>;
|
: T extends object
|
||||||
}>
|
? { [P in keyof T]?: DeepPartial<T[P]> }
|
||||||
: Or<T>;
|
: 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 { matchesStructure } from "../../utils.ts";
|
||||||
import { type DeepPartial } from "../../types.ts";
|
import { type DeepPartial } from "../../types.ts";
|
||||||
|
|
||||||
const identifier: DeepPartial<ESTree.VariableDeclaration> = {
|
const identifier: DeepPartial<ESTree.Node> = {
|
||||||
type: "VariableDeclaration",
|
or: [
|
||||||
kind: "var",
|
|
||||||
declarations: [
|
|
||||||
{
|
{
|
||||||
type: "VariableDeclarator",
|
type: "VariableDeclaration",
|
||||||
id: {
|
kind: "var",
|
||||||
type: "Identifier",
|
declarations: {
|
||||||
},
|
anykey: [
|
||||||
init: {
|
|
||||||
type: "ArrayExpression",
|
|
||||||
elements: [
|
|
||||||
{
|
{
|
||||||
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 = [
|
const catchBlockBody = [
|
||||||
{
|
{
|
||||||
@@ -92,23 +116,37 @@ export function extract(
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.type !== "VariableDeclaration") {
|
if (node.type === "VariableDeclaration") {
|
||||||
return null;
|
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];
|
return null;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeSolverFuncFromName(name: string): ESTree.ArrowFunctionExpression {
|
function makeSolverFuncFromName(name: string): ESTree.ArrowFunctionExpression {
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ const logicalExpression: DeepPartial<ESTree.ExpressionStatement> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const identifier = {
|
const identifier: DeepPartial<ESTree.Node> = {
|
||||||
or: [
|
or: [
|
||||||
{
|
{
|
||||||
type: "ExpressionStatement",
|
type: "ExpressionStatement",
|
||||||
@@ -102,9 +102,7 @@ const identifier = {
|
|||||||
export function extract(
|
export function extract(
|
||||||
node: ESTree.Node,
|
node: ESTree.Node,
|
||||||
): ESTree.ArrowFunctionExpression | null {
|
): ESTree.ArrowFunctionExpression | null {
|
||||||
if (
|
if (!matchesStructure(node, identifier)) {
|
||||||
!matchesStructure(node, identifier as unknown as DeepPartial<ESTree.Node>)
|
|
||||||
) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
let block: ESTree.BlockStatement | undefined | null;
|
let block: ESTree.BlockStatement | undefined | null;
|
||||||
|
|||||||
@@ -236,9 +236,7 @@ export const tests: {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// TODO: es6/tv_es6 variants currently fail
|
|
||||||
player: "2b83d2e0",
|
player: "2b83d2e0",
|
||||||
variants: ["main", "tcc", "tce", "es5", "tv", "phone", "tablet"],
|
|
||||||
n: [
|
n: [
|
||||||
// Synthetic test
|
// Synthetic test
|
||||||
{ input: "0eRGgQWJGfT5rFHFj", expected: "euHbygrCMLksxd" },
|
{ input: "0eRGgQWJGfT5rFHFj", expected: "euHbygrCMLksxd" },
|
||||||
@@ -254,9 +252,7 @@ export const tests: {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// TODO: es6/tv_es6 variants currently fail
|
|
||||||
player: "638ec5c6",
|
player: "638ec5c6",
|
||||||
variants: ["main", "tcc", "tce", "es5", "tv", "phone", "tablet"],
|
|
||||||
n: [
|
n: [
|
||||||
// Synthetic test
|
// Synthetic test
|
||||||
{ input: "ZdZIqFPQK-Ty8wId", expected: "1qov8-KM-yH" },
|
{ 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([
|
export const players = new Map([
|
||||||
|
|||||||
@@ -7,11 +7,15 @@ def core() -> str:
|
|||||||
"""
|
"""
|
||||||
Read the contents of the JavaScript core solver bundle as string.
|
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:
|
def lib() -> str:
|
||||||
"""
|
"""
|
||||||
Read the contents of the JavaScript library solver bundle as string.
|
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