Merge branch 'dev' into better-int-testing
This commit is contained in:
commit
d0dcd9cc7d
|
@ -0,0 +1,4 @@
|
|||
dist
|
||||
node_modules
|
||||
.output
|
||||
.nuxt
|
|
@ -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'
|
||||
}
|
||||
}
|
|
@ -1,3 +1,13 @@
|
|||
node_modules
|
||||
.vitepress/cache
|
||||
.vitepress/dist
|
||||
*.iml
|
||||
.idea
|
||||
*.log*
|
||||
.nuxt
|
||||
.vscode
|
||||
.DS_Store
|
||||
coverage
|
||||
dist
|
||||
sw.*
|
||||
.env
|
||||
.output
|
||||
.nuxt
|
||||
|
|
|
@ -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' }
|
||||
]
|
||||
}
|
||||
})
|
|
@ -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,
|
||||
},
|
||||
},
|
||||
});
|
|
@ -0,0 +1,3 @@
|
|||
code > span {
|
||||
white-space: pre;
|
||||
}
|
|
@ -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.
|
||||
::
|
||||
::
|
|
@ -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}`)
|
||||
```
|
|
@ -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
|
|
@ -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.
|
|
@ -0,0 +1,2 @@
|
|||
icon: ph:book-open-fill
|
||||
navigation.redirect: /guide/usage
|
|
@ -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;
|
||||
}
|
||||
```
|
|
@ -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;
|
||||
};
|
||||
```
|
|
@ -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;
|
||||
};
|
||||
```
|
|
@ -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;
|
||||
};
|
||||
```
|
|
@ -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>;
|
||||
};
|
||||
```
|
|
@ -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>;
|
||||
};
|
||||
```
|
|
@ -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>;
|
||||
};
|
||||
```
|
|
@ -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;
|
||||
```
|
|
@ -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;
|
||||
```
|
|
@ -0,0 +1,2 @@
|
|||
icon: ph:file-code-fill
|
||||
navigation.redirect: /api/makeproviders
|
|
@ -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'
|
||||
]
|
||||
})
|
File diff suppressed because it is too large
Load Diff
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"extends": [
|
||||
"@nuxtjs"
|
||||
],
|
||||
"lockFileMaintenance": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
|
@ -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).
|
|
@ -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)
|
||||
---
|
||||
|
||||
|
|
@ -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).
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
})
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"extends": "./.nuxt/tsconfig.json"
|
||||
}
|
|
@ -7,28 +7,33 @@ on:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
|
||||
- name: Install packages
|
||||
run: cd .docs && npm ci
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
|
||||
- name: Build
|
||||
run: cd .docs && npm run build
|
||||
- name: Install packages
|
||||
working-directory: ./.docs
|
||||
run: npm install
|
||||
|
||||
- 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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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>;
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue