Merge branch 'dev' into better-int-testing

This commit is contained in:
William Oldham 2023-09-28 18:54:12 +01:00 committed by GitHub
commit d0dcd9cc7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 19759 additions and 593 deletions

4
.docs/.eslintignore Normal file
View File

@ -0,0 +1,4 @@
dist
node_modules
.output
.nuxt

8
.docs/.eslintrc.cjs Normal file
View File

@ -0,0 +1,8 @@
module.exports = {
root: true,
extends: '@nuxt/eslint-config',
rules: {
'vue/max-attributes-per-line': 'off',
'vue/multi-word-component-names': 'off'
}
}

14
.docs/.gitignore vendored Normal file → Executable file
View File

@ -1,3 +1,13 @@
node_modules
.vitepress/cache
.vitepress/dist
*.iml
.idea
*.log*
.nuxt
.vscode
.DS_Store
coverage
dist
sw.*
.env
.output
.nuxt

View File

@ -1,28 +0,0 @@
import { defineConfig } from 'vitepress'
export default defineConfig({
title: "MW provider docs",
description: "Documentation for @movie-web/providers",
srcDir: "src",
themeConfig: {
nav: [
{ text: 'Home', link: '/' },
{ text: 'Get Started', link: '/get-started/start' },
{ text: 'Reference', link: '/reference/start' }
],
sidebar: [
{
text: 'Examples',
items: [
{ text: 'Markdown Examples', link: '/markdown-examples' },
{ text: 'Runtime API Examples', link: '/api-examples' }
]
}
],
socialLinks: [
{ icon: 'github', link: 'https://github.com/movie-web/providers' }
]
}
})

17
.docs/app.config.ts Normal file
View File

@ -0,0 +1,17 @@
export default defineAppConfig({
docus: {
title: '@movie-web/providers',
description: 'For all your media scraping needs',
socials: {
github: 'movie-web/providers',
},
image: '',
aside: {
level: 0,
exclude: [],
},
header: {
logo: false,
},
},
});

View File

@ -0,0 +1,3 @@
code > span {
white-space: pre;
}

51
.docs/content/0.index.md Normal file
View File

@ -0,0 +1,51 @@
---
title: "@movie-web/providers | For all your media scraping needs"
navigation: false
layout: page
---
::block-hero
---
cta:
- Get Started
- /guide/usage
secondary:
- Open on GitHub →
- https://github.com/movie-web/providers
snippet: npm i @movie-web/providers
---
#title
@movie-web/providers
#description
Easily scrape all sorts of media sites for content
::
::card-grid
#title
What's included
#root
:ellipsis
#default
::card{icon="vscode-icons:file-type-light-json"}
#title
Scrape popular streaming websites.
#description
Don't settle for just one media site for you content, use everything that's available.
::
::card{icon="codicon:source-control"}
#title
Multi-platform.
#description
Scrape from browser or server, whichever you prefer.
::
::card{icon="logos:typescript-icon-round"}
#title
Easy to use.
#description
Get started with scraping your favourite media sites with just 5 lines of code. Fully typed of course.
::
::

View File

@ -0,0 +1,53 @@
# Usage
Let's get started with `@movie-web/providers`. First lets install the package.
::code-group
```bash [NPM]
npm install @movie-web/providers
```
```bash [Yarn]
yarn add @movie-web/providers
```
```bash [PNPM]
pnpm install @movie-web/providers
```
::
## Scrape your first item
To get started with scraping on the **server**, first you have to make an instance of the providers.
```ts
import { makeProviders, makeDefaultFetcher, targets } from '@movie-web/providers';
// this is how the library will make http requests
const myFetcher = makeDefaultFetcher(fetch);
// make an instance of the providers library
const providers = makeProviders({
fetcher: myFetcher,
// will be played on a native video player
target: targets.NATIVE
})
```
Perfect, now we can start scraping a stream:
```ts [index.ts (server)]
// fetch some data from TMDB
const media = {
type: 'movie',
title: "Hamilton",
releaseYear: 2020,
tmdbId: "556574"
}
const output = await providers.runAll({
media: media
})
if (!output) console.log("No stream found")
console.log(`stream url: ${output.stream.playlist}`)
```

