update bug daashboards

This commit is contained in:
2026-04-18 19:47:13 +07:00
parent e2fa4d2d7b
commit ef902b2604
271 changed files with 44303 additions and 308 deletions

View File

@@ -34,7 +34,7 @@ public function getDashboardData()
public function yearlySubscriptions() public function yearlySubscriptions()
{ {
$subscriptions = PlanSubscribe::whereYear('created_at', request('year') ?? date('Y')) $subscriptions = PlanSubscribe::whereYear('created_at', request('year') ?? date('Y'))
->selectRaw('MONTHNAME(created_at) as month, SUM(price) as total_amount') ->selectRaw("TO_CHAR(created_at, 'Month') as month, SUM(price) as total_amount")
->groupBy('month') ->groupBy('month')
->get(); ->get();

View File

@@ -33,13 +33,13 @@ public function lossProfit(Request $request)
$salesQuery = DB::table('sales') $salesQuery = DB::table('sales')
->select( ->select(
DB::raw('DATE(saleDate) as date'), DB::raw('"saleDate"::date as date'),
DB::raw('SUM(actual_total_amount) as total_sales'), DB::raw('SUM(actual_total_amount) as total_sales'),
DB::raw('SUM(lossProfit) as total_sale_income') DB::raw('SUM("lossProfit") as total_sale_income')
) )
->where('business_id', $businessId) ->where('business_id', $businessId)
->when($branchId, fn($q) => $q->where('branch_id', $branchId)) ->when($branchId, fn($q) => $q->where('branch_id', $branchId))
->groupBy(DB::raw('DATE(saleDate)')); ->groupBy(DB::raw('"saleDate"::date'));
$this->applyDateFilter($salesQuery, $duration, 'saleDate', $request->from_date, $request->to_date); $this->applyDateFilter($salesQuery, $duration, 'saleDate', $request->from_date, $request->to_date);
@@ -56,12 +56,12 @@ public function lossProfit(Request $request)
$incomeQuery = DB::table('incomes') $incomeQuery = DB::table('incomes')
->select( ->select(
DB::raw('DATE(incomeDate) as date'), DB::raw('"incomeDate"::date as date'),
DB::raw('SUM(amount) as total_incomes') DB::raw('SUM(amount) as total_incomes')
) )
->where('business_id', $businessId) ->where('business_id', $businessId)
->when($branchId, fn($q) => $q->where('branch_id', $branchId)) ->when($branchId, fn($q) => $q->where('branch_id', $branchId))
->groupBy(DB::raw('DATE(incomeDate)')); ->groupBy(DB::raw('"incomeDate"::date'));
$this->applyDateFilter($incomeQuery, $duration, 'incomeDate', $request->from_date, $request->to_date); $this->applyDateFilter($incomeQuery, $duration, 'incomeDate', $request->from_date, $request->to_date);
$dailyIncomes = $incomeQuery->get(); $dailyIncomes = $incomeQuery->get();
@@ -92,12 +92,12 @@ public function lossProfit(Request $request)
if (moduleCheck('HrmAddon')) { if (moduleCheck('HrmAddon')) {
$payrollQuery = DB::table('payrolls') $payrollQuery = DB::table('payrolls')
->select( ->select(
DB::raw('DATE(date) as date'), DB::raw('date::date as date'),
DB::raw('SUM(amount) as total_payrolls') DB::raw('SUM(amount) as total_payrolls')
) )
->where('business_id', $businessId) ->where('business_id', $businessId)
->when($branchId, fn($q) => $q->where('branch_id', $branchId)) ->when($branchId, fn($q) => $q->where('branch_id', $branchId))
->groupBy(DB::raw('DATE(date)')); ->groupBy(DB::raw('date::date'));
$this->applyDateFilter($payrollQuery, $duration, 'date', $request->from_date, $request->to_date); $this->applyDateFilter($payrollQuery, $duration, 'date', $request->from_date, $request->to_date);
$dailyPayrolls = $payrollQuery->get(); $dailyPayrolls = $payrollQuery->get();
@@ -105,12 +105,12 @@ public function lossProfit(Request $request)
$expenseQuery = DB::table('expenses') $expenseQuery = DB::table('expenses')
->select( ->select(
DB::raw('DATE(expenseDate) as date'), DB::raw('"expenseDate"::date as date'),
DB::raw('SUM(amount) as total_expenses_only') DB::raw('SUM(amount) as total_expenses_only')
) )
->where('business_id', $businessId) ->where('business_id', $businessId)
->when($branchId, fn($q) => $q->where('branch_id', $branchId)) ->when($branchId, fn($q) => $q->where('branch_id', $branchId))
->groupBy(DB::raw('DATE(expenseDate)')); ->groupBy(DB::raw('"expenseDate"::date'));
$this->applyDateFilter($expenseQuery, $duration, 'expenseDate', $request->from_date, $request->to_date); $this->applyDateFilter($expenseQuery, $duration, 'expenseDate', $request->from_date, $request->to_date);
$dailyExpenses = $expenseQuery->get(); $dailyExpenses = $expenseQuery->get();

View File

@@ -106,16 +106,16 @@ public function dashboard()
return response()->json(['error' => 'Invalid duration'], 400); return response()->json(['error' => 'Invalid duration'], 400);
} }
// SQL date format for grouping // SQL date format for grouping (PostgreSQL TO_CHAR format)
$dateFormatSQL = match ($format) { $dateFormatSQL = match ($format) {
'H' => '%H', 'H' => 'HH24',
'd' => '%Y-%m-%d', 'd' => 'YYYY-MM-DD',
'M' => '%Y-%m', 'M' => 'YYYY-MM',
default => '%Y-%m-%d', default => 'YYYY-MM-DD',
}; };
// Sales data fetch and map // Sales data fetch and map
$sales_data = Sale::selectRaw("DATE_FORMAT(created_at, '$dateFormatSQL') as date, SUM(totalAmount) as amount") $sales_data = Sale::selectRaw("TO_CHAR(created_at, '$dateFormatSQL') as date, SUM(\"totalAmount\") as amount")
->where('business_id', $business_id) ->where('business_id', $business_id)
->whereBetween('created_at', [$start, $end]) ->whereBetween('created_at', [$start, $end])
->groupBy('date') ->groupBy('date')
@@ -128,7 +128,7 @@ public function dashboard()
->keyBy('date'); ->keyBy('date');
// Purchase data fetch and map // Purchase data fetch and map
$purchase_data = Purchase::selectRaw("DATE_FORMAT(created_at, '$dateFormatSQL') as date, SUM(totalAmount) as amount") $purchase_data = Purchase::selectRaw("TO_CHAR(created_at, '$dateFormatSQL') as date, SUM(\"totalAmount\") as amount")
->where('business_id', $business_id) ->where('business_id', $business_id)
->whereBetween('created_at', [$start, $end]) ->whereBetween('created_at', [$start, $end])
->groupBy('date') ->groupBy('date')

View File

@@ -34,7 +34,7 @@ protected static function boot()
static::creating(function ($transfer) { static::creating(function ($transfer) {
$lastNumber = (int) self::whereNotNull('invoice_no') $lastNumber = (int) self::whereNotNull('invoice_no')
->orderByDesc('id') ->orderByDesc('id')
->value(DB::raw("CAST(SUBSTRING(invoice_no, 4) AS UNSIGNED)")) ?? 0; ->value(DB::raw("CAST(SUBSTRING(invoice_no, 4) AS INTEGER)")) ?? 0;
$transfer->invoice_no = str_pad($lastNumber + 1, 5, '0', STR_PAD_LEFT); $transfer->invoice_no = str_pad($lastNumber + 1, 5, '0', STR_PAD_LEFT);
}); });

342
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "b8877c500627363407035db84e7762b1", "content-hash": "102ef9927311b93f5c6e22956143aee4",
"packages": [ "packages": [
{ {
"name": "ageekdev/laravel-barcode", "name": "ageekdev/laravel-barcode",
@@ -11964,6 +11964,99 @@
}, },
"time": "2025-04-30T06:54:44+00:00" "time": "2025-04-30T06:54:44+00:00"
}, },
{
"name": "knuckleswtf/scribe",
"version": "5.9.0",
"source": {
"type": "git",
"url": "https://github.com/knuckleswtf/scribe.git",
"reference": "170cb6f8c56f1b26db692fdd1f26574b1765c6f7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/knuckleswtf/scribe/zipball/170cb6f8c56f1b26db692fdd1f26574b1765c6f7",
"reference": "170cb6f8c56f1b26db692fdd1f26574b1765c6f7",
"shasum": ""
},
"require": {
"ext-fileinfo": "*",
"ext-json": "*",
"ext-pdo": "*",
"fakerphp/faker": "^1.23.1",
"laravel/framework": "^9.21 || ^10.0 || ^11.0 || ^12.0 || ^13.0",
"league/flysystem": "^3.0",
"mpociot/reflection-docblock": "^1.0.1",
"nikic/php-parser": "^5.0",
"nunomaduro/collision": "^6.0 || ^7.0 || ^8.0",
"parsedown/parsedown": "^1.7",
"php": ">=8.1",
"ramsey/uuid": "^4.2.2",
"shalvah/upgrader": "^0.6.0",
"symfony/var-exporter": "^6.0 || ^7.0 || ^8.0",
"symfony/yaml": "^6.0 || ^7.0 || ^8.0"
},
"replace": {
"mpociot/laravel-apidoc-generator": "*"
},
"require-dev": {
"dms/phpunit-arraysubset-asserts": "^0.5.0",
"laravel/legacy-factories": "^1.3.0",
"laravel/pint": "^1.20",
"league/fractal": "^0.20",
"nikic/fast-route": "^1.3",
"orchestra/testbench": "^7.0 || ^8.0 || ^9.10 || ^10.0 || ^11.0",
"pestphp/pest": "^1.21 || ^2.0 || ^3.0 || ^4.0",
"phpstan/phpstan": "^2.1.5",
"phpunit/phpunit": "^9.0 || ^10.0 || ^11.0 || ^12.0",
"spatie/ray": "^1.41",
"symfony/css-selector": "^6.0 || ^7.0 || ^8.0",
"symfony/dom-crawler": "^6.0 || ^7.0 || ^8.0"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Knuckles\\Scribe\\ScribeServiceProvider"
]
}
},
"autoload": {
"files": [
"src/Config/helpers.php"
],
"psr-4": {
"Knuckles\\Camel\\": "camel/",
"Knuckles\\Scribe\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Shalvah"
}
],
"description": "Generate API documentation for humans from your Laravel codebase.✍",
"homepage": "https://github.com/knuckleswtf/scribe",
"keywords": [
"api",
"documentation",
"laravel"
],
"support": {
"issues": "https://github.com/knuckleswtf/scribe/issues",
"source": "https://github.com/knuckleswtf/scribe/tree/5.9.0"
},
"funding": [
{
"url": "https://patreon.com/shalvah",
"type": "patreon"
}
],
"time": "2026-03-21T00:39:27+00:00"
},
{ {
"name": "laravel/breeze", "name": "laravel/breeze",
"version": "v1.29.1", "version": "v1.29.1",
@@ -12239,6 +12332,59 @@
}, },
"time": "2024-05-16T03:13:13+00:00" "time": "2024-05-16T03:13:13+00:00"
}, },
{
"name": "mpociot/reflection-docblock",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/mpociot/reflection-docblock.git",
"reference": "c8b2e2b1f5cebbb06e2b5ccbf2958f2198867587"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mpociot/reflection-docblock/zipball/c8b2e2b1f5cebbb06e2b5ccbf2958f2198867587",
"reference": "c8b2e2b1f5cebbb06e2b5ccbf2958f2198867587",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"suggest": {
"dflydev/markdown": "~1.0",
"erusev/parsedown": "~1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-0": {
"Mpociot": [
"src/"
]
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mike van Riel",
"email": "mike.vanriel@naenius.com"
}
],
"support": {
"issues": "https://github.com/mpociot/reflection-docblock/issues",
"source": "https://github.com/mpociot/reflection-docblock/tree/master"
},
"time": "2016-06-20T20:53:12+00:00"
},
{ {
"name": "nunomaduro/collision", "name": "nunomaduro/collision",
"version": "v7.12.0", "version": "v7.12.0",
@@ -12335,6 +12481,56 @@
], ],
"time": "2025-03-14T22:35:49+00:00" "time": "2025-03-14T22:35:49+00:00"
}, },
{
"name": "parsedown/parsedown",
"version": "1.8.0",
"source": {
"type": "git",
"url": "https://github.com/parsedown/parsedown.git",
"reference": "96baaad00f71ba04d76e45b4620f54d3beabd6f7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/parsedown/parsedown/zipball/96baaad00f71ba04d76e45b4620f54d3beabd6f7",
"reference": "96baaad00f71ba04d76e45b4620f54d3beabd6f7",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"php": ">=7.1"
},
"require-dev": {
"phpunit/phpunit": "^7.5|^8.5|^9.6"
},
"type": "library",
"autoload": {
"psr-0": {
"Parsedown": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Emanuil Rusev",
"email": "hello@erusev.com",
"homepage": "http://erusev.com"
}
],
"description": "Parser for Markdown.",
"homepage": "http://parsedown.org",
"keywords": [
"markdown",
"parser"
],
"support": {
"issues": "https://github.com/parsedown/parsedown/issues",
"source": "https://github.com/parsedown/parsedown/tree/1.8.0"
},
"time": "2026-02-16T11:41:01+00:00"
},
{ {
"name": "phar-io/manifest", "name": "phar-io/manifest",
"version": "2.0.4", "version": "2.0.4",
@@ -13836,6 +14032,64 @@
], ],
"time": "2023-02-07T11:34:05+00:00" "time": "2023-02-07T11:34:05+00:00"
}, },
{
"name": "shalvah/upgrader",
"version": "0.6.0",
"source": {
"type": "git",
"url": "https://github.com/shalvah/upgrader.git",
"reference": "d95ed17fe9f5e1ee7d47ad835595f1af080a867f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/shalvah/upgrader/zipball/d95ed17fe9f5e1ee7d47ad835595f1af080a867f",
"reference": "d95ed17fe9f5e1ee7d47ad835595f1af080a867f",
"shasum": ""
},
"require": {
"illuminate/support": ">=8.0",
"nikic/php-parser": "^5.0",
"php": ">=8.0"
},
"require-dev": {
"dms/phpunit-arraysubset-asserts": "^0.2.0",
"pestphp/pest": "^1.21",
"phpstan/phpstan": "^1.0",
"spatie/ray": "^1.33"
},
"type": "library",
"autoload": {
"psr-4": {
"Shalvah\\Upgrader\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Shalvah",
"email": "hello@shalvah.me"
}
],
"description": "Create automatic upgrades for your package.",
"homepage": "http://github.com/shalvah/upgrader",
"keywords": [
"upgrade"
],
"support": {
"issues": "https://github.com/shalvah/upgrader/issues",
"source": "https://github.com/shalvah/upgrader/tree/0.6.0"
},
"funding": [
{
"url": "https://patreon.com/shalvah",
"type": "patreon"
}
],
"time": "2024-02-20T11:51:46+00:00"
},
{ {
"name": "spatie/backtrace", "name": "spatie/backtrace",
"version": "1.8.1", "version": "1.8.1",
@@ -14217,6 +14471,86 @@
], ],
"time": "2025-02-20T13:13:55+00:00" "time": "2025-02-20T13:13:55+00:00"
}, },
{
"name": "symfony/var-exporter",
"version": "v8.0.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-exporter.git",
"reference": "15776bb07a91b089037da89f8832fa41d5fa6ec6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/15776bb07a91b089037da89f8832fa41d5fa6ec6",
"reference": "15776bb07a91b089037da89f8832fa41d5fa6ec6",
"shasum": ""
},
"require": {
"php": ">=8.4"
},
"require-dev": {
"symfony/property-access": "^7.4|^8.0",
"symfony/serializer": "^7.4|^8.0",
"symfony/var-dumper": "^7.4|^8.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\VarExporter\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Allows exporting any serializable PHP data structure to plain PHP code",
"homepage": "https://symfony.com",
"keywords": [
"clone",
"construct",
"export",
"hydrate",
"instantiate",
"lazy-loading",
"proxy",
"serialize"
],
"support": {
"source": "https://github.com/symfony/var-exporter/tree/v8.0.8"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://github.com/nicolas-grekas",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2026-03-30T15:14:47+00:00"
},
{ {
"name": "symfony/yaml", "name": "symfony/yaml",
"version": "v7.4.1", "version": "v7.4.1",
@@ -14346,12 +14680,12 @@
], ],
"aliases": [], "aliases": [],
"minimum-stability": "stable", "minimum-stability": "stable",
"stability-flags": [], "stability-flags": {},
"prefer-stable": true, "prefer-stable": true,
"prefer-lowest": false, "prefer-lowest": false,
"platform": { "platform": {
"php": "^8.1" "php": "^8.1"
}, },
"platform-dev": [], "platform-dev": {},
"plugin-api-version": "2.3.0" "plugin-api-version": "2.6.0"
} }

5
vendor/autoload.php vendored
View File

@@ -14,7 +14,10 @@
echo $err; echo $err;
} }
} }
throw new RuntimeException($err); trigger_error(
$err,
E_USER_ERROR
);
} }
require_once __DIR__ . '/composer/autoload_real.php'; require_once __DIR__ . '/composer/autoload_real.php';

View File

@@ -28,7 +28,7 @@ class InstalledVersions
{ {
/** /**
* @var mixed[]|null * @var mixed[]|null
* @psalm-var array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}|array{}|null * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
*/ */
private static $installed; private static $installed;
@@ -39,7 +39,7 @@ class InstalledVersions
/** /**
* @var array[] * @var array[]
* @psalm-var array<string, array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}> * @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/ */
private static $installedByVendor = array(); private static $installedByVendor = array();
@@ -98,7 +98,7 @@ public static function isInstalled($packageName, $includeDevRequirements = true)
{ {
foreach (self::getInstalled() as $installed) { foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) { if (isset($installed['versions'][$packageName])) {
return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']); return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
} }
} }
@@ -119,7 +119,7 @@ public static function isInstalled($packageName, $includeDevRequirements = true)
*/ */
public static function satisfies(VersionParser $parser, $packageName, $constraint) public static function satisfies(VersionParser $parser, $packageName, $constraint)
{ {
$constraint = $parser->parseConstraints($constraint); $constraint = $parser->parseConstraints((string) $constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName)); $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint); return $provided->matches($constraint);
@@ -243,7 +243,7 @@ public static function getInstallPath($packageName)
/** /**
* @return array * @return array
* @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string} * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
*/ */
public static function getRootPackage() public static function getRootPackage()
{ {
@@ -257,7 +257,7 @@ public static function getRootPackage()
* *
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
* @return array[] * @return array[]
* @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>} * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
*/ */
public static function getRawData() public static function getRawData()
{ {
@@ -280,7 +280,7 @@ public static function getRawData()
* Returns the raw data of all installed.php which are currently loaded for custom implementations * Returns the raw data of all installed.php which are currently loaded for custom implementations
* *
* @return array[] * @return array[]
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}> * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/ */
public static function getAllRawData() public static function getAllRawData()
{ {
@@ -303,7 +303,7 @@ public static function getAllRawData()
* @param array[] $data A vendor/composer/installed.php data set * @param array[] $data A vendor/composer/installed.php data set
* @return void * @return void
* *
* @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>} $data * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
*/ */
public static function reload($data) public static function reload($data)
{ {
@@ -313,7 +313,7 @@ public static function reload($data)
/** /**
* @return array[] * @return array[]
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}> * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/ */
private static function getInstalled() private static function getInstalled()
{ {
@@ -322,15 +322,20 @@ private static function getInstalled()
} }
$installed = array(); $installed = array();
$copiedLocalDir = false;
if (self::$canGetVendors) { if (self::$canGetVendors) {
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
if (isset(self::$installedByVendor[$vendorDir])) { if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir]; $installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) { } elseif (is_file($vendorDir.'/composer/installed.php')) {
$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php'; /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { $required = require $vendorDir.'/composer/installed.php';
self::$installed = $installed[count($installed) - 1]; self::$installedByVendor[$vendorDir] = $required;
$installed[] = $required;
if (strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
self::$installed = $required;
$copiedLocalDir = true;
} }
} }
} }
@@ -340,12 +345,17 @@ private static function getInstalled()
// only require the installed.php file if this file is loaded from its dumped location, // only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') { if (substr(__DIR__, -8, 1) !== 'C') {
self::$installed = require __DIR__ . '/installed.php'; /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require __DIR__ . '/installed.php';
self::$installed = $required;
} else { } else {
self::$installed = array(); self::$installed = array();
} }
} }
$installed[] = self::$installed;
if (self::$installed !== array() && !$copiedLocalDir) {
$installed[] = self::$installed;
}
return $installed; return $installed;
} }

View File

@@ -2185,6 +2185,7 @@
'Database\\Seeders\\GatewaySeeder' => $baseDir . '/database/seeders/GatewaySeeder.php', 'Database\\Seeders\\GatewaySeeder' => $baseDir . '/database/seeders/GatewaySeeder.php',
'Database\\Seeders\\IncomeCategorySeeder' => $baseDir . '/database/seeders/IncomeCategorySeeder.php', 'Database\\Seeders\\IncomeCategorySeeder' => $baseDir . '/database/seeders/IncomeCategorySeeder.php',
'Database\\Seeders\\IncomeSeeder' => $baseDir . '/database/seeders/IncomeSeeder.php', 'Database\\Seeders\\IncomeSeeder' => $baseDir . '/database/seeders/IncomeSeeder.php',
'Database\\Seeders\\InitialDataSeeder' => $baseDir . '/database/seeders/InitialDataSeeder.php',
'Database\\Seeders\\InterfaceSeeder' => $baseDir . '/database/seeders/InterfaceSeeder.php', 'Database\\Seeders\\InterfaceSeeder' => $baseDir . '/database/seeders/InterfaceSeeder.php',
'Database\\Seeders\\LanguageSeeder' => $baseDir . '/database/seeders/LanguageSeeder.php', 'Database\\Seeders\\LanguageSeeder' => $baseDir . '/database/seeders/LanguageSeeder.php',
'Database\\Seeders\\OptionTableSeeder' => $baseDir . '/database/seeders/OptionTableSeeder.php', 'Database\\Seeders\\OptionTableSeeder' => $baseDir . '/database/seeders/OptionTableSeeder.php',
@@ -5643,6 +5644,128 @@
'Kavenegar\\Exceptions\\BaseRuntimeException' => $vendorDir . '/kavenegar/php/src/Exceptions/BaseRuntimeException.php', 'Kavenegar\\Exceptions\\BaseRuntimeException' => $vendorDir . '/kavenegar/php/src/Exceptions/BaseRuntimeException.php',
'Kavenegar\\Exceptions\\HttpException' => $vendorDir . '/kavenegar/php/src/Exceptions/HttpException.php', 'Kavenegar\\Exceptions\\HttpException' => $vendorDir . '/kavenegar/php/src/Exceptions/HttpException.php',
'Kavenegar\\KavenegarApi' => $vendorDir . '/kavenegar/php/src/KavenegarApi.php', 'Kavenegar\\KavenegarApi' => $vendorDir . '/kavenegar/php/src/KavenegarApi.php',
'Knuckles\\Camel\\BaseDTO' => $vendorDir . '/knuckleswtf/scribe/camel/BaseDTO.php',
'Knuckles\\Camel\\BaseDTOCollection' => $vendorDir . '/knuckleswtf/scribe/camel/BaseDTOCollection.php',
'Knuckles\\Camel\\Camel' => $vendorDir . '/knuckleswtf/scribe/camel/Camel.php',
'Knuckles\\Camel\\Extraction\\ExtractedEndpointData' => $vendorDir . '/knuckleswtf/scribe/camel/Extraction/ExtractedEndpointData.php',
'Knuckles\\Camel\\Extraction\\Metadata' => $vendorDir . '/knuckleswtf/scribe/camel/Extraction/Metadata.php',
'Knuckles\\Camel\\Extraction\\Parameter' => $vendorDir . '/knuckleswtf/scribe/camel/Extraction/Parameter.php',
'Knuckles\\Camel\\Extraction\\Response' => $vendorDir . '/knuckleswtf/scribe/camel/Extraction/Response.php',
'Knuckles\\Camel\\Extraction\\ResponseCollection' => $vendorDir . '/knuckleswtf/scribe/camel/Extraction/ResponseCollection.php',
'Knuckles\\Camel\\Extraction\\ResponseField' => $vendorDir . '/knuckleswtf/scribe/camel/Extraction/ResponseField.php',
'Knuckles\\Camel\\Output\\OutputEndpointData' => $vendorDir . '/knuckleswtf/scribe/camel/Output/OutputEndpointData.php',
'Knuckles\\Camel\\Output\\Parameter' => $vendorDir . '/knuckleswtf/scribe/camel/Output/Parameter.php',
'Knuckles\\Scribe\\Attributes\\Authenticated' => $vendorDir . '/knuckleswtf/scribe/src/Attributes/Authenticated.php',
'Knuckles\\Scribe\\Attributes\\BodyParam' => $vendorDir . '/knuckleswtf/scribe/src/Attributes/BodyParam.php',
'Knuckles\\Scribe\\Attributes\\Deprecated' => $vendorDir . '/knuckleswtf/scribe/src/Attributes/Deprecated.php',
'Knuckles\\Scribe\\Attributes\\Endpoint' => $vendorDir . '/knuckleswtf/scribe/src/Attributes/Endpoint.php',
'Knuckles\\Scribe\\Attributes\\GenericParam' => $vendorDir . '/knuckleswtf/scribe/src/Attributes/GenericParam.php',
'Knuckles\\Scribe\\Attributes\\Group' => $vendorDir . '/knuckleswtf/scribe/src/Attributes/Group.php',
'Knuckles\\Scribe\\Attributes\\Header' => $vendorDir . '/knuckleswtf/scribe/src/Attributes/Header.php',
'Knuckles\\Scribe\\Attributes\\QueryParam' => $vendorDir . '/knuckleswtf/scribe/src/Attributes/QueryParam.php',
'Knuckles\\Scribe\\Attributes\\Response' => $vendorDir . '/knuckleswtf/scribe/src/Attributes/Response.php',
'Knuckles\\Scribe\\Attributes\\ResponseField' => $vendorDir . '/knuckleswtf/scribe/src/Attributes/ResponseField.php',
'Knuckles\\Scribe\\Attributes\\ResponseFromApiResource' => $vendorDir . '/knuckleswtf/scribe/src/Attributes/ResponseFromApiResource.php',
'Knuckles\\Scribe\\Attributes\\ResponseFromFile' => $vendorDir . '/knuckleswtf/scribe/src/Attributes/ResponseFromFile.php',
'Knuckles\\Scribe\\Attributes\\ResponseFromTransformer' => $vendorDir . '/knuckleswtf/scribe/src/Attributes/ResponseFromTransformer.php',
'Knuckles\\Scribe\\Attributes\\Subgroup' => $vendorDir . '/knuckleswtf/scribe/src/Attributes/Subgroup.php',
'Knuckles\\Scribe\\Attributes\\Unauthenticated' => $vendorDir . '/knuckleswtf/scribe/src/Attributes/Unauthenticated.php',
'Knuckles\\Scribe\\Attributes\\UrlParam' => $vendorDir . '/knuckleswtf/scribe/src/Attributes/UrlParam.php',
'Knuckles\\Scribe\\Commands\\DiffConfig' => $vendorDir . '/knuckleswtf/scribe/src/Commands/DiffConfig.php',
'Knuckles\\Scribe\\Commands\\GenerateDocumentation' => $vendorDir . '/knuckleswtf/scribe/src/Commands/GenerateDocumentation.php',
'Knuckles\\Scribe\\Commands\\MakeStrategy' => $vendorDir . '/knuckleswtf/scribe/src/Commands/MakeStrategy.php',
'Knuckles\\Scribe\\Commands\\Upgrade' => $vendorDir . '/knuckleswtf/scribe/src/Commands/Upgrade.php',
'Knuckles\\Scribe\\Config\\AuthIn' => $vendorDir . '/knuckleswtf/scribe/src/Config/AuthIn.php',
'Knuckles\\Scribe\\Config\\Defaults' => $vendorDir . '/knuckleswtf/scribe/src/Config/Defaults.php',
'Knuckles\\Scribe\\Exceptions\\CouldntFindFactory' => $vendorDir . '/knuckleswtf/scribe/src/Exceptions/CouldntFindFactory.php',
'Knuckles\\Scribe\\Exceptions\\CouldntGetRouteDetails' => $vendorDir . '/knuckleswtf/scribe/src/Exceptions/CouldntGetRouteDetails.php',
'Knuckles\\Scribe\\Exceptions\\CouldntProcessValidationRule' => $vendorDir . '/knuckleswtf/scribe/src/Exceptions/CouldntProcessValidationRule.php',
'Knuckles\\Scribe\\Exceptions\\CouldntStartDatabaseTransaction' => $vendorDir . '/knuckleswtf/scribe/src/Exceptions/CouldntStartDatabaseTransaction.php',
'Knuckles\\Scribe\\Exceptions\\DatabaseTransactionsNotSupported' => $vendorDir . '/knuckleswtf/scribe/src/Exceptions/DatabaseTransactionsNotSupported.php',
'Knuckles\\Scribe\\Exceptions\\GroupNotFound' => $vendorDir . '/knuckleswtf/scribe/src/Exceptions/GroupNotFound.php',
'Knuckles\\Scribe\\Exceptions\\ProblemParsingValidationRules' => $vendorDir . '/knuckleswtf/scribe/src/Exceptions/ProblemParsingValidationRules.php',
'Knuckles\\Scribe\\Exceptions\\ScribeException' => $vendorDir . '/knuckleswtf/scribe/src/Exceptions/ScribeException.php',
'Knuckles\\Scribe\\Extracting\\ApiDetails' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/ApiDetails.php',
'Knuckles\\Scribe\\Extracting\\DatabaseTransactionHelpers' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/DatabaseTransactionHelpers.php',
'Knuckles\\Scribe\\Extracting\\Extractor' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Extractor.php',
'Knuckles\\Scribe\\Extracting\\FindsFormRequestForMethod' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/FindsFormRequestForMethod.php',
'Knuckles\\Scribe\\Extracting\\InstantiatesExampleModels' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/InstantiatesExampleModels.php',
'Knuckles\\Scribe\\Extracting\\MethodAstParser' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/MethodAstParser.php',
'Knuckles\\Scribe\\Extracting\\ParamHelpers' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/ParamHelpers.php',
'Knuckles\\Scribe\\Extracting\\ParsesValidationRules' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/ParsesValidationRules.php',
'Knuckles\\Scribe\\Extracting\\RouteDocBlocker' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/RouteDocBlocker.php',
'Knuckles\\Scribe\\Extracting\\Shared\\ApiResourceResponseTools' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Shared/ApiResourceResponseTools.php',
'Knuckles\\Scribe\\Extracting\\Shared\\ResponseFieldTools' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Shared/ResponseFieldTools.php',
'Knuckles\\Scribe\\Extracting\\Shared\\ResponseFileTools' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Shared/ResponseFileTools.php',
'Knuckles\\Scribe\\Extracting\\Shared\\TransformerResponseTools' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Shared/TransformerResponseTools.php',
'Knuckles\\Scribe\\Extracting\\Shared\\UrlParamsNormalizer' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Shared/UrlParamsNormalizer.php',
'Knuckles\\Scribe\\Extracting\\Shared\\ValidationRulesFinders\\RequestValidate' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Shared/ValidationRulesFinders/RequestValidate.php',
'Knuckles\\Scribe\\Extracting\\Shared\\ValidationRulesFinders\\RequestValidateFacade' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Shared/ValidationRulesFinders/RequestValidateFacade.php',
'Knuckles\\Scribe\\Extracting\\Shared\\ValidationRulesFinders\\ThisValidate' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Shared/ValidationRulesFinders/ThisValidate.php',
'Knuckles\\Scribe\\Extracting\\Shared\\ValidationRulesFinders\\ValidatorMake' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Shared/ValidationRulesFinders/ValidatorMake.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\BodyParameters\\GetFromBodyParamAttribute' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/BodyParameters/GetFromBodyParamAttribute.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\BodyParameters\\GetFromBodyParamTag' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/BodyParameters/GetFromBodyParamTag.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\BodyParameters\\GetFromFormRequest' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/BodyParameters/GetFromFormRequest.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\BodyParameters\\GetFromInlineValidator' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/BodyParameters/GetFromInlineValidator.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\GetFieldsFromTagStrategy' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/GetFieldsFromTagStrategy.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\GetFromFormRequestBase' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/GetFromFormRequestBase.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\GetFromInlineValidatorBase' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/GetFromInlineValidatorBase.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\GetParamsFromAttributeStrategy' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/GetParamsFromAttributeStrategy.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\Headers\\GetFromHeaderAttribute' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/Headers/GetFromHeaderAttribute.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\Headers\\GetFromHeaderTag' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/Headers/GetFromHeaderTag.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\Metadata\\GetFromDocBlocks' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/Metadata/GetFromDocBlocks.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\Metadata\\GetFromMetadataAttributes' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/Metadata/GetFromMetadataAttributes.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\PhpAttributeStrategy' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/PhpAttributeStrategy.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\QueryParameters\\GetFromFormRequest' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/QueryParameters/GetFromFormRequest.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\QueryParameters\\GetFromInlineValidator' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/QueryParameters/GetFromInlineValidator.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\QueryParameters\\GetFromQueryParamAttribute' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/QueryParameters/GetFromQueryParamAttribute.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\QueryParameters\\GetFromQueryParamTag' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/QueryParameters/GetFromQueryParamTag.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\ResponseFields\\GetFromResponseFieldAttribute' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/ResponseFields/GetFromResponseFieldAttribute.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\ResponseFields\\GetFromResponseFieldTag' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/ResponseFields/GetFromResponseFieldTag.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\ResponseCalls' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/Responses/ResponseCalls.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\UseApiResourceTags' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/Responses/UseApiResourceTags.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\UseResponseAttributes' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/Responses/UseResponseAttributes.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\UseResponseFileTag' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/Responses/UseResponseFileTag.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\UseResponseTag' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/Responses/UseResponseTag.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\UseTransformerTags' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/Responses/UseTransformerTags.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\StaticData' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/StaticData.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\Strategy' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/Strategy.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\TagStrategyWithFormRequestFallback' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/TagStrategyWithFormRequestFallback.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\UrlParameters\\GetFromLaravelAPI' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/UrlParameters/GetFromLaravelAPI.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\UrlParameters\\GetFromUrlParamAttribute' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/UrlParameters/GetFromUrlParamAttribute.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\UrlParameters\\GetFromUrlParamTag' => $vendorDir . '/knuckleswtf/scribe/src/Extracting/Strategies/UrlParameters/GetFromUrlParamTag.php',
'Knuckles\\Scribe\\GroupedEndpoints\\GroupedEndpointsContract' => $vendorDir . '/knuckleswtf/scribe/src/GroupedEndpoints/GroupedEndpointsContract.php',
'Knuckles\\Scribe\\GroupedEndpoints\\GroupedEndpointsFactory' => $vendorDir . '/knuckleswtf/scribe/src/GroupedEndpoints/GroupedEndpointsFactory.php',
'Knuckles\\Scribe\\GroupedEndpoints\\GroupedEndpointsFromApp' => $vendorDir . '/knuckleswtf/scribe/src/GroupedEndpoints/GroupedEndpointsFromApp.php',
'Knuckles\\Scribe\\GroupedEndpoints\\GroupedEndpointsFromCamelDir' => $vendorDir . '/knuckleswtf/scribe/src/GroupedEndpoints/GroupedEndpointsFromCamelDir.php',
'Knuckles\\Scribe\\Matching\\MatchedRoute' => $vendorDir . '/knuckleswtf/scribe/src/Matching/MatchedRoute.php',
'Knuckles\\Scribe\\Matching\\RouteMatcher' => $vendorDir . '/knuckleswtf/scribe/src/Matching/RouteMatcher.php',
'Knuckles\\Scribe\\Matching\\RouteMatcherInterface' => $vendorDir . '/knuckleswtf/scribe/src/Matching/RouteMatcherInterface.php',
'Knuckles\\Scribe\\Scribe' => $vendorDir . '/knuckleswtf/scribe/src/Scribe.php',
'Knuckles\\Scribe\\ScribeServiceProvider' => $vendorDir . '/knuckleswtf/scribe/src/ScribeServiceProvider.php',
'Knuckles\\Scribe\\Tools\\AnnotationParser' => $vendorDir . '/knuckleswtf/scribe/src/Tools/AnnotationParser.php',
'Knuckles\\Scribe\\Tools\\BladeMarkdownEngine' => $vendorDir . '/knuckleswtf/scribe/src/Tools/BladeMarkdownEngine.php',
'Knuckles\\Scribe\\Tools\\ConfigDiffer' => $vendorDir . '/knuckleswtf/scribe/src/Tools/ConfigDiffer.php',
'Knuckles\\Scribe\\Tools\\ConsoleOutputUtils' => $vendorDir . '/knuckleswtf/scribe/src/Tools/ConsoleOutputUtils.php',
'Knuckles\\Scribe\\Tools\\DocumentationConfig' => $vendorDir . '/knuckleswtf/scribe/src/Tools/DocumentationConfig.php',
'Knuckles\\Scribe\\Tools\\ErrorHandlingUtils' => $vendorDir . '/knuckleswtf/scribe/src/Tools/ErrorHandlingUtils.php',
'Knuckles\\Scribe\\Tools\\Globals' => $vendorDir . '/knuckleswtf/scribe/src/Tools/Globals.php',
'Knuckles\\Scribe\\Tools\\MarkdownParser' => $vendorDir . '/knuckleswtf/scribe/src/Tools/MarkdownParser.php',
'Knuckles\\Scribe\\Tools\\PathConfig' => $vendorDir . '/knuckleswtf/scribe/src/Tools/PathConfig.php',
'Knuckles\\Scribe\\Tools\\RoutePatternMatcher' => $vendorDir . '/knuckleswtf/scribe/src/Tools/RoutePatternMatcher.php',
'Knuckles\\Scribe\\Tools\\Utils' => $vendorDir . '/knuckleswtf/scribe/src/Tools/Utils.php',
'Knuckles\\Scribe\\Tools\\WritingUtils' => $vendorDir . '/knuckleswtf/scribe/src/Tools/WritingUtils.php',
'Knuckles\\Scribe\\Writing\\CustomTranslationsLoader' => $vendorDir . '/knuckleswtf/scribe/src/Writing/CustomTranslationsLoader.php',
'Knuckles\\Scribe\\Writing\\ExternalHtmlWriter' => $vendorDir . '/knuckleswtf/scribe/src/Writing/ExternalHtmlWriter.php',
'Knuckles\\Scribe\\Writing\\HtmlWriter' => $vendorDir . '/knuckleswtf/scribe/src/Writing/HtmlWriter.php',
'Knuckles\\Scribe\\Writing\\OpenAPISpecWriter' => $vendorDir . '/knuckleswtf/scribe/src/Writing/OpenAPISpecWriter.php',
'Knuckles\\Scribe\\Writing\\OpenApiSpecGenerators\\Base31Generator' => $vendorDir . '/knuckleswtf/scribe/src/Writing/OpenApiSpecGenerators/Base31Generator.php',
'Knuckles\\Scribe\\Writing\\OpenApiSpecGenerators\\BaseGenerator' => $vendorDir . '/knuckleswtf/scribe/src/Writing/OpenApiSpecGenerators/BaseGenerator.php',
'Knuckles\\Scribe\\Writing\\OpenApiSpecGenerators\\OpenApiGenerator' => $vendorDir . '/knuckleswtf/scribe/src/Writing/OpenApiSpecGenerators/OpenApiGenerator.php',
'Knuckles\\Scribe\\Writing\\OpenApiSpecGenerators\\OverridesGenerator' => $vendorDir . '/knuckleswtf/scribe/src/Writing/OpenApiSpecGenerators/OverridesGenerator.php',
'Knuckles\\Scribe\\Writing\\OpenApiSpecGenerators\\SecurityGenerator' => $vendorDir . '/knuckleswtf/scribe/src/Writing/OpenApiSpecGenerators/SecurityGenerator.php',
'Knuckles\\Scribe\\Writing\\PostmanCollectionWriter' => $vendorDir . '/knuckleswtf/scribe/src/Writing/PostmanCollectionWriter.php',
'Knuckles\\Scribe\\Writing\\Writer' => $vendorDir . '/knuckleswtf/scribe/src/Writing/Writer.php',
'Kreait\\Firebase\\AppCheck' => $vendorDir . '/kreait/firebase-php/src/Firebase/AppCheck.php', 'Kreait\\Firebase\\AppCheck' => $vendorDir . '/kreait/firebase-php/src/Firebase/AppCheck.php',
'Kreait\\Firebase\\AppCheck\\ApiClient' => $vendorDir . '/kreait/firebase-php/src/Firebase/AppCheck/ApiClient.php', 'Kreait\\Firebase\\AppCheck\\ApiClient' => $vendorDir . '/kreait/firebase-php/src/Firebase/AppCheck/ApiClient.php',
'Kreait\\Firebase\\AppCheck\\AppCheckToken' => $vendorDir . '/kreait/firebase-php/src/Firebase/AppCheck/AppCheckToken.php', 'Kreait\\Firebase\\AppCheck\\AppCheckToken' => $vendorDir . '/kreait/firebase-php/src/Firebase/AppCheck/AppCheckToken.php',
@@ -6884,6 +7007,133 @@
'Mockery\\Undefined' => $vendorDir . '/mockery/mockery/library/Mockery/Undefined.php', 'Mockery\\Undefined' => $vendorDir . '/mockery/mockery/library/Mockery/Undefined.php',
'Mockery\\VerificationDirector' => $vendorDir . '/mockery/mockery/library/Mockery/VerificationDirector.php', 'Mockery\\VerificationDirector' => $vendorDir . '/mockery/mockery/library/Mockery/VerificationDirector.php',
'Mockery\\VerificationExpectation' => $vendorDir . '/mockery/mockery/library/Mockery/VerificationExpectation.php', 'Mockery\\VerificationExpectation' => $vendorDir . '/mockery/mockery/library/Mockery/VerificationExpectation.php',
'Modules\\Business\\App\\Exports\\ExportBalanceSheet' => $baseDir . '/Modules/Business/App/Exports/ExportBalanceSheet.php',
'Modules\\Business\\App\\Exports\\ExportBillWisePofit' => $baseDir . '/Modules/Business/App/Exports/ExportBillWisePofit.php',
'Modules\\Business\\App\\Exports\\ExportCashFlowReport' => $baseDir . '/Modules/Business/App/Exports/ExportCashFlowReport.php',
'Modules\\Business\\App\\Exports\\ExportComboProduct' => $baseDir . '/Modules/Business/App/Exports/ExportComboProduct.php',
'Modules\\Business\\App\\Exports\\ExportComboProductReport' => $baseDir . '/Modules/Business/App/Exports/ExportComboProductReport.php',
'Modules\\Business\\App\\Exports\\ExportCurrentStock' => $baseDir . '/Modules/Business/App/Exports/ExportCurrentStock.php',
'Modules\\Business\\App\\Exports\\ExportCurrentStockReport' => $baseDir . '/Modules/Business/App/Exports/ExportCurrentStockReport.php',
'Modules\\Business\\App\\Exports\\ExportCustomerLedger' => $baseDir . '/Modules/Business/App/Exports/ExportCustomerLedger.php',
'Modules\\Business\\App\\Exports\\ExportDayBookReport' => $baseDir . '/Modules/Business/App/Exports/ExportDayBookReport.php',
'Modules\\Business\\App\\Exports\\ExportDiscountProduct' => $baseDir . '/Modules/Business/App/Exports/ExportDiscountProduct.php',
'Modules\\Business\\App\\Exports\\ExportDue' => $baseDir . '/Modules/Business/App/Exports/ExportDue.php',
'Modules\\Business\\App\\Exports\\ExportExpense' => $baseDir . '/Modules/Business/App/Exports/ExportExpense.php',
'Modules\\Business\\App\\Exports\\ExportExpiredProduct' => $baseDir . '/Modules/Business/App/Exports/ExportExpiredProduct.php',
'Modules\\Business\\App\\Exports\\ExportExpiredProductReport' => $baseDir . '/Modules/Business/App/Exports/ExportExpiredProductReport.php',
'Modules\\Business\\App\\Exports\\ExportIncome' => $baseDir . '/Modules/Business/App/Exports/ExportIncome.php',
'Modules\\Business\\App\\Exports\\ExportLossProfitHistory' => $baseDir . '/Modules/Business/App/Exports/ExportLossProfitHistory.php',
'Modules\\Business\\App\\Exports\\ExportPartyLossProfit' => $baseDir . '/Modules/Business/App/Exports/ExportPartyLossProfit.php',
'Modules\\Business\\App\\Exports\\ExportProduct' => $baseDir . '/Modules/Business/App/Exports/ExportProduct.php',
'Modules\\Business\\App\\Exports\\ExportProductLossProfit' => $baseDir . '/Modules/Business/App/Exports/ExportProductLossProfit.php',
'Modules\\Business\\App\\Exports\\ExportProductPurchaseHistoryDetailReport' => $baseDir . '/Modules/Business/App/Exports/ExportProductPurchaseHistoryDetailReport.php',
'Modules\\Business\\App\\Exports\\ExportProductPurchaseHistoryReport' => $baseDir . '/Modules/Business/App/Exports/ExportProductPurchaseHistoryReport.php',
'Modules\\Business\\App\\Exports\\ExportProductPurchaseReport' => $baseDir . '/Modules/Business/App/Exports/ExportProductPurchaseReport.php',
'Modules\\Business\\App\\Exports\\ExportProductSaleHistoryDetailReport' => $baseDir . '/Modules/Business/App/Exports/ExportProductSaleHistoryDetailReport.php',
'Modules\\Business\\App\\Exports\\ExportProductSaleHistoryReport' => $baseDir . '/Modules/Business/App/Exports/ExportProductSaleHistoryReport.php',
'Modules\\Business\\App\\Exports\\ExportProductSaleReport' => $baseDir . '/Modules/Business/App/Exports/ExportProductSaleReport.php',
'Modules\\Business\\App\\Exports\\ExportPurchaseReturn' => $baseDir . '/Modules/Business/App/Exports/ExportPurchaseReturn.php',
'Modules\\Business\\App\\Exports\\ExportSaleReport' => $baseDir . '/Modules/Business/App/Exports/ExportSaleReport.php',
'Modules\\Business\\App\\Exports\\ExportSalesReturn' => $baseDir . '/Modules/Business/App/Exports/ExportSalesReturn.php',
'Modules\\Business\\App\\Exports\\ExportSingleCustomerLedger' => $baseDir . '/Modules/Business/App/Exports/ExportSingleCustomerLedger.php',
'Modules\\Business\\App\\Exports\\ExportSingleSupplierLedger' => $baseDir . '/Modules/Business/App/Exports/ExportSingleSupplierLedger.php',
'Modules\\Business\\App\\Exports\\ExportSubscription' => $baseDir . '/Modules/Business/App/Exports/ExportSubscription.php',
'Modules\\Business\\App\\Exports\\ExportSupplierDue' => $baseDir . '/Modules/Business/App/Exports/ExportSupplierDue.php',
'Modules\\Business\\App\\Exports\\ExportSupplierLedger' => $baseDir . '/Modules/Business/App/Exports/ExportSupplierLedger.php',
'Modules\\Business\\App\\Exports\\ExportTopCustomer' => $baseDir . '/Modules/Business/App/Exports/ExportTopCustomer.php',
'Modules\\Business\\App\\Exports\\ExportTopProduct' => $baseDir . '/Modules/Business/App/Exports/ExportTopProduct.php',
'Modules\\Business\\App\\Exports\\ExportTopSupplier' => $baseDir . '/Modules/Business/App/Exports/ExportTopSupplier.php',
'Modules\\Business\\App\\Exports\\ExportTransaction' => $baseDir . '/Modules/Business/App/Exports/ExportTransaction.php',
'Modules\\Business\\App\\Exports\\ExportTransactionReport' => $baseDir . '/Modules/Business/App/Exports/ExportTransactionReport.php',
'Modules\\Business\\App\\Exports\\ExportTransfer' => $baseDir . '/Modules/Business/App/Exports/ExportTransfer.php',
'Modules\\Business\\App\\Exports\\ExportVatReport' => $baseDir . '/Modules/Business/App/Exports/ExportVatReport.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooBalanceSheetController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooBalanceSheetController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooBankController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooBankController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooBillWiseProfitController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooBillWiseProfitController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooBrandController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooBrandController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooCashController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooCashController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooCashFlowReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooCashFlowReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooCategoryController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooCategoryController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooChequeController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooChequeController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooComboProductController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooComboProductController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooComboProductReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooComboProductReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooCommissionController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooCommissionController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooCurrencyController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooCurrencyController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooCustomerLedgerController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooCustomerLedgerController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooDayBookReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooDayBookReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooDiscountProductReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooDiscountProductReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooDueController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooDueController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooDueReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooDueReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooExpenseCategoryController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooExpenseCategoryController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooExpenseController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooExpenseController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooExpenseReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooExpenseReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooExpireProductController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooExpireProductController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooExpireProductReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooExpireProductReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooIncomeCategoryController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooIncomeCategoryController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooIncomeController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooIncomeController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooIncomeReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooIncomeReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooLanguageSettingController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooLanguageSettingController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooLossProfitDetailReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooLossProfitDetailReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooLossProfitHistoryController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooLossProfitHistoryController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooLossProfitHistoryReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooLossProfitHistoryReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooNotificationController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooNotificationController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooPartyController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooPartyController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooPartyLossProfitController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooPartyLossProfitController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooProductController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooProductController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooProductLossProfitReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooProductLossProfitReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooProductModelController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooProductModelController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooProductPurchaseHistoryReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooProductPurchaseHistoryReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooProductPurchaseReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooProductPurchaseReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooProductSaleHistoryReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooProductSaleHistoryReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooProductSaleReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooProductSaleReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooPurchaseController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooPurchaseController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooPurchaseReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooPurchaseReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooPurchaseReturnReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooPurchaseReturnReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooRackController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooRackController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooSaleCommissionController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooSaleCommissionController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooSaleController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooSaleController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooSaleReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooSaleReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooSaleReturnReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooSaleReturnReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooSettingsManagerController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooSettingsManagerController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooShelfController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooShelfController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooStockController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooStockController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooStockReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooStockReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooSubscriptionController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooSubscriptionController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooSubscriptionReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooSubscriptionReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooSupplierDueReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooSupplierDueReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooSupplierLedgerController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooSupplierLedgerController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooTopCustomerController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooTopCustomerController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooTopCustomerReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooTopCustomerReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooTopProductReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooTopProductReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooTopSupplierController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooTopSupplierController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooTopSupplierReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooTopSupplierReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooTransactionController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooTransactionController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooTransactionHistoryReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooTransactionHistoryReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooTransferController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooTransferController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooUnitController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooUnitController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooVariationController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooVariationController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooVatController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooVatController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooVatReportController' => $baseDir . '/Modules/Business/App/Http/Controllers/AcnooVatReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\BankTransactionController' => $baseDir . '/Modules/Business/App/Http/Controllers/BankTransactionController.php',
'Modules\\Business\\App\\Http\\Controllers\\BarcodeGeneratorController' => $baseDir . '/Modules/Business/App/Http/Controllers/BarcodeGeneratorController.php',
'Modules\\Business\\App\\Http\\Controllers\\BulkUploadController' => $baseDir . '/Modules/Business/App/Http/Controllers/BulkUploadController.php',
'Modules\\Business\\App\\Http\\Controllers\\CartController' => $baseDir . '/Modules/Business/App/Http/Controllers/CartController.php',
'Modules\\Business\\App\\Http\\Controllers\\DashboardController' => $baseDir . '/Modules/Business/App/Http/Controllers/DashboardController.php',
'Modules\\Business\\App\\Http\\Controllers\\ProfileController' => $baseDir . '/Modules/Business/App/Http/Controllers/ProfileController.php',
'Modules\\Business\\App\\Http\\Controllers\\PurchaseReturnController' => $baseDir . '/Modules/Business/App/Http/Controllers/PurchaseReturnController.php',
'Modules\\Business\\App\\Http\\Controllers\\SaleReturnController' => $baseDir . '/Modules/Business/App/Http/Controllers/SaleReturnController.php',
'Modules\\Business\\App\\Http\\Controllers\\SettingController' => $baseDir . '/Modules/Business/App/Http/Controllers/SettingController.php',
'Modules\\Business\\App\\Http\\Controllers\\UserRoleController' => $baseDir . '/Modules/Business/App/Http/Controllers/UserRoleController.php',
'Modules\\Business\\App\\Providers\\BusinessServiceProvider' => $baseDir . '/Modules/Business/App/Providers/BusinessServiceProvider.php',
'Modules\\Business\\App\\Providers\\RouteServiceProvider' => $baseDir . '/Modules/Business/App/Providers/RouteServiceProvider.php',
'Modules\\MultiBranchAddon\\App\\Http\\Controllers\\AcnooBranchController' => $baseDir . '/Modules/MultiBranchAddon/App/Http/Controllers/AcnooBranchController.php',
'Modules\\MultiBranchAddon\\App\\Http\\Controllers\\Api\\AcnooBranchController' => $baseDir . '/Modules/MultiBranchAddon/App/Http/Controllers/Api/AcnooBranchController.php',
'Modules\\MultiBranchAddon\\App\\Providers\\MultiBranchAddonServiceProvider' => $baseDir . '/Modules/MultiBranchAddon/App/Providers/MultiBranchAddonServiceProvider.php',
'Modules\\MultiBranchAddon\\App\\Providers\\RouteServiceProvider' => $baseDir . '/Modules/MultiBranchAddon/App/Providers/RouteServiceProvider.php',
'Modules\\WarehouseAddon\\App\\Http\\Controllers\\AcnooWarehouseController' => $baseDir . '/Modules/WarehouseAddon/App/Http/Controllers/AcnooWarehouseController.php',
'Modules\\WarehouseAddon\\App\\Http\\Controllers\\Api\\WarehouseController' => $baseDir . '/Modules/WarehouseAddon/App/Http/Controllers/Api/WarehouseController.php',
'Modules\\WarehouseAddon\\App\\Providers\\RouteServiceProvider' => $baseDir . '/Modules/WarehouseAddon/App/Providers/RouteServiceProvider.php',
'Modules\\WarehouseAddon\\App\\Providers\\WarehouseAddonServiceProvider' => $baseDir . '/Modules/WarehouseAddon/App/Providers/WarehouseAddonServiceProvider.php',
'Mollie\\Api\\CompatibilityChecker' => $vendorDir . '/mollie/mollie-api-php/src/CompatibilityChecker.php', 'Mollie\\Api\\CompatibilityChecker' => $vendorDir . '/mollie/mollie-api-php/src/CompatibilityChecker.php',
'Mollie\\Api\\Endpoints\\BalanceEndpoint' => $vendorDir . '/mollie/mollie-api-php/src/Endpoints/BalanceEndpoint.php', 'Mollie\\Api\\Endpoints\\BalanceEndpoint' => $vendorDir . '/mollie/mollie-api-php/src/Endpoints/BalanceEndpoint.php',
'Mollie\\Api\\Endpoints\\BalanceReportEndpoint' => $vendorDir . '/mollie/mollie-api-php/src/Endpoints/BalanceReportEndpoint.php', 'Mollie\\Api\\Endpoints\\BalanceReportEndpoint' => $vendorDir . '/mollie/mollie-api-php/src/Endpoints/BalanceReportEndpoint.php',
@@ -7433,6 +7683,31 @@
'Mpdf\\Writer\\OptionalContentWriter' => $vendorDir . '/mpdf/mpdf/src/Writer/OptionalContentWriter.php', 'Mpdf\\Writer\\OptionalContentWriter' => $vendorDir . '/mpdf/mpdf/src/Writer/OptionalContentWriter.php',
'Mpdf\\Writer\\PageWriter' => $vendorDir . '/mpdf/mpdf/src/Writer/PageWriter.php', 'Mpdf\\Writer\\PageWriter' => $vendorDir . '/mpdf/mpdf/src/Writer/PageWriter.php',
'Mpdf\\Writer\\ResourceWriter' => $vendorDir . '/mpdf/mpdf/src/Writer/ResourceWriter.php', 'Mpdf\\Writer\\ResourceWriter' => $vendorDir . '/mpdf/mpdf/src/Writer/ResourceWriter.php',
'Mpociot\\Reflection\\DocBlock' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock.php',
'Mpociot\\Reflection\\DocBlock\\Context' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Context.php',
'Mpociot\\Reflection\\DocBlock\\Description' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Description.php',
'Mpociot\\Reflection\\DocBlock\\Location' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Location.php',
'Mpociot\\Reflection\\DocBlock\\Serializer' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Serializer.php',
'Mpociot\\Reflection\\DocBlock\\Tag' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\AuthorTag' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/AuthorTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\CoversTag' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/CoversTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\DeprecatedTag' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/DeprecatedTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\ExampleTag' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/ExampleTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\LinkTag' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/LinkTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\MethodTag' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/MethodTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\ParamTag' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/ParamTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\PropertyReadTag' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/PropertyReadTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\PropertyTag' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/PropertyTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\PropertyWriteTag' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/PropertyWriteTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\ReturnTag' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/ReturnTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\SeeTag' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/SeeTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\SinceTag' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/SinceTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\SourceTag' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/SourceTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\ThrowsTag' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/ThrowsTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\UsesTag' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/UsesTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\VarTag' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/VarTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\VersionTag' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/VersionTag.php',
'Mpociot\\Reflection\\DocBlock\\Type\\Collection' => $vendorDir . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Type/Collection.php',
'Nette\\ArgumentOutOfRangeException' => $vendorDir . '/nette/utils/src/exceptions.php', 'Nette\\ArgumentOutOfRangeException' => $vendorDir . '/nette/utils/src/exceptions.php',
'Nette\\DeprecatedException' => $vendorDir . '/nette/utils/src/exceptions.php', 'Nette\\DeprecatedException' => $vendorDir . '/nette/utils/src/exceptions.php',
'Nette\\DirectoryNotFoundException' => $vendorDir . '/nette/utils/src/exceptions.php', 'Nette\\DirectoryNotFoundException' => $vendorDir . '/nette/utils/src/exceptions.php',
@@ -8694,6 +8969,7 @@
'ParagonIE\\ConstantTime\\Encoding' => $vendorDir . '/paragonie/constant_time_encoding/src/Encoding.php', 'ParagonIE\\ConstantTime\\Encoding' => $vendorDir . '/paragonie/constant_time_encoding/src/Encoding.php',
'ParagonIE\\ConstantTime\\Hex' => $vendorDir . '/paragonie/constant_time_encoding/src/Hex.php', 'ParagonIE\\ConstantTime\\Hex' => $vendorDir . '/paragonie/constant_time_encoding/src/Hex.php',
'ParagonIE\\ConstantTime\\RFC4648' => $vendorDir . '/paragonie/constant_time_encoding/src/RFC4648.php', 'ParagonIE\\ConstantTime\\RFC4648' => $vendorDir . '/paragonie/constant_time_encoding/src/RFC4648.php',
'Parsedown' => $vendorDir . '/parsedown/parsedown/Parsedown.php',
'PharIo\\Manifest\\Application' => $vendorDir . '/phar-io/manifest/src/values/Application.php', 'PharIo\\Manifest\\Application' => $vendorDir . '/phar-io/manifest/src/values/Application.php',
'PharIo\\Manifest\\ApplicationName' => $vendorDir . '/phar-io/manifest/src/values/ApplicationName.php', 'PharIo\\Manifest\\ApplicationName' => $vendorDir . '/phar-io/manifest/src/values/ApplicationName.php',
'PharIo\\Manifest\\Author' => $vendorDir . '/phar-io/manifest/src/values/Author.php', 'PharIo\\Manifest\\Author' => $vendorDir . '/phar-io/manifest/src/values/Author.php',
@@ -10400,6 +10676,11 @@
'SebastianBergmann\\Type\\UnknownType' => $vendorDir . '/sebastian/type/src/type/UnknownType.php', 'SebastianBergmann\\Type\\UnknownType' => $vendorDir . '/sebastian/type/src/type/UnknownType.php',
'SebastianBergmann\\Type\\VoidType' => $vendorDir . '/sebastian/type/src/type/VoidType.php', 'SebastianBergmann\\Type\\VoidType' => $vendorDir . '/sebastian/type/src/type/VoidType.php',
'SebastianBergmann\\Version' => $vendorDir . '/sebastian/version/src/Version.php', 'SebastianBergmann\\Version' => $vendorDir . '/sebastian/version/src/Version.php',
'Shalvah\\Upgrader\\ComparesAstNodes' => $vendorDir . '/shalvah/upgrader/src/ComparesAstNodes.php',
'Shalvah\\Upgrader\\ModifiesAsts' => $vendorDir . '/shalvah/upgrader/src/ModifiesAsts.php',
'Shalvah\\Upgrader\\ReadsAndWritesAsts' => $vendorDir . '/shalvah/upgrader/src/ReadsAndWritesAsts.php',
'Shalvah\\Upgrader\\UnresolveNamespaces' => $vendorDir . '/shalvah/upgrader/src/UnresolveNamespaces.php',
'Shalvah\\Upgrader\\Upgrader' => $vendorDir . '/shalvah/upgrader/src/Upgrader.php',
'SimpleSoftwareIO\\QrCode\\DataTypes\\BTC' => $vendorDir . '/simplesoftwareio/simple-qrcode/src/DataTypes/BTC.php', 'SimpleSoftwareIO\\QrCode\\DataTypes\\BTC' => $vendorDir . '/simplesoftwareio/simple-qrcode/src/DataTypes/BTC.php',
'SimpleSoftwareIO\\QrCode\\DataTypes\\DataTypeInterface' => $vendorDir . '/simplesoftwareio/simple-qrcode/src/DataTypes/DataTypeInterface.php', 'SimpleSoftwareIO\\QrCode\\DataTypes\\DataTypeInterface' => $vendorDir . '/simplesoftwareio/simple-qrcode/src/DataTypes/DataTypeInterface.php',
'SimpleSoftwareIO\\QrCode\\DataTypes\\Email' => $vendorDir . '/simplesoftwareio/simple-qrcode/src/DataTypes/Email.php', 'SimpleSoftwareIO\\QrCode\\DataTypes\\Email' => $vendorDir . '/simplesoftwareio/simple-qrcode/src/DataTypes/Email.php',
@@ -12004,6 +12285,24 @@
'Symfony\\Component\\VarDumper\\Server\\DumpServer' => $vendorDir . '/symfony/var-dumper/Server/DumpServer.php', 'Symfony\\Component\\VarDumper\\Server\\DumpServer' => $vendorDir . '/symfony/var-dumper/Server/DumpServer.php',
'Symfony\\Component\\VarDumper\\Test\\VarDumperTestTrait' => $vendorDir . '/symfony/var-dumper/Test/VarDumperTestTrait.php', 'Symfony\\Component\\VarDumper\\Test\\VarDumperTestTrait' => $vendorDir . '/symfony/var-dumper/Test/VarDumperTestTrait.php',
'Symfony\\Component\\VarDumper\\VarDumper' => $vendorDir . '/symfony/var-dumper/VarDumper.php', 'Symfony\\Component\\VarDumper\\VarDumper' => $vendorDir . '/symfony/var-dumper/VarDumper.php',
'Symfony\\Component\\VarExporter\\Exception\\ClassNotFoundException' => $vendorDir . '/symfony/var-exporter/Exception/ClassNotFoundException.php',
'Symfony\\Component\\VarExporter\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/var-exporter/Exception/ExceptionInterface.php',
'Symfony\\Component\\VarExporter\\Exception\\LogicException' => $vendorDir . '/symfony/var-exporter/Exception/LogicException.php',
'Symfony\\Component\\VarExporter\\Exception\\NotInstantiableTypeException' => $vendorDir . '/symfony/var-exporter/Exception/NotInstantiableTypeException.php',
'Symfony\\Component\\VarExporter\\Hydrator' => $vendorDir . '/symfony/var-exporter/Hydrator.php',
'Symfony\\Component\\VarExporter\\Instantiator' => $vendorDir . '/symfony/var-exporter/Instantiator.php',
'Symfony\\Component\\VarExporter\\Internal\\Exporter' => $vendorDir . '/symfony/var-exporter/Internal/Exporter.php',
'Symfony\\Component\\VarExporter\\Internal\\Hydrator' => $vendorDir . '/symfony/var-exporter/Internal/Hydrator.php',
'Symfony\\Component\\VarExporter\\Internal\\LazyDecoratorTrait' => $vendorDir . '/symfony/var-exporter/Internal/LazyDecoratorTrait.php',
'Symfony\\Component\\VarExporter\\Internal\\LazyObjectRegistry' => $vendorDir . '/symfony/var-exporter/Internal/LazyObjectRegistry.php',
'Symfony\\Component\\VarExporter\\Internal\\LazyObjectState' => $vendorDir . '/symfony/var-exporter/Internal/LazyObjectState.php',
'Symfony\\Component\\VarExporter\\Internal\\NamedClosure' => $vendorDir . '/symfony/var-exporter/Internal/NamedClosure.php',
'Symfony\\Component\\VarExporter\\Internal\\Reference' => $vendorDir . '/symfony/var-exporter/Internal/Reference.php',
'Symfony\\Component\\VarExporter\\Internal\\Registry' => $vendorDir . '/symfony/var-exporter/Internal/Registry.php',
'Symfony\\Component\\VarExporter\\Internal\\Values' => $vendorDir . '/symfony/var-exporter/Internal/Values.php',
'Symfony\\Component\\VarExporter\\LazyObjectInterface' => $vendorDir . '/symfony/var-exporter/LazyObjectInterface.php',
'Symfony\\Component\\VarExporter\\ProxyHelper' => $vendorDir . '/symfony/var-exporter/ProxyHelper.php',
'Symfony\\Component\\VarExporter\\VarExporter' => $vendorDir . '/symfony/var-exporter/VarExporter.php',
'Symfony\\Component\\Yaml\\Command\\LintCommand' => $vendorDir . '/symfony/yaml/Command/LintCommand.php', 'Symfony\\Component\\Yaml\\Command\\LintCommand' => $vendorDir . '/symfony/yaml/Command/LintCommand.php',
'Symfony\\Component\\Yaml\\Dumper' => $vendorDir . '/symfony/yaml/Dumper.php', 'Symfony\\Component\\Yaml\\Dumper' => $vendorDir . '/symfony/yaml/Dumper.php',
'Symfony\\Component\\Yaml\\Escaper' => $vendorDir . '/symfony/yaml/Escaper.php', 'Symfony\\Component\\Yaml\\Escaper' => $vendorDir . '/symfony/yaml/Escaper.php',

View File

@@ -9,9 +9,9 @@
'6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php', '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php', '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php', 'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php',
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
'8825ede83f2f289127722d4e842cf7e8' => $vendorDir . '/symfony/polyfill-intl-grapheme/bootstrap.php', '8825ede83f2f289127722d4e842cf7e8' => $vendorDir . '/symfony/polyfill-intl-grapheme/bootstrap.php',
'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php', 'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php',
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php', '667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
@@ -20,6 +20,7 @@
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
'e39a8b23c42d4e1452234d762b03835a' => $vendorDir . '/ramsey/uuid/src/functions.php', 'e39a8b23c42d4e1452234d762b03835a' => $vendorDir . '/ramsey/uuid/src/functions.php',
'9c67151ae59aff4788964ce8eb2a0f43' => $vendorDir . '/clue/stream-filter/src/functions_include.php', '9c67151ae59aff4788964ce8eb2a0f43' => $vendorDir . '/clue/stream-filter/src/functions_include.php',
'35a6ad97d21e794e7e22a17d806652e4' => $vendorDir . '/nunomaduro/termwind/src/Functions.php',
'8cff32064859f4559445b89279f3199c' => $vendorDir . '/php-http/message/src/filters.php', '8cff32064859f4559445b89279f3199c' => $vendorDir . '/php-http/message/src/filters.php',
'72243e5536b63e298acb6476f01f1aff' => $vendorDir . '/thecodingmachine/safe/lib/special_cases.php', '72243e5536b63e298acb6476f01f1aff' => $vendorDir . '/thecodingmachine/safe/lib/special_cases.php',
'3f648889e687f31c52f949ba8a9d0873' => $vendorDir . '/thecodingmachine/safe/generated/apache.php', '3f648889e687f31c52f949ba8a9d0873' => $vendorDir . '/thecodingmachine/safe/generated/apache.php',
@@ -102,29 +103,29 @@
'fe43ca06499ac37bc2dedd823af71eb5' => $vendorDir . '/thecodingmachine/safe/generated/zip.php', 'fe43ca06499ac37bc2dedd823af71eb5' => $vendorDir . '/thecodingmachine/safe/generated/zip.php',
'356736db98a6834f0a886b8d509b0ecd' => $vendorDir . '/thecodingmachine/safe/generated/zlib.php', '356736db98a6834f0a886b8d509b0ecd' => $vendorDir . '/thecodingmachine/safe/generated/zlib.php',
'1232758e40b1d31bb295b6907de02c63' => $vendorDir . '/beste/clock/src/Clock.php', '1232758e40b1d31bb295b6907de02c63' => $vendorDir . '/beste/clock/src/Clock.php',
'2cffec82183ee1cea088009cef9a6fc3' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
'b067bc7112e384b61c701452d53a14a8' => $vendorDir . '/mtdowling/jmespath.php/src/JmesPath.php',
'6124b4c8570aa390c21fafd04a26c69f' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
'35a6ad97d21e794e7e22a17d806652e4' => $vendorDir . '/nunomaduro/termwind/src/Functions.php',
'3bd81c9b8fcc150b69d8b63b4d2ccf23' => $vendorDir . '/spatie/flare-client-php/src/helpers.php',
'09f6b20656683369174dd6fa83b7e5fb' => $vendorDir . '/symfony/polyfill-uuid/bootstrap.php', '09f6b20656683369174dd6fa83b7e5fb' => $vendorDir . '/symfony/polyfill-uuid/bootstrap.php',
'a1105708a18b76903365ca1c4aa61b02' => $vendorDir . '/symfony/translation/Resources/functions.php', 'a1105708a18b76903365ca1c4aa61b02' => $vendorDir . '/symfony/translation/Resources/functions.php',
'06b8a576aaa70a8517a94b7ff6b37e5c' => $vendorDir . '/beste/json/src/Json.php', '2cffec82183ee1cea088009cef9a6fc3' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
'47e1160838b5e5a10346ac4084b58c23' => $vendorDir . '/laravel/prompts/src/helpers.php', '47e1160838b5e5a10346ac4084b58c23' => $vendorDir . '/laravel/prompts/src/helpers.php',
'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php', 'b067bc7112e384b61c701452d53a14a8' => $vendorDir . '/mtdowling/jmespath.php/src/JmesPath.php',
'801c31d8ed748cfa537fa45402288c95' => $vendorDir . '/psy/psysh/src/functions.php', '6124b4c8570aa390c21fafd04a26c69f' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
'941748b3c8cae4466c827dfb5ca9602a' => $vendorDir . '/rmccue/requests/library/Deprecated.php', '3bd81c9b8fcc150b69d8b63b4d2ccf23' => $vendorDir . '/spatie/flare-client-php/src/helpers.php',
'8a9dc1de0ca7e01f3e08231539562f61' => $vendorDir . '/aws/aws-sdk-php/src/functions.php', '06b8a576aaa70a8517a94b7ff6b37e5c' => $vendorDir . '/beste/json/src/Json.php',
'476ca15b8d69b04665cd879be9cb4c68' => $vendorDir . '/laravel/framework/src/Illuminate/Collections/functions.php', '476ca15b8d69b04665cd879be9cb4c68' => $vendorDir . '/laravel/framework/src/Illuminate/Collections/functions.php',
'265b4faa2b3a9766332744949e83bf97' => $vendorDir . '/laravel/framework/src/Illuminate/Collections/helpers.php', '265b4faa2b3a9766332744949e83bf97' => $vendorDir . '/laravel/framework/src/Illuminate/Collections/helpers.php',
'c7a3c339e7e14b60e06a2d7fcce9476b' => $vendorDir . '/laravel/framework/src/Illuminate/Events/functions.php', 'c7a3c339e7e14b60e06a2d7fcce9476b' => $vendorDir . '/laravel/framework/src/Illuminate/Events/functions.php',
'f57d353b41eb2e234b26064d63d8c5dd' => $vendorDir . '/laravel/framework/src/Illuminate/Filesystem/functions.php', 'f57d353b41eb2e234b26064d63d8c5dd' => $vendorDir . '/laravel/framework/src/Illuminate/Filesystem/functions.php',
'f0906e6318348a765ffb6eb24e0d0938' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/helpers.php', 'f0906e6318348a765ffb6eb24e0d0938' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/helpers.php',
'58571171fd5812e6e447dce228f52f4d' => $vendorDir . '/laravel/framework/src/Illuminate/Support/helpers.php', '58571171fd5812e6e447dce228f52f4d' => $vendorDir . '/laravel/framework/src/Illuminate/Support/helpers.php',
'a1cfe24d14977df6878b9bf804af2d1c' => $vendorDir . '/nunomaduro/collision/src/Adapters/Phpunit/Autoload.php',
'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
'801c31d8ed748cfa537fa45402288c95' => $vendorDir . '/psy/psysh/src/functions.php',
'941748b3c8cae4466c827dfb5ca9602a' => $vendorDir . '/rmccue/requests/library/Deprecated.php',
'8a9dc1de0ca7e01f3e08231539562f61' => $vendorDir . '/aws/aws-sdk-php/src/functions.php',
'ec68c9e7f9b5773fa8c153a5386409da' => $vendorDir . '/knuckleswtf/scribe/src/Config/helpers.php',
'c72349b1fe8d0deeedd3a52e8aa814d8' => $vendorDir . '/mockery/mockery/library/helpers.php', 'c72349b1fe8d0deeedd3a52e8aa814d8' => $vendorDir . '/mockery/mockery/library/helpers.php',
'ce9671a430e4846b44e1c68c7611f9f5' => $vendorDir . '/mockery/mockery/library/Mockery.php', 'ce9671a430e4846b44e1c68c7611f9f5' => $vendorDir . '/mockery/mockery/library/Mockery.php',
'db356362850385d08a5381de2638b5fd' => $vendorDir . '/mpdf/mpdf/src/functions.php', 'db356362850385d08a5381de2638b5fd' => $vendorDir . '/mpdf/mpdf/src/functions.php',
'a1cfe24d14977df6878b9bf804af2d1c' => $vendorDir . '/nunomaduro/collision/src/Adapters/Phpunit/Autoload.php',
'9f394da3192a168c4633675768d80428' => $vendorDir . '/nwidart/laravel-modules/src/helpers.php', '9f394da3192a168c4633675768d80428' => $vendorDir . '/nwidart/laravel-modules/src/helpers.php',
'ec07570ca5a812141189b1fa81503674' => $vendorDir . '/phpunit/phpunit/src/Framework/Assert/Functions.php', 'ec07570ca5a812141189b1fa81503674' => $vendorDir . '/phpunit/phpunit/src/Framework/Assert/Functions.php',
'13906c19e3d8fcd1341b24ed4d51cf72' => $vendorDir . '/razorpay/razorpay/Deprecated.php', '13906c19e3d8fcd1341b24ed4d51cf72' => $vendorDir . '/razorpay/razorpay/Deprecated.php',

View File

@@ -6,5 +6,7 @@
$baseDir = dirname($vendorDir); $baseDir = dirname($vendorDir);
return array( return array(
'Parsedown' => array($vendorDir . '/parsedown/parsedown'),
'Mpociot' => array($vendorDir . '/mpociot/reflection-docblock/src'),
'HTMLPurifier' => array($vendorDir . '/ezyang/htmlpurifier/library'), 'HTMLPurifier' => array($vendorDir . '/ezyang/htmlpurifier/library'),
); );

View File

@@ -31,6 +31,7 @@
'Symfony\\Contracts\\Service\\' => array($vendorDir . '/symfony/service-contracts'), 'Symfony\\Contracts\\Service\\' => array($vendorDir . '/symfony/service-contracts'),
'Symfony\\Contracts\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher-contracts'), 'Symfony\\Contracts\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher-contracts'),
'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'), 'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'),
'Symfony\\Component\\VarExporter\\' => array($vendorDir . '/symfony/var-exporter'),
'Symfony\\Component\\VarDumper\\' => array($vendorDir . '/symfony/var-dumper'), 'Symfony\\Component\\VarDumper\\' => array($vendorDir . '/symfony/var-dumper'),
'Symfony\\Component\\Uid\\' => array($vendorDir . '/symfony/uid'), 'Symfony\\Component\\Uid\\' => array($vendorDir . '/symfony/uid'),
'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'), 'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'),
@@ -50,13 +51,14 @@
'Svg\\' => array($vendorDir . '/dompdf/php-svg-lib/src/Svg'), 'Svg\\' => array($vendorDir . '/dompdf/php-svg-lib/src/Svg'),
'Stripe\\' => array($vendorDir . '/stripe/stripe-php/lib'), 'Stripe\\' => array($vendorDir . '/stripe/stripe-php/lib'),
'Spatie\\Permission\\' => array($vendorDir . '/spatie/laravel-permission/src'), 'Spatie\\Permission\\' => array($vendorDir . '/spatie/laravel-permission/src'),
'Spatie\\LaravelIgnition\\' => array($vendorDir . '/spatie/laravel-ignition/src', $vendorDir . '/spatie/error-solutions/legacy/laravel-ignition'), 'Spatie\\LaravelIgnition\\' => array($vendorDir . '/spatie/error-solutions/legacy/laravel-ignition', $vendorDir . '/spatie/laravel-ignition/src'),
'Spatie\\Ignition\\' => array($vendorDir . '/spatie/ignition/src', $vendorDir . '/spatie/error-solutions/legacy/ignition'), 'Spatie\\Ignition\\' => array($vendorDir . '/spatie/error-solutions/legacy/ignition', $vendorDir . '/spatie/ignition/src'),
'Spatie\\FlareClient\\' => array($vendorDir . '/spatie/flare-client-php/src'), 'Spatie\\FlareClient\\' => array($vendorDir . '/spatie/flare-client-php/src'),
'Spatie\\ErrorSolutions\\' => array($vendorDir . '/spatie/error-solutions/src'), 'Spatie\\ErrorSolutions\\' => array($vendorDir . '/spatie/error-solutions/src'),
'Spatie\\Color\\' => array($vendorDir . '/spatie/color/src'), 'Spatie\\Color\\' => array($vendorDir . '/spatie/color/src'),
'Spatie\\Backtrace\\' => array($vendorDir . '/spatie/backtrace/src'), 'Spatie\\Backtrace\\' => array($vendorDir . '/spatie/backtrace/src'),
'SimpleSoftwareIO\\QrCode\\' => array($vendorDir . '/simplesoftwareio/simple-qrcode/src'), 'SimpleSoftwareIO\\QrCode\\' => array($vendorDir . '/simplesoftwareio/simple-qrcode/src'),
'Shalvah\\Upgrader\\' => array($vendorDir . '/shalvah/upgrader/src'),
'Sabberworm\\CSS\\' => array($vendorDir . '/sabberworm/php-css-parser/src'), 'Sabberworm\\CSS\\' => array($vendorDir . '/sabberworm/php-css-parser/src'),
'SMSGatewayMe\\Client\\' => array($vendorDir . '/smsgatewayme/client/lib'), 'SMSGatewayMe\\Client\\' => array($vendorDir . '/smsgatewayme/client/lib'),
'Rize\\' => array($vendorDir . '/rize/uri-template/src/Rize'), 'Rize\\' => array($vendorDir . '/rize/uri-template/src/Rize'),
@@ -113,13 +115,15 @@
'Laravel\\Breeze\\' => array($vendorDir . '/laravel/breeze/src'), 'Laravel\\Breeze\\' => array($vendorDir . '/laravel/breeze/src'),
'Kreait\\Firebase\\JWT\\' => array($vendorDir . '/kreait/firebase-tokens/src/JWT'), 'Kreait\\Firebase\\JWT\\' => array($vendorDir . '/kreait/firebase-tokens/src/JWT'),
'Kreait\\Firebase\\' => array($vendorDir . '/kreait/firebase-php/src/Firebase'), 'Kreait\\Firebase\\' => array($vendorDir . '/kreait/firebase-php/src/Firebase'),
'Knuckles\\Scribe\\' => array($vendorDir . '/knuckleswtf/scribe/src'),
'Knuckles\\Camel\\' => array($vendorDir . '/knuckleswtf/scribe/camel'),
'Kavenegar\\' => array($vendorDir . '/kavenegar/php/src'), 'Kavenegar\\' => array($vendorDir . '/kavenegar/php/src'),
'Karim007\\LaravelBkashTokenize\\' => array($vendorDir . '/karim007/laravel-bkash-tokenize/src'), 'Karim007\\LaravelBkashTokenize\\' => array($vendorDir . '/karim007/laravel-bkash-tokenize/src'),
'JmesPath\\' => array($vendorDir . '/mtdowling/jmespath.php/src'), 'JmesPath\\' => array($vendorDir . '/mtdowling/jmespath.php/src'),
'Illuminate\\Support\\' => array($vendorDir . '/laravel/framework/src/Illuminate/Macroable', $vendorDir . '/laravel/framework/src/Illuminate/Collections', $vendorDir . '/laravel/framework/src/Illuminate/Conditionable'), 'Illuminate\\Support\\' => array($vendorDir . '/laravel/framework/src/Illuminate/Macroable', $vendorDir . '/laravel/framework/src/Illuminate/Collections', $vendorDir . '/laravel/framework/src/Illuminate/Conditionable'),
'Illuminate\\' => array($vendorDir . '/laravel/framework/src/Illuminate'), 'Illuminate\\' => array($vendorDir . '/laravel/framework/src/Illuminate'),
'Http\\Promise\\' => array($vendorDir . '/php-http/promise/src'), 'Http\\Promise\\' => array($vendorDir . '/php-http/promise/src'),
'Http\\Message\\' => array($vendorDir . '/php-http/message-factory/src', $vendorDir . '/php-http/message/src'), 'Http\\Message\\' => array($vendorDir . '/php-http/message/src', $vendorDir . '/php-http/message-factory/src'),
'Http\\Discovery\\' => array($vendorDir . '/php-http/discovery/src'), 'Http\\Discovery\\' => array($vendorDir . '/php-http/discovery/src'),
'Http\\Client\\' => array($vendorDir . '/php-http/httplug/src'), 'Http\\Client\\' => array($vendorDir . '/php-http/httplug/src'),
'Http\\Adapter\\Guzzle7\\' => array($vendorDir . '/php-http/guzzle7-adapter/src'), 'Http\\Adapter\\Guzzle7\\' => array($vendorDir . '/php-http/guzzle7-adapter/src'),

View File

@@ -22,8 +22,6 @@ public static function getLoader()
return self::$loader; return self::$loader;
} }
require __DIR__ . '/platform_check.php';
spl_autoload_register(array('ComposerAutoloaderInite18b3d3bc6afaf5dd5c2b53c80a29450', 'loadClassLoader'), true, true); spl_autoload_register(array('ComposerAutoloaderInite18b3d3bc6afaf5dd5c2b53c80a29450', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInite18b3d3bc6afaf5dd5c2b53c80a29450', 'loadClassLoader')); spl_autoload_unregister(array('ComposerAutoloaderInite18b3d3bc6afaf5dd5c2b53c80a29450', 'loadClassLoader'));

View File

@@ -10,9 +10,9 @@ class ComposerStaticInite18b3d3bc6afaf5dd5c2b53c80a29450
'6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php', '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php', 'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php',
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
'8825ede83f2f289127722d4e842cf7e8' => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme/bootstrap.php', '8825ede83f2f289127722d4e842cf7e8' => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme/bootstrap.php',
'b6b991a57620e2fb6b2f66f03fe9ddc2' => __DIR__ . '/..' . '/symfony/string/Resources/functions.php', 'b6b991a57620e2fb6b2f66f03fe9ddc2' => __DIR__ . '/..' . '/symfony/string/Resources/functions.php',
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php', '667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
@@ -21,6 +21,7 @@ class ComposerStaticInite18b3d3bc6afaf5dd5c2b53c80a29450
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
'e39a8b23c42d4e1452234d762b03835a' => __DIR__ . '/..' . '/ramsey/uuid/src/functions.php', 'e39a8b23c42d4e1452234d762b03835a' => __DIR__ . '/..' . '/ramsey/uuid/src/functions.php',
'9c67151ae59aff4788964ce8eb2a0f43' => __DIR__ . '/..' . '/clue/stream-filter/src/functions_include.php', '9c67151ae59aff4788964ce8eb2a0f43' => __DIR__ . '/..' . '/clue/stream-filter/src/functions_include.php',
'35a6ad97d21e794e7e22a17d806652e4' => __DIR__ . '/..' . '/nunomaduro/termwind/src/Functions.php',
'8cff32064859f4559445b89279f3199c' => __DIR__ . '/..' . '/php-http/message/src/filters.php', '8cff32064859f4559445b89279f3199c' => __DIR__ . '/..' . '/php-http/message/src/filters.php',
'72243e5536b63e298acb6476f01f1aff' => __DIR__ . '/..' . '/thecodingmachine/safe/lib/special_cases.php', '72243e5536b63e298acb6476f01f1aff' => __DIR__ . '/..' . '/thecodingmachine/safe/lib/special_cases.php',
'3f648889e687f31c52f949ba8a9d0873' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/apache.php', '3f648889e687f31c52f949ba8a9d0873' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/apache.php',
@@ -103,29 +104,29 @@ class ComposerStaticInite18b3d3bc6afaf5dd5c2b53c80a29450
'fe43ca06499ac37bc2dedd823af71eb5' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/zip.php', 'fe43ca06499ac37bc2dedd823af71eb5' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/zip.php',
'356736db98a6834f0a886b8d509b0ecd' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/zlib.php', '356736db98a6834f0a886b8d509b0ecd' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/zlib.php',
'1232758e40b1d31bb295b6907de02c63' => __DIR__ . '/..' . '/beste/clock/src/Clock.php', '1232758e40b1d31bb295b6907de02c63' => __DIR__ . '/..' . '/beste/clock/src/Clock.php',
'2cffec82183ee1cea088009cef9a6fc3' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
'b067bc7112e384b61c701452d53a14a8' => __DIR__ . '/..' . '/mtdowling/jmespath.php/src/JmesPath.php',
'6124b4c8570aa390c21fafd04a26c69f' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
'35a6ad97d21e794e7e22a17d806652e4' => __DIR__ . '/..' . '/nunomaduro/termwind/src/Functions.php',
'3bd81c9b8fcc150b69d8b63b4d2ccf23' => __DIR__ . '/..' . '/spatie/flare-client-php/src/helpers.php',
'09f6b20656683369174dd6fa83b7e5fb' => __DIR__ . '/..' . '/symfony/polyfill-uuid/bootstrap.php', '09f6b20656683369174dd6fa83b7e5fb' => __DIR__ . '/..' . '/symfony/polyfill-uuid/bootstrap.php',
'a1105708a18b76903365ca1c4aa61b02' => __DIR__ . '/..' . '/symfony/translation/Resources/functions.php', 'a1105708a18b76903365ca1c4aa61b02' => __DIR__ . '/..' . '/symfony/translation/Resources/functions.php',
'06b8a576aaa70a8517a94b7ff6b37e5c' => __DIR__ . '/..' . '/beste/json/src/Json.php', '2cffec82183ee1cea088009cef9a6fc3' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
'47e1160838b5e5a10346ac4084b58c23' => __DIR__ . '/..' . '/laravel/prompts/src/helpers.php', '47e1160838b5e5a10346ac4084b58c23' => __DIR__ . '/..' . '/laravel/prompts/src/helpers.php',
'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php', 'b067bc7112e384b61c701452d53a14a8' => __DIR__ . '/..' . '/mtdowling/jmespath.php/src/JmesPath.php',
'801c31d8ed748cfa537fa45402288c95' => __DIR__ . '/..' . '/psy/psysh/src/functions.php', '6124b4c8570aa390c21fafd04a26c69f' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
'941748b3c8cae4466c827dfb5ca9602a' => __DIR__ . '/..' . '/rmccue/requests/library/Deprecated.php', '3bd81c9b8fcc150b69d8b63b4d2ccf23' => __DIR__ . '/..' . '/spatie/flare-client-php/src/helpers.php',
'8a9dc1de0ca7e01f3e08231539562f61' => __DIR__ . '/..' . '/aws/aws-sdk-php/src/functions.php', '06b8a576aaa70a8517a94b7ff6b37e5c' => __DIR__ . '/..' . '/beste/json/src/Json.php',
'476ca15b8d69b04665cd879be9cb4c68' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Collections/functions.php', '476ca15b8d69b04665cd879be9cb4c68' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Collections/functions.php',
'265b4faa2b3a9766332744949e83bf97' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Collections/helpers.php', '265b4faa2b3a9766332744949e83bf97' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Collections/helpers.php',
'c7a3c339e7e14b60e06a2d7fcce9476b' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Events/functions.php', 'c7a3c339e7e14b60e06a2d7fcce9476b' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Events/functions.php',
'f57d353b41eb2e234b26064d63d8c5dd' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Filesystem/functions.php', 'f57d353b41eb2e234b26064d63d8c5dd' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Filesystem/functions.php',
'f0906e6318348a765ffb6eb24e0d0938' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Foundation/helpers.php', 'f0906e6318348a765ffb6eb24e0d0938' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Foundation/helpers.php',
'58571171fd5812e6e447dce228f52f4d' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Support/helpers.php', '58571171fd5812e6e447dce228f52f4d' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Support/helpers.php',
'a1cfe24d14977df6878b9bf804af2d1c' => __DIR__ . '/..' . '/nunomaduro/collision/src/Adapters/Phpunit/Autoload.php',
'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
'801c31d8ed748cfa537fa45402288c95' => __DIR__ . '/..' . '/psy/psysh/src/functions.php',
'941748b3c8cae4466c827dfb5ca9602a' => __DIR__ . '/..' . '/rmccue/requests/library/Deprecated.php',
'8a9dc1de0ca7e01f3e08231539562f61' => __DIR__ . '/..' . '/aws/aws-sdk-php/src/functions.php',
'ec68c9e7f9b5773fa8c153a5386409da' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Config/helpers.php',
'c72349b1fe8d0deeedd3a52e8aa814d8' => __DIR__ . '/..' . '/mockery/mockery/library/helpers.php', 'c72349b1fe8d0deeedd3a52e8aa814d8' => __DIR__ . '/..' . '/mockery/mockery/library/helpers.php',
'ce9671a430e4846b44e1c68c7611f9f5' => __DIR__ . '/..' . '/mockery/mockery/library/Mockery.php', 'ce9671a430e4846b44e1c68c7611f9f5' => __DIR__ . '/..' . '/mockery/mockery/library/Mockery.php',
'db356362850385d08a5381de2638b5fd' => __DIR__ . '/..' . '/mpdf/mpdf/src/functions.php', 'db356362850385d08a5381de2638b5fd' => __DIR__ . '/..' . '/mpdf/mpdf/src/functions.php',
'a1cfe24d14977df6878b9bf804af2d1c' => __DIR__ . '/..' . '/nunomaduro/collision/src/Adapters/Phpunit/Autoload.php',
'9f394da3192a168c4633675768d80428' => __DIR__ . '/..' . '/nwidart/laravel-modules/src/helpers.php', '9f394da3192a168c4633675768d80428' => __DIR__ . '/..' . '/nwidart/laravel-modules/src/helpers.php',
'ec07570ca5a812141189b1fa81503674' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Assert/Functions.php', 'ec07570ca5a812141189b1fa81503674' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Assert/Functions.php',
'13906c19e3d8fcd1341b24ed4d51cf72' => __DIR__ . '/..' . '/razorpay/razorpay/Deprecated.php', '13906c19e3d8fcd1341b24ed4d51cf72' => __DIR__ . '/..' . '/razorpay/razorpay/Deprecated.php',
@@ -185,6 +186,7 @@ class ComposerStaticInite18b3d3bc6afaf5dd5c2b53c80a29450
'Symfony\\Contracts\\Service\\' => 26, 'Symfony\\Contracts\\Service\\' => 26,
'Symfony\\Contracts\\EventDispatcher\\' => 34, 'Symfony\\Contracts\\EventDispatcher\\' => 34,
'Symfony\\Component\\Yaml\\' => 23, 'Symfony\\Component\\Yaml\\' => 23,
'Symfony\\Component\\VarExporter\\' => 30,
'Symfony\\Component\\VarDumper\\' => 28, 'Symfony\\Component\\VarDumper\\' => 28,
'Symfony\\Component\\Uid\\' => 22, 'Symfony\\Component\\Uid\\' => 22,
'Symfony\\Component\\Translation\\' => 30, 'Symfony\\Component\\Translation\\' => 30,
@@ -211,6 +213,7 @@ class ComposerStaticInite18b3d3bc6afaf5dd5c2b53c80a29450
'Spatie\\Color\\' => 13, 'Spatie\\Color\\' => 13,
'Spatie\\Backtrace\\' => 17, 'Spatie\\Backtrace\\' => 17,
'SimpleSoftwareIO\\QrCode\\' => 24, 'SimpleSoftwareIO\\QrCode\\' => 24,
'Shalvah\\Upgrader\\' => 17,
'Sabberworm\\CSS\\' => 15, 'Sabberworm\\CSS\\' => 15,
'SMSGatewayMe\\Client\\' => 20, 'SMSGatewayMe\\Client\\' => 20,
), ),
@@ -288,6 +291,8 @@ class ComposerStaticInite18b3d3bc6afaf5dd5c2b53c80a29450
array ( array (
'Kreait\\Firebase\\JWT\\' => 20, 'Kreait\\Firebase\\JWT\\' => 20,
'Kreait\\Firebase\\' => 16, 'Kreait\\Firebase\\' => 16,
'Knuckles\\Scribe\\' => 16,
'Knuckles\\Camel\\' => 15,
'Kavenegar\\' => 10, 'Kavenegar\\' => 10,
'Karim007\\LaravelBkashTokenize\\' => 30, 'Karim007\\LaravelBkashTokenize\\' => 30,
), ),
@@ -500,6 +505,10 @@ class ComposerStaticInite18b3d3bc6afaf5dd5c2b53c80a29450
array ( array (
0 => __DIR__ . '/..' . '/symfony/yaml', 0 => __DIR__ . '/..' . '/symfony/yaml',
), ),
'Symfony\\Component\\VarExporter\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/var-exporter',
),
'Symfony\\Component\\VarDumper\\' => 'Symfony\\Component\\VarDumper\\' =>
array ( array (
0 => __DIR__ . '/..' . '/symfony/var-dumper', 0 => __DIR__ . '/..' . '/symfony/var-dumper',
@@ -578,13 +587,13 @@ class ComposerStaticInite18b3d3bc6afaf5dd5c2b53c80a29450
), ),
'Spatie\\LaravelIgnition\\' => 'Spatie\\LaravelIgnition\\' =>
array ( array (
0 => __DIR__ . '/..' . '/spatie/laravel-ignition/src', 0 => __DIR__ . '/..' . '/spatie/error-solutions/legacy/laravel-ignition',
1 => __DIR__ . '/..' . '/spatie/error-solutions/legacy/laravel-ignition', 1 => __DIR__ . '/..' . '/spatie/laravel-ignition/src',
), ),
'Spatie\\Ignition\\' => 'Spatie\\Ignition\\' =>
array ( array (
0 => __DIR__ . '/..' . '/spatie/ignition/src', 0 => __DIR__ . '/..' . '/spatie/error-solutions/legacy/ignition',
1 => __DIR__ . '/..' . '/spatie/error-solutions/legacy/ignition', 1 => __DIR__ . '/..' . '/spatie/ignition/src',
), ),
'Spatie\\FlareClient\\' => 'Spatie\\FlareClient\\' =>
array ( array (
@@ -606,6 +615,10 @@ class ComposerStaticInite18b3d3bc6afaf5dd5c2b53c80a29450
array ( array (
0 => __DIR__ . '/..' . '/simplesoftwareio/simple-qrcode/src', 0 => __DIR__ . '/..' . '/simplesoftwareio/simple-qrcode/src',
), ),
'Shalvah\\Upgrader\\' =>
array (
0 => __DIR__ . '/..' . '/shalvah/upgrader/src',
),
'Sabberworm\\CSS\\' => 'Sabberworm\\CSS\\' =>
array ( array (
0 => __DIR__ . '/..' . '/sabberworm/php-css-parser/src', 0 => __DIR__ . '/..' . '/sabberworm/php-css-parser/src',
@@ -836,6 +849,14 @@ class ComposerStaticInite18b3d3bc6afaf5dd5c2b53c80a29450
array ( array (
0 => __DIR__ . '/..' . '/kreait/firebase-php/src/Firebase', 0 => __DIR__ . '/..' . '/kreait/firebase-php/src/Firebase',
), ),
'Knuckles\\Scribe\\' =>
array (
0 => __DIR__ . '/..' . '/knuckleswtf/scribe/src',
),
'Knuckles\\Camel\\' =>
array (
0 => __DIR__ . '/..' . '/knuckleswtf/scribe/camel',
),
'Kavenegar\\' => 'Kavenegar\\' =>
array ( array (
0 => __DIR__ . '/..' . '/kavenegar/php/src', 0 => __DIR__ . '/..' . '/kavenegar/php/src',
@@ -864,8 +885,8 @@ class ComposerStaticInite18b3d3bc6afaf5dd5c2b53c80a29450
), ),
'Http\\Message\\' => 'Http\\Message\\' =>
array ( array (
0 => __DIR__ . '/..' . '/php-http/message-factory/src', 0 => __DIR__ . '/..' . '/php-http/message/src',
1 => __DIR__ . '/..' . '/php-http/message/src', 1 => __DIR__ . '/..' . '/php-http/message-factory/src',
), ),
'Http\\Discovery\\' => 'Http\\Discovery\\' =>
array ( array (
@@ -1158,6 +1179,20 @@ class ComposerStaticInite18b3d3bc6afaf5dd5c2b53c80a29450
); );
public static $prefixesPsr0 = array ( public static $prefixesPsr0 = array (
'P' =>
array (
'Parsedown' =>
array (
0 => __DIR__ . '/..' . '/parsedown/parsedown',
),
),
'M' =>
array (
'Mpociot' =>
array (
0 => __DIR__ . '/..' . '/mpociot/reflection-docblock/src',
),
),
'H' => 'H' =>
array ( array (
'HTMLPurifier' => 'HTMLPurifier' =>
@@ -3347,6 +3382,7 @@ class ComposerStaticInite18b3d3bc6afaf5dd5c2b53c80a29450
'Database\\Seeders\\GatewaySeeder' => __DIR__ . '/../..' . '/database/seeders/GatewaySeeder.php', 'Database\\Seeders\\GatewaySeeder' => __DIR__ . '/../..' . '/database/seeders/GatewaySeeder.php',
'Database\\Seeders\\IncomeCategorySeeder' => __DIR__ . '/../..' . '/database/seeders/IncomeCategorySeeder.php', 'Database\\Seeders\\IncomeCategorySeeder' => __DIR__ . '/../..' . '/database/seeders/IncomeCategorySeeder.php',
'Database\\Seeders\\IncomeSeeder' => __DIR__ . '/../..' . '/database/seeders/IncomeSeeder.php', 'Database\\Seeders\\IncomeSeeder' => __DIR__ . '/../..' . '/database/seeders/IncomeSeeder.php',
'Database\\Seeders\\InitialDataSeeder' => __DIR__ . '/../..' . '/database/seeders/InitialDataSeeder.php',
'Database\\Seeders\\InterfaceSeeder' => __DIR__ . '/../..' . '/database/seeders/InterfaceSeeder.php', 'Database\\Seeders\\InterfaceSeeder' => __DIR__ . '/../..' . '/database/seeders/InterfaceSeeder.php',
'Database\\Seeders\\LanguageSeeder' => __DIR__ . '/../..' . '/database/seeders/LanguageSeeder.php', 'Database\\Seeders\\LanguageSeeder' => __DIR__ . '/../..' . '/database/seeders/LanguageSeeder.php',
'Database\\Seeders\\OptionTableSeeder' => __DIR__ . '/../..' . '/database/seeders/OptionTableSeeder.php', 'Database\\Seeders\\OptionTableSeeder' => __DIR__ . '/../..' . '/database/seeders/OptionTableSeeder.php',
@@ -6805,6 +6841,128 @@ class ComposerStaticInite18b3d3bc6afaf5dd5c2b53c80a29450
'Kavenegar\\Exceptions\\BaseRuntimeException' => __DIR__ . '/..' . '/kavenegar/php/src/Exceptions/BaseRuntimeException.php', 'Kavenegar\\Exceptions\\BaseRuntimeException' => __DIR__ . '/..' . '/kavenegar/php/src/Exceptions/BaseRuntimeException.php',
'Kavenegar\\Exceptions\\HttpException' => __DIR__ . '/..' . '/kavenegar/php/src/Exceptions/HttpException.php', 'Kavenegar\\Exceptions\\HttpException' => __DIR__ . '/..' . '/kavenegar/php/src/Exceptions/HttpException.php',
'Kavenegar\\KavenegarApi' => __DIR__ . '/..' . '/kavenegar/php/src/KavenegarApi.php', 'Kavenegar\\KavenegarApi' => __DIR__ . '/..' . '/kavenegar/php/src/KavenegarApi.php',
'Knuckles\\Camel\\BaseDTO' => __DIR__ . '/..' . '/knuckleswtf/scribe/camel/BaseDTO.php',
'Knuckles\\Camel\\BaseDTOCollection' => __DIR__ . '/..' . '/knuckleswtf/scribe/camel/BaseDTOCollection.php',
'Knuckles\\Camel\\Camel' => __DIR__ . '/..' . '/knuckleswtf/scribe/camel/Camel.php',
'Knuckles\\Camel\\Extraction\\ExtractedEndpointData' => __DIR__ . '/..' . '/knuckleswtf/scribe/camel/Extraction/ExtractedEndpointData.php',
'Knuckles\\Camel\\Extraction\\Metadata' => __DIR__ . '/..' . '/knuckleswtf/scribe/camel/Extraction/Metadata.php',
'Knuckles\\Camel\\Extraction\\Parameter' => __DIR__ . '/..' . '/knuckleswtf/scribe/camel/Extraction/Parameter.php',
'Knuckles\\Camel\\Extraction\\Response' => __DIR__ . '/..' . '/knuckleswtf/scribe/camel/Extraction/Response.php',
'Knuckles\\Camel\\Extraction\\ResponseCollection' => __DIR__ . '/..' . '/knuckleswtf/scribe/camel/Extraction/ResponseCollection.php',
'Knuckles\\Camel\\Extraction\\ResponseField' => __DIR__ . '/..' . '/knuckleswtf/scribe/camel/Extraction/ResponseField.php',
'Knuckles\\Camel\\Output\\OutputEndpointData' => __DIR__ . '/..' . '/knuckleswtf/scribe/camel/Output/OutputEndpointData.php',
'Knuckles\\Camel\\Output\\Parameter' => __DIR__ . '/..' . '/knuckleswtf/scribe/camel/Output/Parameter.php',
'Knuckles\\Scribe\\Attributes\\Authenticated' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Attributes/Authenticated.php',
'Knuckles\\Scribe\\Attributes\\BodyParam' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Attributes/BodyParam.php',
'Knuckles\\Scribe\\Attributes\\Deprecated' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Attributes/Deprecated.php',
'Knuckles\\Scribe\\Attributes\\Endpoint' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Attributes/Endpoint.php',
'Knuckles\\Scribe\\Attributes\\GenericParam' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Attributes/GenericParam.php',
'Knuckles\\Scribe\\Attributes\\Group' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Attributes/Group.php',
'Knuckles\\Scribe\\Attributes\\Header' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Attributes/Header.php',
'Knuckles\\Scribe\\Attributes\\QueryParam' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Attributes/QueryParam.php',
'Knuckles\\Scribe\\Attributes\\Response' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Attributes/Response.php',
'Knuckles\\Scribe\\Attributes\\ResponseField' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Attributes/ResponseField.php',
'Knuckles\\Scribe\\Attributes\\ResponseFromApiResource' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Attributes/ResponseFromApiResource.php',
'Knuckles\\Scribe\\Attributes\\ResponseFromFile' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Attributes/ResponseFromFile.php',
'Knuckles\\Scribe\\Attributes\\ResponseFromTransformer' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Attributes/ResponseFromTransformer.php',
'Knuckles\\Scribe\\Attributes\\Subgroup' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Attributes/Subgroup.php',
'Knuckles\\Scribe\\Attributes\\Unauthenticated' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Attributes/Unauthenticated.php',
'Knuckles\\Scribe\\Attributes\\UrlParam' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Attributes/UrlParam.php',
'Knuckles\\Scribe\\Commands\\DiffConfig' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Commands/DiffConfig.php',
'Knuckles\\Scribe\\Commands\\GenerateDocumentation' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Commands/GenerateDocumentation.php',
'Knuckles\\Scribe\\Commands\\MakeStrategy' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Commands/MakeStrategy.php',
'Knuckles\\Scribe\\Commands\\Upgrade' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Commands/Upgrade.php',
'Knuckles\\Scribe\\Config\\AuthIn' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Config/AuthIn.php',
'Knuckles\\Scribe\\Config\\Defaults' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Config/Defaults.php',
'Knuckles\\Scribe\\Exceptions\\CouldntFindFactory' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Exceptions/CouldntFindFactory.php',
'Knuckles\\Scribe\\Exceptions\\CouldntGetRouteDetails' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Exceptions/CouldntGetRouteDetails.php',
'Knuckles\\Scribe\\Exceptions\\CouldntProcessValidationRule' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Exceptions/CouldntProcessValidationRule.php',
'Knuckles\\Scribe\\Exceptions\\CouldntStartDatabaseTransaction' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Exceptions/CouldntStartDatabaseTransaction.php',
'Knuckles\\Scribe\\Exceptions\\DatabaseTransactionsNotSupported' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Exceptions/DatabaseTransactionsNotSupported.php',
'Knuckles\\Scribe\\Exceptions\\GroupNotFound' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Exceptions/GroupNotFound.php',
'Knuckles\\Scribe\\Exceptions\\ProblemParsingValidationRules' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Exceptions/ProblemParsingValidationRules.php',
'Knuckles\\Scribe\\Exceptions\\ScribeException' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Exceptions/ScribeException.php',
'Knuckles\\Scribe\\Extracting\\ApiDetails' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/ApiDetails.php',
'Knuckles\\Scribe\\Extracting\\DatabaseTransactionHelpers' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/DatabaseTransactionHelpers.php',
'Knuckles\\Scribe\\Extracting\\Extractor' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Extractor.php',
'Knuckles\\Scribe\\Extracting\\FindsFormRequestForMethod' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/FindsFormRequestForMethod.php',
'Knuckles\\Scribe\\Extracting\\InstantiatesExampleModels' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/InstantiatesExampleModels.php',
'Knuckles\\Scribe\\Extracting\\MethodAstParser' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/MethodAstParser.php',
'Knuckles\\Scribe\\Extracting\\ParamHelpers' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/ParamHelpers.php',
'Knuckles\\Scribe\\Extracting\\ParsesValidationRules' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/ParsesValidationRules.php',
'Knuckles\\Scribe\\Extracting\\RouteDocBlocker' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/RouteDocBlocker.php',
'Knuckles\\Scribe\\Extracting\\Shared\\ApiResourceResponseTools' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Shared/ApiResourceResponseTools.php',
'Knuckles\\Scribe\\Extracting\\Shared\\ResponseFieldTools' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Shared/ResponseFieldTools.php',
'Knuckles\\Scribe\\Extracting\\Shared\\ResponseFileTools' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Shared/ResponseFileTools.php',
'Knuckles\\Scribe\\Extracting\\Shared\\TransformerResponseTools' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Shared/TransformerResponseTools.php',
'Knuckles\\Scribe\\Extracting\\Shared\\UrlParamsNormalizer' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Shared/UrlParamsNormalizer.php',
'Knuckles\\Scribe\\Extracting\\Shared\\ValidationRulesFinders\\RequestValidate' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Shared/ValidationRulesFinders/RequestValidate.php',
'Knuckles\\Scribe\\Extracting\\Shared\\ValidationRulesFinders\\RequestValidateFacade' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Shared/ValidationRulesFinders/RequestValidateFacade.php',
'Knuckles\\Scribe\\Extracting\\Shared\\ValidationRulesFinders\\ThisValidate' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Shared/ValidationRulesFinders/ThisValidate.php',
'Knuckles\\Scribe\\Extracting\\Shared\\ValidationRulesFinders\\ValidatorMake' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Shared/ValidationRulesFinders/ValidatorMake.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\BodyParameters\\GetFromBodyParamAttribute' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/BodyParameters/GetFromBodyParamAttribute.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\BodyParameters\\GetFromBodyParamTag' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/BodyParameters/GetFromBodyParamTag.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\BodyParameters\\GetFromFormRequest' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/BodyParameters/GetFromFormRequest.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\BodyParameters\\GetFromInlineValidator' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/BodyParameters/GetFromInlineValidator.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\GetFieldsFromTagStrategy' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/GetFieldsFromTagStrategy.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\GetFromFormRequestBase' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/GetFromFormRequestBase.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\GetFromInlineValidatorBase' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/GetFromInlineValidatorBase.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\GetParamsFromAttributeStrategy' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/GetParamsFromAttributeStrategy.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\Headers\\GetFromHeaderAttribute' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/Headers/GetFromHeaderAttribute.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\Headers\\GetFromHeaderTag' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/Headers/GetFromHeaderTag.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\Metadata\\GetFromDocBlocks' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/Metadata/GetFromDocBlocks.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\Metadata\\GetFromMetadataAttributes' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/Metadata/GetFromMetadataAttributes.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\PhpAttributeStrategy' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/PhpAttributeStrategy.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\QueryParameters\\GetFromFormRequest' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/QueryParameters/GetFromFormRequest.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\QueryParameters\\GetFromInlineValidator' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/QueryParameters/GetFromInlineValidator.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\QueryParameters\\GetFromQueryParamAttribute' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/QueryParameters/GetFromQueryParamAttribute.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\QueryParameters\\GetFromQueryParamTag' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/QueryParameters/GetFromQueryParamTag.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\ResponseFields\\GetFromResponseFieldAttribute' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/ResponseFields/GetFromResponseFieldAttribute.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\ResponseFields\\GetFromResponseFieldTag' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/ResponseFields/GetFromResponseFieldTag.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\ResponseCalls' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/Responses/ResponseCalls.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\UseApiResourceTags' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/Responses/UseApiResourceTags.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\UseResponseAttributes' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/Responses/UseResponseAttributes.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\UseResponseFileTag' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/Responses/UseResponseFileTag.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\UseResponseTag' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/Responses/UseResponseTag.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\UseTransformerTags' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/Responses/UseTransformerTags.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\StaticData' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/StaticData.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\Strategy' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/Strategy.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\TagStrategyWithFormRequestFallback' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/TagStrategyWithFormRequestFallback.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\UrlParameters\\GetFromLaravelAPI' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/UrlParameters/GetFromLaravelAPI.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\UrlParameters\\GetFromUrlParamAttribute' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/UrlParameters/GetFromUrlParamAttribute.php',
'Knuckles\\Scribe\\Extracting\\Strategies\\UrlParameters\\GetFromUrlParamTag' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Extracting/Strategies/UrlParameters/GetFromUrlParamTag.php',
'Knuckles\\Scribe\\GroupedEndpoints\\GroupedEndpointsContract' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/GroupedEndpoints/GroupedEndpointsContract.php',
'Knuckles\\Scribe\\GroupedEndpoints\\GroupedEndpointsFactory' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/GroupedEndpoints/GroupedEndpointsFactory.php',
'Knuckles\\Scribe\\GroupedEndpoints\\GroupedEndpointsFromApp' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/GroupedEndpoints/GroupedEndpointsFromApp.php',
'Knuckles\\Scribe\\GroupedEndpoints\\GroupedEndpointsFromCamelDir' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/GroupedEndpoints/GroupedEndpointsFromCamelDir.php',
'Knuckles\\Scribe\\Matching\\MatchedRoute' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Matching/MatchedRoute.php',
'Knuckles\\Scribe\\Matching\\RouteMatcher' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Matching/RouteMatcher.php',
'Knuckles\\Scribe\\Matching\\RouteMatcherInterface' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Matching/RouteMatcherInterface.php',
'Knuckles\\Scribe\\Scribe' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Scribe.php',
'Knuckles\\Scribe\\ScribeServiceProvider' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/ScribeServiceProvider.php',
'Knuckles\\Scribe\\Tools\\AnnotationParser' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Tools/AnnotationParser.php',
'Knuckles\\Scribe\\Tools\\BladeMarkdownEngine' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Tools/BladeMarkdownEngine.php',
'Knuckles\\Scribe\\Tools\\ConfigDiffer' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Tools/ConfigDiffer.php',
'Knuckles\\Scribe\\Tools\\ConsoleOutputUtils' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Tools/ConsoleOutputUtils.php',
'Knuckles\\Scribe\\Tools\\DocumentationConfig' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Tools/DocumentationConfig.php',
'Knuckles\\Scribe\\Tools\\ErrorHandlingUtils' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Tools/ErrorHandlingUtils.php',
'Knuckles\\Scribe\\Tools\\Globals' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Tools/Globals.php',
'Knuckles\\Scribe\\Tools\\MarkdownParser' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Tools/MarkdownParser.php',
'Knuckles\\Scribe\\Tools\\PathConfig' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Tools/PathConfig.php',
'Knuckles\\Scribe\\Tools\\RoutePatternMatcher' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Tools/RoutePatternMatcher.php',
'Knuckles\\Scribe\\Tools\\Utils' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Tools/Utils.php',
'Knuckles\\Scribe\\Tools\\WritingUtils' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Tools/WritingUtils.php',
'Knuckles\\Scribe\\Writing\\CustomTranslationsLoader' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Writing/CustomTranslationsLoader.php',
'Knuckles\\Scribe\\Writing\\ExternalHtmlWriter' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Writing/ExternalHtmlWriter.php',
'Knuckles\\Scribe\\Writing\\HtmlWriter' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Writing/HtmlWriter.php',
'Knuckles\\Scribe\\Writing\\OpenAPISpecWriter' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Writing/OpenAPISpecWriter.php',
'Knuckles\\Scribe\\Writing\\OpenApiSpecGenerators\\Base31Generator' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Writing/OpenApiSpecGenerators/Base31Generator.php',
'Knuckles\\Scribe\\Writing\\OpenApiSpecGenerators\\BaseGenerator' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Writing/OpenApiSpecGenerators/BaseGenerator.php',
'Knuckles\\Scribe\\Writing\\OpenApiSpecGenerators\\OpenApiGenerator' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Writing/OpenApiSpecGenerators/OpenApiGenerator.php',
'Knuckles\\Scribe\\Writing\\OpenApiSpecGenerators\\OverridesGenerator' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Writing/OpenApiSpecGenerators/OverridesGenerator.php',
'Knuckles\\Scribe\\Writing\\OpenApiSpecGenerators\\SecurityGenerator' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Writing/OpenApiSpecGenerators/SecurityGenerator.php',
'Knuckles\\Scribe\\Writing\\PostmanCollectionWriter' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Writing/PostmanCollectionWriter.php',
'Knuckles\\Scribe\\Writing\\Writer' => __DIR__ . '/..' . '/knuckleswtf/scribe/src/Writing/Writer.php',
'Kreait\\Firebase\\AppCheck' => __DIR__ . '/..' . '/kreait/firebase-php/src/Firebase/AppCheck.php', 'Kreait\\Firebase\\AppCheck' => __DIR__ . '/..' . '/kreait/firebase-php/src/Firebase/AppCheck.php',
'Kreait\\Firebase\\AppCheck\\ApiClient' => __DIR__ . '/..' . '/kreait/firebase-php/src/Firebase/AppCheck/ApiClient.php', 'Kreait\\Firebase\\AppCheck\\ApiClient' => __DIR__ . '/..' . '/kreait/firebase-php/src/Firebase/AppCheck/ApiClient.php',
'Kreait\\Firebase\\AppCheck\\AppCheckToken' => __DIR__ . '/..' . '/kreait/firebase-php/src/Firebase/AppCheck/AppCheckToken.php', 'Kreait\\Firebase\\AppCheck\\AppCheckToken' => __DIR__ . '/..' . '/kreait/firebase-php/src/Firebase/AppCheck/AppCheckToken.php',
@@ -8046,6 +8204,133 @@ class ComposerStaticInite18b3d3bc6afaf5dd5c2b53c80a29450
'Mockery\\Undefined' => __DIR__ . '/..' . '/mockery/mockery/library/Mockery/Undefined.php', 'Mockery\\Undefined' => __DIR__ . '/..' . '/mockery/mockery/library/Mockery/Undefined.php',
'Mockery\\VerificationDirector' => __DIR__ . '/..' . '/mockery/mockery/library/Mockery/VerificationDirector.php', 'Mockery\\VerificationDirector' => __DIR__ . '/..' . '/mockery/mockery/library/Mockery/VerificationDirector.php',
'Mockery\\VerificationExpectation' => __DIR__ . '/..' . '/mockery/mockery/library/Mockery/VerificationExpectation.php', 'Mockery\\VerificationExpectation' => __DIR__ . '/..' . '/mockery/mockery/library/Mockery/VerificationExpectation.php',
'Modules\\Business\\App\\Exports\\ExportBalanceSheet' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportBalanceSheet.php',
'Modules\\Business\\App\\Exports\\ExportBillWisePofit' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportBillWisePofit.php',
'Modules\\Business\\App\\Exports\\ExportCashFlowReport' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportCashFlowReport.php',
'Modules\\Business\\App\\Exports\\ExportComboProduct' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportComboProduct.php',
'Modules\\Business\\App\\Exports\\ExportComboProductReport' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportComboProductReport.php',
'Modules\\Business\\App\\Exports\\ExportCurrentStock' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportCurrentStock.php',
'Modules\\Business\\App\\Exports\\ExportCurrentStockReport' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportCurrentStockReport.php',
'Modules\\Business\\App\\Exports\\ExportCustomerLedger' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportCustomerLedger.php',
'Modules\\Business\\App\\Exports\\ExportDayBookReport' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportDayBookReport.php',
'Modules\\Business\\App\\Exports\\ExportDiscountProduct' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportDiscountProduct.php',
'Modules\\Business\\App\\Exports\\ExportDue' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportDue.php',
'Modules\\Business\\App\\Exports\\ExportExpense' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportExpense.php',
'Modules\\Business\\App\\Exports\\ExportExpiredProduct' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportExpiredProduct.php',
'Modules\\Business\\App\\Exports\\ExportExpiredProductReport' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportExpiredProductReport.php',
'Modules\\Business\\App\\Exports\\ExportIncome' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportIncome.php',
'Modules\\Business\\App\\Exports\\ExportLossProfitHistory' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportLossProfitHistory.php',
'Modules\\Business\\App\\Exports\\ExportPartyLossProfit' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportPartyLossProfit.php',
'Modules\\Business\\App\\Exports\\ExportProduct' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportProduct.php',
'Modules\\Business\\App\\Exports\\ExportProductLossProfit' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportProductLossProfit.php',
'Modules\\Business\\App\\Exports\\ExportProductPurchaseHistoryDetailReport' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportProductPurchaseHistoryDetailReport.php',
'Modules\\Business\\App\\Exports\\ExportProductPurchaseHistoryReport' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportProductPurchaseHistoryReport.php',
'Modules\\Business\\App\\Exports\\ExportProductPurchaseReport' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportProductPurchaseReport.php',
'Modules\\Business\\App\\Exports\\ExportProductSaleHistoryDetailReport' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportProductSaleHistoryDetailReport.php',
'Modules\\Business\\App\\Exports\\ExportProductSaleHistoryReport' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportProductSaleHistoryReport.php',
'Modules\\Business\\App\\Exports\\ExportProductSaleReport' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportProductSaleReport.php',
'Modules\\Business\\App\\Exports\\ExportPurchaseReturn' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportPurchaseReturn.php',
'Modules\\Business\\App\\Exports\\ExportSaleReport' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportSaleReport.php',
'Modules\\Business\\App\\Exports\\ExportSalesReturn' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportSalesReturn.php',
'Modules\\Business\\App\\Exports\\ExportSingleCustomerLedger' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportSingleCustomerLedger.php',
'Modules\\Business\\App\\Exports\\ExportSingleSupplierLedger' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportSingleSupplierLedger.php',
'Modules\\Business\\App\\Exports\\ExportSubscription' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportSubscription.php',
'Modules\\Business\\App\\Exports\\ExportSupplierDue' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportSupplierDue.php',
'Modules\\Business\\App\\Exports\\ExportSupplierLedger' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportSupplierLedger.php',
'Modules\\Business\\App\\Exports\\ExportTopCustomer' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportTopCustomer.php',
'Modules\\Business\\App\\Exports\\ExportTopProduct' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportTopProduct.php',
'Modules\\Business\\App\\Exports\\ExportTopSupplier' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportTopSupplier.php',
'Modules\\Business\\App\\Exports\\ExportTransaction' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportTransaction.php',
'Modules\\Business\\App\\Exports\\ExportTransactionReport' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportTransactionReport.php',
'Modules\\Business\\App\\Exports\\ExportTransfer' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportTransfer.php',
'Modules\\Business\\App\\Exports\\ExportVatReport' => __DIR__ . '/../..' . '/Modules/Business/App/Exports/ExportVatReport.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooBalanceSheetController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooBalanceSheetController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooBankController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooBankController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooBillWiseProfitController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooBillWiseProfitController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooBrandController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooBrandController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooCashController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooCashController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooCashFlowReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooCashFlowReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooCategoryController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooCategoryController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooChequeController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooChequeController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooComboProductController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooComboProductController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooComboProductReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooComboProductReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooCommissionController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooCommissionController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooCurrencyController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooCurrencyController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooCustomerLedgerController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooCustomerLedgerController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooDayBookReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooDayBookReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooDiscountProductReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooDiscountProductReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooDueController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooDueController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooDueReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooDueReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooExpenseCategoryController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooExpenseCategoryController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooExpenseController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooExpenseController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooExpenseReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooExpenseReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooExpireProductController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooExpireProductController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooExpireProductReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooExpireProductReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooIncomeCategoryController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooIncomeCategoryController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooIncomeController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooIncomeController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooIncomeReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooIncomeReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooLanguageSettingController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooLanguageSettingController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooLossProfitDetailReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooLossProfitDetailReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooLossProfitHistoryController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooLossProfitHistoryController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooLossProfitHistoryReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooLossProfitHistoryReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooNotificationController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooNotificationController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooPartyController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooPartyController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooPartyLossProfitController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooPartyLossProfitController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooProductController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooProductController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooProductLossProfitReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooProductLossProfitReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooProductModelController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooProductModelController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooProductPurchaseHistoryReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooProductPurchaseHistoryReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooProductPurchaseReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooProductPurchaseReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooProductSaleHistoryReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooProductSaleHistoryReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooProductSaleReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooProductSaleReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooPurchaseController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooPurchaseController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooPurchaseReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooPurchaseReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooPurchaseReturnReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooPurchaseReturnReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooRackController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooRackController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooSaleCommissionController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooSaleCommissionController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooSaleController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooSaleController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooSaleReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooSaleReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooSaleReturnReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooSaleReturnReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooSettingsManagerController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooSettingsManagerController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooShelfController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooShelfController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooStockController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooStockController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooStockReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooStockReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooSubscriptionController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooSubscriptionController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooSubscriptionReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooSubscriptionReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooSupplierDueReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooSupplierDueReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooSupplierLedgerController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooSupplierLedgerController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooTopCustomerController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooTopCustomerController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooTopCustomerReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooTopCustomerReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooTopProductReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooTopProductReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooTopSupplierController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooTopSupplierController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooTopSupplierReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooTopSupplierReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooTransactionController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooTransactionController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooTransactionHistoryReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooTransactionHistoryReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooTransferController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooTransferController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooUnitController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooUnitController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooVariationController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooVariationController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooVatController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooVatController.php',
'Modules\\Business\\App\\Http\\Controllers\\AcnooVatReportController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/AcnooVatReportController.php',
'Modules\\Business\\App\\Http\\Controllers\\BankTransactionController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/BankTransactionController.php',
'Modules\\Business\\App\\Http\\Controllers\\BarcodeGeneratorController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/BarcodeGeneratorController.php',
'Modules\\Business\\App\\Http\\Controllers\\BulkUploadController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/BulkUploadController.php',
'Modules\\Business\\App\\Http\\Controllers\\CartController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/CartController.php',
'Modules\\Business\\App\\Http\\Controllers\\DashboardController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/DashboardController.php',
'Modules\\Business\\App\\Http\\Controllers\\ProfileController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/ProfileController.php',
'Modules\\Business\\App\\Http\\Controllers\\PurchaseReturnController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/PurchaseReturnController.php',
'Modules\\Business\\App\\Http\\Controllers\\SaleReturnController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/SaleReturnController.php',
'Modules\\Business\\App\\Http\\Controllers\\SettingController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/SettingController.php',
'Modules\\Business\\App\\Http\\Controllers\\UserRoleController' => __DIR__ . '/../..' . '/Modules/Business/App/Http/Controllers/UserRoleController.php',
'Modules\\Business\\App\\Providers\\BusinessServiceProvider' => __DIR__ . '/../..' . '/Modules/Business/App/Providers/BusinessServiceProvider.php',
'Modules\\Business\\App\\Providers\\RouteServiceProvider' => __DIR__ . '/../..' . '/Modules/Business/App/Providers/RouteServiceProvider.php',
'Modules\\MultiBranchAddon\\App\\Http\\Controllers\\AcnooBranchController' => __DIR__ . '/../..' . '/Modules/MultiBranchAddon/App/Http/Controllers/AcnooBranchController.php',
'Modules\\MultiBranchAddon\\App\\Http\\Controllers\\Api\\AcnooBranchController' => __DIR__ . '/../..' . '/Modules/MultiBranchAddon/App/Http/Controllers/Api/AcnooBranchController.php',
'Modules\\MultiBranchAddon\\App\\Providers\\MultiBranchAddonServiceProvider' => __DIR__ . '/../..' . '/Modules/MultiBranchAddon/App/Providers/MultiBranchAddonServiceProvider.php',
'Modules\\MultiBranchAddon\\App\\Providers\\RouteServiceProvider' => __DIR__ . '/../..' . '/Modules/MultiBranchAddon/App/Providers/RouteServiceProvider.php',
'Modules\\WarehouseAddon\\App\\Http\\Controllers\\AcnooWarehouseController' => __DIR__ . '/../..' . '/Modules/WarehouseAddon/App/Http/Controllers/AcnooWarehouseController.php',
'Modules\\WarehouseAddon\\App\\Http\\Controllers\\Api\\WarehouseController' => __DIR__ . '/../..' . '/Modules/WarehouseAddon/App/Http/Controllers/Api/WarehouseController.php',
'Modules\\WarehouseAddon\\App\\Providers\\RouteServiceProvider' => __DIR__ . '/../..' . '/Modules/WarehouseAddon/App/Providers/RouteServiceProvider.php',
'Modules\\WarehouseAddon\\App\\Providers\\WarehouseAddonServiceProvider' => __DIR__ . '/../..' . '/Modules/WarehouseAddon/App/Providers/WarehouseAddonServiceProvider.php',
'Mollie\\Api\\CompatibilityChecker' => __DIR__ . '/..' . '/mollie/mollie-api-php/src/CompatibilityChecker.php', 'Mollie\\Api\\CompatibilityChecker' => __DIR__ . '/..' . '/mollie/mollie-api-php/src/CompatibilityChecker.php',
'Mollie\\Api\\Endpoints\\BalanceEndpoint' => __DIR__ . '/..' . '/mollie/mollie-api-php/src/Endpoints/BalanceEndpoint.php', 'Mollie\\Api\\Endpoints\\BalanceEndpoint' => __DIR__ . '/..' . '/mollie/mollie-api-php/src/Endpoints/BalanceEndpoint.php',
'Mollie\\Api\\Endpoints\\BalanceReportEndpoint' => __DIR__ . '/..' . '/mollie/mollie-api-php/src/Endpoints/BalanceReportEndpoint.php', 'Mollie\\Api\\Endpoints\\BalanceReportEndpoint' => __DIR__ . '/..' . '/mollie/mollie-api-php/src/Endpoints/BalanceReportEndpoint.php',
@@ -8595,6 +8880,31 @@ class ComposerStaticInite18b3d3bc6afaf5dd5c2b53c80a29450
'Mpdf\\Writer\\OptionalContentWriter' => __DIR__ . '/..' . '/mpdf/mpdf/src/Writer/OptionalContentWriter.php', 'Mpdf\\Writer\\OptionalContentWriter' => __DIR__ . '/..' . '/mpdf/mpdf/src/Writer/OptionalContentWriter.php',
'Mpdf\\Writer\\PageWriter' => __DIR__ . '/..' . '/mpdf/mpdf/src/Writer/PageWriter.php', 'Mpdf\\Writer\\PageWriter' => __DIR__ . '/..' . '/mpdf/mpdf/src/Writer/PageWriter.php',
'Mpdf\\Writer\\ResourceWriter' => __DIR__ . '/..' . '/mpdf/mpdf/src/Writer/ResourceWriter.php', 'Mpdf\\Writer\\ResourceWriter' => __DIR__ . '/..' . '/mpdf/mpdf/src/Writer/ResourceWriter.php',
'Mpociot\\Reflection\\DocBlock' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock.php',
'Mpociot\\Reflection\\DocBlock\\Context' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Context.php',
'Mpociot\\Reflection\\DocBlock\\Description' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Description.php',
'Mpociot\\Reflection\\DocBlock\\Location' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Location.php',
'Mpociot\\Reflection\\DocBlock\\Serializer' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Serializer.php',
'Mpociot\\Reflection\\DocBlock\\Tag' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\AuthorTag' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/AuthorTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\CoversTag' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/CoversTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\DeprecatedTag' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/DeprecatedTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\ExampleTag' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/ExampleTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\LinkTag' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/LinkTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\MethodTag' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/MethodTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\ParamTag' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/ParamTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\PropertyReadTag' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/PropertyReadTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\PropertyTag' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/PropertyTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\PropertyWriteTag' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/PropertyWriteTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\ReturnTag' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/ReturnTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\SeeTag' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/SeeTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\SinceTag' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/SinceTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\SourceTag' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/SourceTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\ThrowsTag' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/ThrowsTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\UsesTag' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/UsesTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\VarTag' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/VarTag.php',
'Mpociot\\Reflection\\DocBlock\\Tag\\VersionTag' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Tag/VersionTag.php',
'Mpociot\\Reflection\\DocBlock\\Type\\Collection' => __DIR__ . '/..' . '/mpociot/reflection-docblock/src/Mpociot/Reflection/DocBlock/Type/Collection.php',
'Nette\\ArgumentOutOfRangeException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', 'Nette\\ArgumentOutOfRangeException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php',
'Nette\\DeprecatedException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', 'Nette\\DeprecatedException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php',
'Nette\\DirectoryNotFoundException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', 'Nette\\DirectoryNotFoundException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php',
@@ -9856,6 +10166,7 @@ class ComposerStaticInite18b3d3bc6afaf5dd5c2b53c80a29450
'ParagonIE\\ConstantTime\\Encoding' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Encoding.php', 'ParagonIE\\ConstantTime\\Encoding' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Encoding.php',
'ParagonIE\\ConstantTime\\Hex' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Hex.php', 'ParagonIE\\ConstantTime\\Hex' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Hex.php',
'ParagonIE\\ConstantTime\\RFC4648' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/RFC4648.php', 'ParagonIE\\ConstantTime\\RFC4648' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/RFC4648.php',
'Parsedown' => __DIR__ . '/..' . '/parsedown/parsedown/Parsedown.php',
'PharIo\\Manifest\\Application' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Application.php', 'PharIo\\Manifest\\Application' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Application.php',
'PharIo\\Manifest\\ApplicationName' => __DIR__ . '/..' . '/phar-io/manifest/src/values/ApplicationName.php', 'PharIo\\Manifest\\ApplicationName' => __DIR__ . '/..' . '/phar-io/manifest/src/values/ApplicationName.php',
'PharIo\\Manifest\\Author' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Author.php', 'PharIo\\Manifest\\Author' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Author.php',
@@ -11562,6 +11873,11 @@ class ComposerStaticInite18b3d3bc6afaf5dd5c2b53c80a29450
'SebastianBergmann\\Type\\UnknownType' => __DIR__ . '/..' . '/sebastian/type/src/type/UnknownType.php', 'SebastianBergmann\\Type\\UnknownType' => __DIR__ . '/..' . '/sebastian/type/src/type/UnknownType.php',
'SebastianBergmann\\Type\\VoidType' => __DIR__ . '/..' . '/sebastian/type/src/type/VoidType.php', 'SebastianBergmann\\Type\\VoidType' => __DIR__ . '/..' . '/sebastian/type/src/type/VoidType.php',
'SebastianBergmann\\Version' => __DIR__ . '/..' . '/sebastian/version/src/Version.php', 'SebastianBergmann\\Version' => __DIR__ . '/..' . '/sebastian/version/src/Version.php',
'Shalvah\\Upgrader\\ComparesAstNodes' => __DIR__ . '/..' . '/shalvah/upgrader/src/ComparesAstNodes.php',
'Shalvah\\Upgrader\\ModifiesAsts' => __DIR__ . '/..' . '/shalvah/upgrader/src/ModifiesAsts.php',
'Shalvah\\Upgrader\\ReadsAndWritesAsts' => __DIR__ . '/..' . '/shalvah/upgrader/src/ReadsAndWritesAsts.php',
'Shalvah\\Upgrader\\UnresolveNamespaces' => __DIR__ . '/..' . '/shalvah/upgrader/src/UnresolveNamespaces.php',
'Shalvah\\Upgrader\\Upgrader' => __DIR__ . '/..' . '/shalvah/upgrader/src/Upgrader.php',
'SimpleSoftwareIO\\QrCode\\DataTypes\\BTC' => __DIR__ . '/..' . '/simplesoftwareio/simple-qrcode/src/DataTypes/BTC.php', 'SimpleSoftwareIO\\QrCode\\DataTypes\\BTC' => __DIR__ . '/..' . '/simplesoftwareio/simple-qrcode/src/DataTypes/BTC.php',
'SimpleSoftwareIO\\QrCode\\DataTypes\\DataTypeInterface' => __DIR__ . '/..' . '/simplesoftwareio/simple-qrcode/src/DataTypes/DataTypeInterface.php', 'SimpleSoftwareIO\\QrCode\\DataTypes\\DataTypeInterface' => __DIR__ . '/..' . '/simplesoftwareio/simple-qrcode/src/DataTypes/DataTypeInterface.php',
'SimpleSoftwareIO\\QrCode\\DataTypes\\Email' => __DIR__ . '/..' . '/simplesoftwareio/simple-qrcode/src/DataTypes/Email.php', 'SimpleSoftwareIO\\QrCode\\DataTypes\\Email' => __DIR__ . '/..' . '/simplesoftwareio/simple-qrcode/src/DataTypes/Email.php',
@@ -13166,6 +13482,24 @@ class ComposerStaticInite18b3d3bc6afaf5dd5c2b53c80a29450
'Symfony\\Component\\VarDumper\\Server\\DumpServer' => __DIR__ . '/..' . '/symfony/var-dumper/Server/DumpServer.php', 'Symfony\\Component\\VarDumper\\Server\\DumpServer' => __DIR__ . '/..' . '/symfony/var-dumper/Server/DumpServer.php',
'Symfony\\Component\\VarDumper\\Test\\VarDumperTestTrait' => __DIR__ . '/..' . '/symfony/var-dumper/Test/VarDumperTestTrait.php', 'Symfony\\Component\\VarDumper\\Test\\VarDumperTestTrait' => __DIR__ . '/..' . '/symfony/var-dumper/Test/VarDumperTestTrait.php',
'Symfony\\Component\\VarDumper\\VarDumper' => __DIR__ . '/..' . '/symfony/var-dumper/VarDumper.php', 'Symfony\\Component\\VarDumper\\VarDumper' => __DIR__ . '/..' . '/symfony/var-dumper/VarDumper.php',
'Symfony\\Component\\VarExporter\\Exception\\ClassNotFoundException' => __DIR__ . '/..' . '/symfony/var-exporter/Exception/ClassNotFoundException.php',
'Symfony\\Component\\VarExporter\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/var-exporter/Exception/ExceptionInterface.php',
'Symfony\\Component\\VarExporter\\Exception\\LogicException' => __DIR__ . '/..' . '/symfony/var-exporter/Exception/LogicException.php',
'Symfony\\Component\\VarExporter\\Exception\\NotInstantiableTypeException' => __DIR__ . '/..' . '/symfony/var-exporter/Exception/NotInstantiableTypeException.php',
'Symfony\\Component\\VarExporter\\Hydrator' => __DIR__ . '/..' . '/symfony/var-exporter/Hydrator.php',
'Symfony\\Component\\VarExporter\\Instantiator' => __DIR__ . '/..' . '/symfony/var-exporter/Instantiator.php',
'Symfony\\Component\\VarExporter\\Internal\\Exporter' => __DIR__ . '/..' . '/symfony/var-exporter/Internal/Exporter.php',
'Symfony\\Component\\VarExporter\\Internal\\Hydrator' => __DIR__ . '/..' . '/symfony/var-exporter/Internal/Hydrator.php',
'Symfony\\Component\\VarExporter\\Internal\\LazyDecoratorTrait' => __DIR__ . '/..' . '/symfony/var-exporter/Internal/LazyDecoratorTrait.php',
'Symfony\\Component\\VarExporter\\Internal\\LazyObjectRegistry' => __DIR__ . '/..' . '/symfony/var-exporter/Internal/LazyObjectRegistry.php',
'Symfony\\Component\\VarExporter\\Internal\\LazyObjectState' => __DIR__ . '/..' . '/symfony/var-exporter/Internal/LazyObjectState.php',
'Symfony\\Component\\VarExporter\\Internal\\NamedClosure' => __DIR__ . '/..' . '/symfony/var-exporter/Internal/NamedClosure.php',
'Symfony\\Component\\VarExporter\\Internal\\Reference' => __DIR__ . '/..' . '/symfony/var-exporter/Internal/Reference.php',
'Symfony\\Component\\VarExporter\\Internal\\Registry' => __DIR__ . '/..' . '/symfony/var-exporter/Internal/Registry.php',
'Symfony\\Component\\VarExporter\\Internal\\Values' => __DIR__ . '/..' . '/symfony/var-exporter/Internal/Values.php',
'Symfony\\Component\\VarExporter\\LazyObjectInterface' => __DIR__ . '/..' . '/symfony/var-exporter/LazyObjectInterface.php',
'Symfony\\Component\\VarExporter\\ProxyHelper' => __DIR__ . '/..' . '/symfony/var-exporter/ProxyHelper.php',
'Symfony\\Component\\VarExporter\\VarExporter' => __DIR__ . '/..' . '/symfony/var-exporter/VarExporter.php',
'Symfony\\Component\\Yaml\\Command\\LintCommand' => __DIR__ . '/..' . '/symfony/yaml/Command/LintCommand.php', 'Symfony\\Component\\Yaml\\Command\\LintCommand' => __DIR__ . '/..' . '/symfony/yaml/Command/LintCommand.php',
'Symfony\\Component\\Yaml\\Dumper' => __DIR__ . '/..' . '/symfony/yaml/Dumper.php', 'Symfony\\Component\\Yaml\\Dumper' => __DIR__ . '/..' . '/symfony/yaml/Dumper.php',
'Symfony\\Component\\Yaml\\Escaper' => __DIR__ . '/..' . '/symfony/yaml/Escaper.php', 'Symfony\\Component\\Yaml\\Escaper' => __DIR__ . '/..' . '/symfony/yaml/Escaper.php',

View File

@@ -3923,6 +3923,102 @@
}, },
"install-path": "../kavenegar/php" "install-path": "../kavenegar/php"
}, },
{
"name": "knuckleswtf/scribe",
"version": "5.9.0",
"version_normalized": "5.9.0.0",
"source": {
"type": "git",
"url": "https://github.com/knuckleswtf/scribe.git",
"reference": "170cb6f8c56f1b26db692fdd1f26574b1765c6f7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/knuckleswtf/scribe/zipball/170cb6f8c56f1b26db692fdd1f26574b1765c6f7",
"reference": "170cb6f8c56f1b26db692fdd1f26574b1765c6f7",
"shasum": ""
},
"require": {
"ext-fileinfo": "*",
"ext-json": "*",
"ext-pdo": "*",
"fakerphp/faker": "^1.23.1",
"laravel/framework": "^9.21 || ^10.0 || ^11.0 || ^12.0 || ^13.0",
"league/flysystem": "^3.0",
"mpociot/reflection-docblock": "^1.0.1",
"nikic/php-parser": "^5.0",
"nunomaduro/collision": "^6.0 || ^7.0 || ^8.0",
"parsedown/parsedown": "^1.7",
"php": ">=8.1",
"ramsey/uuid": "^4.2.2",
"shalvah/upgrader": "^0.6.0",
"symfony/var-exporter": "^6.0 || ^7.0 || ^8.0",
"symfony/yaml": "^6.0 || ^7.0 || ^8.0"
},
"replace": {
"mpociot/laravel-apidoc-generator": "*"
},
"require-dev": {
"dms/phpunit-arraysubset-asserts": "^0.5.0",
"laravel/legacy-factories": "^1.3.0",
"laravel/pint": "^1.20",
"league/fractal": "^0.20",
"nikic/fast-route": "^1.3",
"orchestra/testbench": "^7.0 || ^8.0 || ^9.10 || ^10.0 || ^11.0",
"pestphp/pest": "^1.21 || ^2.0 || ^3.0 || ^4.0",
"phpstan/phpstan": "^2.1.5",
"phpunit/phpunit": "^9.0 || ^10.0 || ^11.0 || ^12.0",
"spatie/ray": "^1.41",
"symfony/css-selector": "^6.0 || ^7.0 || ^8.0",
"symfony/dom-crawler": "^6.0 || ^7.0 || ^8.0"
},
"time": "2026-03-21T00:39:27+00:00",
"type": "library",
"extra": {
"laravel": {
"providers": [
"Knuckles\\Scribe\\ScribeServiceProvider"
]
}
},
"installation-source": "dist",
"autoload": {
"files": [
"src/Config/helpers.php"
],
"psr-4": {
"Knuckles\\Camel\\": "camel/",
"Knuckles\\Scribe\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Shalvah"
}
],
"description": "Generate API documentation for humans from your Laravel codebase.✍",
"homepage": "https://github.com/knuckleswtf/scribe",
"keywords": [
"api",
"documentation",
"laravel"
],
"support": {
"issues": "https://github.com/knuckleswtf/scribe/issues",
"source": "https://github.com/knuckleswtf/scribe/tree/5.9.0"
},
"funding": [
{
"url": "https://patreon.com/shalvah",
"type": "patreon"
}
],
"install-path": "../knuckleswtf/scribe"
},
{ {
"name": "kreait/firebase-php", "name": "kreait/firebase-php",
"version": "7.24.0", "version": "7.24.0",
@@ -6530,6 +6626,62 @@
}, },
"install-path": "../mpdf/psr-log-aware-trait" "install-path": "../mpdf/psr-log-aware-trait"
}, },
{
"name": "mpociot/reflection-docblock",
"version": "1.0.1",
"version_normalized": "1.0.1.0",
"source": {
"type": "git",
"url": "https://github.com/mpociot/reflection-docblock.git",
"reference": "c8b2e2b1f5cebbb06e2b5ccbf2958f2198867587"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mpociot/reflection-docblock/zipball/c8b2e2b1f5cebbb06e2b5ccbf2958f2198867587",
"reference": "c8b2e2b1f5cebbb06e2b5ccbf2958f2198867587",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"suggest": {
"dflydev/markdown": "~1.0",
"erusev/parsedown": "~1.0"
},
"time": "2016-06-20T20:53:12+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Mpociot": [
"src/"
]
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mike van Riel",
"email": "mike.vanriel@naenius.com"
}
],
"support": {
"issues": "https://github.com/mpociot/reflection-docblock/issues",
"source": "https://github.com/mpociot/reflection-docblock/tree/master"
},
"install-path": "../mpociot/reflection-docblock"
},
{ {
"name": "mtdowling/jmespath.php", "name": "mtdowling/jmespath.php",
"version": "2.8.0", "version": "2.8.0",
@@ -7623,6 +7775,59 @@
}, },
"install-path": "../paragonie/random_compat" "install-path": "../paragonie/random_compat"
}, },
{
"name": "parsedown/parsedown",
"version": "1.8.0",
"version_normalized": "1.8.0.0",
"source": {
"type": "git",
"url": "https://github.com/parsedown/parsedown.git",
"reference": "96baaad00f71ba04d76e45b4620f54d3beabd6f7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/parsedown/parsedown/zipball/96baaad00f71ba04d76e45b4620f54d3beabd6f7",
"reference": "96baaad00f71ba04d76e45b4620f54d3beabd6f7",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"php": ">=7.1"
},
"require-dev": {
"phpunit/phpunit": "^7.5|^8.5|^9.6"
},
"time": "2026-02-16T11:41:01+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-0": {
"Parsedown": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Emanuil Rusev",
"email": "hello@erusev.com",
"homepage": "http://erusev.com"
}
],
"description": "Parser for Markdown.",
"homepage": "http://parsedown.org",
"keywords": [
"markdown",
"parser"
],
"support": {
"issues": "https://github.com/parsedown/parsedown/issues",
"source": "https://github.com/parsedown/parsedown/tree/1.8.0"
},
"install-path": "../parsedown/parsedown"
},
{ {
"name": "paytm/paytmchecksum", "name": "paytm/paytmchecksum",
"version": "v1.1.0", "version": "v1.1.0",
@@ -11141,6 +11346,67 @@
], ],
"install-path": "../setasign/fpdi" "install-path": "../setasign/fpdi"
}, },
{
"name": "shalvah/upgrader",
"version": "0.6.0",
"version_normalized": "0.6.0.0",
"source": {
"type": "git",
"url": "https://github.com/shalvah/upgrader.git",
"reference": "d95ed17fe9f5e1ee7d47ad835595f1af080a867f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/shalvah/upgrader/zipball/d95ed17fe9f5e1ee7d47ad835595f1af080a867f",
"reference": "d95ed17fe9f5e1ee7d47ad835595f1af080a867f",
"shasum": ""
},
"require": {
"illuminate/support": ">=8.0",
"nikic/php-parser": "^5.0",
"php": ">=8.0"
},
"require-dev": {
"dms/phpunit-arraysubset-asserts": "^0.2.0",
"pestphp/pest": "^1.21",
"phpstan/phpstan": "^1.0",
"spatie/ray": "^1.33"
},
"time": "2024-02-20T11:51:46+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"Shalvah\\Upgrader\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Shalvah",
"email": "hello@shalvah.me"
}
],
"description": "Create automatic upgrades for your package.",
"homepage": "http://github.com/shalvah/upgrader",
"keywords": [
"upgrade"
],
"support": {
"issues": "https://github.com/shalvah/upgrader/issues",
"source": "https://github.com/shalvah/upgrader/tree/0.6.0"
},
"funding": [
{
"url": "https://patreon.com/shalvah",
"type": "patreon"
}
],
"install-path": "../shalvah/upgrader"
},
{ {
"name": "simplesoftwareio/simple-qrcode", "name": "simplesoftwareio/simple-qrcode",
"version": "4.2.0", "version": "4.2.0",
@@ -14289,6 +14555,89 @@
], ],
"install-path": "../symfony/var-dumper" "install-path": "../symfony/var-dumper"
}, },
{
"name": "symfony/var-exporter",
"version": "v8.0.8",
"version_normalized": "8.0.8.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-exporter.git",
"reference": "15776bb07a91b089037da89f8832fa41d5fa6ec6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/15776bb07a91b089037da89f8832fa41d5fa6ec6",
"reference": "15776bb07a91b089037da89f8832fa41d5fa6ec6",
"shasum": ""
},
"require": {
"php": ">=8.4"
},
"require-dev": {
"symfony/property-access": "^7.4|^8.0",
"symfony/serializer": "^7.4|^8.0",
"symfony/var-dumper": "^7.4|^8.0"
},
"time": "2026-03-30T15:14:47+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"Symfony\\Component\\VarExporter\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Allows exporting any serializable PHP data structure to plain PHP code",
"homepage": "https://symfony.com",
"keywords": [
"clone",
"construct",
"export",
"hydrate",
"instantiate",
"lazy-loading",
"proxy",
"serialize"
],
"support": {
"source": "https://github.com/symfony/var-exporter/tree/v8.0.8"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://github.com/nicolas-grekas",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"install-path": "../symfony/var-exporter"
},
{ {
"name": "symfony/yaml", "name": "symfony/yaml",
"version": "v7.4.1", "version": "v7.4.1",
@@ -14945,11 +15294,14 @@
"fakerphp/faker", "fakerphp/faker",
"filp/whoops", "filp/whoops",
"hamcrest/hamcrest-php", "hamcrest/hamcrest-php",
"knuckleswtf/scribe",
"laravel/breeze", "laravel/breeze",
"laravel/pint", "laravel/pint",
"laravel/sail", "laravel/sail",
"mockery/mockery", "mockery/mockery",
"mpociot/reflection-docblock",
"nunomaduro/collision", "nunomaduro/collision",
"parsedown/parsedown",
"phar-io/manifest", "phar-io/manifest",
"phar-io/version", "phar-io/version",
"phpunit/php-code-coverage", "phpunit/php-code-coverage",
@@ -14973,11 +15325,13 @@
"sebastian/recursion-context", "sebastian/recursion-context",
"sebastian/type", "sebastian/type",
"sebastian/version", "sebastian/version",
"shalvah/upgrader",
"spatie/backtrace", "spatie/backtrace",
"spatie/error-solutions", "spatie/error-solutions",
"spatie/flare-client-php", "spatie/flare-client-php",
"spatie/ignition", "spatie/ignition",
"spatie/laravel-ignition", "spatie/laravel-ignition",
"symfony/var-exporter",
"symfony/yaml", "symfony/yaml",
"theseer/tokenizer" "theseer/tokenizer"
] ]

File diff suppressed because it is too large Load Diff

View File

@@ -1,29 +0,0 @@
<?php
// platform_check.php @generated by Composer
$issues = array();
if (!(PHP_VERSION_ID >= 80200)) {
$issues[] = 'Your Composer dependencies require a PHP version ">= 8.2.0". You are running ' . PHP_VERSION . '.';
}
if (PHP_INT_SIZE !== 8) {
$issues[] = 'Your Composer dependencies require a 64-bit build of PHP.';
}
if ($issues) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
} elseif (!headers_sent()) {
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
}
}
throw new \RuntimeException(
'Composer detected issues in your platform: ' . implode(' ', $issues)
);
}

View File

@@ -0,0 +1,38 @@
---
name: release-minor
description: Automates the process of tagging a new minor release for Scribe by analyzing commit messages, updating the changelog, and creating a GitHub release.
---
# Release Minor Version
This skill automates the process of tagging a new minor release for Scribe.
## Workflow
1. **Analyze Commits & Build Changelog**:
- Identify the last release tag (e.g., using `git tag --sort=-v:refname | head -n 1`).
- Get all commits from the last tag to `HEAD`.
- Analyze commit messages to categorize them into "Added", "Modified", "Fixed", or "Removed".
- Draft a new section for `CHANGELOG.md` following the existing format:
```markdown
## <New Version> (<Date>)
### Added
- [Description] ([#PR](link))
### Modified
- ...
```
2. **Update Files**:
- Prepend the new section to the top of the release list in `CHANGELOG.md`.
- Update the `public const VERSION` in `src/Scribe.php` to the new version number.
3. **Commit and Push**:
- Stage `CHANGELOG.md` and `src/Scribe.php`.
- Commit with the message: `Bump version to <New Version>`.
- Push the changes to the remote repository.
4. **Create GitHub Release**:
- Use the `gh` CLI to create a new release.
- Command: `gh release create <New Version> --title "<New Version>" --notes "<Changelog Content>"`
- Ensure the notes correspond exactly to the added changelog section.

View File

@@ -0,0 +1,36 @@
#!/usr/bin/env bash
set -euo pipefail
# shared pre-commit hook to run pint
# Try several fallbacks so it works on Unix and common Windows setups.
# Prefer directly executable vendor binary
if [ -x "./vendor/bin/pint" ]; then
./vendor/bin/pint .
exit $?
fi
# If it's a PHP wrapper script, run with php
if [ -f "./vendor/bin/pint" ]; then
php "./vendor/bin/pint" .
exit $?
fi
# If a Windows batch exists under vendor/bin
if [ -x "./vendor/bin/pint.bat" ]; then
./vendor/bin/pint.bat .
exit $?
fi
if [ -f "./vendor/bin/pint.bat" ]; then
# Try running with cmd.exe for Windows Git environments
if command -v cmd.exe >/dev/null 2>&1; then
cmd.exe /C "vendor\\bin\\pint.bat fix"
exit $?
fi
fi
# Nothing to run; do not block the push but inform the user
echo "pint not found at ./vendor/bin/pint; skipping pre-push formatting."
exit 0

82
vendor/knuckleswtf/scribe/AGENTS.md vendored Normal file
View File

@@ -0,0 +1,82 @@
# Agent Guidelines for Scribe
This repository contains the source code for Scribe, a PHP package that generates API documentation for Laravel applications.
## 🛠 Project Tooling & Commands
This project uses **Composer** for dependency management and scripts.
- **Test Runner**: [Pest](https://pestphp.com/) (which wraps PHPUnit).
- **Static Analysis**: [PHPStan](https://phpstan.org/).
- **Code Style**: [PHP-CS-Fixer](https://cs.symfony.com/).
### Key Commands
| Action | Command | Description |
|--------|---------|-------------|
| **Run Tests** | `composer test` | Runs all tests using Pest. |
| **Run Single Test** | `vendor/bin/pest --filter MethodName` | Runs a specific test method. |
| **Run File Tests** | `vendor/bin/pest path/to/Test.php` | Runs all tests in a specific file. |
| **Lint Code** | `composer lint` | Runs PHPStan analysis. |
| **Check Style** | `composer style:check` | Checks code style without modifying files. |
| **Fix Style** | `composer style:fix` | Automatically fixes code style issues. |
> **Note**: Always run `composer test` and `composer lint` before submitting changes.
## 📐 Code Style & Conventions
Adhere strictly to the existing style. The project generally follows **PSR-12**.
### General PHP
- **Version**: PHP 8.1+. Use modern features like typed properties, union types, and constructor promotion where appropriate.
- **Strict Types**: Do **NOT** use `declare(strict_types=1);` unless strictly necessary or found in the file being edited (it is generally absent).
- **Indentation**: 4 spaces.
- **Arrays**: Use short array syntax `[]`.
- **Trailing Commas**: Use trailing commas in multi-line arrays.
### Naming
- **Classes**: `PascalCase` (e.g., `PostmanCollectionWriter`).
- **Methods**: `camelCase` (e.g., `generatePostmanCollection`).
- **Variables**: `camelCase` (e.g., `$groupedEndpoints`).
- **Constants**: `UPPER_CASE_WITH_UNDERSCORES`.
### Imports & Namespaces
- **Ordering**: Alphabetical order.
- **Grouping**: Group standard library imports separately if applicable, but generally keep them sorted.
- **Unused Imports**: Remove unused imports.
### Type Hinting & Docblocks
- **Types**: Use native PHP type hints (param and return types) whenever possible.
- Example: `public function writeDocs(array $groupedEndpoints): void`
- **Docblocks**:
- Use PHPDoc for generic arrays to specify content types (e.g., `/** @param array<string, mixed> $config */`).
- Use `/** @var ClassName $var */` for inline type hinting when the static analyzer cannot infer it (e.g., resolving from container).
- Do not duplicate native type info in docblocks unless adding detail.
### Laravel Integration
- **Dependency Injection**: Prefer constructor injection.
- **Helpers**: Use Laravel helpers (`app()`, `config()`, `public_path()`) where appropriate and consistent with existing code.
- **Facades**: Facades are used (e.g., `Storage`, `Route`). Import them via `Illuminate\Support\Facades\...`.
## 🧪 Testing Guidelines
- **Framework**: Tests are written using PHPUnit class syntax (extending `BaseLaravelTest` or `TestCase`), but executed via Pest.
- **Location**: Place unit tests in `tests/Unit/`.
- **Naming**: Test classes end in `Test.php`. Test methods use the `/** @test */` annotation or start with `test`.
- **Assertions**: Use standard PHPUnit assertions (e.g., `$this->assertEquals`, `$this->assertCount`).
- **Mocking**: Use Mockery or Laravel's mocking helpers if applicable.
## 📂 File Structure
- `src/`: Core package source code.
- `Writing/`: Logic for generating output files (HTML, Postman, OpenAPI).
- `Tools/`: Utility classes.
- `Attributes/`: PHP Attributes used by the package.
- `tests/`: Test suite.
- `resources/views/`: Blade templates for generated documentation.
- `config/`: Configuration files.
## 📝 Error Handling
- Use specific exceptions where possible (e.g., `ScribeException`).
- Handle errors gracefully, especially when parsing user code or configuration.
- Use `ConsoleOutputUtils` (aliased as `c`) for CLI output in commands.

115
vendor/knuckleswtf/scribe/CHANGELOG.md vendored Normal file
View File

@@ -0,0 +1,115 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project aims to adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## <Version> (<Release date>)
### Fixed
### Modified
### Added
### Removed
## 5.9.0 (21 March 2026)
### Modified
- Add symfony/yaml v8 support ([#1063](https://github.com/knuckleswtf/scribe/pull/1063))
## 5.8.0 (23 February 2026)
### Added
- Allow opt in suppressing of model events when generating response data with factories ([#1057](https://github.com/knuckleswtf/scribe/pull/1057))
- Add agent skill for releasing (c56c096d)
### Modified
- Bump dependencies for Laravel 13 ([#1060](https://github.com/knuckleswtf/scribe/pull/1060))
### Fixed
- Fix undefined array key 'text' in MarkdownParser::blockHeader ([#1059](https://github.com/knuckleswtf/scribe/pull/1059))
## 5.7.0 (04 February 2026)
### Added
- Feature: laravel console output ([#1047](https://github.com/knuckleswtf/scribe/pull/1047))
- Add AGENTS.md for AI coding assistants ([#1055](https://github.com/knuckleswtf/scribe/pull/1055))
- Add OpenAPI 3.1 schema example to examples conversion ([#1042](https://github.com/knuckleswtf/scribe/pull/1042))
### Modified
- Replace erusev/parsedown with parsedown/parsedown for PHP 8.4 compatibility ([#1049](https://github.com/knuckleswtf/scribe/pull/1049))
- Use pint for code style ([#1054](https://github.com/knuckleswtf/scribe/pull/1054))
### Fixed
- Fix HTML special characters breaking Try It Out panel JSON display ([#1048](https://github.com/knuckleswtf/scribe/pull/1048))
- Respect wrapping of API resources ([#1046](https://github.com/knuckleswtf/scribe/pull/1046))
- Prevent empty enums when omitting ResponseField parameters ([#1044](https://github.com/knuckleswtf/scribe/pull/1044))
- Openapi nullable response fields ([#1041](https://github.com/knuckleswtf/scribe/pull/1041))
## 5.6.0 (23 November 2025)
- Add support for OpenAPI v3.1 specification ([#1040](https://github.com/knuckleswtf/scribe/pull/1040))
- Added `openapi.version` configuration option to choose between OpenAPI 3.0.3 (default) and 3.1.0
- OpenAPI 3.1 uses JSON Schema Draft 2020-12 compatible nullable syntax: `type: ["string", "null"]`
- OpenAPI 3.0 continues to use `nullable: true` property
- Fully backward compatible - defaults to 3.0.3 if not configured
## 5.5.0 (25 October 2025)
### Modified
- Change shalvah/clara constraint
### Fixed
- fix: handle rare edge case in base OpenApi spec generator after parallel merge ([#1031](https://github.com/knuckleswtf/scribe/pull/1031))
## 5.4.0 (21 October 2025)
### Fixed
- fix: arrays of objects support in OpenAPI response generation ([1021](https://github.com/knuckleswtf/scribe/pull/1021))
- fix: white space issue with headers displaying in endpoint view ([#1023](https://github.com/knuckleswtf/scribe/pull/1023))
- fix: crash when API resource __construct enforces type in ResponseFromApiResource ([#1028](https://github.com/knuckleswtf/scribe/pull/1028))
### Modified
- Replace abandoned spatie/data-transfer-object with own DTO implementation ([#1024](https://github.com/knuckleswtf/scribe/pull/1024))
### Added
- Support `deprecated:` option for `#[BodyParam]/#[QueryParam]` attributes ([#1022](https://github.com/knuckleswtf/scribe/pull/1022))
- Support for `sometimes` rule ([958](https://github.com/knuckleswtf/scribe/pull/958))
- Support for custom response Content-Types (problem+json, etc.) ([#1029](https://github.com/knuckleswtf/scribe/pull/1029))
- Support strings for the `#[Deprecated]` attribute ([#1019](https://github.com/knuckleswtf/scribe/pull/1019))
## 5.3.0 (29 July 2025)
### Added
- Support `@deprecated`/`[#Deprecated]` annotations for deprecating endpoints, along with deprecated badge in the included themes ([#994](https://github.com/knuckleswtf/scribe/pull/994))
- Add enum list to Open API spec response properties ([#902](https://github.com/knuckleswtf/scribe/pull/902))
### Fixed
- Format response codes as strings in OpenAPI spec ([80d21f1c46](https://github.com/knuckleswtf/scribe/commit/80d21f1c4678e44ba8e2e549f075e7b3bfd72fe5))
- Don't escape $baseUrl in view ([39695304c9c](https://github.com/knuckleswtf/scribe/commit/39695304c9cd75d627a4e8b59fe20b4636581066))
- Possible empty part of Route when path_param is not mandatory ([#992](https://github.com/knuckleswtf/scribe/pull/992))
- Postman collection generation failing due to invalid UTF-8 characters ([#997](https://github.com/knuckleswtf/scribe/pull/997))
- Use Recursive Spec Merge in OpenAPI SecurityGenerator & Fix OverrideGenerator base ([#1003](https://github.com/knuckleswtf/scribe/pull/1003))
### Changed
- Resolve fully qualified names ([#1008](https://github.com/knuckleswtf/scribe/pull/1008))
- Ensure Validator facade rules are detected ([#1006](https://github.com/knuckleswtf/scribe/pull/1006))
- Move intro_text directly after description in config/scribe.php for easier discovery ([#1001](https://github.com/knuckleswtf/scribe/pull/1001))
## 5.2.1 (1 May 2025)
### Added
- Fix regressions in parsing validation rules [a9e7a668d](https://github.com/knuckleswtf/scribe/commit/a9e7a668d7fa74ad8a1591e443db6600498238ef)
## 5.2.0 (17 April 2025)
### Added
- Fix breaking bugfix for validation rules (array of objects) in newer Laravel versions [03968babc9](https://github.com/knuckleswtf/scribe/commit/03968babc901d38a284d3569000205e7d38ba1e1)
### Fixed
- Avoid swallowing errors on example model instantiation (#964)[https://github.com/knuckleswtf/scribe/pull/964]
## 5.1.0 (25 February 2025)
### Added
- Support for streamed responses in response calls [790ad94e512](https://github.com/knuckleswtf/scribe/commit/790ad94e512d987feae6f0443835d8cf8de64f53)
### Fixed
- Fixed use of `URL::useOrigin` vs `URL::forceRootURL` [956e9bf418](https://github.com/knuckleswtf/scribe/commit/956e9bf418f5fc06fe70009e476b1e8524aff5b1)
## 5.0.1 (20 February 2025)
### Fixed
- Fix bug in wrongly trying to determine required fields for array of strings [#951](https://github.com/knuckleswtf/scribe/pull/951)
## 5.0.0 (19 February 2025)
See the [migration guide](https://scribe.knuckles.wtf/migrating).

View File

@@ -0,0 +1,2 @@
# Contributing
Please see [our contribution guide](https://scribe.knuckles.wtf/laravel/contributing)

21
vendor/knuckleswtf/scribe/LICENSE.md vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2022 Shalvah
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

34
vendor/knuckleswtf/scribe/README.md vendored Normal file
View File

@@ -0,0 +1,34 @@
<div align="center">
<img src="logo-scribe.png" alt="logo-scribe"><br>
[![Latest Stable Version](https://poser.pugx.org/knuckleswtf/scribe/v/stable)](https://packagist.org/packages/knuckleswtf/scribe)
[![Total Downloads](https://poser.pugx.org/knuckleswtf/scribe/downloads)](https://packagist.org/packages/knuckleswtf/scribe)
[![Code Style](https://img.shields.io/badge/code_style-pint-f58d33)](https://github.com/laravel/pint)
</div>
Scribe helps you generate API documentation for humans from your Laravel codebase. See a live example at [demo.scribe.knuckles.wtf](https://demo.scribe.knuckles.wtf).
## Features
- Useful output:
- Pretty single-page HTML doc, with human-friendly text, code samples, and in-browser API tester ("Try It Out")
- Generates Postman collection and OpenAPI spec (v3.0.3 or v3.1.0)
- Smarts. Scribe can:
- extract request parameter details from FormRequests or validation rules
- safely call API endpoints to get sample responses
- generate sample responses from Eloquent API Resources or Transformers
- Customizable to different levels:
- Customize the UI by adjusting text, ordering, examples, or changing the UI itself
- Add custom strategies to adjust how data is extracted
- Statically define extra endpoints or information not in your codebase
> [!TIP]
> 👋 Scribe helps you generate docs automatically, but if you really want to make friendly, maintainable, and testable API docs, there are some more things you need to know.
> So I made [a course](https://shalvah.teachable.com/p/api-documentation-for-developers?utm_source=scribe-laravel&utm_medium=referral&utm_campaign=none) for you.🤗
## Documentation
Check out the documentation at [scribe.knuckles.wtf/laravel](http://scribe.knuckles.wtf/laravel).
## Contributing
Contributing is easy! See our [contribution guide](https://scribe.knuckles.wtf/laravel/contributing).

View File

@@ -0,0 +1,172 @@
<?php
namespace Knuckles\Camel;
use Illuminate\Contracts\Support\Arrayable;
class BaseDTO implements \ArrayAccess, Arrayable
{
/**
* @var array
* Added so end-users can dynamically add additional properties for their own use
*/
public array $custom = [];
public function __construct(array $parameters = [])
{
// Initialize all properties to their default values first
$this->initializeProperties();
foreach ($parameters as $key => $value) {
if (property_exists($this, $key)) {
$this->{$key} = $this->castProperty($key, $value);
}
}
}
public static function create(array|self $data, array|self $inheritFrom = []): static
{
if ($data instanceof static) {
return $data;
}
$mergedData = $inheritFrom instanceof static ? $inheritFrom->toArray() : $inheritFrom;
foreach ($data as $property => $value) {
$mergedData[$property] = $value;
}
return new static($mergedData);
}
public function toArray(): array
{
$array = [];
foreach (get_object_vars($this) as $property => $value) {
$array[$property] = $value;
}
return $this->parseArray($array);
}
public static function make(array|self $data): static
{
return $data instanceof static ? $data : new static($data);
}
public function offsetExists(mixed $offset): bool
{
return isset($this->{$offset});
}
public function offsetGet(mixed $offset): mixed
{
return $this->{$offset};
}
public function offsetSet(mixed $offset, mixed $value): void
{
$this->{$offset} = $value;
}
public function offsetUnset(mixed $offset): void
{
unset($this->{$offset});
}
public function except(string ...$keys): array
{
$array = [];
foreach (get_object_vars($this) as $property => $value) {
if (! in_array($property, $keys)) {
$array[$property] = $value;
}
}
return $this->parseArray($array);
}
public static function arrayOf(array $items): array
{
return array_map(function ($item) {
return $item instanceof static ? $item : new static($item);
}, $items);
}
protected function initializeProperties(): void
{
$reflection = new \ReflectionClass($this);
foreach ($reflection->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) {
$name = $property->getName();
// Skip if already initialized (has a default value)
if ($property->hasDefaultValue()) {
continue;
}
$type = $property->getType();
if ($type && $type->allowsNull()) {
$this->{$name} = null;
}
}
}
protected function castProperty(string $key, mixed $value): mixed
{
// If the value is already the correct type, return it as-is
if (! is_array($value)) {
return $value;
}
// Get property type through reflection
$reflection = new \ReflectionClass($this);
if (! $reflection->hasProperty($key)) {
return $value;
}
$property = $reflection->getProperty($key);
$type = $property->getType();
if ($type && $type instanceof \ReflectionNamedType && ! $type->isBuiltin()) {
$className = $type->getName();
// If it's a DTO class in our namespace, instantiate it
if (class_exists($className) && is_subclass_of($className, self::class)) {
return new $className($value);
}
// If it's another class in our namespace that has a constructor accepting arrays
if (class_exists($className)) {
try {
return new $className($value);
} catch (\Throwable $e) {
// If instantiation fails, return the original value
return $value;
}
}
}
return $value;
}
protected function parseArray(array $array): array
{
// Reimplementing here so our DTOCollection items can be recursively toArray'ed
foreach ($array as $key => $value) {
if ($value instanceof Arrayable) {
$array[$key] = $value->toArray();
continue;
}
if (! is_array($value)) {
continue;
}
$array[$key] = $this->parseArray($value);
}
return $array;
}
}

View File

@@ -0,0 +1,50 @@
<?php
namespace Knuckles\Camel;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Support\Collection;
/**
* @template T of \Knuckles\Camel\BaseDTO
*/
class BaseDTOCollection extends Collection
{
/**
* @var string the name of the base DTO class
*/
public static string $base = '';
public function __construct($items = [])
{
// Manually cast nested arrays
$items = array_map(
fn ($item) => is_array($item) ? new static::$base($item) : $item,
$items instanceof Collection ? $items->toArray() : $items
);
parent::__construct($items);
}
/**
* Append items to the collection, mutating it.
*
* @param array[]|T[] $items
*/
public function concat($items)
{
foreach ($items as $item) {
$this->push(is_array($item) ? new static::$base($item) : $item);
}
return $this;
}
public function toArray(): array
{
return array_map(
fn ($item) => $item instanceof Arrayable ? $item->toArray() : $item,
$this->items
);
}
}

View File

@@ -0,0 +1,231 @@
<?php
namespace Knuckles\Camel;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Knuckles\Camel\Output\OutputEndpointData;
use Knuckles\Scribe\Tools\PathConfig;
use Knuckles\Scribe\Tools\Utils;
use Symfony\Component\Yaml\Yaml;
class Camel
{
public static function cacheDir(PathConfig $paths): string
{
return $paths->intermediateOutputPath('endpoints.cache');
}
public static function camelDir(PathConfig $paths): string
{
return $paths->intermediateOutputPath('endpoints');
}
/**
* Load endpoints from the Camel files into groups (arrays).
*
* @return array[] each array is a group with keys including `name` and `endpoints`
*/
public static function loadEndpointsIntoGroups(string $folder): array
{
$groups = [];
self::loadEndpointsFromCamelFiles($folder, function (array $group) use (&$groups) {
$groups[$group['name']] = $group;
});
return $groups;
}
/**
* Load endpoints from the Camel files into a flat list of endpoint arrays.
* Useful when we don't care about groups, but simply want to compare endpoints contents
* to see if anything changed.
*
* @return array[] list of endpoint arrays
*/
public static function loadEndpointsToFlatPrimitivesArray(string $folder): array
{
$endpoints = [];
self::loadEndpointsFromCamelFiles($folder, function (array $group) use (&$endpoints) {
foreach ($group['endpoints'] as $endpoint) {
$endpoints[] = $endpoint;
}
});
return $endpoints;
}
public static function loadEndpointsFromCamelFiles(string $folder, callable $callback): void
{
$contents = Utils::listDirectoryContents($folder);
foreach ($contents as $object) {
if (
$object->isFile()
&& Str::endsWith(basename($object->path()), '.yaml')
&& ! Str::startsWith(basename($object->path()), 'custom.')
) {
$group = Yaml::parseFile($object['path']);
$callback($group);
}
}
}
public static function loadUserDefinedEndpoints(string $folder): array
{
$contents = Utils::listDirectoryContents($folder);
$userDefinedEndpoints = [];
foreach ($contents as $object) {
if (
$object->isFile()
&& Str::endsWith(basename($object->path()), '.yaml')
&& Str::startsWith(basename($object->path()), 'custom.')
) {
$endpoints = Yaml::parseFile($object->path());
foreach (($endpoints ?: []) as $endpoint) {
$userDefinedEndpoints[] = $endpoint;
}
}
}
return $userDefinedEndpoints;
}
public static function doesGroupContainEndpoint(array $group, OutputEndpointData $endpoint): bool
{
return (bool) (Arr::first($group['endpoints'], function ($e) use ($endpoint) {
return $e->endpointId() === $endpoint->endpointId();
}));
}
/**
* @param array[] $groupedEndpoints
* @param array $configFileOrder the order for groups that users specified in their config file
* @return array[]
*/
public static function sortByConfigFileOrder(array $groupedEndpoints, array $configFileOrder): array
{
if (empty($configFileOrder)) {
ksort($groupedEndpoints, SORT_NATURAL);
return $groupedEndpoints;
}
// First, sort groups
$groupsOrder = Utils::getTopLevelItemsFromMixedConfigList($configFileOrder);
$groupsCollection = collect($groupedEndpoints);
$wildcardPosition = array_search('*', $groupsOrder);
if ($wildcardPosition !== false) {
$promotedGroups = array_splice($groupsOrder, 0, $wildcardPosition);
$demotedGroups = array_splice($groupsOrder, 1);
$promotedOrderedGroups = $groupsCollection->filter(fn ($group, $groupName) => in_array($groupName, $promotedGroups))
->sortKeysUsing(self::getOrderListComparator($promotedGroups));
$demotedOrderedGroups = $groupsCollection->filter(fn ($group, $groupName) => in_array($groupName, $demotedGroups))
->sortKeysUsing(self::getOrderListComparator($demotedGroups));
$nonWildcardGroups = array_merge($promotedGroups, $demotedGroups);
$wildCardOrderedGroups = $groupsCollection->filter(fn ($group, $groupName) => ! in_array($groupName, $nonWildcardGroups))
->sortKeysUsing(self::getOrderListComparator($demotedGroups));
$groupedEndpoints = $promotedOrderedGroups->merge($wildCardOrderedGroups)
->merge($demotedOrderedGroups);
} else {
$groupedEndpoints = $groupsCollection->sortKeysUsing(self::getOrderListComparator($groupsOrder));
}
return $groupedEndpoints->map(function (array $group, string $groupName) use ($configFileOrder) {
$sortedEndpoints = collect($group['endpoints']);
if (isset($configFileOrder[$groupName])) {
// Second-level order list. Can contain endpoint or subgroup names
$level2Order = Utils::getTopLevelItemsFromMixedConfigList($configFileOrder[$groupName]);
$sortedEndpoints = $sortedEndpoints->sortBy(
function (OutputEndpointData $e) use ($configFileOrder, $level2Order) {
$endpointIdentifier = $e->httpMethods[0].' /'.$e->uri;
// First, check if there's an ordering specified for the endpoint itself
$indexOfEndpointInL2Order = array_search($endpointIdentifier, $level2Order);
if ($indexOfEndpointInL2Order !== false) {
return $indexOfEndpointInL2Order;
}
// Check if there's an ordering for the endpoint's subgroup
$indexOfSubgroupInL2Order = array_search($e->metadata->subgroup, $level2Order);
if ($indexOfSubgroupInL2Order !== false) {
// There's a subgroup order; check if there's an endpoints order within that
$orderOfEndpointsInSubgroup = $configFileOrder[$e->metadata->groupName][$e->metadata->subgroup] ?? [];
$indexOfEndpointInSubGroup = array_search($endpointIdentifier, $orderOfEndpointsInSubgroup);
return ($indexOfEndpointInSubGroup === false)
? $indexOfSubgroupInL2Order
: ($indexOfSubgroupInL2Order + ($indexOfEndpointInSubGroup * 0.1));
}
return INF;
},
);
}
return [
'name' => $groupName,
'description' => $group['description'],
'endpoints' => $sortedEndpoints->all(),
];
})->values()->all();
}
/**
* Prepare endpoints to be turned into HTML.
* Map them into OutputEndpointData DTOs, and sort them by the specified order in the config file.
*
* @param array<string,array[]> $groupedEndpoints
*/
public static function prepareGroupedEndpointsForOutput(array $groupedEndpoints, array $configFileOrder = []): array
{
$groups = array_map(function (array $group) {
return [
'name' => $group['name'],
'description' => $group['description'],
'endpoints' => array_map(
fn (array $endpoint) => OutputEndpointData::fromExtractedEndpointArray($endpoint),
$group['endpoints']
),
];
}, $groupedEndpoints);
return self::sortByConfigFileOrder($groups, $configFileOrder);
}
/**
* Given an $order list like ['first', 'second', ...], return a compare function that can be used to sort
* a list of strings based on the order of items in $order.
* Any strings not in the list are sorted with natural sort.
*/
protected static function getOrderListComparator(array $order): \Closure
{
return function ($a, $b) use ($order) {
$indexOfA = array_search($a, $order);
$indexOfB = array_search($b, $order);
// If both are in the $order list, compare them normally based on their position in the list
if ($indexOfA !== false && $indexOfB !== false) {
return $indexOfA <=> $indexOfB;
}
// If only A is in the $order list, then it must come before B.
if ($indexOfA !== false) {
return -1;
}
// If only B is in the $order list, then it must come before A.
if ($indexOfB !== false) {
return 1;
}
// If neither is present, fall back to natural sort
return strnatcmp($a, $b);
};
}
}

View File

@@ -0,0 +1,169 @@
<?php
namespace Knuckles\Camel\Extraction;
use Illuminate\Http\UploadedFile;
use Illuminate\Routing\Route;
use Knuckles\Camel\BaseDTO;
use Knuckles\Scribe\Extracting\Shared\UrlParamsNormalizer;
use Knuckles\Scribe\Tools\Globals;
use Knuckles\Scribe\Tools\Utils as u;
class ExtractedEndpointData extends BaseDTO
{
/**
* @var array<string>
*/
public array $httpMethods;
public string $uri;
public Metadata $metadata;
/**
* @var array<string,string>
*/
public array $headers = [];
/**
* @var array<string,Parameter>
*/
public array $urlParameters = [];
/**
* @var array<string,mixed>
*/
public array $cleanUrlParameters = [];
/**
* @var array<string,Parameter>
*/
public array $queryParameters = [];
/**
* @var array<string,mixed>
*/
public array $cleanQueryParameters = [];
/**
* @var array<string,Parameter>
*/
public array $bodyParameters = [];
/**
* @var array<string,mixed>
*/
public array $cleanBodyParameters = [];
/**
* @var array<string,array|UploadedFile>
*/
public array $fileParameters = [];
public ResponseCollection $responses;
/**
* @var array<string,ResponseField>
*/
public array $responseFields = [];
/**
* Authentication info for this endpoint. In the form [{where}, {name}, {sample}]
* Example: ["queryParameters", "api_key", "njiuyiw97865rfyvgfvb1"].
*/
public array $auth = [];
public ?\ReflectionClass $controller;
public ?\ReflectionFunctionAbstract $method;
public ?Route $route;
public function __construct(array $parameters = [])
{
$parameters['metadata'] ??= new Metadata([]);
$parameters['responses'] ??= new ResponseCollection([]);
parent::__construct($parameters);
$defaultNormalizer = fn () => UrlParamsNormalizer::normalizeParameterNamesInRouteUri($this->route, $this->method);
$this->uri = match (is_callable(Globals::$__normalizeEndpointUrlUsing)) {
true => call_user_func_array(
Globals::$__normalizeEndpointUrlUsing,
[$this->route->uri, $this->route, $this->method, $this->controller, $defaultNormalizer]
),
default => $defaultNormalizer(),
};
}
/**
* @param array $extras Only used for quick overrides in tests
*
* @throws \ReflectionException
*/
public static function fromRoute(Route $route, array $extras = []): self
{
$httpMethods = self::getMethods($route);
$uri = $route->uri();
[$controllerName, $methodName] = u::getRouteClassAndMethodNames($route);
$controller = new \ReflectionClass($controllerName);
$method = u::getReflectedRouteMethod([$controllerName, $methodName]);
$data = compact('httpMethods', 'uri', 'controller', 'method', 'route');
$data = array_merge($data, $extras);
return new self($data);
}
/**
* @return array<string>
*/
public static function getMethods(Route $route): array
{
$methods = $route->methods();
// Laravel adds an automatic "HEAD" endpoint for each GET request, so we'll strip that out,
// but not if there's only one method (means it was intentional)
if (count($methods) === 1) {
return $methods;
}
return array_diff($methods, ['HEAD']);
}
public function name()
{
return sprintf("[%s] {$this->route->uri}.", implode(',', $this->route->methods));
}
public function endpointId()
{
return $this->httpMethods[0].str_replace(['/', '?', '{', '}', ':', '\\', '+', '|'], '-', $this->uri);
}
/**
* Prepare the endpoint data for serialising.
*/
public function forSerialisation()
{
$copyArray = $this->except(
// Get rid of all duplicate data
'cleanQueryParameters',
'cleanUrlParameters',
'fileParameters',
'cleanBodyParameters',
// and objects used only in extraction
'route',
'controller',
'method',
'auth',
);
// Remove these, since they're on the parent group object
if (isset($copyArray['metadata']) && $copyArray['metadata'] instanceof Metadata) {
$copyArray['metadata'] = $copyArray['metadata']->except('groupName', 'groupDescription');
}
return $copyArray;
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace Knuckles\Camel\Extraction;
use Knuckles\Camel\BaseDTO;
class Metadata extends BaseDTO
{
public ?string $groupName;
public ?string $groupDescription;
public ?string $subgroup;
public ?string $subgroupDescription;
public ?string $title;
public ?string $description;
public bool $authenticated = false;
public bool|string $deprecated = false;
}

View File

@@ -0,0 +1,32 @@
<?php
namespace Knuckles\Camel\Extraction;
use Knuckles\Camel\BaseDTO;
class Parameter extends BaseDTO
{
public string $name;
public ?string $description = null;
public bool $required = false;
public mixed $example = null;
public string $type = 'string';
public array $enumValues = [];
public bool $exampleWasSpecified = false;
public bool $nullable = false;
public bool $deprecated = false;
public function __construct(array $parameters = [])
{
unset($parameters['setter']);
parent::__construct($parameters);
}
}

View File

@@ -0,0 +1,67 @@
<?php
namespace Knuckles\Camel\Extraction;
use Illuminate\Support\Str;
use Knuckles\Camel\BaseDTO;
class Response extends BaseDTO
{
public int $status;
public ?string $content;
public array $headers = [];
public ?string $description;
public function __construct(array $parameters = [])
{
if (is_array($parameters['content'] ?? null)) {
$parameters['content'] = json_encode($parameters['content'], JSON_UNESCAPED_SLASHES);
}
if (isset($parameters['status'])) {
$parameters['status'] = (int) $parameters['status'];
}
$hiddenHeaders = [
'date',
'Date',
'etag',
'ETag',
'last-modified',
'Last-Modified',
'date',
'Date',
'content-length',
'Content-Length',
'connection',
'Connection',
'x-powered-by',
'X-Powered-By',
];
if (! empty($parameters['headers'])) {
foreach ($hiddenHeaders as $headerName) {
unset($parameters['headers'][$headerName]);
}
}
parent::__construct($parameters);
}
public function fullDescription()
{
$description = $this->status;
if ($this->description) {
$description .= ", {$this->description}";
}
return $description;
}
public function isBinary(): bool
{
return is_string($this->content) && Str::startsWith($this->content, '<<binary>>');
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace Knuckles\Camel\Extraction;
use Knuckles\Camel\BaseDTOCollection;
/**
* @extends BaseDTOCollection<Response>
*/
class ResponseCollection extends BaseDTOCollection
{
public static string $base = Response::class;
public function hasSuccessResponse(): bool
{
return $this->first(
fn ($response) => '2' === ((string) ($response->status))[0]
) !== null;
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace Knuckles\Camel\Extraction;
use Knuckles\Camel\BaseDTO;
class ResponseField extends BaseDTO
{
// TODO make this extend Parameter, so we can have strong types and a unified API
// but first we need to normalize incoming data
/** @var string */
public $name;
/** @var string */
public $description;
/** @var string */
public $type;
/** @var bool */
public $required;
/** @var mixed */
public $example;
public array $enumValues = [];
/** @var bool */
public $nullable;
}

View File

@@ -0,0 +1,355 @@
<?php
namespace Knuckles\Camel\Output;
use Illuminate\Http\UploadedFile;
use Illuminate\Routing\Route;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Knuckles\Camel\BaseDTO;
use Knuckles\Camel\Extraction\Metadata;
use Knuckles\Camel\Extraction\ResponseCollection;
use Knuckles\Camel\Extraction\ResponseField;
use Knuckles\Scribe\Extracting\Extractor;
use Knuckles\Scribe\Tools\Utils as u;
use Knuckles\Scribe\Tools\WritingUtils;
/**
* Endpoint DTO, optimized for generating HTML output.
* Unneeded properties removed, extra properties and helper methods added.
*/
class OutputEndpointData extends BaseDTO
{
/**
* @var array<string>
*/
public array $httpMethods;
public string $uri;
public Metadata $metadata;
/**
* @var array<string,string>
*/
public array $headers = [];
/**
* @var array<string,Parameter>
*/
public array $urlParameters = [];
/**
* @var array<string,mixed>
*/
public array $cleanUrlParameters = [];
/**
* @var array<string,Parameter>
*/
public array $queryParameters = [];
/**
* @var array<string,mixed>
*/
public array $cleanQueryParameters = [];
/**
* @var array<string, Parameter>
*/
public array $bodyParameters = [];
/**
* @var array<string,mixed>
*/
public array $cleanBodyParameters = [];
/**
* @var array<string,UploadedFile>
*/
public array $fileParameters = [];
public ResponseCollection $responses;
/**
* @var array<string,ResponseField>
*/
public array $responseFields = [];
/**
* The same as bodyParameters, but organized in a hierarchy.
* So, top-level items first, with a __fields property containing their children, and so on.
* Useful so we can easily render and nest on the frontend.
*
* @var array<string, array>
*/
public array $nestedBodyParameters = [];
/**
* @var array<string, array>
*/
public array $nestedResponseFields = [];
public ?string $boundUri;
public function __construct(array $parameters = [])
{
// spatie/dto currently doesn't auto-cast nested DTOs like that
$parameters['responses'] = new ResponseCollection($parameters['responses'] ?? []);
$parameters['bodyParameters'] = array_map(fn ($param) => new Parameter($param), $parameters['bodyParameters'] ?? []);
$parameters['queryParameters'] = array_map(fn ($param) => new Parameter($param), $parameters['queryParameters'] ?? []);
$parameters['urlParameters'] = array_map(fn ($param) => new Parameter($param), $parameters['urlParameters'] ?? []);
$parameters['responseFields'] = array_map(fn ($param) => new ResponseField($param), $parameters['responseFields'] ?? []);
parent::__construct($parameters);
$this->cleanBodyParameters = Extractor::cleanParams($this->bodyParameters);
$this->cleanQueryParameters = Extractor::cleanParams($this->queryParameters);
$this->cleanUrlParameters = Extractor::cleanParams($this->urlParameters);
$this->nestedBodyParameters = self::nestArrayAndObjectFields($this->bodyParameters, $this->cleanBodyParameters);
$this->nestedResponseFields = self::nestArrayAndObjectFields($this->responseFields);
$this->boundUri = u::getUrlWithBoundParameters($this->uri, $this->cleanUrlParameters);
[$files, $regularParameters] = static::splitIntoFileAndRegularParameters($this->cleanBodyParameters);
if (count($files)) {
$this->headers['Content-Type'] = 'multipart/form-data';
}
$this->fileParameters = $files;
$this->cleanBodyParameters = $regularParameters;
}
/**
* @return array<string>
*/
public static function getMethods(Route $route): array
{
$methods = $route->methods();
// Laravel adds an automatic "HEAD" endpoint for each GET request, so we'll strip that out,
// but not if there's only one method (means it was intentional)
if (count($methods) === 1) {
return $methods;
}
return array_diff($methods, ['HEAD']);
}
public static function fromExtractedEndpointArray(array $endpoint): self
{
return new self($endpoint);
}
/**
* Transform body parameters such that object fields have a `fields` property containing a list of all subfields
* Subfields will be removed from the main parameter map
* For instance, if $parameters is [
* 'dad' => new Parameter(...),
* 'dad.age' => new Parameter(...),
* 'dad.cars[]' => new Parameter(...),
* 'dad.cars[].model' => new Parameter(...),
* 'dad.cars[].price' => new Parameter(...),
* ],
* normalise this into [
* 'dad' => [
* ...,
* '__fields' => [
* 'dad.age' => [...],
* 'dad.cars' => [
* ...,
* '__fields' => [
* 'model' => [...],
* 'price' => [...],
* ],
* ],
* ],
* ]].
*/
public static function nestArrayAndObjectFields(array $parameters, array $cleanParameters = []): array
{
// First, we'll make sure all object fields have parent fields properly set
$normalisedParameters = [];
foreach ($parameters as $name => $parameter) {
if (Str::contains($name, '.')) {
// If the user didn't add a parent field, we'll helpfully add it for them
$ancestors = [];
$parts = explode('.', $name);
$fieldName = array_pop($parts);
$parentName = mb_rtrim(implode('.', $parts), '[]');
// When the body is an array, param names will be "[].paramname",
// so $parentName is empty. Let's fix that.
if (empty($parentName)) {
$parentName = '[]';
}
while ($parentName) {
if (! empty($normalisedParameters[$parentName])) {
break;
}
$details = [
'name' => $parentName,
'type' => $parentName === '[]' ? 'object[]' : 'object',
'description' => '',
'required' => false,
];
if ($parameter instanceof ResponseField) {
$ancestors[] = [$parentName, new ResponseField($details)];
} else {
$lastParentExample = $details['example']
= [$fieldName => $lastParentExample ?? $parameter->example];
$ancestors[] = [$parentName, new Parameter($details)];
}
$fieldName = array_pop($parts);
$parentName = mb_rtrim(implode('.', $parts), '[]');
}
// We add ancestors in reverse so we can iterate over parents first in the next section
foreach (array_reverse($ancestors) as [$ancestorName, $ancestor]) {
$normalisedParameters[$ancestorName] = $ancestor;
}
}
$normalisedParameters[$name] = $parameter;
unset($lastParentExample);
}
$finalParameters = [];
foreach ($normalisedParameters as $name => $parameter) {
$parameter = $parameter->toArray();
if (Str::contains($name, '.')) { // An object field
// Get the various pieces of the name
$parts = explode('.', $name);
$fieldName = array_pop($parts);
$baseName = implode('.__fields.', $parts);
// For subfields, the type is indicated in the source object
// eg test.items[].more and test.items.more would both have parent field with name `items` and containing __fields => more
// The difference would be in the parent field's `type` property (object[] vs object)
// So we can get rid of all [] to get the parent name
$dotPathToParent = str_replace('[]', '', $baseName);
// When the body is an array, param names will be "[].paramname",
// so $parts is ['[]']
if ($parts[0] === '[]') {
$dotPathToParent = '[]'.$dotPathToParent;
}
$dotPath = $dotPathToParent.'.__fields.'.$fieldName;
Arr::set($finalParameters, $dotPath, $parameter);
} else { // A regular field, not a subfield of anything
// Note: we're assuming any subfields of this field are listed *after* it,
// and will set __fields correctly when we iterate over them
// Hence why we create a new "normalisedParameters" array above and push the parent to that first
$parameter['__fields'] = [];
$finalParameters[$name] = $parameter;
}
}
// Finally, if the body is an array, remove any other items.
if (isset($finalParameters['[]'])) {
$finalParameters = ['[]' => $finalParameters['[]']];
// At this point, the examples are likely [[], []],
// but have been correctly set in clean parameters, so let's update them
if ($finalParameters['[]']['example'][0] === [] && ! empty($cleanParameters)) {
$finalParameters['[]']['example'] = $cleanParameters;
}
}
return $finalParameters;
}
public function endpointId(): string
{
return $this->httpMethods[0].str_replace(['/', '?', '{', '}', ':', '\\', '+', '|', '.'], '-', $this->uri);
}
public function name(): string
{
return $this->metadata->title ?: ($this->httpMethods[0].' '.$this->uri);
}
public function fullSlug(): string
{
$groupSlug = Str::slug($this->metadata->groupName);
$endpointId = $this->endpointId();
return "{$groupSlug}-{$endpointId}";
}
public function hasResponses(): bool
{
return count($this->responses) > 0;
}
public function hasFiles(): bool
{
return count($this->fileParameters) > 0;
}
public function isArrayBody(): bool
{
return count($this->nestedBodyParameters) === 1
&& array_keys($this->nestedBodyParameters)[0] === '[]';
}
public function isGet(): bool
{
return in_array('GET', $this->httpMethods);
}
public function isAuthed(): bool
{
return $this->metadata->authenticated;
}
public function hasJsonBody(): bool
{
if ($this->hasFiles() || empty($this->nestedBodyParameters)) {
return false;
}
$contentType = data_get($this->headers, 'Content-Type', data_get($this->headers, 'content-type', ''));
return str_contains($contentType, 'json');
}
public function getSampleBody()
{
return WritingUtils::getSampleBody($this->nestedBodyParameters);
}
public function hasHeadersOrQueryOrBodyParams(): bool
{
return ! empty($this->headers)
|| ! empty($this->cleanQueryParameters)
|| ! empty($this->cleanBodyParameters);
}
public static function splitIntoFileAndRegularParameters(array $parameters): array
{
$files = [];
$regularParameters = [];
foreach ($parameters as $name => $example) {
if ($example instanceof UploadedFile) {
$files[$name] = $example;
} elseif (is_array($example) && ! empty($example)) {
[$subFiles, $subRegulars] = static::splitIntoFileAndRegularParameters($example);
foreach ($subFiles as $subName => $subExample) {
$files[$name][$subName] = $subExample;
}
foreach ($subRegulars as $subName => $subExample) {
$regularParameters[$name][$subName] = $subExample;
}
} else {
$regularParameters[$name] = $example;
}
}
return [$files, $regularParameters];
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Knuckles\Camel\Output;
class Parameter extends \Knuckles\Camel\Extraction\Parameter
{
public array $__fields = [];
public function toArray(): array
{
return $this->except('__fields');
}
}

98
vendor/knuckleswtf/scribe/composer.json vendored Normal file
View File

@@ -0,0 +1,98 @@
{
"name": "knuckleswtf/scribe",
"description": "Generate API documentation for humans from your Laravel codebase.✍",
"license": "MIT",
"keywords": [
"API",
"documentation",
"laravel"
],
"authors": [
{
"name": "Shalvah"
}
],
"homepage": "https://github.com/knuckleswtf/scribe",
"funding": [
{
"type": "patreon",
"url": "https://patreon.com/shalvah"
}
],
"require": {
"php": ">=8.1",
"ext-fileinfo": "*",
"ext-json": "*",
"ext-pdo": "*",
"fakerphp/faker": "^1.23.1",
"laravel/framework": "^9.21 || ^10.0 || ^11.0 || ^12.0 || ^13.0",
"league/flysystem": "^3.0",
"mpociot/reflection-docblock": "^1.0.1",
"nikic/php-parser": "^5.0",
"nunomaduro/collision": "^6.0 || ^7.0 || ^8.0",
"parsedown/parsedown": "^1.7",
"ramsey/uuid": "^4.2.2",
"shalvah/upgrader": "^0.6.0",
"symfony/var-exporter": "^6.0 || ^7.0 || ^8.0",
"symfony/yaml": "^6.0 || ^7.0 || ^8.0"
},
"require-dev": {
"dms/phpunit-arraysubset-asserts": "^0.5.0",
"laravel/legacy-factories": "^1.3.0",
"laravel/pint": "^1.20",
"league/fractal": "^0.20",
"nikic/fast-route": "^1.3",
"orchestra/testbench": "^7.0 || ^8.0 || ^9.10 || ^10.0 || ^11.0",
"pestphp/pest": "^1.21 || ^2.0 || ^3.0 || ^4.0",
"phpstan/phpstan": "^2.1.5",
"phpunit/phpunit": "^9.0 || ^10.0 || ^11.0 || ^12.0",
"spatie/ray": "^1.41",
"symfony/css-selector": "^6.0 || ^7.0 || ^8.0",
"symfony/dom-crawler": "^6.0 || ^7.0 || ^8.0"
},
"replace": {
"mpociot/laravel-apidoc-generator": "*"
},
"autoload": {
"psr-4": {
"Knuckles\\Camel\\": "camel/",
"Knuckles\\Scribe\\": "src/"
},
"files": [
"src/Config/helpers.php"
]
},
"autoload-dev": {
"psr-4": {
"Knuckles\\Scribe\\Tests\\": "tests/"
}
},
"config": {
"allow-plugins": {
"pestphp/pest-plugin": true
},
"preferred-install": "dist",
"process-timeout": 600,
"sort-packages": true
},
"extra": {
"laravel": {
"providers": [
"Knuckles\\Scribe\\ScribeServiceProvider"
]
}
},
"scripts": {
"post-install-cmd": [
"git config core.hooksPath .githooks"
],
"post-update-cmd": [
"git config core.hooksPath .githooks"
],
"lint": "phpstan analyse -c ./phpstan.neon src camel --memory-limit 1G",
"style:check": "pint . --test --parallel --ansi",
"style:fix": "pint . --parallel --ansi",
"test": "pest --stop-on-failure --colors",
"test-ci": "pest"
}
}

View File

@@ -0,0 +1,259 @@
<?php
use Knuckles\Scribe\Config\AuthIn;
use Knuckles\Scribe\Config\Defaults;
use Knuckles\Scribe\Extracting\Strategies;
use function Knuckles\Scribe\Config\configureStrategy;
use function Knuckles\Scribe\Config\removeStrategies;
// Only the most common configs are shown. See the https://scribe.knuckles.wtf/laravel/reference/config for all.
return [
// The HTML <title> for the generated documentation.
'title' => config('app.name').' API Documentation',
// A short description of your API. Will be included in the docs webpage, Postman collection and OpenAPI spec.
'description' => '',
// Text to place in the "Introduction" section, right after the `description`. Markdown and HTML are supported.
'intro_text' => <<<'INTRO'
This documentation aims to provide all the information you need to work with our API.
<aside>As you scroll, you'll see code examples for working with the API in different programming languages in the dark area to the right (or as part of the content on mobile).
You can switch the language used with the tabs at the top right (or from the nav menu at the top left on mobile).</aside>
INTRO,
// The base URL displayed in the docs.
// If you're using `laravel` type, you can set this to a dynamic string, like '{{ config("app.tenant_url") }}' to get a dynamic base URL.
'base_url' => config('app.url'),
// Routes to include in the docs
'routes' => [
[
'match' => [
// Match only routes whose paths match this pattern (use * as a wildcard to match any characters). Example: 'users/*'.
'prefixes' => ['api/*'],
// Match only routes whose domains match this pattern (use * as a wildcard to match any characters). Example: 'api.*'.
'domains' => ['*'],
],
// Include these routes even if they did not match the rules above.
'include' => [
// 'users.index', 'POST /new', '/auth/*'
],
// Exclude these routes even if they matched the rules above.
'exclude' => [
// 'GET /health', 'admin.*'
],
],
],
// The type of documentation output to generate.
// - "static" will generate a static HTMl page in the /public/docs folder,
// - "laravel" will generate the documentation as a Blade view, so you can add routing and authentication.
// - "external_static" and "external_laravel" do the same as above, but pass the OpenAPI spec as a URL to an external UI template
'type' => 'laravel',
// See https://scribe.knuckles.wtf/laravel/reference/config#theme for supported options
'theme' => 'default',
'static' => [
// HTML documentation, assets and Postman collection will be generated to this folder.
// Source Markdown will still be in resources/docs.
'output_path' => 'public/docs',
],
'laravel' => [
// Whether to automatically create a docs route for you to view your generated docs. You can still set up routing manually.
'add_routes' => true,
// URL path to use for the docs endpoint (if `add_routes` is true).
// By default, `/docs` opens the HTML page, `/docs.postman` opens the Postman collection, and `/docs.openapi` the OpenAPI spec.
'docs_url' => '/docs',
// Directory within `public` in which to store CSS and JS assets.
// By default, assets are stored in `public/vendor/scribe`.
// If set, assets will be stored in `public/{{assets_directory}}`
'assets_directory' => null,
// Middleware to attach to the docs endpoint (if `add_routes` is true).
'middleware' => [],
],
'external' => [
'html_attributes' => [],
],
'try_it_out' => [
// Add a Try It Out button to your endpoints so consumers can test endpoints right from their browser.
// Don't forget to enable CORS headers for your endpoints.
'enabled' => true,
// The base URL to use in the API tester. Leave as null to be the same as the displayed URL (`scribe.base_url`).
'base_url' => null,
// [Laravel Sanctum] Fetch a CSRF token before each request, and add it as an X-XSRF-TOKEN header.
'use_csrf' => false,
// The URL to fetch the CSRF token from (if `use_csrf` is true).
'csrf_url' => '/sanctum/csrf-cookie',
],
// How is your API authenticated? This information will be used in the displayed docs, generated examples and response calls.
'auth' => [
// Set this to true if ANY endpoints in your API use authentication.
'enabled' => false,
// Set this to true if your API should be authenticated by default. If so, you must also set `enabled` (above) to true.
// You can then use @unauthenticated or @authenticated on individual endpoints to change their status from the default.
'default' => false,
// Where is the auth value meant to be sent in a request?
'in' => AuthIn::BEARER->value,
// The name of the auth parameter (e.g. token, key, apiKey) or header (e.g. Authorization, Api-Key).
'name' => 'key',
// The value of the parameter to be used by Scribe to authenticate response calls.
// This will NOT be included in the generated documentation. If empty, Scribe will use a random value.
'use_value' => env('SCRIBE_AUTH_KEY'),
// Placeholder your users will see for the auth parameter in the example requests.
// Set this to null if you want Scribe to use a random value as placeholder instead.
'placeholder' => '{YOUR_AUTH_KEY}',
// Any extra authentication-related info for your users. Markdown and HTML are supported.
'extra_info' => 'You can retrieve your token by visiting your dashboard and clicking <b>Generate API token</b>.',
],
// Example requests for each endpoint will be shown in each of these languages.
// Supported options are: bash, javascript, php, python
// To add a language of your own, see https://scribe.knuckles.wtf/laravel/advanced/example-requests
// Note: does not work for `external` docs types
'example_languages' => [
'bash',
'javascript',
],
// Generate a Postman collection (v2.1.0) in addition to HTML docs.
// For 'static' docs, the collection will be generated to public/docs/collection.json.
// For 'laravel' docs, it will be generated to storage/app/scribe/collection.json.
// Setting `laravel.add_routes` to true (above) will also add a route for the collection.
'postman' => [
'enabled' => true,
'overrides' => [
// 'info.version' => '2.0.0',
],
],
// Generate an OpenAPI spec in addition to docs webpage.
// For 'static' docs, the collection will be generated to public/docs/openapi.yaml.
// For 'laravel' docs, it will be generated to storage/app/scribe/openapi.yaml.
// Setting `laravel.add_routes` to true (above) will also add a route for the spec.
'openapi' => [
'enabled' => true,
// The OpenAPI spec version to generate. Supported versions: '3.0.3', '3.1.0'.
// OpenAPI 3.1 is more compatible with JSON Schema and is becoming the dominant version.
// See https://spec.openapis.org/oas/v3.1.0 for details on 3.1 changes.
'version' => '3.0.3',
'overrides' => [
// 'info.version' => '2.0.0',
],
// Additional generators to use when generating the OpenAPI spec.
// Should extend `Knuckles\Scribe\Writing\OpenApiSpecGenerators\OpenApiGenerator`.
'generators' => [],
],
'groups' => [
// Endpoints which don't have a @group will be placed in this default group.
'default' => 'Endpoints',
// By default, Scribe will sort groups alphabetically, and endpoints in the order their routes are defined.
// You can override this by listing the groups, subgroups and endpoints here in the order you want them.
// See https://scribe.knuckles.wtf/blog/laravel-v4#easier-sorting and https://scribe.knuckles.wtf/laravel/reference/config#order for details
// Note: does not work for `external` docs types
'order' => [],
],
// Custom logo path. This will be used as the value of the src attribute for the <img> tag,
// so make sure it points to an accessible URL or path. Set to false to not use a logo.
// For example, if your logo is in public/img:
// - 'logo' => '../img/logo.png' // for `static` type (output folder is public/docs)
// - 'logo' => 'img/logo.png' // for `laravel` type
'logo' => false,
// Customize the "Last updated" value displayed in the docs by specifying tokens and formats.
// Examples:
// - {date:F j Y} => March 28, 2022
// - {git:short} => Short hash of the last Git commit
// Available tokens are `{date:<format>}` and `{git:<format>}`.
// The format you pass to `date` will be passed to PHP's `date()` function.
// The format you pass to `git` can be either "short" or "long".
// Note: does not work for `external` docs types
'last_updated' => 'Last updated: {date:F j, Y}',
'examples' => [
// Set this to any number to generate the same example values for parameters on each run,
'faker_seed' => 1234,
// With API resources and transformers, Scribe tries to generate example models to use in your API responses.
// By default, Scribe will try the model's factory, and if that fails, try fetching the first from the database.
// You can reorder or remove strategies here.
'models_source' => ['factoryCreate', 'factoryMake', 'databaseFirst'],
],
// The strategies Scribe will use to extract information about your routes at each stage.
// Use configureStrategy() to specify settings for a strategy in the list.
// Use removeStrategies() to remove an included strategy.
'strategies' => [
'metadata' => [
...Defaults::METADATA_STRATEGIES,
],
'headers' => [
...Defaults::HEADERS_STRATEGIES,
Strategies\StaticData::withSettings(data: [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
]),
],
'urlParameters' => [
...Defaults::URL_PARAMETERS_STRATEGIES,
],
'queryParameters' => [
...Defaults::QUERY_PARAMETERS_STRATEGIES,
],
'bodyParameters' => [
...Defaults::BODY_PARAMETERS_STRATEGIES,
],
'responses' => configureStrategy(
Defaults::RESPONSES_STRATEGIES,
Strategies\Responses\ResponseCalls::withSettings(
only: ['GET *'],
// Recommended: disable debug mode in response calls to avoid error stack traces in responses
config: [
'app.debug' => false,
]
)
),
'responseFields' => [
...Defaults::RESPONSE_FIELDS_STRATEGIES,
],
],
// For response calls, API resource responses and transformer responses,
// Scribe will try to start database transactions, so no changes are persisted to your database.
// Tell Scribe which connections should be transacted here. If you only use one db connection, you can leave this as is.
'database_connections_to_transact' => [config('database.default')],
'fractal' => [
// If you are using a custom serializer with league/fractal, you can specify it here.
'serializer' => null,
],
];

View File

@@ -0,0 +1,77 @@
<?php
return [
'labels' => [
'search' => 'Search',
'base_url' => 'Base URL',
],
'auth' => [
'none' => 'This API is not authenticated.',
'instruction' => [
'query' => <<<'TEXT'
To authenticate requests, include a query parameter **`:parameterName`** in the request.
TEXT,
'body' => <<<'TEXT'
To authenticate requests, include a parameter **`:parameterName`** in the body of the request.
TEXT,
'query_or_body' => <<<'TEXT'
To authenticate requests, include a parameter **`:parameterName`** either in the query string or in the request body.
TEXT,
'bearer' => <<<'TEXT'
To authenticate requests, include an **`Authorization`** header with the value **`"Bearer :placeholder"`**.
TEXT,
'basic' => <<<'TEXT'
To authenticate requests, include an **`Authorization`** header in the form **`"Basic {credentials}"`**.
The value of `{credentials}` should be your username/id and your password, joined with a colon (:),
and then base64-encoded.
TEXT,
'header' => <<<'TEXT'
To authenticate requests, include a **`:parameterName`** header with the value **`":placeholder"`**.
TEXT,
],
'details' => <<<'TEXT'
All authenticated endpoints are marked with a `requires authentication` badge in the documentation below.
TEXT,
],
'headings' => [
'introduction' => 'Introduction',
'auth' => 'Authenticating requests',
],
'endpoint' => [
'request' => 'Request',
'headers' => 'Headers',
'url_parameters' => 'URL Parameters',
'body_parameters' => 'Body Parameters',
'query_parameters' => 'Query Parameters',
'response' => 'Response',
'response_fields' => 'Response Fields',
'example_request' => 'Example request',
'example_response' => 'Example response',
'responses' => [
'binary' => 'Binary data',
'empty' => 'Empty response',
],
],
'try_it_out' => [
'open' => 'Try it out ⚡',
'cancel' => 'Cancel 🛑',
'send' => 'Send Request 💥',
'loading' => '⏱ Sending...',
'received_response' => 'Received response',
'request_failed' => 'Request failed with error',
'error_help' => <<<'TEXT'
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
TEXT,
],
'links' => [
'postman' => 'View Postman collection',
'openapi' => 'View OpenAPI spec',
],
];

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

View File

@@ -0,0 +1,393 @@
/* Copied from https://github.com/slatedocs/slate/blob/c4b4c0b8f83e891ca9fab6bbe9a1a88d5fe41292/stylesheets/print.css and unminified */
/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
html {
font-family: sans-serif;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%
}
body {
margin: 0
}
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
menu,
nav,
section,
summary {
display: block
}
audio,
canvas,
progress,
video {
display: inline-block;
vertical-align: baseline
}
audio:not([controls]) {
display: none;
height: 0
}
[hidden],
template {
display: none
}
a {
background-color: transparent
}
a:active,
a:hover {
outline: 0
}
abbr[title] {
border-bottom: 1px dotted
}
b,
strong {
font-weight: bold
}
dfn {
font-style: italic
}
h1 {
font-size: 2em;
margin: 0.67em 0
}
mark {
background: #ff0;
color: #000
}
small {
font-size: 80%
}
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline
}
sup {
top: -0.5em
}
sub {
bottom: -0.25em
}
img {
border: 0
}
svg:not(:root) {
overflow: hidden
}
figure {
margin: 1em 40px
}
hr {
box-sizing: content-box;
height: 0
}
pre {
overflow: auto
}
code,
kbd,
pre,
samp {
font-family: monospace, monospace;
font-size: 1em
}
button,
input,
optgroup,
select,
textarea {
color: inherit;
font: inherit;
margin: 0
}
button {
overflow: visible
}
button,
select {
text-transform: none
}
button,
html input[type="button"],
input[type="reset"],
input[type="submit"] {
-webkit-appearance: button;
cursor: pointer
}
button[disabled],
html input[disabled] {
cursor: default
}
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0
}
input {
line-height: normal
}
input[type="checkbox"],
input[type="radio"] {
box-sizing: border-box;
padding: 0
}
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
height: auto
}
input[type="search"] {
-webkit-appearance: textfield;
box-sizing: content-box
}
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none
}
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em
}
legend {
border: 0;
padding: 0
}
textarea {
overflow: auto
}
optgroup {
font-weight: bold
}
table {
border-collapse: collapse;
border-spacing: 0
}
td,
th {
padding: 0
}
.content h1,
.content h2,
.content h3,
.content h4,
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
font-size: 14px
}
.content h1,
.content h2,
.content h3,
.content h4 {
font-weight: bold
}
.content pre,
.content code {
font-family: Consolas, Menlo, Monaco, "Lucida Console", "Liberation Mono", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Courier New", monospace, serif;
font-size: 12px;
line-height: 1.5
}
.content pre,
.content code {
word-break: break-all;
-webkit-hyphens: auto;
-ms-hyphens: auto;
hyphens: auto
}
@font-face {
font-family: 'slate';
src: url(../fonts/slate.eot?-syv14m);
src: url(../fonts/slate.eot?#iefix-syv14m) format("embedded-opentype"), url(../fonts/slate.woff2?-syv14m) format("woff2"), url(../fonts/slate.woff?-syv14m) format("woff"), url(../fonts/slate.ttf?-syv14m) format("truetype"), url(../fonts/slate.svg?-syv14m#slate) format("svg");
font-weight: normal;
font-style: normal
}
.content aside.warning:before,
.content aside.notice:before,
.content aside.success:before {
font-family: 'slate';
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1
}
.content aside.warning:before {
content: "\e600"
}
.content aside.notice:before {
content: "\e602"
}
.content aside.success:before {
content: "\e606"
}
.tocify,
.toc-footer,
.lang-selector,
.search,
#nav-button {
display: none
}
.tocify-wrapper>img {
margin: 0 auto;
display: block
}
.content {
font-size: 12px
}
.content pre,
.content code {
border: 1px solid #999;
border-radius: 5px;
font-size: 0.8em
}
.content pre code {
border: 0
}
.content pre {
padding: 1.3em
}
.content code {
padding: 0.2em
}
.content table {
border: 1px solid #999
}
.content table tr {
border-bottom: 1px solid #999
}
.content table td,
.content table th {
padding: 0.7em
}
.content p {
line-height: 1.5
}
.content a {
text-decoration: none;
color: #000
}
.content h1 {
font-size: 2.5em;
padding-top: 0.5em;
padding-bottom: 0.5em;
margin-top: 1em;
margin-bottom: 21px;
border: 2px solid #ccc;
border-width: 2px 0;
text-align: center
}
.content h2 {
font-size: 1.8em;
margin-top: 2em;
border-top: 2px solid #ccc;
padding-top: 0.8em
}
.content h1+h2,
.content h1+div+h2 {
border-top: none;
padding-top: 0;
margin-top: 0
}
.content h3,
.content h4 {
font-size: 0.8em;
margin-top: 1.5em;
margin-bottom: 0.8em;
text-transform: uppercase
}
.content h5,
.content h6 {
text-transform: uppercase
}
.content aside {
padding: 1em;
border: 1px solid #ccc;
border-radius: 5px;
margin-top: 1.5em;
margin-bottom: 1.5em;
line-height: 1.6
}
.content aside:before {
vertical-align: middle;
padding-right: 0.5em;
font-size: 14px
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,53 @@
# To include an endpoint that isn't a part of your Laravel app (or belongs to a vendor package),
# you can define it in a custom.*.yaml file, like this one.
# Each custom file should contain an array of endpoints. Here's an example:
# See https://scribe.knuckles.wtf/laravel/documenting/custom-endpoints#extra-sorting-groups-in-custom-endpoint-files for more options
#- httpMethods:
# - POST
# uri: api/doSomething/{param}
# metadata:
# groupName: The group the endpoint belongs to. Can be a new group or an existing group.
# groupDescription: A description for the group. You don't need to set this for every endpoint; once is enough.
# subgroup: You can add a subgroup, too.
# title: Do something
# description: 'This endpoint allows you to do something.'
# authenticated: false
# headers:
# Content-Type: application/json
# Accept: application/json
# urlParameters:
# param:
# name: param
# description: A URL param for no reason.
# required: true
# example: 2
# type: integer
# queryParameters:
# speed:
# name: speed
# description: How fast the thing should be done. Can be `slow` or `fast`.
# required: false
# example: fast
# type: string
# bodyParameters:
# something:
# name: something
# description: The things we should do.
# required: true
# example:
# - string 1
# - string 2
# type: 'string[]'
# responses:
# - status: 200
# description: 'When the thing was done smoothly.'
# content: # Your response content can be an object, an array, a string or empty.
# {
# "hey": "ho ho ho"
# }
# responseFields:
# hey:
# name: hey
# description: Who knows?
# type: string # This is optional

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 B

View File

@@ -0,0 +1,149 @@
document.addEventListener('DOMContentLoaded', function() {
const updateHash = function (id) {
window.location.hash = `#${id}`;
};
const navButton = document.getElementById('nav-button');
const menuWrapper = document.querySelector('.tocify-wrapper');
function toggleSidebar(event) {
event.preventDefault();
if (menuWrapper) {
menuWrapper.classList.toggle('open');
navButton.classList.toggle('open');
}
}
function closeSidebar() {
if (menuWrapper) {
menuWrapper.classList.remove('open');
navButton.classList.remove('open');
}
}
navButton.addEventListener('click', toggleSidebar);
window.hljs.highlightAll();
const wrapper = document.getElementById('toc');
// https://jets.js.org/
window.jets = new window.Jets({
// *OR - Selects elements whose values contains at least one part of search substring
searchSelector: '*OR',
searchTag: '#input-search',
contentTag: '#toc li',
didSearch: function(term) {
wrapper.classList.toggle('jets-searching', String(term).length > 0)
},
// map these accent keys to plain values
diacriticsMap: {
a: 'ÀÁÂÃÄÅàáâãäåĀāąĄ',
c: 'ÇçćĆčČ',
d: 'đĐďĎ',
e: 'ÈÉÊËèéêëěĚĒēęĘ',
i: 'ÌÍÎÏìíîïĪī',
l: 'łŁ',
n: 'ÑñňŇńŃ',
o: 'ÒÓÔÕÕÖØòóôõöøŌō',
r: 'řŘ',
s: 'ŠšśŚ',
t: 'ťŤ',
u: 'ÙÚÛÜùúûüůŮŪū',
y: 'ŸÿýÝ',
z: 'ŽžżŻźŹ'
}
});
function hashChange() {
const currentItems = document.querySelectorAll('.tocify-subheader.visible, .tocify-item.tocify-focus');
Array.from(currentItems).forEach((elem) => {
elem.classList.remove('visible', 'tocify-focus');
});
const currentTag = document.querySelector(`a[href="${window.location.hash}"]`);
if (currentTag) {
const parent = currentTag.closest('.tocify-subheader');
if (parent) {
parent.classList.add('visible');
}
const siblings = currentTag.closest('.tocify-header');
if (siblings) {
Array.from(siblings.querySelectorAll('.tocify-subheader')).forEach((elem) => {
elem.classList.add('visible');
});
}
currentTag.parentElement.classList.add('tocify-focus');
// wait for dom changes to be done
setTimeout(() => {
currentTag.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'center' });
// only close the sidebar on level-2 events
if (currentTag.parentElement.classList.contains('level-2')) {
closeSidebar();
}
}, 1500);
}
}
let languages = JSON.parse(document.body.getAttribute('data-languages'));
// Support a key => value object where the key is the name, or an array of strings where the value is the name
if (!Array.isArray(languages)) {
languages = Object.values(languages);
}
// if there is no language use the first one
const currentLanguage = window.localStorage.getItem('language') || languages[0];
const languageStyle = document.getElementById('language-style');
const langSelector = document.querySelectorAll('.lang-selector button.lang-button');
function setActiveLanguage(newLanguage) {
window.localStorage.setItem('language', newLanguage);
if (!languageStyle) {
return;
}
const newStyle = languages.map((language) => {
return language === newLanguage
// the current one should be visible
? `body .content .${language}-example pre { display: block; }`
// the inactive one should be hidden
: `body .content .${language}-example pre { display: none; }`;
}).join(`\n`);
Array.from(langSelector).forEach((elem) => {
elem.classList.toggle('active', elem.getAttribute('data-language-name') === newLanguage);
});
const activeHash = window.location.hash.slice(1);
languageStyle.innerHTML = newStyle;
setTimeout(() => {
updateHash(activeHash);
}, 200);
}
setActiveLanguage(currentLanguage);
Array.from(langSelector).forEach((elem) => {
elem.addEventListener('click', () => {
const newLanguage = elem.getAttribute('data-language-name');
setActiveLanguage(newLanguage);
});
});
window.addEventListener('hashchange', hashChange, false);
const divs = document.querySelectorAll('.content h1[id], .content h2[id]');
document.addEventListener('scroll', () => {
divs.forEach(item => {
const rect = item.getBoundingClientRect();
if (rect.top > 0 && rect.top < 150) {
const location = window.location.toString().split('#')[0];
history.replaceState(null, null, location + '#' + item.id);
hashChange();
}
});
});
hashChange();
});

View File

@@ -0,0 +1,289 @@
window.abortControllers = {};
function cacheAuthValue() {
// Whenever the auth header is set for one endpoint, cache it for the others
window.lastAuthValue = '';
let authInputs = document.querySelectorAll(`.auth-value`)
authInputs.forEach(el => {
el.addEventListener('input', (event) => {
window.lastAuthValue = event.target.value;
authInputs.forEach(otherInput => {
if (otherInput === el) return;
// Don't block the main thread
setTimeout(() => {
otherInput.value = window.lastAuthValue;
}, 0);
});
});
});
}
window.addEventListener('DOMContentLoaded', cacheAuthValue);
function getCookie(name) {
if (!document.cookie) {
return null;
}
const cookies = document.cookie.split(';')
.map(c => c.trim())
.filter(c => c.startsWith(name + '='));
if (cookies.length === 0) {
return null;
}
return decodeURIComponent(cookies[0].split('=')[1]);
}
function tryItOut(endpointId) {
document.querySelector(`#btn-tryout-${endpointId}`).hidden = true;
document.querySelector(`#btn-canceltryout-${endpointId}`).hidden = false;
const executeBtn = document.querySelector(`#btn-executetryout-${endpointId}`).hidden = false;
executeBtn.disabled = false;
// Show all input fields
document.querySelectorAll(`input[data-endpoint=${endpointId}],label[data-endpoint=${endpointId}]`)
.forEach(el => el.style.display = 'block');
if (document.querySelector(`#form-${endpointId}`).dataset.authed === "1") {
const authElement = document.querySelector(`#auth-${endpointId}`);
authElement && (authElement.hidden = false);
}
// Expand all nested fields
document.querySelectorAll(`#form-${endpointId} details`)
.forEach(el => el.open = true);
}
function cancelTryOut(endpointId) {
if (window.abortControllers[endpointId]) {
window.abortControllers[endpointId].abort();
delete window.abortControllers[endpointId];
}
document.querySelector(`#btn-tryout-${endpointId}`).hidden = false;
const executeBtn = document.querySelector(`#btn-executetryout-${endpointId}`);
executeBtn.hidden = true;
executeBtn.textContent = executeBtn.dataset.initialText;
document.querySelector(`#btn-canceltryout-${endpointId}`).hidden = true;
// Hide inputs
document.querySelectorAll(`input[data-endpoint=${endpointId}],label[data-endpoint=${endpointId}]`)
.forEach(el => el.style.display = 'none');
document.querySelectorAll(`#form-${endpointId} details`)
.forEach(el => el.open = false);
const authElement = document.querySelector(`#auth-${endpointId}`);
authElement && (authElement.hidden = true);
document.querySelector('#execution-results-' + endpointId).hidden = true;
document.querySelector('#execution-error-' + endpointId).hidden = true;
// Revert to sample code blocks
document.querySelector('#example-requests-' + endpointId).hidden = false;
document.querySelector('#example-responses-' + endpointId).hidden = false;
}
function makeAPICall(method, path, body = {}, query = {}, headers = {}, endpointId = null) {
console.log({endpointId, path, body, query, headers});
if (!(body instanceof FormData) && typeof body !== "string") {
body = JSON.stringify(body)
}
const url = new URL(window.tryItOutBaseUrl + '/' + path.replace(/^\//, ''));
// We need this function because if you try to set an array or object directly to a URLSearchParams object,
// you'll get [object Object] or the array.toString()
function addItemToSearchParamsObject(key, value, searchParams) {
if (Array.isArray(value)) {
value.forEach((v, i) => {
// Append {filters: [first, second]} as filters[0]=first&filters[1]second
addItemToSearchParamsObject(key + '[' + i + ']', v, searchParams);
})
} else if (typeof value === 'object' && value !== null) {
Object.keys(value).forEach((i) => {
// Append {filters: {name: first}} as filters[name]=first
addItemToSearchParamsObject(key + '[' + i + ']', value[i], searchParams);
});
} else {
searchParams.append(key, value);
}
}
Object.keys(query)
.forEach(key => addItemToSearchParamsObject(key, query[key], url.searchParams));
window.abortControllers[endpointId] = new AbortController();
return fetch(url, {
method,
headers,
body: method === 'GET' ? undefined : body,
signal: window.abortControllers[endpointId].signal,
referrer: window.tryItOutBaseUrl,
mode: 'cors',
credentials: 'same-origin',
})
.then(response => Promise.all([response.status, response.statusText, response.text(), response.headers]));
}
function hideCodeSamples(endpointId) {
document.querySelector('#example-requests-' + endpointId).hidden = true;
document.querySelector('#example-responses-' + endpointId).hidden = true;
}
function handleResponse(endpointId, response, status, headers) {
hideCodeSamples(endpointId);
// Hide error views
document.querySelector('#execution-error-' + endpointId).hidden = true;
const responseContentEl = document.querySelector('#execution-response-content-' + endpointId);
// Check if the response contains Laravel's dd() default dump output
const isLaravelDump = response.includes('Sfdump');
// If it's a Laravel dd() dump, use innerHTML to render it safely
if (isLaravelDump) {
responseContentEl.innerHTML = response === '' ? responseContentEl.dataset.emptyResponseText : response;
} else {
// Otherwise, stick to textContent for regular responses
responseContentEl.textContent = response === '' ? responseContentEl.dataset.emptyResponseText : response;
}
// Prettify it if it's JSON
let isJson = false;
try {
const jsonParsed = JSON.parse(response);
if (jsonParsed !== null) {
isJson = true;
response = JSON.stringify(jsonParsed, null, 4);
responseContentEl.textContent = response;
}
} catch (e) {
}
isJson && window.hljs.highlightElement(responseContentEl);
const statusEl = document.querySelector('#execution-response-status-' + endpointId);
statusEl.textContent = ` (${status})`;
document.querySelector('#execution-results-' + endpointId).hidden = false;
statusEl.scrollIntoView({behavior: "smooth", block: "center"});
}
function handleError(endpointId, err) {
hideCodeSamples(endpointId);
// Hide response views
document.querySelector('#execution-results-' + endpointId).hidden = true;
// Show error views
let errorMessage = err.message || err;
const $errorMessageEl = document.querySelector('#execution-error-message-' + endpointId);
$errorMessageEl.textContent = errorMessage + $errorMessageEl.textContent;
const errorEl = document.querySelector('#execution-error-' + endpointId);
errorEl.hidden = false;
errorEl.scrollIntoView({behavior: "smooth", block: "center"});
}
async function executeTryOut(endpointId, form) {
const executeBtn = document.querySelector(`#btn-executetryout-${endpointId}`);
executeBtn.textContent = executeBtn.dataset.loadingText;
executeBtn.disabled = true;
executeBtn.scrollIntoView({behavior: "smooth", block: "center"});
let body;
let setter;
if (form.dataset.hasfiles === "1") {
body = new FormData();
setter = (name, value) => body.append(name, value);
} else if (form.dataset.isarraybody === "1") {
body = [];
setter = (name, value) => _.set(body, name, value);
} else {
body = {};
setter = (name, value) => _.set(body, name, value);
}
const bodyParameters = form.querySelectorAll('input[data-component=body]');
bodyParameters.forEach(el => {
let value = el.value;
if (el.type === 'number' && typeof value === 'string') {
value = parseFloat(value);
}
if (el.type === 'file' && el.files[0]) {
setter(el.name, el.files[0]);
return;
}
if (el.type !== 'radio') {
if (value === "" && el.required === false) {
// Don't include empty optional values in the request
return;
}
setter(el.name, value);
return;
}
if (el.checked) {
value = (value === 'false') ? false : true;
setter(el.name, value);
}
});
const query = {};
const queryParameters = form.querySelectorAll('input[data-component=query]');
queryParameters.forEach(el => {
if (el.type !== 'radio' || (el.type === 'radio' && el.checked)) {
if (el.value === '') {
// Don't include empty values in the request
return;
}
_.set(query, el.name, el.value);
}
});
let path = form.dataset.path;
const urlParameters = form.querySelectorAll('input[data-component=url]');
urlParameters.forEach(el => (path = path.replace(new RegExp(`\\{${el.name}\\??}`), el.value)));
const headers = Object.fromEntries(Array.from(form.querySelectorAll('input[data-component=header]'))
.map(el => [el.name, el.value]));
// When using FormData, the browser sets the correct content-type + boundary
let method = form.dataset.method;
if (body instanceof FormData) {
delete headers['Content-Type'];
// When using FormData with PUT or PATCH, use method spoofing so PHP can access the post body
if (['PUT', 'PATCH'].includes(form.dataset.method)) {
method = 'POST';
setter('_method', form.dataset.method);
}
}
let preflightPromise = Promise.resolve();
if (window.useCsrf && window.csrfUrl) {
preflightPromise = makeAPICall('GET', window.csrfUrl).then(() => {
headers['X-XSRF-TOKEN'] = getCookie('XSRF-TOKEN');
});
}
return preflightPromise.then(() => makeAPICall(method, path, body, query, headers, endpointId))
.then(([responseStatus, statusText, responseContent, responseHeaders]) => {
handleResponse(endpointId, responseContent, responseStatus, responseHeaders)
})
.catch(err => {
if (err.name === "AbortError") {
console.log("Request cancelled");
return;
}
console.log("Error while making request: ", err);
handleError(endpointId, err);
})
.finally(() => {
executeBtn.disabled = false;
executeBtn.textContent = executeBtn.dataset.initialText;
});
}

View File

@@ -0,0 +1,3 @@
@if($authenticated)@component('scribe::components.badges.base', ['colour' => "darkred", 'text' => 'requires authentication'])
@endcomponent
@endif

View File

@@ -0,0 +1 @@
<small class="badge badge-{{ $colour }}">{{ $text }}</small>

View File

@@ -0,0 +1,5 @@
@if($deprecated !== false)
@php($text = $deprecated === true ? 'deprecated' : "deprecated:$deprecated")
@component('scribe::components.badges.base', ['colour' => 'darkgoldenrod', 'text' => $text])
@endcomponent
@endif

View File

@@ -0,0 +1,5 @@
@component('scribe::components.badges.base', [
'colour' => \Knuckles\Scribe\Tools\WritingUtils::$httpMethodToCssColour[$method],
'text' => $method,
])
@endcomponent

View File

@@ -0,0 +1,76 @@
@php
$html ??= []; $class = $html['class'] ?? null;
@endphp
<b style="line-height: 2;"><code>{{ $name }}</code></b>&nbsp;&nbsp;
@if($type)<small>{{ $type }}</small>@endif&nbsp;
@if($isInput && !$required)<i>optional</i>@endif &nbsp;
@if($isInput && $deprecated)<i>deprecated</i>@endif &nbsp;
@if($isInput && empty($hasChildren))
@php
$isList = Str::endsWith($type, '[]');
$fullName = str_replace('[]', '.0', $fullName ?? $name);
$baseType = $isList ? substr($type, 0, -2) : $type;
// Ignore the first '[]': the frontend will take care of it
while (\Str::endsWith($baseType, '[]')) {
$fullName .= '.0';
$baseType = substr($baseType, 0, -2);
}
// When the body is an array, the item names will be ".0.thing"
$fullName = ltrim($fullName, '.');
$inputType = match($baseType) {
'number', 'integer' => 'number',
'file' => 'file',
default => 'text',
};
@endphp
@if($type === 'boolean')
<label data-endpoint="{{ $endpointId }}" style="display: none">
<input type="radio" name="{{ $fullName }}"
value="{{$component === 'body' ? 'true' : 1}}"
data-endpoint="{{ $endpointId }}"
data-component="{{ $component }}" @if($class)class="{{ $class }}"@endif
>
<code>true</code>
</label>
<label data-endpoint="{{ $endpointId }}" style="display: none">
<input type="radio" name="{{ $fullName }}"
value="{{$component === 'body' ? 'false' : 0}}"
data-endpoint="{{ $endpointId }}"
data-component="{{ $component }}" @if($class)class="{{ $class }}"@endif
>
<code>false</code>
</label>
@elseif($isList)
<input type="{{ $inputType }}" style="display: none"
@if($inputType === 'number')step="any"@endif
name="{{ $fullName."[0]" }}" @if($class)class="{{ $class }}"@endif
data-endpoint="{{ $endpointId }}"
data-component="{{ $component }}">
<input type="{{ $inputType }}" style="display: none"
name="{{ $fullName."[1]" }}" @if($class)class="{{ $class }}"@endif
data-endpoint="{{ $endpointId }}"
data-component="{{ $component }}">
@else
<input type="{{ $inputType }}" style="display: none"
@if($inputType === 'number')step="any"@endif
name="{{ $fullName }}" @if($class)class="{{ $class }}"@endif
data-endpoint="{{ $endpointId }}"
value="{!! (isset($example) && (is_string($example) || is_numeric($example))) ? $example : '' !!}"
data-component="{{ $component }}">
@endif
@endif
<br>
@php
if($example !== null && $example !== '' && !is_array($example)) {
$exampleAsString = $example;
if (is_bool($example)) {
$exampleAsString = $example ? "true" : "false";
}
$description .= " Example: `$exampleAsString`";
}
@endphp
{!! Parsedown::instance()->text(trim($description)) !!}
@if(!empty($enumValues))
Must be one of:
<ul style="list-style-type: square;">{!! implode(" ", array_map(fn($val) => "<li><code>$val</code></li>", $enumValues)) !!}</ul>
@endif

View File

@@ -0,0 +1,105 @@
@php
$isInput ??= true;
$level ??= 0;
@endphp
@foreach($fields as $name => $field)
@if($name === '[]')
@php
$description = "The request body is an array (<code>{$field['type']}</code>`)";
$description .= !empty($field['description']) ? ", representing ".lcfirst($field['description'])."." : '.';
if(count($field['__fields'])) $description .= " Each item has the following properties:";
@endphp
{!! Parsedown::instance()->text($description) !!}
@foreach($field['__fields'] as $subfieldName => $subfield)
@if(!empty($subfield['__fields']))
<x-scribe::nested-fields
:fields="[$subfieldName => $subfield]" :endpointId="$endpointId" :isInput="$isInput" :level="$level + 2"
/>
@else
<div style="margin-left: {{ ($level + 2) * 14 }}px; clear: unset;">
@component('scribe::components.field-details', [
'name' => $subfieldName,
'fullName' => $subfield['name'],
'type' => $subfield['type'] ?? 'string',
'required' => $subfield['required'] ?? false,
'deprecated' => $subfield['deprecated'] ?? false,
'description' => $subfield['description'] ?? '',
'example' => $subfield['example'] ?? '',
'enumValues' => $subfield['enumValues'] ?? null,
'endpointId' => $endpointId,
'hasChildren' => false,
'component' => 'body',
'isInput' => $isInput,
])
@endcomponent
</div>
@endif
@endforeach
@elseif(!empty($field['__fields']))
<div style="@if($level) margin-left: {{ $level * 14 }}px;@else padding-left: 28px; @endif clear: unset;">
<details>
<summary style="padding-bottom: 10px;">
@component('scribe::components.field-details', [
'name' => $name,
'fullName' => $field['name'],
'type' => $field['type'] ?? 'string',
'required' => $field['required'] ?? false,
'deprecated' => $field['deprecated'] ?? false,
'description' => $field['description'] ?? '',
'example' => $field['example'] ?? '',
'enumValues' => $field['enumValues'] ?? null,
'endpointId' => $endpointId,
'hasChildren' => true,
'component' => 'body',
'isInput' => $isInput,
])
@endcomponent
</summary>
@foreach($field['__fields'] as $subfieldName => $subfield)
@if(!empty($subfield['__fields']))
<x-scribe::nested-fields
:fields="[$subfieldName => $subfield]" :endpointId="$endpointId" :isInput="$isInput" :level="$level + 1"
/>
@else
<div style="margin-left: {{ ($level + 1) * 14 }}px; clear: unset;">
@component('scribe::components.field-details', [
'name' => $subfieldName,
'fullName' => $subfield['name'],
'type' => $subfield['type'] ?? 'string',
'required' => $subfield['required'] ?? false,
'deprecated' => $subfield['deprecated'] ?? false,
'description' => $subfield['description'] ?? '',
'example' => $subfield['example'] ?? '',
'enumValues' => $subfield['enumValues'] ?? null,
'endpointId' => $endpointId,
'hasChildren' => false,
'component' => 'body',
'isInput' => $isInput,
])
@endcomponent
</div>
@endif
@endforeach
</details>
</div>
@else
<div style="@if($level) margin-left: {{ ($level + 1) * 14 }}px;@else padding-left: 28px; @endif clear: unset;">
@component('scribe::components.field-details', [
'name' => $name,
'fullName' => $field['name'],
'type' => $field['type'] ?? 'string',
'required' => $field['required'] ?? false,
'deprecated' => $field['deprecated'] ?? false,
'description' => $field['description'] ?? '',
'example' => $field['example'] ?? '',
'enumValues' => $field['enumValues'] ?? null,
'endpointId' => $endpointId,
'hasChildren' => false,
'component' => 'body',
'isInput' => $isInput,
])
@endcomponent
</div>
@endif
@endforeach

View File

@@ -0,0 +1,34 @@
<!-- See https://github.com/stoplightio/elements/blob/main/docs/getting-started/elements/elements-options.md for config -->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>{!! $metadata['title'] !!}</title>
<!-- Embed elements Elements via Web Component -->
<script src="https://unpkg.com/@stoplight/elements/web-components.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/@stoplight/elements/styles.min.css">
<style>
body {
height: 100vh;
}
</style>
</head>
<body>
<elements-api
@foreach($htmlAttributes as $attribute => $value)
{{-- Attributes specified first override later ones --}}
{!! $attribute !!}="{!! $value !!}"
@endforeach
apiDescriptionUrl="{!! $metadata['openapi_spec_url'] !!}"
router="hash"
layout="sidebar"
hideTryIt="{!! ($tryItOut['enabled'] ?? true) ? '' : 'true'!!}"
@if(!empty($metadata['logo']))
logo="{!! $metadata['logo'] !!}"
@endif
/>
</body>
</html>

View File

@@ -0,0 +1,23 @@
<!-- See https://rapidocweb.com/api.html for options -->
<!doctype html> <!-- Important: must specify -->
<html>
<head>
<meta charset="utf-8"> <!-- Important: rapi-doc uses utf8 characters -->
<script type="module" src="https://unpkg.com/rapidoc/dist/rapidoc-min.js"></script>
</head>
<body>
<rapi-doc
@foreach($htmlAttributes as $attribute => $value)
{{-- Attributes specified first override later ones --}}
{!! $attribute !!}="{!! $value !!}"
@endforeach
spec-url="{!! $metadata['openapi_spec_url'] !!}"
render-style="read"
allow-try="{!! ($tryItOut['enabled'] ?? true) ? 'true' : 'false'!!}"
>
@if($metadata['logo'])
<img slot="logo" src="{!! $metadata['logo'] !!}"/>
@endif
</rapi-doc>
</body>
</html>

View File

@@ -0,0 +1,27 @@
<!doctype html>
<html>
<head>
<title>{!! $metadata['title'] !!}</title>
<meta charset="utf-8"/>
<meta
name="viewport"
content="width=device-width, initial-scale=1"/>
<style>
body {
margin: 0;
}
</style>
</head>
<body>
<script
id="api-reference"
@foreach($htmlAttributes as $attribute => $value)
{{-- Attributes specified first override later ones --}}
{!! $attribute !!}="{!! $value !!}"
@endforeach
data-url="{!! $metadata['openapi_spec_url'] !!}">
</script>
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
</body>
</html>

View File

@@ -0,0 +1,12 @@
@php
use Knuckles\Scribe\Tools\Utils as u;
@endphp
# {{ u::trans("scribe::headings.auth") }}
@if(!$isAuthed)
{!! u::trans("scribe::auth.none") !!}
@else
{!! $authDescription !!}
{!! $extraAuthInfo !!}
@endif

View File

@@ -0,0 +1,13 @@
@php
use Knuckles\Scribe\Tools\Utils as u;
@endphp
# {{ u::trans("scribe::headings.introduction") }}
{!! $description !!}
<aside>
<strong>{{ u::trans("scribe::labels.base_url") }}</strong>: <code>{!! $baseUrl !!}</code>
</aside>
{!! $introText !!}

View File

@@ -0,0 +1,34 @@
@php
use Knuckles\Scribe\Tools\WritingUtils as u;
/** @var Knuckles\Camel\Output\OutputEndpointData $endpoint */
@endphp
```bash
curl --request {{$endpoint->httpMethods[0]}} \
{{$endpoint->httpMethods[0] == 'GET' ? '--get ' : ''}}"{!! rtrim($baseUrl, '/') !!}/{{ ltrim($endpoint->boundUri, '/') }}@if(count($endpoint->cleanQueryParameters))?{!! u::printQueryParamsAsString($endpoint->cleanQueryParameters) !!}@endif"@if(count($endpoint->headers)) \
@foreach($endpoint->headers as $header => $value)
--header "{{$header}}: {{ addslashes($value) }}"@if(! ($loop->last) || ($loop->last && count($endpoint->bodyParameters))) \
@endif
@endforeach
@endif
@if($endpoint->hasFiles() || (isset($endpoint->headers['Content-Type']) && $endpoint->headers['Content-Type'] == 'multipart/form-data' && count($endpoint->cleanBodyParameters)))
@foreach($endpoint->cleanBodyParameters as $parameter => $value)
@foreach(u::getParameterNamesAndValuesForFormData($parameter, $value) as $key => $actualValue)
--form "{!! "$key=".$actualValue !!}"@if(!($loop->parent->last) || count($endpoint->fileParameters))\
@endif
@endforeach
@endforeach
@foreach($endpoint->fileParameters as $parameter => $value)
@foreach(u::getParameterNamesAndValuesForFormData($parameter, $value) as $key => $file)
--form "{!! "$key=@".$file->path() !!}" @if(!($loop->parent->last))\
@endif
@endforeach
@endforeach
@elseif(count($endpoint->cleanBodyParameters))
@if ($endpoint->headers['Content-Type'] == 'application/x-www-form-urlencoded')
--data "{!! http_build_query($endpoint->cleanBodyParameters, '', '&') !!}"
@else
--data "{!! addslashes(json_encode($endpoint->cleanBodyParameters, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)) !!}"
@endif
@endif
```

View File

@@ -0,0 +1,62 @@
@php
use Knuckles\Scribe\Tools\WritingUtils as u;
/** @var Knuckles\Camel\Output\OutputEndpointData $endpoint */
@endphp
```javascript
const url = new URL(
"{!! rtrim($baseUrl, '/') !!}/{{ ltrim($endpoint->boundUri, '/') }}"
);
@if(count($endpoint->cleanQueryParameters))
const params = {!! u::printQueryParamsAsKeyValue($endpoint->cleanQueryParameters, "\"", ":", 4, "{}") !!};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
@endif
@if(!empty($endpoint->headers))
const headers = {
@foreach($endpoint->headers as $header => $value)
"{{$header}}": "{{$value}}",
@endforeach
@empty($endpoint->headers['Accept'])
"Accept": "application/json",
@endempty
};
@endif
@if($endpoint->hasFiles() || (isset($endpoint->headers['Content-Type']) && $endpoint->headers['Content-Type'] == 'multipart/form-data' && count($endpoint->cleanBodyParameters)))
const body = new FormData();
@foreach($endpoint->cleanBodyParameters as $parameter => $value)
@foreach( u::getParameterNamesAndValuesForFormData($parameter, $value) as $key => $actualValue)
body.append('{!! $key !!}', '{!! $actualValue !!}');
@endforeach
@endforeach
@foreach($endpoint->fileParameters as $parameter => $value)
@foreach( u::getParameterNamesAndValuesForFormData($parameter, $value) as $key => $file)
body.append('{!! $key !!}', document.querySelector('input[name="{!! $key !!}"]').files[0]);
@endforeach
@endforeach
@elseif(count($endpoint->cleanBodyParameters))
@if ($endpoint->headers['Content-Type'] == 'application/x-www-form-urlencoded')
let body = "{!! http_build_query($endpoint->cleanBodyParameters, '', '&') !!}";
@else
let body = {!! json_encode($endpoint->cleanBodyParameters, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) !!};
@endif
@endif
fetch(url, {
method: "{{$endpoint->httpMethods[0]}}",
@if(count($endpoint->headers))
headers,
@endif
@if($endpoint->hasFiles() || (isset($endpoint->headers['Content-Type']) && $endpoint->headers['Content-Type'] == 'multipart/form-data' && count($endpoint->cleanBodyParameters)))
body,
@elseif(count($endpoint->cleanBodyParameters))
@if ($endpoint->headers['Content-Type'] == 'application/x-www-form-urlencoded')
body,
@else
body: JSON.stringify(body),
@endif
@endif
}).then(response => response.json());
```

View File

@@ -0,0 +1,51 @@
@php
use Knuckles\Scribe\Tools\WritingUtils as u;
/** @var Knuckles\Camel\Output\OutputEndpointData $endpoint */
@endphp
```php
$client = new \GuzzleHttp\Client();
$url = '{!! rtrim($baseUrl, '/') . '/' . ltrim($endpoint->boundUri, '/') !!}';
@if($endpoint->hasHeadersOrQueryOrBodyParams())
$response = $client->{{ strtolower($endpoint->httpMethods[0]) }}(
$url,
[
@if(!empty($endpoint->headers))
'headers' => {!! u::printPhpValue($endpoint->headers, 8) !!},
@endif
@if(!empty($endpoint->cleanQueryParameters))
'query' => {!! u::printQueryParamsAsKeyValue($endpoint->cleanQueryParameters, "'", " =>", 12, "[]", 8) !!},
@endif
@if($endpoint->hasFiles() || (isset($endpoint->headers['Content-Type']) && $endpoint->headers['Content-Type'] == 'multipart/form-data' && !empty($endpoint->cleanBodyParameters)))
'multipart' => [
@foreach($endpoint->cleanBodyParameters as $parameter => $value)
@foreach(u::getParameterNamesAndValuesForFormData($parameter, $value) as $key => $actualValue)
[
'name' => '{!! $key !!}',
'contents' => '{!! $actualValue !!}'
],
@endforeach
@endforeach
@foreach($endpoint->fileParameters as $parameter => $value)
@foreach(u::getParameterNamesAndValuesForFormData($parameter, $value) as $key => $file)
[
'name' => '{!! $key !!}',
'contents' => fopen('{!! $file->path() !!}', 'r')
],
@endforeach
@endforeach
],
@elseif(count($endpoint->cleanBodyParameters))
@if ($endpoint->headers['Content-Type'] == 'application/x-www-form-urlencoded')
'form_params' => {!! u::printPhpValue($endpoint->cleanBodyParameters, 8) !!},
@else
'json' => {!! u::printPhpValue($endpoint->cleanBodyParameters, 8) !!},
@endif
@endif
]
);
@else
$response = $client->{{ strtolower($endpoint->httpMethods[0]) }}($url);
@endif
$body = $response->getBody();
print_r(json_decode((string) $body));
```

View File

@@ -0,0 +1,52 @@
@php
use Knuckles\Scribe\Tools\WritingUtils as u;
/** @var Knuckles\Camel\Output\OutputEndpointData $endpoint */
@endphp
```python
import requests
import json
url = '{!! rtrim($baseUrl, '/') !!}/{{ $endpoint->boundUri }}'
@if($endpoint->hasFiles() || (isset($endpoint->headers['Content-Type']) && $endpoint->headers['Content-Type'] == 'multipart/form-data' && count($endpoint->cleanBodyParameters)))
files = {
@foreach($endpoint->cleanBodyParameters as $parameter => $value)
@foreach(u::getParameterNamesAndValuesForFormData($parameter, $value) as $key => $actualValue)
'{!! $key !!}': (None, '{!! $actualValue !!}')@if(!($loop->parent->last) || count($endpoint->fileParameters)),
@endif
@endforeach
@endforeach
@foreach($endpoint->fileParameters as $parameter => $value)
@foreach(u::getParameterNamesAndValuesForFormData($parameter, $value) as $key => $file)
'{!! $key !!}': open('{!! $file->path() !!}', 'rb')@if(!($loop->parent->last)),
@endif
@endforeach
@endforeach
}
@endif
@if(count($endpoint->cleanBodyParameters))
payload = {!! json_encode($endpoint->cleanBodyParameters, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) !!}
@endif
@if(count($endpoint->cleanQueryParameters))
params = {!! u::printQueryParamsAsKeyValue($endpoint->cleanQueryParameters, "'", ":", 2, "{}") !!}
@endif
@if(!empty($endpoint->headers))
headers = {
@foreach($endpoint->headers as $header => $value)
'{{$header}}': '{{$value}}'@if(!($loop->last)),
@endif
@endforeach
}
@endif
@php
$optionalArguments = [];
if (count($endpoint->headers)) $optionalArguments[] = "headers=headers";
if (count($endpoint->fileParameters)) $optionalArguments[] = "files=files";
if (count($endpoint->cleanBodyParameters) && $endpoint->headers['Content-Type'] != 'multipart/form-data') $optionalArguments[] = (count($endpoint->fileParameters) || $endpoint->headers['Content-Type'] == 'application/x-www-form-urlencoded' ? "data=payload" : "json=payload");
if (count($endpoint->cleanQueryParameters)) $optionalArguments[] = "params=params";
$optionalArguments = implode(', ',$optionalArguments);
@endphp
response = requests.request('{{$endpoint->httpMethods[0]}}', url, {{ $optionalArguments }})
response.json()
```

View File

@@ -0,0 +1,190 @@
@php
use Knuckles\Scribe\Tools\Utils as u;
/** @var Knuckles\Camel\Output\OutputEndpointData $endpoint */
@endphp
<h2 id="{!! $endpoint->fullSlug() !!}">{{ $endpoint->name() }}</h2>
<p>
@component('scribe::components.badges.auth', ['authenticated' => $endpoint->isAuthed()])
@endcomponent
@component('scribe::components.badges.deprecated', ['deprecated' => $endpoint->metadata->deprecated])
@endcomponent
</p>
{!! Parsedown::instance()->text($endpoint->metadata->description ?: '') !!}
<span id="example-requests-{!! $endpoint->endpointId() !!}">
<blockquote>{{ u::trans("scribe::endpoint.example_request") }}:</blockquote>
@foreach($metadata['example_languages'] as $language)
<div class="{{ $language }}-example">
@include("scribe::partials.example-requests.$language")
</div>
@endforeach
</span>
<span id="example-responses-{!! $endpoint->endpointId() !!}">
@if($endpoint->isGet() || $endpoint->hasResponses())
@foreach($endpoint->responses as $response)
<blockquote>
<p>{{ u::trans("scribe::endpoint.example_response") }} ({{ $response->fullDescription() }}):</p>
</blockquote>
@if(count($response->headers))
<details class="annotation">
<summary style="cursor: pointer;">
<small onclick="textContent = parentElement.parentElement.open ? 'Show headers' : 'Hide headers'">Show headers</small>
</summary>
<pre><code class="language-http">@foreach($response->headers as $header => $value)
{{ $header }}: {{ is_array($value) ? implode('; ', $value) : $value }}
@endforeach </code></pre></details> @endif
<pre>
@if($response->isBinary())
<code>{!! u::trans("scribe::endpoint.responses.binary") !!} - {{ htmlentities(str_replace("<<binary>>", "", $response->content)) }}</code>
@elseif($response->status == 204)
<code>{!! u::trans("scribe::endpoint.responses.empty") !!}</code>
@else
@php($parsed = json_decode($response->content))
{{-- If response is a JSON string, prettify it. Otherwise, just print it --}}
<code class="language-json" style="max-height: 300px;">{!! htmlentities($parsed != null ? json_encode($parsed, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) : $response->content) !!}</code>
@endif </pre>
@endforeach
@endif
</span>
<span id="execution-results-{{ $endpoint->endpointId() }}" hidden>
<blockquote>{{ u::trans("scribe::try_it_out.received_response") }}<span
id="execution-response-status-{{ $endpoint->endpointId() }}"></span>:
</blockquote>
<pre class="json"><code id="execution-response-content-{{ $endpoint->endpointId() }}"
data-empty-response-text="<{{ u::trans("scribe::endpoint.responses.empty") }}>" style="max-height: 400px;"></code></pre>
</span>
<span id="execution-error-{{ $endpoint->endpointId() }}" hidden>
<blockquote>{{ u::trans("scribe::try_it_out.request_failed") }}:</blockquote>
<pre><code id="execution-error-message-{{ $endpoint->endpointId() }}">{{ "\n\n".u::trans("scribe::try_it_out.error_help") }}</code></pre>
</span>
<form id="form-{{ $endpoint->endpointId() }}" data-method="{{ $endpoint->httpMethods[0] }}"
data-path="{{ $endpoint->uri }}"
data-authed="{{ $endpoint->isAuthed() ? 1 : 0 }}"
data-hasfiles="{{ $endpoint->hasFiles() ? 1 : 0 }}"
data-isarraybody="{{ $endpoint->isArrayBody() ? 1 : 0 }}"
autocomplete="off"
onsubmit="event.preventDefault(); executeTryOut('{{ $endpoint->endpointId() }}', this);">
<h3>
{{ u::trans("scribe::endpoint.request") }}&nbsp;&nbsp;&nbsp;
@if($metadata['try_it_out']['enabled'] ?? false)
<button type="button"
style="background-color: #8fbcd4; padding: 5px 10px; border-radius: 5px; border-width: thin;"
id="btn-tryout-{{ $endpoint->endpointId() }}"
onclick="tryItOut('{{ $endpoint->endpointId() }}');">{{ u::trans("scribe::try_it_out.open") }}
</button>
<button type="button"
style="background-color: #c97a7e; padding: 5px 10px; border-radius: 5px; border-width: thin;"
id="btn-canceltryout-{{ $endpoint->endpointId() }}"
onclick="cancelTryOut('{{ $endpoint->endpointId() }}');" hidden>{{ u::trans("scribe::try_it_out.cancel") }}
</button>&nbsp;&nbsp;
<button type="submit"
style="background-color: #6ac174; padding: 5px 10px; border-radius: 5px; border-width: thin;"
id="btn-executetryout-{{ $endpoint->endpointId() }}"
data-initial-text="{{ u::trans("scribe::try_it_out.send") }}"
data-loading-text="{{ u::trans("scribe::try_it_out.loading") }}"
hidden>{{ u::trans("scribe::try_it_out.send") }}
</button>
@endif
</h3>
@foreach($endpoint->httpMethods as $method)
<p>
@component('scribe::components.badges.http-method', ['method' => $method])@endcomponent
<b><code>{{$endpoint->uri}}</code></b>
</p>
@endforeach
@if(count($endpoint->headers))
<h4 class="fancy-heading-panel"><b>{{ u::trans("scribe::endpoint.headers") }}</b></h4>
@foreach($endpoint->headers as $name => $example)
<?php
$htmlOptions = [];
if ($endpoint->isAuthed() && 'header' == $metadata['auth']['location'] && $metadata['auth']['name'] == $name) {
$htmlOptions = ['class' => 'auth-value'];
}
?>
<div style="padding-left: 28px; clear: unset;">
@component('scribe::components.field-details', [
'name' => $name,
'type' => null,
'required' => true,
'deprecated' => false,
'description' => null,
'example' => $example,
'endpointId' => $endpoint->endpointId(),
'component' => 'header',
'isInput' => true,
'html' => $htmlOptions,
])
@endcomponent
</div>
@endforeach
@endif
@if(count($endpoint->urlParameters))
<h4 class="fancy-heading-panel"><b>{{ u::trans("scribe::endpoint.url_parameters") }}</b></h4>
@foreach($endpoint->urlParameters as $attribute => $parameter)
<div style="padding-left: 28px; clear: unset;">
@component('scribe::components.field-details', [
'name' => $parameter->name,
'type' => $parameter->type ?? 'string',
'required' => $parameter->required,
'deprecated' => $parameter->deprecated,
'description' => $parameter->description,
'example' => $parameter->example ?? '',
'enumValues' => $parameter->enumValues,
'endpointId' => $endpoint->endpointId(),
'component' => 'url',
'isInput' => true,
])
@endcomponent
</div>
@endforeach
@endif
@if(count($endpoint->queryParameters))
<h4 class="fancy-heading-panel"><b>{{ u::trans("scribe::endpoint.query_parameters") }}</b></h4>
@foreach($endpoint->queryParameters as $attribute => $parameter)
<?php
$htmlOptions = [];
if ($endpoint->isAuthed() && 'query' == $metadata['auth']['location'] && $metadata['auth']['name'] == $attribute) {
$htmlOptions = ['class' => 'auth-value'];
}
?>
<div style="padding-left: 28px; clear: unset;">
@component('scribe::components.field-details', [
'name' => $parameter->name,
'type' => $parameter->type,
'required' => $parameter->required,
'deprecated' => $parameter->deprecated,
'description' => $parameter->description,
'example' => $parameter->example ?? '',
'enumValues' => $parameter->enumValues,
'endpointId' => $endpoint->endpointId(),
'component' => 'query',
'isInput' => true,
'html' => $htmlOptions,
])
@endcomponent
</div>
@endforeach
@endif
@if(count($endpoint->nestedBodyParameters))
<h4 class="fancy-heading-panel"><b>{{ u::trans("scribe::endpoint.body_parameters") }}</b></h4>
<x-scribe::nested-fields
:fields="$endpoint->nestedBodyParameters" :endpointId="$endpoint->endpointId()"
/>
@endif
</form>
@if(count($endpoint->responseFields))
<h3>{{ u::trans("scribe::endpoint.response") }}</h3>
<h4 class="fancy-heading-panel"><b>{{ u::trans("scribe::endpoint.response_fields") }}</b></h4>
<x-scribe::nested-fields
:fields="$endpoint->nestedResponseFields" :endpointId="$endpoint->endpointId()"
:isInput="false"
/>
@endif

View File

@@ -0,0 +1,21 @@
@foreach($groupedEndpoints as $group)
<h1 id="{!! Str::slug($group['name']) !!}">{!! $group['name'] !!}</h1>
{!! Parsedown::instance()->text($group['description']) !!}
@foreach($group['subgroups'] as $subgroupName => $subgroup)
@if($subgroupName !== "")
<h2 id="{!! Str::slug($group['name']) !!}-{!! Str::slug($subgroupName) !!}">{{ $subgroupName }}</h2>
@php($subgroupDescription = collect($subgroup)->first(fn ($e) => $e->metadata->subgroupDescription)?->metadata?->subgroupDescription)
@if($subgroupDescription)
<p>
{!! Parsedown::instance()->text($subgroupDescription) !!}
</p>
@endif
@endif
@foreach($subgroup as $endpoint)
@include("scribe::themes.default.endpoint")
@endforeach
@endforeach
@endforeach

View File

@@ -0,0 +1,74 @@
@php
use Knuckles\Scribe\Tools\WritingUtils as u;
@endphp
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>{!! $metadata['title'] !!}</title>
<link href="https://fonts.googleapis.com/css?family=Open+Sans&display=swap" rel="stylesheet">
<link rel="stylesheet" href="{!! $assetPathPrefix !!}css/theme-default.style.css" media="screen">
<link rel="stylesheet" href="{!! $assetPathPrefix !!}css/theme-default.print.css" media="print">
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>
<link rel="stylesheet"
href="https://unpkg.com/@highlightjs/cdn-assets@11.6.0/styles/obsidian.min.css">
<script src="https://unpkg.com/@highlightjs/cdn-assets@11.6.0/highlight.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jets/0.14.1/jets.min.js"></script>
@if(isset($metadata['example_languages']))
<style id="language-style">
/* starts out as display none and is replaced with js later */
@foreach($metadata['example_languages'] as $lang)
body .content .{{ $lang }}-example code { display: none; }
@endforeach
</style>
@endif
@if($tryItOut['enabled'] ?? true)
<script>
var tryItOutBaseUrl = "{!! $tryItOut['base_url'] ?? $baseUrl !!}";
var useCsrf = Boolean({!! $tryItOut['use_csrf'] ?? null !!});
var csrfUrl = "{!! $tryItOut['csrf_url'] ?? null !!}";
</script>
<script src="{{ u::getVersionedAsset($assetPathPrefix.'js/tryitout.js') }}"></script>
@endif
<script src="{{ u::getVersionedAsset($assetPathPrefix.'js/theme-default.js') }}"></script>
</head>
<body data-languages="{{ json_encode($metadata['example_languages'] ?? []) }}">
@include("scribe::themes.default.sidebar")
<div class="page-wrapper">
<div class="dark-box"></div>
<div class="content">
{!! $intro !!}
{!! $auth !!}
@include("scribe::themes.default.groups")
{!! $append !!}
</div>
<div class="dark-box">
@if(isset($metadata['example_languages']))
<div class="lang-selector">
@foreach($metadata['example_languages'] as $name => $lang)
@php if (is_numeric($name)) $name = $lang; @endphp
<button type="button" class="lang-button" data-language-name="{{$lang}}">{{$name}}</button>
@endforeach
</div>
@endif
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,69 @@
@php
use Knuckles\Scribe\Tools\Utils as u;
@endphp
<a href="#" id="nav-button">
<span>
MENU
<img src="{!! $assetPathPrefix !!}images/navbar.png" alt="navbar-image"/>
</span>
</a>
<div class="tocify-wrapper">
@if($metadata['logo'] != false)
<img src="{{ $metadata['logo'] }}" alt="logo" class="logo" style="padding-top: 10px;" width="100%"/>
@endif
@isset($metadata['example_languages'])
<div class="lang-selector">
@foreach($metadata['example_languages'] as $name => $lang)
@php if (is_numeric($name)) $name = $lang; @endphp
<button type="button" class="lang-button" data-language-name="{{ $lang }}">{{ $name }}</button>
@endforeach
</div>
@endisset
<div class="search">
<input type="text" class="search" id="input-search" placeholder="{{ u::trans("scribe::labels.search") }}">
</div>
<div id="toc">
@foreach($headings as $h1)
<ul id="tocify-header-{{ $h1['slug'] }}" class="tocify-header">
<li class="tocify-item level-1" data-unique="{!! $h1['slug'] !!}">
<a href="#{!! $h1['slug'] !!}">{!! $h1['name'] !!}</a>
</li>
@if(count($h1['subheadings']) > 0)
<ul id="tocify-subheader-{!! $h1['slug'] !!}" class="tocify-subheader">
@foreach($h1['subheadings'] as $h2)
<li class="tocify-item level-2" data-unique="{!! $h2['slug'] !!}">
<a href="#{!! $h2['slug'] !!}">{!! $h2['name'] !!}</a>
</li>
@if(count($h2['subheadings']) > 0)
<ul id="tocify-subheader-{!! $h2['slug'] !!}" class="tocify-subheader">
@foreach($h2['subheadings'] as $h3)
<li class="tocify-item level-3" data-unique="{!! $h3['slug'] !!}">
<a href="#{!! $h3['slug'] !!}">{!! $h3['name'] !!}</a>
</li>
@endforeach
</ul>
@endif
@endforeach
</ul>
@endif
</ul>
@endforeach
</div>
<ul class="toc-footer" id="toc-footer">
@if($metadata['postman_collection_url'])
<li style="padding-bottom: 5px;"><a href="{!! $metadata['postman_collection_url'] !!}">{!! u::trans("scribe::links.postman") !!}</a></li>
@endif
@if($metadata['openapi_spec_url'])
<li style="padding-bottom: 5px;"><a href="{!! $metadata['openapi_spec_url'] !!}">{!! u::trans("scribe::links.openapi") !!}</a></li>
@endif
<li><a href="http://github.com/knuckleswtf/scribe">Documentation powered by Scribe </a></li>
</ul>
<ul class="toc-footer" id="last-updated">
<li>{{ $metadata['last_updated'] }}</li>
</ul>
</div>

View File

@@ -0,0 +1,70 @@
@php
$hasChildren ??= false;
$isArrayBody = $name == "[]";
$expandable = $hasChildren && !$isArrayBody;
@endphp
<div class="sl-flex sl-relative sl-max-w-full sl-py-2 sl-pl-3">
<div class="sl-w-1 sl-mt-2 sl-mr-3 sl--ml-3 sl-border-t"></div>
<div class="sl-stack sl-stack--vertical sl-stack--1 sl-flex sl-flex-1 sl-flex-col sl-items-stretch sl-max-w-full sl-ml-2 @if($expandable) sl-cursor-pointer @endif">
<div class="sl-flex sl-items-center sl-max-w-full">
@if($expandable)
<div class="sl-flex sl-justify-center sl-w-8 sl--ml-8 sl-pl-3 sl-text-muted expansion-chevrons" role="button">
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="chevron-right"
class="svg-inline--fa fa-chevron-right fa-fw fa-sm sl-icon" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M96 480c-8.188 0-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L242.8 256L73.38 86.63c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l192 192c12.5 12.5 12.5 32.75 0 45.25l-192 192C112.4 476.9 104.2 480 96 480z"></path>
</svg>
</div>
@endif
@unless($isArrayBody)
<div class="sl-flex sl-items-baseline sl-text-base">
<div class="sl-font-mono sl-font-semibold sl-mr-2">{{ $name }}</div>
@if($type)
<span class="sl-truncate sl-text-muted">{{ $type }}</span>
@endif
</div>
@if($required || $deprecated)
<div class="sl-flex-1 sl-h-px sl-mx-3"></div>
<div class="sl-flex sl-items-center">
@if($required)
<span class="sl-ml-2 sl-text-warning">required</span>
@endif
@if($deprecated)
<span class="sl-ml-2 sl-text-warning">deprecated</span>
@endif
</div>
@endif
@endunless
</div>
@if($description)
<div class="sl-prose sl-markdown-viewer" style="font-size: 12px;">
{!! Parsedown::instance()->text($description) !!}
</div>
@endif
@if(!empty($enumValues))
Must be one of:
<ul style="list-style-position: inside; list-style-type: square;">{!! implode(" ", array_map(fn($val) => "<li><code>$val</code></li>", $enumValues)) !!}</ul>
@endif
@if($isArrayBody)
<div class="sl-flex sl-items-baseline sl-text-base">
<div class="sl-font-mono sl-font-semibold sl-mr-2">array of:</div>
@if($required)
<div class="sl-flex-1 sl-h-px sl-mx-3"></div>
<span class="sl-ml-2 sl-text-warning">required</span>
@endif
</div>
@endif
@if(!$hasChildren && !is_null($example) && $example !== '')
<div class="sl-stack sl-stack--horizontal sl-stack--2 sl-flex sl-flex-row sl-items-baseline sl-text-muted">
<span>Example:</span> <!-- <span> important for spacing -->
<div class="sl-flex sl-flex-1 sl-flex-wrap" style="gap: 4px;">
<div class="sl-max-w-full sl-break-all sl-px-1 sl-bg-canvas-tint sl-text-muted sl-rounded sl-border">
{{ is_array($example) || is_bool($example) ? json_encode($example) : $example }}
</div>
</div>
</div>
@endif
</div>
</div>

View File

@@ -0,0 +1,38 @@
@php
$level ??= 0;
$levelNestingClass = match($level) {
0 => "sl-ml-px",
default => "sl-ml-7"
};
$expandable ??= !isset($fields["[]"]);
@endphp
@foreach($fields as $name => $field)
<div class="{{ $expandable ? 'expandable' : '' }} sl-text-sm sl-border-l {{ $levelNestingClass }}">
@component('scribe::themes.elements.components.field-details', [
'name' => $name,
'type' => $field['type'] ?? 'string',
'required' => $field['required'] ?? false,
'deprecated' => $field['deprecated'] ?? false,
'description' => $field['description'] ?? '',
'example' => $field['example'] ?? '',
'enumValues' => $field['enumValues'] ?? null,
'endpointId' => $endpointId,
'hasChildren' => !empty($field['__fields']),
'component' => 'body',
])
@endcomponent
@if(!empty($field['__fields']))
<div class="children" style="{{ $expandable ? 'display: none;' : '' }}">
@component('scribe::themes.elements.components.nested-fields', [
'fields' => $field['__fields'],
'endpointId' => $endpointId,
'level' => $level + 1,
'expandable'=> $expandable,
])
@endcomponent
</div>
@endif
</div>
@endforeach

View File

@@ -0,0 +1,281 @@
@php
use Knuckles\Scribe\Tools\Utils as u;
/** @var Knuckles\Camel\Output\OutputEndpointData $endpoint */
@endphp
<div class="sl-stack sl-stack--vertical sl-stack--8 HttpOperation sl-flex sl-flex-col sl-items-stretch sl-w-full">
<div class="sl-stack sl-stack--vertical sl-stack--5 sl-flex sl-flex-col sl-items-stretch">
<div class="sl-relative">
<div class="sl-stack sl-stack--horizontal sl-stack--5 sl-flex sl-flex-row sl-items-center">
<h2 class="sl-text-3xl sl-leading-tight sl-font-prose sl-text-heading sl-mt-5 sl-mb-1"
id="{!! $endpoint->fullSlug() !!}">
{{ $endpoint->name() }}
</h2>
</div>
</div>
<div class="sl-relative">
<div title="{!! rtrim($baseUrl, '/') . '/'. ltrim($endpoint->uri, '/') !!}"
class="sl-stack sl-stack--horizontal sl-stack--3 sl-inline-flex sl-flex-row sl-items-center sl-max-w-full sl-font-mono sl-py-2 sl-pr-4 sl-bg-canvas-50 sl-rounded-lg"
>
@foreach($endpoint->httpMethods as $method)
<div class="sl-text-lg sl-font-semibold sl-px-2.5 sl-py-1 sl-text-on-primary sl-rounded-lg"
style="background-color: {{ \Knuckles\Scribe\Tools\WritingUtils::$httpMethodToCssColour[$method] }};"
>
{{ $method }}
</div>
@endforeach
<div class="sl-flex sl-overflow-x-hidden sl-text-lg sl-select-all">
<div dir="rtl"
class="sl-overflow-x-hidden sl-truncate sl-text-muted">{!! rtrim($baseUrl, '/') !!}</div>
<div class="sl-flex-1 sl-font-semibold">/{{ ltrim($endpoint->uri, '/') }}</div>
</div>
@if($endpoint->metadata->authenticated)
<div class="sl-font-prose sl-font-semibold sl-px-1.5 sl-py-0.5 sl-text-on-primary sl-rounded-lg"
style="background-color: darkred"
>requires authentication
</div>
@endif
@if($endpoint->metadata->deprecated === true)
<div class="sl-font-prose sl-font-semibold sl-px-1.5 sl-py-0.5 sl-text-on-primary sl-rounded-lg"
style="background-color: darkgoldenrod"
>deprecated
</div>
@endif
@if(is_string($endpoint->metadata->deprecated))
<div class="sl-font-prose sl-font-semibold sl-px-1.5 sl-py-0.5 sl-text-on-primary sl-rounded-lg"
style="background-color: darkgoldenrod"
>deprecated:{{$endpoint->metadata->deprecated}}
</div>
@endif
</div>
</div>
{!! Parsedown::instance()->text($endpoint->metadata->description ?: '') !!}
</div>
<div class="sl-flex">
<div data-testid="two-column-left" class="sl-flex-1 sl-w-0">
<div class="sl-stack sl-stack--vertical sl-stack--10 sl-flex sl-flex-col sl-items-stretch">
<div class="sl-stack sl-stack--vertical sl-stack--8 sl-flex sl-flex-col sl-items-stretch">
@if(count($endpoint->headers))
<div class="sl-stack sl-stack--vertical sl-stack--5 sl-flex sl-flex-col sl-items-stretch">
<h3 class="sl-text-2xl sl-leading-snug sl-font-prose">
{{ u::trans("scribe::endpoint.headers") }}
</h3>
<div class="sl-text-sm">
@foreach($endpoint->headers as $header => $value)
@component('scribe::themes.elements.components.field-details', [
'name' => $header,
'type' => null,
'required' => false,
'deprecated' => false,
'description' => null,
'example' => $value,
'endpointId' => $endpoint->endpointId(),
'component' => 'header',
'isInput' => true,
])
@endcomponent
@endforeach
</div>
</div>
@endif
@if(count($endpoint->urlParameters))
<div class="sl-stack sl-stack--vertical sl-stack--6 sl-flex sl-flex-col sl-items-stretch">
<h3 class="sl-text-2xl sl-leading-snug sl-font-prose">{{ u::trans("scribe::endpoint.url_parameters") }}</h3>
<div class="sl-text-sm">
@foreach($endpoint->urlParameters as $attribute => $parameter)
@component('scribe::themes.elements.components.field-details', [
'name' => $parameter->name,
'type' => $parameter->type ?? 'string',
'required' => $parameter->required,
'deprecated' => $parameter->deprecated,
'description' => $parameter->description,
'example' => $parameter->example ?? '',
'enumValues' => $parameter->enumValues,
'endpointId' => $endpoint->endpointId(),
'component' => 'url',
'isInput' => true,
])
@endcomponent
@endforeach
</div>
</div>
@endif
@if(count($endpoint->queryParameters))
<div class="sl-stack sl-stack--vertical sl-stack--6 sl-flex sl-flex-col sl-items-stretch">
<h3 class="sl-text-2xl sl-leading-snug sl-font-prose">{{ u::trans("scribe::endpoint.query_parameters") }}</h3>
<div class="sl-text-sm">
@foreach($endpoint->queryParameters as $attribute => $parameter)
@component('scribe::themes.elements.components.field-details', [
'name' => $parameter->name,
'type' => $parameter->type,
'required' => $parameter->required,
'deprecated' => $parameter->deprecated,
'description' => $parameter->description,
'example' => $parameter->example ?? '',
'enumValues' => $parameter->enumValues,
'endpointId' => $endpoint->endpointId(),
'component' => 'query',
'isInput' => true,
])
@endcomponent
@endforeach
</div>
</div>
@endif
@if(count($endpoint->nestedBodyParameters))
<div class="sl-stack sl-stack--vertical sl-stack--6 sl-flex sl-flex-col sl-items-stretch">
<h3 class="sl-text-2xl sl-leading-snug sl-font-prose">{{ u::trans("scribe::endpoint.body_parameters") }}</h3>
<div class="sl-text-sm">
@component('scribe::themes.elements.components.nested-fields', [
'fields' => $endpoint->nestedBodyParameters,
'endpointId' => $endpoint->endpointId(),
])
@endcomponent
</div>
</div>
@endif
@if(count($endpoint->responseFields))
<div class="sl-stack sl-stack--vertical sl-stack--6 sl-flex sl-flex-col sl-items-stretch">
<h3 class="sl-text-2xl sl-leading-snug sl-font-prose">{{ u::trans("scribe::endpoint.response_fields") }}</h3>
<div class="sl-text-sm">
@component('scribe::themes.elements.components.nested-fields', [
'fields' => $endpoint->nestedResponseFields,
'endpointId' => $endpoint->endpointId(),
'isInput' => false,
])
@endcomponent
</div>
</div>
@endif
</div>
</div>
</div>
<div data-testid="two-column-right" class="sl-relative sl-w-2/5 sl-ml-16" style="max-width: 500px;">
<div class="sl-stack sl-stack--vertical sl-stack--6 sl-flex sl-flex-col sl-items-stretch">
@if($metadata['try_it_out']['enabled'] ?? false)
@include("scribe::themes.elements.try_it_out")
@endif
@if($metadata['example_languages'])
<div class="sl-panel sl-outline-none sl-w-full sl-rounded-lg">
<div class="sl-panel__titlebar sl-flex sl-items-center sl-relative focus:sl-z-10 sl-text-base sl-leading-none sl-pr-3 sl-pl-4 sl-bg-canvas-200 sl-text-body sl-border-input focus:sl-border-primary sl-select-none">
<div class="sl-flex sl-flex-1 sl-items-center sl-h-lg">
<div class="sl--ml-2">
{{ u::trans("scribe::endpoint.example_request") }}:
<select class="example-request-lang-toggle sl-text-base"
aria-label="Request Sample Language"
onchange="switchExampleLanguage(event.target.value);">
@foreach($metadata['example_languages'] as $language)
<option>{{ $language }}</option>
@endforeach
</select>
</div>
</div>
</div>
@foreach($metadata['example_languages'] as $index => $language)
<div class="sl-bg-canvas-100 example-request example-request-{{ $language }}"
style="{{ $index == 0 ? '' : 'display: none;' }}">
<div class="sl-px-0 sl-py-1">
<div style="max-height: 400px;" class="sl-overflow-y-auto sl-rounded">
@include("scribe::partials.example-requests.$language")
</div>
</div>
</div>
@endforeach
</div>
@endif
@if($endpoint->isGet() || $endpoint->hasResponses())
<div class="sl-panel sl-outline-none sl-w-full sl-rounded-lg">
<div class="sl-panel__titlebar sl-flex sl-items-center sl-relative focus:sl-z-10 sl-text-base sl-leading-none sl-pr-3 sl-pl-4 sl-bg-canvas-200 sl-text-body sl-border-input focus:sl-border-primary sl-select-none">
<div class="sl-flex sl-flex-1 sl-items-center sl-py-2">
<div class="sl--ml-2">
<div class="sl-h-sm sl-text-base sl-font-medium sl-px-1.5 sl-text-muted sl-rounded sl-border-transparent sl-border">
<div class="sl-mb-2 sl-inline-block">{{ u::trans("scribe::endpoint.example_response") }}:</div>
<div class="sl-mb-2 sl-inline-block">
<select
class="example-response-{{ $endpoint->endpointId() }}-toggle sl-text-base"
aria-label="Response sample"
onchange="switchExampleResponse('{{ $endpoint->endpointId() }}', event.target.value);">
@foreach($endpoint->responses as $index => $response)
<option value="{{ $index }}">{{ $response->fullDescription() }}</option>
@endforeach
</select></div>
</div>
</div>
</div>
<button type="button"
class="sl-button sl-h-sm sl-text-base sl-font-medium sl-px-1.5 hover:sl-bg-canvas-50 active:sl-bg-canvas-100 sl-text-muted hover:sl-text-body focus:sl-text-body sl-rounded sl-border-transparent sl-border disabled:sl-opacity-70">
<div class="sl-mx-0">
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="copy"
class="svg-inline--fa fa-copy fa-fw fa-sm sl-icon" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path fill="currentColor"
d="M384 96L384 0h-112c-26.51 0-48 21.49-48 48v288c0 26.51 21.49 48 48 48H464c26.51 0 48-21.49 48-48V128h-95.1C398.4 128 384 113.6 384 96zM416 0v96h96L416 0zM192 352V128h-144c-26.51 0-48 21.49-48 48v288c0 26.51 21.49 48 48 48h192c26.51 0 48-21.49 48-48L288 416h-32C220.7 416 192 387.3 192 352z"></path>
</svg>
</div>
</button>
</div>
@foreach($endpoint->responses as $index => $response)
<div class="sl-panel__content-wrapper sl-bg-canvas-100 example-response-{{ $endpoint->endpointId() }} example-response-{{ $endpoint->endpointId() }}-{{ $index }}"
style=" {{ $index == 0 ? '' : 'display: none;' }}"
>
<div class="sl-panel__content sl-p-0">@if(count($response->headers))
<details class="sl-pl-2">
<summary style="cursor: pointer; list-style: none;">
<small>
<span class="expansion-chevrons">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="chevron-right"
class="svg-inline--fa fa-chevron-right fa-fw sl-icon sl-text-muted"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M96 480c-8.188 0-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L242.8 256L73.38 86.63c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l192 192c12.5 12.5 12.5 32.75 0 45.25l-192 192C112.4 476.9 104.2 480 96 480z"></path>
</svg>
</span>
Headers
</small>
</summary>
@php
$headerLines = [];
foreach($response->headers as $header => $value) {
$headerLines[] = $header . ': ' . (is_array($value) ? implode('; ', $value) : $value);
}
@endphp
<pre><code class="language-http">{{ implode("\n", $headerLines) }}</code></pre>
</details>
@endif
@if($response->isBinary())
<pre><code>[{{ u::trans("scribe::endpoint.responses.binary") }}] - {{ htmlentities(str_replace("<<binary>>", "", $response->content)) }}</code></pre>
@elseif($response->status == 204)
<pre><code>[{{ u::trans("scribe::endpoint.responses.empty") }}]</code></pre>
@else
@php($parsed = json_decode($response->content))
{{-- If response is a JSON string, prettify it. Otherwise, just print it --}}
<pre><code style="max-height: 300px;"
class="language-json sl-overflow-x-auto sl-overflow-y-auto">{!! htmlentities($parsed != null ? json_encode($parsed, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) : $response->content) !!}</code></pre>
@endif
</div>
</div>
@endforeach
</div>
@endif
</div>
</div>
</div>

View File

@@ -0,0 +1,28 @@
@foreach($groupedEndpoints as $group)
<h1 id="{!! Str::slug($group['name']) !!}"
class="sl-text-5xl sl-leading-tight sl-font-prose sl-text-heading"
>
{!! $group['name'] !!}
</h1>
{!! Parsedown::instance()->text($group['description']) !!}
@foreach($group['subgroups'] as $subgroupName => $subgroup)
@if($subgroupName !== "")
<h2 id="{!! Str::slug($group['name']) !!}-{!! Str::slug($subgroupName) !!}"
class="sl-text-3xl sl-leading-tight sl-font-prose sl-text-heading sl-mt-5 sl-mb-3"
>
{{ $subgroupName }}
</h2>
@php($subgroupDescription = collect($subgroup)->first(fn ($e) => $e->metadata->subgroupDescription)?->metadata?->subgroupDescription)
@if($subgroupDescription)
{!! Parsedown::instance()->text($subgroupDescription) !!}
@endif
<br>
@endif
@foreach($subgroup as $endpoint)
@include("scribe::themes.elements.endpoint")
@endforeach
@endforeach
@endforeach

View File

@@ -0,0 +1,360 @@
@php
use Knuckles\Scribe\Tools\WritingUtils as u;
@endphp
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>{!! $metadata['title'] !!}</title>
<link href="https://fonts.googleapis.com/css?family=PT+Sans&display=swap" rel="stylesheet">
<link rel="stylesheet" href="{!! $assetPathPrefix !!}css/theme-elements.style.css" media="screen">
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>
<link rel="stylesheet"
href="https://unpkg.com/@highlightjs/cdn-assets@11.6.0/styles/docco.min.css">
<script src="https://unpkg.com/@highlightjs/cdn-assets@11.6.0/highlight.min.js"></script>
<script>hljs.highlightAll();</script>
<script type="module">
import {CodeJar} from 'https://medv.io/codejar/codejar.js'
window.CodeJar = CodeJar;
</script>
@if($tryItOut['enabled'] ?? true)
<script>
var tryItOutBaseUrl = "{!! $tryItOut['base_url'] ?? $baseUrl !!}";
var useCsrf = Boolean({{ $tryItOut['use_csrf'] ?? null }});
var csrfUrl = "{{ $tryItOut['csrf_url'] ?? null }}";
</script>
<script src="{{ u::getVersionedAsset($assetPathPrefix.'js/tryitout.js') }}"></script>
<style>
.code-editor, .response-content {
color: whitesmoke;
background-color: transparent;
}
/*
Problem: we want syntax highlighting for the Try It Out JSON body code editor
However, the Try It Out area uses a dark background, while request and response samples
(which are already highlighted) use a light background. HighlightJS can only use one theme per document.
Our options:
1. Change the bg of one. => No, it looks out of place on the page.
2. Use the same highlighting for both. => Nope, one would be unreadable.
3. Copy styles for a dark-bg h1js theme and prefix them for the CodeEditor, which is what we're doing.
Since it's only JSON, we only need a few styles anyway.
Styles taken from the Nord theme: https://github.com/highlightjs/highlight.js/blob/3997c9b430a568d5ad46d96693b90a74fc01ea7f/src/styles/nord.css#L2
*/
.code-editor > .hljs-attr {
color: #8FBCBB;
}
.code-editor > .hljs-string {
color: #A3BE8C;
}
.code-editor > .hljs-number {
color: #B48EAD;
}
.code-editor > .hljs-literal{
color: #81A1C1;
}
</style>
<script>
function tryItOut(btnElement) {
btnElement.disabled = true;
let endpointId = btnElement.dataset.endpoint;
let errorPanel = document.querySelector(`.tryItOut-error[data-endpoint=${endpointId}]`);
errorPanel.hidden = true;
let responsePanel = document.querySelector(`.tryItOut-response[data-endpoint=${endpointId}]`);
responsePanel.hidden = true;
let form = btnElement.form;
let { method, path, hasjsonbody: hasJsonBody} = form.dataset;
let body = {};
if (hasJsonBody === "1") {
body = form.querySelector('.code-editor').textContent;
} else if (form.dataset.hasfiles === "1") {
body = new FormData();
form.querySelectorAll('input[data-component=body]')
.forEach(el => {
if (el.type === 'file') {
if (el.files[0]) body.append(el.name, el.files[0])
} else body.append(el.name, el.value);
});
} else {
form.querySelectorAll('input[data-component=body]').forEach(el => {
_.set(body, el.name, el.value);
});
}
const urlParameters = form.querySelectorAll('input[data-component=url]');
urlParameters.forEach(el => (path = path.replace(new RegExp(`\\{${el.name}\\??}`), el.value)));
const headers = Object.fromEntries(Array.from(form.querySelectorAll('input[data-component=header]'))
.map(el => [el.name, (el.dataset.prefix || '') + el.value]));
const query = {}
form.querySelectorAll('input[data-component=query]').forEach(el => {
_.set(query, el.name, el.value);
});
let preflightPromise = Promise.resolve();
if (window.useCsrf && window.csrfUrl) {
preflightPromise = makeAPICall('GET', window.csrfUrl).then(() => {
headers['X-XSRF-TOKEN'] = getCookie('XSRF-TOKEN');
});
}
// content type has to be unset otherwise file upload won't work
if (form.dataset.hasfiles === "1") {
delete headers['Content-Type'];
}
return preflightPromise.then(() => makeAPICall(method, path, body, query, headers, endpointId))
.then(([responseStatus, statusText, responseContent, responseHeaders]) => {
responsePanel.hidden = false;
responsePanel.querySelector(`.response-status`).textContent = responseStatus + " " + statusText ;
let contentEl = responsePanel.querySelector(`.response-content`);
if (responseContent === '') {
contentEl.textContent = contentEl.dataset.emptyResponseText;
return;
}
// Prettify it if it's JSON
let isJson = false;
try {
const jsonParsed = JSON.parse(responseContent);
if (jsonParsed !== null) {
isJson = true;
responseContent = JSON.stringify(jsonParsed, null, 4);
}
} catch (e) {}
// Replace HTML entities
responseContent = responseContent.replace(/[<>&]/g, (i) => '&#' + i.charCodeAt(0) + ';');
contentEl.innerHTML = responseContent;
isJson && window.hljs.highlightElement(contentEl);
})
.catch(err => {
console.log(err);
let errorMessage = err.message || err;
errorPanel.hidden = false;
errorPanel.querySelector(`.error-message`).textContent = errorMessage;
})
.finally(() => { btnElement.disabled = false } );
}
window.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('.tryItOut-btn').forEach(el => {
el.addEventListener('click', () => tryItOut(el));
});
})
</script>
@endif
</head>
<body>
@if($metadata['example_languages'])
<script>
function switchExampleLanguage(lang) {
document.querySelectorAll(`.example-request`).forEach(el => el.style.display = 'none');
document.querySelectorAll(`.example-request-${lang}`).forEach(el => el.style.display = 'initial');
document.querySelectorAll(`.example-request-lang-toggle`).forEach(el => el.value = lang);
}
</script>
@endif
<script>
function switchExampleResponse(endpointId, index) {
document.querySelectorAll(`.example-response-${endpointId}`).forEach(el => el.style.display = 'none');
document.querySelectorAll(`.example-response-${endpointId}-${index}`).forEach(el => el.style.display = 'initial');
document.querySelectorAll(`.example-response-${endpointId}-toggle`).forEach(el => el.value = index);
}
/*
* Requirement: a div with class `expansion-chevrons`
* (or `expansion-chevrons-solid` to use the solid version).
* Also add the `expanded` class if your div is expanded by default.
*/
function toggleExpansionChevrons(evt) {
let elem = evt.currentTarget;
let chevronsArea = elem.querySelector('.expansion-chevrons');
const solid = chevronsArea.classList.contains('expansion-chevrons-solid');
const newState = chevronsArea.classList.contains('expanded') ? 'expand' : 'expanded';
if (newState === 'expanded') {
const selector = solid ? '#expanded-chevron-solid' : '#expanded-chevron';
const template = document.querySelector(selector);
const chevron = template.content.cloneNode(true);
chevronsArea.replaceChildren(chevron);
chevronsArea.classList.add('expanded');
} else {
const selector = solid ? '#expand-chevron-solid' : '#expand-chevron';
const template = document.querySelector(selector);
const chevron = template.content.cloneNode(true);
chevronsArea.replaceChildren(chevron);
chevronsArea.classList.remove('expanded');
}
}
/**
* 1. Make sure the children are inside the parent element
* 2. Add `expandable` class to the parent
* 3. Add `children` class to the children.
* 4. Wrap the default chevron SVG in a div with class `expansion-chevrons`
* (or `expansion-chevrons-solid` to use the solid version).
* Also add the `expanded` class if your div is expanded by default.
*/
function toggleElementChildren(evt) {
let elem = evt.currentTarget;
let children = elem.querySelector(`.children`);
if (!children) return;
if (children.contains(event.target)) return;
let oldState = children.style.display
if (oldState === 'none') {
children.style.removeProperty('display');
toggleExpansionChevrons(evt);
} else {
children.style.display = 'none';
toggleExpansionChevrons(evt);
}
evt.stopPropagation();
}
function highlightSidebarItem(evt = null) {
if (evt && evt.oldURL) {
let oldHash = new URL(evt.oldURL).hash.slice(1);
if (oldHash) {
let previousItem = window['sidebar'].querySelector(`#toc-item-${oldHash}`);
previousItem.classList.remove('sl-bg-primary-tint');
previousItem.classList.add('sl-bg-canvas-100');
}
}
let newHash = location.hash.slice(1);
if (newHash) {
let item = window['sidebar'].querySelector(`#toc-item-${newHash}`);
item.classList.remove('sl-bg-canvas-100');
item.classList.add('sl-bg-primary-tint');
}
}
addEventListener('DOMContentLoaded', () => {
highlightSidebarItem();
document.querySelectorAll('.code-editor').forEach(elem => CodeJar(elem, (editor) => {
// highlight.js does not trim old tags,
// which means highlighting doesn't update on type (only on paste)
// See https://github.com/antonmedv/codejar/issues/18
editor.textContent = editor.textContent
return hljs.highlightElement(editor)
}));
document.querySelectorAll('.expandable').forEach(el => {
el.addEventListener('click', toggleElementChildren);
});
document.querySelectorAll('details').forEach(el => {
el.addEventListener('toggle', toggleExpansionChevrons);
});
});
addEventListener('hashchange', highlightSidebarItem);
</script>
<div class="sl-elements sl-antialiased sl-h-full sl-text-base sl-font-ui sl-text-body sl-flex sl-inset-0">
@include("scribe::themes.elements.sidebar")
<div class="sl-overflow-y-auto sl-flex-1 sl-w-full sl-px-16 sl-bg-canvas sl-py-16" style="max-width: 1500px;">
<div class="sl-mb-10">
<div class="sl-mb-4">
<h1 class="sl-text-5xl sl-leading-tight sl-font-prose sl-font-semibold sl-text-heading">
{!! $metadata['title'] !!}
</h1>
@if($metadata['postman_collection_url'])
<a title="Download Postman collection" class="sl-mx-1"
href="{!! $metadata['postman_collection_url'] !!}" target="_blank">
<small>Postman collection </small>
</a>
@endif
@if($metadata['openapi_spec_url'])
<a title="Download OpenAPI spec" class="sl-mx-1"
href="{!! $metadata['openapi_spec_url'] !!}" target="_blank">
<small>OpenAPI spec </small>
</a>
@endif
</div>
<div class="sl-prose sl-markdown-viewer sl-my-4">
{!! $intro !!}
{!! $auth !!}
</div>
</div>
@include("scribe::themes.elements.groups")
<div class="sl-prose sl-markdown-viewer sl-my-5">
{!! $append !!}
</div>
</div>
</div>
<template id="expand-chevron">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="chevron-right"
class="svg-inline--fa fa-chevron-right fa-fw sl-icon sl-text-muted"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M96 480c-8.188 0-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L242.8 256L73.38 86.63c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l192 192c12.5 12.5 12.5 32.75 0 45.25l-192 192C112.4 476.9 104.2 480 96 480z"></path>
</svg>
</template>
<template id="expanded-chevron">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="chevron-down"
class="svg-inline--fa fa-chevron-down fa-fw sl-icon sl-text-muted"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<path fill="currentColor"
d="M224 416c-8.188 0-16.38-3.125-22.62-9.375l-192-192c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0L224 338.8l169.4-169.4c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25l-192 192C240.4 412.9 232.2 416 224 416z"></path>
</svg>
</template>
<template id="expand-chevron-solid">
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-right"
class="svg-inline--fa fa-caret-right fa-fw sl-icon" role="img" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 256 512">
<path fill="currentColor"
d="M118.6 105.4l128 127.1C252.9 239.6 256 247.8 256 255.1s-3.125 16.38-9.375 22.63l-128 127.1c-9.156 9.156-22.91 11.9-34.88 6.943S64 396.9 64 383.1V128c0-12.94 7.781-24.62 19.75-29.58S109.5 96.23 118.6 105.4z"></path>
</svg>
</template>
<template id="expanded-chevron-solid">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="caret-down"
class="svg-inline--fa fa-caret-down fa-fw sl-icon" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M310.6 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z"></path>
</svg>
</template>
</body>
</html>

View File

@@ -0,0 +1,92 @@
<div id="sidebar" class="sl-flex sl-overflow-y-auto sl-flex-col sl-sticky sl-inset-y-0 sl-pt-8 sl-bg-canvas-100 sl-border-r"
style="width: calc((100% - 1800px) / 2 + 300px); padding-left: calc((100% - 1800px) / 2); min-width: 300px; max-height: 100vh">
<div class="sl-flex sl-items-center sl-mb-5 sl-ml-4">
@if($metadata['logo'] != false)
<div class="sl-inline sl-overflow-x-hidden sl-overflow-y-hidden sl-mr-3 sl-rounded-lg"
style="background-color: transparent;">
<img src="{{ $metadata['logo'] }}" height="30px" width="30px" alt="logo">
</div>
@endif
<h4 class="sl-text-paragraph sl-leading-snug sl-font-prose sl-font-semibold sl-text-heading">
{{ $metadata['title'] }}
</h4>
</div>
<div class="sl-flex sl-overflow-y-auto sl-flex-col sl-flex-grow sl-flex-shrink">
<div class="sl-overflow-y-auto sl-w-full sl-bg-canvas-100">
<div class="sl-my-3">
@foreach($headings as $h1)
<div class="expandable">
<div title="{!! $h1['name'] !!}" id="toc-item-{!! $h1['slug'] !!}"
class="sl-flex sl-items-center sl-h-md sl-pr-4 sl-pl-4 sl-bg-canvas-100 hover:sl-bg-canvas-200 sl-cursor-pointer sl-select-none">
<a href="#{!! $h1['slug'] !!}"
class="sl-flex-1 sl-items-center sl-truncate sl-mr-1.5 sl-p-0">{!! $h1['name'] !!}</a>
@if(count($h1['subheadings']) > 0)
<div class="sl-flex sl-items-center sl-text-xs expansion-chevrons">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="chevron-right"
class="svg-inline--fa fa-chevron-right fa-fw sl-icon sl-text-muted"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M96 480c-8.188 0-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L242.8 256L73.38 86.63c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l192 192c12.5 12.5 12.5 32.75 0 45.25l-192 192C112.4 476.9 104.2 480 96 480z"></path>
</svg>
</div>
@endif
</div>
@if(count($h1['subheadings']) > 0)
<div class="children" style="display: none;">
@foreach($h1['subheadings'] as $h2)
<div class="expandable">
<div class="sl-flex sl-items-center sl-h-md sl-pr-4 sl-pl-8 sl-bg-canvas-100 hover:sl-bg-canvas-200 sl-cursor-pointer sl-select-none"
id="toc-item-{!! $h2['slug'] !!}">
<div class="sl-flex-1 sl-items-center sl-truncate sl-mr-1.5 sl-p-0" title="{!! $h2['name'] !!}">
<a class="ElementsTableOfContentsItem sl-block sl-no-underline"
href="#{!! $h2['slug'] !!}">
{!! $h2['name'] !!}
</a>
</div>
@if(count($h2['subheadings']) > 0)
<div class="sl-flex sl-items-center sl-text-xs expansion-chevrons">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="chevron-right"
class="svg-inline--fa fa-chevron-right fa-fw sl-icon sl-text-muted"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M96 480c-8.188 0-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L242.8 256L73.38 86.63c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l192 192c12.5 12.5 12.5 32.75 0 45.25l-192 192C112.4 476.9 104.2 480 96 480z"></path>
</svg>
</div>
@endif
</div>
@if(count($h2['subheadings']) > 0)
<div class="children" style="display: none;">
@foreach($h2['subheadings'] as $h3)
<a class="ElementsTableOfContentsItem sl-block sl-no-underline"
href="#{!! $h3['slug'] !!}">
<div title="{!! $h3['name'] !!}" id="toc-item-{!! $h3['slug'] !!}"
class="sl-flex sl-items-center sl-h-md sl-pr-4 sl-pl-12 sl-bg-canvas-100 hover:sl-bg-canvas-200 sl-cursor-pointer sl-select-none">
{!! $h3['name'] !!}
</div>
</a>
@endforeach
</div>
@endif
</div>
@endforeach
</div>
@endif
</div>
@endforeach
</div>
</div>
<div class="sl-flex sl-items-center sl-px-4 sl-py-3 sl-border-t">
{{ $metadata['last_updated'] }}
</div>
<div class="sl-flex sl-items-center sl-px-4 sl-py-3 sl-border-t">
<a href="http://github.com/knuckleswtf/scribe">Documentation powered by Scribe </a>
</div>
</div>
</div>

View File

@@ -0,0 +1,322 @@
@php
use Knuckles\Scribe\Tools\Utils as u;
/** @var \Knuckles\Camel\Output\OutputEndpointData $endpoint */
@endphp
<div class="sl-inverted">
<div class="sl-overflow-y-hidden sl-rounded-lg">
<form class="TryItPanel sl-bg-canvas-100 sl-rounded-lg"
data-method="{{ $endpoint->httpMethods[0] }}"
data-path="{{ $endpoint->uri }}"
data-hasfiles="{{ $endpoint->hasFiles() ? 1 : 0 }}"
data-hasjsonbody="{{ $endpoint->hasJsonBody() ? 1 : 0 }}">
@if($endpoint->isAuthed() && $metadata['auth']['location'] !== 'body')
<div class="sl-panel sl-outline-none sl-w-full expandable">
<div class="sl-panel__titlebar sl-flex sl-items-center sl-relative focus:sl-z-10 sl-text-base sl-leading-none sl-pr-4 sl-pl-3 sl-bg-canvas-200 sl-text-body sl-border-input focus:sl-border-primary sl-cursor-pointer sl-select-none"
role="button">
<div class="sl-flex sl-flex-1 sl-items-center sl-h-lg">
<div class="sl-flex sl-items-center sl-mr-1.5 expansion-chevrons expansion-chevrons-solid expanded">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="caret-down"
class="svg-inline--fa fa-caret-down fa-fw sl-icon" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M310.6 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z"></path>
</svg>
</div>
Auth
</div>
</div>
<div class="sl-panel__content-wrapper sl-bg-canvas-100 children" role="region">
<div class="ParameterGrid sl-p-4">
<label aria-hidden="true"
for="auth-{{ $endpoint->endpointId() }}">{{ $metadata['auth']['name'] }}</label>
<span class="sl-mx-3">:</span>
<div class="sl-flex sl-flex-1">
<div class="sl-input sl-flex-1 sl-relative">
<code>{{ $metadata['auth']['prefix'] }}</code>
<input aria-label="{{ $metadata['auth']['name'] }}"
id="auth-{{ $endpoint->endpointId() }}"
data-component="{{ $metadata['auth']['location'] }}"
data-prefix="{{ $metadata['auth']['prefix'] }}"
name="{{ $metadata['auth']['name'] }}"
placeholder="{{ $metadata['auth']['placeholder'] }}"
class="auth-value sl-relative {{ $metadata['auth']['prefix'] ? 'sl-w-3/5' : 'sl-w-full sl-pr-2.5 sl-pl-2.5' }} sl-h-md sl-text-base sl-rounded sl-border-transparent hover:sl-border-input focus:sl-border-primary sl-border">
</div>
</div>
</div>
</div>
</div>
@endif
@if(count($endpoint->headers))
<div class="sl-panel sl-outline-none sl-w-full expandable">
<div class="sl-panel__titlebar sl-flex sl-items-center sl-relative focus:sl-z-10 sl-text-base sl-leading-none sl-pr-4 sl-pl-3 sl-bg-canvas-200 sl-text-body sl-border-input focus:sl-border-primary sl-cursor-pointer sl-select-none"
role="button">
<div class="sl-flex sl-flex-1 sl-items-center sl-h-lg">
<div class="sl-flex sl-items-center sl-mr-1.5 expansion-chevrons expansion-chevrons-solid expanded">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="caret-down"
class="svg-inline--fa fa-caret-down fa-fw sl-icon" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M310.6 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z"></path>
</svg>
</div>
Headers
</div>
</div>
<div class="sl-panel__content-wrapper sl-bg-canvas-100 children" role="region">
<div class="ParameterGrid sl-p-4">
@foreach($endpoint->headers as $name => $example)
@php
if($endpoint->isAuthed() && $metadata['auth']['location'] === 'header' && $name === $metadata['auth']['name']) continue;
@endphp
<label aria-hidden="true"
for="header-{{ $endpoint->endpointId() }}-{{ $name }}">{{ $name }}</label>
<span class="sl-mx-3">:</span>
<div class="sl-flex sl-flex-1">
<div class="sl-input sl-flex-1 sl-relative">
<input aria-label="{{ $name }}" name="{{ $name }}"
id="header-{{ $endpoint->endpointId() }}-{{ $name }}"
value="{{ $example }}" data-component="header"
class="sl-relative sl-w-full sl-h-md sl-text-base sl-pr-2.5 sl-pl-2.5 sl-rounded sl-border-transparent hover:sl-border-input focus:sl-border-primary sl-border">
</div>
</div>
@endforeach
</div>
</div>
</div>
@endif
@if(count($endpoint->urlParameters))
<div class="sl-panel sl-outline-none sl-w-full expandable">
<div class="sl-panel__titlebar sl-flex sl-items-center sl-relative focus:sl-z-10 sl-text-base sl-leading-none sl-pr-4 sl-pl-3 sl-bg-canvas-200 sl-text-body sl-border-input focus:sl-border-primary sl-cursor-pointer sl-select-none"
role="button">
<div class="sl-flex sl-flex-1 sl-items-center sl-h-lg">
<div class="sl-flex sl-items-center sl-mr-1.5 expansion-chevrons expansion-chevrons-solid expanded">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="caret-down"
class="svg-inline--fa fa-caret-down fa-fw sl-icon" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M310.6 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z"></path>
</svg>
</div>
URL Parameters
</div>
</div>
<div class="sl-panel__content-wrapper sl-bg-canvas-100 children" role="region">
<div class="ParameterGrid sl-p-4">
@foreach($endpoint->urlParameters as $name => $parameter)
<label aria-hidden="true"
for="urlparam-{{ $endpoint->endpointId() }}-{{ $name }}">{{ $name }}</label>
<span class="sl-mx-3">:</span>
<div class="sl-flex sl-flex-1">
<div class="sl-input sl-flex-1 sl-relative">
<input aria-label="{{ $name }}" name="{{ $name }}"
id="urlparam-{{ $endpoint->endpointId() }}-{{ $name }}"
placeholder="{{ $parameter->description }}"
value="{{ $parameter->example }}" data-component="url"
class="sl-relative sl-w-full sl-h-md sl-text-base sl-pr-2.5 sl-pl-2.5 sl-rounded sl-border-transparent hover:sl-border-input focus:sl-border-primary sl-border">
</div>
</div>
@endforeach
</div>
</div>
</div>
@endif
@if(count($endpoint->queryParameters))
<div class="sl-panel sl-outline-none sl-w-full expandable">
<div class="sl-panel__titlebar sl-flex sl-items-center sl-relative focus:sl-z-10 sl-text-base sl-leading-none sl-pr-4 sl-pl-3 sl-bg-canvas-200 sl-text-body sl-border-input focus:sl-border-primary sl-cursor-pointer sl-select-none"
role="button">
<div class="sl-flex sl-flex-1 sl-items-center sl-h-lg">
<div class="sl-flex sl-items-center sl-mr-1.5 expansion-chevrons expansion-chevrons-solid expanded">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="caret-down"
class="svg-inline--fa fa-caret-down fa-fw sl-icon" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M310.6 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z"></path>
</svg>
</div>
Query Parameters
</div>
</div>
<div class="sl-panel__content-wrapper sl-bg-canvas-100 children" role="region">
<div class="ParameterGrid sl-p-4">
@foreach($endpoint->queryParameters as $name => $parameter)
@php
/** @var \Knuckles\Camel\Output\Parameter $parameter */
if ($parameter->type == 'object') // Skip; individual object children are listed
continue;
if (str_contains($name, "[]"))
// This likely belongs to an obj-array (eg objs[].a); we only show the parent (objs[]), so skip
continue;
if($endpoint->isAuthed() && $metadata['auth']['location'] === 'query'
&& $name === $metadata['auth']['name']) continue;
@endphp
<label aria-hidden="true"
for="queryparam-{{ $endpoint->endpointId() }}-{{ $name }}">{{ $name }}</label>
<span class="sl-mx-3">:</span>
<div class="sl-flex sl-flex-1">
<div class="sl-input sl-flex-1 sl-relative">
@if(str_ends_with($parameter->type, '[]'))
<input aria-label="{{ $name }}" name="{{ $name }}"
id="queryparam-{{ $endpoint->endpointId() }}-{{ $name }}"
placeholder="{{ $parameter->description }}"
value="{{ json_encode($parameter->example, JSON_HEX_TAG | JSON_HEX_AMP) }}" data-component="query"
class="sl-relative sl-w-full sl-h-md sl-text-base sl-pr-2.5 sl-pl-2.5 sl-rounded sl-border-transparent hover:sl-border-input focus:sl-border-primary sl-border"
>
@else
<input aria-label="{{ $name }}" name="{{ $name }}"
id="queryparam-{{ $endpoint->endpointId() }}-{{ $name }}"
placeholder="{{ $parameter->description }}"
value="{{ $parameter->example }}" data-component="query"
class="sl-relative sl-w-full sl-h-md sl-text-base sl-pr-2.5 sl-pl-2.5 sl-rounded sl-border-transparent hover:sl-border-input focus:sl-border-primary sl-border"
>
@endif
</div>
</div>
@endforeach
</div>
</div>
</div>
@endif
@if(count($endpoint->bodyParameters))
<div class="sl-panel sl-outline-none sl-w-full expandable">
<div class="sl-panel__titlebar sl-flex sl-items-center sl-relative focus:sl-z-10 sl-text-base sl-leading-none sl-pr-4 sl-pl-3 sl-bg-canvas-200 sl-text-body sl-border-input focus:sl-border-primary sl-cursor-pointer sl-select-none"
role="button">
<div class="sl-flex sl-flex-1 sl-items-center sl-h-lg">
<div class="sl-flex sl-items-center sl-mr-1.5 expansion-chevrons expansion-chevrons-solid expanded">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="caret-down"
class="svg-inline--fa fa-caret-down fa-fw sl-icon" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M310.6 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z"></path>
</svg>
</div>
Body
</div>
</div>
<div class="sl-panel__content-wrapper sl-bg-canvas-100 children" role="region">
@if($endpoint->hasJsonBody())
<div class="TextRequestBody sl-p-4">
<div class="code-editor language-json"
id="json-body-{{ $endpoint->endpointId() }}"
style="font-family: var(--font-code); font-size: 12px; line-height: var(--lh-code);"
>{!! json_encode($endpoint->getSampleBody(), JSON_PRETTY_PRINT | JSON_HEX_TAG | JSON_HEX_AMP) !!}</div>
</div>
@else
<div class="ParameterGrid sl-p-4">
@foreach($endpoint->bodyParameters as $name => $parameter)
@php
/** @var \Knuckles\Camel\Output\Parameter $parameter */
if ($parameter->type == 'object') // Skip; individual object children are listed
continue;
if (str_contains($name, "[]"))
// This likely belongs to an obj-array (eg objs[].a); we only show the parent (objs[]), so skip
continue;
@endphp
<label aria-hidden="true"
for="bodyparam-{{ $endpoint->endpointId() }}-{{ $name }}">{{ $name }}</label>
<span class="sl-mx-3">:</span>
<div class="sl-flex sl-flex-1">
<div class="sl-input sl-flex-1 sl-relative">
@if($parameter->type == 'file')
<input aria-label="{{ $name }}" name="{{ $name }}"
id="bodyparam-{{ $endpoint->endpointId() }}-{{ $name }}"
type="file" data-component="body"
class="sl-relative sl-w-full sl-h-md sl-text-base sl-pr-2.5 sl-pl-2.5 sl-rounded sl-border-transparent hover:sl-border-input focus:sl-border-primary sl-border"
>
@elseif(str_ends_with($parameter->type, '[]'))
<input aria-label="{{ $name }}" name="{{ $name }}"
id="bodyparam-{{ $endpoint->endpointId() }}-{{ $name }}"
placeholder="{{ $parameter->description }}"
value="{{ json_encode($parameter->example, JSON_HEX_TAG | JSON_HEX_AMP) }}" data-component="body"
class="sl-relative sl-w-full sl-h-md sl-text-base sl-pr-2.5 sl-pl-2.5 sl-rounded sl-border-transparent hover:sl-border-input focus:sl-border-primary sl-border"
>
@else
<input aria-label="{{ $name }}" name="{{ $name }}"
id="bodyparam-{{ $endpoint->endpointId() }}-{{ $name }}"
placeholder="{{ $parameter->description }}"
value="{{ $parameter->example }}" data-component="body"
class="sl-relative sl-w-full sl-h-md sl-text-base sl-pr-2.5 sl-pl-2.5 sl-rounded sl-border-transparent hover:sl-border-input focus:sl-border-primary sl-border"
>
@endif
</div>
</div>
@endforeach
</div>
@endif
</div>
</div>
@endif
<div class="SendButtonHolder sl-mt-4 sl-p-4 sl-pt-0">
<div class="sl-stack sl-stack--horizontal sl-stack--2 sl-flex sl-flex-row sl-items-center">
<button type="button" data-endpoint="{{ $endpoint->endpointId() }}"
class="tryItOut-btn sl-button sl-h-sm sl-text-base sl-font-medium sl-px-1.5 sl-bg-primary hover:sl-bg-primary-dark active:sl-bg-primary-darker disabled:sl-bg-canvas-100 sl-text-on-primary disabled:sl-text-body sl-rounded sl-border-transparent sl-border disabled:sl-opacity-70"
>
{{ u::trans("scribe::try_it_out.send") }}
</button>
</div>
</div>
<div data-endpoint="{{ $endpoint->endpointId() }}"
class="tryItOut-error expandable sl-panel sl-outline-none sl-w-full" hidden>
<div class="sl-panel__titlebar sl-flex sl-items-center sl-relative focus:sl-z-10 sl-text-base sl-leading-none sl-pr-4 sl-pl-3 sl-bg-canvas-200 sl-text-body sl-border-input focus:sl-border-primary sl-cursor-pointer sl-select-none"
role="button">
<div class="sl-flex sl-flex-1 sl-items-center sl-h-lg">
<div class="sl-flex sl-items-center sl-mr-1.5 expansion-chevrons expansion-chevrons-solid expanded">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="caret-down"
class="svg-inline--fa fa-caret-down fa-fw sl-icon" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M310.6 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z"></path>
</svg>
</div>
{{ u::trans("scribe::try_it_out.request_failed") }}
</div>
</div>
<div class="sl-panel__content-wrapper sl-bg-canvas-100 children" role="region">
<div class="sl-panel__content sl-p-4">
<p class="sl-pb-2"><strong class="error-message"></strong></p>
<p class="sl-pb-2">{{ u::trans("scribe::try_it_out.error_help") }}</p>
</div>
</div>
</div>
<div data-endpoint="{{ $endpoint->endpointId() }}"
class="tryItOut-response expandable sl-panel sl-outline-none sl-w-full" hidden>
<div class="sl-panel__titlebar sl-flex sl-items-center sl-relative focus:sl-z-10 sl-text-base sl-leading-none sl-pr-4 sl-pl-3 sl-bg-canvas-200 sl-text-body sl-border-input focus:sl-border-primary sl-cursor-pointer sl-select-none"
role="button">
<div class="sl-flex sl-flex-1 sl-items-center sl-h-lg">
<div class="sl-flex sl-items-center sl-mr-1.5 expansion-chevrons expansion-chevrons-solid expanded">
<svg aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="caret-down"
class="svg-inline--fa fa-caret-down fa-fw sl-icon" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor"
d="M310.6 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z"></path>
</svg>
</div>
{{ u::trans("scribe::try_it_out.received_response") }}
</div>
</div>
<div class="sl-panel__content-wrapper sl-bg-canvas-100 children" role="region">
<div class="sl-panel__content sl-p-4">
<p class="sl-pb-2 response-status"></p>
<pre><code class="sl-pb-2 response-content language-json"
data-empty-response-text="<{{ u::trans("scribe::endpoint.responses.empty") }}>"
style="max-height: 300px;"></code></pre>
</div>
</div>
</div>
</form>
</div>
</div>

View File

@@ -0,0 +1,21 @@
<?php
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Storage;
$prefix = config('scribe.laravel.docs_url', '/docs');
$middleware = config('scribe.laravel.middleware', []);
Route::middleware($middleware)
->group(function () use ($prefix) {
Route::view($prefix, 'scribe.index')->name('scribe');
Route::get("{$prefix}.postman", function () {
return new JsonResponse(Storage::disk('local')->get('scribe/collection.json'), json: true);
})->name('scribe.postman');
Route::get("{$prefix}.openapi", function () {
return response()->file(Storage::disk('local')->path('scribe/openapi.yaml'));
})->name('scribe.openapi');
});

View File

@@ -0,0 +1,16 @@
<?php
namespace Knuckles\Scribe\Attributes;
#[\Attribute(\Attribute::TARGET_FUNCTION | \Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)]
class Authenticated
{
public function __construct(
public ?bool $authenticated = true,
) {}
public function toArray()
{
return ['authenticated' => $this->authenticated];
}
}

View File

@@ -0,0 +1,6 @@
<?php
namespace Knuckles\Scribe\Attributes;
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_FUNCTION | \Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)]
class BodyParam extends GenericParam {}

View File

@@ -0,0 +1,16 @@
<?php
namespace Knuckles\Scribe\Attributes;
#[\Attribute(\Attribute::TARGET_FUNCTION | \Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)]
class Deprecated
{
public function __construct(
public bool|string|null $deprecated = true,
) {}
public function toArray()
{
return ['deprecated' => $this->deprecated];
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace Knuckles\Scribe\Attributes;
use Attribute;
#[Attribute(Attribute::TARGET_FUNCTION | Attribute::TARGET_METHOD | Attribute::TARGET_CLASS)]
class Endpoint
{
public function __construct(
public string $title,
public ?string $description = '',
/** You can use the separate #[Authenticated] attribute, or pass authenticated: false to this. */
public ?bool $authenticated = null,
) {}
public function toArray()
{
$data = [
'title' => $this->title,
'description' => $this->description,
];
if (! is_null($this->authenticated)) {
$data['authenticated'] = $this->authenticated;
}
return $data;
}
}

View File

@@ -0,0 +1,57 @@
<?php
namespace Knuckles\Scribe\Attributes;
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_FUNCTION | \Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)]
class GenericParam
{
public function __construct(
public string $name,
public ?string $type = 'string',
public ?string $description = '',
public ?bool $required = true,
public mixed $example = null, // Pass 'No-example' to omit the example
public mixed $enum = null, // Can pass a list of values, or a native PHP enum
public ?bool $nullable = false,
public ?bool $deprecated = false,
) {}
public function toArray()
{
return [
'name' => $this->name,
'description' => $this->description,
'type' => $this->type,
'required' => $this->required,
'example' => $this->example,
'enumValues' => $this->getEnumValues(),
'nullable' => $this->nullable,
'deprecated' => $this->deprecated,
];
}
protected function getEnumValues(): array
{
if (! $this->enum) {
return [];
}
if (is_array($this->enum)) {
return $this->enum;
}
if (enum_exists($this->enum) && method_exists($this->enum, 'tryFrom')) {
return array_map(
// $case->value only exists on BackedEnums, not UnitEnums
// method_exists($enum, 'tryFrom') implies the enum is a BackedEnum
// @phpstan-ignore-next-line
fn ($case) => $case->value,
$this->enum::cases()
);
}
throw new \InvalidArgumentException(
'The enum property of a parameter must be either a PHP enum or an array of values'
);
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace Knuckles\Scribe\Attributes;
use Attribute;
#[Attribute(Attribute::TARGET_FUNCTION | Attribute::TARGET_METHOD | Attribute::TARGET_CLASS)]
class Group
{
public function __construct(
public mixed $name,
public ?string $description = '',
/** You can use the separate #[Authenticated] attribute, or pass authenticated: false to this. */
public ?bool $authenticated = null,
) {}
public function toArray()
{
$data = [
'groupName' => $this->getName(),
'groupDescription' => $this->description,
];
if (! is_null($this->authenticated)) {
$data['authenticated'] = $this->authenticated;
}
return $data;
}
protected function getName(): string
{
if (is_string($this->name)) {
return $this->name;
}
if (interface_exists('BackedEnum') && is_a($this->name, 'BackedEnum')) {
return $this->name->value;
}
throw new \InvalidArgumentException(
'The name property of a group must be either a PHP Backed Enum or a string'
);
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace Knuckles\Scribe\Attributes;
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_FUNCTION | \Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)]
class Header
{
public function __construct(
public string $name,
public mixed $example = null,
) {}
public function toArray()
{
return [
'name' => $this->name,
'example' => $this->example,
];
}
}

View File

@@ -0,0 +1,6 @@
<?php
namespace Knuckles\Scribe\Attributes;
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_FUNCTION | \Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)]
class QueryParam extends GenericParam {}

View File

@@ -0,0 +1,26 @@
<?php
namespace Knuckles\Scribe\Attributes;
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_FUNCTION | \Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)]
class Response
{
public function __construct(
public array|string|null $content = null,
public int $status = 200,
public ?string $description = '',
) {}
public function toArray()
{
return [
'status' => $this->status,
'content' => match (true) {
is_null($this->content) => null,
is_string($this->content) => $this->content,
default => json_encode($this->content, JSON_THROW_ON_ERROR),
},
'description' => $this->description,
];
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace Knuckles\Scribe\Attributes;
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_FUNCTION | \Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)]
class ResponseField extends GenericParam
{
// Don't default to string; type inference is currently handled by the normalizer
// TODO change this in the future
public function __construct(
public string $name,
public ?string $type = null,
public ?string $description = '',
public ?bool $required = true,
public mixed $example = null, // Pass 'No-example' to omit the example
public mixed $enum = null, // Can pass a list of values, or a native PHP enum,
public ?bool $nullable = false,
public ?bool $deprecated = false,
) {}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace Knuckles\Scribe\Attributes;
use Illuminate\Http\Resources\Json\ResourceCollection;
use Knuckles\Scribe\Extracting\Shared\ApiResourceResponseTools;
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_FUNCTION | \Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)]
class ResponseFromApiResource
{
public function __construct(
public string $name,
public ?string $model = null,
public int $status = 200,
public ?string $description = '',
// Mark if this should be used as a collection. Only needed if not using a ResourceCollection.
public ?bool $collection = null,
public array $factoryStates = [],
public array $with = [],
public ?int $paginate = null,
public ?int $simplePaginate = null,
public ?int $cursorPaginate = null,
public array $additional = [],
public array $withCount = [],
) {}
public function modelToBeTransformed(): ?string
{
if (! empty($this->model)) {
return $this->model;
}
return ApiResourceResponseTools::tryToInferApiResourceModel($this->name);
}
public function isCollection(): bool
{
if (! is_null($this->collection)) {
return $this->collection;
}
return is_subclass_of($this->name, ResourceCollection::class);
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace Knuckles\Scribe\Attributes;
use Knuckles\Scribe\Extracting\Shared\ResponseFileTools;
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_FUNCTION | \Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)]
class ResponseFromFile
{
public function __construct(
public string $file,
public int $status = 200,
public array|string $merge = [],
public ?string $description = '',
) {}
public function toArray()
{
return [
'status' => $this->status,
'description' => $this->description,
'content' => ResponseFileTools::getResponseContents($this->file, $this->merge),
];
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Knuckles\Scribe\Attributes;
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_FUNCTION | \Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)]
class ResponseFromTransformer
{
public function __construct(
public string $name,
public ?string $model = null,
public int $status = 200,
public ?string $description = '',
// Mark if this should be used as a collection. Only needed if not using a CollectionTransformer.
public bool $collection = false,
public array $factoryStates = [],
public array $with = [],
public ?string $resourceKey = null,
// Format: [adapter, numberPerPage]. Example: [SomePaginator::class, 10]
public array $paginate = [],
) {}
}

View File

@@ -0,0 +1,35 @@
<?php
namespace Knuckles\Scribe\Attributes;
#[\Attribute(\Attribute::TARGET_FUNCTION | \Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)]
class Subgroup
{
public function __construct(
public mixed $name,
public ?string $description = '',
) {}
public function toArray()
{
return [
'subgroup' => $this->getName(),
'subgroupDescription' => $this->description,
];
}
protected function getName(): string
{
if (is_string($this->name)) {
return $this->name;
}
if (interface_exists('BackedEnum') && is_a($this->name, 'BackedEnum')) {
return $this->name->value;
}
throw new \InvalidArgumentException(
'The name property of a subgroup must be either a PHP Backed Enum or a string'
);
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace Knuckles\Scribe\Attributes;
#[\Attribute(\Attribute::TARGET_FUNCTION | \Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)]
class Unauthenticated
{
public function toArray()
{
return ['authenticated' => false];
}
}

View File

@@ -0,0 +1,6 @@
<?php
namespace Knuckles\Scribe\Attributes;
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_FUNCTION | \Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)]
class UrlParam extends GenericParam {}

View File

@@ -0,0 +1,35 @@
<?php
namespace Knuckles\Scribe\Commands;
use Illuminate\Console\Command;
use Knuckles\Scribe\Tools\ConfigDiffer;
class DiffConfig extends Command
{
protected $signature = 'scribe:config:diff {--config=scribe : choose which config file to use}';
protected $description = 'Dump your changed config to the console. Use this when posting bug reports';
public function handle(): void
{
$usersConfig = config($this->option('config'));
$defaultConfig = require __DIR__.'/../../config/scribe.php';
$ignore = ['example_languages', 'routes', 'description', 'auth.extra_info', 'intro_text', 'groups'];
$asList = ['strategies.*', 'examples.models_source'];
$differ = new ConfigDiffer(original: $defaultConfig, changed: $usersConfig, ignorePaths: $ignore, asList: $asList);
$diff = $differ->getDiff();
if (empty($diff)) {
$this->info('------ SAME AS DEFAULT CONFIG ------');
return;
}
foreach ($diff as $key => $item) {
$this->line("{$key} => {$item}");
}
}
}

View File

@@ -0,0 +1,257 @@
<?php
namespace Knuckles\Scribe\Commands;
use Illuminate\Console\Command;
use Illuminate\Console\View\Components\Factory;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Str;
use Knuckles\Camel\Camel;
use Knuckles\Scribe\GroupedEndpoints\GroupedEndpointsFactory;
use Knuckles\Scribe\Matching\RouteMatcherInterface;
use Knuckles\Scribe\Scribe;
use Knuckles\Scribe\Tools\ConfigDiffer;
use Knuckles\Scribe\Tools\ConsoleOutputUtils as c;
use Knuckles\Scribe\Tools\DocumentationConfig;
use Knuckles\Scribe\Tools\ErrorHandlingUtils as e;
use Knuckles\Scribe\Tools\Globals;
use Knuckles\Scribe\Tools\PathConfig;
use Knuckles\Scribe\Writing\Writer;
class GenerateDocumentation extends Command
{
protected $signature = "scribe:generate
{--force : Discard any changes you've made to the YAML or Markdown files}
{--no-extraction : Skip extraction of route and API info and just transform the YAML and Markdown files into HTML}
{--no-upgrade-check : Skip checking for config file upgrades. Won't make things faster, but can be helpful if the command is buggy}
{--config=scribe : Choose which config file to use}
{--scribe-dir= : Specify the directory where Scribe stores its intermediate output and cache. Defaults to `.<config_file>`}
";
protected $description = 'Generate API documentation from your Laravel routes.';
protected DocumentationConfig $docConfig;
protected bool $shouldExtract;
protected bool $forcing;
protected PathConfig $paths;
public function handle(RouteMatcherInterface $routeMatcher, GroupedEndpointsFactory $groupedEndpointsFactory): void
{
$this->bootstrap();
if (! empty($this->docConfig->get('default_group'))) {
$this->warn('It looks like you just upgraded to Scribe v4.');
$this->warn('Please run the upgrade command first: `php artisan scribe:upgrade`.');
exit(1);
}
// Extraction stage - extract endpoint info either from app or existing Camel files (previously extracted data)
$groupedEndpointsInstance = $groupedEndpointsFactory->make($this, $routeMatcher, $this->paths);
$extractedEndpoints = $groupedEndpointsInstance->get();
$userDefinedEndpoints = Camel::loadUserDefinedEndpoints(Camel::camelDir($this->paths));
$groupedEndpoints = $this->mergeUserDefinedEndpoints($extractedEndpoints, $userDefinedEndpoints);
// Output stage
$configFileOrder = $this->docConfig->get('groups.order', []);
$groupedEndpoints = Camel::prepareGroupedEndpointsForOutput($groupedEndpoints, $configFileOrder);
if (! count($userDefinedEndpoints)) {
// Update the example custom file if there were no custom endpoints
$this->writeExampleCustomEndpoint();
}
/** @var Writer $writer */
$writer = app(Writer::class, ['config' => $this->docConfig, 'paths' => $this->paths]);
$writer->writeDocs($groupedEndpoints);
// Retiring the automatic upgrade check, since the config file is no longer changing as frequently.
// $this->upgradeConfigFileIfNeeded();
$this->sayGoodbye(errored: $groupedEndpointsInstance->hasEncounteredErrors());
}
public function isForcing(): bool
{
return $this->forcing;
}
public function shouldExtract(): bool
{
return $this->shouldExtract;
}
public function getDocConfig(): DocumentationConfig
{
return $this->docConfig;
}
/**
* Get access to output components for task-based output.
*
* @return Factory
*/
public function outputComponents()
{
return $this->components;
}
public function bootstrap(): void
{
// The --verbose option is included with all Artisan commands.
Globals::$shouldBeVerbose = $this->option('verbose');
c::bootstrapOutput($this->output);
c::setCommand($this);
$configName = $this->option('config');
if (! config($configName)) {
throw new \InvalidArgumentException("The specified config (config/{$configName}.php) doesn't exist.");
}
$this->paths = new PathConfig($configName);
if ($this->hasOption('scribe-dir') && ! empty($this->option('scribe-dir'))) {
$this->paths = new PathConfig(
$configName,
scribeDir: $this->option('scribe-dir')
);
}
$this->docConfig = new DocumentationConfig(config($this->paths->configName));
// Force root URL so it works in Postman collection
$baseUrl = $this->docConfig->get('base_url') ?? config('app.url');
try {
// Renamed from forceRootUrl in Laravel 11.43 or so
URL::useOrigin($baseUrl);
} catch (\BadMethodCallException) {
URL::forceRootUrl($baseUrl);
}
$this->forcing = $this->option('force');
$this->shouldExtract = ! $this->option('no-extraction');
if ($this->forcing && ! $this->shouldExtract) {
throw new \InvalidArgumentException("Can't use --force and --no-extraction together.");
}
$this->runBootstrapHook();
}
protected function runBootstrapHook()
{
if (is_callable(Globals::$__bootstrap)) {
call_user_func_array(Globals::$__bootstrap, [$this]);
}
}
protected function mergeUserDefinedEndpoints(array $groupedEndpoints, array $userDefinedEndpoints): array
{
foreach ($userDefinedEndpoints as $endpoint) {
$indexOfGroupWhereThisEndpointShouldBeAdded = Arr::first(array_keys($groupedEndpoints), function ($key) use ($groupedEndpoints, $endpoint) {
$group = $groupedEndpoints[$key];
return $group['name'] === ($endpoint['metadata']['groupName'] ?? $this->docConfig->get('groups.default', ''));
});
if ($indexOfGroupWhereThisEndpointShouldBeAdded !== null) {
$groupedEndpoints[$indexOfGroupWhereThisEndpointShouldBeAdded]['endpoints'][] = $endpoint;
} else {
$newGroup = [
'name' => $endpoint['metadata']['groupName'] ?? $this->docConfig->get('groups.default', ''),
'description' => $endpoint['metadata']['groupDescription'] ?? null,
'endpoints' => [$endpoint],
];
$groupedEndpoints[$newGroup['name']] = $newGroup;
}
}
return $groupedEndpoints;
}
protected function writeExampleCustomEndpoint(): void
{
// We add an example to guide users in case they need to add a custom endpoint.
copy(__DIR__.'/../../resources/example_custom_endpoint.yaml', Camel::camelDir($this->paths).'/custom.0.yaml');
}
protected function upgradeConfigFileIfNeeded(): void
{
if ($this->option('no-upgrade-check')) {
return;
}
$this->info('Checking for any pending upgrades to your config file...');
try {
$defaultConfig = require __DIR__.'/../../config/scribe.php';
$ignore = ['example_languages', 'routes', 'description', 'auth.extra_info', 'intro_text', 'groups', 'database_connections_to_transact'];
$asList = ['strategies.*', 'examples.models_source'];
$differ = new ConfigDiffer(original: $this->docConfig->data, changed: $defaultConfig, ignorePaths: $ignore, asList: $asList);
$diff = $differ->getDiff();
// Remove items the user has set
$realDiff = [];
foreach ($diff as $key => $value) {
if (is_null($this->docConfig->get($key))) {
$realDiff[$key] = $value;
}
}
if (! empty($realDiff)) {
$this->newLine();
$this->warn("You're using an updated version of Scribe, which may have added new items to the config file.");
$this->info("Here's what is different:");
foreach ($realDiff as $key => $item) {
$this->line("{$key} --now defaults to-> {$item}");
}
if (! $this->input->isInteractive()) {
$this->info(sprintf('To upgrade, see the full changelog at: https://github.com/knuckleswtf/scribe/blob/%s/CHANGELOG.md,', Scribe::VERSION));
$this->info('And config reference at https://scribe.knuckles.wtf/laravel/reference/config');
return;
}
}
} catch (\Throwable $e) {
$this->warn('Check failed with error:');
e::dumpExceptionIfVerbose($e);
$this->warn('This did not affect your docs. Please report this issue in the project repo: https://github.com/knuckleswtf/scribe');
}
}
protected function sayGoodbye(bool $errored = false): void
{
$message = 'All done.';
$url = null;
if ($this->docConfig->outputRoutedThroughLaravel()) {
if ($this->docConfig->get('laravel.add_routes')) {
$url = url($this->docConfig->get('laravel.docs_url'));
}
} elseif (Str::endsWith(base_path('public'), 'public') && Str::startsWith($this->docConfig->get('static.output_path'), 'public/')) {
$url = url(str_replace('public/', '', $this->docConfig->get('static.output_path')));
}
$this->newLine();
if ($url) {
$this->components->twoColumnDetail($message, $url);
} else {
$this->components->info($message);
}
if ($errored) {
$this->components->warn('Generated docs, but encountered some errors while processing routes.');
$this->components->warn('Check the output above for details.');
if (empty($_SERVER['SCRIBE_TESTS'])) {
exit(2);
}
}
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace Knuckles\Scribe\Commands;
use Illuminate\Console\GeneratorCommand;
class MakeStrategy extends GeneratorCommand
{
protected $signature = 'scribe:strategy
{name : Name of the class.}
{--force : Overwrite file if it exists}
';
protected $description = 'Create a new strategy class.';
protected $type = 'Strategy';
protected function getStub()
{
return __DIR__.'/stubs/strategy.stub';
}
protected function getDefaultNamespace($rootNamespace)
{
return $rootNamespace.'\Docs\Strategies';
}
protected function replaceClass($stub, $name)
{
return parent::replaceClass($stub, $name);
}
}

View File

@@ -0,0 +1,182 @@
<?php
namespace Knuckles\Scribe\Commands;
use Illuminate\Console\Command;
use Knuckles\Camel\Camel;
use Knuckles\Scribe\GroupedEndpoints\GroupedEndpointsFactory;
use Knuckles\Scribe\Scribe;
use Knuckles\Scribe\Tools\PathConfig;
use Shalvah\Upgrader\Upgrader;
use Symfony\Component\VarExporter\VarExporter;
class Upgrade extends Command
{
protected $signature = 'scribe:upgrade {--dry-run : Print the changes that will be made, without actually making them}
{--config=scribe : choose which config file to use}
';
protected $description = '';
protected bool $applyChanges;
protected string $configName;
public function handle(): void
{
$this->applyChanges = ! $this->option('dry-run');
$this->configName = $this->option('config');
if (! ($oldConfig = config($this->configName))) {
$this->error("The specified config (config/{$this->configName}.php) doesn't exist.");
return;
}
if (array_key_exists('interactive', $oldConfig)) {
$this->error("This upgrade tool is for upgrading from Scribe v3 to v4, but it looks like you're coming from v2.");
$this->error('Please install v3 and follow its upgrade guide first.');
return;
}
$isMajorUpgrade = array_key_exists('default_group', $oldConfig) || array_key_exists('faker_seed', $oldConfig);
if ($isMajorUpgrade) {
$this->info('Welcome to the Scribe v3 to v4 upgrader.');
}
$this->line('Checking for config file changes...');
$upgrader = Upgrader::ofConfigFile("config/{$this->configName}.php", __DIR__.'/../../config/scribe.php')
->dontTouch(
'routes',
'laravel.middleware',
'postman.overrides',
'openapi.overrides',
'example_languages',
'database_connections_to_transact',
'strategies',
'examples.models_source',
'external.html_attributes'
)
->move('default_group', 'groups.default')
->move('faker_seed', 'examples.faker_seed');
if (! $isMajorUpgrade) {
$upgrader->dontTouch('groups');
}
$changes = $upgrader->dryRun();
if (empty($changes)) {
$this->info('✔ No config file changes needed.');
} else {
$this->info('The following changes will be made to your config file:');
$this->newLine();
foreach ($changes as $change) {
$this->line($change['description']);
}
if ($this->applyChanges) {
$upgrader->upgrade();
$this->info("✔ Upgraded your config file. Your old config is backed up at config/{$this->configName}.php.bak.");
}
}
$this->newLine();
if (! $isMajorUpgrade) {
$this->info('✔ Done.');
$this->info(sprintf('See the full changelog at https://github.com/knuckleswtf/scribe/blob/%s/CHANGELOG.md', Scribe::VERSION));
return;
}
$this->finishV4Upgrade();
}
protected function finishV4Upgrade(): void
{
$this->migrateToConfigFileSort();
if ($this->applyChanges) {
if ($this->confirm('Do you have any custom strategies?')) {
$this->line('1. Add a new property <info>public ?ExtractedEndpointData $endpointData;</info>.');
$this->line('2. Replace the <info>array $routeRules</info> parameter in __invoke() with <info>array $routeRules = []</info> .');
}
$this->newLine();
$this->info('✔ Done.');
}
$this->line('See the release announcement at <href=https://scribe.knuckles.wtf/blog/laravel-v4>http://scribe.knuckles.wtf/blog/laravel-v4</> for the full upgrade guide!');
}
/**
* In v3, you sorted endpoints by reordering them in the group file, and groups by renaming the group files alphabetically
* (or by using `beforeGroup`/`afterGroup` for custom endpoints).
* v4 replaces them with the config item `groups.order`.
*/
protected function migrateToConfigFileSort()
{
$this->info('In v3, you sorted endpoints/groups by editing/renaming the generated YAML files (or `beforeGroup`/`afterGroup` for custom endpoints).');
$this->info("We'll automatically import your current sorting into the config item `groups.order`.");
$defaultGroup = config($this->configName.'.default_group');
$pathConfig = new PathConfig($this->configName);
$extractedEndpoints = GroupedEndpointsFactory::fromCamelDir($pathConfig)->get();
$order = array_map(function (array $group) {
return array_map(function (array $endpoint) {
return $endpoint['metadata']['title'] ?: ($endpoint['httpMethods'][0].' /'.$endpoint['uri']);
}, $group['endpoints']);
}, $extractedEndpoints);
$groupsOrder = array_keys($order);
$keyIndices = array_flip($groupsOrder);
$userDefinedEndpoints = Camel::loadUserDefinedEndpoints(Camel::camelDir($pathConfig));
if ($userDefinedEndpoints) {
foreach ($userDefinedEndpoints as $endpoint) {
$groupName = $endpoint['metadata']['groupName'] ?? $defaultGroup;
$endpointTitle = $endpoint['metadata']['title'] ?? ($endpoint['httpMethods'][0].' /'.$endpoint['uri']);
if (! isset($order[$groupName])) {
// This is a new group; place it at the right spot.
if ($nextGroup = $endpoint['metadata']['beforeGroup'] ?? null) {
$index = $keyIndices[$nextGroup];
array_splice($groupsOrder, $index, 0, [$groupName]);
} elseif ($previousGroup = $endpoint['metadata']['afterGroup'] ?? null) {
$index = $keyIndices[$previousGroup];
array_splice($groupsOrder, $index + 1, 0, [$groupName]);
} else {
$groupsOrder[] = $groupName;
}
$order[$groupName] = [$endpointTitle];
} else {
// Existing group, add endpoint
$order[$groupName] = [...$order[$groupName], $endpointTitle];
}
}
}
// Re-add them, so it's sorted in the right order
$newOrder = [];
foreach ($groupsOrder as $groupName) {
$newOrder[$groupName] = $order[$groupName];
}
$output = VarExporter::export($newOrder);
if ($this->applyChanges) {
$configFile = "config/{$this->configName}.php";
$output = str_replace("\n", "\n ", $output);
$newContents = str_replace(
"'order' => [],",
"'order' => {$output},",
file_get_contents($configFile)
);
file_put_contents($configFile, $newContents);
$this->info('✔ Updated `groups.order`.');
} else {
$this->line('- `groups.order` will be set to:');
$this->info($output);
}
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace DummyNamespace;
use Knuckles\Scribe\Extracting\ParamHelpers;
use Knuckles\Scribe\Extracting\Strategies\Strategy;
use Knuckles\Camel\Extraction\ExtractedEndpointData;
class DummyClass extends Strategy
{
/**
* Trait containing some helper methods for dealing with "parameters",
* such as generating examples and casting values to types.
* Useful if your strategy extracts information about parameters or generates examples.
*/
use ParamHelpers;
/**
* @link https://scribe.knuckles.wtf/laravel/advanced/plugins
* @param ExtractedEndpointData $endpointData The endpoint we are currently processing.
* Contains details about httpMethods, controller, method, route, url, etc, as well as already extracted data.
* @param array $settings Settings to be applied to this strategy
*
* See the documentation linked above for more details about writing custom strategies.
*
* @return array|null
*/
public function __invoke(ExtractedEndpointData $endpointData, array $settings = []): ?array
{
return [];
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Knuckles\Scribe\Config;
enum AuthIn: string
{
case BEARER = 'bearer';
case BASIC = 'basic';
case HEADER = 'header';
case QUERY = 'query';
case BODY = 'body';
case QUERY_OR_BODY = 'query_or_body';
}

View File

@@ -0,0 +1,52 @@
<?php
namespace Knuckles\Scribe\Config;
use Knuckles\Scribe\Extracting\Strategies;
class Defaults
{
public const METADATA_STRATEGIES = [
Strategies\Metadata\GetFromDocBlocks::class,
Strategies\Metadata\GetFromMetadataAttributes::class,
];
public const HEADERS_STRATEGIES = [
Strategies\Headers\GetFromHeaderAttribute::class,
Strategies\Headers\GetFromHeaderTag::class,
];
public const URL_PARAMETERS_STRATEGIES = [
Strategies\UrlParameters\GetFromLaravelAPI::class,
Strategies\UrlParameters\GetFromUrlParamAttribute::class,
Strategies\UrlParameters\GetFromUrlParamTag::class,
];
public const QUERY_PARAMETERS_STRATEGIES = [
Strategies\QueryParameters\GetFromFormRequest::class,
Strategies\QueryParameters\GetFromInlineValidator::class,
Strategies\QueryParameters\GetFromQueryParamAttribute::class,
Strategies\QueryParameters\GetFromQueryParamTag::class,
];
public const BODY_PARAMETERS_STRATEGIES = [
Strategies\BodyParameters\GetFromFormRequest::class,
Strategies\BodyParameters\GetFromInlineValidator::class,
Strategies\BodyParameters\GetFromBodyParamAttribute::class,
Strategies\BodyParameters\GetFromBodyParamTag::class,
];
public const RESPONSES_STRATEGIES = [
Strategies\Responses\UseResponseAttributes::class,
Strategies\Responses\UseTransformerTags::class,
Strategies\Responses\UseApiResourceTags::class,
Strategies\Responses\UseResponseTag::class,
Strategies\Responses\UseResponseFileTag::class,
Strategies\Responses\ResponseCalls::class,
];
public const RESPONSE_FIELDS_STRATEGIES = [
Strategies\ResponseFields\GetFromResponseFieldAttribute::class,
Strategies\ResponseFields\GetFromResponseFieldTag::class,
];
}

View File

@@ -0,0 +1,58 @@
<?php
namespace Knuckles\Scribe\Config;
use Illuminate\Support\Arr;
// Strategies can be:
// 1. (Original) A class name, e.g. Strategies\Responses\ResponseCalls::class
// 2. (New) A tuple containing the class name (or "static_data") as item 1, and its settings array as item 2
/**
* Remove one or more strategies from a list of strategies.
*/
function removeStrategies(array $strategiesList, array $strategyNamesToRemove): array
{
$correspondingStrategies = Arr::where($strategiesList, function ($strategy) use ($strategyNamesToRemove) {
$strategyName = is_string($strategy) ? $strategy : $strategy[0];
return in_array($strategyName, $strategyNamesToRemove);
});
foreach ($correspondingStrategies as $key => $value) {
unset($strategiesList[$key]);
}
return $strategiesList;
}
/**
* Add/replace a strategy and its settings in a list of strategies.
* This method generates a tuple containing [strategyName, settingsArray],
* and adds or replaces the strategy entry in the list.
*
* @param array $configurationTuple Tuple of [strategyName, settingsArray].
* By default, all strategies support the "only" and "except" setting to apply them to specific endpoints.
* You can easily create the tuple by calling Strategy::wrapWithSettings(only: [], except: []).
*/
function configureStrategy(array $strategiesList, array $configurationTuple): array
{
$strategyFound = false;
$strategiesList = array_map(function ($strategy) use ($configurationTuple, &$strategyFound) {
$strategyName = is_string($strategy) ? $strategy : $strategy[0];
if ($strategyName === $configurationTuple[0]) {
$strategyFound = true;
return $configurationTuple;
}
return $strategy;
}, $strategiesList);
// If strategy wasn't in there, add it.
if (! $strategyFound) {
$strategiesList = array_merge($strategiesList, [$configurationTuple]);
}
return $strategiesList;
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Knuckles\Scribe\Exceptions;
class CouldntFindFactory extends \RuntimeException implements ScribeException
{
public static function forModel(string $modelName): self
{
return new self("Couldn't find the Eloquent model factory. Did you add the HasFactory trait to your {$modelName} model?");
}
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Knuckles\Scribe\Exceptions;
class CouldntGetRouteDetails extends \RuntimeException implements ScribeException
{
public static function new(): self
{
return new self('Unable to retrieve controller and method for route; try running `php artisan route:clear`');
}
}

View File

@@ -0,0 +1,15 @@
<?php
namespace Knuckles\Scribe\Exceptions;
class CouldntProcessValidationRule extends \RuntimeException implements ScribeException
{
public static function forParam(string $paramName, $rule, \Throwable $innerException): self
{
return new self(
"Couldn't process the validation rule ".var_export($rule, true)." for the param `{$paramName}`: {$innerException->getMessage()}",
0,
$innerException
);
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace Knuckles\Scribe\Exceptions;
class CouldntStartDatabaseTransaction extends \RuntimeException implements ScribeException
{
public static function forConnection(string $connectionName, \Throwable $originalException): self
{
return new self(
"Couldn't start a database transaction for the connection {$connectionName}. "
."Make sure this database is running. If you aren't using this connection, remove it from your `databaseConnectionsToTransact` config",
0,
$originalException
);
}
}

Some files were not shown because too many files have changed in this diff Show More