3 Commits
0.2.1 ... 0.3.1

Author SHA1 Message Date
bashonly
4b4ac2b896 Include test data directory in sdist (#27) 2025-11-06 22:09:05 +00:00
sepro
2655b1f55f Fix es6 and tv_es6 n func extraction (#26) 2025-10-28 21:54:48 +01:00
Simon Sawicki
877164a326 Add build time lockfile for deno (#25) 2025-10-28 00:41:18 +01:00
10 changed files with 1368 additions and 49 deletions

View File

@@ -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
View File

@@ -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

View File

@@ -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:

1262
deno.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -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"):

View File

@@ -47,6 +47,7 @@ source = "vcs"
exclude = [ exclude = [
"/.github/**", "/.github/**",
"/src/yt/solver/test/players/*", "/src/yt/solver/test/players/*",
"!/src/yt/solver/test/players/.gitignore",
] ]
[tool.hatch.build.targets.wheel] [tool.hatch.build.targets.wheel]

View File

@@ -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>>[] };

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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([