From e7745cb4d9ca5578df834eec009c18d18217ff77 Mon Sep 17 00:00:00 2001 From: xboard Date: Fri, 10 Jan 2025 12:41:09 +0800 Subject: [PATCH] upgrade to lararvel 11 and fixcorrect know file issues --- .gitignore | 3 +- .../V1/Passport/AuthController.php | 68 +++-- .../Controllers/V2/Admin/OrderController.php | 60 ++-- .../Controllers/V2/Admin/TicketController.php | 53 ++-- app/Http/Requests/Admin/ServerSave.php | 115 ++++---- app/Services/AuthService.php | 14 +- composer.json | 24 +- config/app.php | 51 ---- config/scribe.php | 270 ++++++++++++++++++ phpunit.xml | 41 --- pm2.yaml | 5 - 11 files changed, 448 insertions(+), 256 deletions(-) create mode 100644 config/scribe.php delete mode 100755 phpunit.xml delete mode 100644 pm2.yaml diff --git a/.gitignore b/.gitignore index b64312e..6ce6c19 100755 --- a/.gitignore +++ b/.gitignore @@ -29,4 +29,5 @@ cli-php.ini frontend docker-compose.yaml bun.lockb -compose.yaml \ No newline at end of file +compose.yaml +.scribe \ No newline at end of file diff --git a/app/Http/Controllers/V1/Passport/AuthController.php b/app/Http/Controllers/V1/Passport/AuthController.php index 8979be6..cd34e4f 100644 --- a/app/Http/Controllers/V1/Passport/AuthController.php +++ b/app/Http/Controllers/V1/Passport/AuthController.php @@ -180,7 +180,7 @@ class AuthController extends Controller $authService = new AuthService($user); - $data = $authService->generateAuthData($request); + $data = $authService->generateAuthData(); return $this->success($data); } @@ -223,48 +223,70 @@ class AuthController extends Controller } $authService = new AuthService($user); - return $this->success($authService->generateAuthData($request)); + return $this->success($authService->generateAuthData()); } public function token2Login(Request $request) { - if ($request->input('token')) { - $redirect = '/#/login?verify=' . $request->input('token') . '&redirect=' . ($request->input('redirect') ? $request->input('redirect') : 'dashboard'); - if (admin_setting('app_url')) { - $location = admin_setting('app_url') . $redirect; - } else { - $location = url($redirect); - } - return redirect()->to($location)->send(); + if ($token = $request->input('token')) { + $redirect = '/#/login?verify=' . $token . '&redirect=' . ($request->input('redirect', 'dashboard')); + + return redirect()->to( + admin_setting('app_url') + ? admin_setting('app_url') . $redirect + : url($redirect) + ); } - if ($request->input('verify')) { - $key = CacheKey::get('TEMP_TOKEN', $request->input('verify')); + if ($verify = $request->input('verify')) { + $key = CacheKey::get('TEMP_TOKEN', $verify); $userId = Cache::get($key); + if (!$userId) { - return $this->fail([400,__('Token error')]); - } - $user = User::find($userId); - if (!$user) { - return $this->fail([400,__('The user does not ')]); + return response()->json([ + 'message' => __('Token error') + ], 400); } + + $user = User::findOrFail($userId); + if ($user->banned) { - return $this->fail([400,__('Your account has been suspended')]); + return response()->json([ + 'message' => __('Your account has been suspended') + ], 400); } + Cache::forget($key); $authService = new AuthService($user); - return $this->success($authService->generateAuthData($request)); + + return response()->json([ + 'data' => $authService->generateAuthData() + ]); } + + return response()->json([ + 'message' => __('Invalid request') + ], 400); } public function getQuickLoginUrl(Request $request) { $authorization = $request->input('auth_data') ?? $request->header('authorization'); - if (!$authorization) return $this->fail(ResponseEnum::CLIENT_HTTP_UNAUTHORIZED); - - $user = AuthService::decryptAuthData($authorization); - if (!$user) return $this->fail(ResponseEnum::CLIENT_HTTP_UNAUTHORIZED_EXPIRED); + + if (!$authorization) { + return response()->json([ + 'message' => ResponseEnum::CLIENT_HTTP_UNAUTHORIZED + ], 401); + } + $user = AuthService::findUserByBearerToken($authorization); + + if (!$user) { + return response()->json([ + 'message' => ResponseEnum::CLIENT_HTTP_UNAUTHORIZED_EXPIRED + ], 401); + } + $code = Helper::guid(); $key = CacheKey::get('TEMP_TOKEN', $code); Cache::put($key, $user['id'], 60); diff --git a/app/Http/Controllers/V2/Admin/OrderController.php b/app/Http/Controllers/V2/Admin/OrderController.php index ff0f4da..3d2285f 100644 --- a/app/Http/Controllers/V2/Admin/OrderController.php +++ b/app/Http/Controllers/V2/Admin/OrderController.php @@ -35,47 +35,47 @@ class OrderController extends Controller $current = $request->input('current', 1); $pageSize = $request->input('pageSize', 10); $orderModel = Order::with('plan:id,name'); - if ($request->input('is_commission')) { + + if ($request->boolean('is_commission')) { $orderModel->whereNotNull('invite_user_id') ->whereNotIn('status', [0, 2]) ->where('commission_balance', '>', 0); } + $this->applyFiltersAndSorts($request, $orderModel); - $orders = $orderModel - ->orderBy('created_at', 'desc') - ->paginate($pageSize, ['*'], 'page', $current); - return response([ - 'data' => $orders->transform(function ($order) { - $order['period'] = PlanService::getLegacyPeriod($order->period); - return $order; - }), - 'total' => $orders->total() - ]); + + return response()->json( + $orderModel + ->latest('created_at') + ->paginate( + perPage: $pageSize, + page: $current + )->through(fn($order) => [ + ...$order->toArray(), + 'period' => PlanService::getLegacyPeriod($order->period) + ]), + ); } private function applyFiltersAndSorts(Request $request, $builder) { - if ($request->has('filter')) { - collect($request->input('filter'))->each(callback: function ($filter) use ($builder) { - $key = $filter['id']; - $value = $filter['value']; - $builder->where(function ($query) use ($key, $value) { - if (is_array($value)) { - $query->whereIn($key, $value); - } else { - $query->where($key, 'like', "%{$value}%"); - } - }); - }); - } + $request->collect('filter')->each(function ($filter) use ($builder) { + $key = $filter['id']; + $value = $filter['value']; - if ($request->has('sort')) { - collect($request->input('sort'))->each(function ($sort) use ($builder) { - $key = $sort['id']; - $value = $sort['desc'] ? 'DESC' : 'ASC'; - $builder->orderBy($key, $value); + $builder->where(function ($query) use ($key, $value) { + is_array($value) + ? $query->whereIn($key, $value) + : $query->where($key, 'like', "%{$value}%"); }); - } + }); + + $request->collect('sort')->each(function ($sort) use ($builder) { + $builder->orderBy( + $sort['id'], + $sort['desc'] ? 'DESC' : 'ASC' + ); + }); } public function paid(Request $request) diff --git a/app/Http/Controllers/V2/Admin/TicketController.php b/app/Http/Controllers/V2/Admin/TicketController.php index 539927c..fc51d39 100644 --- a/app/Http/Controllers/V2/Admin/TicketController.php +++ b/app/Http/Controllers/V2/Admin/TicketController.php @@ -2,11 +2,8 @@ namespace App\Http\Controllers\V2\Admin; -use App\Exceptions\ApiException; use App\Http\Controllers\Controller; use App\Models\Ticket; -use App\Models\TicketMessage; -use App\Models\User; use App\Services\TicketService; use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Http\Request; @@ -54,15 +51,15 @@ class TicketController extends Controller private function fetchTicketById(Request $request) { $ticket = Ticket::with('messages', 'user')->find($request->input('id')); - + if (!$ticket) { return $this->fail([400202, '工单不存在']); } - + $ticket->messages->each(function ($message) use ($ticket) { $message->is_me = $message->user_id !== $ticket->user_id; }); - + return $this->success($ticket); } @@ -73,35 +70,27 @@ class TicketController extends Controller */ private function fetchTickets(Request $request) { - $current = $request->input('current') ?? 1; - $pageSize = $request->input('pageSize') >= 10 ? $request->input('pageSize') : 10; + $ticketModel = Ticket::query() + ->when($request->has('status'), function ($query) use ($request) { + $query->where('status', $request->input('status')); + }) + ->when($request->has('reply_status'), function ($query) use ($request) { + $query->whereIn('reply_status', $request->input('reply_status')); + }) + ->when($request->has('email'), function ($query) use ($request) { + $query->whereHas('user', function ($q) use ($request) { + $q->where('email', $request->input('email')); + }); + }); - $ticketModel = Ticket::query(); $this->applyFiltersAndSorts($request, $ticketModel); - $ticketModel->orderBy('updated_at', 'DESC'); - if ($request->has('status')) { - $ticketModel->where('status', $request->input('status')); - } - - if ($request->has('reply_status')) { - $ticketModel->whereIn('reply_status', $request->input('reply_status')); - } - - if ($request->has('email')) { - $user = User::where('email', $request->input('email'))->first(); - if ($user) { - $ticketModel->where('user_id', $user->id); - } - } - - $total = $ticketModel->count(); - $res = $ticketModel->forPage($current, $pageSize)->get(); - - return response([ - 'data' => $res, - 'total' => $total - ]); + return response()->json($ticketModel + ->latest('updated_at') + ->paginate( + perPage: $request->integer('pageSize', 10), + page: $request->integer('current', 1) + )); } public function reply(Request $request) diff --git a/app/Http/Requests/Admin/ServerSave.php b/app/Http/Requests/Admin/ServerSave.php index 357bfc5..2446118 100644 --- a/app/Http/Requests/Admin/ServerSave.php +++ b/app/Http/Requests/Admin/ServerSave.php @@ -1,5 +1,7 @@ [ + 'cipher' => 'required|string', + 'obfs' => 'nullable|string', + 'obfs_settings.path' => 'nullable|string', + 'obfs_settings.host' => 'nullable|string', + ], + 'vmess' => [ + 'tls' => 'required|integer', + 'network' => 'required|string', + 'network_settings' => 'nullable|array', + 'tls_settings.server_name' => 'nullable|string', + 'tls_settings.allow_insecure' => 'nullable|boolean', + ], + 'trojan' => [ + 'network' => 'required|string', + 'network_settings' => 'nullable|array', + 'server_name' => 'nullable|string', + 'allow_insecure' => 'nullable|boolean', + ], + 'hysteria' => [ + 'version' => 'required|integer', + 'alpn' => 'nullable|string', + 'obfs.open' => 'nullable|boolean', + 'obfs.type' => 'string|nullable', + 'obfs.password' => 'string|nullable', + 'tls.server_name' => 'nullable|string', + 'tls.allow_insecure' => 'nullable|boolean', + 'bandwidth.up' => 'nullable|integer', + 'bandwidth.down' => 'nullable|integer', + ], + 'vless' => [ + 'tls' => 'required|integer', + 'network' => 'required|string', + 'network_settings' => 'nullable|array', + 'flow' => 'nullable|string', + 'tls_settings.server_name' => 'nullable|string', + 'tls_settings.allow_insecure' => 'nullable|boolean', + 'reality_settings.allow_insecure' => 'nullable|boolean', + 'reality_settings.server_name' => 'nullable|string', + 'reality_settings.server_port' => 'nullable|integer', + 'reality_settings.public_key' => 'nullable|string', + 'reality_settings.private_key' => 'nullable|string', + 'reality_settings.short_id' => 'nullable|string', + ] + ]; + + private function getBaseRules(): array { - $type = $this->input('type'); - $protocolRules = [ + return [ 'type' => 'required|in:' . implode(',', Server::VALID_TYPES), 'spectific_key' => 'nullable|string', 'code' => 'nullable|string', @@ -33,56 +76,14 @@ class ServerSave extends FormRequest 'rate' => 'required|numeric', 'protocol_settings' => 'array', ]; + } - $protocolSpecificRules = [ - 'shadowsocks' => [ - 'cipher' => 'required|string', - 'obfs' => 'nullable|string', - 'obfs_settings.path' => 'nullable|string', - 'obfs_settings.host' => 'nullable|string', - ], - 'vmess' => [ - 'tls' => 'required|integer', - 'network' => 'required|string', - 'network_settings' => 'nullable|array', - 'tls_settings.server_name' => 'nullable|string', - 'tls_settings.allow_insecure' => 'nullable|boolean', - ], - 'trojan' => [ - 'network' => 'required|string', - 'network_settings' => 'nullable|array', - 'server_name' => 'nullable|string', - 'allow_insecure' => 'nullable|boolean', - ], - 'hysteria' => [ - 'version' => 'required|integer', - 'alpn' => 'nullable|string', - 'obfs.open' => 'nullable|boolean', - 'obfs.type' => 'string|nullable', - 'obfs.password' => 'string|nullable', - 'tls.server_name' => 'nullable|string', - 'tls.allow_insecure' => 'nullable|boolean', - 'bandwidth.up' => 'nullable|integer', - 'bandwidth.down' => 'nullable|integer', - ], - 'vless' => [ - 'tls' => 'required|integer', - 'network' => 'required|string', - 'network_settings' => 'nullable|array', - 'flow' => 'nullable|string', - 'tls_settings.server_name' => 'nullable|string', - 'tls_settings.allow_insecure' => 'nullable|boolean', - 'reality_settings.allow_insecure' => 'nullable|boolean', - 'reality_settings.server_name' => 'nullable|string', - 'reality_settings.server_port' => 'nullable|integer', - 'reality_settings.public_key' => 'nullable|string', - 'reality_settings.private_key' => 'nullable|string', - 'reality_settings.short_id' => 'nullable|string', - ] - ]; - - $rules = $protocolRules; - foreach ($protocolSpecificRules[$type] as $field => $rule) { + public function rules(): array + { + $type = $this->input('type'); + $rules = $this->getBaseRules(); + + foreach (self::PROTOCOL_RULES[$type] ?? [] as $field => $rule) { $rules['protocol_settings.' . $field] = $rule; } diff --git a/app/Services/AuthService.php b/app/Services/AuthService.php index 9398894..547d250 100644 --- a/app/Services/AuthService.php +++ b/app/Services/AuthService.php @@ -3,11 +3,8 @@ namespace App\Services; use App\Models\User; -use App\Utils\CacheKey; -use Illuminate\Http\Request; -use Illuminate\Support\Facades\Cache; -use Laravel\Sanctum\NewAccessToken; use Illuminate\Support\Str; +use Laravel\Sanctum\PersonalAccessToken; class AuthService { @@ -47,4 +44,13 @@ class AuthService $this->user->tokens()->delete(); return true; } + + public static function findUserByBearerToken(string $bearerToken): ?User + { + $token = str_replace('Bearer ', '', $bearerToken); + + $accessToken = PersonalAccessToken::findToken($token); + + return $accessToken?->tokenable; + } } diff --git a/composer.json b/composer.json index e5eba2c..44544ef 100755 --- a/composer.json +++ b/composer.json @@ -11,17 +11,17 @@ ], "license": "MIT", "require": { - "php": "^8.1", + "php": "^8.2", "doctrine/dbal": "^3.7", "google/cloud-storage": "^1.35", "google/recaptcha": "^1.2", - "guzzlehttp/guzzle": "^7.4.3", - "laravel/framework": "10.*", - "laravel/horizon": "^5.9.6", - "laravel/octane": "*", - "laravel/prompts": "^0.1.22", - "laravel/sanctum": "^3.3", - "laravel/tinker": "^2.5", + "guzzlehttp/guzzle": "^7.8", + "laravel/framework": "^11.0", + "laravel/horizon": "^5.21", + "laravel/octane": "^2.3", + "laravel/prompts": "^0.1.13", + "laravel/sanctum": "^4.0", + "laravel/tinker": "^2.9", "linfo/linfo": "^4.0", "paragonie/sodium_compat": "^1.20", "php-curl-class/php-curl-class": "^8.6", @@ -35,11 +35,11 @@ "require-dev": { "barryvdh/laravel-debugbar": "^3.9", "fakerphp/faker": "^1.9.1", - "mockery/mockery": "^1.3.1", - "nunomaduro/collision": "^7.10", + "mockery/mockery": "^1.6", + "nunomaduro/collision": "^8.0", "orangehill/iseed": "^3.0", - "phpunit/phpunit": "^10.0", - "spatie/laravel-ignition": "^2.0" + "phpunit/phpunit": "^10.5", + "spatie/laravel-ignition": "^2.4" }, "config": { "optimize-autoloader": true, diff --git a/config/app.php b/config/app.php index c5dbbbe..a4bfd69 100755 --- a/config/app.php +++ b/config/app.php @@ -180,57 +180,6 @@ return [ ], - /* - |-------------------------------------------------------------------------- - | Class Aliases - |-------------------------------------------------------------------------- - | - | This array of class aliases will be registered when this application - | is started. However, feel free to register as many as you wish as - | the aliases are "lazy" loaded so they don't hinder performance. - | - */ - - 'aliases' => [ - - 'App' => Illuminate\Support\Facades\App::class, - 'Arr' => Illuminate\Support\Arr::class, - 'Artisan' => Illuminate\Support\Facades\Artisan::class, - 'Auth' => Illuminate\Support\Facades\Auth::class, - 'Blade' => Illuminate\Support\Facades\Blade::class, - 'Broadcast' => Illuminate\Support\Facades\Broadcast::class, - 'Bus' => Illuminate\Support\Facades\Bus::class, - 'Cache' => Illuminate\Support\Facades\Cache::class, - 'Config' => Illuminate\Support\Facades\Config::class, - 'Cookie' => Illuminate\Support\Facades\Cookie::class, - 'Crypt' => Illuminate\Support\Facades\Crypt::class, - 'DB' => Illuminate\Support\Facades\DB::class, - 'Eloquent' => Illuminate\Database\Eloquent\Model::class, - 'Event' => Illuminate\Support\Facades\Event::class, - 'File' => Illuminate\Support\Facades\File::class, - 'Gate' => Illuminate\Support\Facades\Gate::class, - 'Hash' => Illuminate\Support\Facades\Hash::class, - 'Lang' => Illuminate\Support\Facades\Lang::class, - 'Log' => Illuminate\Support\Facades\Log::class, - 'Mail' => Illuminate\Support\Facades\Mail::class, - 'Notification' => Illuminate\Support\Facades\Notification::class, - 'Password' => Illuminate\Support\Facades\Password::class, - 'Queue' => Illuminate\Support\Facades\Queue::class, - 'Redirect' => Illuminate\Support\Facades\Redirect::class, - 'Redis' => Illuminate\Support\Facades\Redis::class, - 'Request' => Illuminate\Support\Facades\Request::class, - 'Response' => Illuminate\Support\Facades\Response::class, - 'Route' => Illuminate\Support\Facades\Route::class, - 'Schema' => Illuminate\Support\Facades\Schema::class, - 'Session' => Illuminate\Support\Facades\Session::class, - 'Storage' => Illuminate\Support\Facades\Storage::class, - 'Str' => Illuminate\Support\Str::class, - 'URL' => Illuminate\Support\Facades\URL::class, - 'Validator' => Illuminate\Support\Facades\Validator::class, - 'View' => Illuminate\Support\Facades\View::class, - - ], - /* |-------------------------------------------------------------------------- | V2board version diff --git a/config/scribe.php b/config/scribe.php new file mode 100644 index 0000000..b2e0c03 --- /dev/null +++ b/config/scribe.php @@ -0,0 +1,270 @@ + for the generated documentation. If this is empty, Scribe will infer it from config('app.name'). + 'title' => null, + + // A short description of your API. Will be included in the docs webpage, Postman collection and OpenAPI spec. + 'description' => '', + + // The base URL displayed in the docs. If this is empty, Scribe will use the value of config('app.url') at generation time. + // 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' => null, + + 'routes' => [ + [ + // Routes that match these conditions will be included in the docs + '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' => ['*'], + + // [Dingo router only] Match only routes registered under this version. Wildcards are NOT supported. + 'versions' => ['v1'], + ], + + // 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 generate a basic template, + // passing the OpenAPI spec as a URL, allowing you to easily use the docs with an external generator + 'type' => 'static', + + // 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 endpoint for you to view your generated docs. + // If this is false, 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 for the API tester to use (for example, you can set this to your staging URL). + // Leave as null to use the current app URL when generating (config("app.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? + // Options: query, body, basic, bearer, header (for custom header) + 'in' => 'bearer', + + // 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 Generate API token.', + ], + + // Text to place in the "Introduction" section, right after the `description`. Markdown and HTML are supported. + 'intro_text' => <<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). +INTRO + , + + // 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 + '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 (v3.0.1) 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, + + 'overrides' => [ + // 'info.version' => '2.0.0', + ], + ], + + '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 + 'order' => [], + ], + + // Custom logo path. This will be used as the value of the src attribute for the 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:}` and `{git:}`. + // 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". + 'last_updated' => 'Last updated: {date:F j, Y}', + + 'examples' => [ + // Set this to any number (e.g. 1234) to generate the same example values for parameters on each run, + 'faker_seed' => null, + + // 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. + // If you create or install a custom strategy, add it here. + 'strategies' => [ + 'metadata' => [ + Strategies\Metadata\GetFromDocBlocks::class, + Strategies\Metadata\GetFromMetadataAttributes::class, + ], + 'urlParameters' => [ + Strategies\UrlParameters\GetFromLaravelAPI::class, + Strategies\UrlParameters\GetFromUrlParamAttribute::class, + Strategies\UrlParameters\GetFromUrlParamTag::class, + ], + 'queryParameters' => [ + Strategies\QueryParameters\GetFromFormRequest::class, + Strategies\QueryParameters\GetFromInlineValidator::class, + Strategies\QueryParameters\GetFromQueryParamAttribute::class, + Strategies\QueryParameters\GetFromQueryParamTag::class, + ], + 'headers' => [ + Strategies\Headers\GetFromHeaderAttribute::class, + Strategies\Headers\GetFromHeaderTag::class, + [ + 'override', + [ + 'Content-Type' => 'application/json', + 'Accept' => 'application/json', + ] + ] + ], + 'bodyParameters' => [ + Strategies\BodyParameters\GetFromFormRequest::class, + Strategies\BodyParameters\GetFromInlineValidator::class, + Strategies\BodyParameters\GetFromBodyParamAttribute::class, + Strategies\BodyParameters\GetFromBodyParamTag::class, + ], + 'responses' => [ + Strategies\Responses\UseResponseAttributes::class, + Strategies\Responses\UseTransformerTags::class, + Strategies\Responses\UseApiResourceTags::class, + Strategies\Responses\UseResponseTag::class, + Strategies\Responses\UseResponseFileTag::class, + [ + Strategies\Responses\ResponseCalls::class, + [ + 'only' => ['GET *'], + // Disable debug mode when generating response calls to avoid error stack traces in responses + 'config' => [ + 'app.debug' => false, + ], + ] + ] + ], + 'responseFields' => [ + Strategies\ResponseFields\GetFromResponseFieldAttribute::class, + Strategies\ResponseFields\GetFromResponseFieldTag::class, + ], + ], + + // 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, + ], + + 'routeMatcher' => \Knuckles\Scribe\Matching\RouteMatcher::class, +]; diff --git a/phpunit.xml b/phpunit.xml deleted file mode 100755 index 61b6b64..0000000 --- a/phpunit.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - ./tests/Unit - - - - ./tests/Feature - - - - - ./app - - - - - - - - - - - - - - - - - - - diff --git a/pm2.yaml b/pm2.yaml deleted file mode 100644 index 48c2425..0000000 --- a/pm2.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apps: - - name : 'V2Board' - script : 'php artisan horizon' - instances: 1 - out_file : './storage/logs/queue/queue.log'