diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 07999ebc4d..440efb6b59 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -132,3 +132,7 @@ jobs: - name: Run Telescope dashboard tests working-directory: src/telescope run: npm test + + - name: Build Telescope dashboard assets + working-directory: src/telescope + run: npm run build diff --git a/_archive/docs/0.3/.vuepress/config.js b/_archive/docs/0.3/.vuepress/config.js deleted file mode 100644 index 44b79440e9..0000000000 --- a/_archive/docs/0.3/.vuepress/config.js +++ /dev/null @@ -1,80 +0,0 @@ -import { defaultTheme } from '@vuepress/theme-default' -import { defineUserConfig } from 'vuepress/cli' -import { viteBundler } from '@vuepress/bundler-vite' -import { mdEnhancePlugin } from "vuepress-plugin-md-enhance" -import { redirectPlugin } from '@vuepress/plugin-redirect' -import { docsearchPlugin } from '@vuepress/plugin-docsearch' -import { sidebarConfig } from './sidebar.js' -import { removeHtmlExtensionPlugin } from 'vuepress-plugin-remove-html-extension' -import { seoPlugin } from '@vuepress/plugin-seo' - -export default defineUserConfig({ - lang: 'en-US', - title: 'Hypervel', - description: 'A Coroutine PHP Framework for Laravel Artisans.', - - ignoreDeadLinks: true, - bundler: viteBundler(), - - plugins: [ - seoPlugin({ - hostname: 'https://hypervel.org', - fallBackImage: 'https://hypervel.org/home.png', - customHead: (head) => { - head.push(['title', {}, 'Hypervel - A Coroutine PHP Framework for Laravel Artisans.']); - }, - ogp: (ogp, page) => ({ - ...ogp, - 'og:title': 'Hypervel - A Coroutine PHP Framework for Laravel Artisans', - 'og:description': "Hypervel is a Laravel-style framework with native coroutine support for ultra-high performance.", - 'twitter:title': 'Hypervel - A Coroutine PHP Framework For Laravel Artisans', - 'twitter:description': "Hypervel is a Laravel-style framework with native coroutine support for ultra-high performance.", - 'twitter:image': 'https://hypervel.org/home.png', - 'twitter:card': 'summary_large_image', - }), - }), - removeHtmlExtensionPlugin(), - mdEnhancePlugin({ - hint: true, - tasklist: true, - include: true, - tabs: true, - align: true, - chart: true, - }), - redirectPlugin({ - config: { - '/docs': '/docs/introduction.html', - }, - }), - docsearchPlugin({ - appId: 'VH8TNYFP5F', - apiKey: '434aa2025192c8d2fb19499cb78e5d48', - indexName: 'hypervel' - }), - ], - - theme: defaultTheme({ - logo: 'icon.svg', - - docsRepo: 'hypervel/hypervel.org', - - docsBranch: 'main/docs', - - navbar: [ - '/', - { - text: 'Documentation', - link: '/docs/introduction', - }, - { - text: 'GitHub', - link: 'https://github.com/hypervel/hypervel', - } - ], - - sidebar: sidebarConfig, - - sidebarDepth: 0, - }), -}) diff --git a/_archive/docs/0.3/.vuepress/public/favicon.ico b/_archive/docs/0.3/.vuepress/public/favicon.ico deleted file mode 100644 index d6ec6e174d..0000000000 Binary files a/_archive/docs/0.3/.vuepress/public/favicon.ico and /dev/null differ diff --git a/_archive/docs/0.3/.vuepress/public/home.png b/_archive/docs/0.3/.vuepress/public/home.png deleted file mode 100644 index 1d942c3dfb..0000000000 Binary files a/_archive/docs/0.3/.vuepress/public/home.png and /dev/null differ diff --git a/_archive/docs/0.3/.vuepress/public/icon.png b/_archive/docs/0.3/.vuepress/public/icon.png deleted file mode 100644 index c44ab7dd95..0000000000 Binary files a/_archive/docs/0.3/.vuepress/public/icon.png and /dev/null differ diff --git a/_archive/docs/0.3/.vuepress/public/icon.svg b/_archive/docs/0.3/.vuepress/public/icon.svg deleted file mode 100644 index 3f3eee7a06..0000000000 --- a/_archive/docs/0.3/.vuepress/public/icon.svg +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/_archive/docs/0.3/.vuepress/public/images/prompts-example.png b/_archive/docs/0.3/.vuepress/public/images/prompts-example.png deleted file mode 100644 index 45b09ae478..0000000000 Binary files a/_archive/docs/0.3/.vuepress/public/images/prompts-example.png and /dev/null differ diff --git a/_archive/docs/0.3/.vuepress/public/images/whoops.png b/_archive/docs/0.3/.vuepress/public/images/whoops.png deleted file mode 100644 index 710f8e893c..0000000000 Binary files a/_archive/docs/0.3/.vuepress/public/images/whoops.png and /dev/null differ diff --git a/_archive/docs/0.3/.vuepress/public/logo.png b/_archive/docs/0.3/.vuepress/public/logo.png deleted file mode 100644 index 3a1d32ecad..0000000000 Binary files a/_archive/docs/0.3/.vuepress/public/logo.png and /dev/null differ diff --git a/_archive/docs/0.3/.vuepress/public/logo.svg b/_archive/docs/0.3/.vuepress/public/logo.svg deleted file mode 100644 index 046e2221d5..0000000000 --- a/_archive/docs/0.3/.vuepress/public/logo.svg +++ /dev/null @@ -1,68 +0,0 @@ - - diff --git a/_archive/docs/0.3/.vuepress/sidebar.js b/_archive/docs/0.3/.vuepress/sidebar.js deleted file mode 100644 index dc50ece6f3..0000000000 --- a/_archive/docs/0.3/.vuepress/sidebar.js +++ /dev/null @@ -1,370 +0,0 @@ -export const sidebarConfig = ({ - '/docs': [ - { - text: 'Documentation', - prefix: '/docs/', - children: [ - { - text: 'Prologue', - collapsible: true, - children: [ - { - text: 'Contributing Guide', - link: 'contributions', - } - ] - }, - { - text: 'Getting Started', - collapsible: true, - children: [ - { - text: 'Introduction', - link: 'introduction', - }, - { - text: 'Installation', - link: 'installation', - }, - { - text: 'Configuration', - link: 'configuration', - }, - { - text: 'Directory Structure', - link: 'structure', - }, - { - text: 'Deployment', - link: 'deployment', - } - ], - }, - { - text: 'Architecture Concepts', - collapsible: true, - children: [ - { - text: 'Request Lifecycle', - link: 'lifecycle', - }, - { - text: 'Service Container', - link: 'container', - }, - { - text: 'Service Providers', - link: 'providers', - }, - { - text: 'Facades', - link: 'facades', - } - ], - }, - { - text: 'The Basics', - collapsible: true, - children: [ - { - text: 'Routing', - link: 'routing', - }, - { - text: 'Middleware', - link: 'middleware', - }, - { - text: 'CSRF Protection', - link: 'csrf', - }, - { - text: 'Controllers', - link: 'controllers', - }, - { - text: 'Requests', - link: 'requests', - }, - { - text: 'Responses', - link: 'responses', - }, - { - text: 'Views', - link: 'views', - }, - { - text: 'Blade Templates', - link: 'blade', - }, - { - text: 'URL Generation', - link: 'urls', - }, - { - text: 'Session', - link: 'session', - }, - { - text: 'Validation', - link: 'validation', - }, - { - text: 'Error Handling', - link: 'errors', - }, - { - text: 'Logging', - link: 'logging', - } - ], - }, - { - text: 'Digging Deeper', - collapsible: true, - children: [ - { - text: 'Artisan Console', - link: 'artisan', - }, - { - text: 'Broadcasting', - link: 'broadcasting', - }, - { - text: 'Cache', - link: 'cache', - }, - { - text: 'Collections', - link: 'collections', - }, - { - text: 'Context', - link: 'context', - }, - { - text: 'Coroutine', - link: 'coroutine', - }, - { - text: 'Contracts', - link: 'contracts', - }, - { - text: 'Data Objects', - link: 'data-objects', - }, - { - text: 'Events', - link: 'events', - }, - { - text: 'File Storage', - link: 'filesystem', - }, - { - text: 'Helpers', - link: 'helpers', - }, - { - text: 'HTTP Client', - link: 'http-client', - }, - { - text: 'Localization', - link: 'localization', - }, - { - text: 'Mail', - link: 'mail', - }, - { - text: 'Notifications', - link: 'notifications', - }, - { - text: 'Package Development', - link: 'packages', - }, - { - text: 'Package Porting', - link: 'packages-porting', - }, - { - text: 'Processes', - link: 'processes', - }, - { - text: 'Queues', - link: 'queues', - }, - { - text: 'Rate Limiting', - link: 'rate-limiting', - }, - { - text: 'Strings', - link: 'strings', - }, - { - text: 'Task Scheduling', - link: 'scheduling', - }, - ], - }, - { - text: 'Security', - collapsible: true, - children: [ - { - text: 'Authentication', - link: 'authentication', - }, - { - text: 'Authorization', - link: 'authorization', - }, - { - text: 'Encryption', - link: 'encryption', - }, - { - text: 'Hashing', - link: 'hashing', - } - ], - }, - { - text: 'Database', - collapsible: true, - children: [ - { - text: 'Getting Started', - link: 'database', - }, - { - text: 'Query Builder', - link: 'queries', - }, - { - text: 'Pagination', - link: 'pagination', - }, - { - text: 'Migrations', - link: 'migrations', - }, - { - text: 'Seeding', - link: 'seeding', - }, - { - text: 'Redis', - link: 'redis', - } - ], - }, - { - text: 'Eloquent ORM', - collapsible: true, - children: [ - { - text: 'Getting Started', - link: 'eloquent', - }, - { - text: 'Relationships', - link: 'eloquent-relationships', - }, - { - text: 'Collections', - link: 'eloquent-collections', - }, - { - text: 'Mutators / Casts', - link: 'eloquent-mutators', - }, - { - text: 'API Resources', - link: 'eloquent-resources', - }, - { - text: 'Serialization', - link: 'eloquent-serialization', - }, - { - text: 'Factories', - link: 'eloquent-factories', - } - ], - }, - { - text: 'Testing', - collapsible: true, - children: [ - { - text: 'Getting Started', - link: 'testing', - }, - { - text: 'HTTP Tests', - link: 'http-tests', - }, - { - text: 'Console Tests', - link: 'console-tests', - }, - { - text: 'Database', - link: 'database-testing', - }, - { - text: 'Mocking', - link: 'mocking', - }, - { - text: 'Packages Toolkit', - link: 'testbench', - }, - ], - }, - { - text: 'Packages', - collapsible: true, - children: [ - { - text: 'Horizon', - link: 'horizon', - }, - { - text: 'Sanctum', - link: 'sanctum', - }, - { - text: 'Socialite', - link: 'socialite', - }, - { - text: 'Permission', - link: 'permission', - }, - { - text: 'Prompts', - link: 'prompts', - }, - { - text: 'Nested Set', - link: 'nested-set', - }, - { - text: 'Telescope', - link: 'telescope', - } - ], - }, - ], - } - ], -}) \ No newline at end of file diff --git a/_archive/docs/0.3/.vuepress/styles/palette.scss b/_archive/docs/0.3/.vuepress/styles/palette.scss deleted file mode 100644 index 0b94286e3b..0000000000 --- a/_archive/docs/0.3/.vuepress/styles/palette.scss +++ /dev/null @@ -1,182 +0,0 @@ -.vp-hero-description { - max-width: 40rem; -} - -/* Code examples styles */ -.code-examples-table { - display: flex; - width: 100%; - border: 1px solid var(--c-border); - border-radius: 8px; - margin: 2rem 0; - height: 600px; - background: var(--c-bg); -} - -.code-nav { - flex: 0 0 250px; - background: var(--c-bg-light); - border-right: 1px solid var(--c-border); - overflow-y: auto; - - ul { - list-style: none; - padding: 0; - margin: 0; - } - - .category-item { - padding: 0.75rem 1.5rem; - cursor: pointer; - transition: all 0.3s ease; - border-left: 3px solid transparent; - - &:hover { - background: var(--c-bg); - border-left-color: var(--c-brand); - color: var(--c-brand); - } - - &.active { - background: var(--c-bg); - border-left-color: var(--c-brand); - color: var(--c-brand); - } - } -} - -.code-content { - flex: 1; - padding: 1.5rem; - overflow-y: auto; - height: 100%; -} - -.code-block { - display: none; - opacity: 0; - transition: opacity 0.3s ease; - - &.active { - display: block; - opacity: 1; - } - - .file-name { - padding: 0.5rem 1rem; - background: var(--c-bg-light); - color: var(--c-text); - font-family: var(--font-family-mono); - font-size: 0.9rem; - border: 1px solid var(--c-border); - border-bottom: none; - border-top-left-radius: 6px; - border-top-right-radius: 6px; - margin-bottom: 0; - } - - div[class*="language-"] { - margin: 0; - border-top-left-radius: 0; - border-top-right-radius: 0; - border-bottom-left-radius: 6px; - border-bottom-right-radius: 6px; - } -} - -/* Responsive design */ -@media (max-width: 768px) { - .code-examples-table { - flex-direction: column; - height: auto; - } - - .code-nav { - flex: none; - height: 150px; - border-right: none; - border-bottom: 1px solid var(--c-border); - } - - .code-content { - flex: none; - height: 250px; - } -} - -/* Benchmark tabs styles */ -.benchmark-tabs { - display: flex; - flex-direction: column; - width: 100%; - border: 1px solid var(--c-border); - border-radius: 8px; - margin: 2rem 0; - background: var(--c-bg); -} - -.benchmark-nav { - flex: 0 0 auto; - background: var(--c-bg-light); - border-bottom: 1px solid var(--c-border); - - ul { - list-style: none; - padding: 0; - margin: 0; - display: flex; - } - - .benchmark-item { - padding: 0.75rem 1.5rem; - cursor: pointer; - transition: all 0.3s ease; - border-bottom: 3px solid transparent; - - &:hover { - background: var(--c-bg); - border-bottom-color: var(--c-brand); - color: var(--c-brand); - } - - &.active { - background: var(--c-bg); - border-bottom-color: var(--c-brand); - color: var(--c-brand); - } - } -} - -.benchmark-content { - flex: 1; - padding: 1.5rem; -} - -.benchmark-block { - display: none; - opacity: 0; - transition: opacity 0.3s ease; - - &.active { - display: block; - opacity: 1; - } -} - -/* Responsive design for benchmark tabs */ -@media (max-width: 768px) { - .benchmark-nav ul { - flex-direction: column; - } - - .benchmark-nav .benchmark-item { - border-bottom: none; - border-left: 3px solid transparent; - - &:hover, - &.active { - border-left-color: var(--c-brand); - border-bottom-color: transparent; - } - } -} \ No newline at end of file diff --git a/_archive/docs/0.3/README.md b/_archive/docs/0.3/README.md deleted file mode 100644 index 9db4f58ad1..0000000000 --- a/_archive/docs/0.3/README.md +++ /dev/null @@ -1,631 +0,0 @@ ---- -home: true -title: Hypervel -heroImage: icon.svg -actions: - - text: Get Started - link: /docs/introduction - type: primary - - text: GitHub - link: https://github.com/hypervel/hypervel - type: secondary -features: - - title: Laravel Friendly - details: By porting Laravel's core infrastructure and fundamental components, this framework enables Laravel developers to quickly adapt to it. - - title: High Performance - details: Leveraging Swoole's native coroutine support, it delivers exceptional performance and efficient concurrency handling. - - title: Ecosystem Compatibility - details: Hypervel is compatible with the Hyperf ecosystem, sharing the same community resources and packages. -footer: MIT Licensed | Copyright © 2024-present Hypervel ---- - -## Coding Like in Laravel - -Laravel artisans can enjoy a familiar development experience that mirrors the original framework. The simple, elegant syntax remains intact, enabling developers to stay productive while leveraging enhanced performance. - -
Is Hypervel compatible with Laravel packages?
-No! While Hypervel maintains the similar development experience like Laravel, unfortunately, you can't install Laravel packages on this framework due to the fundamental differences in architecture. Developers need to migrate these Laravel packages on their own. We encourage developers to contribute to Hypervel's ecosystem together.
-How does Hypervel achieve high performance?
-Hypervel achieves high performance through Swoole's coroutine system, which enables non-blocking I/O operations and efficient concurrency handling. This allows the framework to handle more concurrent connections with fewer resources compared to traditional PHP-FPM.
-Why not use Octane directly?
-Octane accelerates Laravel by maintaining the framework in a persistent application state, resetting request-scoped resources between requests. However, it doesn't introduce non-blocking I/O capabilities to Laravel's architecture. Furthermore, all components in Laravel weren't designed with coroutines in mind. It will cause states bleeding while context switching among coroutines. - -For I/O-intensive scenarios, even with Octane's improvements, your application's ability to handle concurrent requests is still limited by the duration of these I/O operations. -
-Should I migrate my current Laravel projects to Hypervel?
-If you don't have performance issues in your current projects, I would suggest remaining in Laravel because of the mature community and rich ecosystem. There will be necessary refactorings for the migration process. You can also consider migrating only the APIs and modules with performance issues to Hypervel, and adopt architecture like API Gateway to allow Laravel and Hypervel projects to work simultaneously.
-This is user {{ $user->id }}
-@endforeach - -@forelse ($users as $user) -No users
-@endforelse - -@while (true) -I'm looping forever.
-@endwhile -``` - -::: important -While iterating through a `foreach` loop, you may use the [loop variable](#the-loop-variable) to gain valuable information about the loop, such as whether you are in the first or last iteration through the loop. -::: - -When using loops you may also skip the current iteration or end the loop using the `@continue` and `@break` directives: - -```html -@foreach ($users as $user) - @if ($user->type == 1) - @continue - @endif - -This is user {{ $user->id }}
-@endforeach -``` - -If you are in a nested loop, you may access the parent loop's `$loop` variable via the `parent` property: - -```html -@foreach ($users as $user) - @foreach ($user->posts as $post) - @if ($loop->parent->first) - This is the first iteration of the parent loop. - @endif - @endforeach -@endforeach -``` - -The `$loop` variable also contains a variety of other useful properties: - -| Property | Description | -|--------------------|--------------------------------------------------------| -| `$loop->index` | The index of the current loop iteration (starts at 0). | -| `$loop->iteration` | The current loop iteration (starts at 1). | -| `$loop->remaining` | The iterations remaining in the loop. | -| `$loop->count` | The total number of items in the array being iterated. | -| `$loop->first` | Whether this is the first iteration through the loop. | -| `$loop->last` | Whether this is the last iteration through the loop. | -| `$loop->even` | Whether this is an even iteration through the loop. | -| `$loop->odd` | Whether this is an odd iteration through the loop. | -| `$loop->depth` | The nesting level of the current loop. | -| `$loop->parent` | When in a nested loop, the parent's loop variable. | - -### Conditional Classes & Styles - -The `@class` directive conditionally compiles a CSS class string. The directive accepts an array of classes where the array key contains the class or classes you wish to add, while the value is a boolean expression. If the array element has a numeric key, it will always be included in the rendered class list: - -```html -@php - $isActive = false; - $hasError = true; -@endphp - - $isActive, - 'text-gray-500' => ! $isActive, - 'bg-red' => $hasError, -])> - - -``` - -Likewise, the `@style` directive may be used to conditionally add inline CSS styles to an HTML element: - -```html -@php - $isActive = true; -@endphp - - $isActive, -])> - - -``` - -### Including Subviews - -::: note -While you're free to use the `@include` directive, Blade [components](#components) provide similar functionality and offer several benefits over the `@include` directive such as data and attribute binding. -::: - -Blade's `@include` directive allows you to include a Blade view from within another view. All variables that are available to the parent view will be made available to the included view: - -```html -This is appended to the master sidebar.
-@endsection - -@section('content') -This is my body content.
-@endsection -``` - -In this example, the `sidebar` section is utilizing the `@@parent` directive to append (rather than overwriting) content to the layout's sidebar. The `@@parent` directive will be replaced by the content of the layout when the view is rendered. - -::: note -Contrary to the previous example, this `sidebar` section ends with `@endsection` instead of `@show`. The `@endsection` directive will only define a section while `@show` will define and **immediately yield** the section. -::: - -The `@yield` directive also accepts a default value as its second parameter. This value will be rendered if the section being yielded is undefined: - -```html -@yield('content', 'Default content') -``` - -### Validation Errors - -The `@error` directive may be used to quickly check if [validation error messages](/docs/validation#quick-displaying-the-validation-errors) exist for a given attribute. Within an `@error` directive, you may echo the `$message` variable to display the error message: - -```html - - - - - - -@error('title') -
-
-## Installation
-
-::: warning
-Hypervel Horizon requires that you use [Redis](https://redis.io) to power your queue. Therefore, you should ensure that your queue connection is set to `redis` in your application's `config/queue.php` configuration file.
-:::
-
-You may install Horizon into your project using the Composer package manager:
-
-```shell
-composer require hypervel/horizon
-```
-
-After installing Horizon, publish its assets using the `horizon:install` Artisan command:
-
-```shell
-php artisan horizon:install
-```
-
-### Configuration
-
-After publishing Horizon's assets, its primary configuration file will be located at `config/horizon.php`. This configuration file allows you to configure the queue worker options for your application. Each configuration option includes a description of its purpose, so be sure to thoroughly explore this file.
-
-::: warning
-Horizon uses a Redis connection named `horizon` internally. This Redis connection name is reserved and should not be assigned to another Redis connection in the `database.php` configuration file or as the value of the `use` option in the `horizon.php` configuration file.
-:::
-
-#### Environments
-
-After installation, the primary Horizon configuration option that you should familiarize yourself with is the `environments` configuration option. This configuration option is an array of environments that your application runs on and defines the worker process options for each environment. By default, this entry contains a `production` and `local` environment. However, you are free to add more environments as needed:
-
-```php
-'environments' => [
- 'production' => [
- 'supervisor-1' => [
- 'maxProcesses' => 10,
- 'balanceMaxShift' => 1,
- 'balanceCooldown' => 3,
- ],
- ],
-
- 'local' => [
- 'supervisor-1' => [
- 'maxProcesses' => 3,
- ],
- ],
-],
-```
-
-You may also define a wildcard environment (`*`) which will be used when no other matching environment is found:
-
-```php
-'environments' => [
- // ...
-
- '*' => [
- 'supervisor-1' => [
- 'maxProcesses' => 3,
- ],
- ],
-],
-```
-
-When you start Horizon, it will use the worker process configuration options for the environment that your application is running on. Typically, the environment is determined by the value of the `APP_ENV` [environment variable](/docs/configuration#determining-the-current-environment). For example, the default `local` Horizon environment is configured to start three worker processes and automatically balance the number of worker processes assigned to each queue. The default `production` environment is configured to start a maximum of 10 worker processes and automatically balance the number of worker processes assigned to each queue.
-
-::: warning
-You should ensure that the `environments` portion of your `horizon` configuration file contains an entry for each [environment](/docs/configuration#environment-configuration) on which you plan to run Horizon.
-:::
-
-#### Supervisors
-
-As you can see in Horizon's default configuration file, each environment can contain one or more "supervisors". By default, the configuration file defines this supervisor as `supervisor-1`; however, you are free to name your supervisors whatever you want. Each supervisor is essentially responsible for "supervising" a group of worker processes and takes care of balancing worker processes across queues.
-
-You may add additional supervisors to a given environment if you would like to define a new group of worker processes that should run in that environment. You may choose to do this if you would like to define a different balancing strategy or worker process count for a given queue used by your application.
-
-#### Default Values
-
-Within Horizon's default configuration file, you will notice a `defaults` configuration option. This configuration option specifies the default values for your application's [supervisors](#supervisors). The supervisor's default configuration values will be merged into the supervisor's configuration for each environment, allowing you to avoid unnecessary repetition when defining your supervisors.
-
-### Dashboard Authorization
-
-The Horizon dashboard may be accessed via the `/horizon` route. By default, you will only be able to access this dashboard in the `local` environment. However, within your `app/Providers/HorizonServiceProvider.php` file, there is an [authorization gate](/docs/authorization#gates) definition. This authorization gate controls access to Horizon in **non-local** environments. You are free to modify this gate as needed to restrict access to your Horizon installation:
-
-```php
-/**
- * Register the Horizon gate.
- *
- * This gate determines who can access Horizon in non-local environments.
- */
-protected function gate(): void
-{
- Gate::define('viewHorizon', function (User $user) {
- return in_array($user->email, [
- 'taylor@Hypervel.com',
- ]);
- });
-}
-```
-
-#### Alternative Authentication Strategies
-
-Remember that Hypervel automatically injects the authenticated user into the gate closure. If your application is providing Horizon security via another method, such as IP restrictions, then your Horizon users may not need to "login". Therefore, you will need to change `function (User $user)` closure signature above to `function (User $user = null)` in order to force Hypervel to not require authentication.
-
-### Max Job Attempts
-
-::: note
-Before refining these options, make sure you are familiar with Hypervel's default [queue services](/docs/queues#max-job-attempts-and-timeout) and the concept of 'attempts'.
-:::
-
-You can define the maximum number of attempts a job can consume within a supervisor's configuration:
-
-```php
-'environments' => [
- 'production' => [
- 'supervisor-1' => [
- // ...
- 'tries' => 10,
- ],
- ],
-],
-```
-
-::: note
-This option is similar to the `--tries` option when using the Artisan command to process queues.
-:::
-
-Adjusting the `tries` option is essential when using middlewares such as `WithoutOverlapping` or `RateLimited` because they consume attempts. To handle this, adjust the `tries` configuration value either at the supervisor level or by defining the `$tries` property on the job class.
-
-If you don't set the `tries` option, Horizon defaults to a single attempt, unless the job class defines `$tries`, which takes precedence over the Horizon configuration.
-
-Setting `tries` or `$tries` to 0 allows unlimited attempts, which is ideal when the number of attempts is uncertain. To prevent endless failures, you can limit the number of exceptions allowed by setting the `$maxExceptions` property on the job class.
-
-### Job Timeout
-
-Similarly, you can set a `timeout` value at the supervisor level, which specifies how many seconds a worker process can run a job before it's forcefully terminated. Once terminated, the job will either be retried or marked as failed, depending on your queue configuration:
-
-```php
-'environments' => [
- 'production' => [
- 'supervisor-1' => [
- // ...¨
- 'timeout' => 60,
- ],
- ],
-],
-```
-
-::: warning
-When using the `auto` balancing strategy, Horizon will consider in-progress workers as "hanging" and force-kill them after the Horizon timeout during scale down. Always ensure the Horizon timeout is greater than any job-level timeout, otherwise jobs may be terminated mid-execution. In addition, the `timeout` value should always be at least a few seconds shorter than the `retry_after` value defined in your `config/queue.php` configuration file. Otherwise, your jobs may be processed twice.
-:::
-
-### Job Backoff
-
-You can define the `backoff` value at the supervisor level to specify how long Horizon should wait before retrying a job that encounters an unhandled exception:
-
-```php
-'environments' => [
- 'production' => [
- 'supervisor-1' => [
- // ...
- 'backoff' => 10,
- ],
- ],
-],
-```
-
-You may also configure "exponential" backoffs by using an array for the `backoff` value. In this example, the retry delay will be 1 second for the first retry, 5 seconds for the second retry, 10 seconds for the third retry, and 10 seconds for every subsequent retry if there are more attempts remaining:
-
-```php
-'environments' => [
- 'production' => [
- 'supervisor-1' => [
- // ...
- 'backoff' => [1, 5, 10],
- ],
- ],
-],
-```
-
-### Silenced Jobs
-
-Sometimes, you may not be interested in viewing certain jobs dispatched by your application or third-party packages. Instead of these jobs taking up space in your "Completed Jobs" list, you can silence them. To get started, add the job's class name to the `silenced` configuration option in your application's `horizon` configuration file:
-
-```php
-'silenced' => [
- App\Jobs\ProcessPodcast::class,
-],
-```
-
-In addition to silencing individual job classes, Horizon also supports silencing jobs based on [tags](#tags). This can be useful if you want to hide multiple jobs that share a common tag:
-
-```php
-'silenced_tags' => [
- 'notifications'
-],
-```
-
-Alternatively, the job you wish to silence can implement the `Hypervel\Horizon\Contracts\Silenced` interface. If a job implements this interface, it will automatically be silenced, even if it is not present in the `silenced` configuration array:
-
-```php
-use Hypervel\Horizon\Contracts\Silenced;
-
-class ProcessPodcast implements ShouldQueue, Silenced
-{
- use Queueable;
-
- // ...
-}
-```
-
-## Balancing Strategies
-
-Each supervisor can process one or more queues but unlike Hypervel's default queue system, Horizon allows you to choose from three worker balancing strategies: `auto`, `simple`, and `false`.
-
-::: important
-Unlike Laravel, Hypervel's Queue Worker has native concurrency capabilities. In traditional Laravel, even when handling multiple I/O-bound tasks, you need multiple workers to achieve concurrency and avoid blocking. However, in Hypervel, you can easily specify the concurrency level for each worker through the `--concurrency` parameter, which utilizes coroutines for concurrent execution.
-
-This means that what previously required 10 worker processes in Laravel to achieve a certain level of concurrency can now be accomplished in Hypervel with just a single worker by controlling the number of concurrent coroutines through the `concurrency` parameter!
-
-```php
-php artisan horizon:supervisor --concurrency=10
-```
-
-> If you have 10 workers and set the concurrency to 10, this means you can have a total concurrency capacity of 100.
-:::
-
-### Auto Balancing
-
-The `auto` strategy, which is the default strategy, adjusts the number of worker processes per queue based on the current workload of the queue. For example, if your `notifications` queue has 1,000 pending jobs while your `default` queue is empty, Horizon will allocate more workers to your `notifications` queue until the queue is empty.
-
-When using the `auto` strategy, you may also configure the `minProcesses` and `maxProcesses` configuration options:
-
-
-
-```
-
-### Attachable Objects
-
-While attaching files to messages via simple string paths is often sufficient, in many cases the attachable entities within your application are represented by classes. For example, if your application is attaching a photo to a message, your application may also have a `Photo` model that represents that photo. When that is the case, wouldn't it be convenient to simply pass the `Photo` model to the `attach` method? Attachable objects allow you to do just that.
-
-To get started, implement the `Hypervel\Mail\Contracts\Attachable` interface on the object that will be attachable to messages. This interface dictates that your class defines a `toMailAttachment` method that returns an `Hypervel\Mail\Attachment` instance:
-
-```php
-
- */
-public function attachments(): array
-{
- return [$this->photo];
-}
-```
-
-Of course, attachment data may be stored on a remote file storage service such as Amazon S3. So, Hypervel also allows you to generate attachment instances from data that is stored on one of your application's [filesystem disks](/docs/filesystem):
-
-```php
-// Create an attachment from a file on your default disk...
-return Attachment::fromStorage($this->path);
-
-// Create an attachment from a file on a specific disk...
-return Attachment::fromStorageDisk('backblaze', $this->path);
-```
-
-In addition, you may create attachment instances via data that you have in memory. To accomplish this, provide a closure to the `fromData` method. The closure should return the raw data that represents the attachment:
-
-```php
-return Attachment::fromData(fn () => $this->content, 'Photo Name');
-```
-
-Hypervel also provides additional methods that you may use to customize your attachments. For example, you may use the `as` and `withMime` methods to customize the file's name and MIME type:
-
-```php
-return Attachment::fromPath('/path/to/file')
- ->as('Photo Name')
- ->withMime('image/jpeg');
-```
-
-### Headers
-
-Sometimes you may need to attach additional headers to the outgoing message. For instance, you may need to set a custom `Message-Id` or other arbitrary text headers.
-
-To accomplish this, define a `headers` method on your mailable. The `headers` method should return an `Hypervel\Mail\Mailables\Headers` instance. This class accepts `messageId`, `references`, and `text` parameters. Of course, you may provide only the parameters you need for your particular message:
-
-```php
-use Hypervel\Mail\Mailables\Headers;
-
-/**
- * Get the message headers.
- */
-public function headers(): Headers
-{
- return new Headers(
- messageId: 'custom-message-id@example.com',
- references: ['previous-message@example.com'],
- text: [
- 'X-Custom-Header' => 'Custom Value',
- ],
- );
-}
-```
-
-### Tags and Metadata
-
-Some third-party email providers such as Mailgun and Postmark support message "tags" and "metadata", which may be used to group and track emails sent by your application. You may add tags and metadata to an email message via your `Envelope` definition:
-
-```php
-use Hypervel\Mail\Mailables\Envelope;
-
-/**
- * Get the message envelope.
- *
- * @return \Hypervel\Mail\Mailables\Envelope
- */
-public function envelope(): Envelope
-{
- return new Envelope(
- subject: 'Order Shipped',
- tags: ['shipment'],
- metadata: [
- 'order_id' => $this->order->id,
- ],
- );
-}
-```
-
-If your application is using the Mailgun driver, you may consult Mailgun's documentation for more information on [tags](https://documentation.mailgun.com/docs/mailgun/user-manual/tracking-messages/#tagging) and [metadata](https://documentation.mailgun.com/docs/mailgun/user-manual/tracking-messages/#attaching-data-to-messages). Likewise, the Postmark documentation may also be consulted for more information on their support for [tags](https://postmarkapp.com/blog/tags-support-for-smtp) and [metadata](https://postmarkapp.com/support/article/1125-custom-metadata-faq).
-
-If your application is using Amazon SES to send emails, you should use the `metadata` method to attach [SES "tags"](https://docs.aws.amazon.com/ses/latest/APIReference/API_MessageTag.html) to the message.
-
-### Customizing the Symfony Message
-
-Hypervel's mail capabilities are powered by Symfony Mailer. Hypervel allows you to register custom callbacks that will be invoked with the Symfony Message instance before sending the message. This gives you an opportunity to deeply customize the message before it is sent. To accomplish this, define a `using` parameter on your `Envelope` definition:
-
-```php
-use Hypervel\Mail\Mailables\Envelope;
-use Symfony\Component\Mime\Email;
-
-/**
- * Get the message envelope.
- */
-public function envelope(): Envelope
-{
- return new Envelope(
- subject: 'Order Shipped',
- using: [
- function (Email $message) {
- // ...
- },
- ]
- );
-}
-```
-
-## Markdown Mailables
-
-Markdown mailable messages allow you to take advantage of the pre-built templates and components of [mail notifications](/docs/notifications#mail-notifications) in your mailables. Since the messages are written in Markdown, Hypervel is able to render beautiful, responsive HTML templates for the messages while also automatically generating a plain-text counterpart.
-
-### Generating Markdown Mailables
-
-To generate a mailable with a corresponding Markdown template, you may use the `--markdown` option of the `make:mail` Artisan command:
-
-```shell:no-line-numbers
-php artisan make:mail OrderShipped --markdown=mail.orders.shipped
-```
-
-When configuring the mailable `Content` definition within its `content` method, use the `markdown` parameter instead of the `view` parameter:
-
-```php
-use Hypervel\Mail\Mailables\Content;
-
-/**
- * Get the message content definition.
- */
-public function content(): Content
-{
- return new Content(
- markdown: 'mail.orders.shipped',
- with: [
- 'url' => $this->orderUrl,
- ],
- );
-}
-```
-
-> `make:mail` is not supported yet.
-
-### Writing Markdown Messages
-
-Markdown mailables use a combination of Blade components and Markdown syntax which allow you to easily construct mail messages while leveraging Hypervel's pre-built email UI components:
-
-```html
-Inject: alert("Hello XSS!");
-``` - - -#### mask - -The `mask` method masks a portion of a string with a repeated character, and may be used to obfuscate segments of strings such as email addresses and phone numbers: - -```php -use Hypervel\Support\Str; - -$string = Str::of('taylor@example.com')->mask('*', 3); - -// tay*************** -``` - -If needed, you may provide negative numbers as the third or fourth argument to the `mask` method, which will instruct the method to begin masking at the given distance from the end of the string: - -```php -$string = Str::of('taylor@example.com')->mask('*', -15, 3); - -// tay***@example.com - -$string = Str::of('taylor@example.com')->mask('*', 4, -4); - -// tayl**********.com -``` - - -#### match - -The `match` method will return the portion of a string that matches a given regular expression pattern: - -```php -use Hypervel\Support\Str; - -$result = Str::of('foo bar')->match('/bar/'); - -// 'bar' - -$result = Str::of('foo bar')->match('/foo (.*)/'); - -// 'bar' -``` - - -#### matchAll - -The `matchAll` method will return a collection containing the portions of a string that match a given regular expression pattern: - -```php -use Hypervel\Support\Str; - -$result = Str::of('bar foo bar')->matchAll('/bar/'); - -// collect(['bar', 'bar']) -``` - -If you specify a matching group within the expression, Hypervel will return a collection of the first matching group's matches: - -```php -use Hypervel\Support\Str; - -$result = Str::of('bar fun bar fly')->matchAll('/f(\w*)/'); - -// collect(['un', 'ly']); -``` - -If no matches are found, an empty collection will be returned. - - -#### isMatch - -The `isMatch` method will return `true` if the string matches a given regular expression: - -```php -use Hypervel\Support\Str; - -$result = Str::of('foo bar')->isMatch('/foo (.*)/'); - -// true - -$result = Str::of('laravel')->isMatch('/foo (.*)/'); - -// false -``` - - -#### newLine - -The `newLine` method appends an "end of line" character to a string: - -```php -use Hypervel\Support\Str; - -$padded = Str::of('Laravel')->newLine()->append('Framework'); - -// 'Laravel -// Framework' -``` - - -#### padBoth - -The `padBoth` method wraps PHP's `str_pad` function, padding both sides of a string with another string until the final string reaches the desired length: - -```php -use Hypervel\Support\Str; - -$padded = Str::of('James')->padBoth(10, '_'); - -// '__James___' - -$padded = Str::of('James')->padBoth(10); - -// ' James ' -``` - - -#### padLeft - -The `padLeft` method wraps PHP's `str_pad` function, padding the left side of a string with another string until the final string reaches the desired length: - -```php -use Hypervel\Support\Str; - -$padded = Str::of('James')->padLeft(10, '-='); - -// '-=-=-James' - -$padded = Str::of('James')->padLeft(10); - -// ' James' -``` - - -#### padRight - -The `padRight` method wraps PHP's `str_pad` function, padding the right side of a string with another string until the final string reaches the desired length: - -```php -use Hypervel\Support\Str; - -$padded = Str::of('James')->padRight(10, '-'); - -// 'James-----' - -$padded = Str::of('James')->padRight(10); - -// 'James ' -``` - - -#### pipe - -The `pipe` method allows you to transform the string by passing its current value to the given callable: - -```php -use Hypervel\Support\Str; -use Hypervel\Support\Stringable; - -$hash = Str::of('Laravel')->pipe('md5')->prepend('Checksum: '); - -// 'Checksum: a5c95b86291ea299fcbe64458ed12702' - -$closure = Str::of('foo')->pipe(function (Stringable $str) { - return 'bar'; -}); - -// 'bar' -``` - - -#### plural - -The `plural` method converts a singular word string to its plural form. This function supports [any of the languages support by Laravel's pluralizer](/docs/localization#pluralization-language): - -```php -use Hypervel\Support\Str; - -$plural = Str::of('car')->plural(); - -// cars - -$plural = Str::of('child')->plural(); - -// children -``` - -You may provide an integer as a second argument to the function to retrieve the singular or plural form of the string: - -```php -use Hypervel\Support\Str; - -$plural = Str::of('child')->plural(2); - -// children - -$plural = Str::of('child')->plural(1); - -// child -``` - - -#### position - -The `position` method returns the position of the first occurrence of a substring in a string. If the substring does not exist within the string, `false` is returned: - -```php -use Hypervel\Support\Str; - -$position = Str::of('Hello, World!')->position('Hello'); - -// 0 - -$position = Str::of('Hello, World!')->position('W'); - -// 7 -``` - - -#### prepend - -The `prepend` method prepends the given values onto the string: - -```php -use Hypervel\Support\Str; - -$string = Str::of('Framework')->prepend('Hypervel '); - -// Hypervel Framework -``` - - -#### remove - -The `remove` method removes the given value or array of values from the string: - -```php -use Hypervel\Support\Str; - -$string = Str::of('Arkansas is quite beautiful!')->remove('quite'); - -// Arkansas is beautiful! -``` - -You may also pass `false` as a second parameter to ignore case when removing strings. - - -#### repeat - -The `repeat` method repeats the given string: - -```php -use Hypervel\Support\Str; - -$repeated = Str::of('a')->repeat(5); - -// aaaaa -``` - - -#### replace - -The `replace` method replaces a given string within the string: - -```php -use Hypervel\Support\Str; - -$replaced = Str::of('Laravel 6.x')->replace('6.x', '7.x'); - -// Laravel 7.x -``` - -The `replace` method also accepts a `caseSensitive` argument. By default, the `replace` method is case sensitive: - -```php -$replaced = Str::of('macOS 13.x')->replace( - 'macOS', 'iOS', caseSensitive: false -); -``` - - -#### replaceArray - -The `replaceArray` method replaces a given value in the string sequentially using an array: - -```php -use Hypervel\Support\Str; - -$string = 'The event will take place between ? and ?'; - -$replaced = Str::of($string)->replaceArray('?', ['8:30', '9:00']); - -// The event will take place between 8:30 and 9:00 -``` - - -#### replaceFirst - -The `replaceFirst` method replaces the first occurrence of a given value in a string: - -```php -use Hypervel\Support\Str; - -$replaced = Str::of('the quick brown fox jumps over the lazy dog')->replaceFirst('the', 'a'); - -// a quick brown fox jumps over the lazy dog -``` - - -#### replaceLast - -The `replaceLast` method replaces the last occurrence of a given value in a string: - -```php -use Hypervel\Support\Str; - -$replaced = Str::of('the quick brown fox jumps over the lazy dog')->replaceLast('the', 'a'); - -// the quick brown fox jumps over a lazy dog -``` - - -#### replaceMatches - -The `replaceMatches` method replaces all portions of a string matching a pattern with the given replacement string: - -```php -use Hypervel\Support\Str; - -$replaced = Str::of('(+1) 501-555-1000')->replaceMatches('/[^A-Za-z0-9]++/', '') - -// '15015551000' -``` - -The `replaceMatches` method also accepts a closure that will be invoked with each portion of the string matching the given pattern, allowing you to perform the replacement logic within the closure and return the replaced value: - -```php -use Hypervel\Support\Str; - -$replaced = Str::of('123')->replaceMatches('/\d/', function (array $matches) { - return '['.$matches[0].']'; -}); - -// '[1][2][3]' -``` - - -#### replaceStart - -The `replaceStart` method replaces the first occurrence of the given value only if the value appears at the start of the string: - -```php -use Hypervel\Support\Str; - -$replaced = Str::of('Hello World')->replaceStart('Hello', 'Laravel'); - -// Laravel World - -$replaced = Str::of('Hello World')->replaceStart('World', 'Laravel'); - -// Hello World -``` - - -#### replaceEnd - -The `replaceEnd` method replaces the last occurrence of the given value only if the value appears at the end of the string: - -```php -use Hypervel\Support\Str; - -$replaced = Str::of('Hello World')->replaceEnd('World', 'Laravel'); - -// Hello Laravel - -$replaced = Str::of('Hello World')->replaceEnd('Hello', 'Laravel'); - -// Hello World -``` - - -#### scan - -The `scan` method parses input from a string into a collection according to a format supported by the [`sscanf` PHP function](https://www.php.net/manual/en/function.sscanf.php): - -```php -use Hypervel\Support\Str; - -$collection = Str::of('filename.jpg')->scan('%[^.].%s'); - -// collect(['filename', 'jpg']) -``` - - -#### singular - -The `singular` method converts a string to its singular form. This function supports [any of the languages support by Laravel's pluralizer](/docs/localization#pluralization-language): - -```php -use Hypervel\Support\Str; - -$singular = Str::of('cars')->singular(); - -// car - -$singular = Str::of('children')->singular(); - -// child -``` - - -#### slug - -The `slug` method generates a URL friendly "slug" from the given string: - -```php -use Hypervel\Support\Str; - -$slug = Str::of('Hypervel Framework')->slug('-'); - -// hypervel-framework -``` - - -#### snake - -The `snake` method converts the given string to `snake_case`: - -```php -use Hypervel\Support\Str; - -$converted = Str::of('fooBar')->snake(); - -// foo_bar -``` - - -#### split - -The `split` method splits a string into a collection using a regular expression: - -```php -use Hypervel\Support\Str; - -$segments = Str::of('one, two, three')->split('/[\s,]+/'); - -// collect(["one", "two", "three"]) -``` - - -#### squish - -The `squish` method removes all extraneous white space from a string, including extraneous white space between words: - -```php -use Hypervel\Support\Str; - -$string = Str::of(' Hypervel framework ')->squish(); - -// Hypervel framework -``` - - -#### start - -The `start` method adds a single instance of the given value to a string if it does not already start with that value: - -```php -use Hypervel\Support\Str; - -$adjusted = Str::of('this/string')->start('/'); - -// /this/string - -$adjusted = Str::of('/this/string')->start('/'); - -// /this/string -``` - - -#### startsWith - -The `startsWith` method determines if the given string begins with the given value: - -```php -use Hypervel\Support\Str; - -$result = Str::of('This is my name')->startsWith('This'); - -// true -``` - - -#### stripTags - -The `stripTags` method removes all HTML and PHP tags from a string: - -```php -use Hypervel\Support\Str; - -$result = Str::of('Taylor Otwell')->stripTags(); - -// Taylor Otwell - -$result = Str::of('Taylor Otwell')->stripTags(''); - -// Taylor Otwell -``` - - -#### studly - -The `studly` method converts the given string to `StudlyCase`: - -```php -use Hypervel\Support\Str; - -$converted = Str::of('foo_bar')->studly(); - -// FooBar -``` - - -#### substr - -The `substr` method returns the portion of the string specified by the given start and length parameters: - -```php -use Hypervel\Support\Str; - -$string = Str::of('Laravel Framework')->substr(8); - -// Framework - -$string = Str::of('Laravel Framework')->substr(8, 5); - -// Frame -``` - - -#### substrReplace - -The `substrReplace` method replaces text within a portion of a string, starting at the position specified by the second argument and replacing the number of characters specified by the third argument. Passing `0` to the method's third argument will insert the string at the specified position without replacing any of the existing characters in the string: - -```php -use Hypervel\Support\Str; - -$string = Str::of('1300')->substrReplace(':', 2); - -// 13: - -$string = Str::of('The Framework')->substrReplace(' Laravel', 3, 0); - -// The Laravel Framework -``` - - -#### swap - -The `swap` method replaces multiple values in the string using PHP's `strtr` function: - -```php -use Hypervel\Support\Str; - -$string = Str::of('Tacos are great!') - ->swap([ - 'Tacos' => 'Burritos', - 'great' => 'fantastic', - ]); - -// Burritos are fantastic! -``` - - -#### take - -The `take` method returns a specified number of characters from the beginning of the string: - -```php -use Hypervel\Support\Str; - -$taken = Str::of('Build something amazing!')->take(5); - -// Build -``` - - -#### tap - -The `tap` method passes the string to the given closure, allowing you to examine and interact with the string while not affecting the string itself. The original string is returned by the `tap` method regardless of what is returned by the closure: - -```php -use Hypervel\Support\Str; -use Hypervel\Support\Stringable; - -$string = Str::of('Laravel') - ->append(' Framework') - ->tap(function (Stringable $string) { - dump('String after append: '.$string); - }) - ->upper(); - -// LARAVEL FRAMEWORK -``` - - -#### test - -The `test` method determines if a string matches the given regular expression pattern: - -```php -use Hypervel\Support\Str; - -$result = Str::of('Laravel Framework')->test('/Laravel/'); - -// true -``` - - -#### title - -The `title` method converts the given string to `Title Case`: - -```php -use Hypervel\Support\Str; - -$converted = Str::of('a nice title uses the correct case')->title(); - -// A Nice Title Uses The Correct Case -``` - - -#### toBase64 - -The `toBase64` method converts the given string to Base64: - -```php -use Hypervel\Support\Str; - -$base64 = Str::of('Laravel')->toBase64(); - -// TGFyYXZlbA== -``` - - -#### trim - -The `trim` method trims the given string. Unlike PHP's native `trim` function, Laravel's `trim` method also removes unicode whitespace characters: - -```php -use Hypervel\Support\Str; - -$string = Str::of(' Hypervel ')->trim(); - -// 'Hypervel' - -$string = Str::of('/Hypervel/')->trim('/'); - -// 'Hypervel' -``` - - -#### ltrim - -The `ltrim` method trims the left side of the string. Unlike PHP's native `ltrim` function, Laravel's `ltrim` method also removes unicode whitespace characters: - -```php -use Hypervel\Support\Str; - -$string = Str::of(' Hypervel ')->ltrim(); - -// 'Hypervel ' - -$string = Str::of('/Hypervel/')->ltrim('/'); - -// 'Hypervel/' -``` - - -#### rtrim - -The `rtrim` method trims the right side of the given string. Unlike PHP's native `rtrim` function, Laravel's `rtrim` method also removes unicode whitespace characters: - -```php -use Hypervel\Support\Str; - -$string = Str::of(' Hypervel ')->rtrim(); - -// ' Hypervel' - -$string = Str::of('/Hypervel/')->rtrim('/'); - -// '/Hypervel' -``` - - -#### ucfirst - -The `ucfirst` method returns the given string with the first character capitalized: - -```php -use Hypervel\Support\Str; - -$string = Str::of('foo bar')->ucfirst(); - -// Foo bar -``` - - -#### ucsplit - -The `ucsplit` method splits the given string into a collection by uppercase characters: - -```php -use Hypervel\Support\Str; - -$string = Str::of('Foo Bar')->ucsplit(); - -// collect(['Foo', 'Bar']) -``` - - -#### unwrap - -The `unwrap` method removes the specified strings from the beginning and end of a given string: - -```php -use Hypervel\Support\Str; - -Str::of('-Laravel-')->unwrap('-'); - -// Laravel - -Str::of('{framework: "Laravel"}')->unwrap('{', '}'); - -// framework: "Laravel" -``` - - -#### upper - -The `upper` method converts the given string to uppercase: - -```php -use Hypervel\Support\Str; - -$adjusted = Str::of('laravel')->upper(); - -// LARAVEL -``` - - -#### when - -The `when` method invokes the given closure if a given condition is `true`. The closure will receive the fluent string instance: - -```php -use Hypervel\Support\Str; -use Hypervel\Support\Stringable; - -$string = Str::of('Taylor') - ->when(true, function (Stringable $string) { - return $string->append(' Otwell'); - }); - -// 'Taylor Otwell' -``` - -If necessary, you may pass another closure as the third parameter to the `when` method. This closure will execute if the condition parameter evaluates to `false`. - - -#### whenContains - -The `whenContains` method invokes the given closure if the string contains the given value. The closure will receive the fluent string instance: - -```php -use Hypervel\Support\Str; -use Hypervel\Support\Stringable; - -$string = Str::of('tony stark') - ->whenContains('tony', function (Stringable $string) { - return $string->title(); - }); - -// 'Tony Stark' -``` - -If necessary, you may pass another closure as the third parameter to the `when` method. This closure will execute if the string does not contain the given value. - -You may also pass an array of values to determine if the given string contains any of the values in the array: - -```php -use Hypervel\Support\Str; -use Hypervel\Support\Stringable; - -$string = Str::of('tony stark') - ->whenContains(['tony', 'hulk'], function (Stringable $string) { - return $string->title(); - }); - -// Tony Stark -``` - - -#### whenContainsAll - -The `whenContainsAll` method invokes the given closure if the string contains all of the given sub-strings. The closure will receive the fluent string instance: - -```php -use Hypervel\Support\Str; -use Hypervel\Support\Stringable; - -$string = Str::of('tony stark') - ->whenContainsAll(['tony', 'stark'], function (Stringable $string) { - return $string->title(); - }); - -// 'Tony Stark' -``` - -If necessary, you may pass another closure as the third parameter to the `when` method. This closure will execute if the condition parameter evaluates to `false`. - - -#### whenEmpty - -The `whenEmpty` method invokes the given closure if the string is empty. If the closure returns a value, that value will also be returned by the `whenEmpty` method. If the closure does not return a value, the fluent string instance will be returned: - -```php -use Hypervel\Support\Str; -use Hypervel\Support\Stringable; - -$string = Str::of(' ')->whenEmpty(function (Stringable $string) { - return $string->trim()->prepend('Laravel'); -}); - -// 'Laravel' -``` - - -#### whenNotEmpty - -The `whenNotEmpty` method invokes the given closure if the string is not empty. If the closure returns a value, that value will also be returned by the `whenNotEmpty` method. If the closure does not return a value, the fluent string instance will be returned: - -```php -use Hypervel\Support\Str; -use Hypervel\Support\Stringable; - -$string = Str::of('Framework')->whenNotEmpty(function (Stringable $string) { - return $string->prepend('Hypervel '); -}); - -// 'Hypervel Framework' -``` - - -#### whenStartsWith - -The `whenStartsWith` method invokes the given closure if the string starts with the given sub-string. The closure will receive the fluent string instance: - -```php -use Hypervel\Support\Str; -use Hypervel\Support\Stringable; - -$string = Str::of('disney world')->whenStartsWith('disney', function (Stringable $string) { - return $string->title(); -}); - -// 'Disney World' -``` - - -#### whenEndsWith - -The `whenEndsWith` method invokes the given closure if the string ends with the given sub-string. The closure will receive the fluent string instance: - -```php -use Hypervel\Support\Str; -use Hypervel\Support\Stringable; - -$string = Str::of('disney world')->whenEndsWith('world', function (Stringable $string) { - return $string->title(); -}); - -// 'Disney World' -``` - - -#### whenExactly - -The `whenExactly` method invokes the given closure if the string exactly matches the given string. The closure will receive the fluent string instance: - -```php -use Hypervel\Support\Str; -use Hypervel\Support\Stringable; - -$string = Str::of('laravel')->whenExactly('laravel', function (Stringable $string) { - return $string->title(); -}); - -// 'Laravel' -``` - - -#### whenNotExactly - -The `whenNotExactly` method invokes the given closure if the string does not exactly match the given string. The closure will receive the fluent string instance: - -```php -use Hypervel\Support\Str; -use Hypervel\Support\Stringable; - -$string = Str::of('framework')->whenNotExactly('laravel', function (Stringable $string) { - return $string->title(); -}); - -// 'Framework' -``` - - -#### whenIs - -The `whenIs` method invokes the given closure if the string matches a given pattern. Asterisks may be used as wildcard values. The closure will receive the fluent string instance: - -```php -use Hypervel\Support\Str; -use Hypervel\Support\Stringable; - -$string = Str::of('foo/bar')->whenIs('foo/*', function (Stringable $string) { - return $string->append('/baz'); -}); - -// 'foo/bar/baz' -``` - - -#### whenIsAscii - -The `whenIsAscii` method invokes the given closure if the string is 7 bit ASCII. The closure will receive the fluent string instance: - -```php -use Hypervel\Support\Str; -use Hypervel\Support\Stringable; - -$string = Str::of('laravel')->whenIsAscii(function (Stringable $string) { - return $string->title(); -}); - -// 'Laravel' -``` - - -#### whenIsUlid - -The `whenIsUlid` method invokes the given closure if the string is a valid ULID. The closure will receive the fluent string instance: - -```php -use Hypervel\Support\Str; - -$string = Str::of('01gd6r360bp37zj17nxb55yv40')->whenIsUlid(function (Stringable $string) { - return $string->substr(0, 8); -}); - -// '01gd6r36' -``` - - -#### whenIsUuid - -The `whenIsUuid` method invokes the given closure if the string is a valid UUID. The closure will receive the fluent string instance: - -```php -use Hypervel\Support\Str; -use Hypervel\Support\Stringable; - -$string = Str::of('a0a2a2d2-0b87-4a18-83f2-2529882be2de')->whenIsUuid(function (Stringable $string) { - return $string->substr(0, 8); -}); - -// 'a0a2a2d2' -``` - - -#### whenTest - -The `whenTest` method invokes the given closure if the string matches the given regular expression. The closure will receive the fluent string instance: - -```php -use Hypervel\Support\Str; -use Hypervel\Support\Stringable; - -$string = Str::of('laravel framework')->whenTest('/laravel/', function (Stringable $string) { - return $string->title(); -}); - -// 'Laravel Framework' -``` - - -#### wordCount - -The `wordCount` method returns the number of words that a string contains: - -```php -use Hypervel\Support\Str; - -Str::of('Hello, world!')->wordCount(); // 2 -``` - - -#### words - -The `words` method limits the number of words in a string. If necessary, you may specify an additional string that will be appended to the truncated string: - -```php -use Hypervel\Support\Str; - -$string = Str::of('Perfectly balanced, as all things should be.')->words(3, ' >>>'); - -// Perfectly balanced, as >>> -``` - - -#### wrap - -The `wrap` method wraps the given string with an additional string or pair of strings: - -```php -use Hypervel\Support\Str; - -Str::of('Laravel')->wrap('"'); - -// "Laravel" - -Str::is('is')->wrap(before: 'This ', after: ' Laravel!'); - -// This is Laravel! -``` \ No newline at end of file diff --git a/_archive/docs/0.3/docs/structure.md b/_archive/docs/0.3/docs/structure.md deleted file mode 100644 index 5f4612abca..0000000000 --- a/_archive/docs/0.3/docs/structure.md +++ /dev/null @@ -1,174 +0,0 @@ -# Directory Structure -[[toc]] - -## Introduction - -The default Hypervel application structure follows by Laravel. It can provide you a great starting point for both large and small applications. You're free to organize your application however you like. But some directories such as `bootstrap`, `config`, `database` and `runtime` should remain due to the core design in Hypervel. - -Here's how you directory structure looks like: - -```plaintext:no-line-numbers -├── app -│ ├── Console -│ │ └── Commands -│ ├── Events -│ ├── Exceptions -│ ├── Http -│ │ ├── Controllers -│ │ ├── Middleware -│ │ └── Requests -| |── Jobs -│ ├── Listeners -│ ├── Models -│ └── Providers -├── bootstrap -├── config -├── database -│ ├── factories -│ ├── migrations -│ └── seeders -├── lang -│ ├── en -│ ├── zh_CN -│ └── zh_TW -|── public -|── resources -├── routes -├── runtime -│ └── container -├── storage -│ ├── app -| ├── framework -│ └── logs -└── tests - ├── Feature - └── Unit -``` - -## The Root Directory - -### The App Directory - -The `app` directory contains the core code of your application. We'll explore this directory in more detail soon; however, almost all of the classes in your application will be in this directory. - -### The Bootstrap Directory - -The `bootstrap` directory contains the `app.php` file which bootstraps the framework. - -### The Runtime Directory - -This directory stores files generated by Hypervel during runtime. It houses a `container` directory which contains framework generated files for caching the scanning result. - -### The Config Directory - -The `config` directory, as the name implies, contains all of your application's configuration files. It's a great idea to read through all of these files and familiarize yourself with all of the options available to you. - -::: warning -There's additional `autoload` directory inside `config` in Hyperf. This folder is removed in Hypervel. All the config files are flattened as Laravel does. - -`hyperf.php` is preserved for the compatibility of root configs in Hyperf. All the configs here will not include any prefixes. And all the configs in `config/config.php` are moved to `config/app.php` in Hypervel. -::: - -### The Database Directory - -The `database` directory contains your database migrations, model factories, and seeds. If you wish, you may also use this directory to hold an SQLite database. - -### The Public Directory - -The public directory houses your static assets such as images, JavaScript, and CSS. - -### The Resources Directory - -The `resources` directory contains your [views](/docs/views) as well as your raw, un-compiled assets such as CSS or JavaScript. - -### The Lang Directory - -The `lang` directory contains the translation files. Within this directory, there may be subdirectories for each language supported by the application. This is the approach Hypervel uses to manage translation strings for built-in features such as validation error messages. - -### The Routes Directory - -The `routes` directory contains all of the route definitions for your application. By default, three route files are included with Hypervel: `web.php`, `api.php` and `console.php`. - -The `web.php` file contains routes that serves common requests such as views, files in Hypervel. - -The `api.php` file contains routes that are intended to be stateless, so requests entering the application through these routes are intended to be authenticated and will not have access to session state. - -::: info -Middleware groups are applied to `web.php` and `api.php`, but are kept in empty by default. You can configure them manually if in need. -::: - -The `console.php` file is where you may define all of your closure based console commands. Each closure is bound to a command instance allowing a simple approach to interacting with each command's IO methods. Even though this file does not define HTTP routes, it defines console based entry points (routes) into your application. You may also [schedule](/docs/scheduling) tasks in the `console.php` file. - -### The Storage Directory - -The `storage` directory contains your logs, compiled Blade templates, file caches, and other files generated by the framework. This directory is segregated into `app`, `framework`, and `logs` directories. The `app` directory may be used to store any files generated by your application. The `framework` directory is used to store caches (and framework generated files in the future). Finally, the `logs` directory contains your application's log files. - -The `storage/app/public` directory may be used to store user-generated files, such as profile avatars, that should be publicly accessible. You should create a symbolic link at `public/storage` which points to this directory. - -### The Tests Directory - -The `tests` directory contains your automated tests. Example [PHPUnit](https://phpunit.de/) unit tests and feature tests are provided out of the box. Each test class should be suffixed with the word `Test`. You may run your tests using the `/vendor/bin/phpunit` commands. - -::: note -Pest package is not supported yet. -::: - -## The App Directory - -The majority of your application is housed in the `app` directory. By default, this directory is namespaced under `App` and is autoloaded by Composer using the [PSR-4 autoloading standard](https://www.php-fig.org/psr/psr-4/). - -The `app` directory contains a variety of additional directories such as `Console`, `Http`, and `Providers`. Think of the `Console` and `Http` directories as providing an API into the core of your application. The HTTP protocol and CLI are both mechanisms to interact with your application, but do not actually contain application logic. In other words, they are two ways of issuing commands to your application. The `Console` directory contains all of your Artisan commands, while the `Http` directory contains your controllers, middleware, and requests. - -::: note -Many of the classes in the `app` directory can be generated by Hypervel via commands. To review the available commands, run the `php artisan list make` command in your terminal. -::: - -### The Console Directory - -The `Console` directory contains all of the custom Artisan commands for your application. These commands may be generated using the `make:command` command. This directory also houses your console kernel, which is where your custom Artisan commands are registered and your [scheduled tasks](/docs/scheduling) are defined. - -### The Events Directory - -The `Events` directory houses [event classes](/docs/events). Events may be used to alert other parts of your application that a given action has occurred, providing a great deal of flexibility and decoupling. - -### The Exceptions Directory - -The `Exceptions` directory contains your application's exception handler and is also a good place to place any exceptions thrown by your application. If you would like to customize how your exceptions are logged or rendered, you should modify the Handler class in this directory. - -### The Http Directory - -The `Http` directory contains your controllers, middleware, and form requests. Almost all of the logic to handle requests entering your application will be placed in this directory. - -### The Jobs Directory - -This directory does not exist by default, but will be created for you if you execute the `make:job` Artisan command. The `Jobs` directory houses the [queueable jobs](/docs/queues) for your application. Jobs may be queued by your application or run synchronously within the current request lifecycle. Jobs that run synchronously during the current request are sometimes referred to as "commands" since they are an implementation of the [command pattern](https://en.wikipedia.org/wiki/Command_pattern). - -### The Listeners Directory - -The `Listeners` directory contains the classes that handle your [events](/docs/events). Event listeners receive an event instance and perform logic in response to the event being fired. For example, a `UserRegistered` event might be handled by a `SendWelcomeEmail` listener. If you execute the `make:listener` command, listener classes will be placed in this directory. - -### The Mail Directory - -This directory does not exist by default, but will be created for you if you execute the `make:mail` Artisan command. The `Mail` directory contains all of your [classes that represent emails](/docs/mail) sent by your application. Mail objects allow you to encapsulate all of the logic of building an email in a single, simple class that may be sent using the `Mail::send` method. - -### The Models Directory - -The `Models` directory contains all of your [Eloquent model classes](/docs/eloquent). The Eloquent ORM included with Hypervel provides a beautiful, simple ActiveRecord implementation for working with your database. Each database table has a corresponding "Model" which is used to interact with that table. Models allow you to query for data in your tables, as well as insert new records into the table. - -### The Notifications Directory - -This directory does not exist by default, but will be created for you if you execute the `make:notification` Artisan command. The `Notifications` directory contains all of the "transactional" [notifications](/docs/notifications) that are sent by your application, such as simple notifications about events that happen within your application. Laravel's notification feature abstracts sending notifications over a variety of drivers such as email, Slack, SMS, or stored in a database. - -### The Policies Directory - -This directory does not exist by default, but will be created for you if you execute the `make:policy` Artisan command. The `Policies` directory contains the [authorization policy classes](/docs/authorization) for your application. Policies are used to determine if a user can perform a given action against a resource. - -### The Providers Directory - -The `Providers` directory contains all of the [service providers](/docs/providers) for your application. Service providers bootstrap your application by binding services in the service container, registering events, or performing any other tasks to prepare your application for incoming requests. - -In a fresh Hypervel application, this directory will already contain several providers. You are free to add your own providers to this directory as needed. - -### The Rules Directory - -This directory does not exist by default, but will be created for you if you execute the `make:rule` Artisan command. The `Rules` directory contains the custom validation rule objects for your application. Rules are used to encapsulate complicated validation logic in a simple object. For more information, check out the [validation documentation](/docs/validation). \ No newline at end of file diff --git a/_archive/docs/0.3/docs/telescope.md b/_archive/docs/0.3/docs/telescope.md deleted file mode 100644 index 211900caf2..0000000000 --- a/_archive/docs/0.3/docs/telescope.md +++ /dev/null @@ -1,404 +0,0 @@ -# Hypervel Telescope -[[toc]] - -## Introduction - -[Hypervel Telescope](https://github.com/hypervel/telescope) makes a wonderful companion to your local Hypervel development environment. Telescope provides insight into the requests coming into your application, exceptions, log entries, database queries, queued jobs, mail, notifications, cache operations, scheduled tasks, variable dumps, and more. - -
-
-## Installation
-
-You may use the Composer package manager to install Telescope into your Hypervel project:
-
-```shell
-composer require hypervel/telescope
-```
-
-After installing Telescope, publish its assets and migrations using the `vendor:publish` Artisan command. After installing Telescope, you should also run the `migrate` command in order to create the tables needed to store Telescope's data:
-
-```shell
-php artisan vendor:publish "Hypervel\Telescope\TelescopeServiceProvider"
-
-php artisan migrate
-```
-
-Finally, you may access the Telescope dashboard via the `/telescope` route.
-
-### Local Only Installation
-
-If you plan to only use Telescope to assist your local development, you may install Telescope using the `--dev` flag:
-
-```shell
-composer require hypervel/telescope --dev
-
-php artisan vendor:publish "Hypervel\Telescope\TelescopeServiceProvider"
-
-php artisan migrate
-```
-
-After running `vendor:publish`, you should remove the `TelescopeServiceProvider` service provider registration from your application's `bootstrap/providers.php` configuration file. Instead, manually register Telescope's service providers in the `register` method of your `App\Providers\AppServiceProvider` class. We will ensure the current environment is `local` before registering the providers:
-
-```php
-/**
- * Register any application services.
- */
-public function register(): void
-{
- if ($this->app->environment('local') && class_exists(\Hypervel\Telescope\TelescopeServiceProvider::class)) {
- $this->app->register(\Hypervel\Telescope\TelescopeServiceProvider::class);
- $this->app->register(TelescopeServiceProvider::class);
- }
-}
-```
-
-Finally, you should also prevent the Telescope package from being [auto-discovered](/docs/packages#package-discovery) by adding the following to your `composer.json` file:
-
-```json
-"extra": {
- "hypervel": {
- "dont-discover": [
- "hypervel/telescope"
- ]
- }
-},
-```
-
-### Configuration
-
-After publishing Telescope's assets, its primary configuration file will be located at `config/telescope.php`. This configuration file allows you to configure your [watcher options](#available-watchers). Each configuration option includes a description of its purpose, so be sure to thoroughly explore this file.
-
-If desired, you may disable Telescope's data collection entirely using the `enabled` configuration option:
-
-```php
-'enabled' => env('TELESCOPE_ENABLED', true),
-```
-
-### Data Pruning
-
-Without pruning, the `telescope_entries` table can accumulate records very quickly. To mitigate this, you should [schedule](/docs/scheduling) the `telescope:prune` Artisan command to run daily:
-
-```php
-use Hypervel\Support\Facades\Schedule;
-
-Schedule::command('telescope:prune')->daily();
-```
-
-By default, all entries older than 24 hours will be pruned. You may use the `hours` option when calling the command to determine how long to retain Telescope data. For example, the following command will delete all records created over 48 hours ago:
-
-```php
-use Hypervel\Support\Facades\Schedule;
-
-Schedule::command('telescope:prune --hours=48')->daily();
-```
-
-### Dashboard Authorization
-
-The Telescope dashboard may be accessed via the `/telescope` route. By default, you will only be able to access this dashboard in the `local` environment. Within your `app/Providers/TelescopeServiceProvider.php` file, there is an [authorization gate](/docs/authorization#gates) definition. This authorization gate controls access to Telescope in **non-local** environments. You are free to modify this gate as needed to restrict access to your Telescope installation:
-
-```php
-use App\Models\User;
-
-/**
- * Register the Telescope gate.
- *
- * This gate determines who can access Telescope in non-local environments.
- */
-protected function gate(): void
-{
- Gate::define('viewTelescope', function (User $user) {
- return in_array($user->email, [
- 'albert@hypervel.org',
- ]);
- });
-}
-```
-
-::: warning
-You should ensure you change your `APP_ENV` environment variable to `production` in your production environment. Otherwise, your Telescope installation will be publicly available.
-:::
-
-## Filtering
-
-### Entries
-
-You may filter the data that is recorded by Telescope via the `filter` closure that is defined in your `App\Providers\TelescopeServiceProvider` class. By default, this closure records all data in the `local` environment and exceptions, failed jobs, scheduled tasks, and data with monitored tags in all other environments:
-
-```php
-use Hypervel\Telescope\IncomingEntry;
-use Hypervel\Telescope\Telescope;
-
-/**
- * Register any application services.
- */
-public function register(): void
-{
- $this->hideSensitiveRequestDetails();
-
- Telescope::filter(function (IncomingEntry $entry) {
- if ($this->app->environment('local')) {
- return true;
- }
-
- return $entry->isReportableException() ||
- $entry->isFailedJob() ||
- $entry->isScheduledTask() ||
- $entry->isSlowQuery() ||
- $entry->hasMonitoredTag();
- });
-}
-```
-
-### Batches
-
-While the `filter` closure filters data for individual entries, you may use the `filterBatch` method to register a closure that filters all data for a given request or console command. If the closure returns `true`, all of the entries are recorded by Telescope:
-
-```php
-use Hypervel\Support\Collection;
-use Hypervel\Telescope\IncomingEntry;
-use Hypervel\Telescope\Telescope;
-
-/**
- * Register any application services.
- */
-public function register(): void
-{
- $this->hideSensitiveRequestDetails();
-
- Telescope::filterBatch(function (Collection $entries) {
- if ($this->app->environment('local')) {
- return true;
- }
-
- return $entries->contains(function (IncomingEntry $entry) {
- return $entry->isReportableException() ||
- $entry->isFailedJob() ||
- $entry->isScheduledTask() ||
- $entry->isSlowQuery() ||
- $entry->hasMonitoredTag();
- });
- });
-}
-```
-
-## Tagging
-
-Telescope allows you to search entries by "tag". Often, tags are Eloquent model class names or authenticated user IDs which Telescope automatically adds to entries. Occasionally, you may want to attach your own custom tags to entries. To accomplish this, you may use the `Telescope::tag` method. The `tag` method accepts a closure which should return an array of tags. The tags returned by the closure will be merged with any tags Telescope would automatically attach to the entry. Typically, you should call the `tag` method within the `register` method of your `App\Providers\TelescopeServiceProvider` class:
-
-```php
-use Hypervel\Telescope\IncomingEntry;
-use Hypervel\Telescope\Telescope;
-
-/**
- * Register any application services.
- */
-public function register(): void
-{
- $this->hideSensitiveRequestDetails();
-
- Telescope::tag(function (IncomingEntry $entry) {
- return $entry->type === 'request'
- ? ['status:'.$entry->content['response_status']]
- : [];
- });
-}
-```
-
-## Available Watchers
-
-Telescope "watchers" gather application data when a request or console command is executed. You may customize the list of watchers that you would like to enable within your `config/telescope.php` configuration file:
-
-```php
-'watchers' => [
- Watchers\CacheWatcher::class => true,
- Watchers\CommandWatcher::class => true,
- // ...
-],
-```
-
-Some watchers also allow you to provide additional customization options:
-
-```php
-'watchers' => [
- Watchers\QueryWatcher::class => [
- 'enabled' => env('TELESCOPE_QUERY_WATCHER', true),
- 'slow' => 100,
- ],
- // ...
-],
-```
-
-### Batch Watcher
-
-The batch watcher records information about queued [batches](/docs/queues#job-batching), including the job and connection information.
-
-### Cache Watcher
-
-The cache watcher records data when a cache key is hit, missed, updated and forgotten.
-
-### Client Request Watcher
-
-The client request watcher records all HTTP requests sent via Guzzle's HTTP client.
-
-### Command Watcher
-
-The command watcher records the arguments, options, exit code, and output whenever an Artisan command is executed. If you would like to exclude certain commands from being recorded by the watcher, you may specify the command in the `ignore` option within your `config/telescope.php` file:
-
-```php
-'watchers' => [
- Watchers\CommandWatcher::class => [
- 'enabled' => env('TELESCOPE_COMMAND_WATCHER', true),
- 'ignore' => ['key:generate'],
- ],
- // ...
-]
-```
-
-### Dump Watcher
-
-The dump watcher records and displays your variable dumps in Telescope. When using Hypervel, variables may be dumped using the global `dump` function. The dump watcher tab must be open in a browser for the dump to be recorded, otherwise, the dumps will be ignored by the watcher.
-
-### Event Watcher
-
-The event watcher records the payload, listeners, and broadcast data for any [events](/docs/events) dispatched by your application. The Hypervel framework's internal events are ignored by the Event watcher.
-
-### Exception Watcher
-
-The exception watcher records the data and stack trace for any reportable exceptions that are thrown by your application.
-
-### Gate Watcher
-
-The gate watcher records the data and result of [gate and policy](/docs/authorization) checks by your application. If you would like to exclude certain abilities from being recorded by the watcher, you may specify those in the `ignore_abilities` option in your `config/telescope.php` file:
-
-```php
-'watchers' => [
- Watchers\GateWatcher::class => [
- 'enabled' => env('TELESCOPE_GATE_WATCHER', true),
- 'ignore_abilities' => ['viewNova'],
- ],
- // ...
-],
-```
-
-### HTTP Client Watcher
-
-The HTTP client watcher records outgoing [HTTP client requests](/docs/http-client) made by your application.
-
-### Job Watcher
-
-The job watcher records the data and status of any [jobs](/docs/queues) dispatched by your application.
-
-### Log Watcher
-
-The log watcher records the [log data](/docs/logging) for any logs written by your application.
-
-By default, Telescope will only record logs at the `error` level and above. However, you can modify the `level` option in your application's `config/telescope.php` configuration file to modify this behavior:
-
-```php
-'watchers' => [
- Watchers\LogWatcher::class => [
- 'enabled' => env('TELESCOPE_LOG_WATCHER', true),
- 'level' => 'debug',
- ],
-
- // ...
-],
-```
-
-### Mail Watcher
-
-The mail watcher allows you to view an in-browser preview of [emails](/docs/mail) sent by your application along with their associated data. You may also download the email as an `.eml` file.
-
-### Model Watcher
-
-The model watcher records model changes whenever an Eloquent [model event](/docs/eloquent#events) is dispatched. You may specify which model events should be recorded via the watcher's `events` option:
-
-```php
-'watchers' => [
- Watchers\ModelWatcher::class => [
- 'enabled' => env('TELESCOPE_MODEL_WATCHER', true),
- 'events' => ['eloquent.created*', 'eloquent.updated*'],
- ],
- // ...
-],
-```
-
-If you would like to record the number of models hydrated during a given request, enable the `hydrations` option:
-
-```php
-'watchers' => [
- Watchers\ModelWatcher::class => [
- 'enabled' => env('TELESCOPE_MODEL_WATCHER', true),
- 'events' => ['eloquent.created*', 'eloquent.updated*'],
- 'hydrations' => true,
- ],
- // ...
-],
-```
-
-### Notification Watcher
-
-The notification watcher records all [notifications](/docs/notifications) sent by your application. If the notification triggers an email and you have the mail watcher enabled, the email will also be available for preview on the mail watcher screen.
-
-### Query Watcher
-
-The query watcher records the raw SQL, bindings, and execution time for all queries that are executed by your application. The watcher also tags any queries slower than 100 milliseconds as `slow`. You may customize the slow query threshold using the watcher's `slow` option:
-
-```php
-'watchers' => [
- Watchers\QueryWatcher::class => [
- 'enabled' => env('TELESCOPE_QUERY_WATCHER', true),
- 'slow' => 50,
- ],
- // ...
-],
-```
-
-### Redis Watcher
-
-The Redis watcher records all [Redis](/docs/redis) commands executed by your application. If you are using Redis for caching, cache commands will also be recorded by the Redis watcher.
-
-### Request Watcher
-
-The request watcher records the request, headers, session, and response data associated with any requests handled by the application. You may limit your recorded response data via the `size_limit` (in kilobytes) option:
-
-```php
-'watchers' => [
- Watchers\RequestWatcher::class => [
- 'enabled' => env('TELESCOPE_REQUEST_WATCHER', true),
- 'size_limit' => env('TELESCOPE_RESPONSE_SIZE_LIMIT', 64),
- ],
- // ...
-],
-```
-
-### Schedule Watcher
-
-The schedule watcher records the command and output of any [scheduled tasks](/docs/scheduling) run by your application.
-
-### View Watcher
-
-The view watcher records the [view](/docs/views) name, path, data, and "composers" used when rendering views.
-
-## Displaying User Avatars
-
-The Telescope dashboard displays the user avatar for the user that was authenticated when a given entry was saved. By default, Telescope will retrieve avatars using the Gravatar web service. However, you may customize the avatar URL by registering a callback in your `App\Providers\TelescopeServiceProvider` class. The callback will receive the user's ID and email address and should return the user's avatar image URL:
-
-```php
-use App\Models\User;
-use Hypervel\Telescope\Telescope;
-
-/**
- * Register any application services.
- */
-public function register(): void
-{
- // ...
-
- Telescope::avatar(function (?string $id, ?string $email) {
- return ! is_null($id)
- ? '/avatars/'.User::find($id)->avatar_path
- : '/generic-avatar.jpg';
- });
-}
-```
\ No newline at end of file
diff --git a/_archive/docs/0.3/docs/testbench.md b/_archive/docs/0.3/docs/testbench.md
deleted file mode 100644
index 46df99d72e..0000000000
--- a/_archive/docs/0.3/docs/testbench.md
+++ /dev/null
@@ -1,141 +0,0 @@
-# Packages Toolkit: Testbench
-[[toc]]
-
-## Introduction
-
-Packages Toolkit for Hypervel is a collection of packages that have been designed to write, test, and preview your Hypervel packages.
-
-Before going through the rest of this documentation, please take some time to read the [Package Development](/docs/packages) section of Hypervel's own documentation, if you haven't done so yet.
-
-## Installation
-
-To start using Packages Toolkit for Hypervel you can first install the components:
-
-```shell:no-line-numbers
-composer require --dev hypervel/testbench
-```
-
-## Configuration
-
-The Packages Toolkit for Hypervel uses `testbench.yaml` as a configuration file where you can define the following schemas to be used within Workbench environment:
-
- Name | Type | Description
-:----------------|:----------|:--------------------
- `hypervel` | `string` | Set the path to Hypervel skeleton.
- `providers` | `array` | List of Service Provider classes to be loaded.
- `dont-discover` | `array` | List of packages to be ignored.
- `env` | `array` | Set environment variables to be loaded.
- `purge` | `array` | Configurable `files` and `directories` to be pruned after executing test cases.
- `workbench` | Object | See [Workbench configuration](#workbench-discovery-configuration) for details.
-
-## Basic Usages
-
-For the `testbench` command to understand any required service providers, bootstrappers, environment variables or other options to be used when executing the "artisan" command you need to add the following `testbench.yaml` file on the project root directory.
-
-```yaml
-providers:
- - Hypervel\Package\PackageServiceProvider
-
-dont-discover:
- - hypervel/sanctum
-```
-
-### Hypervel Skeleton
-
-You can use `hypervel` configuration key to set a custom location instead of using the default `vendor/hypervel/testbench/workbench`:
-
-```yaml
-hypervel: ./workbench
-```
-
-To publish the skeleton folder, you can run the following command:
-
-```shell:no-line-numbers
-vendor/bin/testbench-sync workbench
-```
-
-### Service Providers
-
-You can use `providers` configuration key to set an array of service providers to be loaded additionally:
-
-```yaml
-providers:
- - Hypervel\Sanctum\SanctumServiceProvider
- - Workbench\App\Providers\WorkbenchServiceProvider
-```
-
-### Exclude Packages
-
-To exclude specific packages, you can also use `dont-discover` to exclude specific packages from being loaded:
-
-```yaml
-dont-discover:
- - hypervel/html
-```
-
-### Environment Variables
-
-You can use `env` configuration key to set an array of environment variables to be loaded:
-
-```yaml
-env:
- - SEND_QUERIES_TO_RAY=(false)
-```
-
-::: warning
-The `env` environment variables are only applied when using the CLI and will not be used when running tests.
-:::
-
-#### Workbench Discovery Configuration
-
-The `discovers` configuration allows Workbench to discover routes and commands.
-
- Name | Type | Description
-:----------------|:--------------|:--------------------
- `web` | `bool` | Enabling the options allows Workbench to register routes from `workbench/routes/web.php`
- `api` | `bool` | Enabling the options allows Workbench to register routes from `workbench/routes/api.php`
- `commands` | `bool` | Enabling the options allows Workbench to register console commands from `workbench/routes/console.php`
-
-#### Example
-
-```yaml
-workbench:
- discovers:
- web: true
- api: false
- commands: false
-```
-
-## Getting Started
-
-To use Testbench Component, all you need to do is extend `Hypervel\Testbench\TestCase` instead of `PHPUnit\Framework\TestCase`. The fixture app booted by `Hypervel\Testbench\TestCase` is predefined to follow the base application skeleton of Hypervel.
-
-```php
-class TestCase extends \Hypervel\Testbench\TestCase
-{
- //
-}
-```
-
-### PHPUnit Configuration
-
-You can separate your tests in your `phpunit.xml` file by providing different test suites, allowing you to run your Feature tests on demand.
-
-For example:
-
-```yaml
-