commit 88188b041e1f2c8de23072df8b11a65511c2779e
parent 930dc1af6c6365c8aa4121b5281b6fbaa4f0e116
Author: MTRNord <mtrnord1@gmail.com>
Date: Wed, 18 Oct 2023 14:27:32 +0200
Add api docs
Diffstat:
15 files changed, 2979 insertions(+), 3 deletions(-)
diff --git a/.env.example b/.env.example
@@ -1,4 +1,4 @@
-APP_NAME=Home ERP
+APP_NAME="Home ERP"
APP_ENV=local
APP_KEY=
APP_DEBUG=false
diff --git a/.scribe/.filehashes b/.scribe/.filehashes
@@ -0,0 +1,4 @@
+# GENERATED. YOU SHOULDN'T MODIFY OR DELETE THIS FILE.
+# Scribe uses this file to know when you change something manually in your docs.
+.scribe/intro.md=1d48e07f464af5f96c20c1058d0e753f
+.scribe/auth.md=5ea0b82b0e0252887e6b1c8bc7382937
+\ No newline at end of file
diff --git a/.scribe/auth.md b/.scribe/auth.md
@@ -0,0 +1,7 @@
+# Authenticating requests
+
+To authenticate requests, include an **`Authorization`** header with the value **`"Bearer {YOUR_AUTH_KEY}"`**.
+
+All authenticated endpoints are marked with a `requires authentication` badge in the documentation below.
+
+You can retrieve your token by visiting your dashboard and clicking <b>Generate API token</b>.
diff --git a/.scribe/endpoints/custom.0.yaml b/.scribe/endpoints/custom.0.yaml
@@ -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
diff --git a/.scribe/intro.md b/.scribe/intro.md
@@ -0,0 +1,10 @@
+# Introduction
+
+
+
+<aside>
+ <strong>Base URL</strong>: <code>http://localhost</code>
+</aside>
+
+This documentation aims to provide all the information you need to work with our API.
+
diff --git a/composer.json b/composer.json
@@ -16,6 +16,7 @@
},
"require-dev": {
"fakerphp/faker": "^1.9.1",
+ "knuckleswtf/scribe": "^4.25",
"laravel/breeze": "^1.25",
"laravel/pint": "^1.0",
"laravel/sail": "^1.18",
diff --git a/composer.lock b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "69b0c884691733551c8db1d1144a059d",
+ "content-hash": "9e2d008d090a204d31b7d0fd4f63a3a6",
"packages": [
{
"name": "brick/math",
@@ -5774,6 +5774,56 @@
],
"packages-dev": [
{
+ "name": "erusev/parsedown",
+ "version": "1.7.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/erusev/parsedown.git",
+ "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/erusev/parsedown/zipball/cb17b6477dfff935958ba01325f2e8a2bfa6dab3",
+ "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3",
+ "shasum": ""
+ },
+ "require": {
+ "ext-mbstring": "*",
+ "php": ">=5.3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35"
+ },
+ "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/erusev/parsedown/issues",
+ "source": "https://github.com/erusev/parsedown/tree/1.7.x"
+ },
+ "time": "2019-12-30T22:54:17+00:00"
+ },
+ {
"name": "fakerphp/faker",
"version": "v1.23.0",
"source": {
@@ -5964,6 +6014,101 @@
"time": "2020-07-09T08:09:16+00:00"
},
{
+ "name": "knuckleswtf/scribe",
+ "version": "4.25.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/knuckleswtf/scribe.git",
+ "reference": "e45e3afc5f97008294b9c18edd16666223e486a2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/knuckleswtf/scribe/zipball/e45e3afc5f97008294b9c18edd16666223e486a2",
+ "reference": "e45e3afc5f97008294b9c18edd16666223e486a2",
+ "shasum": ""
+ },
+ "require": {
+ "erusev/parsedown": "1.7.4",
+ "ext-fileinfo": "*",
+ "ext-json": "*",
+ "ext-pdo": "*",
+ "fakerphp/faker": "^1.9.1",
+ "illuminate/console": "^8.0|^9.0|^10.0",
+ "illuminate/routing": "^8.0|^9.0|^10.0",
+ "illuminate/support": "^8.0|^9.0|^10.0",
+ "league/flysystem": "^1.1.4|^2.1.1|^3.0",
+ "mpociot/reflection-docblock": "^1.0.1",
+ "nikic/php-parser": "^4.10",
+ "nunomaduro/collision": "^5.10|^6.0|^7.0",
+ "php": ">=8.0",
+ "ramsey/uuid": "^4.2.2",
+ "shalvah/clara": "^3.1.0",
+ "shalvah/upgrader": "^0.3.0",
+ "spatie/data-transfer-object": "^2.6|^3.0",
+ "symfony/var-exporter": "^5.4|^6.0",
+ "symfony/yaml": "^5.4|^6.0"
+ },
+ "replace": {
+ "mpociot/laravel-apidoc-generator": "*"
+ },
+ "require-dev": {
+ "brianium/paratest": "^6.0",
+ "dms/phpunit-arraysubset-asserts": "^0.4",
+ "laravel/legacy-factories": "^1.3.0",
+ "laravel/lumen-framework": "^8.0|^9.0|^10.0",
+ "league/fractal": "^0.20",
+ "nikic/fast-route": "^1.3",
+ "orchestra/testbench": "^6.0|^7.0|^8.0",
+ "pestphp/pest": "^1.21",
+ "phpstan/phpstan": "^1.0",
+ "phpunit/phpunit": "^9.0|^10.0",
+ "symfony/css-selector": "^5.4|^6.0",
+ "symfony/dom-crawler": "^5.4|^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "laravel": {
+ "providers": [
+ "Knuckles\\Scribe\\ScribeServiceProvider"
+ ]
+ }
+ },
+ "autoload": {
+ "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": "http://github.com/knuckleswtf/scribe",
+ "keywords": [
+ "api",
+ "dingo",
+ "documentation",
+ "laravel"
+ ],
+ "support": {
+ "issues": "https://github.com/knuckleswtf/scribe/issues",
+ "source": "https://github.com/knuckleswtf/scribe/tree/4.25.0"
+ },
+ "funding": [
+ {
+ "url": "https://patreon.com/shalvah",
+ "type": "patreon"
+ }
+ ],
+ "time": "2023-09-29T22:23:01+00:00"
+ },
+ {
"name": "laravel/breeze",
"version": "v1.25.0",
"source": {
@@ -6242,6 +6387,59 @@
"time": "2023-08-09T00:03:52+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": "myclabs/deep-copy",
"version": "1.11.1",
"source": {
@@ -7845,6 +8043,111 @@
"time": "2023-02-07T11:34:05+00:00"
},
{
+ "name": "shalvah/clara",
+ "version": "3.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/shalvah/clara.git",
+ "reference": "d3ae9b277393d438edbfcf9ddb7ca42e958fa054"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/shalvah/clara/zipball/d3ae9b277393d438edbfcf9ddb7ca42e958fa054",
+ "reference": "d3ae9b277393d438edbfcf9ddb7ca42e958fa054",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.4",
+ "symfony/console": "^4.0|^5.0|^6.0"
+ },
+ "require-dev": {
+ "eloquent/phony-phpunit": "^7.0",
+ "phpunit/phpunit": "^9.1"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "helpers.php"
+ ],
+ "psr-4": {
+ "Shalvah\\Clara\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "🔊 Simple, pretty, testable console output for CLI apps.",
+ "keywords": [
+ "cli",
+ "log",
+ "logging"
+ ],
+ "support": {
+ "issues": "https://github.com/shalvah/clara/issues",
+ "source": "https://github.com/shalvah/clara/tree/3.1.0"
+ },
+ "time": "2022-01-14T13:54:30+00:00"
+ },
+ {
+ "name": "shalvah/upgrader",
+ "version": "0.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/shalvah/upgrader.git",
+ "reference": "c7f1cca8be5cd0114cd816d8bfff9c80565f7390"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/shalvah/upgrader/zipball/c7f1cca8be5cd0114cd816d8bfff9c80565f7390",
+ "reference": "c7f1cca8be5cd0114cd816d8bfff9c80565f7390",
+ "shasum": ""
+ },
+ "require": {
+ "illuminate/support": "^8.0|^9.0|^10.0",
+ "nikic/php-parser": "^4.13",
+ "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.3.1"
+ },
+ "funding": [
+ {
+ "url": "https://patreon.com/shalvah",
+ "type": "patreon"
+ }
+ ],
+ "time": "2023-02-06T01:20:37+00:00"
+ },
+ {
"name": "spatie/backtrace",
"version": "1.5.3",
"source": {
@@ -7907,6 +8210,70 @@
"time": "2023-06-28T12:59:17+00:00"
},
{
+ "name": "spatie/data-transfer-object",
+ "version": "3.9.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/spatie/data-transfer-object.git",
+ "reference": "1df0906c4e9e3aebd6c0506fd82c8b7d5548c1c8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/spatie/data-transfer-object/zipball/1df0906c4e9e3aebd6c0506fd82c8b7d5548c1c8",
+ "reference": "1df0906c4e9e3aebd6c0506fd82c8b7d5548c1c8",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^8.0"
+ },
+ "require-dev": {
+ "illuminate/collections": "^8.36",
+ "jetbrains/phpstorm-attributes": "^1.0",
+ "larapack/dd": "^1.1",
+ "phpunit/phpunit": "^9.5.5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Spatie\\DataTransferObject\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Brent Roose",
+ "email": "brent@spatie.be",
+ "homepage": "https://spatie.be",
+ "role": "Developer"
+ }
+ ],
+ "description": "Data transfer objects with batteries included",
+ "homepage": "https://github.com/spatie/data-transfer-object",
+ "keywords": [
+ "data-transfer-object",
+ "spatie"
+ ],
+ "support": {
+ "issues": "https://github.com/spatie/data-transfer-object/issues",
+ "source": "https://github.com/spatie/data-transfer-object/tree/3.9.1"
+ },
+ "funding": [
+ {
+ "url": "https://spatie.be/open-source/support-us",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/spatie",
+ "type": "github"
+ }
+ ],
+ "abandoned": "spatie/laravel-data",
+ "time": "2022-09-16T13:34:38+00:00"
+ },
+ {
"name": "spatie/flare-client-php",
"version": "1.4.3",
"source": {
@@ -8152,6 +8519,80 @@
"time": "2023-10-09T12:55:26+00:00"
},
{
+ "name": "symfony/var-exporter",
+ "version": "v6.3.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/var-exporter.git",
+ "reference": "df1f8aac5751871b83d30bf3e2c355770f8f0691"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/var-exporter/zipball/df1f8aac5751871b83d30bf3e2c355770f8f0691",
+ "reference": "df1f8aac5751871b83d30bf3e2c355770f8f0691",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "symfony/var-dumper": "^5.4|^6.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/v6.3.4"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-08-16T18:14:47+00:00"
+ },
+ {
"name": "symfony/yaml",
"version": "v6.3.3",
"source": {
diff --git a/config/app.php b/config/app.php
@@ -16,7 +16,7 @@ return [
|
*/
- 'name' => env('APP_NAME', 'Home_ERP'),
+ 'name' => env('APP_NAME', 'Home ERP'),
/*
|--------------------------------------------------------------------------
diff --git a/config/scribe.php b/config/scribe.php
@@ -0,0 +1,441 @@
+<?php
+
+use Knuckles\Scribe\Extracting\Strategies;
+
+return [
+
+ 'theme' => 'default',
+
+ /*
+ * The HTML <title> 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,
+
+ /*
+ * Tell Scribe what routes to generate documentation for.
+ * Each group contains rules defining which routes should be included ('match', 'include' and 'exclude' sections)
+ * and settings which should be applied to them ('apply' section).
+ */
+ 'routes' => [
+ [
+ /*
+ * Specify conditions to determine what routes will be a part of this group.
+ * A route must fulfill ALL conditions to be included.
+ */
+ '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.
+ * The route can be referenced by name or path here. Wildcards are supported.
+ */
+ 'include' => [
+ // 'users.index', 'healthcheck*'
+ ],
+
+ /*
+ * Exclude these routes even if they matched the rules above.
+ * The route can be referenced by name or path here. Wildcards are supported.
+ */
+ 'exclude' => [
+ // '/health', 'admin.*'
+ ],
+
+ /*
+ * Settings to be applied to all the matched routes in this group when generating documentation
+ */
+ 'apply' => [
+ /*
+ * Additional headers to be added to the example requests
+ */
+ 'headers' => [
+ 'Content-Type' => 'application/json',
+ 'Accept' => 'application/json',
+ ],
+
+ /*
+ * If no @response or @transformer declarations are found for the route,
+ * Scribe will try to get a sample response by attempting an API call.
+ * Configure the settings for the API call here.
+ */
+ 'response_calls' => [
+ /*
+ * API calls will be made only for routes in this group matching these HTTP methods (GET, POST, etc).
+ * List the methods here or use '*' to mean all methods. Leave empty to disable API calls.
+ */
+ 'methods' => ['GET'],
+
+ /*
+ * Laravel config variables which should be set for the API call.
+ * This is a good place to ensure that notifications, emails and other external services
+ * are not triggered during the documentation API calls.
+ * You can also create a `.env.docs` file and run the generate command with `--env docs`.
+ */
+ 'config' => [
+ 'app.env' => 'documentation',
+ // 'app.debug' => false,
+ ],
+
+ /*
+ * Query parameters which should be sent with the API call.
+ */
+ 'queryParams' => [
+ // 'key' => 'value',
+ ],
+
+ /*
+ * Body parameters which should be sent with the API call.
+ */
+ 'bodyParams' => [
+ // 'key' => 'value',
+ ],
+
+ /*
+ * Files which should be sent with the API call.
+ * Each value should be a valid path (absolute or relative to your project directory) to a file on this machine (but not in the project root).
+ */
+ 'fileParams' => [
+ // 'key' => 'storage/app/image.png',
+ ],
+
+ /*
+ * Cookies which should be sent with the API call.
+ */
+ 'cookies' => [
+ // 'name' => 'value'
+ ],
+ ],
+ ],
+ ],
+ ],
+
+ /*
+ * 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.
+ */
+ 'type' => 'laravel',
+
+ /*
+ * Settings for `static` type output.
+ */
+ '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',
+ ],
+
+ /*
+ * Settings for `laravel` type output.
+ */
+ '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' => [],
+ ],
+
+ '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,
+
+ /**
+ * Fetch a CSRF token before each request, and add it as an X-XSRF-TOKEN header. Needed if you're using Laravel Sanctum.
+ */
+ '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' => true,
+
+ /*
+ * 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' => true,
+
+ /*
+ * 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 (eg token, key, apiKey) or header (eg Authorization, Api-Key).
+ */
+ 'name' => 'Authorization',
+
+ /*
+ * The value of the parameter to be used by Scribe to authenticate response calls.
+ * This will NOT be included in the generated documentation.
+ * If this value is 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. For instance, you can describe how to find or generate their auth credentials.
+ * Markdown and HTML are supported.
+ */
+ 'extra_info' => 'You can retrieve your token by visiting your dashboard and clicking <b>Generate API token</b>.',
+ ],
+
+ /*
+ * 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.
+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,
+
+ /*
+ * Manually override some generated content in the spec. Dot notation is supported.
+ */
+ '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,
+
+ /*
+ * Manually override some generated content in the spec. Dot notation is supported.
+ */
+ '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.
+ *
+ * Any groups, subgroups or endpoints you don't list here will be added as usual after the ones here unless you
+ * use the "*" character as this specifies the position of all unspecified groups
+ * If an endpoint/subgroup is listed under a group it doesn't belong in, it will be ignored.
+ * Note: you must include the initial '/' when writing an endpoint.
+ */
+ 'order' => [
+ // 'This group will come first',
+ // 'This group will come next' => [
+ // 'POST /this-endpoint-will-comes-first',
+ // 'GET /this-endpoint-will-comes-next',
+ // ],
+ // 'This group will come third' => [
+ // 'This subgroup will come first' => [
+ // 'GET /this-other-endpoint-will-comes-first',
+ // 'GET /this-other-endpoint-will-comes-next',
+ // ]
+ // ]
+ ],
+ ],
+
+ /*
+ * 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".
+ */
+ 'last_updated' => 'Last updated: {date:F j, Y}',
+
+ 'examples' => [
+ /*
+ * If you would like the package to generate the same example values for parameters on each run,
+ * set this to any number (eg. 1234)
+ */
+ 'faker_seed' => "12345",
+
+ /*
+ * 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\GetFromLumenAPI::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\GetFromRouteRules::class,
+ Strategies\Headers\GetFromHeaderAttribute::class,
+ Strategies\Headers\GetFromHeaderTag::class,
+ ],
+ '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,
+ ],
+ 'responseFields' => [
+ Strategies\ResponseFields\GetFromResponseFieldAttribute::class,
+ Strategies\ResponseFields\GetFromResponseFieldTag::class,
+ ],
+ ],
+
+ 'fractal' => [
+ /* If you are using a custom serializer with league/fractal, you can specify it here.
+ * Leave as null to use no serializer or return simple JSON.
+ */
+ 'serializer' => null,
+ ],
+
+ /*
+ * [Advanced] Custom implementation of RouteMatcherInterface to customise how routes are matched
+ *
+ */
+ 'routeMatcher' => \Knuckles\Scribe\Matching\RouteMatcher::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')]
+];
diff --git a/public/vendor/scribe/css/theme-default.print.css b/public/vendor/scribe/css/theme-default.print.css
@@ -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
+}
diff --git a/public/vendor/scribe/css/theme-default.style.css b/public/vendor/scribe/css/theme-default.style.css
@@ -0,0 +1,1097 @@
+/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
+
+html {
+ font-family: 'Open Sans', sans-serif;
+ font-size: 1.2em;
+ -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 {
+ display: block
+}
+
+summary {
+ cursor: pointer;
+}
+
+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: 700
+}
+
+dfn {
+ font-style: italic
+}
+
+h1 {
+ font-size: 2em;
+ margin: .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: -.5em
+}
+
+sub {
+ bottom: -.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 silver;
+ margin: 0 2px;
+ padding: .35em .625em .75em
+}
+
+legend {
+ border: 0;
+ padding: 0
+}
+
+textarea {
+ overflow: auto
+}
+
+optgroup {
+ font-weight: 700
+}
+
+table {
+ border-collapse: collapse;
+ border-spacing: 0
+}
+
+td,
+th {
+ padding: 0
+}
+
+body,
+html {
+ font-family: 'Open Sans', Helvetica Neue, Helvetica, Arial, Microsoft Yahei, 微软雅黑, STXihei, 华文细黑, sans-serif;
+ font-size: 16px;
+}
+
+.content h1,
+.content h2,
+.content h3,
+.content h4,
+.content h5,
+.content h6 {
+ font-family: 'Open Sans', Helvetica Neue, Helvetica, Arial, Microsoft Yahei, 微软雅黑, STXihei, 华文细黑, sans-serif;
+}
+
+.content h1,
+.content h2,
+.content h3,
+.content h4,
+.content h5,
+.content h6 {
+ font-weight: 700
+}
+
+.content code,
+.content pre {
+ font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;
+ font-size: 14px;
+ line-height: 1.5
+}
+
+.content code {
+ word-break: break-all;
+ word-break: break-word;
+ -webkit-hyphens: auto;
+ -ms-hyphens: auto;
+ hyphens: auto
+}
+
+.content aside.notice:before,
+.content aside.success:before,
+.content aside.warning:before,
+.tocify-wrapper>.search:before {
+ font-family: 'Open Sans', sans-serif;
+ speak: none;
+ font-style: normal;
+ font-variant: normal;
+ text-transform: none;
+ line-height: 1
+}
+
+.content aside.warning:before {
+ content: "✋"
+}
+
+.content aside.notice:before {
+ content: "ℹ"
+}
+
+.content aside.success:before {
+ content: "✅"
+}
+
+.tocify-wrapper>.search:before {
+ content: "🔎"
+}
+
+.highlight .c,
+.highlight .c1,
+.highlight .cm,
+.highlight .cs {
+ color: #909090
+}
+
+.highlight,
+.highlight .w {
+ background-color: #292929
+}
+
+.hljs {
+ display: block;
+ overflow-x: auto;
+ padding: .5em;
+ background: #23241f
+}
+
+.hljs,
+.hljs-subst,
+.hljs-tag {
+ color: #f8f8f2
+}
+
+.hljs-emphasis,
+.hljs-strong {
+ color: #a8a8a2
+}
+
+.hljs-bullet,
+.hljs-link,
+.hljs-literal,
+.hljs-number,
+.hljs-quote,
+.hljs-regexp {
+ color: #ae81ff
+}
+
+.hljs-code,
+.hljs-section,
+.hljs-selector-class,
+.hljs-title {
+ color: #a6e22e
+}
+
+.hljs-strong {
+ font-weight: 700
+}
+
+.hljs-emphasis {
+ font-style: italic
+}
+
+.hljs-attr,
+.hljs-keyword,
+.hljs-name,
+.hljs-selector-tag {
+ color: #f92672
+}
+
+.hljs-attribute,
+.hljs-symbol {
+ color: #66d9ef
+}
+
+.hljs-class .hljs-title,
+.hljs-params {
+ color: #f8f8f2
+}
+
+.hljs-addition,
+.hljs-built_in,
+.hljs-builtin-name,
+.hljs-selector-attr,
+.hljs-selector-id,
+.hljs-selector-pseudo,
+.hljs-string,
+.hljs-template-variable,
+.hljs-type,
+.hljs-variable {
+ color: #e6db74
+}
+
+.hljs-comment,
+.hljs-deletion,
+.hljs-meta {
+ color: #75715e
+}
+
+body,
+html {
+ color: #333;
+ padding: 0;
+ margin: 0;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ background-color: whitesmoke;
+ height: 100%;
+ -webkit-text-size-adjust: none
+}
+
+#toc>ul>li>a>span {
+ float: right;
+ background-color: #2484ff;
+ border-radius: 40px;
+ width: 20px
+}
+
+.tocify-wrapper {
+ transition: left .3s ease-in-out;
+ overflow-y: auto;
+ overflow-x: hidden;
+ position: fixed;
+ z-index: 30;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ width: 230px;
+ background-color: #393939;
+ font-size: 13px;
+ font-weight: 700
+}
+
+.tocify-wrapper .lang-selector {
+ display: none
+}
+
+.tocify-wrapper .lang-selector a {
+ padding-top: .5em;
+ padding-bottom: .5em
+}
+
+.tocify-wrapper>img {
+ display: block
+}
+
+.tocify-wrapper>.search {
+ position: relative
+}
+
+.tocify-wrapper>.search input {
+ background: #393939;
+ border-width: 0 0 1px;
+ border-color: #666;
+ padding: 6px 0 6px 20px;
+ box-sizing: border-box;
+ margin: 10px 15px;
+ width: 200px;
+ outline: none;
+ color: #fff;
+ border-radius: 0
+}
+
+.tocify-wrapper>.search:before {
+ position: absolute;
+ top: 17px;
+ left: 15px;
+ color: #fff
+}
+
+.tocify-wrapper img+.tocify {
+ margin-top: 20px
+}
+
+.tocify-wrapper .search-results {
+ margin-top: 0;
+ box-sizing: border-box;
+ height: 0;
+ overflow-y: auto;
+ overflow-x: hidden;
+ transition-property: height, margin;
+ transition-duration: .18s;
+ transition-timing-function: ease-in-out;
+ background: linear-gradient(180deg, rgba(0, 0, 0, .2), transparent 8px), linear-gradient(0deg, rgba(0, 0, 0, .2), transparent 8px), linear-gradient(180deg, #000, transparent 1.5px), linear-gradient(0deg, #939393, hsla(0, 0%, 58%, 0) 1.5px), #262626
+}
+
+.tocify-wrapper .search-results.visible {
+ height: 30%;
+ margin-bottom: 1em
+}
+
+.tocify-wrapper .search-results li {
+ margin: 1em 15px;
+ line-height: 1
+}
+
+.tocify-wrapper a {
+ color: #fff;
+ text-decoration: none
+}
+
+.tocify-wrapper .search-results a:hover {
+ text-decoration: underline
+}
+
+.tocify-wrapper .toc-footer li,
+.tocify-wrapper .tocify-item>a {
+ padding: 0 15px;
+ display: block;
+ overflow-x: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis
+}
+.tocify-wrapper .tocify-item.level-3>a {
+ padding: 0 25px;
+}
+
+.tocify-wrapper li,
+.tocify-wrapper ul {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ line-height: 28px
+}
+
+.tocify-wrapper li {
+ color: #fff;
+ transition-property: background;
+ transition-timing-function: linear;
+ transition-duration: .23s
+}
+
+.tocify-wrapper .tocify-focus {
+ box-shadow: 0 1px 0 #000;
+ background-color: #2467af;
+ color: #fff;
+ font-weight: bold;
+}
+
+.tocify-wrapper .tocify-subheader {
+ display: none;
+ background-color: #262626;
+ font-weight: 500;
+ background: linear-gradient(180deg, rgba(0, 0, 0, .2), transparent 8px), linear-gradient(0deg, rgba(0, 0, 0, .2), transparent 8px), linear-gradient(180deg, #000, transparent 1.5px), linear-gradient(0deg, #939393, hsla(0, 0%, 58%, 0) 1.5px), #262626
+}
+
+.tocify-wrapper .jets-searching .tocify-subheader,
+.tocify-wrapper .tocify-subheader.visible {
+ display: block;
+}
+
+.tocify-wrapper .tocify-subheader .tocify-item>a {
+ padding-left: 25px;
+ font-size: 12px
+}
+
+.tocify-wrapper .tocify-subheader .tocify-item.level-3>a {
+ padding-left: 35px;
+}
+
+.tocify-wrapper .tocify-subheader>li:last-child {
+ box-shadow: none
+}
+
+.tocify-wrapper .toc-footer {
+ padding: 1em 0;
+ margin-top: 1em;
+ border-top: 1px dashed #666
+}
+
+.tocify-wrapper .toc-footer a,
+.tocify-wrapper .toc-footer li {
+ color: #fff;
+ text-decoration: none
+}
+
+.tocify-wrapper .toc-footer a:hover {
+ text-decoration: underline
+}
+
+.tocify-wrapper .toc-footer li {
+ font-size: .8em;
+ line-height: 1.7;
+ text-decoration: none
+}
+
+#nav-button {
+ padding: 0 1.5em 5em 0;
+ display: none;
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: 100;
+ color: #000;
+ text-decoration: none;
+ font-weight: 700;
+ opacity: .7;
+ line-height: 16px;
+ transition: left .3s ease-in-out
+}
+
+#nav-button span {
+ display: block;
+ padding: 6px;
+ background-color: rgba(234, 242, 246, .7);
+ -webkit-transform-origin: 0 0;
+ transform-origin: 0 0;
+ -webkit-transform: rotate(-90deg) translate(-100%);
+ transform: rotate(-90deg) translate(-100%);
+ border-radius: 0 0 0 5px
+}
+
+#nav-button img {
+ height: 16px;
+ vertical-align: bottom
+}
+
+#nav-button:hover {
+ opacity: 1
+}
+
+#nav-button.open {
+ left: 230px
+}
+
+.page-wrapper {
+ margin-left: 230px;
+ position: relative;
+ z-index: 10;
+ background-color: #eaf2f6;
+ min-height: 100%;
+ padding-bottom: 1px
+}
+
+.page-wrapper .dark-box {
+ width: 50%;
+ background-color: #393939;
+ position: absolute;
+ right: 0;
+ top: 0;
+ bottom: 0
+}
+
+.page-wrapper .lang-selector {
+ position: fixed;
+ z-index: 50;
+ border-bottom: 5px solid #393939
+}
+
+.lang-selector {
+ background-color: #222;
+ width: 100%;
+ font-weight: 700
+}
+
+.lang-selector button {
+ display: block;
+ float: left;
+ color: #fff;
+ text-decoration: none;
+ padding: 0 10px;
+ line-height: 30px;
+ outline: 0;
+ background: transparent;
+ border: none;
+}
+
+.lang-selector button:active,
+.lang-selector button:hover,
+.lang-selector button:focus {
+ background-color: #111;
+ color: #fff
+}
+
+.lang-selector button.active {
+ background-color: #393939;
+ color: #fff
+}
+
+.lang-selector:after {
+ content: '';
+ clear: both;
+ display: block
+}
+
+.content {
+ position: relative;
+ z-index: 30
+}
+
+.content:after {
+ content: '';
+ display: block;
+ clear: both
+}
+
+.content>aside,
+.content>details,
+.content>dl,
+.content>h1,
+.content>h2,
+.content>h3,
+.content>h4,
+.content>h5,
+.content>h6,
+.content>ol,
+.content>p,
+.content>table,
+.content>ul,
+.content>form>aside,
+.content>form>details,
+.content>form>h1,
+.content>form>h2,
+.content>form>h3,
+.content>form>h4,
+.content>form>h5,
+.content>form>h6,
+.content>form>p,
+.content>form>table,
+.content>form>ul,
+.content>form>div {
+ margin-right: 50%;
+ padding: 0 28px;
+ box-sizing: border-box;
+ display: block;
+ text-shadow: 0 1px 0 #fff
+}
+
+.content>ol,
+.content>ul {
+ padding-left: 43px
+}
+
+.content>div,
+.content>h1,
+.content>h2 {
+ clear: both
+}
+
+.content h1 {
+ font-size: 30px;
+ padding-top: .5em;
+ padding-bottom: .5em;
+ border-bottom: 1px solid #ccc;
+ margin-bottom: 21px;
+ margin-top: 2em;
+ border-top: 1px solid #ddd;
+ background-image: linear-gradient(180deg, #fff, #f9f9f9)
+}
+
+.content div:first-child+h1,
+.content h1:first-child {
+ border-top-width: 0;
+ margin-top: 0
+}
+
+.content h2 {
+ font-size: 20px;
+ margin-top: 4em;
+ margin-bottom: 0;
+ border-top: 1px solid #ccc;
+ padding-top: 1.2em;
+ padding-bottom: 1.2em;
+ background-image: linear-gradient(180deg, hsla(0, 0%, 100%, .4), hsla(0, 0%, 100%, 0))
+}
+
+.content h1+div+h2,
+.content h1+h2 {
+ margin-top: -21px;
+ border-top: none
+}
+
+.content h3,
+.content h4,
+.content h5,
+.content h6 {
+ font-size: 15px;
+ margin-top: 2.5em;
+ margin-bottom: .8em
+}
+
+.content h4,
+.content h5,
+.content h6 {
+ font-size: 10px
+}
+
+.content hr {
+ margin: 2em 0;
+ border-top: 2px solid #393939;
+ border-bottom: 2px solid #eaf2f6
+}
+
+.content table {
+ margin-bottom: 1em;
+ overflow: auto
+}
+
+.content table td,
+.content table th {
+ text-align: left;
+ vertical-align: top;
+ line-height: 1.6
+}
+
+.content table th {
+ padding: 5px 10px;
+ border-bottom: 1px solid #ccc;
+ vertical-align: bottom
+}
+
+.content table td {
+ padding: 10px
+}
+
+.content table tr:last-child {
+ border-bottom: 1px solid #ccc
+}
+
+.content table tr:nth-child(odd)>td {
+ background-color: #ebf3f6
+}
+
+.content table tr:nth-child(even)>td {
+ background-color: #ebf2f6
+}
+
+.content dt {
+ font-weight: 700
+}
+
+.content dd {
+ margin-left: 15px
+}
+
+.content dd,
+.content dt,
+.content li,
+.content p {
+ line-height: 1.6;
+ margin-top: 0
+}
+
+.content img {
+ max-width: 100%
+}
+
+.content code {
+ padding: 3px;
+ border-radius: 3px
+}
+
+.content pre>code {
+ background-color: transparent;
+ padding: 0
+}
+
+.content aside {
+ padding-top: 1em;
+ padding-bottom: 1em;
+ margin-top: 1.5em;
+ margin-bottom: 1.5em;
+ background: #292929;
+ line-height: 1.6;
+ color: #c8c8c8;
+ text-shadow: none;
+}
+
+.content aside.info {
+ background: #8fbcd4;
+ text-shadow: 0 1px 0 #a0c6da;
+ color: initial;
+}
+
+.content aside.warning {
+ background-color: #c97a7e;
+ text-shadow: 0 1px 0 #d18e91;
+ color: initial;
+}
+
+.content aside.success {
+ background-color: #6ac174;
+ text-shadow: 0 1px 0 #80ca89;
+ color: initial;
+}
+
+.content aside:before {
+ vertical-align: middle;
+ padding-right: .5em;
+ font-size: 14px
+}
+
+.content .search-highlight {
+ padding: 2px;
+ margin: -2px;
+ border-radius: 4px;
+ border: 1px solid #f7e633;
+ text-shadow: 1px 1px 0 #666;
+ background: linear-gradient(to top left, #f7e633, #f1d32f)
+}
+
+.content blockquote,
+.content pre {
+ background-color: #292929;
+ color: #fff;
+ padding: 1.5em 28px;
+ margin: 0;
+ width: 50%;
+ float: right;
+ clear: right;
+ box-sizing: border-box;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, .4)
+}
+
+.content .annotation {
+ background-color: #292929;
+ color: #fff;
+ padding: 0 28px;
+ margin: 0;
+ width: 50%;
+ float: right;
+ clear: right;
+ box-sizing: border-box;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, .4)
+}
+
+.content .annotation pre {
+ padding: 0 0;
+ width: 100%;
+ float: none;
+}
+
+.content blockquote>p,
+.content pre>p {
+ margin: 0
+}
+
+.content blockquote a,
+.content pre a {
+ color: #fff;
+ text-decoration: none;
+ border-bottom: 1px dashed #ccc
+}
+
+.content blockquote>p {
+ background-color: #1c1c1c;
+ border-radius: 5px;
+ padding: 13px;
+ color: #ccc;
+ border-top: 1px solid #000;
+ border-bottom: 1px solid #404040
+}
+
+@media (max-width:930px) {
+ .tocify-wrapper {
+ left: -230px
+ }
+ .tocify-wrapper.open {
+ left: 0
+ }
+ .page-wrapper {
+ margin-left: 0
+ }
+ #nav-button {
+ display: block
+ }
+ .tocify-wrapper .tocify-item>a {
+ padding-top: .3em;
+ padding-bottom: .3em
+ }
+}
+
+@media (max-width:700px) {
+ .dark-box {
+ display: none
+ }
+ .tocify-wrapper .lang-selector {
+ display: block
+ }
+ .page-wrapper .lang-selector {
+ display: none
+ }
+ .content aside,
+ .content dl,
+ .content h1,
+ .content h2,
+ .content h3,
+ .content h4,
+ .content h5,
+ .content h6,
+ .content ol,
+ .content p,
+ .content table,
+ .content ul {
+ margin-right: 0
+ }
+ .content>aside,
+ .content>details,
+ .content>dl,
+ .content>h1,
+ .content>h2,
+ .content>h3,
+ .content>h4,
+ .content>h5,
+ .content>h6,
+ .content>ol,
+ .content>p,
+ .content>table,
+ .content>ul,
+ .content>form>aside,
+ .content>form>details,
+ .content>form>h1,
+ .content>form>h2,
+ .content>form>h3,
+ .content>form>h4,
+ .content>form>h5,
+ .content>form>h6,
+ .content>form>p,
+ .content>form>table,
+ .content>form>ul,
+ .content>form>div {
+ margin-right: 0;
+ }
+ .content blockquote,
+ .content pre {
+ float: none;
+ width: auto
+ }
+ .content .annotation {
+ float: none;
+ width: auto
+ }
+}
+
+.badge {
+ padding: 1px 9px 2px;
+ white-space: nowrap;
+ -webkit-border-radius: 9px;
+ -moz-border-radius: 9px;
+ border-radius: 9px;
+ color: #ffffff;
+ text-shadow: none !important;
+ font-weight: bold;
+}
+
+.badge.badge-darkred {
+ background-color: darkred;
+}
+
+.badge.badge-red {
+ background-color: red;
+}
+
+.badge.badge-blue {
+ background-color: blue;
+}
+
+.badge.badge-darkblue {
+ background-color: darkblue;
+}
+
+.badge.badge-green {
+ background-color: green;
+}
+
+.badge.badge-darkgreen {
+ background-color: darkgreen;
+}
+
+.badge.badge-purple {
+ background-color: purple;
+}
+
+.badge.badge-black {
+ background-color: black;
+}
+
+.badge.badge-grey {
+ background-color: grey;
+}
+
+.fancy-heading-panel {
+ background-color: lightgrey;
+ border-radius: 5px;
+ padding-left: 5px !important;
+ padding-top: 5px !important;
+ padding-bottom: 5px !important;
+ margin-left: 25px;
+ margin-right: 10px;
+ width: 47%;
+}
+
+@media screen and (max-width: 700px) {
+ .fancy-heading-panel {
+ width: 95%;
+ }
+
+}
+
+button {
+ border: none;
+}
+
+* {
+ /* Foreground, Background */
+ scrollbar-color: #3c4c67 transparent;
+}
+*::-webkit-scrollbar { /* Background */
+ width: 10px;
+ height: 10px;
+ background: transparent;
+}
+
+*::-webkit-scrollbar-thumb { /* Foreground */
+ background: #626161;
+}
diff --git a/public/vendor/scribe/images/navbar.png b/public/vendor/scribe/images/navbar.png
Binary files differ.
diff --git a/public/vendor/scribe/js/theme-default-4.25.0.js b/public/vendor/scribe/js/theme-default-4.25.0.js
@@ -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();
+});
diff --git a/public/vendor/scribe/js/tryitout-4.25.0.js b/public/vendor/scribe/js/tryitout-4.25.0.js
@@ -0,0 +1,272 @@
+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);
+
+ // 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);
+ }
+ } catch (e) {
+
+ }
+ responseContentEl.textContent = response === '' ? responseContentEl.dataset.emptyResponseText : response;
+ 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 === '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;
+ });
+}
diff --git a/resources/views/scribe/index.blade.php b/resources/views/scribe/index.blade.php
@@ -0,0 +1,107 @@
+<!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>Home ERP Documentation</title>
+
+ <link href="https://fonts.googleapis.com/css?family=Open+Sans&display=swap" rel="stylesheet">
+
+ <link rel="stylesheet" href="{{ asset("/vendor/scribe/css/theme-default.style.css") }}" media="screen">
+ <link rel="stylesheet" href="{{ asset("/vendor/scribe/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>
+
+ <style id="language-style">
+ /* starts out as display none and is replaced with js later */
+ body .content .bash-example code { display: none; }
+ body .content .javascript-example code { display: none; }
+ </style>
+
+ <script>
+ var tryItOutBaseUrl = "http://localhost";
+ var useCsrf = Boolean();
+ var csrfUrl = "/sanctum/csrf-cookie";
+ </script>
+ <script src="{{ asset("/vendor/scribe/js/tryitout-4.25.0.js") }}"></script>
+
+ <script src="{{ asset("/vendor/scribe/js/theme-default-4.25.0.js") }}"></script>
+
+</head>
+
+<body data-languages="["bash","javascript"]">
+
+<a href="#" id="nav-button">
+ <span>
+ MENU
+ <img src="{{ asset("/vendor/scribe/images/navbar.png") }}" alt="navbar-image"/>
+ </span>
+</a>
+<div class="tocify-wrapper">
+
+ <div class="lang-selector">
+ <button type="button" class="lang-button" data-language-name="bash">bash</button>
+ <button type="button" class="lang-button" data-language-name="javascript">javascript</button>
+ </div>
+
+ <div class="search">
+ <input type="text" class="search" id="input-search" placeholder="Search">
+ </div>
+
+ <div id="toc">
+ <ul id="tocify-header-introduction" class="tocify-header">
+ <li class="tocify-item level-1" data-unique="introduction">
+ <a href="#introduction">Introduction</a>
+ </li>
+ </ul>
+ <ul id="tocify-header-authenticating-requests" class="tocify-header">
+ <li class="tocify-item level-1" data-unique="authenticating-requests">
+ <a href="#authenticating-requests">Authenticating requests</a>
+ </li>
+ </ul>
+ </div>
+
+ <ul class="toc-footer" id="toc-footer">
+ <li style="padding-bottom: 5px;"><a href="{{ route("scribe.postman") }}">View Postman collection</a></li>
+ <li style="padding-bottom: 5px;"><a href="{{ route("scribe.openapi") }}">View OpenAPI spec</a></li>
+ <li><a href="http://github.com/knuckleswtf/scribe">Documentation powered by Scribe ✍</a></li>
+ </ul>
+
+ <ul class="toc-footer" id="last-updated">
+ <li>Last updated: October 18, 2023</li>
+ </ul>
+</div>
+
+<div class="page-wrapper">
+ <div class="dark-box"></div>
+ <div class="content">
+ <h1 id="introduction">Introduction</h1>
+<aside>
+ <strong>Base URL</strong>: <code>http://localhost</code>
+</aside>
+<p>This documentation aims to provide all the information you need to work with our API.</p>
+
+ <h1 id="authenticating-requests">Authenticating requests</h1>
+<p>To authenticate requests, include an <strong><code>Authorization</code></strong> header with the value <strong><code>"Bearer {YOUR_AUTH_KEY}"</code></strong>.</p>
+<p>All authenticated endpoints are marked with a <code>requires authentication</code> badge in the documentation below.</p>
+<p>You can retrieve your token by visiting your dashboard and clicking <b>Generate API token</b>.</p>
+
+
+
+ </div>
+ <div class="dark-box">
+ <div class="lang-selector">
+ <button type="button" class="lang-button" data-language-name="bash">bash</button>
+ <button type="button" class="lang-button" data-language-name="javascript">javascript</button>
+ </div>
+ </div>
+</div>
+</body>
+</html>