Add vitepress documentation site

This commit is contained in:
Jerome Thayananthajothy 2024-09-30 20:46:03 +01:00
parent 05bb7db8f5
commit fe5782e10f
15 changed files with 1639 additions and 169 deletions

View File

@ -13,6 +13,8 @@ Whether you're building small APIs or large-scale systems with high concurrency
Make sure to check out [Matrix](https://github.com/Thavarshan/matrix) for more information on how FetchPHP is powered by PHP Fibers.
Full documentation can be found [here](./docs)
---
### **Why Choose FetchPHP Over Guzzle?**
@ -47,6 +49,8 @@ Heres a breakdown of FetchPHPs underlying async task management powered by
---
> **Note**: The `fetch()` function allows for flexible HTTP request handling. When a URL is provided, it immediately sends the request. When no URL is provided, it returns a `ClientHandler` instance to enable further chaining for advanced request configuration.
#### **Example: Managing Asynchronous Tasks with FetchPHP**
```php
@ -171,7 +175,17 @@ async(fn () => fetch('https://example.com', [
### **Using the Fluent API**
The **fluent API** allows for a more flexible and readable way of building and sending HTTP requests:
FetchPHPs fluent API provides the following methods for building requests:
- `withToken()`: Attach a Bearer token to the request.
- `withAuth()`: Attach basic authentication credentials.
- `withHeaders()`: Add headers to the request.
- `withBody()`: Add a request body (e.g., JSON, form data).
- `withProxy()`: Specify a proxy server for the request.
- `withCookies()`: Attach cookies to the request.
- `withQueryParameters()`: Add query parameters to the request URL.
- `timeout()`: Set the timeout for the request.
- `retry()`: Set the number of retries and delay for failed requests.
#### **Synchronous Example**

View File

@ -5,24 +5,34 @@ export default defineConfig({
title: "Fetch PHP",
description: "The JavaScript fetch API for PHP.",
themeConfig: {
// https://vitepress.dev/reference/default-theme-config
nav: [
{ text: 'Home', link: '/' },
{ text: 'Examples', link: '/markdown-examples' }
{ text: 'Guide', link: '/guide/getting-started' },
{ text: 'API Reference', link: '/api/' }
],
sidebar: [
{
text: 'Examples',
items: [
{ text: 'Markdown Examples', link: '/markdown-examples' },
{ text: 'Runtime API Examples', link: '/api-examples' }
]
}
],
socialLinks: [
{ icon: 'github', link: 'https://github.com/vuejs/vitepress' }
]
sidebar: {
'/guide/': [
{
text: 'Guide',
items: [
{ text: 'Getting Started', link: '/guide/getting-started' },
{ text: 'Installation', link: '/guide/installation' },
{ text: 'Synchronous Requests', link: '/guide/sync-requests' },
{ text: 'Asynchronous Requests', link: '/guide/async-requests' },
{ text: 'Error Handling', link: '/guide/error-handling' },
]
}
],
'/api/': [
{
text: 'API Reference',
items: [
{ text: 'Overview', link: '/api/' },
{ text: 'fetch()', link: '/api/fetch' },
{ text: 'ClientHandler', link: '/api/client-handler' },
{ text: 'Response', link: '/api/response' }
]
}
]
}
}
});

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).

300
docs/api/client-handler.md Normal file
View File

@ -0,0 +1,300 @@
# `ClientHandler` Class API Reference
The `ClientHandler` class in FetchPHP provides a fluent API for building and sending HTTP requests. This class allows you to easily configure requests by chaining methods like `withHeaders()`, `withBody()`, `withToken()`, and more. It supports both synchronous and asynchronous requests, allowing flexible request handling based on your application's needs.
## Class Definition
```php
namespace Fetch\Http;
use Fetch\Interfaces\ClientHandler as ClientHandlerInterface;
class ClientHandler implements ClientHandlerInterface
```
The `ClientHandler` class is responsible for managing HTTP requests and providing methods to set various request options. It supports:
- Fluent API for constructing requests.
- Built-in retry and timeout mechanisms.
- Handling synchronous and asynchronous requests.
- Full support for configuring headers, body, query parameters, and more.
## Constructor
```php
public function __construct(
?ClientInterface $syncClient = null,
array $options = [],
?int $timeout = null,
?int $retries = null,
?int $retryDelay = null,
bool $isAsync = false
)
```
### Parameters
- **`$syncClient`** (ClientInterface|null): The synchronous HTTP client, typically an instance of Guzzles `Client`.
- **`$options`** (array): An array of options to configure the request, such as headers, method, etc.
- **`$timeout`** (int|null): Timeout in seconds for the request.
- **`$retries`** (int|null): Number of retries for the request in case of failure.
- **`$retryDelay`** (int|null): Delay in milliseconds between retries.
- **`$isAsync`** (bool): Indicates whether the request should be asynchronous.
## Available Methods
### **`handle()`**
```php
public static function handle(string $method, string $uri, array $options = []): mixed
```
Executes the HTTP request based on the provided method, URI, and options.
- **`$method`**: HTTP method (e.g., `GET`, `POST`).
- **`$uri`**: The URI for the request.
- **`$options`**: An array of request options.
**Returns**: A response object for synchronous requests or an `AsyncHelper` for asynchronous requests.
### **`baseUri()`**
```php
public function baseUri(string $baseUri): self
```
Sets the base URI for the request.
- **`$baseUri`**: The base URL for the request.
**Returns**: The `ClientHandler` instance for chaining.
### **`withHeaders()`**
```php
public function withHeaders(array $headers): self
```
Sets the headers for the request.
- **`$headers`**: An associative array of headers, where the key is the header name and the value is the header value.
**Returns**: The `ClientHandler` instance for chaining.
### **`withBody()`**
```php
public function withBody(mixed $body): self
```
Sets the request body.
- **`$body`**: The content of the body, which could be a string, array (for JSON), or other data.
**Returns**: The `ClientHandler` instance for chaining.
### **`withQueryParameters()`**
```php
public function withQueryParameters(array $queryParams): self
```
Adds query parameters to the request URL.
- **`$queryParams`**: An associative array of query parameters.
**Returns**: The `ClientHandler` instance for chaining.
### **`withToken()`**
```php
public function withToken(string $token): self
```
Adds a Bearer token for authentication.
- **`$token`**: The Bearer token string.
**Returns**: The `ClientHandler` instance for chaining.
### **`withAuth()`**
```php
public function withAuth(string $username, string $password): self
```
Adds Basic Authentication credentials.
- **`$username`**: Username for authentication.
- **`$password`**: Password for authentication.
**Returns**: The `ClientHandler` instance for chaining.
### **`timeout()`**
```php
public function timeout(int $seconds): self
```
Sets the timeout for the request.
- **`$seconds`**: Timeout in seconds.
**Returns**: The `ClientHandler` instance for chaining.
### **`retry()`**
```php
public function retry(int $retries, int $delay = 100): self
```
Configures retry logic for failed requests.
- **`$retries`**: Number of retry attempts.
- **`$delay`**: Delay in milliseconds between retries.
**Returns**: The `ClientHandler` instance for chaining.
### **`async()`**
```php
public function async(): self
```
Marks the request as asynchronous.
**Returns**: The `ClientHandler` instance for chaining.
### **`withProxy()`**
```php
public function withProxy(string|array $proxy): self
```
Sets a proxy server for the request.
- **`$proxy`**: A proxy URL or an array of proxy configurations.
**Returns**: The `ClientHandler` instance for chaining.
### **`withCookies()`**
```php
public function withCookies(bool|CookieJarInterface $cookies): self
```
Adds cookies to the request.
- **`$cookies`**: Either `true` to enable cookies, or an instance of `CookieJarInterface` to manage cookies.
**Returns**: The `ClientHandler` instance for chaining.
### **`withRedirects()`**
```php
public function withRedirects(bool|array $redirects = true): self
```
Configures whether the request should follow redirects.
- **`$redirects`**: Either `true` to follow redirects, or an array of redirect options.
**Returns**: The `ClientHandler` instance for chaining.
### **`withCert()`**
```php
public function withCert(string|array $cert): self
```
Specifies SSL certificates for the request.
- **`$cert`**: A path to the certificate or an array of certificate options.
**Returns**: The `ClientHandler` instance for chaining.
### **`withSslKey()`**
```php
public function withSslKey(string|array $sslKey): self
```
Specifies the SSL key for the request.
- **`$sslKey`**: A path to the SSL key or an array of key options.
**Returns**: The `ClientHandler` instance for chaining.
### **`withStream()`**
```php
public function withStream(bool $stream): self
```
Configures whether the request should be streamed.
- **`$stream`**: `true` to enable streaming.
**Returns**: The `ClientHandler` instance for chaining.
### **`get()`**
```php
public function get(string $uri): mixed
```
Sends a `GET` request.
- **`$uri`**: The URI for the request.
**Returns**: The response for synchronous requests, or `AsyncHelper` for async requests.
### **`post()`**
```php
public function post(string $uri, mixed $body = null): mixed
```
Sends a `POST` request.
- **`$uri`**: The URI for the request.
- **`$body`**: Optional request body.
**Returns**: The response for synchronous requests, or `AsyncHelper` for async requests.
### **`put()`**
```php
public function put(string $uri, mixed $body = null): mixed
```
Sends a `PUT` request.
- **`$uri`**: The URI for the request.
- **`$body`**: Optional request body.
**Returns**: The response for synchronous requests, or `AsyncHelper` for async requests.
### **`delete()`**
```php
public function delete(string $uri): mixed
```
Sends a `DELETE` request.
- **`$uri`**: The URI for the request.
**Returns**: The response for synchronous requests, or `AsyncHelper` for async requests.
### **`options()`**
```php
public function options(string $uri): mixed
```
Sends an `OPTIONS` request.
- **`$uri`**: The URI for the request.
**Returns**: The response for synchronous requests, or `AsyncHelper` for async requests.

205
docs/api/fetch.md Normal file
View File

@ -0,0 +1,205 @@
# `fetch` Function API Reference
The `fetch()` function in FetchPHP is designed to mimic JavaScripts `fetch()` API for making HTTP requests. It provides an easy-to-use interface for sending both synchronous and asynchronous requests, and supports flexible configuration through options.
---
## Function Signature
```php
function fetch(?string $url = null, ?array $options = []): \Fetch\Http\Response|\Fetch\Http\ClientHandler
```
---
## Parameters
### **`$url`** (string|null)
- The URL to which the HTTP request will be sent.
- If `null`, the function returns a `ClientHandler` instance, allowing for fluent chaining of methods before sending the request.
### **`$options`** (array|null)
- An associative array of options to customize the request.
- These options include HTTP method, headers, body, and other configurations.
- If not provided, default options are merged with any specified values.
---
## Return Type
- **`Response`**: If a URL is provided, the function sends an HTTP request and returns a `Fetch\Http\Response` object that contains the response data.
- **`ClientHandler`**: If no URL is provided, the function returns a `Fetch\Http\ClientHandler` object to allow for further configuration of the request before sending it.
---
## Behavior
The `fetch()` function sends an HTTP request and handles several common use cases, including:
1. **Method Specification**:
- The HTTP method (e.g., `GET`, `POST`, `PUT`, `DELETE`) is specified in the `$options` array using the `'method'` key.
- If no method is specified, `GET` is used by default.
- The method is automatically uppercased for consistency.
2. **JSON Handling**:
- If the `body` in the options array is an associative array, the function automatically converts it to a JSON string and sets the `Content-Type` header to `application/json`.
3. **Base URI Handling**:
- If a `base_uri` is provided in the options, the function will append the URL to this base URI. The `base_uri` is removed from the options after concatenation.
4. **Exception Handling**:
- The function catches any exceptions thrown during the request.
- If the exception is a `RequestException` (from Guzzle) and a response is available, the function returns the response.
- Otherwise, it rethrows the exception for further handling.
---
## Usage Examples
### **Basic GET Request**
```php
$response = fetch('https://example.com/api/resource');
if ($response->ok()) {
$data = $response->json();
print_r($data);
} else {
echo "Error: " . $response->statusText();
}
```
### **POST Request with JSON Body**
```php
$response = fetch('https://example.com/api/resource', [
'method' => 'POST',
'headers' => [
'Content-Type' => 'application/json',
],
'body' => ['key' => 'value'], // Automatically converted to JSON
]);
$data = $response->json();
echo $data['key'];
```
### **Using `ClientHandler` for Fluent API**
```php
$response = fetch()
->baseUri('https://example.com')
->withHeaders('Content-Type', 'application/json')
->withBody(json_encode(['key' => 'value']))
->withToken('fake-bearer-auth-token')
->post('/posts');
$data = $response->json();
```
### **Error Handling**
```php
try {
$response = fetch('https://example.com/nonexistent');
if ($response->ok()) {
$data = $response->json();
} else {
echo "Error: " . $response->statusText();
}
} catch (\Throwable $e) {
echo "Error: " . $e->getMessage();
}
```
---
## Available Options
The `$options` array supports the following keys:
### **`method`** (string)
- The HTTP method to be used for the request (e.g., `GET`, `POST`, `PUT`, `DELETE`).
- Default: `GET`.
### **`headers`** (array)
- An associative array of headers to include in the request.
- Example: `['Authorization' => 'Bearer token']`.
### **`body`** (mixed)
- The body of the request. If this is an associative array, it will be converted to JSON and the `Content-Type` header will be set automatically.
### **`timeout`** (int)
- Timeout for the request in seconds.
- Default: 30 seconds.
### **`auth`** (array)
- An array for HTTP Basic or Digest authentication.
- Example: `['username', 'password']`.
### **`proxy`** (string|array)
- A proxy server URL or an associative array of proxy configurations.
- Example: `'tcp://localhost:8080'`.
### **`base_uri`** (string)
- A base URI to prepend to the URL for the request.
- Example: `'https://api.example.com'`.
### **`http_errors`** (bool)
- Set to `false` to disable throwing exceptions on HTTP error responses (4xx, 5xx).
- Default: `true`.
---
## Handling Responses
FetchPHP provides several methods for handling the response:
- **`json()`**: Parses the response body as JSON.
- **`text()`**: Returns the raw response body as plain text.
- **`statusText()`**: Returns the status text of the response (e.g., "OK" for 200 responses).
- **`ok()`**: Returns `true` if the response status code is 2xx.
- **`status()`**: Retrieves the HTTP status code of the response (e.g., 200, 404).
- **`headers()`**: Retrieves the response headers as an associative array.
---
## Error Handling
### **HTTP Errors**
FetchPHP throws exceptions for HTTP errors by default (4xx and 5xx status codes). This behavior can be disabled by setting the `http_errors` option to `false`.
```php
$response = fetch('https://example.com/not-found', [
'http_errors' => false
]);
if (!$response->ok()) {
echo "Error: " . $response->statusText();
}
```
### **Exception Handling**
Exceptions thrown by FetchPHP, such as network issues or invalid responses, can be caught using a `try/catch` block.
```php
try {
$response = fetch('https://example.com/api');
echo $response->text();
} catch (\Throwable $e) {
echo "Error: " . $e->getMessage();
}
```

49
docs/api/index.md Normal file
View File

@ -0,0 +1,49 @@
# Overview
The FetchPHP API reference provides detailed documentation on all the available functions, classes, and methods within the FetchPHP library. FetchPHP offers a robust, flexible, and easy-to-use interface for making HTTP requests in PHP, providing both synchronous and asynchronous capabilities, with an API similar to JavaScripts `fetch()`.
This section will cover the core features and functionality of FetchPHP, including:
- **`fetch()` Function**: The main function for performing HTTP requests, modeled after the JavaScript `fetch()` API.
- **ClientHandler Class**: A fluent API for constructing and sending HTTP requests with flexible options.
- **Response Handling**: Methods for parsing and interacting with the response data returned from requests.
- **Asynchronous Requests**: A guide on making async requests using PHP Fibers and managing tasks.
- **Task Lifecycle Management**: Features for pausing, resuming, retrying, and canceling asynchronous tasks.
## Key Components
### **`fetch()` Function**
The `fetch()` function is the core API for making HTTP requests. It allows you to perform synchronous and asynchronous requests, similar to the JavaScript `fetch()` API. It supports various HTTP methods, flexible configuration through options, and automatic JSON handling.
For more details, check the [fetch() API Reference](./fetch.md).
### **ClientHandler Class**
The `ClientHandler` class provides a fluent interface for constructing complex HTTP requests. By chaining methods like `withHeaders()`, `withBody()`, and `withToken()`, you can easily build and send requests with full control over the request's configuration.
For more information, refer to the [ClientHandler API](./client-handler.md).
### **Response Handling**
FetchPHPs response object allows you to interact with the data returned from HTTP requests. You can easily parse JSON, retrieve status codes, and access response headers. The `Response` class provides methods like `json()`, `text()`, `status()`, and `headers()` for processing responses.
Learn more about response handling in the [Response API](./response.md).
### **Asynchronous Requests**
FetchPHP enables asynchronous HTTP requests using PHP Fibers, providing true concurrency. The `async()` function allows you to perform non-blocking requests while handling the results using `.then()` and `.catch()` for success and error scenarios. You can also manage the lifecycle of asynchronous tasks, including pausing, resuming, canceling, and retrying tasks.
Explore the [Async API](./async-requests.md) for details on making asynchronous requests.
### **Task Lifecycle Management**
For asynchronous tasks, FetchPHP provides control mechanisms to manage long-running processes or tasks. The `Task` class, powered by the Matrix package, allows you to start, pause, resume, cancel, and retry tasks, making it ideal for handling asynchronous workflows that require fine-grained control.
Refer to the [Task Management API](./task-management.md) for more information.
### Error Handling
FetchPHP offers robust error-handling mechanisms for both synchronous and asynchronous requests. You can manage exceptions using `try/catch` blocks, disable automatic HTTP error exceptions, and implement custom retry logic for failed requests.
Detailed information can be found in the [Error Handling API](./error-handling.md).

198
docs/api/response.md Normal file
View File

@ -0,0 +1,198 @@
# `Response` Class API Reference
The `Response` class in FetchPHP handles the responses from HTTP requests. It extends Guzzle's `Response` class and implements `Fetch\Interfaces\Response`. This class provides methods for interacting with the response data, including handling JSON, plain text, binary data, and streams, as well as methods for checking status codes.
## Class Definition
```php
namespace Fetch\Http;
class Response extends \GuzzleHttp\Psr7\Response implements ResponseInterface
```
The `Response` class handles the response body and status, providing utility methods to parse the response and check status codes.
## Constructor
```php
public function __construct(
int $status = 200,
array $headers = [],
string $body = '',
string $version = '1.1',
string $reason = null
)
```
### Parameters
- **`$status`** (int): The HTTP status code (e.g., 200, 404).
- **`$headers`** (array): An associative array of headers.
- **`$body`** (string): The response body as a string.
- **`$version`** (string): The HTTP protocol version (e.g., '1.1').
- **`$reason`** (string|null): The reason phrase for the status code (optional).
## Available Methods
### **`json()`**
```php
public function json(bool $assoc = true, bool $throwOnError = true): mixed
```
Parses the response body as JSON.
- **`$assoc`** (bool): If `true`, returns the JSON data as an associative array. If `false`, returns it as an object.
- **`$throwOnError`** (bool): If `true`, throws an exception if the body is not valid JSON.
**Returns**: The parsed JSON as an array or object, or `null` if invalid and `$throwOnError` is `false`.
### Example
```php
$data = $response->json();
```
### **`text()`**
```php
public function text(): string
```
Returns the raw response body as a plain text string.
**Returns**: The response body as a string.
### Example
```php
$content = $response->text();
```
### **`blob()`**
```php
public function blob(): resource|false
```
Returns the response body as a stream (similar to a "blob" in JavaScript).
**Returns**: A stream resource or `false` on failure.
### Example
```php
$stream = $response->blob();
```
### **`arrayBuffer()`**
```php
public function arrayBuffer(): string
```
Returns the response body as a binary string (array buffer).
**Returns**: The raw binary data as a string.
### Example
```php
$binaryData = $response->arrayBuffer();
```
### **`statusText()`**
```php
public function statusText(): string
```
Returns the reason phrase associated with the status code (e.g., "OK" for a 200 status).
**Returns**: The reason phrase or a default message if none is available.
### Example
```php
$statusMessage = $response->statusText();
```
### **`createFromBase()`**
```php
public static function createFromBase(PsrResponseInterface $response): self
```
Creates a new `Response` instance from a base PSR-7 response.
- **`$response`**: A PSR-7 response object from which to create the new `Response`.
**Returns**: A new `Response` instance.
### Example
```php
$response = Response::createFromBase($psrResponse);
```
## Status Code Checking
The `Response` class provides several methods to check the status code category of the response.
### **`isInformational()`**
```php
public function isInformational(): bool
```
Checks if the status code is informational (1xx).
**Returns**: `true` if the status code is in the 100-199 range.
### **`ok()`**
```php
public function ok(): bool
```
Checks if the status code is successful (2xx).
**Returns**: `true` if the status code is in the 200-299 range.
### Example
```php
if ($response->ok()) {
// Handle successful response
}
```
### **`isRedirection()`**
```php
public function isRedirection(): bool
```
Checks if the status code is a redirection (3xx).
**Returns**: `true` if the status code is in the 300-399 range.
### **`isClientError()`**
```php
public function isClientError(): bool
```
Checks if the status code indicates a client error (4xx).
**Returns**: `true` if the status code is in the 400-499 range.
### **`isServerError()`**
```php
public function isServerError(): bool
```
Checks if the status code indicates a server error (5xx).
**Returns**: `true` if the status code is in the 500-599 range.

View File

@ -0,0 +1,168 @@
# Asynchronous HTTP Requests
FetchPHP provides a powerful and flexible API for making asynchronous HTTP requests using PHP Fibers. This API allows you to manage asynchronous tasks in a way similar to JavaScripts `async/await`, with additional task control and error handling capabilities.
## Basic Async Fetch API
FetchPHP allows you to make asynchronous HTTP requests using the `async()` function. Below is an example of an asynchronous POST request:
### **Asynchronous POST Request Example**
```php
use Fetch\Interfaces\Response as ResponseInterface;
$response = async(fn () => fetch('https://example.com', [
'method' => 'POST',
'headers' => [
'Content-Type' => 'application/json',
],
'body' => json_encode(['key' => 'value']),
]))
->then(fn (ResponseInterface $response) => $response->json()) // Success handler
->catch(fn (Throwable $e) => $e->getMessage()); // Error handler
```
In this example:
- **async()**: Executes the request asynchronously.
- **then()**: Handles the success scenario when the request completes.
- **catch()**: Catches any exceptions or errors that occur during the request.
The request sends a POST request to `https://example.com` and processes the JSON response if successful, or catches and displays the error if something goes wrong.
## Fluent API for Asynchronous Requests
FetchPHPs Fluent API can also be used to build asynchronous requests. This API allows for greater flexibility by chaining methods to customize the request.
### **Asynchronous POST Request Using Fluent API**
```php
use Fetch\Interfaces\Response as ResponseInterface;
$response = async(fn () => fetch()
->baseUri('https://example.com')
->withHeaders('Content-Type', 'application/json')
->withBody(json_encode(['key' => 'value']))
->withToken('fake-bearer-auth-token')
->post('/posts'))
->then(fn (ResponseInterface $response) => $response->json()) // Success handler
->catch(fn (Throwable $e) => $e->getMessage()); // Error handler
```
In this example:
- **baseUri()**: Sets the base URL.
- **withHeaders()**: Adds the `Content-Type` header.
- **withBody()**: Sets the JSON body for the request.
- **withToken()**: Adds a Bearer token for authentication.
- **post()**: Sends a POST request to `/posts`.
This request will run asynchronously, and on success, the JSON response will be processed. If an error occurs, it will be caught by the `catch()` block.
## Task Management in Asynchronous Requests
FetchPHP provides task management features such as pausing, resuming, and canceling tasks. These controls can be useful in long-running processes or when dealing with high concurrency.
### **Example: Managing Async Task Lifecycle**
```php
use Matrix\Task;
use Matrix\Enum\TaskStatus;
$task = new Task(function () {
return fetch('https://example.com/api/resource');
});
// Start the task
$task->start();
// Pause the task if needed
$task->pause();
// Resume the task
$task->resume();
// Cancel the task if required
$task->cancel();
```
In this example, a long-running asynchronous task is started, paused, resumed, and potentially canceled based on the tasks lifecycle needs.
## Advanced Async Examples
### **Asynchronous GET Request with Fluent API**
```php
use Fetch\Interfaces\Response as ResponseInterface;
$response = async(fn () => fetch()
->baseUri('https://example.com')
->withQueryParameters(['page' => 1])
->withToken('fake-bearer-auth-token')
->get('/resources'))
->then(fn (ResponseInterface $response) => $response->json()) // Success handler
->catch(fn (Throwable $e) => $e->getMessage()); // Error handler
```
This example demonstrates an asynchronous GET request where query parameters and a Bearer token are used to retrieve data from an API.
### **Retry Logic with Asynchronous Requests**
You can implement retry logic in asynchronous requests by utilizing the `retry()` method:
```php
use Fetch\Interfaces\Response as ResponseInterface;
$response = async(fn () => fetch()
->baseUri('https://example.com')
->withHeaders('Content-Type', 'application/json')
->withBody(json_encode(['key' => 'value']))
->retry(3, 1000) // Retry 3 times with a 1-second delay between retries
->post('/posts'))
->then(fn (ResponseInterface $response) => $response->json()) // Success handler
->catch(fn (Throwable $e) => $e->getMessage()); // Error handler
```
In this example:
- **retry(3, 1000)**: The request will be retried up to 3 times with a delay of 1000 milliseconds between each retry.
## Error Handling in Asynchronous Requests
FetchPHP makes it easy to handle errors in asynchronous requests using the `catch()` method. Errors can include failed network connections, invalid responses, or server errors.
### **Asynchronous Error Handling Example**
```php
use Fetch\Interfaces\Response as ResponseInterface;
$response = async(fn () => fetch('https://nonexistent-url.com'))
->then(fn (ResponseInterface $response) => $response->json()) // Success handler
->catch(fn (Throwable $e) => "Error: " . $e->getMessage()); // Error handler
echo $response;
```
In this example, any errors that occur during the request are caught and handled gracefully.
## Handling JSON and Other Response Types
Just like synchronous requests, asynchronous requests allow you to handle different types of response content:
### **Example: Handling JSON Response**
```php
$response = async(fn () => fetch('https://example.com/api/resource'))
->then(fn ($response) => $response->json())
->catch(fn (Throwable $e) => $e->getMessage());
echo $response;
```
- **json()**: Parses the response as JSON.
---
FetchPHPs asynchronous API, combined with PHP Fibers, provides a robust and flexible way to manage HTTP requests. The Fluent API makes it easier to construct complex requests while the asynchronous control mechanisms allow for better task management.
For more examples of task management, refer to the [Matrix Documentation](https://github.com/Thavarshan/matrix).

View File

@ -0,0 +1,203 @@
# Error Handling
Handling errors is an essential part of any HTTP request workflow, and FetchPHP provides mechanisms to handle errors for both synchronous and asynchronous requests. Whether dealing with network failures, server errors, or invalid responses, FetchPHP gives you the flexibility to handle errors gracefully.
## Synchronous Error Handling
In synchronous requests, FetchPHP will throw an exception when an HTTP error occurs (for example, 4xx or 5xx responses). These exceptions can be caught using PHPs native `try/catch` structure.
### **Synchronous Error Handling Example**
```php
<?php
try {
$response = fetch('https://nonexistent-url.com');
if ($response->ok()) {
$data = $response->json();
print_r($data);
} else {
echo "Error: " . $response->statusText();
}
} catch (\Throwable $e) {
echo "Caught Exception: " . $e->getMessage();
}
```
In this example:
- **try/catch**: Catches exceptions and displays the error message.
- **ok()**: Checks whether the response is successful (2xx status codes).
- **statusText()**: Retrieves the response's status text (e.g., "Not Found").
## Asynchronous Error Handling
In asynchronous requests, FetchPHP uses the `.catch()` method to handle errors that occur during the request. This works similarly to JavaScripts `Promise`-based error handling.
### **Asynchronous Error Handling Example**
```php
use Fetch\Interfaces\Response as ResponseInterface;
$response = async(fn () => fetch('https://nonexistent-url.com'))
->then(fn (ResponseInterface $response) => $response->json()) // Success handler
->catch(fn (Throwable $e) => "Error: " . $e->getMessage()); // Error handler
echo $response;
```
In this example:
- **catch()**: Catches any errors or exceptions during the asynchronous request.
- The error message is printed when the request fails.
## Handling HTTP Errors
FetchPHP automatically throws exceptions for HTTP errors (4xx and 5xx responses). You can disable this behavior by setting the `http_errors` option to `false` in the request.
### **Disabling HTTP Errors Example**
```php
$response = fetch('https://example.com/nonexistent', [
'http_errors' => false // Disable automatic HTTP exceptions
]);
if ($response->ok()) {
echo $response->json();
} else {
echo "HTTP Error: " . $response->status() . " - " . $response->statusText();
}
```
In this example:
- **http_errors**: Disables automatic exception throwing for HTTP error responses.
- **status()**: Retrieves the response status code (e.g., 404).
- **statusText()**: Retrieves the status text (e.g., "Not Found").
## Custom Error Handling Logic
You can implement custom error handling logic with FetchPHP by catching exceptions and performing actions like retries, logging, or fallback mechanisms.
### **Custom Error Handling Example**
```php
<?php
try {
$response = fetch('https://example.com/api/resource');
if ($response->ok()) {
echo $response->json();
} else {
// Custom error logic for HTTP errors
throw new \Exception('Server error: ' . $response->statusText());
}
} catch (\Throwable $e) {
// Custom handling: log error, retry, or show user-friendly message
logError($e->getMessage());
echo "There was an error processing your request. Please try again.";
}
```
In this example:
- If the request fails, a custom error message is thrown, and additional logic such as logging can be implemented.
## Retry Logic for Failed Requests
FetchPHPs fluent API provides a `retry()` method that can be used to retry failed requests. This is especially useful in cases of network failures or intermittent errors.
### **Retry Example**
```php
use Fetch\Interfaces\Response as ResponseInterface;
$response = async(fn () => fetch()
->baseUri('https://example.com')
->withHeaders('Content-Type', 'application/json')
->withBody(json_encode(['key' => 'value']))
->retry(3, 1000) // Retry 3 times with a 1-second delay between retries
->post('/posts'))
->then(fn (ResponseInterface $response) => $response->json()) // Success handler
->catch(fn (Throwable $e) => "Error: " . $e->getMessage()); // Error handler
echo $response;
```
In this example:
- **retry(3, 1000)**: Retries the request up to 3 times with a 1-second delay between each retry if it fails.
- You can adjust the retry count and delay as needed.
## Handling JSON and Other Response Types
You can handle different response types and implement error handling based on the response content. For instance, if the server returns invalid JSON, FetchPHP will throw an exception when trying to parse the response as JSON.
### **Handling Invalid JSON Response Example**
```php
<?php
try {
$response = fetch('https://example.com/invalid-json');
$data = $response->json(); // This will throw an error if the response is not valid JSON
} catch (\Throwable $e) {
echo "Invalid JSON response: " . $e->getMessage();
}
```
In this example:
- The `json()` method will throw an exception if the response body is not valid JSON.
## Custom Exception Handling
FetchPHP allows you to handle exceptions in a more structured way, including network errors, request timeouts, or invalid responses. For example, you can catch specific exceptions thrown by Guzzle or create custom exceptions to handle various error scenarios.
### **Custom Exception Example**
```php
use GuzzleHttp\Exception\RequestException;
try {
$response = fetch('https://example.com/api/resource');
} catch (RequestException $e) {
echo "Network error: " . $e->getMessage();
} catch (\Throwable $e) {
echo "Other error: " . $e->getMessage();
}
```
In this example:
- **RequestException**: Catches network-related issues like timeouts or connection failures.
- **\Throwable**: Catches all other exceptions, including invalid responses or internal errors.
## Handling Timeouts
You can configure request timeouts and catch exceptions when the request exceeds the timeout limit.
### **Timeout Handling Example**
```php
<?php
try {
$response = fetch('https://example.com/api/resource', [
'timeout' => 2, // Timeout in 2 seconds
]);
} catch (\Throwable $e) {
echo "Request timed out: " . $e->getMessage();
}
```
In this example:
- If the request takes longer than 2 seconds, it will throw a timeout exception, which can be caught and handled.
---
FetchPHP provides flexible and robust error-handling mechanisms for both synchronous and asynchronous requests. By using the `try/catch` structure, `.catch()` for asynchronous requests, and features like `retry()`, you can effectively manage errors in your applications. Make sure to implement proper error handling in your workflow to improve reliability and user experience.

View File

@ -0,0 +1,180 @@
# Getting Started
FetchPHP is a modern HTTP client for PHP that mimics the JavaScript `fetch()` API, providing both synchronous and asynchronous request handling. Whether you're familiar with JavaScript's `fetch()` or Laravel's HTTP client, FetchPHP provides a similar, intuitive API. It is powered by the Guzzle HTTP client for synchronous requests and Matrix for asynchronous task management using PHP Fibers.
## Core Features
FetchPHP offers several key features to simplify HTTP requests in PHP:
- **JavaScript-like `fetch()` API**: Similar to JavaScript's `fetch()`, making it intuitive for developers.
- **Fluent API**: Chain methods for flexible and readable HTTP request building.
- **Asynchronous Support**: Manage asynchronous tasks via PHP Fibers, powered by Matrix.
- **Powered by Guzzle**: Synchronous requests use the reliable Guzzle HTTP client.
- **Error Handling**: Comprehensive error management with both synchronous and asynchronous request support.
## Usage Examples
### JavaScript-like Fetch API
FetchPHP allows you to easily perform synchronous HTTP requests with a syntax similar to JavaScripts `fetch()`.
#### **Synchronous Example**
```php
$response = fetch('https://example.com', [
'method' => 'POST',
'headers' => [
'Content-Type' => 'application/json',
],
'body' => json_encode(['key' => 'value']),
]);
$data = $response->json();
```
This example sends a POST request with a JSON body and retrieves the JSON response.
### JavaScript-like Async Fetch API
FetchPHP also supports asynchronous requests using a syntax similar to JavaScripts async/await.
#### **Asynchronous Example**
```php
use Fetch\Interfaces\Response as ResponseInterface;
$response = async(fn () => fetch('https://example.com', [
'method' => 'POST',
'headers' => [
'Content-Type' => 'application/json',
],
'body' => json_encode(['key' => 'value']),
]))
->then(fn (ResponseInterface $response) => $response->json()) // Success handler
->catch(fn (Throwable $e) => $e->getMessage()); // Error handler
```
This example asynchronously sends a POST request and processes the JSON response, or handles an error using `.catch()`.
### Fluent API
FetchPHPs fluent API allows you to chain methods to build and send HTTP requests more elegantly and flexibly.
#### **Synchronous Example Using Fluent API**
```php
$response = fetch()
->baseUri('https://example.com')
->withHeaders('Content-Type', 'application/json')
->withBody(json_encode(['key' => 'value']))
->withToken('fake-bearer-auth-token')
->post('/posts');
$data = $response->json();
```
This fluent API example sends a POST request to `/posts` with a JSON body and Bearer token authorization.
### Fluent API in Async
You can also use the fluent API for asynchronous requests:
#### **Asynchronous Example Using Fluent API**
```php
use Fetch\Interfaces\Response as ResponseInterface;
$response = async(fn () => fetch()
->baseUri('https://example.com')
->withHeaders('Content-Type', 'application/json')
->withBody(json_encode(['key' => 'value']))
->withToken('fake-bearer-auth-token')
->post('/posts'))
->then(fn (ResponseInterface $response) => $response->json()) // Success handler
->catch(fn (Throwable $e) => $e->getMessage()); // Error handler
```
This example asynchronously sends a POST request using the fluent API, handles the response, or catches any errors.
## Task Lifecycle Management
FetchPHP, powered by Matrix, allows you to manage long-running or asynchronous tasks with more control over their lifecycle.
### **Example: Task Lifecycle Control**
```php
use Matrix\Task;
use Matrix\Enum\TaskStatus;
// Define a long-running task
$task = new Task(function () {
return "Task completed!";
});
// Start the task
$task->start();
// Pause and resume the task dynamically
$task->pause();
$task->resume();
// Cancel the task if needed
$task->cancel();
// Retry the task if it fails
if ($task->getStatus() === TaskStatus::FAILED) {
$task->retry();
}
$result = $task->getResult();
```
## Error Handling
FetchPHP provides flexible error handling for both synchronous and asynchronous requests.
### **Synchronous Error Handling Example**
```php
$response = fetch('https://nonexistent-url.com');
if ($response->ok()) {
echo $response->json();
} else {
echo "Error: " . $response->statusText();
}
```
### **Asynchronous Error Handling Example**
```php
use Fetch\Interfaces\Response as ResponseInterface;
$response = async(fn () => fetch('https://nonexistent-url.com'))
->then(fn (ResponseInterface $response) => $response->json())
->catch(fn (\Throwable $e) => echo "Error: " . $e->getMessage());
```
## Proxy and Authentication Support
FetchPHP includes built-in support for proxies and authentication:
### **Proxy Example**
```php
$response = fetch('https://example.com')
->withProxy('tcp://localhost:8080')
->get();
echo $response->statusText();
```
### **Authentication Example**
```php
$response = fetch('https://example.com/secure-endpoint')
->withAuth('username', 'password')
->get();
echo $response->statusText();
```

104
docs/guide/installation.md Normal file
View File

@ -0,0 +1,104 @@
# Installation
## Prerequisites
Before installing FetchPHP, ensure that your environment meets the following requirements:
- **PHP 8.1 or higher**: FetchPHP relies on PHP Fibers, which were introduced in PHP 8.1. Make sure your project or server is running PHP 8.1 or above.
- **Composer**: FetchPHP is distributed via Composer, so youll need Composer installed in your environment.
## Installing FetchPHP
To install FetchPHP in your project, run the following command:
```bash
composer require jerome/fetch-php
```
This will download and install FetchPHP along with its required dependencies, including **Guzzle** for HTTP client handling and **Matrix** for asynchronous task management.
## Configuration
FetchPHP uses Guzzle as its underlying HTTP client, and you can configure various Guzzle options by passing them into the `fetch()` function or creating a custom Guzzle client. Below is a list of Guzzle configuration options that can be used in FetchPHP:
### Guzzle Client Options
- **base_uri**: The base URI to use with requests. Example: `https://example.com`.
- **timeout**: Timeout in seconds for the request. Example: `timeout => 5`.
- **connect_timeout**: Timeout in seconds for establishing a connection. Example: `connect_timeout => 2`.
- **allow_redirects**: Allows redirections. Can be `true`, `false`, or an array of options. Default is `true`.
- **proxy**: A string or array of proxy servers. Example: `'proxy' => 'tcp://localhost:8080'`.
- **auth**: Array for HTTP Basic, Digest, or NTLM authentication. Example: `['username', 'password']`.
- **headers**: Array of default headers to send with every request.
- **verify**: Enable or disable SSL certificate verification. Default is `true`. Can be a boolean or a path to a CA file.
- **cookies**: Enable or disable cookies for requests. Can be a `CookieJar` object or `true` to use a shared `CookieJar`.
- **debug**: Set to `true` to enable debug output.
- **http_errors**: Set to `false` to disable exceptions on HTTP protocol errors (e.g., 4xx, 5xx responses). Default is `true`.
- **query**: Associative array of query string parameters to include in the request URL.
- **form_params**: Associative array of data for form submissions (used for `application/x-www-form-urlencoded` requests).
- **json**: JSON data to include as the request body.
- **multipart**: An array of multipart form data fields. Used for `multipart/form-data` requests.
- **sink**: Path to a file where the response body will be saved.
- **ssl_key**: Path to SSL key file or array `[path, password]`.
- **cert**: Path to an SSL certificate file or array `[path, password]`.
- **stream**: Set to `true` to return the response body as a stream.
- **delay**: The number of milliseconds to delay before sending the request.
- **on_stats**: A callable function that receives transfer statistics after a request is completed.
> **Note**: Most options can also be invoked as methods on the `fetch()` function or `ClientHandler` class. Check the API reference for more details.
### Example of Custom Guzzle Client
You can configure FetchPHP with these options by creating a custom Guzzle client and passing it into FetchPHPs `ClientHandler`:
```php
use GuzzleHttp\Client;
use Fetch\Http\ClientHandler;
// Create a custom Guzzle client
$client = new Client([
'base_uri' => 'https://example.com',
'timeout' => 5,
'headers' => ['User-Agent' => 'My-App'],
'auth' => ['username', 'password'],
]);
// Use the custom client with FetchPHP
$response = ClientHandler::handle('GET', '/endpoint', ['client' => $client]);
$data = $response->json();
```
## Updating FetchPHP
To update FetchPHP to the latest version, run the following Composer command:
```bash
composer update jerome/fetch-php
```
This will pull the latest version of FetchPHP and its dependencies.
## Checking Installation
To verify that FetchPHP was installed correctly, you can run a simple test:
```php
<?php
$response = fetch('https://example.com');
if ($response->ok()) {
echo "FetchPHP is working correctly!";
}
```
## Uninstalling FetchPHP
If you need to remove FetchPHP from your project, run the following Composer command:
```bash
composer remove jerome/fetch-php
```
This will uninstall FetchPHP and remove it from your `composer.json` file.

175
docs/guide/sync-requests.md Normal file
View File

@ -0,0 +1,175 @@
# Synchronous HTTP Requests
FetchPHP provides an easy-to-use API for making synchronous HTTP requests. You can use either the familiar JavaScript-like `fetch()` function or the powerful Fluent API to build and send requests.
## JavaScript-like Fetch API
Heres an example of a basic synchronous GET request using the JavaScript-like `fetch()` function:
### **GET Request Example**
```php
$response = fetch('https://example.com/api/resource');
if ($response->ok()) {
$data = $response->json(); // Parse the response as JSON
print_r($data);
} else {
echo "Error: " . $response->statusText();
}
```
### **POST Request Example with JSON**
```php
$response = fetch('https://example.com/api/resource', [
'method' => 'POST',
'headers' => [
'Content-Type' => 'application/json',
],
'body' => json_encode(['key' => 'value']),
]);
$data = $response->json();
echo $data['key'];
```
## Fluent API
The Fluent API in FetchPHP allows for more flexible request building by chaining methods. This API makes it easier to manage headers, body content, query parameters, authentication, and more, in a clean and readable way.
### **POST Request Example Using Fluent API**
```php
$response = fetch()
->baseUri('https://example.com')
->withHeaders('Content-Type', 'application/json')
->withBody(json_encode(['key' => 'value']))
->withToken('fake-bearer-auth-token')
->post('/posts');
$data = $response->json();
```
In this example:
- `baseUri()`: Sets the base URI for the request.
- `withHeaders()`: Adds custom headers like `Content-Type`.
- `withBody()`: Sets the request body, which in this case is JSON.
- `withToken()`: Adds a Bearer token to the request for authentication.
- `post()`: Sends the request as a POST to the specified endpoint.
### **GET Request Example Using Fluent API**
```php
$response = fetch()
->baseUri('https://example.com')
->withQueryParameters(['page' => 2])
->withToken('fake-bearer-auth-token')
->get('/resources');
$data = $response->json();
```
In this example:
- `withQueryParameters()`: Adds query parameters to the request URL.
- `get()`: Sends a GET request to the `/resources` endpoint.
## Available Fluent API Methods
The following methods are available in FetchPHPs Fluent API:
- **baseUri(string $uri)**: Set the base URI for the request.
- **withHeaders(array $headers)**: Add or modify headers for the request.
- **withBody(mixed $body)**: Set the request body (e.g., JSON, form data).
- **withQueryParameters(array $params)**: Add query parameters to the URL.
- **withToken(string $token)**: Add a Bearer token for authentication.
- **withAuth(string $username, string $password)**: Add Basic authentication credentials.
- **timeout(int $seconds)**: Set a timeout for the request in seconds.
- **retry(int $retries, int $delay = 100)**: Configure retry logic for failed requests.
- **withProxy(string|array $proxy)**: Add a proxy server for the request.
- **withCookies(bool|CookieJarInterface $cookies)**: Manage cookies for the request.
- **withRedirects(bool|array $redirects = true)**: Enable or disable redirects.
- **withCert(string|array $cert)**: Specify SSL certificates for secure requests.
- **withSslKey(string|array $sslKey)**: Provide an SSL key for the request.
- **withStream(bool $stream)**: Set the response to be streamed.
## Advanced Examples
### **PUT Request with Fluent API**
```php
$response = fetch()
->baseUri('https://example.com')
->withHeaders('Content-Type', 'application/json')
->withBody(json_encode(['key' => 'updated_value']))
->put('/resource/1');
$data = $response->json();
echo $data['key'];
```
### **DELETE Request with Fluent API**
```php
$response = fetch()
->baseUri('https://example.com')
->delete('/resource/1');
if ($response->ok()) {
echo "Resource deleted successfully.";
} else {
echo "Error: " . $response->statusText();
}
```
### **Using Proxies with Fluent API**
```php
$response = fetch()
->baseUri('https://example.com')
->withProxy('tcp://localhost:8080')
->get('/resource');
$data = $response->json();
```
### **Basic Authentication with Fluent API**
```php
$response = fetch()
->baseUri('https://example.com')
->withAuth('username', 'password')
->get('/secure-endpoint');
$data = $response->json();
```
## Handling Responses
FetchPHP provides several methods to handle and process the response data:
- **json()**: Parse the response body as JSON.
- **text()**: Get the raw response body as plain text.
- **statusText()**: Get the response's status text (e.g., "OK" for 200 responses).
- **ok()**: Returns `true` if the response status code is in the 2xx range.
- **status()**: Get the response status code (e.g., 200, 404, etc.).
- **headers()**: Retrieve the response headers as an associative array.
Example:
```php
$response = fetch('https://example.com/api/resource');
if ($response->ok()) {
$data = $response->json();
echo "JSON Response: " . print_r($data, true);
} else {
echo "Error: " . $response->status() . " - " . $response->statusText();
}
```
---
The Fluent API provides a more flexible and chainable way of building and sending HTTP requests with FetchPHP. For more advanced usage, check out the [Asynchronous Requests](./async-requests.md) page.

View File

@ -1,25 +1,23 @@
---
# https://vitepress.dev/reference/default-theme-home-page
layout: home
hero:
name: "Fetch PHP"
text: "The JavaScript fetch API for PHP."
tagline: My great project tagline
text: "The PHP library that brings the power of the JavaScript fetch API."
tagline: "Synchronous and Asynchronous HTTP requests made easy with PHP Fibers."
actions:
- theme: brand
text: Markdown Examples
link: /markdown-examples
text: Get Started
link: /guide/getting-started
- theme: alt
text: API Examples
link: /api-examples
text: API Reference
link: /api/
features:
- title: Feature A
details: Lorem ipsum dolor sit amet, consectetur adipiscing elit
- title: Feature B
details: Lorem ipsum dolor sit amet, consectetur adipiscing elit
- title: Feature C
details: Lorem ipsum dolor sit amet, consectetur adipiscing elit
- title: JavaScript-like API
details: FetchPHP mimics the intuitive syntax of JavaScript's `fetch` API for both synchronous and asynchronous requests.
- title: True Asynchronous Support
details: Powered by PHP Fibers and Matrix, FetchPHP allows for true async task management with fine-grained control.
- title: Fluent API for Flexibility
details: Chain methods and build requests effortlessly, inspired by Laravel's HTTP client for flexible, readable code.
---

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**
````md
```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).

View File

@ -2,9 +2,9 @@
"private": true,
"type": "module",
"scripts": {
"docs:dev": "vitepress dev docs",
"docs:build": "vitepress build docs",
"docs:preview": "vitepress preview docs"
"dev": "vitepress dev docs",
"build": "vitepress build docs",
"preview": "vitepress preview docs"
},
"devDependencies": {
"vitepress": "latest"