View File

@ -0,0 +1,13 @@
# Targets
When making an instance of the library using `makeProviders()`. It will immediately require choosing a target.
::alert{type="info"}
A target is the device where the stream will be played on.
**Where the scraping is run has nothing to do with the target**, only where the stream is finally played in the end is significant in choosing a target.
::
#### Possible targets
- **`targets.BROWSER`** Stream will be played in a browser with CORS
- **`targets.NATIVE`** Stream will be played natively
- **`targets.ALL`** Stream will be played on a device with no restrictions of any kind

View File

@ -0,0 +1,47 @@
# Fetchers
When making an instance of the library using `makeProviders()`. It will immediately make a fetcher.
This comes with some considerations depending on the environment youre running.
## Using `fetch()`
In most cases, you can use the `fetch()` API. This will work in newer versions of Node.js (18 and above) and on the browser.
```ts
const fetcher = makeDefaultFetcher(fetch);
```
If you using older version of Node.js. You can use the npm package `node-fetch` to polyfill fetch:
```ts
import fetch from "node-fetch";
const fetcher = makeDefaultFetcher(fetch);
```
## Using fetchers on the browser
When using this library on a browser, you will need a proxy. Browsers come with many restrictions on when a web request can be made, and to bypass those restrictions, you will need a cors proxy.
The movie-web team has a proxy pre-made and pre-configured for you to use. For more information, check out [movie-web/simple-proxy](https://github.com/movie-web/simple-proxy). After installing, you can use this proxy like so:
```ts
const fetcher = makeSimpleProxyFetcher("https://your.proxy.workers.dev/", fetch);
```
If you aren't able to use this specific proxy and need to use a different one, you can make your own fetcher in the next section.
## Making a custom fetcher
In some rare cases, a custom fetcher will need to be made. This can be quite difficult to do from scratch so it's recommended to base it off an existing fetcher and building your own functionality around it.
```ts
export function makeCustomFetcher(): Fetcher {
const fetcher = makeStandardFetcher(f);
const customFetcher: Fetcher = (url, ops) => {
return fetcher(url, ops);
};
return customFetcher;
}
```
If you need to make your own fetcher for a proxy. Make sure you make it compatible with the following headers: `Cookie`, `Referer`, `Origin`. Proxied fetchers need to be able to write those headers when making a request.

View File

@ -0,0 +1,2 @@
icon: ph:book-open-fill
navigation.redirect: /guide/usage

View File

@ -0,0 +1,34 @@
# `makeProviders`
Make an instance of providers with configuration.
This is the main entrypoint of the library. It is recommended to make one instance globally and reuse it throughout your application.
## Example
```ts
import { targets, makeProviders, makeDefaultFetcher } from "@movie-web/providers";
const providers = makeProviders({
fetcher: makeDefaultFetcher(fetch),
target: targets.NATIVE, // target native app streams
});
```
## Type
```ts
function makeProviders(ops: ProviderBuilderOptions): ProviderControls;
interface ProviderBuilderOptions {
// instance of a fetcher, all webrequests are made with the fetcher.
fetcher: Fetcher;
// instance of a fetcher, in case the request has cors restrictions.
// this fetcher will be called instead of normal fetcher.
// if your environment doesnt have cors restrictions (like nodejs), there is no need to set this.
proxiedFetcher?: Fetcher;
// target to get streams for
target: Targets;
}
```

View File

@ -0,0 +1,61 @@
# `ProviderControls.runAll`
Run all providers one by one in order of their built-in ranking.
You can attach events if you need to know what is going on while its processing.
## Example
```ts
// media from TMDB
const media = {
type: 'movie',
title: "Hamilton",
releaseYear: 2020,
tmdbId: "556574"
}
// scrape a stream
const stream = await providers.runAll({
media: media,
})
// scrape a stream, but prioritize flixhq above all
// (other scrapers are stil ran if flixhq fails, it just has priority)
const flixhqStream = await providers.runAll({
media: media,
sourceOrder: ['flixhq']
})
```
## Type
```ts
function runAll(runnerOps: RunnerOptions): Promise<RunOutput | null>;
interface RunnerOptions {
// overwrite the order of sources to run. list of ids
// any omitted ids are in added to the end in order of rank (highest first)
sourceOrder?: string[];
// overwrite the order of embeds to run. list of ids
// any omitted ids are in added to the end in order of rank (highest first)
embedOrder?: string[];
// object of event functions
events?: FullScraperEvents;
// the media you want to see sources from
media: ScrapeMedia;
}
type RunOutput = {
// source scraper id
sourceId: string;
// if from an embed, this is the embed scraper id
embedId?: string;
// the outputed stream
stream: Stream;
};
```

View File

@ -0,0 +1,66 @@
# `ProviderControls.runSourceScraper`
Run a specific source scraper and get its outputted streams.
## Example
```ts
import { SourcererOutput, NotFoundError } from "@movie-web/providers";
// media from TMDB
const media = {
type: 'movie',
title: "Hamilton",
releaseYear: 2020,
tmdbId: "556574"
}
// scrape a stream from flixhq
let output: SourcererOutput;
try {
output = await providers.runSourceScraper({
id: 'flixhq',
media: media,
})
} catch (err) {
if (err instanceof NotFoundError) {
console.log("source doesnt have this media");
} else {
console.log("failed to scrape")
}
return;
}
if (!output.stream && output.embeds.length === 0) {
console.log("no streams found");
}
```
## Type
```ts
function runSourceScraper(runnerOps: SourceRunnerOptions): Promise<SourcererOutput>;
interface SourceRunnerOptions {
// object of event functions
events?: IndividualScraperEvents;
// the media you want to see sources from
media: ScrapeMedia;
// id of the source scraper you want to scrape from
id: string;
}
type SourcererOutput = {
// list of embeds that the source scraper found.
// embed id is a reference to an embed scraper
embeds: {
embedId: string;
url: string;
}[];
// the stream that the scraper found
stream?: Stream;
};
```

View File

@ -0,0 +1,44 @@
# `ProviderControls.runEmbedScraper`
Run a specific embed scraper and get its outputted streams.
## Example
```ts
import { SourcererOutput } from "@movie-web/providers";
// scrape a stream from upcloud
let output: EmbedOutput;
try {
output = await providers.runSourceScraper({
id: 'upcloud',
url: 'https://example.com/123',
})
} catch (err) {
console.log("failed to scrape")
return;
}
// output.stream now has your stream
```
## Type
```ts
function runEmbedScraper(runnerOps: SourceRunnerOptions): Promise<EmbedOutput>;
interface EmbedRunnerOptions {
// object of event functions
events?: IndividualScraperEvents;
// the embed url
url: string;
// id of the embed scraper you want to scrape from
id: string;
}
type EmbedOutput = {
stream: Stream;
};
```

View File

@ -0,0 +1,25 @@
# `ProviderControls.listSources`
List all source scrapers that applicable for the target.
They are sorted by rank, highest first
## Example
```ts
const sourceScrapers = providers.listSources();
// Guaranteed to only return type: 'source'
```
## Type
```ts
function listSources(): MetaOutput[];
type MetaOutput = {
type: 'embed' | 'source';
id: string;
rank: number;
name: string;
mediaTypes?: Array<MediaTypes>;
};
```

View File

@ -0,0 +1,25 @@
# `ProviderControls.listEmbeds`
List all embed scrapers that applicable for the target.
They are sorted by rank, highest first
## Example
```ts
const embedScrapers = providers.listEmbeds();
// Guaranteed to only return type: 'embed'
```
## Type
```ts
function listEmbeds(): MetaOutput[];
type MetaOutput = {
type: 'embed' | 'source';
id: string;
rank: number;
name: string;
mediaTypes?: Array<MediaTypes>;
};
```

View File

@ -0,0 +1,24 @@
# `ProviderControls.getMetadata`
Get meta data for a scraper, can be either source or embed scraper.
Returns null if the `id` is not recognized.
## Example
```ts
const flixhqSource = providers.getMetadata('flixhq');
```
## Type
```ts
function getMetadata(id: string): MetaOutput | null;
type MetaOutput = {
type: 'embed' | 'source';
id: string;
rank: number;
name: string;
mediaTypes?: Array<MediaTypes>;
};
```

View File

@ -0,0 +1,20 @@
# `makeStandardFetcher`
Make a fetcher from a `fetch()` API. It is used for making a instance of providers with `makeProviders()`.
## Example
```ts
import { targets, makeProviders, makeDefaultFetcher } from "@movie-web/providers";
const providers = makeProviders({
fetcher: makeDefaultFetcher(fetch),
target: targets.NATIVE,
});
```
## Type
```ts
function makeDefaultFetcher(fetchApi: typeof fetch): Fetcher;
```

View File

@ -0,0 +1,23 @@
# `makeSimpleProxyFetcher`
Make a fetcher to use with [movie-web/simple-proxy](https://github.com/movie-web/simple-proxy). This is for making a proxiedFetcher, so you can run this library in the browser.
## Example
```ts
import { targets, makeProviders, makeDefaultFetcher, makeSimpleProxyFetcher } from "@movie-web/providers";
const proxyUrl = "https://your.proxy.workers.dev/"
const providers = makeProviders({
fetcher: makeDefaultFetcher(fetch),
proxiedFetcher: makeSimpleProxyFetcher(proxyUrl, fetch),
target: targets.BROWSER,
});
```
## Type
```ts
function makeSimpleProxyFetcher(proxyUrl: string, fetchApi: typeof fetch): Fetcher;
```

View File

@ -0,0 +1,2 @@
icon: ph:file-code-fill
navigation.redirect: /api/makeproviders

21
.docs/nuxt.config.ts Executable file
View File

@ -0,0 +1,21 @@
export default defineNuxtConfig({
// https://github.com/nuxt-themes/docus
extends: '@nuxt-themes/docus',
css: [
'@/assets/css/main.css',
],
build: {
transpile: [
"chalk"
]
},
modules: [
// https://github.com/nuxt-modules/plausible
'@nuxtjs/plausible',
// https://github.com/nuxt/devtools
'@nuxt/devtools'
]
})

19466
.docs/package-lock.json generated

File diff suppressed because it is too large Load Diff

18
.docs/package.json Normal file → Executable file
View File

@ -1,9 +1,21 @@
{
"name": "providers-docs",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "vitepress dev .",
"build": "vitepress build ."
"dev": "nuxi dev",
"build": "nuxi build",
"generate": "nuxi generate",
"preview": "nuxi preview",
"lint": "eslint ."
},
"devDependencies": {
"vitepress": "^1.0.0-rc.10"
"@nuxt-themes/docus": "^1.13.1",
"@nuxt/devtools": "^0.6.7",
"@nuxt/eslint-config": "^0.1.1",
"@nuxtjs/plausible": "^0.2.1",
"@types/node": "^20.4.0",
"eslint": "^8.44.0",
"nuxt": "^3.6.2"
}
}

BIN
.docs/public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

8
.docs/renovate.json Executable file
View File

@ -0,0 +1,8 @@
{
"extends": [
"@nuxtjs"
],
"lockFileMaintenance": {
"enabled": true
}
}

View File

@ -1,49 +0,0 @@
---
outline: deep
---
# Runtime API Examples
This page demonstrates usage of some of the runtime APIs provided by VitePress.
The main `useData()` API can be used to access site, theme, and page data for the current page. It works in both `.md` and `.vue` files:
```md
<script setup>
import { useData } from 'vitepress'
const { theme, page, frontmatter } = useData()
</script>
## Results
### Theme Data
<pre>{{ theme }}</pre>
### Page Data
<pre>{{ page }}</pre>
### Page Frontmatter
<pre>{{ frontmatter }}</pre>
```
<script setup>
import { useData } from 'vitepress'
const { site, theme, page, frontmatter } = useData()
</script>
## Results
### Theme Data
<pre>{{ theme }}</pre>
### Page Data
<pre>{{ page }}</pre>
### Page Frontmatter
<pre>{{ frontmatter }}</pre>
## More
Check out the documentation for the [full list of runtime APIs](https://vitepress.dev/reference/runtime-api#usedata).

View File

@ -1,24 +0,0 @@
---
layout: home
hero:
name: "@movie-web/providers"
tagline: Providers for all kinds of media
actions:
- theme: brand
text: Get Started
link: /get-started/start
- theme: alt
text: reference
link: /reference/start
features:
- title: All the scraping!
icon: '!'
details: scrape popular streaming websites
- title: Client & server
icon: '!'
details: This library can be ran both server-side and client-side (with CORS proxy)
---

View File

@ -1,85 +0,0 @@
# Markdown Extension Examples
This page demonstrates some of the built-in markdown extensions provided by VitePress.
## Syntax Highlighting
VitePress provides Syntax Highlighting powered by [Shiki](https://github.com/shikijs/shiki), with additional features like line-highlighting:
**Input**
````
```js{4}
export default {
data () {
return {
msg: 'Highlighted!'
}
}
}
```
````
**Output**
```js{4}
export default {
data () {
return {
msg: 'Highlighted!'
}
}
}
```
## Custom Containers
**Input**
```md
::: info
This is an info box.
:::
::: tip
This is a tip.
:::
::: warning
This is a warning.
:::
::: danger
This is a dangerous warning.
:::
::: details
This is a details block.
:::
```
**Output**
::: info
This is an info box.
:::
::: tip
This is a tip.
:::
::: warning
This is a warning.
:::
::: danger
This is a dangerous warning.
:::
::: details
This is a details block.
:::
## More
Check out the documentation for the [full list of markdown extensions](https://vitepress.dev/guide/markdown).

18
.docs/tokens.config.ts Normal file
View File

@ -0,0 +1,18 @@
import { defineTheme } from 'pinceau'
export default defineTheme({
color: {
primary: {
50: "#F5E5FF",
100: "#E7CCFF",
200: "#D4A9FF",
300: "#BE85FF",
400: "#A861FF",
500: "#8E3DFF",
600: "#7F36D4",
700: "#662CA6",
800: "#552578",
900: "#441E49"
}
}
})

3
.docs/tsconfig.json Executable file
View File

@ -0,0 +1,3 @@
{
"extends": "./.nuxt/tsconfig.json"
}

View File

@ -7,28 +7,33 @@ on:
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Checkout code
uses: actions/checkout@v3
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: 18
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: 18
- name: Install packages
run: cd .docs && npm ci
- name: Install packages
working-directory: ./.docs
run: npm install
- name: Build
run: cd .docs && npm run build
- name: Build project
working-directory: ./.docs
run: npm run generate
- name: Upload
uses: actions/upload-pages-artifact@v2
with:
path: ./.docs/.vitepress/dist
- name: Upload production-ready build files
uses: actions/upload-pages-artifact@v1
with:
path: ./.docs/.output/public
deploy:
name: Deploy
needs: build
permissions:
pages: write

View File

@ -32,6 +32,3 @@ Example testing the FlixHQ source on the movie "Spirited Away"
```bash
npm run test:dev -- -sid flixhq -tid 129 -t movie
```
Todos:
- make default fetcher maker thing work with both undici and node-fetch

9
package-lock.json generated
View File

@ -32,6 +32,7 @@
"eslint-import-resolver-typescript": "^3.5.5",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-prettier": "^4.2.1",
"node-fetch": "^2.7.0",
"prettier": "^2.6.2",
"spinnies": "^0.5.1",
"ts-node": "^10.9.1",
@ -4724,6 +4725,7 @@
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"dev": true,
"dependencies": {
"whatwg-url": "^5.0.0"
},
@ -4742,17 +4744,20 @@
"node_modules/node-fetch/node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"dev": true
},
"node_modules/node-fetch/node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
"dev": true
},
"node_modules/node-fetch/node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"dev": true,
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"

View File

@ -72,7 +72,8 @@
"vite": "^4.0.0",
"vite-plugin-dts": "^3.5.3",
"vite-plugin-eslint": "^1.8.1",
"vitest": "^0.32.2"
"vitest": "^0.32.2",
"node-fetch": "^2.7.0"
},
"dependencies": {
"cheerio": "^1.0.0-rc.12",

View File

@ -1,11 +1,9 @@
// eslint-disable-next-line import/no-extraneous-dependencies
/* eslint import/no-extraneous-dependencies: ["error", {"devDependencies": true}] */
import { program } from 'commander';
// eslint-disable-next-line import/no-extraneous-dependencies
import dotenv from 'dotenv';
// eslint-disable-next-line import/no-extraneous-dependencies
import { prompt } from 'enquirer';
import nodeFetch from 'node-fetch';
// eslint-disable-next-line import/no-extraneous-dependencies
import Spinnies from 'spinnies';
import { MetaOutput, MovieMedia, ProviderControls, ShowMedia, makeProviders, makeStandardFetcher, targets } from '.';
@ -278,7 +276,7 @@ async function processOptions(options: CommandLineArguments) {
let fetcher;
if (options.fetcher === 'native') {
fetcher = makeStandardFetcher(fetch as any);
fetcher = makeStandardFetcher(fetch);
} else {
fetcher = makeStandardFetcher(nodeFetch);
}

22
src/fetchers/fetch.ts Normal file
View File

@ -0,0 +1,22 @@
/**
* This file is a very relaxed definition of the fetch api
* Only containing what we need for it to function.
*/
export type FetchOps = {
headers: Record<string, string>;
method: string;
body: any;
};
export type FetchHeaders = {
get(key: string): string | null;
};
export type FetchReply = {
text(): Promise<string>;
json(): Promise<any>;
headers: FetchHeaders;
};
export type FetchLike = (url: string, ops?: FetchOps | undefined) => Promise<FetchReply>;

View File

@ -1,6 +1,5 @@
import fetch from 'node-fetch';
import { makeFullUrl } from '@/fetchers/common';
import { FetchLike } from '@/fetchers/fetch';
import { makeStandardFetcher } from '@/fetchers/standardFetch';
import { Fetcher } from '@/fetchers/types';
@ -10,7 +9,7 @@ const headerMap: Record<string, string> = {
origin: 'X-Origin',
};
export function makeSimpleProxyFetcher(proxyUrl: string, f: typeof fetch): Fetcher {
export function makeSimpleProxyFetcher(proxyUrl: string, f: FetchLike): Fetcher {
const fetcher = makeStandardFetcher(f);
const proxiedFetch: Fetcher = async (url, ops) => {
const fullUrl = makeFullUrl(url, ops);

View File

@ -1,10 +1,9 @@
import fetch from 'node-fetch';
import { serializeBody } from '@/fetchers/body';
import { makeFullUrl } from '@/fetchers/common';
import { FetchLike } from '@/fetchers/fetch';
import { Fetcher } from '@/fetchers/types';
export function makeStandardFetcher(f: typeof fetch): Fetcher {
export function makeStandardFetcher(f: FetchLike): Fetcher {
const normalFetch: Fetcher = async (url, ops) => {
const fullUrl = makeFullUrl(url, ops);
const seralizedBody = serializeBody(ops.body);

View File

@ -7,6 +7,7 @@ export type Flags = (typeof flags)[keyof typeof flags];
export const targets = {
BROWSER: 'browser',
NATIVE: 'native',
ALL: 'all',
} as const;
export type Targets = (typeof targets)[keyof typeof targets];
@ -22,6 +23,9 @@ export const targetToFeatures: Record<Targets, FeatureMap> = {
native: {
requires: [],
},
all: {
requires: [],
},
} as const;
export function getTargetFeatures(target: Targets): FeatureMap {