├── .gitignore
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── composer.json
├── config
└── blueprintdocs.php
├── example.apib
├── package-lock.json
├── package.json
├── public
├── css
│ ├── app.css
│ ├── blueprintdocs.css
│ └── vendor.css
├── fonts
│ └── vendor
│ │ └── bootstrap-sass
│ │ └── bootstrap
│ │ ├── glyphicons-halflings-regular.eot
│ │ ├── glyphicons-halflings-regular.svg
│ │ ├── glyphicons-halflings-regular.ttf
│ │ ├── glyphicons-halflings-regular.woff
│ │ └── glyphicons-halflings-regular.woff2
├── js
│ ├── app.js
│ └── blueprintdocs.js
└── mix-manifest.json
├── resources
├── assets
│ ├── js
│ │ ├── app.js
│ │ └── blueprintdocs.js
│ └── sass
│ │ ├── _highlight.scss
│ │ ├── _variables.scss
│ │ ├── app.scss
│ │ └── blueprintdocs.scss
└── views
│ ├── action.blade.php
│ ├── index.blade.php
│ ├── navigation.blade.php
│ ├── parameters.blade.php
│ ├── requestresponsebody.blade.php
│ ├── resource.blade.php
│ └── resource_group.blade.php
├── src
├── BlueprintDocs.php
├── BlueprintDocsController.php
├── BlueprintDocsServiceProvider.php
├── DescriptionParser.php
├── Elements
│ ├── Action.php
│ ├── Api.php
│ ├── Asset.php
│ ├── Base.php
│ ├── HrefVariable.php
│ ├── HttpRequest.php
│ ├── HttpResponse.php
│ ├── Mapping.php
│ ├── Resource.php
│ └── ResourceGroup.php
└── routes.php
└── webpack.mix.js
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /vendor
3 | .DS_Store
4 | .idea
5 | composer.lock
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | When wanting to contribute to this repository, please first
4 |
5 | * discuss the change you wish to make via issue,
6 | email, or any other method with the owners of this repository,
7 | * follow this excellent tutorial on [How To Create a Pull Request on GitHub](https://www.digitalocean.com/community/tutorials/how-to-create-a-pull-request-on-github) and
8 | * acknowledge our Code of Conduct in all your interactions with the project.
9 |
10 | ## Code of Conduct
11 |
12 | ### Our Pledge
13 |
14 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
15 |
16 | ### Our Standards
17 |
18 | Examples of behavior that contributes to creating a positive environment include:
19 |
20 | * Using welcoming and inclusive language
21 | * Being respectful of differing viewpoints and experiences
22 | * Gracefully accepting constructive criticism
23 | * Focusing on what is best for the community
24 | * Showing empathy towards other community members
25 |
26 | Examples of unacceptable behavior by participants include:
27 |
28 | * The use of sexualized language or imagery and unwelcome sexual attention or
29 | advances
30 | * Trolling, insulting/derogatory comments, and personal or political attacks
31 | * Public or private harassment
32 | * Publishing others' private information, such as a physical or electronic
33 | address, without explicit permission
34 | * Other conduct which could reasonably be considered inappropriate in a
35 | professional setting
36 |
37 | ### Our Responsibilities
38 |
39 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
40 |
41 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
42 |
43 | ### Scope
44 |
45 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
46 |
47 | ### Enforcement
48 |
49 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
50 |
51 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
52 |
53 | ### Attribution
54 |
55 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
56 |
57 | [homepage]: http://contributor-covenant.org
58 | [version]: http://contributor-covenant.org/version/1/4/
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2018 Michael Schmidt-Voigt
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | # API Blueprint Renderer for Laravel
12 |
13 | This Laravel package *Blueprint Docs* renders your [API Blueprint](http://apiblueprint.org/). It comes with a standard theme that you can customize via Blade templates. Install the package and find your rendered documentation at route `/api-documentation`.
14 |
15 | **Example output**: If used with [API Blueprint boilerplate](https://github.com/jsynowiec/api-blueprint-boilerplate), this would be [*Blueprint Docs'* output](https://m165437.github.io/laravel-blueprint-docs).
16 |
17 | API Blueprint is a Markdown-based document format that lets you write API descriptions and documentation in a simple and straightforward way. Currently supported is [API Blueprint format 1A](https://github.com/apiaryio/api-blueprint/blob/master/API%20Blueprint%20Specification.md).
18 |
19 | ## Requirements
20 |
21 | * Laravel 5.4 or greater
22 | * Drafter (the official C++ API Blueprint parser) [command line tool](https://github.com/apiaryio/drafter#drafter-command-line-tool)
23 | * A valid API Blueprint `blueprint.apib` in the root directory of your Laravel project (example available)
24 |
25 | **Drafter is not included** and must be installed beforehand. Use the [Drafter Installer](https://github.com/hendrikmaus/drafter-installer) composer package to "install drafter in your php project with ease". Head over there and install it now.
26 |
27 | ## Installation
28 |
29 | Install the package via composer:
30 |
31 | ``` bash
32 | composer require m165437/laravel-blueprint-docs
33 | ```
34 |
35 | Next, register its service provider (Laravel >= 5.5 does this automatically via [Package Discovery](https://laravel.com/docs/5.5/packages#package-discovery)):
36 |
37 | ```php
38 | // config/app.php
39 | 'providers' => [
40 | ...
41 | M165437\BlueprintDocs\BlueprintDocsServiceProvider::class,
42 | ];
43 | ```
44 |
45 | Optionally, publish the example [API Blueprint boilerplate](https://github.com/jsynowiec/api-blueprint-boilerplate) file `blueprint.apib` to the root directory of your Laravel project:
46 |
47 | ```bash
48 | php artisan vendor:publish --provider="M165437\BlueprintDocs\BlueprintDocsServiceProvider" --tag="example"
49 | ```
50 |
51 | Finally, publish its assets to `public/vendor/blueprintdocs`:
52 |
53 | ```bash
54 | php artisan vendor:publish --provider="M165437\BlueprintDocs\BlueprintDocsServiceProvider" --tag="public"
55 | ```
56 |
57 | Find your documentation at route `/api-documentation`.
58 |
59 | ## Update
60 |
61 | When you update this package, you might need to republish its assets (note the added parameter `--force`):
62 |
63 | ```bash
64 | php artisan vendor:publish --provider="M165437\BlueprintDocs\BlueprintDocsServiceProvider" --tag="public" --force
65 | ```
66 |
67 | ## Configuration
68 |
69 | To adjust Blueprint Docs' configuration, publish its config file to `config/blueprintdocs.php`:
70 |
71 | ``` bash
72 | php artisan vendor:publish --provider="M165437\BlueprintDocs\BlueprintDocsServiceProvider" --tag="config"
73 | ```
74 |
75 | The default contents of the configuration file look like this:
76 |
77 | ```php
78 | return [
79 |
80 | /*
81 | |--------------------------------------------------------------------------
82 | | Blueprint Docs
83 | |--------------------------------------------------------------------------
84 | |
85 | | Find your rendered docs at the given route or set route to false if you
86 | | want to use your own route and controller. Provide a fully qualified
87 | | path to your API blueprint as well as to the required Drafter CLI.
88 | |
89 | */
90 |
91 | 'route' => 'api-documentation',
92 |
93 | 'condense_navigation' => false,
94 |
95 | 'blueprint_file' => base_path('blueprint.apib'),
96 |
97 | 'drafter' => base_path('vendor/bin/drafter')
98 |
99 | ];
100 | ```
101 |
102 | If you want to use Blueprint Docs with your own route and controller, set `'route' => false` and have a look at `vendor/m165437/laravel-blueprint-docs/src/BlueprintDocsController.php` to get an idea on how to set it up.
103 |
104 | ## Theming
105 |
106 | To customize the default theme, publish its views to `views/vendor/blueprintdocs`:
107 |
108 | ``` bash
109 | php artisan vendor:publish --provider="M165437\BlueprintDocs\BlueprintDocsServiceProvider" --tag="views"
110 | ```
111 |
112 | ## Contributing
113 |
114 | Thank you for considering contributing to this package! Please see [CONTRIBUTING](CONTRIBUTING.md) for details.
115 |
116 | ## Credits
117 |
118 | This package relies heavily on work done by [Hendrik Maus](https://github.com/hendrikmaus), namely his [Drafter PHP Wrapper](https://github.com/hendrikmaus/drafter-php) and [Reynaldo](https://github.com/hendrikmaus/reynaldo), it's inspired by [Aglio](https://github.com/danielgtaylor/aglio), an API Blueprint renderer written in Node.js, and provides the [API Blueprint boilerplate](https://github.com/jsynowiec/api-blueprint-boilerplate) as an example. The header is the modified part of a [graphic created by Iconicbestiary](http://www.freepik.com/free-vector/hands-signing-house-or-apartment-contract_1311557.htm), via [Freepik.com](http://www.freepik.com).
119 |
120 | ## License
121 |
122 | Blueprint Docs is licensed under the MIT License (MIT). Please see the [LICENSE](LICENSE.md) file for more information.
123 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "m165437/laravel-blueprint-docs",
3 | "description": "API Blueprint Renderer for Laravel",
4 | "keywords": [
5 | "api",
6 | "blueprint",
7 | "renderer",
8 | "laravel",
9 | "docs"
10 | ],
11 | "license": "MIT",
12 | "homepage": "https://github.com/M165437/laravel-blueprint-docs",
13 | "authors": [
14 | {
15 | "name": "Michael Schmidt-Voigt",
16 | "email": "michael@schmidt-voigt.de",
17 | "homepage": "https://github.com/M165437",
18 | "role": "Developer"
19 | }
20 | ],
21 | "require": {
22 | "php": ">=5.6.4",
23 | "laravel/framework": ">=5.4|~7.0",
24 | "hmaus/drafter-php": "^6.1.1",
25 | "hmaus/reynaldo": "^0.1.5",
26 | "erusev/parsedown": "^1.7.0",
27 | "erusev/parsedown-extra": "^0.7.1"
28 | },
29 | "autoload": {
30 | "psr-4": {
31 | "M165437\\BlueprintDocs\\": "src/"
32 | }
33 | },
34 | "extra": {
35 | "laravel": {
36 | "providers": [
37 | "M165437\\BlueprintDocs\\BlueprintDocsServiceProvider"
38 | ]
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/config/blueprintdocs.php:
--------------------------------------------------------------------------------
1 | 'api-documentation',
17 |
18 | 'condense_navigation' => false,
19 |
20 | 'blueprint_file' => base_path('blueprint.apib'),
21 |
22 | 'drafter' => base_path('vendor/bin/drafter')
23 |
24 | ];
--------------------------------------------------------------------------------
/example.apib:
--------------------------------------------------------------------------------
1 | FORMAT: 1A
2 | HOST: https://api.example.com
3 |
4 | # Blueprint Docs
5 |
6 | *This API blueprint is subject to change due to technology restrictions, performance optimizations or changing requirements.*
7 |
8 | ## Authentication
9 |
10 | + This API uses [JWT](http://jwt.io/) for authentication,
11 | + Every token MUST be refreshed before its expiration time,
12 | + Token MUST be provided in `Authorization` header,
13 | + Toke MUST be provided for each request that requires authentication,
14 | + This API issues a **long-lived access tokens** for consumers. A long-lived JWT generally SHOULD lasts about **30 days**. If no requests are made, the token MUST expire and the user MUST go through the login flow again to get a new one.
15 |
16 | > A custom scheme like "JWT" seems to be more appropriate than coercing the OAuth2 Bearer scheme.
17 |
18 | ### Example Header
19 | ```
20 | Authorization: JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhNnZoQW8zRkc3dDEiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE0NzA1OTg5NzIsImV4cCI6MTQ3MDY4NTM3Mn0.ltA9zZmJKszBJuuV7pTWtY7LzLXrRUfebJDhy_jGMeM
21 | ```
22 |
23 | ### Claims
24 | + `exp` - The exp ( *expiration time* ) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing.
25 | + `iat` - The iat ( *issued at* ) claim identifies the time at which the JWT was issued.
26 | + `sub` - The aud ( *audience* ) claim identifies the subject of this token (for e.g. a user id).
27 | + `iss` - The iss ( *issuer* ) claim identifies the principal that issued the JWT.
28 |
29 | ## Consumer Identification
30 |
31 | This API uses `User-Agent` and `Application-Id` headers to identify API consumer. `Application-Id` MUST contain an UUID that uniquely identifies a particular consumer installation.
32 |
33 | ### Example Headers
34 | ```
35 | User-Agent: Mozilla/5.0 (Linux; Android 4.4; Nexus 5 Build/_BuildID_) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36
36 | Application-Id: 6454d937-0a18-44a8-b482-bb48684f1ed4
37 | ```
38 |
39 | ## Filtering, Ordering, Pagination & Searching
40 |
41 | ### Filtering
42 |
43 | This API can filter returned collections based on provided query parameters. Virtually any model field can be used as a filter.
44 |
45 | For example, when requesting a list of movies from the /movies endpoint, you may want to limit these to only those of drama genre. This could be accomplished with a request like `GET /movies?genre=drama`. Here, genre is a query parameter that implements a filter.
46 |
47 | ### Ordering
48 |
49 | This API can sort returned collections. A generic query parameter `sort` is used to describe sorting rules. This parameter can take a list of comma separated field, each with a possible unary negative to imply descending sort order.
50 |
51 | E.g. `GET /movies?sort=-rating` - Retrieves a list of movies in descending order of user rating.
52 |
53 | By default all resources are ordered by their creation time, from newest to oldest.
54 |
55 | ### Pagination
56 |
57 | This API uses the [Link header - RFC 5988](http://tools.ietf.org/html/rfc5988#page-6) to include pagination details.
58 |
59 | An example of a Link header is described in [GitHub documentation](https://developer.github.com/guides/traversing-with-pagination/).
60 |
61 | This API returns total count of paged resources in `Total-Count` HTTP header.
62 |
63 | ### Searching
64 |
65 | This API uses a generic parameter `search` to expose a full text search mechanism.
66 |
67 | ## HTTP Methods
68 |
69 | This API uses HTTP verbs (methods) as following:
70 |
71 | + `GET` - *Read* - used to **read** (or retrieve) a representation of a resource,
72 | + `POST` - *Create* - used to **create** new resources. In particular, it's used to create subordinate resources.
73 | + `PUT` - *Update/Replace* - used for **update** capabilities, PUT-ing to a known resource URI with the request body containing the newly-updated representation of the original resource. On successful request, replaces identified resource with the request body.
74 | + `PATCH` - *Update/Modify* - used for **modify** capabilities. The PATCH request only needs to contain the changes to the resource, not the complete resource.
75 | + `DELETE` - *Delete* - used to **delete** a resource identified by a URI.
76 |
77 | ## Localization
78 |
79 | This API uses `Accept-Language` header to identify the locale.
80 |
81 | `Accept-Language: en`
82 |
83 | This header SHOULD be present in every request. If not, API MUST use the **english** language/locale.
84 |
85 | ## Media Type
86 |
87 | Where applicable this API MUST use the JSON media-type. Requests with a message-body are using plain JSON to set or update resource states.
88 |
89 | `Content-type: application/json` and `Accept: application/json` headers SHOULD be set on all requests if not stated otherwise.
90 |
91 | ## Notational Conventions
92 |
93 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119](https://www.ietf.org/rfc/rfc2119).
94 |
95 | ## Representation of Date and Time
96 |
97 | All exchange of date and time-related data MUST be done according to ISO 8601 standard and stored in UTC.
98 |
99 | When returning date and time-related data `YYYY-MM-DDThh:mm:ss.SSSZ` format MUST be used.
100 |
101 | ## Resource IDs
102 |
103 | This API uses short non-sequential url-friendly unique ids. Every resource id MUST consists of 9 url-friendly characters: `A-Z`, `a-z`, `0-9`, `_` and `-`.
104 |
105 | ### Example
106 | `a6vhAo3FG7t1`
107 |
108 | ## Status Codes and Errors
109 |
110 | This API uses HTTP status codes to communicate with the API consumer.
111 |
112 | + `200 OK` - Response to a successful GET, PUT, PATCH or DELETE.
113 | + `201 Created` - Response to a POST that results in a creation.
114 | + `204 No Content` - Response to a successful request that won't be returning a body (like a DELETE request).
115 | + `400 Bad Request` - Malformed request; form validation errors.
116 | + `401 Unauthorized` - When no or invalid authentication details are provided.
117 | + `403 Forbidden` - When authentication succeeded but authenticated user doesn't have access to the resource.
118 | + `404 Not Found` - When a non-existent resource is requested.
119 | + `405 Method Not Allowed` - Method not allowed.
120 | + `406 Not Acceptable` - Could not satisfy the request Accept header.
121 | + `415 Unsupported Media Type` - Unsupported media type in request.
122 |
123 | ### Error response
124 |
125 | This API returns both, machine-readable error codes and human-readable error messages in response body when an error is encountered.
126 |
127 | #### Example
128 |
129 | ##### Validation Error
130 |
131 | ```js
132 | {
133 | "statusCode": 400,
134 | "error": "Bad Request",
135 | "message": "Invalid query parameters",
136 | "data": {
137 | "code": 10003,
138 | "validation": {
139 | "details":[
140 | {
141 | "message": "\"name\" is required",
142 | "path": "name",
143 | "type": "any.required",
144 | "context": {
145 | "key": "name"
146 | }
147 | },{
148 | "message": "\"email\" must be a valid email",
149 | "path": "email",
150 | "type": "string.email",
151 | "context": {
152 | "value": "foo",
153 | "key": "email"
154 | }
155 | }
156 | ],
157 | "source": "query",
158 | "keys": [ "name","email" ]
159 | }
160 | }
161 | }
162 | ```
163 |
164 | ##### Generic Error
165 |
166 | ```js
167 | {
168 | "statusCode": 403,
169 | "error": "Forbidden",
170 | "message": "Your account is suspended and is not permitted to access this feature",
171 | "data": {
172 | "code": 13003
173 | }
174 | }
175 | ```
176 |
177 | #### Error Codes Dictionary
178 |
179 | + `10003` - Invalid query parameters
180 | + `10005` - Date is not in ISO 8601 standard
181 | + `10010` - Invalid Content-Type
182 | + `10011` - Invalid User-Agent
183 | + `10012` - Invalid or missing Application-Id
184 | + `11001` - Invalid or expired token
185 | + `11003` - Bad authentication data - *Method requires authentication but it was not presented or was wholly invalid.*
186 | + `11005` - Account not allowed to access this endpoint
187 | + `13003` - Your account is suspended and is not permitted to access this feature
188 |
189 | ## Versioning
190 |
191 | This API uses `Api-Version` header to identify requested version. Every **minor** version SHOULD be backward compatible. However, **major** versions MAY introduce *breaking changes*.
192 |
193 | `Api-Version: 1.0.0`
194 |
195 | This header SHOULD be present in every request. If not, API MUST use the newest available major release.
196 |
197 | If requested version is not available, API SHOULD try to fall back to the next available minor release.
198 |
199 | # Group Authentication
200 |
201 | ## User login [/auth/login]
202 |
203 | Access tokens are required to access nearly all endpoints of this API.
204 |
205 | ### Retrieve a token [POST]
206 |
207 | Allows to retrieve a valid JSON Web Token for username and password.
208 |
209 | **Endpoint information**
210 |
211 | | | |
212 | |-------------------------|-----|
213 | | Requires authentication | No |
214 | | Has restricted scope | No |
215 |
216 | + Request (application/json)
217 | + Attributes
218 | + login: `john.doe@mail.com` (string, required) - User email address
219 | + password: `QXR0mi38a2` (string, required) - User password
220 |
221 | + Response 200 (application/json)
222 | + Attributes
223 | + token: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9....` (string) - JSON Web Token.
224 |
225 | ## Refresh a token [POST /auth/refresh-token]
226 |
227 | Allows to retrieve a new, valid JSON Web Token based on a valid JSON Web Token.
228 |
229 | Expired tokens MUST NOT be refreshed.
230 |
231 | **Endpoint information**
232 |
233 | | | |
234 | |-------------------------|-----|
235 | | Requires authentication | Yes |
236 | | Has restricted scope | No |
237 |
238 | + Request
239 | + Headers
240 |
241 | Authorization: JWT
242 |
243 | + Response 200 (application/json)
244 | + Attributes
245 | + token: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9....` (string) - New JWT
246 |
247 | ## User registration [/auth/register]
248 |
249 | ### Register a new user [POST]
250 |
251 | Creates a new user account.
252 |
253 | + Provided email address MUST be unique.
254 | + Passwords MUST have at least six characters.
255 | + Passwords MUST NOT contain the user name or parts of the user’s full name, such as his first name.
256 | + Passwords MUST use at least three of the four available character types: lowercase letters, uppercase letters, numbers, and symbols.
257 |
258 | After successful registration a confirmation email MUST be sent to provided address.
259 |
260 | **Endpoint information**
261 |
262 | | | |
263 | |-------------------------|-----|
264 | | Requires authentication | No |
265 |
266 | **Error codes**
267 |
268 | | | | |
269 | |-------|---------| ------------------------------------------- |
270 | | `400` | `4001` | Password doesn't match password guidelines |
271 | | `400` | `3001` | User already exists |
272 |
273 | + Request (application/json)
274 | + Attributes
275 | + email: `john.doe@mail.com` (string, required) - E-mail address.
276 | + password: `QXR0mi38a2` (string, required) - User password.
277 |
278 | + Response 201
279 |
280 | # Group User
281 |
282 | ## Current user profile [/users/me]
283 |
284 | Current user MUST be identifed by JWT provided in request header.
285 |
286 | ### Retrieve profile of the current user [GET]
287 |
288 | Retrieves the profile of the current user.
289 |
290 | **Endpoint information**
291 |
292 | | | |
293 | |-------------------------|-----|
294 | | Requires authentication | Yes |
295 | | Has restricted scope | No |
296 |
297 | + Request
298 | + Headers
299 |
300 | Authorization: JWT
301 |
302 | + Response 200 (application/json)
303 | + Attributes (User)
304 |
305 | ### Partialy update a profile of the current user [PATCH]
306 |
307 | Updates a profile of the current user setting the values of the parameters passed. Any parameters not provided will be left unchanged.
308 |
309 | **Endpoint information**
310 |
311 | | | |
312 | |-------------------------|-----|
313 | | Requires authentication | Yes |
314 | | Has restricted scope | No |
315 |
316 | + Request (application/json)
317 | + Headers
318 |
319 | Authorization: JWT
320 | + Attributes
321 | + name: `Ben` (string) - First name of the user.
322 |
323 | + Response 200 (application/json)
324 | + Attributes (User)
325 |
326 | ## User password [/users/me/password]
327 |
328 | ### Change a password of the current user [PUT]
329 |
330 | Changes user password.
331 |
332 | After password is changed all access tokens issued for this user prior to password change must be invalidated.
333 |
334 | **Endpoint information**
335 |
336 | | | |
337 | |-------------------------|-----|
338 | | Requires authentication | Yes |
339 | | Has restricted scope | No |
340 |
341 | **Error codes**
342 |
343 | | | | |
344 | |-------|---------| ----------------------------------------- |
345 | | `400` | `4001` | Password doesn't match password guidelines |
346 |
347 | + Request (application/json)
348 | + Headers
349 |
350 | Authorization: JWT
351 | + Attributes
352 | + old_password: `secret` (string, required)
353 | + new_password: `$3C6e7` (string, required)
354 |
355 | + Response 200
356 | + Attributes
357 | + token: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...` (string) - New JSON Web Token.
358 |
359 | ## User avatar [/users/me/avatar]
360 |
361 | ### Set user avatar [POST]
362 |
363 | Sets user avatar.
364 |
365 | Either upload the raw binary ( **media** parameter) of the file, or its base64-encoded contents ( **media_data** parameter). Use raw binary when possible, because base64 encoding results in larger file sizes.
366 |
367 | **Endpoint information**
368 |
369 | | | |
370 | |-------------------------|-----|
371 | | Requires authentication | Yes |
372 | | Has restricted scope | No |
373 |
374 | **Error codes**
375 |
376 | | | | |
377 | |-------|---------| --------------------- |
378 | | `400` | `2001` | File is too large |
379 | | `400` | `2002` | Unsupported file type |
380 |
381 | + Request (multipart/form-data)
382 | + Headers
383 |
384 | Authorization: JWT
385 |
386 | + Response 200
387 | + Attributes
388 | + avatar: `https://...` (string) - Public download URL
389 |
390 | ### Delete user avatar [DELETE]
391 |
392 | Restores user avatar to the default one.
393 |
394 | **Endpoint information**
395 |
396 | | | |
397 | |-------------------------|-----|
398 | | Requires authentication | Yes |
399 | | Has restricted scope | No |
400 |
401 | + Request
402 | + Headers
403 |
404 | Authorization: JWT
405 |
406 | + Response 204
407 |
408 | ## Users [/users]
409 |
410 | ### List all users [GET]
411 |
412 | Returns a list of users. The users are returned in sorter order, with the most recently created user accounts appearing first.
413 |
414 | | | |
415 | |-------------------------|-----|
416 | | Requires authentication | Yes |
417 | | Has restricted scope | No |
418 |
419 | + Request
420 | + Headers
421 |
422 | Authorization: JWT
423 |
424 | + Response 200 (application/json)
425 | + Attributes (array[User])
426 |
427 | ## User [/users/{id}]
428 |
429 | + Parameters
430 | + id: `a6vhAo3FG7t1` (string) - id of the user.
431 |
432 | ### Retrieve a user [GET]
433 |
434 | Retrieves the details of an existing user.
435 |
436 | | | |
437 | |-------------------------|-----|
438 | | Requires authentication | Yes |
439 | | Has restricted scope | No |
440 |
441 | **Error codes**
442 |
443 | | | | |
444 | |-------|---------| ----------------------------- |
445 | | `400` | `1000` | Referenced resource not found |
446 |
447 | + Request
448 | + Headers
449 |
450 | Authorization: JWT
451 |
452 | + Response 200 (application/json)
453 | + Attributes (User)
454 |
455 | + Response 404
456 |
457 | # Data Structures
458 |
459 | ## Resource (object)
460 | + id: `a6vhAo3FG7t1` (string, fixed) - Short non-sequential url-friendly unique id.
461 | + createdAt: `2016-07-01T15:11:09.553Z` (string) - ISO Date/time string. When this resource was created.
462 | + updatedAt: `2016-07-01T15:11:09.553Z` (string) - ISO Date/time string. When this resource was last updated.
463 |
464 | ## User (Resource)
465 | + email: `john.doe@mail.com` (string, required) - Login. Unique email address of the user.
466 | + facebookId: `888047057953991` (number, optional, nullable) - Facebook ID of the user if user account is linked to the Facebook account.
467 | + name: `John` (string, optional, nullable) - First name of the user.
468 | + surname: `Doe` (string, optional, nullable) - Last name of the user.
469 | + avatar (string, optional, nullable) - URL to user avatar.
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "dev": "npm run development",
5 | "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
6 | "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
7 | "watch-poll": "npm run watch -- --watch-poll",
8 | "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
9 | "prod": "npm run production",
10 | "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
11 | },
12 | "devDependencies": {
13 | "bootstrap-sass": "^3.4.1",
14 | "cross-env": "^5.2.0",
15 | "css-element-queries": "^1.1.1",
16 | "highlight.js": "^10.4.1",
17 | "jquery": "^3.5.0",
18 | "laravel-mix": "^4.0.14",
19 | "resolve-url-loader": "2.3.1",
20 | "sass": "^1.26.3",
21 | "sass-loader": "7.*",
22 | "sticky-sidebar": "^3.3.1",
23 | "vue-template-compiler": "^2.6.7"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/public/css/blueprintdocs.css:
--------------------------------------------------------------------------------
1 | .hljs-comment,.hljs-quote{color:#8e908c}.hljs-attr,.hljs-attribute,.hljs-deletion,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#c82829}.hljs-built_in,.hljs-builtin-name,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-params,.hljs-type{color:#f5871f}.hljs-addition,.hljs-bullet,.hljs-string,.hljs-symbol{color:#718c00}.hljs-section,.hljs-title{color:#4271ae}.hljs-keyword,.hljs-selector-tag{color:#8959a8}.hljs{display:block;overflow-x:auto;background:transparent;color:#4d4d4c;padding:.5em}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}pre{border:1px solid #e6e6e6}.sidebar{display:none;float:left;margin:0 15px;will-change:min-height}@media (min-width:992px){.sidebar{display:block;width:293px}}@media (min-width:1200px){.sidebar{display:block;width:360px}}.sidebar__inner{position:relative;-webkit-transform:translate(0);transform:translate(0);-webkit-transform:translateZ(0);transform:translateZ(0);will-change:position,transform;overflow:auto}.host{margin-bottom:22px;text-align:center;word-wrap:break-word}.main{margin-left:0;padding:0 15px}@media (min-width:992px){.main{margin-left:323px}}@media (min-width:1200px){.main{margin-left:390px}}.panel{border:1px solid #d3e0e9;overflow:hidden}.panel-group .panel{margin-bottom:22px;border-radius:4px}.panel-collapsable .panel-heading{padding:10px 15px;color:#333;border-color:#d3e0e9;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px;background-color:#f5f5f5}.panel-collapsable .panel-title{font-size:15px;line-height:1.6}.panel-collapsable .panel-title a{position:relative}.panel-collapsable .panel-title a:active,.panel-collapsable .panel-title a:hover,.panel-collapsable .panel-title a:link,.panel-collapsable .panel-title a:visited{text-decoration:none}.panel-collapsable .panel-title a.collapsed:after{content:"+";line-height:1}.panel-collapsable .panel-body{padding:0}.panel-body,.stacked-tabs{font-weight:300}.stacked-tabs{border-radius:4px}.stacked-tabs a{border-top:1px solid #e4ecf2;border-left:2px solid transparent;color:#636b6f}.stacked-tabs li a:active,.stacked-tabs li a:hover,.stacked-tabs li a:link,.stacked-tabs li a:visited{background-color:#fff}.stacked-tabs li a:hover{border-left-color:#e4ecf2}.stacked-tabs ul li a{padding-left:30px}.stacked-tabs li .method{display:inline-block;float:right}.panel-description .panel-title{font-size:36px;line-height:1.8;color:#636b6f}.panel-resource-group>.panel-heading .panel-title{font-size:18px;line-height:1.6}.panel-description h2{margin-top:30px;font-size:23px}.panel-description h3{margin-top:30px;font-size:20px}.panel-description h4{font-size:16px;font-weight:700;margin-top:30px}.panel-default>.panel-heading{color:inherit}.panel-action .panel-title{font-size:15px;line-height:1.6}.panel-action .panel-title .name{float:right;padding:3px 0}.panel-action .panel-title .method{display:inline-block;margin-right:12px;padding:3px 12px;font-size:14px;font-weight:600;border-radius:3px}.panel-action .panel-title .method.get,.panel-action .panel-title .method.head,.panel-action .panel-title .method.options{color:#fff;background-color:#337ab7}.panel-action .panel-title .method.patch,.panel-action .panel-title .method.put{color:#fff;background-color:#ed9c28}.panel-action .panel-title .method.post{color:#fff;background-color:#5cb85c}.panel-action .panel-title .method.delete{color:#fff;background-color:#d9534f}.panel-action .definition{margin:0 0 11px}.panel-action .definition .uri{color:#000}.panel-action .definition .uri .hostname{color:#636b6f}.panel-action .panel-footer{background-color:#fff}.panel-action .panel-footer .nav-pills>li.active>a,.panel-action .panel-footer .nav-pills>li.active>a:hover{color:#216a94;background-color:#f5f5f5}.panel-action .panel-footer .tab-pane.active>:first-child{margin-top:15px}.main ul li p{margin:0}.main table{margin:0 0 11px}.main table td,.main table th{padding:6px 12px;vertical-align:top;border:1px solid #e6e6e6}.panel-collapsable .panel-title a:after{content:"-";position:absolute;top:0;right:0;font-size:25px;font-weight:200;line-height:.8}.main .parameters table{width:100%;margin-top:10px}.main .parameters table p{margin:0}.method{margin-right:5px;font-weight:600}.method.get,.method.head,.method.options{color:#337ab7}.method.patch,.method.put{color:#ed9c28}.method.post{color:#5cb85c}.method.delete{color:#d9534f}
--------------------------------------------------------------------------------
/public/css/vendor.css:
--------------------------------------------------------------------------------
1 | .hljs{display:block;overflow-x:auto;padding:.5em;background:#fdf6e3;color:#657b83}.hljs-comment,.hljs-quote{color:#93a1a1}.hljs-addition,.hljs-keyword,.hljs-selector-tag{color:#859900}.hljs-doctag,.hljs-literal,.hljs-meta .hljs-meta-string,.hljs-number,.hljs-regexp,.hljs-string{color:#2aa198}.hljs-name,.hljs-section,.hljs-selector-class,.hljs-selector-id,.hljs-title{color:#268bd2}.hljs-attr,.hljs-attribute,.hljs-class .hljs-title,.hljs-template-variable,.hljs-type,.hljs-variable{color:#b58900}.hljs-bullet,.hljs-link,.hljs-meta,.hljs-meta .hljs-keyword,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-subst,.hljs-symbol{color:#cb4b16}.hljs-built_in,.hljs-deletion{color:#dc322f}.hljs-formula{background:#eee8d5}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}
--------------------------------------------------------------------------------
/public/fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/M165437/laravel-blueprint-docs/cea446aa6a78ce6a6b0f086fb0cc65c4bd9264ff/public/fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/public/fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/public/fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/M165437/laravel-blueprint-docs/cea446aa6a78ce6a6b0f086fb0cc65c4bd9264ff/public/fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/public/fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/M165437/laravel-blueprint-docs/cea446aa6a78ce6a6b0f086fb0cc65c4bd9264ff/public/fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/public/fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/M165437/laravel-blueprint-docs/cea446aa6a78ce6a6b0f086fb0cc65c4bd9264ff/public/fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/public/js/blueprintdocs.js:
--------------------------------------------------------------------------------
1 | !function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=4)}([,,,,function(e,t,n){e.exports=n(5)},function(e,t,n){window.ResizeSensor=n(6),n(7);var i=n(8);i.registerLanguage("http",n(9)),i.registerLanguage("json",n(10)),$(document).ready(function(){var e=new StickySidebar(".sidebar",{topSpacing:22,bottomSpacing:0,containerSelector:".content-wrapper",innerWrapperSelector:".sidebar__inner",resizeSensor:!0});$(window).resize(function(){e.updateSticky()}),$("[id^=collapse-]").on("show.bs.collapse",function(){var e=$(this).prev().find("a").data("group-id"),t=$(document.getElementById(e)).offset().top-33;$("html, body").animate({scrollTop:t})}),$("[id^=collapse-]").on("hide.bs.collapse",function(e){var t=$(this).prev().find("a").data("group-id"),n=$(document.getElementById(t)).offset().top-33;$("html, body").animate({scrollTop:n}),($(window).scrollTop()n+1)&&e.preventDefault()}),$(".tabs").on("click","a",function(e){var t=$(this).attr("href").substring(1),n=$(document.getElementById(t)).offset().top-33;$("html, body").animate({scrollTop:n}),e.preventDefault()}),$(".nav-pills").on("click",".active a",function(e){var t=$(this);e.preventDefault(),window.setTimeout(function(){t.closest(".nav-pills").next(".tab-content").find(".tab-pane").removeClass("active"),t.parent("li").removeClass("active")},0)}),$("pre code").each(function(e,t){i.highlightBlock(t)})})},function(e,t,n){"use strict";var i,r;"undefined"!=typeof window&&window,void 0===(r="function"==typeof(i=function(){if("undefined"==typeof window)return null;var e=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||function(e){return window.setTimeout(e,20)};function t(e,t){var n=Object.prototype.toString.call(e),i="[object Array]"===n||"[object NodeList]"===n||"[object HTMLCollection]"===n||"[object Object]"===n||"undefined"!=typeof jQuery&&e instanceof jQuery||"undefined"!=typeof Elements&&e instanceof Elements,r=0,s=e.length;if(i)for(;r