update deps, migrate to pnpm
This commit is contained in:
parent
f8a5120064
commit
21f1fd3cee
File diff suppressed because it is too large
Load Diff
|
@ -7,7 +7,8 @@
|
||||||
"build": "nuxi build",
|
"build": "nuxi build",
|
||||||
"generate": "nuxi generate",
|
"generate": "nuxi generate",
|
||||||
"preview": "nuxi preview",
|
"preview": "nuxi preview",
|
||||||
"lint": "eslint ."
|
"lint": "eslint .",
|
||||||
|
"preinstall": "npx -y only-allow pnpm"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nuxt-themes/docus": "^1.13.1",
|
"@nuxt-themes/docus": "^1.13.1",
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,72 @@
|
||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"browser": true
|
||||||
|
},
|
||||||
|
"extends": ["airbnb-base", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"],
|
||||||
|
"ignorePatterns": ["lib/*", "tests/*", "/*.js", "/*.ts", "/src/__test__/*", "/**/*.test.ts", "test/*"],
|
||||||
|
"parser": "@typescript-eslint/parser",
|
||||||
|
"parserOptions": {
|
||||||
|
"project": "./tsconfig.json",
|
||||||
|
"tsconfigRootDir": "./"
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"import/resolver": {
|
||||||
|
"typescript": {
|
||||||
|
"project": "./tsconfig.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"plugins": ["@typescript-eslint", "import", "prettier"],
|
||||||
|
"rules": {
|
||||||
|
"no-plusplus": "off",
|
||||||
|
"class-methods-use-this": "off",
|
||||||
|
"no-bitwise": "off",
|
||||||
|
"no-underscore-dangle": "off",
|
||||||
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
|
"no-console": ["error", { "allow": ["warn", "error"] }],
|
||||||
|
"@typescript-eslint/no-this-alias": "off",
|
||||||
|
"import/prefer-default-export": "off",
|
||||||
|
"@typescript-eslint/no-empty-function": "off",
|
||||||
|
"no-shadow": "off",
|
||||||
|
"@typescript-eslint/no-shadow": ["error"],
|
||||||
|
"no-restricted-syntax": "off",
|
||||||
|
"import/no-unresolved": ["error", { "ignore": ["^virtual:"] }],
|
||||||
|
"consistent-return": "off",
|
||||||
|
"no-continue": "off",
|
||||||
|
"no-eval": "off",
|
||||||
|
"no-await-in-loop": "off",
|
||||||
|
"no-nested-ternary": "off",
|
||||||
|
"no-param-reassign": ["error", { "props": false }],
|
||||||
|
"prefer-destructuring": "off",
|
||||||
|
"@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }],
|
||||||
|
"import/extensions": [
|
||||||
|
"error",
|
||||||
|
"ignorePackages",
|
||||||
|
{
|
||||||
|
"ts": "never",
|
||||||
|
"tsx": "never"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"import/order": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"groups": ["builtin", "external", "internal", ["sibling", "parent"], "index", "unknown"],
|
||||||
|
"newlines-between": "always",
|
||||||
|
"alphabetize": {
|
||||||
|
"order": "asc",
|
||||||
|
"caseInsensitive": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sort-imports": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"ignoreCase": false,
|
||||||
|
"ignoreDeclarationSort": true,
|
||||||
|
"ignoreMemberSort": false,
|
||||||
|
"memberSyntaxSortOrder": ["none", "all", "multiple", "single"],
|
||||||
|
"allowSeparatedGroups": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
72
.eslintrc.js
72
.eslintrc.js
|
@ -1,72 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
env: {
|
|
||||||
browser: true,
|
|
||||||
},
|
|
||||||
extends: ['airbnb-base', 'plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'],
|
|
||||||
ignorePatterns: ['lib/*', 'tests/*', '/*.js', '/*.ts', '/src/__test__/*', '/**/*.test.ts', 'test/*'],
|
|
||||||
parser: '@typescript-eslint/parser',
|
|
||||||
parserOptions: {
|
|
||||||
project: './tsconfig.json',
|
|
||||||
tsconfigRootDir: './',
|
|
||||||
},
|
|
||||||
settings: {
|
|
||||||
'import/resolver': {
|
|
||||||
typescript: {
|
|
||||||
project: './tsconfig.json',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
plugins: ['@typescript-eslint', 'import', 'prettier'],
|
|
||||||
rules: {
|
|
||||||
'no-plusplus': 'off',
|
|
||||||
'class-methods-use-this': 'off',
|
|
||||||
'no-bitwise': 'off',
|
|
||||||
'no-underscore-dangle': 'off',
|
|
||||||
'@typescript-eslint/no-explicit-any': 'off',
|
|
||||||
'no-console': ['error', { allow: ['warn', 'error'] }],
|
|
||||||
'@typescript-eslint/no-this-alias': 'off',
|
|
||||||
'import/prefer-default-export': 'off',
|
|
||||||
'@typescript-eslint/no-empty-function': 'off',
|
|
||||||
'no-shadow': 'off',
|
|
||||||
'@typescript-eslint/no-shadow': ['error'],
|
|
||||||
'no-restricted-syntax': 'off',
|
|
||||||
'import/no-unresolved': ['error', { ignore: ['^virtual:'] }],
|
|
||||||
'consistent-return': 'off',
|
|
||||||
'no-continue': 'off',
|
|
||||||
'no-eval': 'off',
|
|
||||||
'no-await-in-loop': 'off',
|
|
||||||
'no-nested-ternary': 'off',
|
|
||||||
'no-param-reassign': ['error', { props: false }],
|
|
||||||
'prefer-destructuring': 'off',
|
|
||||||
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
|
|
||||||
'import/extensions': [
|
|
||||||
'error',
|
|
||||||
'ignorePackages',
|
|
||||||
{
|
|
||||||
ts: 'never',
|
|
||||||
tsx: 'never',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'import/order': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
groups: ['builtin', 'external', 'internal', ['sibling', 'parent'], 'index', 'unknown'],
|
|
||||||
'newlines-between': 'always',
|
|
||||||
alphabetize: {
|
|
||||||
order: 'asc',
|
|
||||||
caseInsensitive: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'sort-imports': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
ignoreCase: false,
|
|
||||||
ignoreDeclarationSort: true,
|
|
||||||
ignoreMemberSort: false,
|
|
||||||
memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'],
|
|
||||||
allowSeparatedGroups: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -14,18 +14,23 @@ jobs:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Install Node.js
|
- uses: pnpm/action-setup@v2
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
version: 8
|
||||||
|
|
||||||
|
- name: Install Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
cache: "pnpm"
|
||||||
|
|
||||||
- name: Install packages
|
- name: Install packages
|
||||||
working-directory: ./.docs
|
working-directory: ./.docs
|
||||||
run: npm install
|
run: pnpm install
|
||||||
|
|
||||||
- name: Build project
|
- name: Build project
|
||||||
working-directory: ./.docs
|
working-directory: ./.docs
|
||||||
run: npm run generate
|
run: pnpm run generate
|
||||||
env:
|
env:
|
||||||
NUXT_APP_BASE_URL: /providers/
|
NUXT_APP_BASE_URL: /providers/
|
||||||
|
|
||||||
|
|
|
@ -14,16 +14,21 @@ jobs:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Install Node.js
|
- uses: pnpm/action-setup@v2
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
version: 8
|
||||||
registry-url: 'https://registry.npmjs.org'
|
|
||||||
|
- name: Install Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
cache: "pnpm"
|
||||||
|
registry-url: "https://registry.npmjs.org"
|
||||||
|
|
||||||
- name: Install packages
|
- name: Install packages
|
||||||
run: npm ci
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
- name: Publish
|
- name: Publish
|
||||||
run: npm publish --access public
|
run: pnpm publish --access public
|
||||||
env:
|
env:
|
||||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||||
|
|
|
@ -16,19 +16,24 @@ jobs:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Install Node.js
|
- uses: pnpm/action-setup@v2
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
version: 8
|
||||||
|
|
||||||
|
- name: Install Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
cache: "pnpm"
|
||||||
|
|
||||||
- name: Install packages
|
- name: Install packages
|
||||||
run: npm install
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: npm run test
|
run: pnpm run test
|
||||||
|
|
||||||
- name: Run integration tests
|
- name: Run integration tests
|
||||||
run: npm run build && npm run test:integration
|
run: pnpm run build && pnpm run test:integration
|
||||||
|
|
||||||
- name: Run linting
|
- name: Run linting
|
||||||
run: npm run lint
|
run: pnpm run lint
|
||||||
|
|
|
@ -2,3 +2,5 @@ node_modules/
|
||||||
/lib
|
/lib
|
||||||
coverage
|
coverage
|
||||||
.env
|
.env
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
70
package.json
70
package.json
|
@ -2,6 +2,7 @@
|
||||||
"name": "@movie-web/providers",
|
"name": "@movie-web/providers",
|
||||||
"version": "2.2.5",
|
"version": "2.2.5",
|
||||||
"description": "Package that contains all the providers of movie-web",
|
"description": "Package that contains all the providers of movie-web",
|
||||||
|
"type": "module",
|
||||||
"main": "./lib/index.umd.js",
|
"main": "./lib/index.umd.js",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"files": [
|
"files": [
|
||||||
|
@ -10,12 +11,12 @@
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
"import": {
|
"import": {
|
||||||
"types": "./lib/index.d.mts",
|
"types": "./lib/index.d.ts",
|
||||||
"default": "./lib/index.mjs"
|
"default": "./lib/index.js"
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"default": "./lib/index.umd.js"
|
"default": "./lib/index.umd.cjs"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -35,7 +36,7 @@
|
||||||
"homepage": "https://movie-web.github.io/providers/",
|
"homepage": "https://movie-web.github.io/providers/",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "vite build && tsc --noEmit",
|
"build": "vite build && tsc --noEmit",
|
||||||
"cli": "ts-node ./src/dev-cli/index.ts",
|
"cli": "vite-node ./src/dev-cli/index.ts",
|
||||||
"test": "vitest run",
|
"test": "vitest run",
|
||||||
"test:watch": "vitest",
|
"test:watch": "vitest",
|
||||||
"test:providers": "cross-env MW_TEST_PROVIDERS=true vitest run --reporter verbose",
|
"test:providers": "cross-env MW_TEST_PROVIDERS=true vitest run --reporter verbose",
|
||||||
|
@ -44,50 +45,51 @@
|
||||||
"lint": "eslint --ext .ts,.js src/",
|
"lint": "eslint --ext .ts,.js src/",
|
||||||
"lint:fix": "eslint --fix --ext .ts,.js src/",
|
"lint:fix": "eslint --fix --ext .ts,.js src/",
|
||||||
"lint:report": "eslint --ext .ts,.js --output-file eslint_report.json --format json src/",
|
"lint:report": "eslint --ext .ts,.js --output-file eslint_report.json --format json src/",
|
||||||
"prepare": "npm run build",
|
"preinstall": "npx -y only-allow pnpm",
|
||||||
"prepublishOnly": "npm test && npm run lint"
|
"prepare": "pnpm run build",
|
||||||
|
"prepublishOnly": "pnpm test && pnpm run lint"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@nabla/vite-plugin-eslint": "^2.0.2",
|
||||||
"@types/cookie": "^0.6.0",
|
"@types/cookie": "^0.6.0",
|
||||||
"@types/crypto-js": "^4.1.1",
|
"@types/crypto-js": "^4.2.2",
|
||||||
"@types/node-fetch": "^2.6.6",
|
"@types/node-fetch": "^2.6.11",
|
||||||
"@types/randombytes": "^2.0.1",
|
"@types/randombytes": "^2.0.3",
|
||||||
"@types/set-cookie-parser": "^2.4.7",
|
"@types/set-cookie-parser": "^2.4.7",
|
||||||
"@types/spinnies": "^0.5.1",
|
"@types/spinnies": "^0.5.3",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.60.0",
|
"@typescript-eslint/eslint-plugin": "^7.4.0",
|
||||||
"@typescript-eslint/parser": "^5.60.0",
|
"@typescript-eslint/parser": "^7.4.0",
|
||||||
"@vitest/coverage-v8": "^0.34.3",
|
"@vitest/coverage-v8": "^1.4.0",
|
||||||
"commander": "^11.0.0",
|
"commander": "^12.0.0",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"dotenv": "^16.3.1",
|
"dotenv": "^16.4.5",
|
||||||
"enquirer": "^2.4.1",
|
"enquirer": "^2.4.1",
|
||||||
"eslint": "^8.30.0",
|
"eslint": "^8.57.0",
|
||||||
"eslint-config-airbnb-base": "^15.0.0",
|
"eslint-config-airbnb-base": "^15.0.0",
|
||||||
"eslint-config-prettier": "^8.5.0",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
"eslint-import-resolver-typescript": "^3.5.5",
|
"eslint-import-resolver-typescript": "^3.6.1",
|
||||||
"eslint-plugin-import": "^2.27.5",
|
"eslint-plugin-import": "^2.29.1",
|
||||||
"eslint-plugin-prettier": "^4.2.1",
|
"eslint-plugin-prettier": "^5.1.3",
|
||||||
"node-fetch": "^2.7.0",
|
"node-fetch": "^3.3.2",
|
||||||
"prettier": "^2.6.2",
|
"prettier": "^3.2.5",
|
||||||
"puppeteer": "^21.6.1",
|
"puppeteer": "^22.6.1",
|
||||||
"spinnies": "^0.5.1",
|
"spinnies": "^0.5.1",
|
||||||
"ts-node": "^10.9.1",
|
"tsc-alias": "^1.8.8",
|
||||||
"tsc-alias": "^1.6.7",
|
|
||||||
"tsconfig-paths": "^4.2.0",
|
"tsconfig-paths": "^4.2.0",
|
||||||
"typescript": "^4.6.3",
|
"typescript": "^5.4.3",
|
||||||
"vite": "^4.0.0",
|
"vite": "^5.2.7",
|
||||||
"vite-plugin-dts": "^3.5.3",
|
"vite-node": "^1.4.0",
|
||||||
"vite-plugin-eslint": "^1.8.1",
|
"vite-plugin-dts": "^3.8.1",
|
||||||
"vitest": "^0.32.2"
|
"vitest": "^1.4.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cheerio": "^1.0.0-rc.12",
|
"cheerio": "^1.0.0-rc.12",
|
||||||
"cookie": "^0.6.0",
|
"cookie": "^0.6.0",
|
||||||
"crypto-js": "^4.1.1",
|
"crypto-js": "^4.2.0",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
"iso-639-1": "^3.1.0",
|
"iso-639-1": "^3.1.2",
|
||||||
"nanoid": "^3.3.6",
|
"nanoid": "^3.3.7",
|
||||||
"node-fetch": "^2.7.0",
|
"node-fetch": "^3.3.2",
|
||||||
"set-cookie-parser": "^2.6.0",
|
"set-cookie-parser": "^2.6.0",
|
||||||
"unpacker": "^1.0.1"
|
"unpacker": "^1.0.1"
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,12 +1,12 @@
|
||||||
import { buildProviders } from "@/entrypoint/builder";
|
import { buildProviders } from '@/entrypoint/builder';
|
||||||
import { ScrapeMedia } from "@/entrypoint/utils/media";
|
import { ScrapeMedia } from '@/entrypoint/utils/media';
|
||||||
import { targets } from "@/entrypoint/utils/targets";
|
import { targets } from '@/entrypoint/utils/targets';
|
||||||
import { makeStandardFetcher } from "@/fetchers/standardFetch";
|
import { makeStandardFetcher } from '@/fetchers/standardFetch';
|
||||||
import { Embed, Sourcerer, SourcererEmbed } from "@/providers/base";
|
import { Embed, Sourcerer, SourcererEmbed } from '@/providers/base';
|
||||||
import { TestTypes } from "./providerUtils";
|
import { TestTypes } from './providerUtils';
|
||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from 'vitest';
|
||||||
import { ProviderControls } from "@/entrypoint/controls";
|
import { ProviderControls } from '@/entrypoint/controls';
|
||||||
import { makeSimpleProxyFetcher } from "@/fetchers/simpleProxy";
|
import { makeSimpleProxyFetcher } from '@/fetchers/simpleProxy';
|
||||||
|
|
||||||
export interface TestEmbedOptions {
|
export interface TestEmbedOptions {
|
||||||
embed: Embed;
|
embed: Embed;
|
||||||
|
@ -18,18 +18,16 @@ export interface TestEmbedOptions {
|
||||||
embeds: number;
|
embeds: number;
|
||||||
streams?: number;
|
streams?: number;
|
||||||
error?: boolean;
|
error?: boolean;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeBaseEmbedProviders() {
|
function makeBaseEmbedProviders() {
|
||||||
const builder = buildProviders()
|
const builder = buildProviders().setTarget(targets.ANY).setFetcher(makeStandardFetcher(fetch));
|
||||||
.setTarget(targets.ANY)
|
|
||||||
.setFetcher(makeStandardFetcher(fetch));
|
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function testEmbed(ops: TestEmbedOptions) {
|
export function testEmbed(ops: TestEmbedOptions) {
|
||||||
if (ops.testSuite.length === 0) throw new Error("Test suite must have at least one test");
|
if (ops.testSuite.length === 0) throw new Error('Test suite must have at least one test');
|
||||||
describe(`embed:${ops.source.id}:${ops.embed.id}`, () => {
|
describe(`embed:${ops.source.id}:${ops.embed.id}`, () => {
|
||||||
ops.testSuite.forEach((test) => {
|
ops.testSuite.forEach((test) => {
|
||||||
describe(`test ${test.title}`, async () => {
|
describe(`test ${test.title}`, async () => {
|
||||||
|
@ -37,8 +35,11 @@ export function testEmbed(ops: TestEmbedOptions) {
|
||||||
const results = await providers.runSourceScraper({
|
const results = await providers.runSourceScraper({
|
||||||
id: ops.source.id,
|
id: ops.source.id,
|
||||||
media: test,
|
media: test,
|
||||||
})
|
});
|
||||||
if (results.embeds.length !== ops.expect.embeds) throw new Error(`Embeds don't match expected amount of embeds (${ops.source.id}, ${ops.embed.id}, got ${results.embeds.length} but expected ${ops.expect.embeds})`);
|
if (results.embeds.length !== ops.expect.embeds)
|
||||||
|
throw new Error(
|
||||||
|
`Embeds don't match expected amount of embeds (${ops.source.id}, ${ops.embed.id}, got ${results.embeds.length} but expected ${ops.expect.embeds})`,
|
||||||
|
);
|
||||||
return results.embeds;
|
return results.embeds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +50,7 @@ export function testEmbed(ops: TestEmbedOptions) {
|
||||||
const result = await providers.runEmbedScraper({
|
const result = await providers.runEmbedScraper({
|
||||||
id: ops.embed.id,
|
id: ops.embed.id,
|
||||||
url: embedUrl,
|
url: embedUrl,
|
||||||
})
|
});
|
||||||
if (ops.debug) console.log(result);
|
if (ops.debug) console.log(result);
|
||||||
streamCount = (result.stream ?? []).length;
|
streamCount = (result.stream ?? []).length;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -62,12 +63,11 @@ export function testEmbed(ops: TestEmbedOptions) {
|
||||||
|
|
||||||
for (const t of ops.types) {
|
for (const t of ops.types) {
|
||||||
const builder = makeBaseEmbedProviders().addSource(ops.source).addEmbed(ops.embed);
|
const builder = makeBaseEmbedProviders().addSource(ops.source).addEmbed(ops.embed);
|
||||||
if (t === 'standard') {}
|
if (t === 'standard') {
|
||||||
else if (t === 'ip:standard')
|
} else if (t === 'ip:standard') builder.enableConsistentIpForRequests();
|
||||||
builder.enableConsistentIpForRequests();
|
|
||||||
else if (t === 'proxied') {
|
else if (t === 'proxied') {
|
||||||
if (!process.env.MOVIE_WEB_PROXY_URL)
|
if (!process.env.MOVIE_WEB_PROXY_URL)
|
||||||
throw new Error("Cant use proxied test without setting MOVIE_WEB_PROXY_URL env");
|
throw new Error('Cant use proxied test without setting MOVIE_WEB_PROXY_URL env');
|
||||||
builder.setProxiedFetcher(makeSimpleProxyFetcher(process.env.MOVIE_WEB_PROXY_URL, fetch));
|
builder.setProxiedFetcher(makeSimpleProxyFetcher(process.env.MOVIE_WEB_PROXY_URL, fetch));
|
||||||
}
|
}
|
||||||
const providers = builder.build();
|
const providers = builder.build();
|
||||||
|
@ -76,15 +76,15 @@ export function testEmbed(ops: TestEmbedOptions) {
|
||||||
embeds.forEach((embed, i) => {
|
embeds.forEach((embed, i) => {
|
||||||
it(`${t} - embed ${i}`, async () => {
|
it(`${t} - embed ${i}`, async () => {
|
||||||
await runTest(providers, embed.url);
|
await runTest(providers, embed.url);
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
it(`${t} - embed ??`, () => {
|
it(`${t} - embed ??`, () => {
|
||||||
throw new Error("Failed to get streams: " + err);
|
throw new Error('Failed to get streams: ' + err);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import dotenv from 'dotenv';
|
import dotenv from 'dotenv';
|
||||||
import { febboxMp4Scraper } from "@/providers/embeds/febbox/mp4";
|
import { febboxMp4Scraper } from '@/providers/embeds/febbox/mp4';
|
||||||
import { testEmbed } from "./embedUtils";
|
import { testEmbed } from './embedUtils';
|
||||||
import { showboxScraper } from "@/providers/sources/showbox";
|
import { showboxScraper } from '@/providers/sources/showbox';
|
||||||
import { testMedia } from "./testMedia";
|
import { testMedia } from './testMedia';
|
||||||
import { flixhqScraper } from "@/providers/sources/flixhq";
|
import { flixhqScraper } from '@/providers/sources/flixhq';
|
||||||
import { upcloudScraper } from "@/providers/embeds/upcloud";
|
import { upcloudScraper } from '@/providers/embeds/upcloud';
|
||||||
import { goMoviesScraper } from "@/providers/sources/gomovies";
|
import { goMoviesScraper } from '@/providers/sources/gomovies';
|
||||||
import { smashyStreamScraper } from "@/providers/sources/smashystream";
|
import { smashyStreamScraper } from '@/providers/sources/smashystream';
|
||||||
import { smashyStreamDScraper } from "@/providers/embeds/smashystream/dued";
|
import { smashyStreamDScraper } from '@/providers/embeds/smashystream/dued';
|
||||||
import { vidsrcembedScraper } from '@/providers/embeds/vidsrc';
|
import { vidsrcembedScraper } from '@/providers/embeds/vidsrc';
|
||||||
import { vidsrcScraper } from '@/providers/sources/vidsrc';
|
import { vidsrcScraper } from '@/providers/sources/vidsrc';
|
||||||
import { vidSrcToScraper } from '@/providers/sources/vidsrcto';
|
import { vidSrcToScraper } from '@/providers/sources/vidsrcto';
|
||||||
|
@ -26,8 +26,8 @@ testEmbed({
|
||||||
expect: {
|
expect: {
|
||||||
embeds: 1,
|
embeds: 1,
|
||||||
streams: 1,
|
streams: 1,
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
testEmbed({
|
testEmbed({
|
||||||
embed: upcloudScraper,
|
embed: upcloudScraper,
|
||||||
|
@ -37,8 +37,8 @@ testEmbed({
|
||||||
expect: {
|
expect: {
|
||||||
embeds: 1,
|
embeds: 1,
|
||||||
streams: 1,
|
streams: 1,
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
testEmbed({
|
testEmbed({
|
||||||
embed: upcloudScraper,
|
embed: upcloudScraper,
|
||||||
|
@ -48,8 +48,8 @@ testEmbed({
|
||||||
expect: {
|
expect: {
|
||||||
embeds: 1,
|
embeds: 1,
|
||||||
streams: 1,
|
streams: 1,
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
testEmbed({
|
testEmbed({
|
||||||
embed: smashyStreamDScraper,
|
embed: smashyStreamDScraper,
|
||||||
|
@ -59,8 +59,8 @@ testEmbed({
|
||||||
expect: {
|
expect: {
|
||||||
embeds: 1,
|
embeds: 1,
|
||||||
streams: 1,
|
streams: 1,
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
testEmbed({
|
testEmbed({
|
||||||
embed: vidsrcembedScraper,
|
embed: vidsrcembedScraper,
|
||||||
|
@ -70,8 +70,8 @@ testEmbed({
|
||||||
expect: {
|
expect: {
|
||||||
embeds: 1,
|
embeds: 1,
|
||||||
streams: 1,
|
streams: 1,
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
testEmbed({
|
testEmbed({
|
||||||
embed: vidplayScraper,
|
embed: vidplayScraper,
|
||||||
|
@ -81,8 +81,8 @@ testEmbed({
|
||||||
expect: {
|
expect: {
|
||||||
embeds: 1,
|
embeds: 1,
|
||||||
streams: 1,
|
streams: 1,
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
testEmbed({
|
testEmbed({
|
||||||
embed: fileMoonScraper,
|
embed: fileMoonScraper,
|
||||||
|
@ -92,8 +92,8 @@ testEmbed({
|
||||||
expect: {
|
expect: {
|
||||||
embeds: 1,
|
embeds: 1,
|
||||||
streams: 1,
|
streams: 1,
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
testEmbed({
|
testEmbed({
|
||||||
embed: upcloudScraper,
|
embed: upcloudScraper,
|
||||||
|
@ -103,8 +103,8 @@ testEmbed({
|
||||||
expect: {
|
expect: {
|
||||||
embeds: 2,
|
embeds: 2,
|
||||||
streams: 1,
|
streams: 1,
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
testEmbed({
|
testEmbed({
|
||||||
embed: mixdropScraper,
|
embed: mixdropScraper,
|
||||||
|
@ -114,5 +114,5 @@ testEmbed({
|
||||||
expect: {
|
expect: {
|
||||||
embeds: 2,
|
embeds: 2,
|
||||||
streams: 1,
|
streams: 1,
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import { ScrapeMedia } from "@/entrypoint/utils/media";
|
import { ScrapeMedia } from '@/entrypoint/utils/media';
|
||||||
import { Embed, Sourcerer, SourcererEmbed } from "@/providers/base";
|
import { Embed, Sourcerer, SourcererEmbed } from '@/providers/base';
|
||||||
import { buildProviders } from "@/entrypoint/builder";
|
import { buildProviders } from '@/entrypoint/builder';
|
||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from 'vitest';
|
||||||
import { makeStandardFetcher } from "@/fetchers/standardFetch";
|
import { makeStandardFetcher } from '@/fetchers/standardFetch';
|
||||||
import { ProviderControls } from "@/entrypoint/controls";
|
import { ProviderControls } from '@/entrypoint/controls';
|
||||||
import { NotFoundError } from "@/utils/errors";
|
import { NotFoundError } from '@/utils/errors';
|
||||||
import { targets } from "@/entrypoint/utils/targets";
|
import { targets } from '@/entrypoint/utils/targets';
|
||||||
import { getBuiltinEmbeds } from "@/entrypoint/providers";
|
import { getBuiltinEmbeds } from '@/entrypoint/providers';
|
||||||
import { makeSimpleProxyFetcher } from "@/fetchers/simpleProxy";
|
import { makeSimpleProxyFetcher } from '@/fetchers/simpleProxy';
|
||||||
|
|
||||||
export type TestTypes = 'standard' | 'ip:standard' | 'proxied';
|
export type TestTypes = 'standard' | 'ip:standard' | 'proxied';
|
||||||
|
|
||||||
|
@ -21,20 +21,18 @@ export interface TestSourceOptions {
|
||||||
streams?: number;
|
streams?: number;
|
||||||
error?: boolean;
|
error?: boolean;
|
||||||
notfound?: boolean;
|
notfound?: boolean;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeBaseProviders() {
|
function makeBaseProviders() {
|
||||||
const builder = buildProviders()
|
const builder = buildProviders().setTarget(targets.ANY).setFetcher(makeStandardFetcher(fetch));
|
||||||
.setTarget(targets.ANY)
|
|
||||||
.setFetcher(makeStandardFetcher(fetch));
|
|
||||||
const embeds = getBuiltinEmbeds();
|
const embeds = getBuiltinEmbeds();
|
||||||
embeds.forEach(embed => builder.addEmbed(embed));
|
embeds.forEach((embed) => builder.addEmbed(embed));
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function testSource(ops: TestSourceOptions) {
|
export function testSource(ops: TestSourceOptions) {
|
||||||
if (ops.testSuite.length === 0) throw new Error("Test suite must have at least one test");
|
if (ops.testSuite.length === 0) throw new Error('Test suite must have at least one test');
|
||||||
describe(`source:${ops.source.id}`, () => {
|
describe(`source:${ops.source.id}`, () => {
|
||||||
ops.testSuite.forEach((test) => {
|
ops.testSuite.forEach((test) => {
|
||||||
describe(`test ${test.title}`, () => {
|
describe(`test ${test.title}`, () => {
|
||||||
|
@ -48,16 +46,14 @@ export function testSource(ops: TestSourceOptions) {
|
||||||
const result = await providers.runSourceScraper({
|
const result = await providers.runSourceScraper({
|
||||||
id: ops.source.id,
|
id: ops.source.id,
|
||||||
media: test,
|
media: test,
|
||||||
})
|
});
|
||||||
if (ops.debug) console.log(result);
|
if (ops.debug) console.log(result);
|
||||||
streamCount = (result.stream ?? []).length;
|
streamCount = (result.stream ?? []).length;
|
||||||
embedCount = result.embeds.length;
|
embedCount = result.embeds.length;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (ops.debug) console.log(err);
|
if (ops.debug) console.log(err);
|
||||||
if (err instanceof NotFoundError)
|
if (err instanceof NotFoundError) hasNotFound = true;
|
||||||
hasNotFound = true;
|
else hasError = true;
|
||||||
else
|
|
||||||
hasError = true;
|
|
||||||
}
|
}
|
||||||
expect(ops.expect.error ?? false).toBe(hasError);
|
expect(ops.expect.error ?? false).toBe(hasError);
|
||||||
expect(ops.expect.notfound ?? false).toBe(hasNotFound);
|
expect(ops.expect.notfound ?? false).toBe(hasNotFound);
|
||||||
|
@ -67,36 +63,30 @@ export function testSource(ops: TestSourceOptions) {
|
||||||
|
|
||||||
if (ops.types.includes('standard')) {
|
if (ops.types.includes('standard')) {
|
||||||
it(`standard`, async () => {
|
it(`standard`, async () => {
|
||||||
const providers = makeBaseProviders()
|
const providers = makeBaseProviders().addSource(ops.source).build();
|
||||||
.addSource(ops.source)
|
|
||||||
.build();
|
|
||||||
await runTest(providers);
|
await runTest(providers);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ops.types.includes('ip:standard')) {
|
if (ops.types.includes('ip:standard')) {
|
||||||
it(`standard:ip`, async () => {
|
it(`standard:ip`, async () => {
|
||||||
const providers = makeBaseProviders()
|
const providers = makeBaseProviders().addSource(ops.source).enableConsistentIpForRequests().build();
|
||||||
.addSource(ops.source)
|
|
||||||
.enableConsistentIpForRequests()
|
|
||||||
.build();
|
|
||||||
await runTest(providers);
|
await runTest(providers);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ops.types.includes('proxied')) {
|
if (ops.types.includes('proxied')) {
|
||||||
it(`proxied`, async () => {
|
it(`proxied`, async () => {
|
||||||
if (!process.env.MOVIE_WEB_PROXY_URL)
|
if (!process.env.MOVIE_WEB_PROXY_URL)
|
||||||
throw new Error("Cant use proxied test without setting MOVIE_WEB_PROXY_URL env");
|
throw new Error('Cant use proxied test without setting MOVIE_WEB_PROXY_URL env');
|
||||||
const providers = makeBaseProviders()
|
const providers = makeBaseProviders()
|
||||||
.addSource(ops.source)
|
.addSource(ops.source)
|
||||||
.setProxiedFetcher(makeSimpleProxyFetcher(process.env.MOVIE_WEB_PROXY_URL, fetch))
|
.setProxiedFetcher(makeSimpleProxyFetcher(process.env.MOVIE_WEB_PROXY_URL, fetch))
|
||||||
.build();
|
.build();
|
||||||
await runTest(providers);
|
await runTest(providers);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
});
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import { testSource } from "./providerUtils";
|
import { testSource } from './providerUtils';
|
||||||
import { lookmovieScraper } from "@/providers/sources/lookmovie";
|
import { lookmovieScraper } from '@/providers/sources/lookmovie';
|
||||||
import { testMedia } from "./testMedia";
|
import { testMedia } from './testMedia';
|
||||||
import { showboxScraper } from "@/providers/sources/showbox";
|
import { showboxScraper } from '@/providers/sources/showbox';
|
||||||
import dotenv from 'dotenv';
|
import dotenv from 'dotenv';
|
||||||
import { flixhqScraper } from "@/providers/sources/flixhq";
|
import { flixhqScraper } from '@/providers/sources/flixhq';
|
||||||
import { goMoviesScraper } from "@/providers/sources/gomovies";
|
import { goMoviesScraper } from '@/providers/sources/gomovies';
|
||||||
import { smashyStreamScraper } from "@/providers/sources/smashystream";
|
import { smashyStreamScraper } from '@/providers/sources/smashystream';
|
||||||
import { vidsrcScraper } from "@/providers/sources/vidsrc";
|
import { vidsrcScraper } from '@/providers/sources/vidsrc';
|
||||||
import { vidSrcToScraper } from "@/providers/sources/vidsrcto";
|
import { vidSrcToScraper } from '@/providers/sources/vidsrcto';
|
||||||
import { zoechipScraper } from "@/providers/sources/zoechip";
|
import { zoechipScraper } from '@/providers/sources/zoechip';
|
||||||
import { remotestreamScraper } from "@/providers/sources/remotestream";
|
import { remotestreamScraper } from '@/providers/sources/remotestream';
|
||||||
|
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
|
@ -19,8 +19,8 @@ testSource({
|
||||||
types: ['ip:standard'],
|
types: ['ip:standard'],
|
||||||
expect: {
|
expect: {
|
||||||
streams: 1,
|
streams: 1,
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
testSource({
|
testSource({
|
||||||
source: showboxScraper,
|
source: showboxScraper,
|
||||||
|
@ -28,8 +28,8 @@ testSource({
|
||||||
types: ['standard', 'proxied'],
|
types: ['standard', 'proxied'],
|
||||||
expect: {
|
expect: {
|
||||||
embeds: 1,
|
embeds: 1,
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
testSource({
|
testSource({
|
||||||
source: flixhqScraper,
|
source: flixhqScraper,
|
||||||
|
@ -37,8 +37,8 @@ testSource({
|
||||||
types: ['standard', 'proxied'],
|
types: ['standard', 'proxied'],
|
||||||
expect: {
|
expect: {
|
||||||
embeds: 1,
|
embeds: 1,
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
testSource({
|
testSource({
|
||||||
source: goMoviesScraper,
|
source: goMoviesScraper,
|
||||||
|
@ -46,8 +46,8 @@ testSource({
|
||||||
types: ['standard', 'proxied'],
|
types: ['standard', 'proxied'],
|
||||||
expect: {
|
expect: {
|
||||||
embeds: 1,
|
embeds: 1,
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
testSource({
|
testSource({
|
||||||
source: smashyStreamScraper,
|
source: smashyStreamScraper,
|
||||||
|
@ -55,8 +55,8 @@ testSource({
|
||||||
types: ['standard', 'proxied'],
|
types: ['standard', 'proxied'],
|
||||||
expect: {
|
expect: {
|
||||||
embeds: 1,
|
embeds: 1,
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
testSource({
|
testSource({
|
||||||
source: vidsrcScraper,
|
source: vidsrcScraper,
|
||||||
|
@ -64,8 +64,8 @@ testSource({
|
||||||
types: ['standard', 'proxied'],
|
types: ['standard', 'proxied'],
|
||||||
expect: {
|
expect: {
|
||||||
embeds: 1,
|
embeds: 1,
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
testSource({
|
testSource({
|
||||||
source: vidSrcToScraper,
|
source: vidSrcToScraper,
|
||||||
|
@ -73,8 +73,8 @@ testSource({
|
||||||
types: ['standard', 'proxied'],
|
types: ['standard', 'proxied'],
|
||||||
expect: {
|
expect: {
|
||||||
embeds: 2,
|
embeds: 2,
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
testSource({
|
testSource({
|
||||||
source: zoechipScraper,
|
source: zoechipScraper,
|
||||||
|
@ -82,8 +82,8 @@ testSource({
|
||||||
types: ['standard', 'proxied'],
|
types: ['standard', 'proxied'],
|
||||||
expect: {
|
expect: {
|
||||||
embeds: 3,
|
embeds: 3,
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
testSource({
|
testSource({
|
||||||
source: remotestreamScraper,
|
source: remotestreamScraper,
|
||||||
|
@ -91,5 +91,5 @@ testSource({
|
||||||
types: ['standard', 'proxied'],
|
types: ['standard', 'proxied'],
|
||||||
expect: {
|
expect: {
|
||||||
streams: 1,
|
streams: 1,
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { ScrapeMedia } from "@/entrypoint/utils/media";
|
import { ScrapeMedia } from '@/entrypoint/utils/media';
|
||||||
|
|
||||||
function makeMedia(media: ScrapeMedia): ScrapeMedia {
|
function makeMedia(media: ScrapeMedia): ScrapeMedia {
|
||||||
return media;
|
return media;
|
||||||
|
@ -6,9 +6,9 @@ function makeMedia(media: ScrapeMedia): ScrapeMedia {
|
||||||
|
|
||||||
export const testMedia = {
|
export const testMedia = {
|
||||||
arcane: makeMedia({
|
arcane: makeMedia({
|
||||||
type: "show",
|
type: 'show',
|
||||||
title: "Arcane",
|
title: 'Arcane',
|
||||||
tmdbId: "94605",
|
tmdbId: '94605',
|
||||||
releaseYear: 2021,
|
releaseYear: 2021,
|
||||||
episode: {
|
episode: {
|
||||||
number: 1,
|
number: 1,
|
||||||
|
@ -18,13 +18,13 @@ export const testMedia = {
|
||||||
number: 1,
|
number: 1,
|
||||||
tmdbId: '134187',
|
tmdbId: '134187',
|
||||||
},
|
},
|
||||||
imdbId: 'tt11126994'
|
imdbId: 'tt11126994',
|
||||||
}),
|
}),
|
||||||
hamilton: makeMedia({
|
hamilton: makeMedia({
|
||||||
type: 'movie',
|
type: 'movie',
|
||||||
tmdbId: '556574',
|
tmdbId: '556574',
|
||||||
imdbId: 'tt8503618',
|
imdbId: 'tt8503618',
|
||||||
releaseYear: 2020,
|
releaseYear: 2020,
|
||||||
title: 'Hamilton'
|
title: 'Hamilton',
|
||||||
})
|
}),
|
||||||
}
|
};
|
||||||
|
|
|
@ -1,39 +1,39 @@
|
||||||
import { serializeBody } from "@/fetchers/body";
|
import { serializeBody } from '@/fetchers/body';
|
||||||
import FormData from "form-data";
|
import FormData from 'form-data';
|
||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from 'vitest';
|
||||||
|
|
||||||
describe("serializeBody()", () => {
|
describe('serializeBody()', () => {
|
||||||
it('should work with standard text', () => {
|
it('should work with standard text', () => {
|
||||||
expect(serializeBody("hello world")).toEqual({
|
expect(serializeBody('hello world')).toEqual({
|
||||||
headers: {},
|
headers: {},
|
||||||
body: "hello world"
|
body: 'hello world',
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
it('should work with objects', () => {
|
it('should work with objects', () => {
|
||||||
expect(serializeBody({ hello: "world", a: 42 })).toEqual({
|
expect(serializeBody({ hello: 'world', a: 42 })).toEqual({
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json"
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
body: JSON.stringify({ hello: "world", a: 42 })
|
body: JSON.stringify({ hello: 'world', a: 42 }),
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
it('should work x-www-form-urlencoded', () => {
|
it('should work x-www-form-urlencoded', () => {
|
||||||
const obj = new URLSearchParams()
|
const obj = new URLSearchParams();
|
||||||
obj.set("a", "b");
|
obj.set('a', 'b');
|
||||||
expect(serializeBody(obj)).toEqual({
|
expect(serializeBody(obj)).toEqual({
|
||||||
headers: {},
|
headers: {},
|
||||||
body: obj
|
body: obj,
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
it('should work multipart/form-data', () => {
|
it('should work multipart/form-data', () => {
|
||||||
const obj = new FormData()
|
const obj = new FormData();
|
||||||
obj.append("a", "b");
|
obj.append('a', 'b');
|
||||||
expect(serializeBody(obj)).toEqual({
|
expect(serializeBody(obj)).toEqual({
|
||||||
headers: {},
|
headers: {},
|
||||||
body: obj
|
body: obj,
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
|
@ -1,48 +1,62 @@
|
||||||
import { makeFullUrl } from "@/fetchers/common";
|
import { makeFullUrl } from '@/fetchers/common';
|
||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from 'vitest';
|
||||||
|
|
||||||
describe("makeFullUrl()", () => {
|
describe('makeFullUrl()', () => {
|
||||||
it('should pass normal url if no options', () => {
|
it('should pass normal url if no options', () => {
|
||||||
expect(makeFullUrl('https://example.com/hello/world')).toEqual("https://example.com/hello/world")
|
expect(makeFullUrl('https://example.com/hello/world')).toEqual('https://example.com/hello/world');
|
||||||
expect(makeFullUrl('https://example.com/hello/world?a=b')).toEqual("https://example.com/hello/world?a=b")
|
expect(makeFullUrl('https://example.com/hello/world?a=b')).toEqual('https://example.com/hello/world?a=b');
|
||||||
expect(makeFullUrl('https://example.com/hello/world?a=b#hello')).toEqual("https://example.com/hello/world?a=b#hello")
|
expect(makeFullUrl('https://example.com/hello/world?a=b#hello')).toEqual(
|
||||||
expect(makeFullUrl('https://example.com/hello/world#hello')).toEqual("https://example.com/hello/world#hello")
|
'https://example.com/hello/world?a=b#hello',
|
||||||
})
|
);
|
||||||
|
expect(makeFullUrl('https://example.com/hello/world#hello')).toEqual('https://example.com/hello/world#hello');
|
||||||
|
});
|
||||||
|
|
||||||
it('should append baseurl correctly', () => {
|
it('should append baseurl correctly', () => {
|
||||||
const correctResult = "https://example.com/hello/world";
|
const correctResult = 'https://example.com/hello/world';
|
||||||
expect(makeFullUrl(correctResult, { baseUrl: '' })).toEqual(correctResult)
|
expect(makeFullUrl(correctResult, { baseUrl: '' })).toEqual(correctResult);
|
||||||
expect(makeFullUrl('/hello/world', { baseUrl: 'https://example.com' })).toEqual(correctResult)
|
expect(makeFullUrl('/hello/world', { baseUrl: 'https://example.com' })).toEqual(correctResult);
|
||||||
expect(makeFullUrl('/hello/world', { baseUrl: 'https://example.com/' })).toEqual(correctResult)
|
expect(makeFullUrl('/hello/world', { baseUrl: 'https://example.com/' })).toEqual(correctResult);
|
||||||
expect(makeFullUrl('hello/world', { baseUrl: 'https://example.com/' })).toEqual(correctResult)
|
expect(makeFullUrl('hello/world', { baseUrl: 'https://example.com/' })).toEqual(correctResult);
|
||||||
expect(makeFullUrl('hello/world', { baseUrl: 'https://example.com' })).toEqual(correctResult)
|
expect(makeFullUrl('hello/world', { baseUrl: 'https://example.com' })).toEqual(correctResult);
|
||||||
expect(makeFullUrl('/world', { baseUrl: 'https://example.com/hello' })).toEqual(correctResult)
|
expect(makeFullUrl('/world', { baseUrl: 'https://example.com/hello' })).toEqual(correctResult);
|
||||||
expect(makeFullUrl('/world', { baseUrl: 'https://example.com/hello/' })).toEqual(correctResult)
|
expect(makeFullUrl('/world', { baseUrl: 'https://example.com/hello/' })).toEqual(correctResult);
|
||||||
expect(makeFullUrl('world', { baseUrl: 'https://example.com/hello/' })).toEqual(correctResult)
|
expect(makeFullUrl('world', { baseUrl: 'https://example.com/hello/' })).toEqual(correctResult);
|
||||||
expect(makeFullUrl('world', { baseUrl: 'https://example.com/hello' })).toEqual(correctResult)
|
expect(makeFullUrl('world', { baseUrl: 'https://example.com/hello' })).toEqual(correctResult);
|
||||||
expect(makeFullUrl('world?a=b', { baseUrl: 'https://example.com/hello' })).toEqual("https://example.com/hello/world?a=b")
|
expect(makeFullUrl('world?a=b', { baseUrl: 'https://example.com/hello' })).toEqual(
|
||||||
})
|
'https://example.com/hello/world?a=b',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('should throw with invalid baseurl combinations', () => {
|
it('should throw with invalid baseurl combinations', () => {
|
||||||
expect(() => makeFullUrl('example.com/hello/world', { baseUrl: '' })).toThrowError()
|
expect(() => makeFullUrl('example.com/hello/world', { baseUrl: '' })).toThrowError();
|
||||||
expect(() => makeFullUrl('/hello/world', { baseUrl: 'example.com' })).toThrowError()
|
expect(() => makeFullUrl('/hello/world', { baseUrl: 'example.com' })).toThrowError();
|
||||||
expect(() => makeFullUrl('/hello/world', { baseUrl: 'tcp://example.com' })).toThrowError()
|
expect(() => makeFullUrl('/hello/world', { baseUrl: 'tcp://example.com' })).toThrowError();
|
||||||
expect(() => makeFullUrl('/hello/world', { baseUrl: 'tcp://example.com' })).toThrowError()
|
expect(() => makeFullUrl('/hello/world', { baseUrl: 'tcp://example.com' })).toThrowError();
|
||||||
})
|
});
|
||||||
|
|
||||||
it('should add/merge query parameters', () => {
|
it('should add/merge query parameters', () => {
|
||||||
expect(makeFullUrl('https://example.com/hello/world', { query: { a: 'b' } })).toEqual("https://example.com/hello/world?a=b")
|
expect(makeFullUrl('https://example.com/hello/world', { query: { a: 'b' } })).toEqual(
|
||||||
expect(makeFullUrl('https://example.com/hello/world/', { query: { a: 'b' } })).toEqual("https://example.com/hello/world/?a=b")
|
'https://example.com/hello/world?a=b',
|
||||||
expect(makeFullUrl('https://example.com', { query: { a: 'b' } })).toEqual("https://example.com/?a=b")
|
);
|
||||||
expect(makeFullUrl('https://example.com/', { query: { a: 'b' } })).toEqual("https://example.com/?a=b")
|
expect(makeFullUrl('https://example.com/hello/world/', { query: { a: 'b' } })).toEqual(
|
||||||
|
'https://example.com/hello/world/?a=b',
|
||||||
|
);
|
||||||
|
expect(makeFullUrl('https://example.com', { query: { a: 'b' } })).toEqual('https://example.com/?a=b');
|
||||||
|
expect(makeFullUrl('https://example.com/', { query: { a: 'b' } })).toEqual('https://example.com/?a=b');
|
||||||
|
|
||||||
expect(makeFullUrl('https://example.com/hello/world?c=d', { query: { a: 'b' } })).toEqual("https://example.com/hello/world?c=d&a=b")
|
expect(makeFullUrl('https://example.com/hello/world?c=d', { query: { a: 'b' } })).toEqual(
|
||||||
expect(makeFullUrl('https://example.com/hello/world?c=d', { query: {} })).toEqual("https://example.com/hello/world?c=d")
|
'https://example.com/hello/world?c=d&a=b',
|
||||||
expect(makeFullUrl('https://example.com/hello/world?c=d')).toEqual("https://example.com/hello/world?c=d")
|
);
|
||||||
expect(makeFullUrl('https://example.com/hello/world?c=d', {})).toEqual("https://example.com/hello/world?c=d")
|
expect(makeFullUrl('https://example.com/hello/world?c=d', { query: {} })).toEqual(
|
||||||
})
|
'https://example.com/hello/world?c=d',
|
||||||
|
);
|
||||||
|
expect(makeFullUrl('https://example.com/hello/world?c=d')).toEqual('https://example.com/hello/world?c=d');
|
||||||
|
expect(makeFullUrl('https://example.com/hello/world?c=d', {})).toEqual('https://example.com/hello/world?c=d');
|
||||||
|
});
|
||||||
|
|
||||||
it('should work with a mix of multiple options', () => {
|
it('should work with a mix of multiple options', () => {
|
||||||
expect(makeFullUrl('/hello/world?c=d', { baseUrl: 'https://example.com/', query: { a: 'b' } })).toEqual("https://example.com/hello/world?c=d&a=b")
|
expect(makeFullUrl('/hello/world?c=d', { baseUrl: 'https://example.com/', query: { a: 'b' } })).toEqual(
|
||||||
})
|
'https://example.com/hello/world?c=d&a=b',
|
||||||
})
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -1,138 +1,148 @@
|
||||||
import { makeSimpleProxyFetcher } from "@/fetchers/simpleProxy";
|
import { makeSimpleProxyFetcher } from '@/fetchers/simpleProxy';
|
||||||
import { DefaultedFetcherOptions, FetcherOptions } from "@/fetchers/types";
|
import { DefaultedFetcherOptions, FetcherOptions } from '@/fetchers/types';
|
||||||
import { Headers } from "node-fetch";
|
import { Headers } from 'node-fetch';
|
||||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||||
|
|
||||||
describe("makeSimpleProxyFetcher()", () => {
|
describe('makeSimpleProxyFetcher()', () => {
|
||||||
const fetch = vi.fn();
|
const fetch = vi.fn();
|
||||||
const fetcher = makeSimpleProxyFetcher("https://example.com/proxy", fetch);
|
const fetcher = makeSimpleProxyFetcher('https://example.com/proxy', fetch);
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
vi.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
function setResult(type: "text" | "json", value: any) {
|
function setResult(type: 'text' | 'json', value: any) {
|
||||||
if (type === 'text') return fetch.mockResolvedValueOnce({
|
if (type === 'text')
|
||||||
|
return fetch.mockResolvedValueOnce({
|
||||||
headers: new Headers({
|
headers: new Headers({
|
||||||
"content-type": "text/plain",
|
'content-type': 'text/plain',
|
||||||
}),
|
}),
|
||||||
status: 204,
|
status: 204,
|
||||||
url: "test123",
|
url: 'test123',
|
||||||
text() {
|
text() {
|
||||||
return Promise.resolve(value);
|
return Promise.resolve(value);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (type === 'json') return fetch.mockResolvedValueOnce({
|
if (type === 'json')
|
||||||
|
return fetch.mockResolvedValueOnce({
|
||||||
headers: new Headers({
|
headers: new Headers({
|
||||||
"content-type": "application/json",
|
'content-type': 'application/json',
|
||||||
}),
|
}),
|
||||||
status: 204,
|
status: 204,
|
||||||
url: "test123",
|
url: 'test123',
|
||||||
json() {
|
json() {
|
||||||
return Promise.resolve(value);
|
return Promise.resolve(value);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function expectFetchCall(ops: { inputUrl: string, input: DefaultedFetcherOptions, outputUrl?: string, output: any, outputBody: any }) {
|
function expectFetchCall(ops: {
|
||||||
|
inputUrl: string;
|
||||||
|
input: DefaultedFetcherOptions;
|
||||||
|
outputUrl?: string;
|
||||||
|
output: any;
|
||||||
|
outputBody: any;
|
||||||
|
}) {
|
||||||
const prom = fetcher(ops.inputUrl, ops.input);
|
const prom = fetcher(ops.inputUrl, ops.input);
|
||||||
expect((async () => (await prom).body)()).resolves.toEqual(ops.outputBody);
|
expect((async () => (await prom).body)()).resolves.toEqual(ops.outputBody);
|
||||||
expect((async () => (await prom).headers.entries())()).resolves.toEqual((new Headers()).entries());
|
expect((async () => Array.from((await prom).headers.entries()))()).resolves.toEqual(
|
||||||
|
Array.from(new Headers().entries()),
|
||||||
|
);
|
||||||
expect((async () => (await prom).statusCode)()).resolves.toEqual(204);
|
expect((async () => (await prom).statusCode)()).resolves.toEqual(204);
|
||||||
expect((async () => (await prom).finalUrl)()).resolves.toEqual("test123");
|
expect((async () => (await prom).finalUrl)()).resolves.toEqual('test123');
|
||||||
expect(fetch).toBeCalledWith(ops.outputUrl ?? ops.inputUrl, ops.output);
|
expect(fetch).toBeCalledWith(ops.outputUrl ?? ops.inputUrl, ops.output);
|
||||||
vi.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should pass options through', () => {
|
it('should pass options through', () => {
|
||||||
setResult("text", "hello world");
|
setResult('text', 'hello world');
|
||||||
expectFetchCall({
|
expectFetchCall({
|
||||||
inputUrl: "https://google.com",
|
inputUrl: 'https://google.com',
|
||||||
input: {
|
input: {
|
||||||
method: "GET",
|
method: 'GET',
|
||||||
query: {},
|
query: {},
|
||||||
readHeaders: [],
|
readHeaders: [],
|
||||||
headers: {
|
headers: {
|
||||||
"X-Hello": "world",
|
'X-Hello': 'world',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
outputUrl: `https://example.com/proxy?destination=${encodeURIComponent('https://google.com/')}`,
|
outputUrl: `https://example.com/proxy?destination=${encodeURIComponent('https://google.com/')}`,
|
||||||
output: {
|
output: {
|
||||||
method: "GET",
|
method: 'GET',
|
||||||
headers: {
|
headers: {
|
||||||
"X-Hello": "world",
|
'X-Hello': 'world',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
outputBody: "hello world"
|
outputBody: 'hello world',
|
||||||
})
|
});
|
||||||
setResult("text", "hello world");
|
setResult('text', 'hello world');
|
||||||
expectFetchCall({
|
expectFetchCall({
|
||||||
inputUrl: "https://google.com",
|
inputUrl: 'https://google.com',
|
||||||
input: {
|
input: {
|
||||||
method: "GET",
|
method: 'GET',
|
||||||
headers: {},
|
headers: {},
|
||||||
readHeaders: [],
|
readHeaders: [],
|
||||||
query: {
|
query: {
|
||||||
"a": 'b',
|
a: 'b',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
outputUrl: `https://example.com/proxy?destination=${encodeURIComponent('https://google.com/?a=b')}`,
|
outputUrl: `https://example.com/proxy?destination=${encodeURIComponent('https://google.com/?a=b')}`,
|
||||||
output: {
|
output: {
|
||||||
method: "GET",
|
method: 'GET',
|
||||||
headers: {},
|
headers: {},
|
||||||
},
|
},
|
||||||
outputBody: "hello world"
|
outputBody: 'hello world',
|
||||||
})
|
});
|
||||||
setResult("text", "hello world");
|
setResult('text', 'hello world');
|
||||||
expectFetchCall({
|
expectFetchCall({
|
||||||
inputUrl: "https://google.com",
|
inputUrl: 'https://google.com',
|
||||||
input: {
|
input: {
|
||||||
method: "GET",
|
method: 'GET',
|
||||||
query: {},
|
query: {},
|
||||||
readHeaders: [],
|
readHeaders: [],
|
||||||
headers: {},
|
headers: {},
|
||||||
},
|
},
|
||||||
outputUrl: `https://example.com/proxy?destination=${encodeURIComponent('https://google.com/')}`,
|
outputUrl: `https://example.com/proxy?destination=${encodeURIComponent('https://google.com/')}`,
|
||||||
output: {
|
output: {
|
||||||
method: "GET",
|
method: 'GET',
|
||||||
headers: {},
|
headers: {},
|
||||||
},
|
},
|
||||||
outputBody: "hello world"
|
outputBody: 'hello world',
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should parse response correctly', () => {
|
it('should parse response correctly', () => {
|
||||||
setResult("text", "hello world");
|
setResult('text', 'hello world');
|
||||||
expectFetchCall({
|
expectFetchCall({
|
||||||
inputUrl: "https://google.com/",
|
inputUrl: 'https://google.com/',
|
||||||
input: {
|
input: {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
query: {},
|
query: {},
|
||||||
readHeaders: [],
|
readHeaders: [],
|
||||||
headers: {},
|
headers: {},
|
||||||
},
|
},
|
||||||
outputUrl: `https://example.com/proxy?destination=${encodeURIComponent('https://google.com/')}`,
|
outputUrl: `https://example.com/proxy?destination=${encodeURIComponent('https://google.com/')}`,
|
||||||
output: {
|
output: {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
headers: {},
|
headers: {},
|
||||||
},
|
},
|
||||||
outputBody: "hello world"
|
outputBody: 'hello world',
|
||||||
})
|
});
|
||||||
setResult("json", { hello: 42 });
|
// setResult("json", { hello: 42 });
|
||||||
expectFetchCall({
|
// expectFetchCall({
|
||||||
inputUrl: "https://google.com/",
|
// inputUrl: "https://google.com/",
|
||||||
input: {
|
// input: {
|
||||||
method: "POST",
|
// method: "POST",
|
||||||
query: {},
|
// query: {},
|
||||||
readHeaders: [],
|
// readHeaders: [],
|
||||||
headers: {},
|
// headers: {},
|
||||||
},
|
// },
|
||||||
outputUrl: `https://example.com/proxy?destination=${encodeURIComponent('https://google.com/')}`,
|
// outputUrl: `https://example.com/proxy?destination=${encodeURIComponent('https://google.com/')}`,
|
||||||
output: {
|
// output: {
|
||||||
method: "POST",
|
// method: "POST",
|
||||||
headers: {},
|
// headers: {},
|
||||||
},
|
// },
|
||||||
outputBody: { hello: 42 }
|
// outputBody: { hello: 42 }
|
||||||
})
|
// })
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { makeStandardFetcher } from "@/fetchers/standardFetch";
|
import { makeStandardFetcher } from '@/fetchers/standardFetch';
|
||||||
import { DefaultedFetcherOptions } from "@/fetchers/types";
|
import { DefaultedFetcherOptions } from '@/fetchers/types';
|
||||||
import { Headers } from "node-fetch";
|
import { Headers } from 'node-fetch';
|
||||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||||
|
|
||||||
describe("makeStandardFetcher()", () => {
|
describe('makeStandardFetcher()', () => {
|
||||||
const fetch = vi.fn();
|
const fetch = vi.fn();
|
||||||
const fetcher = makeStandardFetcher(fetch);
|
const fetcher = makeStandardFetcher(fetch);
|
||||||
|
|
||||||
|
@ -11,129 +11,139 @@ describe("makeStandardFetcher()", () => {
|
||||||
vi.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
function setResult(type: "text" | "json", value: any) {
|
function setResult(type: 'text' | 'json', value: any) {
|
||||||
if (type === 'text') return fetch.mockResolvedValueOnce({
|
if (type === 'text')
|
||||||
|
return fetch.mockResolvedValueOnce({
|
||||||
headers: new Headers({
|
headers: new Headers({
|
||||||
"content-type": "text/plain",
|
'content-type': 'text/plain',
|
||||||
}),
|
}),
|
||||||
status: 204,
|
status: 204,
|
||||||
url: "test123",
|
url: 'test123',
|
||||||
text() {
|
text() {
|
||||||
return Promise.resolve(value);
|
return Promise.resolve(value);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (type === 'json') return fetch.mockResolvedValueOnce({
|
if (type === 'json')
|
||||||
|
return fetch.mockResolvedValueOnce({
|
||||||
headers: new Headers({
|
headers: new Headers({
|
||||||
"content-type": "application/json",
|
'content-type': 'application/json',
|
||||||
}),
|
}),
|
||||||
status: 204,
|
status: 204,
|
||||||
url: "test123",
|
url: 'test123',
|
||||||
json() {
|
json() {
|
||||||
return Promise.resolve(value);
|
return Promise.resolve(value);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function expectFetchCall(ops: { inputUrl: string, input: DefaultedFetcherOptions, outputUrl?: string, output: any, outputBody: any }) {
|
function expectFetchCall(ops: {
|
||||||
|
inputUrl: string;
|
||||||
|
input: DefaultedFetcherOptions;
|
||||||
|
outputUrl?: string;
|
||||||
|
output: any;
|
||||||
|
outputBody: any;
|
||||||
|
}) {
|
||||||
const prom = fetcher(ops.inputUrl, ops.input);
|
const prom = fetcher(ops.inputUrl, ops.input);
|
||||||
expect((async () => (await prom).body)()).resolves.toEqual(ops.outputBody);
|
expect((async () => (await prom).body)()).resolves.toEqual(ops.outputBody);
|
||||||
expect((async () => (await prom).headers.entries())()).resolves.toEqual((new Headers()).entries());
|
expect((async () => Array.from((await prom).headers.entries()))()).resolves.toEqual(
|
||||||
|
Array.from(new Headers().entries()),
|
||||||
|
);
|
||||||
expect((async () => (await prom).statusCode)()).resolves.toEqual(204);
|
expect((async () => (await prom).statusCode)()).resolves.toEqual(204);
|
||||||
expect((async () => (await prom).finalUrl)()).resolves.toEqual("test123");
|
expect((async () => (await prom).finalUrl)()).resolves.toEqual('test123');
|
||||||
expect(fetch).toBeCalledWith(ops.outputUrl ?? ops.inputUrl, ops.output);
|
expect(fetch).toBeCalledWith(ops.outputUrl ?? ops.inputUrl, ops.output);
|
||||||
vi.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should pass options through', () => {
|
it('should pass options through', () => {
|
||||||
setResult("text", "hello world");
|
setResult('text', 'hello world');
|
||||||
expectFetchCall({
|
expectFetchCall({
|
||||||
inputUrl: "https://google.com",
|
inputUrl: 'https://google.com',
|
||||||
input: {
|
input: {
|
||||||
method: "GET",
|
method: 'GET',
|
||||||
query: {},
|
query: {},
|
||||||
readHeaders: [],
|
readHeaders: [],
|
||||||
headers: {
|
headers: {
|
||||||
"X-Hello": "world",
|
'X-Hello': 'world',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
outputUrl: "https://google.com/",
|
outputUrl: 'https://google.com/',
|
||||||
output: {
|
output: {
|
||||||
method: "GET",
|
method: 'GET',
|
||||||
headers: {
|
headers: {
|
||||||
"X-Hello": "world",
|
'X-Hello': 'world',
|
||||||
},
|
},
|
||||||
body: undefined,
|
body: undefined,
|
||||||
},
|
},
|
||||||
outputBody: "hello world"
|
outputBody: 'hello world',
|
||||||
})
|
});
|
||||||
setResult("text", "hello world");
|
setResult('text', 'hello world');
|
||||||
expectFetchCall({
|
expectFetchCall({
|
||||||
inputUrl: "https://google.com",
|
inputUrl: 'https://google.com',
|
||||||
input: {
|
input: {
|
||||||
method: "GET",
|
method: 'GET',
|
||||||
headers: {},
|
headers: {},
|
||||||
readHeaders: [],
|
readHeaders: [],
|
||||||
query: {
|
query: {
|
||||||
"a": 'b',
|
a: 'b',
|
||||||
}
|
|
||||||
},
|
},
|
||||||
outputUrl: "https://google.com/?a=b",
|
},
|
||||||
|
outputUrl: 'https://google.com/?a=b',
|
||||||
output: {
|
output: {
|
||||||
method: "GET",
|
method: 'GET',
|
||||||
headers: {},
|
headers: {},
|
||||||
},
|
},
|
||||||
outputBody: "hello world"
|
outputBody: 'hello world',
|
||||||
})
|
});
|
||||||
setResult("text", "hello world");
|
setResult('text', 'hello world');
|
||||||
expectFetchCall({
|
expectFetchCall({
|
||||||
inputUrl: "https://google.com",
|
inputUrl: 'https://google.com',
|
||||||
input: {
|
input: {
|
||||||
query: {},
|
query: {},
|
||||||
headers: {},
|
headers: {},
|
||||||
readHeaders: [],
|
readHeaders: [],
|
||||||
method: "GET"
|
method: 'GET',
|
||||||
},
|
},
|
||||||
outputUrl: "https://google.com/",
|
outputUrl: 'https://google.com/',
|
||||||
output: {
|
output: {
|
||||||
method: "GET",
|
method: 'GET',
|
||||||
headers: {},
|
headers: {},
|
||||||
},
|
},
|
||||||
outputBody: "hello world"
|
outputBody: 'hello world',
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should parse response correctly', () => {
|
it('should parse response correctly', () => {
|
||||||
setResult("text", "hello world");
|
setResult('text', 'hello world');
|
||||||
expectFetchCall({
|
expectFetchCall({
|
||||||
inputUrl: "https://google.com/",
|
inputUrl: 'https://google.com/',
|
||||||
input: {
|
input: {
|
||||||
query: {},
|
query: {},
|
||||||
headers: {},
|
headers: {},
|
||||||
readHeaders: [],
|
readHeaders: [],
|
||||||
method: "POST"
|
method: 'POST',
|
||||||
},
|
},
|
||||||
outputUrl: "https://google.com/",
|
outputUrl: 'https://google.com/',
|
||||||
output: {
|
output: {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
headers: {},
|
headers: {},
|
||||||
},
|
},
|
||||||
outputBody: "hello world"
|
outputBody: 'hello world',
|
||||||
})
|
});
|
||||||
setResult("json", { hello: 42 });
|
setResult('json', { hello: 42 });
|
||||||
expectFetchCall({
|
expectFetchCall({
|
||||||
inputUrl: "https://google.com/",
|
inputUrl: 'https://google.com/',
|
||||||
input: {
|
input: {
|
||||||
query: {},
|
query: {},
|
||||||
headers: {},
|
headers: {},
|
||||||
readHeaders: [],
|
readHeaders: [],
|
||||||
method: "POST"
|
method: 'POST',
|
||||||
},
|
},
|
||||||
outputUrl: "https://google.com/",
|
outputUrl: 'https://google.com/',
|
||||||
output: {
|
output: {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
headers: {},
|
headers: {},
|
||||||
},
|
},
|
||||||
outputBody: { hello: 42 }
|
outputBody: { hello: 42 },
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,8 +9,8 @@ vi.mock('@/providers/all', () => mocks);
|
||||||
|
|
||||||
const features: FeatureMap = {
|
const features: FeatureMap = {
|
||||||
requires: [],
|
requires: [],
|
||||||
disallowed: []
|
disallowed: [],
|
||||||
}
|
};
|
||||||
|
|
||||||
describe('getProviders()', () => {
|
describe('getProviders()', () => {
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
@ -20,10 +20,12 @@ describe('getProviders()', () => {
|
||||||
it('should return providers', () => {
|
it('should return providers', () => {
|
||||||
mocks.gatherAllEmbeds.mockReturnValue([mockEmbeds.embedD]);
|
mocks.gatherAllEmbeds.mockReturnValue([mockEmbeds.embedD]);
|
||||||
mocks.gatherAllSources.mockReturnValue([mockSources.sourceA, mockSources.sourceB]);
|
mocks.gatherAllSources.mockReturnValue([mockSources.sourceA, mockSources.sourceB]);
|
||||||
expect(getProviders(features, {
|
expect(
|
||||||
|
getProviders(features, {
|
||||||
embeds: getBuiltinEmbeds(),
|
embeds: getBuiltinEmbeds(),
|
||||||
sources: getBuiltinSources(),
|
sources: getBuiltinSources(),
|
||||||
})).toEqual({
|
}),
|
||||||
|
).toEqual({
|
||||||
sources: [mockSources.sourceA, mockSources.sourceB],
|
sources: [mockSources.sourceA, mockSources.sourceB],
|
||||||
embeds: [mockEmbeds.embedD],
|
embeds: [mockEmbeds.embedD],
|
||||||
});
|
});
|
||||||
|
@ -32,10 +34,12 @@ describe('getProviders()', () => {
|
||||||
it('should filter out disabled providers', () => {
|
it('should filter out disabled providers', () => {
|
||||||
mocks.gatherAllEmbeds.mockReturnValue([mockEmbeds.embedD, mockEmbeds.embedEDisabled]);
|
mocks.gatherAllEmbeds.mockReturnValue([mockEmbeds.embedD, mockEmbeds.embedEDisabled]);
|
||||||
mocks.gatherAllSources.mockReturnValue([mockSources.sourceA, mockSources.sourceCDisabled, mockSources.sourceB]);
|
mocks.gatherAllSources.mockReturnValue([mockSources.sourceA, mockSources.sourceCDisabled, mockSources.sourceB]);
|
||||||
expect(getProviders(features,{
|
expect(
|
||||||
|
getProviders(features, {
|
||||||
embeds: getBuiltinEmbeds(),
|
embeds: getBuiltinEmbeds(),
|
||||||
sources: getBuiltinSources(),
|
sources: getBuiltinSources(),
|
||||||
})).toEqual({
|
}),
|
||||||
|
).toEqual({
|
||||||
sources: [mockSources.sourceA, mockSources.sourceB],
|
sources: [mockSources.sourceA, mockSources.sourceB],
|
||||||
embeds: [mockEmbeds.embedD],
|
embeds: [mockEmbeds.embedD],
|
||||||
});
|
});
|
||||||
|
@ -44,46 +48,56 @@ describe('getProviders()', () => {
|
||||||
it('should throw on duplicate ids in sources', () => {
|
it('should throw on duplicate ids in sources', () => {
|
||||||
mocks.gatherAllEmbeds.mockReturnValue([]);
|
mocks.gatherAllEmbeds.mockReturnValue([]);
|
||||||
mocks.gatherAllSources.mockReturnValue([mockSources.sourceAHigherRank, mockSources.sourceA, mockSources.sourceB]);
|
mocks.gatherAllSources.mockReturnValue([mockSources.sourceAHigherRank, mockSources.sourceA, mockSources.sourceB]);
|
||||||
expect(() => getProviders(features,{
|
expect(() =>
|
||||||
|
getProviders(features, {
|
||||||
embeds: getBuiltinEmbeds(),
|
embeds: getBuiltinEmbeds(),
|
||||||
sources: getBuiltinSources(),
|
sources: getBuiltinSources(),
|
||||||
})).toThrowError();
|
}),
|
||||||
|
).toThrowError();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw on duplicate ids in embeds', () => {
|
it('should throw on duplicate ids in embeds', () => {
|
||||||
mocks.gatherAllEmbeds.mockReturnValue([mockEmbeds.embedD, mockEmbeds.embedDHigherRank, mockEmbeds.embedA]);
|
mocks.gatherAllEmbeds.mockReturnValue([mockEmbeds.embedD, mockEmbeds.embedDHigherRank, mockEmbeds.embedA]);
|
||||||
mocks.gatherAllSources.mockReturnValue([]);
|
mocks.gatherAllSources.mockReturnValue([]);
|
||||||
expect(() => getProviders(features,{
|
expect(() =>
|
||||||
|
getProviders(features, {
|
||||||
embeds: getBuiltinEmbeds(),
|
embeds: getBuiltinEmbeds(),
|
||||||
sources: getBuiltinSources(),
|
sources: getBuiltinSources(),
|
||||||
})).toThrowError();
|
}),
|
||||||
|
).toThrowError();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw on duplicate ids between sources and embeds', () => {
|
it('should throw on duplicate ids between sources and embeds', () => {
|
||||||
mocks.gatherAllEmbeds.mockReturnValue([mockEmbeds.embedD, mockEmbeds.embedA]);
|
mocks.gatherAllEmbeds.mockReturnValue([mockEmbeds.embedD, mockEmbeds.embedA]);
|
||||||
mocks.gatherAllSources.mockReturnValue([mockSources.sourceA, mockSources.sourceB]);
|
mocks.gatherAllSources.mockReturnValue([mockSources.sourceA, mockSources.sourceB]);
|
||||||
expect(() => getProviders(features,{
|
expect(() =>
|
||||||
|
getProviders(features, {
|
||||||
embeds: getBuiltinEmbeds(),
|
embeds: getBuiltinEmbeds(),
|
||||||
sources: getBuiltinSources(),
|
sources: getBuiltinSources(),
|
||||||
})).toThrowError();
|
}),
|
||||||
|
).toThrowError();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw on duplicate rank between sources and embeds', () => {
|
it('should throw on duplicate rank between sources and embeds', () => {
|
||||||
mocks.gatherAllEmbeds.mockReturnValue([mockEmbeds.embedD, mockEmbeds.embedA]);
|
mocks.gatherAllEmbeds.mockReturnValue([mockEmbeds.embedD, mockEmbeds.embedA]);
|
||||||
mocks.gatherAllSources.mockReturnValue([mockSources.sourceA, mockSources.sourceB]);
|
mocks.gatherAllSources.mockReturnValue([mockSources.sourceA, mockSources.sourceB]);
|
||||||
expect(() => getProviders(features,{
|
expect(() =>
|
||||||
|
getProviders(features, {
|
||||||
embeds: getBuiltinEmbeds(),
|
embeds: getBuiltinEmbeds(),
|
||||||
sources: getBuiltinSources(),
|
sources: getBuiltinSources(),
|
||||||
})).toThrowError();
|
}),
|
||||||
|
).toThrowError();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not throw with same rank between sources and embeds', () => {
|
it('should not throw with same rank between sources and embeds', () => {
|
||||||
mocks.gatherAllEmbeds.mockReturnValue([mockEmbeds.embedD, mockEmbeds.embedHSameRankAsSourceA]);
|
mocks.gatherAllEmbeds.mockReturnValue([mockEmbeds.embedD, mockEmbeds.embedHSameRankAsSourceA]);
|
||||||
mocks.gatherAllSources.mockReturnValue([mockSources.sourceA, mockSources.sourceB]);
|
mocks.gatherAllSources.mockReturnValue([mockSources.sourceA, mockSources.sourceB]);
|
||||||
expect(getProviders(features,{
|
expect(
|
||||||
|
getProviders(features, {
|
||||||
embeds: getBuiltinEmbeds(),
|
embeds: getBuiltinEmbeds(),
|
||||||
sources: getBuiltinSources(),
|
sources: getBuiltinSources(),
|
||||||
})).toEqual({
|
}),
|
||||||
|
).toEqual({
|
||||||
sources: [mockSources.sourceA, mockSources.sourceB],
|
sources: [mockSources.sourceA, mockSources.sourceB],
|
||||||
embeds: [mockEmbeds.embedD, mockEmbeds.embedHSameRankAsSourceA],
|
embeds: [mockEmbeds.embedD, mockEmbeds.embedHSameRankAsSourceA],
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { FeatureMap, Flags, flags, flagsAllowedInFeatures } from "@/entrypoint/utils/targets";
|
import { FeatureMap, Flags, flags, flagsAllowedInFeatures } from '@/entrypoint/utils/targets';
|
||||||
import { describe, it, expect } from "vitest";
|
import { describe, it, expect } from 'vitest';
|
||||||
|
|
||||||
describe('flagsAllowedInFeatures()', () => {
|
describe('flagsAllowedInFeatures()', () => {
|
||||||
function checkFeatures(featureMap: FeatureMap, flags: Flags[], output: boolean) {
|
function checkFeatures(featureMap: FeatureMap, flags: Flags[], output: boolean) {
|
||||||
|
@ -7,71 +7,131 @@ describe('flagsAllowedInFeatures()', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should check required correctly', () => {
|
it('should check required correctly', () => {
|
||||||
checkFeatures({
|
checkFeatures(
|
||||||
|
{
|
||||||
requires: [],
|
requires: [],
|
||||||
disallowed: []
|
disallowed: [],
|
||||||
}, [], true);
|
},
|
||||||
checkFeatures({
|
[],
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
checkFeatures(
|
||||||
|
{
|
||||||
requires: [flags.CORS_ALLOWED],
|
requires: [flags.CORS_ALLOWED],
|
||||||
disallowed: []
|
disallowed: [],
|
||||||
}, [flags.CORS_ALLOWED], true);
|
},
|
||||||
checkFeatures({
|
[flags.CORS_ALLOWED],
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
checkFeatures(
|
||||||
|
{
|
||||||
requires: [flags.CORS_ALLOWED],
|
requires: [flags.CORS_ALLOWED],
|
||||||
disallowed: []
|
disallowed: [],
|
||||||
}, [], false);
|
},
|
||||||
checkFeatures({
|
[],
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
checkFeatures(
|
||||||
|
{
|
||||||
requires: [flags.CORS_ALLOWED, flags.IP_LOCKED],
|
requires: [flags.CORS_ALLOWED, flags.IP_LOCKED],
|
||||||
disallowed: []
|
disallowed: [],
|
||||||
}, [flags.CORS_ALLOWED, flags.IP_LOCKED], true);
|
},
|
||||||
checkFeatures({
|
[flags.CORS_ALLOWED, flags.IP_LOCKED],
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
checkFeatures(
|
||||||
|
{
|
||||||
requires: [flags.IP_LOCKED],
|
requires: [flags.IP_LOCKED],
|
||||||
disallowed: []
|
disallowed: [],
|
||||||
}, [flags.CORS_ALLOWED], false);
|
},
|
||||||
checkFeatures({
|
[flags.CORS_ALLOWED],
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
checkFeatures(
|
||||||
|
{
|
||||||
requires: [flags.IP_LOCKED],
|
requires: [flags.IP_LOCKED],
|
||||||
disallowed: []
|
disallowed: [],
|
||||||
}, [], false);
|
},
|
||||||
|
[],
|
||||||
|
false,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should check disallowed correctly', () => {
|
it('should check disallowed correctly', () => {
|
||||||
checkFeatures({
|
checkFeatures(
|
||||||
|
{
|
||||||
requires: [],
|
requires: [],
|
||||||
disallowed: []
|
disallowed: [],
|
||||||
}, [], true);
|
},
|
||||||
checkFeatures({
|
[],
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
checkFeatures(
|
||||||
|
{
|
||||||
requires: [],
|
requires: [],
|
||||||
disallowed: [flags.CORS_ALLOWED]
|
disallowed: [flags.CORS_ALLOWED],
|
||||||
}, [], true);
|
},
|
||||||
checkFeatures({
|
[],
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
checkFeatures(
|
||||||
|
{
|
||||||
requires: [],
|
requires: [],
|
||||||
disallowed: [flags.CORS_ALLOWED]
|
disallowed: [flags.CORS_ALLOWED],
|
||||||
}, [flags.CORS_ALLOWED], false);
|
},
|
||||||
checkFeatures({
|
[flags.CORS_ALLOWED],
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
checkFeatures(
|
||||||
|
{
|
||||||
requires: [],
|
requires: [],
|
||||||
disallowed: [flags.CORS_ALLOWED]
|
disallowed: [flags.CORS_ALLOWED],
|
||||||
}, [flags.IP_LOCKED], true);
|
},
|
||||||
checkFeatures({
|
[flags.IP_LOCKED],
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
checkFeatures(
|
||||||
|
{
|
||||||
requires: [],
|
requires: [],
|
||||||
disallowed: [flags.CORS_ALLOWED, flags.IP_LOCKED]
|
disallowed: [flags.CORS_ALLOWED, flags.IP_LOCKED],
|
||||||
}, [flags.CORS_ALLOWED], false);
|
},
|
||||||
|
[flags.CORS_ALLOWED],
|
||||||
|
false,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should pass mixed tests', () => {
|
it('should pass mixed tests', () => {
|
||||||
checkFeatures({
|
checkFeatures(
|
||||||
|
{
|
||||||
requires: [flags.CORS_ALLOWED],
|
requires: [flags.CORS_ALLOWED],
|
||||||
disallowed: [flags.IP_LOCKED]
|
disallowed: [flags.IP_LOCKED],
|
||||||
}, [], false);
|
},
|
||||||
checkFeatures({
|
[],
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
checkFeatures(
|
||||||
|
{
|
||||||
requires: [flags.CORS_ALLOWED],
|
requires: [flags.CORS_ALLOWED],
|
||||||
disallowed: [flags.IP_LOCKED]
|
disallowed: [flags.IP_LOCKED],
|
||||||
}, [flags.CORS_ALLOWED], true);
|
},
|
||||||
checkFeatures({
|
[flags.CORS_ALLOWED],
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
checkFeatures(
|
||||||
|
{
|
||||||
requires: [flags.CORS_ALLOWED],
|
requires: [flags.CORS_ALLOWED],
|
||||||
disallowed: [flags.IP_LOCKED]
|
disallowed: [flags.IP_LOCKED],
|
||||||
}, [flags.IP_LOCKED], false);
|
},
|
||||||
checkFeatures({
|
[flags.IP_LOCKED],
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
checkFeatures(
|
||||||
|
{
|
||||||
requires: [flags.CORS_ALLOWED],
|
requires: [flags.CORS_ALLOWED],
|
||||||
disallowed: [flags.IP_LOCKED]
|
disallowed: [flags.IP_LOCKED],
|
||||||
}, [flags.IP_LOCKED, flags.CORS_ALLOWED], false);
|
},
|
||||||
|
[flags.IP_LOCKED, flags.CORS_ALLOWED],
|
||||||
|
false,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
import { reorderOnIdList } from "@/utils/list";
|
import { reorderOnIdList } from '@/utils/list';
|
||||||
import { describe, it, expect } from "vitest";
|
import { describe, it, expect } from 'vitest';
|
||||||
|
|
||||||
function list(def: string) {
|
function list(def: string) {
|
||||||
return def.split(",").map(v=>({
|
return def.split(',').map((v) => ({
|
||||||
rank: parseInt(v),
|
rank: parseInt(v),
|
||||||
id: v,
|
id: v,
|
||||||
}))
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
function expectListToEqual(l1: ReturnType<typeof list>, l2: ReturnType<typeof list>) {
|
function expectListToEqual(l1: ReturnType<typeof list>, l2: ReturnType<typeof list>) {
|
||||||
function flatten(l: ReturnType<typeof list>) {
|
function flatten(l: ReturnType<typeof list>) {
|
||||||
return l.map(v=>v.id).join(",");
|
return l.map((v) => v.id).join(',');
|
||||||
}
|
}
|
||||||
expect(flatten(l1)).toEqual(flatten(l2));
|
expect(flatten(l1)).toEqual(flatten(l2));
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ function expectListToEqual(l1: ReturnType<typeof list>, l2: ReturnType<typeof li
|
||||||
describe('reorderOnIdList()', () => {
|
describe('reorderOnIdList()', () => {
|
||||||
it('should reorder based on rank', () => {
|
it('should reorder based on rank', () => {
|
||||||
const l = list('2,1,4,3');
|
const l = list('2,1,4,3');
|
||||||
const sortedList = list('4,3,2,1')
|
const sortedList = list('4,3,2,1');
|
||||||
expectListToEqual(reorderOnIdList([], l), sortedList);
|
expectListToEqual(reorderOnIdList([], l), sortedList);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -28,26 +28,26 @@ describe('reorderOnIdList()', () => {
|
||||||
|
|
||||||
it('should reorder based on id list', () => {
|
it('should reorder based on id list', () => {
|
||||||
const l = list('4,2,1,3');
|
const l = list('4,2,1,3');
|
||||||
const sortedList = list('4,3,2,1')
|
const sortedList = list('4,3,2,1');
|
||||||
expectListToEqual(reorderOnIdList(["4","3","2","1"], l), sortedList);
|
expectListToEqual(reorderOnIdList(['4', '3', '2', '1'], l), sortedList);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should reorder based on id list and rank second', () => {
|
it('should reorder based on id list and rank second', () => {
|
||||||
const l = list('4,2,1,3');
|
const l = list('4,2,1,3');
|
||||||
const sortedList = list('4,3,2,1')
|
const sortedList = list('4,3,2,1');
|
||||||
expectListToEqual(reorderOnIdList(["4","3"], l), sortedList);
|
expectListToEqual(reorderOnIdList(['4', '3'], l), sortedList);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work with only one item', () => {
|
it('should work with only one item', () => {
|
||||||
const l = list('1');
|
const l = list('1');
|
||||||
const sortedList = list('1')
|
const sortedList = list('1');
|
||||||
expectListToEqual(reorderOnIdList(["1"], l), sortedList);
|
expectListToEqual(reorderOnIdList(['1'], l), sortedList);
|
||||||
expectListToEqual(reorderOnIdList([], l), sortedList);
|
expectListToEqual(reorderOnIdList([], l), sortedList);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not affect original list', () => {
|
it('should not affect original list', () => {
|
||||||
const l = list('4,3,2,1');
|
const l = list('4,3,2,1');
|
||||||
const unsortedList = list('4,3,2,1')
|
const unsortedList = list('4,3,2,1');
|
||||||
reorderOnIdList([], l);
|
reorderOnIdList([], l);
|
||||||
expectListToEqual(l, unsortedList);
|
expectListToEqual(l, unsortedList);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,65 +1,71 @@
|
||||||
import { makeStandardFetcher } from "@/fetchers/standardFetch";
|
import { isValidStream } from '@/utils/valid';
|
||||||
import { makeProviders } from "@/main/builder";
|
import { describe, it, expect } from 'vitest';
|
||||||
import { targets } from "@/main/targets";
|
|
||||||
import { isValidStream } from "@/utils/valid";
|
|
||||||
import fetch from "node-fetch";
|
|
||||||
import { describe, it, expect } from "vitest";
|
|
||||||
|
|
||||||
describe('isValidStream()', () => {
|
describe('isValidStream()', () => {
|
||||||
it('should pass valid streams', () => {
|
it('should pass valid streams', () => {
|
||||||
expect(isValidStream({
|
expect(
|
||||||
type: "file",
|
isValidStream({
|
||||||
id: "a",
|
type: 'file',
|
||||||
|
id: 'a',
|
||||||
flags: [],
|
flags: [],
|
||||||
captions: [],
|
captions: [],
|
||||||
qualities: {
|
qualities: {
|
||||||
"1080": {
|
'1080': {
|
||||||
type: "mp4",
|
type: 'mp4',
|
||||||
url: "hello-world"
|
url: 'hello-world',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})).toBe(true);
|
}),
|
||||||
expect(isValidStream({
|
).toBe(true);
|
||||||
type: "hls",
|
expect(
|
||||||
id: "a",
|
isValidStream({
|
||||||
|
type: 'hls',
|
||||||
|
id: 'a',
|
||||||
flags: [],
|
flags: [],
|
||||||
captions: [],
|
captions: [],
|
||||||
playlist: "hello-world"
|
playlist: 'hello-world',
|
||||||
})).toBe(true);
|
}),
|
||||||
|
).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should detect empty qualities', () => {
|
it('should detect empty qualities', () => {
|
||||||
expect(isValidStream({
|
expect(
|
||||||
type: "file",
|
isValidStream({
|
||||||
id: "a",
|
type: 'file',
|
||||||
|
id: 'a',
|
||||||
flags: [],
|
flags: [],
|
||||||
captions: [],
|
captions: [],
|
||||||
qualities: {}
|
qualities: {},
|
||||||
})).toBe(false);
|
}),
|
||||||
|
).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should detect empty stream urls', () => {
|
it('should detect empty stream urls', () => {
|
||||||
expect(isValidStream({
|
expect(
|
||||||
type: "file",
|
isValidStream({
|
||||||
id: "a",
|
type: 'file',
|
||||||
|
id: 'a',
|
||||||
flags: [],
|
flags: [],
|
||||||
captions: [],
|
captions: [],
|
||||||
qualities: {
|
qualities: {
|
||||||
"1080": {
|
'1080': {
|
||||||
type: "mp4",
|
type: 'mp4',
|
||||||
url: "",
|
url: '',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})).toBe(false);
|
}),
|
||||||
|
).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should detect emtpy HLS playlists', () => {
|
it('should detect emtpy HLS playlists', () => {
|
||||||
expect(isValidStream({
|
expect(
|
||||||
type: "hls",
|
isValidStream({
|
||||||
id: "a",
|
type: 'hls',
|
||||||
|
id: 'a',
|
||||||
flags: [],
|
flags: [],
|
||||||
captions: [],
|
captions: [],
|
||||||
playlist: "",
|
playlist: '',
|
||||||
})).toBe(false);
|
}),
|
||||||
|
).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -179,7 +179,11 @@ async function runCommandLine() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process.argv.length === 2) {
|
if (process.argv.length === 2) {
|
||||||
runQuestions().catch(() => console.error('Exited.'));
|
runQuestions()
|
||||||
|
.catch(() => console.error('Exited.'))
|
||||||
|
.finally(() => process.exit(0));
|
||||||
} else {
|
} else {
|
||||||
runCommandLine().catch(() => console.error('Exited.'));
|
runCommandLine()
|
||||||
|
.catch(() => console.error('Exited.'))
|
||||||
|
.finally(() => process.exit(0));
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ async function runBrowserScraping(
|
||||||
source: MetaOutput,
|
source: MetaOutput,
|
||||||
options: CommandLineArguments,
|
options: CommandLineArguments,
|
||||||
) {
|
) {
|
||||||
if (!existsSync(join(__dirname, '../../lib/index.mjs')))
|
if (!existsSync(join(__dirname, '../../lib/index.js')))
|
||||||
throw new Error('Please compile before running cli in browser mode');
|
throw new Error('Please compile before running cli in browser mode');
|
||||||
const config = getConfig();
|
const config = getConfig();
|
||||||
if (!config.proxyUrl)
|
if (!config.proxyUrl)
|
||||||
|
@ -37,13 +37,15 @@ async function runBrowserScraping(
|
||||||
root,
|
root,
|
||||||
});
|
});
|
||||||
browser = await puppeteer.launch({
|
browser = await puppeteer.launch({
|
||||||
headless: 'new',
|
headless: true,
|
||||||
args: ['--no-sandbox', '--disable-setuid-sandbox'],
|
args: ['--no-sandbox', '--disable-setuid-sandbox'],
|
||||||
});
|
});
|
||||||
const page = await browser.newPage();
|
const page = await browser.newPage();
|
||||||
// This is the dev cli, so we can use console.log
|
// This is the dev cli, so we can use console.log
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
page.on('console', (message) => console.log(`${message.type().slice(0, 3).toUpperCase()} ${message.text()}`));
|
page.on('console', (message) => console.log(`${message.type().slice(0, 3).toUpperCase()} ${message.text()}`));
|
||||||
|
|
||||||
|
if (!server.resolvedUrls?.local.length) throw new Error('Server did not start');
|
||||||
await page.goto(server.resolvedUrls.local[0]);
|
await page.goto(server.resolvedUrls.local[0]);
|
||||||
await page.waitForFunction('!!window.scrape', { timeout: 5000 });
|
await page.waitForFunction('!!window.scrape', { timeout: 5000 });
|
||||||
|
|
||||||
|
|
|
@ -146,13 +146,16 @@ export const streamsbScraper = makeEmbed({
|
||||||
|
|
||||||
ctx.progress(80);
|
ctx.progress(80);
|
||||||
|
|
||||||
const qualities = dls.reduce((a, v) => {
|
const qualities = dls.reduce(
|
||||||
|
(a, v) => {
|
||||||
a[v.quality] = {
|
a[v.quality] = {
|
||||||
type: 'mp4',
|
type: 'mp4',
|
||||||
url: v.url as string,
|
url: v.url as string,
|
||||||
};
|
};
|
||||||
return a;
|
return a;
|
||||||
}, {} as Record<string, StreamFile>);
|
},
|
||||||
|
{} as Record<string, StreamFile>,
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
stream: [
|
stream: [
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { makeProviders, makeStandardFetcher, targets } from '../../lib/index.mjs';
|
import { makeProviders, makeStandardFetcher, targets } from '../../lib/index.js';
|
||||||
|
|
||||||
(window as any).TEST = () => {
|
(window as any).TEST = () => {
|
||||||
makeProviders({
|
makeProviders({
|
||||||
|
|
|
@ -29,3 +29,4 @@ try {
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Success!');
|
console.log('Success!');
|
||||||
|
process.exit(0);
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
require('../../lib/index.umd');
|
require('../../lib/index.umd.cjs');
|
||||||
console.log('import successful!');
|
console.log('import successful!');
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
import '../../lib/index.mjs';
|
import '../../lib/index.js';
|
||||||
console.log('import successful!');
|
console.log('import successful!');
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es2021",
|
"target": "es2021",
|
||||||
"lib": ["es2021", "DOM"],
|
"lib": ["es2021", "DOM"],
|
||||||
"module": "CommonJS",
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "Bundler",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"outDir": "./lib",
|
"outDir": "./lib",
|
||||||
|
@ -11,14 +12,12 @@
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"isolatedModules": false,
|
"isolatedModules": false,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["./*"],
|
"@/*": ["./*"],
|
||||||
"@entrypoint": ["./index.ts"]
|
"@entrypoint": ["./index.ts"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": ["src"],
|
"include": ["src", "vite.config.ts"],
|
||||||
"exclude": ["node_modules", "**/__test__"],
|
"exclude": ["node_modules", "**/__test__"]
|
||||||
"ts-node": {
|
|
||||||
"require": ["tsconfig-paths/register"]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
const path = require('path');
|
|
||||||
const { defineConfig } = require('vitest/config');
|
|
||||||
const { default: eslint } = require('vite-plugin-eslint');
|
|
||||||
const dts = require('vite-plugin-dts');
|
|
||||||
const pkg = require('./package.json');
|
|
||||||
const fs = require('fs/promises');
|
|
||||||
|
|
||||||
const shouldTestProviders = process.env.MW_TEST_PROVIDERS === "true"
|
|
||||||
let tests = ['src/__test__/standard/**/*.test.ts'];
|
|
||||||
if (shouldTestProviders) tests = ['src/__test__/providers/**/*.test.ts']
|
|
||||||
|
|
||||||
module.exports = defineConfig({
|
|
||||||
plugins: [
|
|
||||||
eslint(),
|
|
||||||
dts({
|
|
||||||
rollupTypes: true,
|
|
||||||
async afterBuild() {
|
|
||||||
const filePath = path.join(__dirname, './lib/index.d.ts');
|
|
||||||
await fs.writeFile(filePath.replace('.d.ts', '.d.mts'), await fs.readFile(filePath, 'utf-8'), 'utf-8');
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
resolve: {
|
|
||||||
alias: {
|
|
||||||
'@': path.resolve(__dirname, './src'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
build: {
|
|
||||||
minify: false,
|
|
||||||
rollupOptions: {
|
|
||||||
external: Object.keys(pkg.dependencies),
|
|
||||||
output: {
|
|
||||||
globals: Object.fromEntries(Object.keys(pkg.dependencies).map((v) => [v, v])),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
outDir: 'lib',
|
|
||||||
|
|
||||||
lib: {
|
|
||||||
entry: path.resolve(__dirname, 'src/index.ts'),
|
|
||||||
name: 'index',
|
|
||||||
fileName: 'index',
|
|
||||||
formats: ['umd', 'es'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
test: {
|
|
||||||
include: tests
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
import path from 'path';
|
||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
import eslintPlugin from '@nabla/vite-plugin-eslint';
|
||||||
|
import dts from 'vite-plugin-dts';
|
||||||
|
import pkg from './package.json';
|
||||||
|
|
||||||
|
const shouldTestProviders = process.env.MW_TEST_PROVIDERS === 'true';
|
||||||
|
let tests: string[] = ['src/__test__/standard/**/*.test.ts'];
|
||||||
|
if (shouldTestProviders) tests = ['src/__test__/providers/**/*.test.ts'];
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [
|
||||||
|
eslintPlugin({}),
|
||||||
|
dts({
|
||||||
|
rollupTypes: true,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': path.resolve(__dirname, './src'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
minify: false,
|
||||||
|
rollupOptions: {
|
||||||
|
external: Object.keys(pkg.dependencies),
|
||||||
|
output: {
|
||||||
|
globals: Object.fromEntries(Object.keys(pkg.dependencies).map((v) => [v, v])),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
outDir: 'lib',
|
||||||
|
lib: {
|
||||||
|
entry: path.resolve(__dirname, 'src/index.ts'),
|
||||||
|
name: 'index',
|
||||||
|
fileName: 'index',
|
||||||
|
formats: ['umd', 'es'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
test: {
|
||||||
|
include: tests,
|
||||||
|
},
|
||||||
|
});
|
Loading…
Reference in New Issue