Compare commits
60 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1ac85f6eba | |||
| c2e4d7767b | |||
| baaa79a29d | |||
| 8dfab883a5 | |||
| dfe06b5c95 | |||
| 18ff51a025 | |||
| e1aedab73f | |||
| 060fe1881a | |||
| 5d8c936956 | |||
| 25dea81bc6 | |||
| a419eec071 | |||
| d41f0c5ac4 | |||
| c510de13d7 | |||
| 207a7e2b2d | |||
| cbae10c434 | |||
| 81fa4b44c8 | |||
| 20786e53c3 | |||
| 120c4dd884 | |||
| 5bdce56bba | |||
| e761e2da50 | |||
| 9d330d9509 | |||
| c8f6d16891 | |||
| 857ef05b07 | |||
| 586b88d8f3 | |||
| 27cd5f7f2a | |||
| 90812f5c43 | |||
| a6ae8b0521 | |||
| 91530b64c6 | |||
| 6820d6bc70 | |||
| f50ad29a2b | |||
| 27e38101a4 | |||
| 4bac38e67b | |||
| 10abf46597 | |||
| 42841e3092 | |||
| 0654aefe58 | |||
| 41b1ca4483 | |||
| b109d4c847 | |||
| 591c12f1a7 | |||
| 271918a678 | |||
| c5c40e31c4 | |||
| 3ac6c9ec3a | |||
| 5fa35d5b81 | |||
| f9b215deab | |||
| 0837873f55 | |||
| 02b8848912 | |||
| 6e39a58b2d | |||
| e146a9712e | |||
| ec7529399e | |||
| 824baf7e9d | |||
| dd50eb5e12 | |||
| 9b56e1a4c8 | |||
| 608abaf0e1 | |||
| 64e13a94da | |||
| 5051f91c97 | |||
| d1ae81a27e | |||
| 1ca401959c | |||
| cd4bd4a18e | |||
| 8a69f08c29 | |||
| e533b0827a | |||
| dc78dfdad8 |
+2
-3
@@ -1,7 +1,8 @@
|
||||
node_modules/
|
||||
testproj/db.sqlite3
|
||||
testproj/staticfiles
|
||||
.vscode/
|
||||
\.pytest_cache/
|
||||
docs/\.doctrees/
|
||||
|
||||
# Created by .ignore support plugin (hsz.mobi)
|
||||
### Python template
|
||||
@@ -159,5 +160,3 @@ com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
\.pytest_cache/
|
||||
|
||||
Generated
+11
-3
@@ -16,22 +16,30 @@
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/testproj" isTestSource="false" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.pytest_cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/docs/.doctrees" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/docs/_build" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/htmlcov" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/src/drf_yasg.egg-info" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Python 3.6 (drf-yasg)" jdkType="Python SDK" />
|
||||
<orderEntry type="jdk" jdkName="Python 3 (drf-yasg)" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="immutable" level="application" />
|
||||
</component>
|
||||
<component name="TemplatesService">
|
||||
<option name="TEMPLATE_CONFIGURATION" value="Django" />
|
||||
<option name="TEMPLATE_FOLDERS">
|
||||
<list>
|
||||
<option value="$MODULE_DIR$/src/drf_yasg/templates" />
|
||||
<option value="$MODULE_DIR$/testproj/testproj/templates" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="TestRunnerService">
|
||||
<option name="projectConfiguration" value="py.test" />
|
||||
<option name="PROJECT_TEST_RUNNER" value="py.test" />
|
||||
<option name="projectConfiguration" value="pytest" />
|
||||
<option name="PROJECT_TEST_RUNNER" value="pytest" />
|
||||
</component>
|
||||
</module>
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JavaScriptLibraryMappings">
|
||||
<file url="file://$PROJECT_DIR$" libraries="{immutable}" />
|
||||
</component>
|
||||
</project>
|
||||
Generated
+1
-1
@@ -69,7 +69,7 @@
|
||||
<textMaps />
|
||||
</LinkMapSettings>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6 (drf-yasg)" project-jdk-type="Python SDK" />
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3 (drf-yasg)" project-jdk-type="Python SDK" />
|
||||
<component name="PythonCompatibilityInspectionAdvertiser">
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
|
||||
+1
-7
@@ -6,13 +6,7 @@ python:
|
||||
- '3.5'
|
||||
- '3.6'
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.cache/pip
|
||||
- .tox
|
||||
before_cache:
|
||||
- rm -f $HOME/.cache/pip/log/debug.log
|
||||
- rm -fr .tox/log/ .tox/*/log/ .tox/*/tmp/ .tox/dist .tox/*/lib/*/site-packages/drf_yasg*
|
||||
cache: pip
|
||||
|
||||
jobs:
|
||||
include:
|
||||
|
||||
@@ -3,6 +3,57 @@ Changelog
|
||||
#########
|
||||
|
||||
|
||||
**********
|
||||
**1.11.0**
|
||||
**********
|
||||
|
||||
*Release date: Oct 14, 2018*
|
||||
|
||||
- **ADDED:** ``PERSIST_AUTH``, ``REFETCH_SCHEMA_WITH_AUTH``, ``REFETCH_SCHEMA_ON_LOGOUT``
|
||||
settings and related javascript implementation for persisting authentication data to swagger-ui localStorage
|
||||
- **IMPROVED:** UI-enabled views will now no longer generate the full specification document twice; the HTML part
|
||||
of the view will only generate a barebones ``Swagger`` object with no ``paths`` and ``definitions``
|
||||
- **IMPROVED:** added the ``FETCH_SCHEMA_WITH_QUERY`` setting to enable fetching of the schema document using
|
||||
query parameters passed to the UI view (:issue:`208`)
|
||||
- **IMPROVED:** added support for the very common ``x-nullable`` extension (:issue:`217`)
|
||||
- **IMPROVED:** extensibility of some classes was improved by adding more extension points, together with more blocks
|
||||
for ``swagger-ui.html``/``redoc.html`` and some JavaScript hooks in ``swagger-ui-init.js``
|
||||
- **FIXED:** removed usage of ``inspect.signature`` on python 2.7 (:issue:`222`)
|
||||
|
||||
**********
|
||||
**1.10.2**
|
||||
**********
|
||||
|
||||
*Release date: Sep 13, 2018*
|
||||
|
||||
- **ADDED:** added the ``DISPLAY_OPERATION_ID`` ``swagger-ui`` setting
|
||||
- **IMPROVED:** updated ``ReDoc`` to version 2.0.0-alpha.38
|
||||
- **IMPROVED:** Operation summary will now be parsed from multi-line view method docstrings (:issue:`205`)
|
||||
- **IMPROVED:** ``pattern`` will now work on any field with a ``RegexValidator``
|
||||
(would previously not appear on fields with special formats such as ``EmailField``)
|
||||
- **FIXED:** fixed an issue with ``RelatedFieldInspector`` handling of nested serializers
|
||||
- **FIXED:** fixed handling of ``reverse_lazy`` in URL settings (:issue:`209`)
|
||||
|
||||
**********
|
||||
**1.10.1**
|
||||
**********
|
||||
|
||||
*Release date: Sep 10, 2018*
|
||||
|
||||
- **ADDED:** added the ``SPEC_URL`` setting for controlling the download link in ``swagger-ui`` and ``ReDoc``
|
||||
- **ADDED:** updated ``ReDoc`` settings (added ``NATIVE_SCROLLBARS`` and ``REQUIRED_PROPS_FIRST``)
|
||||
- **ADDED:** added ``extra_styles`` and ``extra_scripts`` blocks to ui templates (:issue:`178`)
|
||||
- **IMPROVED:** updated ``swagger-ui`` to version 3.18.2
|
||||
- **IMPROVED:** updated ``ReDoc`` to version 2.0.0-alpha.37
|
||||
- **FIXED:** stopped generating invalid OpenAPI by improper placement of ``readOnly`` Schemas
|
||||
- **FIXED:** fixed broken CSS when ``USE_SESSION_AUTH=False``
|
||||
- **FIXED:** fixed implementation of ``operation_summary`` and ``deprecated`` (:pr:`194`, :pr:`198`)
|
||||
- **FIXED:** fixed a bug related to nested ``typing`` hints (:pr:`195`)
|
||||
- **FIXED:** removed dependency on ``future`` (:issue:`196`)
|
||||
- **FIXED:** fixed exceptions logged for fields with ``default=None`` (:issue:`203`)
|
||||
- **FIXED:** fixed ``request_body=no_body`` handling and related tests (:issue:`188`, :issue:`199`)
|
||||
|
||||
|
||||
**********
|
||||
**1.10.0**
|
||||
**********
|
||||
|
||||
+3
-1
@@ -155,7 +155,9 @@ texinfo_documents = [
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
autodoc_default_flags = ['private-members']
|
||||
autodoc_default_options = {
|
||||
'private-members': None
|
||||
}
|
||||
autodoc_member_order = 'bysource'
|
||||
autoclass_content = 'both'
|
||||
autodoc_mock_imports = []
|
||||
|
||||
+11
-3
@@ -2,6 +2,14 @@
|
||||
Customizing the web UI
|
||||
######################
|
||||
|
||||
There is currently no pluggable way of customizing the web UI apart from the settings available in
|
||||
:ref:`swagger-ui-settings` and :ref:`redoc-ui-settings`. If you really need to, you can override one of the
|
||||
``drf-yasg/swagger-ui.html`` or ``drf-yasg/redoc.html`` templates that are used for rendering.
|
||||
The web UI can be customized using the settings available in :ref:`swagger-ui-settings` and :ref:`redoc-ui-settings`.
|
||||
|
||||
You can also extend one of the `drf-yasg/swagger-ui.html`_ or `drf-yasg/redoc.html`_ templates that are used for
|
||||
rendering. See the template source code (linked above) for a complete list of customizable blocks.
|
||||
|
||||
The ``swagger-ui`` view has some quite involed JavaScript hooks used for some functionality, which you might also
|
||||
want to review at `drf-yasg/swagger-ui-init.js`_.
|
||||
|
||||
.. _drf-yasg/swagger-ui.html: https://github.com/axnsan12/drf-yasg/blob/master/src/drf_yasg/templates/drf-yasg/swagger-ui.html
|
||||
.. _drf-yasg/swagger-ui-init.js: https://github.com/axnsan12/drf-yasg/blob/master/src/drf_yasg/static/drf-yasg/swagger-ui-init.js
|
||||
.. _drf-yasg/redoc.html: https://github.com/axnsan12/drf-yasg/blob/master/src/drf_yasg/templates/drf-yasg/redoc.html
|
||||
|
||||
+122
-13
@@ -27,16 +27,27 @@ Example:
|
||||
}
|
||||
|
||||
REDOC_SETTINGS = {
|
||||
'LAZY_RENDERING': True,
|
||||
'LAZY_RENDERING': False,
|
||||
...
|
||||
}
|
||||
|
||||
.. _url-settings:
|
||||
|
||||
All settings which configure URLs (``LOGIN_URL``, ``SPEC_URL``, ``VALIDATOR_URL``, etc.) can accept several forms of
|
||||
input:
|
||||
|
||||
* A view name: `urls.reverse()` will be used to reverse-resolve the name
|
||||
* A 2-tuple of ``(view_name, kwargs)```: `urls.reverse()` will be used to reverse-resolve the name using the given
|
||||
`kwargs`; `kwargs` must be a dict
|
||||
* A 3-tuple of ``(view_name, args, kwargs)```: `urls.reverse()` will be used to reverse-resolve the name using the given
|
||||
`args` and `kwargs`; `args`, `kwargs` must be a tuple/list and a dict respectively
|
||||
* A URL, which will be used as-is
|
||||
|
||||
The possible settings and their default values are as follows:
|
||||
|
||||
********************
|
||||
``SWAGGER_SETTINGS``
|
||||
********************
|
||||
|
||||
****************
|
||||
SWAGGER_SETTINGS
|
||||
****************
|
||||
|
||||
.. _default-class-settings:
|
||||
|
||||
@@ -192,6 +203,15 @@ Swagger UI settings
|
||||
Swagger UI configuration settings. |br|
|
||||
See https://github.com/swagger-api/swagger-ui/blob/112bca906553a937ac67adc2e500bdeed96d067b/docs/usage/configuration.md#parameters.
|
||||
|
||||
SPEC_URL
|
||||
--------
|
||||
|
||||
URL pointing to a swagger document for use by swagger-ui. The default behaviour is to append ``?format=openapi`` to the
|
||||
URL which serves the UI; see :ref:`note on URL settings <url-settings>` above.
|
||||
|
||||
**Default**: :python:`None` |br|
|
||||
*Maps to parameter*: ``url``
|
||||
|
||||
VALIDATOR_URL
|
||||
-------------
|
||||
|
||||
@@ -202,6 +222,40 @@ set to ``None`` to remove the badge.
|
||||
**Default**: :python:`'http://online.swagger.io/validator/'` |br|
|
||||
*Maps to parameter*: ``validatorUrl``
|
||||
|
||||
PERSIST_AUTH
|
||||
------------
|
||||
|
||||
Persist swagger-ui authorization data to local storage. |br|
|
||||
**WARNING:** This may be a security risk as the credentials are stored unencrypted and can be accessed
|
||||
by all javascript code running on the same domain.
|
||||
|
||||
**Default**: :python:`'False` |br|
|
||||
*Maps to parameter*: -
|
||||
|
||||
REFETCH_SCHEMA_WITH_AUTH
|
||||
------------------------
|
||||
|
||||
Re-fetch the OpenAPI document with the new credentials after authorization is performed through swagger-ui.
|
||||
|
||||
**Default**: :python:`'False` |br|
|
||||
*Maps to parameter*: -
|
||||
|
||||
REFETCH_SCHEMA_ON_LOGOUT
|
||||
------------------------
|
||||
|
||||
Re-fetch the OpenAPI document without credentials after authorization is removed through swagger-ui.
|
||||
|
||||
**Default**: :python:`'False` |br|
|
||||
*Maps to parameter*: -
|
||||
|
||||
FETCH_SCHEMA_WITH_QUERY
|
||||
-----------------------
|
||||
|
||||
Fetch the OpenAPI document using the query parameters passed to the swagger-ui page request.
|
||||
|
||||
**Default**: :python:`'True` |br|
|
||||
*Maps to parameter*: -
|
||||
|
||||
OPERATIONS_SORTER
|
||||
-----------------
|
||||
|
||||
@@ -312,9 +366,17 @@ This does not filter the operations from the display.
|
||||
**Default**: :python:`['get','put','post','delete','options','head','patch','trace']` |br|
|
||||
*Maps to parameter*: ``supportedSubmitMethods``
|
||||
|
||||
******************
|
||||
``REDOC_SETTINGS``
|
||||
******************
|
||||
DISPLAY_OPERATION_ID
|
||||
--------------------
|
||||
|
||||
Controls the display of operationId in operations list.
|
||||
|
||||
**Default**: :python:`True`
|
||||
*Maps to parameter*: ``displayOperationId``
|
||||
|
||||
**************
|
||||
REDOC_SETTINGS
|
||||
**************
|
||||
|
||||
.. _redoc-ui-settings:
|
||||
|
||||
@@ -324,29 +386,76 @@ ReDoc UI settings
|
||||
ReDoc UI configuration settings. |br|
|
||||
See https://github.com/Rebilly/ReDoc#configuration.
|
||||
|
||||
SPEC_URL
|
||||
--------
|
||||
|
||||
URL pointing to a swagger document for use by ReDoc. The default behaviour is to append ``?format=openapi`` to the
|
||||
URL which serves the UI; see :ref:`note on URL settings <url-settings>` above.
|
||||
|
||||
**Default**: :python:`None` |br|
|
||||
*Maps to attribute*: ``spec-url``
|
||||
|
||||
LAZY_RENDERING
|
||||
--------------
|
||||
|
||||
**Default**: :python:`True` |br|
|
||||
*Maps to attribute*: ``lazy-rendering``
|
||||
If set, enables lazy rendering mode in ReDoc. This mode is useful for APIs with big number of operations (e.g. > 50).
|
||||
In this mode ReDoc shows initial screen ASAP and then renders the rest operations asynchronously while showing
|
||||
progress bar on the top.
|
||||
|
||||
**NOTE:** this feature might be removed in future versions of ReDoc (see https://github.com/Rebilly/ReDoc/issues/475)
|
||||
|
||||
**Default**: :python:`False` |br|
|
||||
*Maps to attribute*: ``lazyRendering``
|
||||
|
||||
HIDE_HOSTNAME
|
||||
-------------
|
||||
|
||||
If set, the protocol and hostname is not shown in the operation definition.
|
||||
|
||||
**Default**: :python:`False` |br|
|
||||
*Maps to attribute*: ``hide-hostname``
|
||||
*Maps to attribute*: ``hideHostname``
|
||||
|
||||
EXPAND_RESPONSES
|
||||
----------------
|
||||
|
||||
Specify which responses to expand by default by response codes. Values should be passed as comma-separated list without
|
||||
spaces e.g. expandResponses="200,201". Special value "all" expands all responses by default.
|
||||
Be careful: this option can slow-down documentation rendering time.
|
||||
|
||||
**Default**: :python:`'all'` |br|
|
||||
*Maps to attribute*: ``expand-responses``
|
||||
*Maps to attribute*: ``expandResponses``
|
||||
|
||||
PATH_IN_MIDDLE
|
||||
--------------
|
||||
|
||||
Show path link and HTTP verb in the middle panel instead of the right one.
|
||||
|
||||
**Default**: :python:`False` |br|
|
||||
*Maps to attribute*: ``path-in-middle-panel``
|
||||
*Maps to attribute*: ``pathInMiddlePanel``
|
||||
|
||||
NATIVE_SCROLLBARS
|
||||
-----------------
|
||||
|
||||
Use native scrollbar for sidemenu instead of perfect-scroll (scrolling performance optimization for big specs).
|
||||
|
||||
**Default**: :python:`False` |br|
|
||||
*Maps to attribute*: ``nativeScrollbars``
|
||||
|
||||
REQUIRED_PROPS_FIRST
|
||||
--------------------
|
||||
|
||||
Show required properties first ordered in the same order as in required array.
|
||||
|
||||
**Default**: :python:`False` |br|
|
||||
*Maps to attribute*: ``requiredPropsFirst``
|
||||
|
||||
FETCH_SCHEMA_WITH_QUERY
|
||||
-----------------------
|
||||
|
||||
Fetch the OpenAPI document using the query parameters passed to the ReDoc page request.
|
||||
|
||||
**Default**: :python:`'True` |br|
|
||||
*Maps to parameter*: -
|
||||
|
||||
|
||||
.. _FORCE_SCRIPT_NAME: https://docs.djangoproject.com/en/2.0/ref/settings/#force-script-name
|
||||
|
||||
Generated
+78
-237
@@ -3,6 +3,14 @@
|
||||
"requires": true,
|
||||
"lockfileVersion": 1,
|
||||
"dependencies": {
|
||||
"@babel/runtime": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.1.2.tgz",
|
||||
"integrity": "sha512-Y3SCjmhSupzFB6wcv1KmmFucH6gDVnI30WjOcicV10ju0cZjak3Jcs67YLIXBrmZYw1xCrVeJPbycFwrqNyxpg==",
|
||||
"requires": {
|
||||
"regenerator-runtime": "^0.12.0"
|
||||
}
|
||||
},
|
||||
"argparse": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
@@ -11,25 +19,6 @@
|
||||
"sprintf-js": "~1.0.2"
|
||||
}
|
||||
},
|
||||
"asap": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
|
||||
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
|
||||
},
|
||||
"base64-js": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
|
||||
"integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw=="
|
||||
},
|
||||
"buffer": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.0.tgz",
|
||||
"integrity": "sha512-nUJyfChH7PMJy75eRDCCKtszSEFokUNXC1hNVSe+o+VdcgvDPLs20k3v8UXI8ruRYAJiYtyRea8mYyqPxoHWDw==",
|
||||
"requires": {
|
||||
"base64-js": "^1.0.2",
|
||||
"ieee754": "^1.1.4"
|
||||
}
|
||||
},
|
||||
"call-me-maybe": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz",
|
||||
@@ -51,32 +40,12 @@
|
||||
"tiny-emitter": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"core-js": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
|
||||
"integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
|
||||
},
|
||||
"css-color-keywords": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
|
||||
"integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU="
|
||||
},
|
||||
"css-to-react-native": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-2.2.1.tgz",
|
||||
"integrity": "sha512-v++LRcf633phJiYZBDqtmGPj3+BVof0isd2jgwYLWZJ5YSuhCkrfYtDsNhM6oJthiEco0f9tDVJ1vUkDJNgGEA==",
|
||||
"requires": {
|
||||
"css-color-keywords": "^1.0.0",
|
||||
"fbjs": "^0.8.5",
|
||||
"postcss-value-parser": "^3.3.0"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"version": "3.2.6",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
|
||||
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"decko": {
|
||||
@@ -96,17 +65,9 @@
|
||||
"integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg="
|
||||
},
|
||||
"dompurify": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-1.0.7.tgz",
|
||||
"integrity": "sha512-1xK0JEda/jvIm3SgqHXKvRCh3AbEKCyBbUAGpNCMVIljBD145cPvBR66JSj3O4SdscFUx5NXsDkJpz6vDT8KLg=="
|
||||
},
|
||||
"encoding": {
|
||||
"version": "0.1.12",
|
||||
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
|
||||
"integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
|
||||
"requires": {
|
||||
"iconv-lite": "~0.4.13"
|
||||
}
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-1.0.8.tgz",
|
||||
"integrity": "sha512-vetRFbN1SXSPfP3ClIiYnxTrXquSqakBEOoB5JESn0SVcSYzpu6ougjakpKnskGctYdlNpwf+riUHSkG7d4XUw=="
|
||||
},
|
||||
"esprima": {
|
||||
"version": "4.0.1",
|
||||
@@ -123,20 +84,6 @@
|
||||
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
|
||||
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
|
||||
},
|
||||
"fbjs": {
|
||||
"version": "0.8.17",
|
||||
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz",
|
||||
"integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=",
|
||||
"requires": {
|
||||
"core-js": "^1.0.0",
|
||||
"isomorphic-fetch": "^2.1.1",
|
||||
"loose-envify": "^1.0.0",
|
||||
"object-assign": "^4.1.0",
|
||||
"promise": "^7.1.1",
|
||||
"setimmediate": "^1.0.5",
|
||||
"ua-parser-js": "^0.7.18"
|
||||
}
|
||||
},
|
||||
"foreach": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
|
||||
@@ -165,43 +112,11 @@
|
||||
"delegate": "^3.1.2"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
|
||||
"integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
|
||||
},
|
||||
"hoist-non-react-statics": {
|
||||
"version": "2.5.5",
|
||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz",
|
||||
"integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw=="
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.23",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
|
||||
"integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
|
||||
"requires": {
|
||||
"safer-buffer": ">= 2.1.2 < 3"
|
||||
}
|
||||
},
|
||||
"ieee754": {
|
||||
"version": "1.1.12",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz",
|
||||
"integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA=="
|
||||
},
|
||||
"is-stream": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
|
||||
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
|
||||
},
|
||||
"isomorphic-fetch": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
|
||||
"integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
|
||||
"requires": {
|
||||
"node-fetch": "^1.0.1",
|
||||
"whatwg-fetch": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
@@ -225,14 +140,14 @@
|
||||
}
|
||||
},
|
||||
"json-schema-ref-parser": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-ref-parser/-/json-schema-ref-parser-5.1.2.tgz",
|
||||
"integrity": "sha512-gP0mSqqkG99xNeA4F6bf2pXQYv5fFqe9SybbKO9qSMmyzzfFFIqd16s9Y65mRWKzZ0muTjyEtcSE/hLZLvIjZw==",
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-ref-parser/-/json-schema-ref-parser-5.1.3.tgz",
|
||||
"integrity": "sha512-CpDFlBwz/6la78hZxyB9FECVKGYjIIl3Ms3KLqFj99W7IIb7D00/RDgc++IGB4BBALl0QRhh5m4q5WNSopvLtQ==",
|
||||
"requires": {
|
||||
"call-me-maybe": "^1.0.1",
|
||||
"debug": "^3.1.0",
|
||||
"js-yaml": "^3.12.0",
|
||||
"ono": "^4.0.5"
|
||||
"ono": "^4.0.6"
|
||||
}
|
||||
},
|
||||
"loose-envify": {
|
||||
@@ -244,9 +159,9 @@
|
||||
}
|
||||
},
|
||||
"lunr": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.1.tgz",
|
||||
"integrity": "sha1-ETYWorYC3cEJMqe/ik5uV+v+zfI="
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.3.tgz",
|
||||
"integrity": "sha512-rlAEsgU9Bnavca2w1WJ6+6cdeHMXNyadcersyk3ZpuhgWb5HBNj8l4WwJz9PjksAhYDlpQffCVXPctOn+wCIVA=="
|
||||
},
|
||||
"mark.js": {
|
||||
"version": "8.11.1",
|
||||
@@ -254,14 +169,14 @@
|
||||
"integrity": "sha1-GA8fnr74sOY45BZq1S24eb6y/8U="
|
||||
},
|
||||
"marked": {
|
||||
"version": "0.3.18",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-0.3.18.tgz",
|
||||
"integrity": "sha512-49i2QYhfULqaXzNZpxC808PisuCTGT2fgG0zrzdCI9N3rIfAWfW0nggvbXr6zvpynZdOG5+9xNxdzP0kwZnERw=="
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-0.5.1.tgz",
|
||||
"integrity": "sha512-iUkBZegCZou4AdwbKTwSW/lNDcz5OuRSl3qdcl31Ia0B2QPG0Jn+tKblh/9/eP9/6+4h27vpoh8wel/vQOV0vw=="
|
||||
},
|
||||
"memoize-one": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-4.0.0.tgz",
|
||||
"integrity": "sha512-wdpOJ4XBejprGn/xhd1i2XR8Dv1A25FJeIvR7syQhQlz9eXsv+06llcvcmBxlWVGv4C73QBsWA8kxvZozzNwiQ=="
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-4.0.2.tgz",
|
||||
"integrity": "sha512-ucx2DmXTeZTsS4GPPUZCbULAN7kdPT1G+H49Y34JjbQ5ESc6OGhVxKvb1iKhr9v19ZB9OtnHwNnhUnNR/7Wteg=="
|
||||
},
|
||||
"min-document": {
|
||||
"version": "2.19.0",
|
||||
@@ -272,27 +187,18 @@
|
||||
}
|
||||
},
|
||||
"mobx-react": {
|
||||
"version": "5.2.3",
|
||||
"resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-5.2.3.tgz",
|
||||
"integrity": "sha512-OuSlF2nJEa1PGookZcZnINbvEK4iWNNYiqUh6aebk2AkWxj3sG8OafDOQMcMYApQALTHRsrBIjOx/K8TFxcz7w==",
|
||||
"version": "5.2.8",
|
||||
"resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-5.2.8.tgz",
|
||||
"integrity": "sha512-VAkeqkrIpdoy3VPPoqvxjdQmcTT6hi7i3TsZSwcKbSrPbSTuWc7cp1EOiX/zV1wPWEuoNAQ22bCrskQwvdYTJA==",
|
||||
"requires": {
|
||||
"hoist-non-react-statics": "^2.5.0",
|
||||
"react-lifecycles-compat": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "1.7.3",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
|
||||
"integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
|
||||
"requires": {
|
||||
"encoding": "^0.1.11",
|
||||
"is-stream": "^1.0.1"
|
||||
}
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
@@ -300,17 +206,17 @@
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
|
||||
},
|
||||
"ono": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/ono/-/ono-4.0.5.tgz",
|
||||
"integrity": "sha512-ZVNuV9kJbr/2tWs83I2snrYo+WIS0DISF/xUfX9p9b6GyDD6F5N9PzHjW+p/dep6IGwSYylf1HCub5I/nM0R5Q==",
|
||||
"version": "4.0.10",
|
||||
"resolved": "https://registry.npmjs.org/ono/-/ono-4.0.10.tgz",
|
||||
"integrity": "sha512-4Xz4hlbq7MzV0I3vKfZwRvyj8tCbXODqBNzFqtkjP+KTV93zzDRju8kw1qnf6P5kcZ2+xlIq6wSCqA+euSKxhA==",
|
||||
"requires": {
|
||||
"format-util": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"openapi-sampler": {
|
||||
"version": "1.0.0-beta.13",
|
||||
"resolved": "https://registry.npmjs.org/openapi-sampler/-/openapi-sampler-1.0.0-beta.13.tgz",
|
||||
"integrity": "sha512-NReKJh92NlUmY9CDo86L1Skkx3DMDeWmiLoqMxQSX7xBpoSx8WJ1JdTb7nEwz6M7S+WDPrQsEfS5BaIW27nMrQ==",
|
||||
"version": "1.0.0-beta.14",
|
||||
"resolved": "https://registry.npmjs.org/openapi-sampler/-/openapi-sampler-1.0.0-beta.14.tgz",
|
||||
"integrity": "sha512-NNmH9YAN5AaCE4w6MQXdCrmsOJJQTswHVSp075+h+iiG+OTonpZE8HzwocozovD2imx4lamkuxGLs4E4bO4Z+g==",
|
||||
"requires": {
|
||||
"json-pointer": "^0.6.0"
|
||||
}
|
||||
@@ -321,14 +227,12 @@
|
||||
"integrity": "sha512-/2Sk/khljhdrsamjJYS5NjrH+GKEHEwh7zFSiYyxROyYKagkE4kSn2zDQDRTOMo8mpT2jikxx6yI1dG7lNP/hw=="
|
||||
},
|
||||
"polished": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/polished/-/polished-1.9.3.tgz",
|
||||
"integrity": "sha512-4NmSD7fMFlM8roNxs7YXPv7UFRbYzb0gufR5zBxJLRzY54+zFsavxBo6zsQzP9ep6Hh3pC2pTyrpSTBEaB6IkQ=="
|
||||
},
|
||||
"postcss-value-parser": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz",
|
||||
"integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU="
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/polished/-/polished-2.2.0.tgz",
|
||||
"integrity": "sha512-GEKeNET1XIri53xKpFwGZX4fh2k3b5GE5fxwLWYYR2sGWkMAHJVcb7bK1g6QHIDcoIEEGC8CzHOQgl2qFByd3w==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"prismjs": {
|
||||
"version": "1.15.0",
|
||||
@@ -343,14 +247,6 @@
|
||||
"resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz",
|
||||
"integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8="
|
||||
},
|
||||
"promise": {
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
|
||||
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
|
||||
"requires": {
|
||||
"asap": "~2.0.3"
|
||||
}
|
||||
},
|
||||
"prop-types": {
|
||||
"version": "15.6.2",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.2.tgz",
|
||||
@@ -361,17 +257,17 @@
|
||||
}
|
||||
},
|
||||
"react-dropdown": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/react-dropdown/-/react-dropdown-1.5.0.tgz",
|
||||
"integrity": "sha512-rRv3a7NiP++yC1rzdjzkviC5ujq759i4SRa0M3C0Cr7loYT4Z3+JhSPekv1/04JiZNXX46cV3/g6A9kS7rkI4Q==",
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/react-dropdown/-/react-dropdown-1.6.2.tgz",
|
||||
"integrity": "sha512-6RpKAFEVZLr53y91qnxC9rAWcoDvq8A9YstmeSV2AQgJxNFRcsreN1mJNRUctSvIwm0Hph07ouMvDc2GvfQBsA==",
|
||||
"requires": {
|
||||
"classnames": "^2.2.3"
|
||||
}
|
||||
},
|
||||
"react-hot-loader": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/react-hot-loader/-/react-hot-loader-4.3.4.tgz",
|
||||
"integrity": "sha512-LlKjtHq+RhDq9xm6crXojbkzrEvli5F4/RaeJ//XtDWrwwsAHDjEqKfZZiPCxv7gWV2cxE3YE8TXeE9BDzLqOA==",
|
||||
"version": "4.3.11",
|
||||
"resolved": "https://registry.npmjs.org/react-hot-loader/-/react-hot-loader-4.3.11.tgz",
|
||||
"integrity": "sha512-T0G5jURyTsFLoiW6MTr5Q35UHC/B2pmYJ7+VBjk8yMDCEABRmCGy4g6QwxoB4pWg4/xYvVTa/Pbqnsgx/+NLuA==",
|
||||
"requires": {
|
||||
"fast-levenshtein": "^2.0.6",
|
||||
"global": "^4.3.0",
|
||||
@@ -381,59 +277,53 @@
|
||||
"shallowequal": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"react-is": {
|
||||
"version": "16.4.2",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.4.2.tgz",
|
||||
"integrity": "sha512-rI3cGFj/obHbBz156PvErrS5xc6f1eWyTwyV4mo0vF2lGgXgS+mm7EKD5buLJq6jNgIagQescGSVG2YzgXt8Yg=="
|
||||
},
|
||||
"react-lifecycles-compat": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
|
||||
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
|
||||
},
|
||||
"react-tabs": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/react-tabs/-/react-tabs-2.2.2.tgz",
|
||||
"integrity": "sha512-jZGAAoq1yknr/XF60/2kH5X3UJdR1X8ItcsLZ1mJnHfoniKcCr3shT2TK5wiS2sO0LOmqwX2BtJQX3snKd50sg==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/react-tabs/-/react-tabs-2.3.0.tgz",
|
||||
"integrity": "sha512-pYaefgVy76/36AMEP+B8YuVVzDHa3C5UFZ3REU78zolk0qMxEhKvUFofvDCXyLZwf0RZjxIfiwok1BEb18nHyA==",
|
||||
"requires": {
|
||||
"classnames": "^2.2.0",
|
||||
"prop-types": "^15.5.0"
|
||||
}
|
||||
},
|
||||
"redoc": {
|
||||
"version": "2.0.0-alpha.32",
|
||||
"resolved": "https://registry.npmjs.org/redoc/-/redoc-2.0.0-alpha.32.tgz",
|
||||
"integrity": "sha512-hqQlQ8lnXszLOJGyrRCLtCH+yPJfS22FjbqJ9X6/KM3U46UXk7rv3jZG/quV0IIRhcyehRm6h8a6Eu18KRupng==",
|
||||
"version": "2.0.0-alpha.40",
|
||||
"resolved": "https://registry.npmjs.org/redoc/-/redoc-2.0.0-alpha.40.tgz",
|
||||
"integrity": "sha512-qc6wmw97a1Yh7LAqlF3BEVp8ualHaGjGLnsRL2O8BScqVmhFgyeAkFqayHdaT7qe5/g5Bge090U6Eq5OyvXi2Q==",
|
||||
"requires": {
|
||||
"classnames": "^2.2.6",
|
||||
"decko": "^1.2.0",
|
||||
"dompurify": "^1.0.6",
|
||||
"dompurify": "^1.0.7",
|
||||
"eventemitter3": "^3.0.0",
|
||||
"json-pointer": "^0.6.0",
|
||||
"json-schema-ref-parser": "^5.1.1",
|
||||
"lunr": "^2.3.0",
|
||||
"json-schema-ref-parser": "^5.1.2",
|
||||
"lunr": "^2.3.2",
|
||||
"mark.js": "^8.11.1",
|
||||
"marked": "0.3.18",
|
||||
"marked": "^0.5.1",
|
||||
"memoize-one": "^4.0.0",
|
||||
"mobx-react": "^5.2.3",
|
||||
"openapi-sampler": "1.0.0-beta.13",
|
||||
"mobx-react": "^5.2.5",
|
||||
"openapi-sampler": "1.0.0-beta.14",
|
||||
"perfect-scrollbar": "^1.4.0",
|
||||
"polished": "^1.9.3",
|
||||
"polished": "^2.0.2",
|
||||
"prismjs": "^1.15.0",
|
||||
"prop-types": "^15.6.2",
|
||||
"react-dropdown": "^1.3.0",
|
||||
"react-hot-loader": "^4.3.3",
|
||||
"react-dropdown": "^1.6.2",
|
||||
"react-hot-loader": "^4.3.5",
|
||||
"react-tabs": "^2.0.0",
|
||||
"slugify": "^1.2.1",
|
||||
"slugify": "^1.3.1",
|
||||
"stickyfill": "^1.1.1",
|
||||
"styled-components": "^3.3.3",
|
||||
"tslib": "^1.9.3"
|
||||
}
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
"regenerator-runtime": {
|
||||
"version": "0.12.1",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz",
|
||||
"integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg=="
|
||||
},
|
||||
"select": {
|
||||
"version": "1.1.2",
|
||||
@@ -441,20 +331,15 @@
|
||||
"integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=",
|
||||
"optional": true
|
||||
},
|
||||
"setimmediate": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
|
||||
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
|
||||
},
|
||||
"shallowequal": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
|
||||
"integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="
|
||||
},
|
||||
"slugify": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.3.0.tgz",
|
||||
"integrity": "sha512-vvz+9ANt7CtdTHwJpfrsHOnGkgxky+CUPnvtzDZBZYFo/H/CdZkd5lJL7z7RqtH/x9QW/ItYYfHlcGf38CBK1w=="
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.3.1.tgz",
|
||||
"integrity": "sha512-6BwyhjF5tG5P8s+0DPNyJmBSBePG6iMyhjvIW5zGdA3tFik9PtK+yNkZgTeiroCRGZYgkHftFA62tGVK1EI9Kw=="
|
||||
},
|
||||
"sprintf-js": {
|
||||
"version": "1.0.3",
|
||||
@@ -466,44 +351,10 @@
|
||||
"resolved": "https://registry.npmjs.org/stickyfill/-/stickyfill-1.1.1.tgz",
|
||||
"integrity": "sha1-OUE/7p0CXHSn5ZzuyyN4TMDxfwI="
|
||||
},
|
||||
"styled-components": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/styled-components/-/styled-components-3.4.0.tgz",
|
||||
"integrity": "sha1-0lb7RmfmwRWn7WGrePEgKDtD3QA=",
|
||||
"requires": {
|
||||
"buffer": "^5.0.3",
|
||||
"css-to-react-native": "^2.0.3",
|
||||
"fbjs": "^0.8.16",
|
||||
"hoist-non-react-statics": "^2.5.0",
|
||||
"prop-types": "^15.5.4",
|
||||
"react-is": "^16.3.1",
|
||||
"stylis": "^3.5.0",
|
||||
"stylis-rule-sheet": "^0.0.10",
|
||||
"supports-color": "^3.2.3"
|
||||
}
|
||||
},
|
||||
"stylis": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/stylis/-/stylis-3.5.3.tgz",
|
||||
"integrity": "sha512-TxU0aAscJghF9I3V9q601xcK3Uw1JbXvpsBGj/HULqexKOKlOEzzlIpLFRbKkCK990ccuxfXUqmPbIIo7Fq/cQ=="
|
||||
},
|
||||
"stylis-rule-sheet": {
|
||||
"version": "0.0.10",
|
||||
"resolved": "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz",
|
||||
"integrity": "sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw=="
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
|
||||
"integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
|
||||
"requires": {
|
||||
"has-flag": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"swagger-ui-dist": {
|
||||
"version": "3.18.0",
|
||||
"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.18.0.tgz",
|
||||
"integrity": "sha512-AwFwmd9pf4XJb/IwLvpZ6Bl6wDhjidwjgBiqGv3/kXHp1hbVWi5ZKGSwKjdJ9att6MDJFhgp0+Dvd/Zqb7uySA=="
|
||||
"version": "3.19.3",
|
||||
"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.19.3.tgz",
|
||||
"integrity": "sha512-bHH4yJrOpNCxLPqoEx2ZdwSuLMmc+V3JmFM9oetqWKKRv9AgUnrO1XNhePe9uc53QPaeJ0nCf3cLCxJBle6hjA=="
|
||||
},
|
||||
"tiny-emitter": {
|
||||
"version": "2.0.2",
|
||||
@@ -515,16 +366,6 @@
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
|
||||
"integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ=="
|
||||
},
|
||||
"ua-parser-js": {
|
||||
"version": "0.7.18",
|
||||
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.18.tgz",
|
||||
"integrity": "sha512-LtzwHlVHwFGTptfNSgezHp7WUlwiqb0gA9AALRbKaERfxwJoiX0A73QbTToxteIAuIaFshhgIZfqK8s7clqgnA=="
|
||||
},
|
||||
"whatwg-fetch": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz",
|
||||
"integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "drf-yasg",
|
||||
"dependencies": {
|
||||
"redoc": "^2.0.0-alpha.32",
|
||||
"swagger-ui-dist": "^3.18.0"
|
||||
"redoc": "^2.0.0-alpha.40",
|
||||
"swagger-ui-dist": "^3.19.3"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
coreapi>=2.3.3
|
||||
coreschema>=0.0.4
|
||||
openapi_codec>=1.3.2
|
||||
ruamel.yaml>=0.15.34
|
||||
inflection>=0.3.1
|
||||
future>=0.16.0
|
||||
six>=1.10.0
|
||||
uritemplate>=3.0.0
|
||||
|
||||
|
||||
@@ -2,3 +2,5 @@
|
||||
-r tox.txt
|
||||
-r test.txt
|
||||
-r lint.txt
|
||||
|
||||
tox-battery>=0.5
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# requirements for building and running tox
|
||||
tox>=3.1.2
|
||||
tox-battery>=0.5
|
||||
|
||||
-r setup.txt
|
||||
|
||||
@@ -33,14 +33,19 @@ SWAGGER_DEFAULTS = {
|
||||
|
||||
'USE_SESSION_AUTH': True,
|
||||
'SECURITY_DEFINITIONS': {
|
||||
'basic': {
|
||||
'Basic': {
|
||||
'type': 'basic'
|
||||
}
|
||||
},
|
||||
'SECURITY_REQUIREMENTS': None,
|
||||
'LOGIN_URL': getattr(settings, 'LOGIN_URL', None),
|
||||
'LOGOUT_URL': getattr(settings, 'LOGOUT_URL', None),
|
||||
'SPEC_URL': None,
|
||||
'VALIDATOR_URL': '',
|
||||
'PERSIST_AUTH': False,
|
||||
'REFETCH_SCHEMA_WITH_AUTH': False,
|
||||
'REFETCH_SCHEMA_ON_LOGOUT': False,
|
||||
'FETCH_SCHEMA_WITH_QUERY': True,
|
||||
|
||||
'OPERATIONS_SORTER': None,
|
||||
'TAGS_SORTER': None,
|
||||
@@ -62,13 +67,18 @@ SWAGGER_DEFAULTS = {
|
||||
'patch',
|
||||
'trace'
|
||||
],
|
||||
'DISPLAY_OPERATION_ID': True,
|
||||
}
|
||||
|
||||
REDOC_DEFAULTS = {
|
||||
'LAZY_RENDERING': True,
|
||||
'SPEC_URL': None,
|
||||
'LAZY_RENDERING': False,
|
||||
'HIDE_HOSTNAME': False,
|
||||
'EXPAND_RESPONSES': 'all',
|
||||
'PATH_IN_MIDDLE': False,
|
||||
'NATIVE_SCROLLBARS': False,
|
||||
'REQUIRED_PROPS_FIRST': False,
|
||||
'FETCH_SCHEMA_WITH_QUERY': True,
|
||||
}
|
||||
|
||||
IMPORT_STRINGS = [
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from future.utils import raise_from
|
||||
from six import raise_from
|
||||
|
||||
import copy
|
||||
import json
|
||||
|
||||
@@ -15,7 +15,7 @@ from rest_framework.settings import api_settings as rest_framework_settings
|
||||
from . import openapi
|
||||
from .app_settings import swagger_settings
|
||||
from .errors import SwaggerGenerationError
|
||||
from .inspectors.field import get_basic_type_info, get_queryset_field
|
||||
from .inspectors.field import get_basic_type_info, get_queryset_field, get_queryset_from_view
|
||||
from .openapi import ReferenceResolver
|
||||
from .utils import force_real_str, get_consumes, get_produces
|
||||
|
||||
@@ -134,7 +134,7 @@ class EndpointEnumerator(_EndpointEnumerator):
|
||||
"""Remove backslashe escapes from all path components outside {parameters}. This is needed because
|
||||
``simplify_regex`` does not handle this correctly - note however that this implementation is
|
||||
|
||||
**NOTE:** this might destructively affect some url regex patterns that contain metacharacters (e.g. \w, \d)
|
||||
**NOTE:** this might destructively affect some url regex patterns that contain metacharacters (e.g. \\w, \\d)
|
||||
outside path parameter groups; if you are in this category, God help you
|
||||
|
||||
:param str path: path possibly containing
|
||||
@@ -311,6 +311,27 @@ class OpenAPISchemaGenerator(object):
|
||||
"""
|
||||
return self._gen.determine_path_prefix(paths)
|
||||
|
||||
def should_include_endpoint(self, path, method, view, public):
|
||||
"""Check if a given endpoint should be included in the resulting schema.
|
||||
|
||||
:param str path: request path
|
||||
:param str method: http request method
|
||||
:param view: instantiated view callback
|
||||
:param bool public: if True, all endpoints are included regardless of access through `request`
|
||||
:returns: true if the view should be excluded
|
||||
:rtype: bool
|
||||
"""
|
||||
return public or self._gen.has_view_permissions(path, method, view)
|
||||
|
||||
def get_paths_object(self, paths):
|
||||
"""Construct the Swagger Paths object.
|
||||
|
||||
:param OrderedDict[str,openapi.PathItem] paths: mapping of paths to :class:`.PathItem` objects
|
||||
:returns: the :class:`.Paths` object
|
||||
:rtype: openapi.Paths
|
||||
"""
|
||||
return openapi.Paths(paths=paths)
|
||||
|
||||
def get_paths(self, endpoints, components, request, public):
|
||||
"""Generate the Swagger Paths for the API from the given endpoints.
|
||||
|
||||
@@ -331,7 +352,7 @@ class OpenAPISchemaGenerator(object):
|
||||
for path, (view_cls, methods) in sorted(endpoints.items()):
|
||||
operations = {}
|
||||
for method, view in methods:
|
||||
if not public and not self._gen.has_view_permissions(path, method, view):
|
||||
if not self.should_include_endpoint(path, method, view, public):
|
||||
continue
|
||||
|
||||
operation = self.get_operation(view, path, prefix, method, components, request)
|
||||
@@ -346,7 +367,7 @@ class OpenAPISchemaGenerator(object):
|
||||
path_suffix = '/' + path_suffix
|
||||
paths[path_suffix] = self.get_path_item(path, view_cls, operations)
|
||||
|
||||
return openapi.Paths(paths=paths), prefix
|
||||
return self.get_paths_object(paths), prefix
|
||||
|
||||
def get_operation(self, view, path, prefix, method, components, request):
|
||||
"""Get an :class:`.Operation` for the given API endpoint (path, method). This method delegates to
|
||||
@@ -424,7 +445,7 @@ class OpenAPISchemaGenerator(object):
|
||||
:rtype: list[openapi.Parameter]
|
||||
"""
|
||||
parameters = []
|
||||
queryset = getattr(view_cls, 'queryset', None)
|
||||
queryset = get_queryset_from_view(view_cls)
|
||||
|
||||
for variable in sorted(uritemplate.variables(path)):
|
||||
model, model_field = get_queryset_field(queryset, variable)
|
||||
|
||||
@@ -192,7 +192,7 @@ class FieldInspector(BaseInspector):
|
||||
|
||||
- arguments specified by the ``kwargs`` parameter of :meth:`._get_partial_types`
|
||||
- ``instance_kwargs`` passed to the constructor function
|
||||
- ``title``, ``description``, ``required`` and ``default`` inferred from the field,
|
||||
- ``title``, ``description``, ``required``, ``x-nullable`` and ``default`` inferred from the field,
|
||||
where appropriate
|
||||
|
||||
If ``existing_object`` is not ``None``, it is updated instead of creating a new object.
|
||||
@@ -225,6 +225,9 @@ class FieldInspector(BaseInspector):
|
||||
instance_kwargs.setdefault('title', title)
|
||||
if description is not None:
|
||||
instance_kwargs.setdefault('description', description)
|
||||
if field.allow_null and not instance_kwargs.get('required', False) and not field.required:
|
||||
instance_kwargs['x_nullable'] = True
|
||||
|
||||
instance_kwargs.update(kwargs)
|
||||
|
||||
if existing_object is not None:
|
||||
@@ -258,7 +261,7 @@ class SerializerInspector(FieldInspector):
|
||||
return NotHandled
|
||||
|
||||
def get_request_parameters(self, serializer, in_):
|
||||
"""Convert a DRF serializer into a list of :class:`.Parameter`\ s.
|
||||
"""Convert a DRF serializer into a list of :class:`.Parameter`\\ s.
|
||||
|
||||
Should return :data:`.NotHandled` if this inspector does not know how to handle the given `serializer`.
|
||||
|
||||
@@ -372,7 +375,7 @@ class ViewInspector(BaseInspector):
|
||||
)
|
||||
|
||||
def serializer_to_parameters(self, serializer, in_):
|
||||
"""Convert a serializer to a possibly empty list of :class:`.Parameter`\ s.
|
||||
"""Convert a serializer to a possibly empty list of :class:`.Parameter`\\ s.
|
||||
|
||||
:param serializers.BaseSerializer serializer: the ``Serializer`` instance
|
||||
:param str in_: the location of the parameters, one of the `openapi.IN_*` constants
|
||||
|
||||
@@ -17,11 +17,15 @@ from ..utils import decimal_as_float, filter_none, get_serializer_class, get_ser
|
||||
from .base import FieldInspector, NotHandled, SerializerInspector
|
||||
|
||||
try:
|
||||
# Python>=3.5
|
||||
import typing
|
||||
except ImportError:
|
||||
typing = None
|
||||
|
||||
try:
|
||||
from inspect import signature as inspect_signature
|
||||
except ImportError:
|
||||
inspect_signature = None
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -82,10 +86,10 @@ class InlineSerializerInspector(SerializerInspector):
|
||||
|
||||
ref_name = self.get_serializer_ref_name(field)
|
||||
|
||||
def make_schema_definition():
|
||||
def make_schema_definition(serializer=field):
|
||||
properties = OrderedDict()
|
||||
required = []
|
||||
for property_name, child in field.fields.items():
|
||||
for property_name, child in serializer.fields.items():
|
||||
property_name = self.get_property_name(property_name)
|
||||
prop_kwargs = {
|
||||
'read_only': bool(child.read_only) or None
|
||||
@@ -118,6 +122,8 @@ class InlineSerializerInspector(SerializerInspector):
|
||||
|
||||
definitions = self.components.with_scope(openapi.SCHEMA_DEFINITIONS)
|
||||
actual_schema = definitions.setdefault(ref_name, make_schema_definition)
|
||||
actual_schema._remove_read_only()
|
||||
|
||||
actual_serializer = get_serializer_class(getattr(actual_schema, '_serializer', None))
|
||||
this_serializer = get_serializer_class(field)
|
||||
if actual_serializer and actual_serializer != this_serializer: # pragma: no cover
|
||||
@@ -162,6 +168,25 @@ def get_model_field(model, field_name):
|
||||
return None
|
||||
|
||||
|
||||
def get_queryset_from_view(view, serializer=None):
|
||||
"""Try to get the queryset of the given view
|
||||
|
||||
:param view: the view instance or class
|
||||
:param serializer: if given, will check that the view's get_serializer_class return matches this serialzier
|
||||
:return: queryset or ``None``
|
||||
"""
|
||||
try:
|
||||
queryset = getattr(view, 'queryset', None)
|
||||
|
||||
if queryset is not None and serializer is not None:
|
||||
# make sure the view is actually using *this* serializer
|
||||
assert type(serializer) == view.get_serializer_class()
|
||||
|
||||
return queryset
|
||||
except Exception: # pragma: no cover
|
||||
return None
|
||||
|
||||
|
||||
def get_parent_serializer(field):
|
||||
"""Get the nearest parent ``Serializer`` instance for the given field.
|
||||
|
||||
@@ -194,7 +219,7 @@ def get_related_model(model, source):
|
||||
|
||||
|
||||
class RelatedFieldInspector(FieldInspector):
|
||||
"""Provides conversions for ``RelatedField``\ s."""
|
||||
"""Provides conversions for ``RelatedField``\\ s."""
|
||||
|
||||
def field_to_swagger_object(self, field, swagger_object_type, use_references, **kwargs):
|
||||
SwaggerType, ChildSwaggerType = self._get_partial_types(field, swagger_object_type, use_references, **kwargs)
|
||||
@@ -228,10 +253,18 @@ class RelatedFieldInspector(FieldInspector):
|
||||
else:
|
||||
# if the RelatedField has no queryset (e.g. read only), try to find the target model
|
||||
# from the view queryset or ModelSerializer model, if present
|
||||
view_queryset = getattr(self.view, 'queryset', None)
|
||||
serializer_meta = getattr(get_parent_serializer(field), 'Meta', None)
|
||||
this_model = getattr(view_queryset, 'model', None) or getattr(serializer_meta, 'model', None)
|
||||
parent_serializer = get_parent_serializer(field)
|
||||
|
||||
serializer_meta = getattr(parent_serializer, 'Meta', None)
|
||||
this_model = getattr(serializer_meta, 'model', None)
|
||||
if not this_model:
|
||||
view_queryset = get_queryset_from_view(self.view, parent_serializer)
|
||||
this_model = getattr(view_queryset, 'model', None)
|
||||
|
||||
source = getattr(field, 'source', '') or field.field_name
|
||||
if not source and isinstance(field.parent, serializers.ManyRelatedField):
|
||||
source = field.parent.field_name
|
||||
|
||||
model = get_related_model(this_model, source)
|
||||
model_field = get_model_field(model, target_field)
|
||||
|
||||
@@ -253,13 +286,22 @@ def find_regex(regex_field):
|
||||
regex_validator = None
|
||||
for validator in regex_field.validators:
|
||||
if isinstance(validator, validators.RegexValidator):
|
||||
if isinstance(validator, validators.URLValidator) or validator == validators.validate_ipv4_address:
|
||||
# skip the default url and IP regexes because they are complex and unhelpful
|
||||
# validate_ipv4_address is a RegexValidator instance in Django 1.11
|
||||
continue
|
||||
if regex_validator is not None:
|
||||
# bail if multiple validators are found - no obvious way to choose
|
||||
return None # pragma: no cover
|
||||
regex_validator = validator
|
||||
|
||||
# regex_validator.regex should be a compiled re object...
|
||||
pattern = getattr(getattr(regex_validator, 'regex', None), 'pattern', None)
|
||||
try:
|
||||
pattern = getattr(getattr(regex_validator, 'regex', None), 'pattern', None)
|
||||
except Exception: # pragma: no cover
|
||||
logger.warning('failed to compile regex validator of ' + str(regex_field), exc_info=True)
|
||||
return None
|
||||
|
||||
if pattern:
|
||||
# attempt some basic cleanup to remove regex constructs not supported by JavaScript
|
||||
# -- swagger uses javascript-style regexes - see https://github.com/swagger-api/swagger-editor/issues/1601
|
||||
@@ -393,7 +435,7 @@ def get_basic_type_info(field):
|
||||
return None
|
||||
|
||||
pattern = None
|
||||
if swagger_type == openapi.TYPE_STRING and format in (None, openapi.FORMAT_SLUG):
|
||||
if swagger_type == openapi.TYPE_STRING:
|
||||
pattern = find_regex(field)
|
||||
|
||||
limits = find_limits(field)
|
||||
@@ -505,11 +547,13 @@ class SerializerMethodFieldInspector(FieldInspector):
|
||||
serializer.read_only = True
|
||||
|
||||
return self.probe_field_inspectors(serializer, swagger_object_type, use_references, read_only=True)
|
||||
elif typing:
|
||||
elif typing and inspect_signature:
|
||||
# look for Python 3.5+ style type hinting of the return value
|
||||
hint_class = inspect.signature(method).return_annotation
|
||||
hint_class = inspect_signature(method).return_annotation
|
||||
|
||||
if not issubclass(hint_class, inspect._empty):
|
||||
if not inspect.isclass(hint_class) and hasattr(hint_class, '__args__'):
|
||||
hint_class = hint_class.__args__[0]
|
||||
if inspect.isclass(hint_class) and not issubclass(hint_class, inspect._empty):
|
||||
type_info = get_basic_type_info_from_hint(hint_class)
|
||||
|
||||
if type_info is not None:
|
||||
@@ -568,7 +612,7 @@ class ChoiceFieldInspector(FieldInspector):
|
||||
|
||||
|
||||
class FileFieldInspector(FieldInspector):
|
||||
"""Provides conversions for ``FileField``\ s."""
|
||||
"""Provides conversions for ``FileField``\\ s."""
|
||||
|
||||
def field_to_swagger_object(self, field, swagger_object_type, use_references, **kwargs):
|
||||
SwaggerType, ChildSwaggerType = self._get_partial_types(field, swagger_object_type, use_references, **kwargs)
|
||||
@@ -634,42 +678,56 @@ try:
|
||||
from djangorestframework_camel_case.render import CamelCaseJSONRenderer
|
||||
from djangorestframework_camel_case.render import camelize
|
||||
except ImportError: # pragma: no cover
|
||||
class CamelCaseJSONFilter(FieldInspector):
|
||||
"""Converts property names to camelCase if ``djangorestframework_camel_case`` is used."""
|
||||
pass
|
||||
else:
|
||||
def camelize_string(s):
|
||||
"""Hack to force ``djangorestframework_camel_case`` to camelize a plain string."""
|
||||
CamelCaseJSONParser = CamelCaseJSONRenderer = None
|
||||
|
||||
def camelize(data):
|
||||
return data
|
||||
|
||||
|
||||
class CamelCaseJSONFilter(FieldInspector):
|
||||
"""Converts property names to camelCase if ``djangorestframework_camel_case`` is used."""
|
||||
|
||||
def camelize_string(self, s):
|
||||
"""Hack to force ``djangorestframework_camel_case`` to camelize a plain string.
|
||||
|
||||
:param str s: the string
|
||||
:return: camelized string
|
||||
:rtype: str
|
||||
"""
|
||||
return next(iter(camelize({s: ''})))
|
||||
|
||||
def camelize_schema(schema_or_ref, components):
|
||||
"""Recursively camelize property names for the given schema using ``djangorestframework_camel_case``."""
|
||||
schema = openapi.resolve_ref(schema_or_ref, components)
|
||||
def camelize_schema(self, schema):
|
||||
"""Recursively camelize property names for the given schema using ``djangorestframework_camel_case``.
|
||||
The target schema object must be modified in-place.
|
||||
|
||||
:param openapi.Schema schema: the :class:`.Schema` object
|
||||
"""
|
||||
if getattr(schema, 'properties', {}):
|
||||
schema.properties = OrderedDict(
|
||||
(camelize_string(key), camelize_schema(val, components))
|
||||
(self.camelize_string(key), self.camelize_schema(openapi.resolve_ref(val, self.components)) or val)
|
||||
for key, val in schema.properties.items()
|
||||
)
|
||||
|
||||
if getattr(schema, 'required', []):
|
||||
schema.required = [camelize_string(p) for p in schema.required]
|
||||
schema.required = [self.camelize_string(p) for p in schema.required]
|
||||
|
||||
return schema_or_ref
|
||||
def process_result(self, result, method_name, obj, **kwargs):
|
||||
if isinstance(result, openapi.Schema.OR_REF) and self.is_camel_case():
|
||||
schema = openapi.resolve_ref(result, self.components)
|
||||
self.camelize_schema(schema)
|
||||
|
||||
class CamelCaseJSONFilter(FieldInspector):
|
||||
"""Converts property names to camelCase if ``CamelCaseJSONParser`` or ``CamelCaseJSONRenderer`` are used."""
|
||||
return result
|
||||
|
||||
if CamelCaseJSONParser and CamelCaseJSONRenderer:
|
||||
def is_camel_case(self):
|
||||
return (
|
||||
any(issubclass(parser, CamelCaseJSONParser) for parser in self.view.parser_classes) or
|
||||
any(issubclass(renderer, CamelCaseJSONRenderer) for renderer in self.view.renderer_classes)
|
||||
)
|
||||
else:
|
||||
def is_camel_case(self):
|
||||
return False
|
||||
|
||||
def process_result(self, result, method_name, obj, **kwargs):
|
||||
if isinstance(result, openapi.Schema.OR_REF) and self.is_camel_case():
|
||||
return camelize_schema(result, self.components)
|
||||
|
||||
return result
|
||||
|
||||
try:
|
||||
from rest_framework_recursive.fields import RecursiveField
|
||||
|
||||
@@ -3,14 +3,13 @@ from collections import OrderedDict
|
||||
import coreschema
|
||||
from rest_framework.pagination import CursorPagination, LimitOffsetPagination, PageNumberPagination
|
||||
|
||||
from drf_yasg.utils import force_real_str
|
||||
|
||||
from .. import openapi
|
||||
from ..utils import force_real_str
|
||||
from .base import FilterInspector, PaginatorInspector
|
||||
|
||||
|
||||
class CoreAPICompatInspector(PaginatorInspector, FilterInspector):
|
||||
"""Converts ``coreapi.Field``\ s to :class:`.openapi.Parameter`\ s for filters and paginators that implement a
|
||||
"""Converts ``coreapi.Field``\\ s to :class:`.openapi.Parameter`\\ s for filters and paginators that implement a
|
||||
``get_schema_fields`` method.
|
||||
"""
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ from rest_framework.status import is_success
|
||||
from .. import openapi
|
||||
from ..errors import SwaggerGenerationError
|
||||
from ..utils import (
|
||||
force_real_str, force_serializer_instance, get_consumes, get_produces, guess_response_status, is_list_view, no_body,
|
||||
param_list_to_odict
|
||||
force_real_str, force_serializer_instance, get_consumes, get_produces, guess_response_status, is_list_view,
|
||||
merge_params, no_body, param_list_to_odict
|
||||
)
|
||||
from .base import ViewInspector
|
||||
|
||||
@@ -63,7 +63,7 @@ class SwaggerAutoSchema(ViewInspector):
|
||||
- a list of primitive Parameters parsed as form data
|
||||
|
||||
:param list[str] consumes: a list of accepted MIME types as returned by :meth:`.get_consumes`
|
||||
:return: a (potentially empty) list of :class:`.Parameter`\ s either ``in: body`` or ``in: formData``
|
||||
:return: a (potentially empty) list of :class:`.Parameter`\\ s either ``in: body`` or ``in: formData``
|
||||
:rtype: list[openapi.Parameter]
|
||||
"""
|
||||
serializer = self.get_request_serializer()
|
||||
@@ -106,7 +106,7 @@ class SwaggerAutoSchema(ViewInspector):
|
||||
|
||||
if body_override is not None:
|
||||
if body_override is no_body:
|
||||
return None
|
||||
return no_body
|
||||
if self.method not in self.body_methods:
|
||||
raise SwaggerGenerationError("request_body can only be applied to (" + ','.join(self.body_methods) +
|
||||
"); are you looking for query_serializer or manual_parameters?")
|
||||
@@ -126,10 +126,13 @@ class SwaggerAutoSchema(ViewInspector):
|
||||
if body_override is None and self.method in self.implicit_body_methods:
|
||||
return self.get_view_serializer()
|
||||
|
||||
if body_override is no_body:
|
||||
return None
|
||||
|
||||
return body_override
|
||||
|
||||
def get_request_form_parameters(self, serializer):
|
||||
"""Given a Serializer, return a list of ``in: formData`` :class:`.Parameter`\ s.
|
||||
"""Given a Serializer, return a list of ``in: formData`` :class:`.Parameter`\\ s.
|
||||
|
||||
:param serializer: the view's request serializer as returned by :meth:`.get_request_serializer`
|
||||
:rtype: list[openapi.Parameter]
|
||||
@@ -159,21 +162,19 @@ class SwaggerAutoSchema(ViewInspector):
|
||||
:return: modified parameters
|
||||
:rtype: list[openapi.Parameter]
|
||||
"""
|
||||
parameters = param_list_to_odict(parameters)
|
||||
manual_parameters = self.overrides.get('manual_parameters', None) or []
|
||||
|
||||
if any(param.in_ == openapi.IN_BODY for param in manual_parameters): # pragma: no cover
|
||||
raise SwaggerGenerationError("specify the body parameter as a Schema or Serializer in request_body")
|
||||
if any(param.in_ == openapi.IN_FORM for param in manual_parameters): # pragma: no cover
|
||||
if any(param.in_ == openapi.IN_BODY for param in parameters.values()):
|
||||
if any(param.in_ == openapi.IN_BODY for param in parameters):
|
||||
raise SwaggerGenerationError("cannot add form parameters when the request has a request body; "
|
||||
"did you forget to set an appropriate parser class on the view?")
|
||||
if self.method not in self.body_methods:
|
||||
raise SwaggerGenerationError("form parameters can only be applied to (" + ','.join(self.body_methods) +
|
||||
") HTTP methods")
|
||||
|
||||
parameters.update(param_list_to_odict(manual_parameters))
|
||||
return list(parameters.values())
|
||||
return merge_params(parameters, manual_parameters)
|
||||
|
||||
def get_responses(self):
|
||||
"""Get the possible responses for this view as a swagger :class:`.Responses` object.
|
||||
@@ -192,7 +193,11 @@ class SwaggerAutoSchema(ViewInspector):
|
||||
|
||||
:return: response serializer, :class:`.Schema`, :class:`.SchemaRef`, ``None``
|
||||
"""
|
||||
return self._get_request_body_override() or self.get_view_serializer()
|
||||
body_override = self._get_request_body_override()
|
||||
if body_override and body_override is not no_body:
|
||||
return body_override
|
||||
|
||||
return self.get_view_serializer()
|
||||
|
||||
def get_default_responses(self):
|
||||
"""Get the default responses determined for this view from the request serializer and request method.
|
||||
@@ -207,8 +212,6 @@ class SwaggerAutoSchema(ViewInspector):
|
||||
default_schema = self.get_default_response_serializer()
|
||||
|
||||
default_schema = default_schema or ''
|
||||
if any(is_form_media_type(encoding) for encoding in self.get_consumes()):
|
||||
default_schema = ''
|
||||
if default_schema and not isinstance(default_schema, openapi.Schema):
|
||||
default_schema = self.serializer_to_schema(default_schema) or ''
|
||||
|
||||
@@ -223,7 +226,7 @@ class SwaggerAutoSchema(ViewInspector):
|
||||
def get_response_serializers(self):
|
||||
"""Return the response codes that this view is expected to return, and the serializer for each response body.
|
||||
The return value should be a dict where the keys are possible status codes, and values are either strings,
|
||||
``Serializer``\ s, :class:`.Schema`, :class:`.SchemaRef` or :class:`.Response` objects. See
|
||||
``Serializer``\\ s, :class:`.Schema`, :class:`.SchemaRef` or :class:`.Response` objects. See
|
||||
:func:`@swagger_auto_schema <.swagger_auto_schema>` for more details.
|
||||
|
||||
:return: the response serializers
|
||||
@@ -318,16 +321,32 @@ class SwaggerAutoSchema(ViewInspector):
|
||||
operation_id = '_'.join(operation_keys)
|
||||
return operation_id
|
||||
|
||||
def _extract_description_and_summary(self):
|
||||
description = self.overrides.get('operation_description', None)
|
||||
summary = self.overrides.get('operation_summary', None)
|
||||
if description is None:
|
||||
description = self._sch.get_description(self.path, self.method) or ''
|
||||
description = description.strip().replace('\r', '')
|
||||
|
||||
if description and (summary is None):
|
||||
# description from docstring ... do summary magic
|
||||
# https://www.python.org/dev/peps/pep-0257/#multi-line-docstrings
|
||||
summary_max_len = 120 # OpenAPI 2.0 spec says summary should be under 120 characters
|
||||
sections = description.split('\n\n', 1)
|
||||
if len(sections) == 2:
|
||||
sections[0] = sections[0].strip()
|
||||
if len(sections[0]) < summary_max_len:
|
||||
summary, description = sections
|
||||
|
||||
return description, summary
|
||||
|
||||
def get_description(self):
|
||||
"""Return an operation description determined as appropriate from the view's method and class docstrings.
|
||||
|
||||
:return: the operation description
|
||||
:rtype: str
|
||||
"""
|
||||
description = self.overrides.get('operation_description', None)
|
||||
if description is None:
|
||||
description = self._sch.get_description(self.path, self.method)
|
||||
return description
|
||||
return self._extract_description_and_summary()[0]
|
||||
|
||||
def get_summary(self):
|
||||
"""Return a summary description for this operation.
|
||||
@@ -335,7 +354,7 @@ class SwaggerAutoSchema(ViewInspector):
|
||||
:return: the summary
|
||||
:rtype: str
|
||||
"""
|
||||
return self.overrides.get('operation_summary', None)
|
||||
return self._extract_description_and_summary()[1]
|
||||
|
||||
def get_security(self):
|
||||
"""Return a list of security requirements for this operation.
|
||||
|
||||
+27
-7
@@ -291,6 +291,8 @@ class Paths(SwaggerDict):
|
||||
|
||||
|
||||
class PathItem(SwaggerDict):
|
||||
OPERATION_NAMES = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch']
|
||||
|
||||
def __init__(self, get=None, put=None, post=None, delete=None, options=None,
|
||||
head=None, patch=None, parameters=None, **extra):
|
||||
"""Information about a single path
|
||||
@@ -315,6 +317,15 @@ class PathItem(SwaggerDict):
|
||||
self.parameters = filter_none(parameters)
|
||||
self._insert_extras__()
|
||||
|
||||
@property
|
||||
def operations(self):
|
||||
"""A list of all standard Operations on this PathItem object. See :attr:`.OPERATION_NAMES`.
|
||||
|
||||
:return: list of (method name, Operation) tuples
|
||||
:rtype: list[tuple[str,Operation]]
|
||||
"""
|
||||
return [(k, v) for k, v in self.items() if k in PathItem.OPERATION_NAMES and v]
|
||||
|
||||
|
||||
class Operation(SwaggerDict):
|
||||
def __init__(self, operation_id, responses, parameters=None, consumes=None, produces=None, summary=None,
|
||||
@@ -387,8 +398,6 @@ class Parameter(SwaggerDict):
|
||||
:param default: default value if the parameter is not provided; must conform to parameter type
|
||||
"""
|
||||
super(Parameter, self).__init__(**extra)
|
||||
if (not schema and not type) or (schema and type):
|
||||
raise AssertionError("either schema or type are required for Parameter object!")
|
||||
self.name = name
|
||||
self.in_ = in_
|
||||
self.description = description
|
||||
@@ -401,6 +410,10 @@ class Parameter(SwaggerDict):
|
||||
self.items = items
|
||||
self.default = default
|
||||
self._insert_extras__()
|
||||
if (not schema and not type) or (schema and type):
|
||||
raise AssertionError("either schema or type are required for Parameter object (not both)!")
|
||||
if schema and isinstance(schema, Schema):
|
||||
schema._remove_read_only()
|
||||
if self['in'] == IN_PATH:
|
||||
# path parameters must always be required
|
||||
assert required is not False, "path parameter cannot be optional"
|
||||
@@ -432,9 +445,9 @@ class Schema(SwaggerDict):
|
||||
:param bool,.Schema,.SchemaRef additional_properties: allow wildcard properties not listed in `properties`
|
||||
:param list[str] required: list of requried property names
|
||||
:param .Schema,.SchemaRef items: type of array items, only valid if `type` is ``array``
|
||||
:param default: only valid when insider another ``Schema``\ 's ``properties``;
|
||||
:param default: only valid when insider another ``Schema``\\ 's ``properties``;
|
||||
the default value of this property if it is not provided, must conform to the type of this Schema
|
||||
:param read_only: only valid when insider another ``Schema``\ 's ``properties``;
|
||||
:param read_only: only valid when insider another ``Schema``\\ 's ``properties``;
|
||||
declares the property as read only - it must only be sent as part of responses, never in requests
|
||||
"""
|
||||
super(Schema, self).__init__(**extra)
|
||||
@@ -465,6 +478,11 @@ class Schema(SwaggerDict):
|
||||
if pattern and type != TYPE_STRING:
|
||||
raise AssertionError("pattern can only be used when type is string")
|
||||
|
||||
def _remove_read_only(self):
|
||||
# readOnly is only valid for Schemas inside another Schema's properties;
|
||||
# when placing Schema elsewhere we must take care to remove the readOnly flag
|
||||
self.pop('readOnly', '')
|
||||
|
||||
|
||||
class _Ref(SwaggerDict):
|
||||
ref_name_re = re.compile(r"#/(?P<scope>.+)/(?P<name>[^/]+)$")
|
||||
@@ -497,12 +515,12 @@ class _Ref(SwaggerDict):
|
||||
ref_match = self.ref_name_re.match(self.ref)
|
||||
return resolver.get(ref_match.group('name'), scope=ref_match.group('scope'))
|
||||
|
||||
def __setitem__(self, key, value, **kwargs):
|
||||
def __setitem__(self, key, value):
|
||||
if key == "$ref":
|
||||
return super(_Ref, self).__setitem__(key, value, **kwargs)
|
||||
return super(_Ref, self).__setitem__(key, value)
|
||||
raise NotImplementedError("only $ref can be set on Reference objects (not %s)" % key)
|
||||
|
||||
def __delitem__(self, key, **kwargs):
|
||||
def __delitem__(self, key):
|
||||
raise NotImplementedError("cannot delete property of Reference object")
|
||||
|
||||
|
||||
@@ -560,6 +578,8 @@ class Response(SwaggerDict):
|
||||
self.schema = schema
|
||||
self.examples = examples
|
||||
self._insert_extras__()
|
||||
if schema and isinstance(schema, Schema):
|
||||
schema._remove_read_only()
|
||||
|
||||
|
||||
class ReferenceResolver(object):
|
||||
|
||||
+83
-48
@@ -1,11 +1,14 @@
|
||||
import six
|
||||
|
||||
from django.shortcuts import render, resolve_url
|
||||
from django.utils.functional import Promise
|
||||
from rest_framework.renderers import BaseRenderer, JSONRenderer, TemplateHTMLRenderer
|
||||
from rest_framework.utils import json
|
||||
|
||||
from drf_yasg.openapi import Swagger
|
||||
|
||||
from .app_settings import redoc_settings, swagger_settings
|
||||
from .codecs import VALIDATORS, OpenAPICodecJson, OpenAPICodecYaml
|
||||
from .openapi import Swagger
|
||||
from .utils import filter_none
|
||||
|
||||
|
||||
class _SpecRenderer(BaseRenderer):
|
||||
@@ -25,7 +28,7 @@ class _SpecRenderer(BaseRenderer):
|
||||
|
||||
if not isinstance(data, Swagger): # pragma: no cover
|
||||
# if `swagger` is not a ``Swagger`` object, it means we somehow got a non-success ``Response``
|
||||
# in that case, it's probably better to let the default ``TemplateHTMLRenderer`` render it
|
||||
# in that case, it's probably better to let the default ``JSONRenderer`` render it
|
||||
# see https://github.com/axnsan12/drf-yasg/issues/58
|
||||
return JSONRenderer().render(data, media_type, renderer_context)
|
||||
return codec.encode(data)
|
||||
@@ -65,32 +68,60 @@ class _UIRenderer(BaseRenderer):
|
||||
# see https://github.com/axnsan12/drf-yasg/issues/58
|
||||
return TemplateHTMLRenderer().render(swagger, accepted_media_type, renderer_context)
|
||||
self.set_context(renderer_context, swagger)
|
||||
return render(
|
||||
renderer_context['request'],
|
||||
self.template,
|
||||
renderer_context
|
||||
)
|
||||
return render(renderer_context['request'], self.template, renderer_context)
|
||||
|
||||
def set_context(self, renderer_context, swagger):
|
||||
renderer_context['title'] = swagger.info.title
|
||||
renderer_context['version'] = swagger.info.version
|
||||
renderer_context['swagger_settings'] = json.dumps(self.get_swagger_ui_settings())
|
||||
renderer_context['redoc_settings'] = json.dumps(self.get_redoc_settings())
|
||||
def set_context(self, renderer_context, swagger=None):
|
||||
renderer_context['title'] = swagger.info.title or '' if swagger else ''
|
||||
renderer_context['version'] = swagger.info.version or '' if swagger else ''
|
||||
renderer_context['oauth2_config'] = json.dumps(self.get_oauth2_config())
|
||||
renderer_context['USE_SESSION_AUTH'] = swagger_settings.USE_SESSION_AUTH
|
||||
renderer_context.update(self.get_auth_urls())
|
||||
|
||||
def get_auth_urls(self):
|
||||
urls = {}
|
||||
if swagger_settings.LOGIN_URL is not None:
|
||||
urls['LOGIN_URL'] = resolve_url(swagger_settings.LOGIN_URL)
|
||||
if swagger_settings.LOGOUT_URL is not None:
|
||||
urls['LOGOUT_URL'] = resolve_url(swagger_settings.LOGOUT_URL)
|
||||
def resolve_url(self, to):
|
||||
if isinstance(to, Promise):
|
||||
to = str(to)
|
||||
|
||||
return urls
|
||||
if to is None:
|
||||
return None
|
||||
|
||||
args, kwargs = None, None
|
||||
if not isinstance(to, six.string_types):
|
||||
if len(to) > 2:
|
||||
to, args, kwargs = to
|
||||
elif len(to) == 2:
|
||||
to, kwargs = to
|
||||
|
||||
args = args or ()
|
||||
kwargs = kwargs or {}
|
||||
|
||||
return resolve_url(to, *args, **kwargs)
|
||||
|
||||
def get_auth_urls(self):
|
||||
urls = {
|
||||
'LOGIN_URL': self.resolve_url(swagger_settings.LOGIN_URL),
|
||||
'LOGOUT_URL': self.resolve_url(swagger_settings.LOGOUT_URL),
|
||||
}
|
||||
|
||||
return filter_none(urls)
|
||||
|
||||
def get_oauth2_config(self):
|
||||
data = swagger_settings.OAUTH2_CONFIG
|
||||
assert isinstance(data, dict), "OAUTH2_CONFIG must be a dict"
|
||||
return data
|
||||
|
||||
|
||||
class SwaggerUIRenderer(_UIRenderer):
|
||||
"""Renders a swagger-ui web interface for schema browisng."""
|
||||
template = 'drf-yasg/swagger-ui.html'
|
||||
format = 'swagger'
|
||||
|
||||
def set_context(self, renderer_context, swagger=None):
|
||||
super(SwaggerUIRenderer, self).set_context(renderer_context, swagger)
|
||||
renderer_context['swagger_settings'] = json.dumps(self.get_swagger_ui_settings())
|
||||
|
||||
def get_swagger_ui_settings(self):
|
||||
data = {
|
||||
'url': self.resolve_url(swagger_settings.SPEC_URL),
|
||||
'operationsSorter': swagger_settings.OPERATIONS_SORTER,
|
||||
'tagsSorter': swagger_settings.TAGS_SORTER,
|
||||
'docExpansion': swagger_settings.DOC_EXPANSION,
|
||||
@@ -102,40 +133,44 @@ class _UIRenderer(BaseRenderer):
|
||||
'showCommonExtensions': swagger_settings.SHOW_COMMON_EXTENSIONS,
|
||||
'oauth2RedirectUrl': swagger_settings.OAUTH2_REDIRECT_URL,
|
||||
'supportedSubmitMethods': swagger_settings.SUPPORTED_SUBMIT_METHODS,
|
||||
'displayOperationId': swagger_settings.DISPLAY_OPERATION_ID,
|
||||
'persistAuth': swagger_settings.PERSIST_AUTH,
|
||||
'refetchWithAuth': swagger_settings.REFETCH_SCHEMA_WITH_AUTH,
|
||||
'refetchOnLogout': swagger_settings.REFETCH_SCHEMA_ON_LOGOUT,
|
||||
'fetchSchemaWithQuery': swagger_settings.FETCH_SCHEMA_WITH_QUERY,
|
||||
}
|
||||
data = {k: v for k, v in data.items() if v is not None}
|
||||
|
||||
data = filter_none(data)
|
||||
if swagger_settings.VALIDATOR_URL != '':
|
||||
data['validatorUrl'] = swagger_settings.VALIDATOR_URL
|
||||
data['validatorUrl'] = self.resolve_url(swagger_settings.VALIDATOR_URL)
|
||||
|
||||
return data
|
||||
|
||||
def get_redoc_settings(self):
|
||||
data = {
|
||||
'lazyRendering': redoc_settings.LAZY_RENDERING,
|
||||
'hideHostname': redoc_settings.HIDE_HOSTNAME,
|
||||
'expandResponses': redoc_settings.EXPAND_RESPONSES,
|
||||
'pathInMiddle': redoc_settings.PATH_IN_MIDDLE,
|
||||
}
|
||||
|
||||
return data
|
||||
|
||||
def get_oauth2_config(self):
|
||||
data = swagger_settings.OAUTH2_CONFIG
|
||||
assert isinstance(data, dict), "OAUTH2_CONFIG must be a dict"
|
||||
return data
|
||||
|
||||
|
||||
class SwaggerUIRenderer(_UIRenderer):
|
||||
"""Renders a swagger-ui web interface for schema browisng.
|
||||
Also requires :class:`.OpenAPIRenderer` as an available renderer on the same view.
|
||||
"""
|
||||
template = 'drf-yasg/swagger-ui.html'
|
||||
format = 'swagger'
|
||||
|
||||
|
||||
class ReDocRenderer(_UIRenderer):
|
||||
"""Renders a ReDoc web interface for schema browisng.
|
||||
Also requires :class:`.OpenAPIRenderer` as an available renderer on the same view.
|
||||
"""
|
||||
"""Renders a ReDoc web interface for schema browisng."""
|
||||
template = 'drf-yasg/redoc.html'
|
||||
format = 'redoc'
|
||||
|
||||
def set_context(self, renderer_context, swagger=None):
|
||||
super(ReDocRenderer, self).set_context(renderer_context, swagger)
|
||||
renderer_context['redoc_settings'] = json.dumps(self.get_redoc_settings())
|
||||
|
||||
def get_redoc_settings(self):
|
||||
data = {
|
||||
'url': self.resolve_url(redoc_settings.SPEC_URL),
|
||||
'lazyRendering': redoc_settings.LAZY_RENDERING,
|
||||
'hideHostname': redoc_settings.HIDE_HOSTNAME,
|
||||
'expandResponses': redoc_settings.EXPAND_RESPONSES,
|
||||
'pathInMiddlePanel': redoc_settings.PATH_IN_MIDDLE,
|
||||
'nativeScrollbars': redoc_settings.NATIVE_SCROLLBARS,
|
||||
'requiredPropsFirst': redoc_settings.REQUIRED_PROPS_FIRST,
|
||||
'fetchSchemaWithQuery': redoc_settings.FETCH_SCHEMA_WITH_QUERY,
|
||||
}
|
||||
|
||||
return filter_none(data)
|
||||
|
||||
|
||||
class ReDocOldRenderer(ReDocRenderer):
|
||||
"""Renders a ReDoc 1.x.x web interface for schema browisng."""
|
||||
template = 'drf-yasg/redoc-old.html'
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Copyright (c) 2014-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Immutable=e()}(this,function(){"use strict";function t(t,e){e&&(t.prototype=Object.create(e.prototype)),t.prototype.constructor=t}function e(t){return o(t)?t:O(t)}function r(t){return u(t)?t:x(t)}function n(t){return s(t)?t:k(t)}function i(t){return o(t)&&!a(t)?t:A(t)}function o(t){return!(!t||!t[ar])}function u(t){return!(!t||!t[hr])}function s(t){return!(!t||!t[fr])}function a(t){return u(t)||s(t)}function h(t){return!(!t||!t[cr])}function f(t){return t.value=!1,t}function c(t){t&&(t.value=!0)}function _(){}function p(t,e){e=e||0;for(var r=Math.max(0,t.length-e),n=Array(r),i=0;r>i;i++)n[i]=t[i+e];return n}function v(t){return void 0===t.size&&(t.size=t.__iterate(y)),t.size}function l(t,e){if("number"!=typeof e){var r=e>>>0;if(""+r!==e||4294967295===r)return NaN;e=r}return 0>e?v(t)+e:e}function y(){return!0}function d(t,e,r){return(0===t||void 0!==r&&-r>=t)&&(void 0===e||void 0!==r&&e>=r)}function m(t,e){return w(t,e,0)}function g(t,e){return w(t,e,e)}function w(t,e,r){return void 0===t?r:0>t?Math.max(0,e+t):void 0===e?t:Math.min(e,t)}function S(t){this.next=t}function z(t,e,r,n){var i=0===t?e:1===t?r:[e,r];return n?n.value=i:n={value:i,done:!1},n}function I(){return{value:void 0,done:!0}}function b(t){return!!M(t)}function q(t){return t&&"function"==typeof t.next}function D(t){var e=M(t);return e&&e.call(t)}function M(t){var e=t&&(zr&&t[zr]||t[Ir]);return"function"==typeof e?e:void 0}function E(t){return t&&"number"==typeof t.length}function O(t){return null===t||void 0===t?T():o(t)?t.toSeq():C(t)}function x(t){return null===t||void 0===t?T().toKeyedSeq():o(t)?u(t)?t.toSeq():t.fromEntrySeq():B(t)}function k(t){return null===t||void 0===t?T():o(t)?u(t)?t.entrySeq():t.toIndexedSeq():W(t)}function A(t){return(null===t||void 0===t?T():o(t)?u(t)?t.entrySeq():t:W(t)).toSetSeq()}function j(t){this._array=t,this.size=t.length}function R(t){var e=Object.keys(t);this._object=t,this._keys=e,
|
||||
this.size=e.length}function U(t){this._iterable=t,this.size=t.length||t.size}function K(t){this._iterator=t,this._iteratorCache=[]}function L(t){return!(!t||!t[qr])}function T(){return Dr||(Dr=new j([]))}function B(t){var e=Array.isArray(t)?new j(t).fromEntrySeq():q(t)?new K(t).fromEntrySeq():b(t)?new U(t).fromEntrySeq():"object"==typeof t?new R(t):void 0;if(!e)throw new TypeError("Expected Array or iterable object of [k, v] entries, or keyed object: "+t);return e}function W(t){var e=J(t);if(!e)throw new TypeError("Expected Array or iterable object of values: "+t);return e}function C(t){var e=J(t)||"object"==typeof t&&new R(t);if(!e)throw new TypeError("Expected Array or iterable object of values, or keyed object: "+t);return e}function J(t){return E(t)?new j(t):q(t)?new K(t):b(t)?new U(t):void 0}function N(t,e,r,n){var i=t._cache;if(i){for(var o=i.length-1,u=0;o>=u;u++){var s=i[r?o-u:u];if(e(s[1],n?s[0]:u,t)===!1)return u+1}return u}return t.__iterateUncached(e,r)}function P(t,e,r,n){var i=t._cache;if(i){var o=i.length-1,u=0;return new S(function(){var t=i[r?o-u:u];return u++>o?I():z(e,n?t[0]:u-1,t[1])})}return t.__iteratorUncached(e,r)}function H(t,e){return e?V(e,t,"",{"":t}):Y(t)}function V(t,e,r,n){return Array.isArray(e)?t.call(n,r,k(e).map(function(r,n){return V(t,r,n,e)})):Q(e)?t.call(n,r,x(e).map(function(r,n){return V(t,r,n,e)})):e}function Y(t){return Array.isArray(t)?k(t).map(Y).toList():Q(t)?x(t).map(Y).toMap():t}function Q(t){return t&&(t.constructor===Object||void 0===t.constructor)}function X(t,e){if(t===e||t!==t&&e!==e)return!0;if(!t||!e)return!1;if("function"==typeof t.valueOf&&"function"==typeof e.valueOf){if(t=t.valueOf(),e=e.valueOf(),t===e||t!==t&&e!==e)return!0;if(!t||!e)return!1}return"function"==typeof t.equals&&"function"==typeof e.equals&&t.equals(e)?!0:!1}function F(t,e){if(t===e)return!0;if(!o(e)||void 0!==t.size&&void 0!==e.size&&t.size!==e.size||void 0!==t.__hash&&void 0!==e.__hash&&t.__hash!==e.__hash||u(t)!==u(e)||s(t)!==s(e)||h(t)!==h(e))return!1;if(0===t.size&&0===e.size)return!0;
|
||||
var r=!a(t);if(h(t)){var n=t.entries();return e.every(function(t,e){var i=n.next().value;return i&&X(i[1],t)&&(r||X(i[0],e))})&&n.next().done}var i=!1;if(void 0===t.size)if(void 0===e.size)"function"==typeof t.cacheResult&&t.cacheResult();else{i=!0;var f=t;t=e,e=f}var c=!0,_=e.__iterate(function(e,n){return(r?t.has(e):i?X(e,t.get(n,yr)):X(t.get(n,yr),e))?void 0:(c=!1,!1)});return c&&t.size===_}function G(t,e){if(!(this instanceof G))return new G(t,e);if(this._value=t,this.size=void 0===e?1/0:Math.max(0,e),0===this.size){if(Mr)return Mr;Mr=this}}function Z(t,e){if(!t)throw Error(e)}function $(t,e,r){if(!(this instanceof $))return new $(t,e,r);if(Z(0!==r,"Cannot step a Range by 0"),t=t||0,void 0===e&&(e=1/0),r=void 0===r?1:Math.abs(r),t>e&&(r=-r),this._start=t,this._end=e,this._step=r,this.size=Math.max(0,Math.ceil((e-t)/r-1)+1),0===this.size){if(Er)return Er;Er=this}}function tt(){throw TypeError("Abstract")}function et(){}function rt(){}function nt(){}function it(t){return t>>>1&1073741824|3221225471&t}function ot(t){if(t===!1||null===t||void 0===t)return 0;if("function"==typeof t.valueOf&&(t=t.valueOf(),t===!1||null===t||void 0===t))return 0;if(t===!0)return 1;var e=typeof t;if("number"===e){if(t!==t||t===1/0)return 0;var r=0|t;for(r!==t&&(r^=4294967295*t);t>4294967295;)t/=4294967295,r^=t;return it(r)}if("string"===e)return t.length>Kr?ut(t):st(t);if("function"==typeof t.hashCode)return t.hashCode();if("object"===e)return at(t);if("function"==typeof t.toString)return st(""+t);throw Error("Value type "+e+" cannot be hashed.")}function ut(t){var e=Br[t];return void 0===e&&(e=st(t),Tr===Lr&&(Tr=0,Br={}),Tr++,Br[t]=e),e}function st(t){for(var e=0,r=0;t.length>r;r++)e=31*e+t.charCodeAt(r)|0;return it(e)}function at(t){var e;if(jr&&(e=Or.get(t),void 0!==e))return e;if(e=t[Ur],void 0!==e)return e;if(!Ar){if(e=t.propertyIsEnumerable&&t.propertyIsEnumerable[Ur],void 0!==e)return e;if(e=ht(t),void 0!==e)return e}if(e=++Rr,1073741824&Rr&&(Rr=0),jr)Or.set(t,e);else{if(void 0!==kr&&kr(t)===!1)throw Error("Non-extensible objects are not allowed as keys.");
|
||||
if(Ar)Object.defineProperty(t,Ur,{enumerable:!1,configurable:!1,writable:!1,value:e});else if(void 0!==t.propertyIsEnumerable&&t.propertyIsEnumerable===t.constructor.prototype.propertyIsEnumerable)t.propertyIsEnumerable=function(){return this.constructor.prototype.propertyIsEnumerable.apply(this,arguments)},t.propertyIsEnumerable[Ur]=e;else{if(void 0===t.nodeType)throw Error("Unable to set a non-enumerable property on object.");t[Ur]=e}}return e}function ht(t){if(t&&t.nodeType>0)switch(t.nodeType){case 1:return t.uniqueID;case 9:return t.documentElement&&t.documentElement.uniqueID}}function ft(t){Z(t!==1/0,"Cannot perform this action with an infinite size.")}function ct(t){return null===t||void 0===t?zt():_t(t)&&!h(t)?t:zt().withMutations(function(e){var n=r(t);ft(n.size),n.forEach(function(t,r){return e.set(r,t)})})}function _t(t){return!(!t||!t[Wr])}function pt(t,e){this.ownerID=t,this.entries=e}function vt(t,e,r){this.ownerID=t,this.bitmap=e,this.nodes=r}function lt(t,e,r){this.ownerID=t,this.count=e,this.nodes=r}function yt(t,e,r){this.ownerID=t,this.keyHash=e,this.entries=r}function dt(t,e,r){this.ownerID=t,this.keyHash=e,this.entry=r}function mt(t,e,r){this._type=e,this._reverse=r,this._stack=t._root&&wt(t._root)}function gt(t,e){return z(t,e[0],e[1])}function wt(t,e){return{node:t,index:0,__prev:e}}function St(t,e,r,n){var i=Object.create(Cr);return i.size=t,i._root=e,i.__ownerID=r,i.__hash=n,i.__altered=!1,i}function zt(){return Jr||(Jr=St(0))}function It(t,e,r){var n,i;if(t._root){var o=f(dr),u=f(mr);if(n=bt(t._root,t.__ownerID,0,void 0,e,r,o,u),!u.value)return t;i=t.size+(o.value?r===yr?-1:1:0)}else{if(r===yr)return t;i=1,n=new pt(t.__ownerID,[[e,r]])}return t.__ownerID?(t.size=i,t._root=n,t.__hash=void 0,t.__altered=!0,t):n?St(i,n):zt()}function bt(t,e,r,n,i,o,u,s){return t?t.update(e,r,n,i,o,u,s):o===yr?t:(c(s),c(u),new dt(e,n,[i,o]))}function qt(t){return t.constructor===dt||t.constructor===yt}function Dt(t,e,r,n,i){if(t.keyHash===n)return new yt(e,n,[t.entry,i]);var o,u=(0===r?t.keyHash:t.keyHash>>>r)&lr,s=(0===r?n:n>>>r)&lr,a=u===s?[Dt(t,e,r+pr,n,i)]:(o=new dt(e,n,i),
|
||||
s>u?[t,o]:[o,t]);return new vt(e,1<<u|1<<s,a)}function Mt(t,e,r,n){t||(t=new _);for(var i=new dt(t,ot(r),[r,n]),o=0;e.length>o;o++){var u=e[o];i=i.update(t,0,void 0,u[0],u[1])}return i}function Et(t,e,r,n){for(var i=0,o=0,u=Array(r),s=0,a=1,h=e.length;h>s;s++,a<<=1){var f=e[s];void 0!==f&&s!==n&&(i|=a,u[o++]=f)}return new vt(t,i,u)}function Ot(t,e,r,n,i){for(var o=0,u=Array(vr),s=0;0!==r;s++,r>>>=1)u[s]=1&r?e[o++]:void 0;return u[n]=i,new lt(t,o+1,u)}function xt(t,e,n){for(var i=[],u=0;n.length>u;u++){var s=n[u],a=r(s);o(s)||(a=a.map(function(t){return H(t)})),i.push(a)}return jt(t,e,i)}function kt(t,e,r){return t&&t.mergeDeep&&o(e)?t.mergeDeep(e):X(t,e)?t:e}function At(t){return function(e,r,n){if(e&&e.mergeDeepWith&&o(r))return e.mergeDeepWith(t,r);var i=t(e,r,n);return X(e,i)?e:i}}function jt(t,e,r){return r=r.filter(function(t){return 0!==t.size}),0===r.length?t:0!==t.size||t.__ownerID||1!==r.length?t.withMutations(function(t){for(var n=e?function(r,n){t.update(n,yr,function(t){return t===yr?r:e(t,r,n)})}:function(e,r){t.set(r,e)},i=0;r.length>i;i++)r[i].forEach(n)}):t.constructor(r[0])}function Rt(t,e,r,n){var i=t===yr,o=e.next();if(o.done){var u=i?r:t,s=n(u);return s===u?t:s}Z(i||t&&t.set,"invalid keyPath");var a=o.value,h=i?yr:t.get(a,yr),f=Rt(h,e,r,n);return f===h?t:f===yr?t.remove(a):(i?zt():t).set(a,f)}function Ut(t){return t-=t>>1&1431655765,t=(858993459&t)+(t>>2&858993459),t=t+(t>>4)&252645135,t+=t>>8,t+=t>>16,127&t}function Kt(t,e,r,n){var i=n?t:p(t);return i[e]=r,i}function Lt(t,e,r,n){var i=t.length+1;if(n&&e+1===i)return t[e]=r,t;for(var o=Array(i),u=0,s=0;i>s;s++)s===e?(o[s]=r,u=-1):o[s]=t[s+u];return o}function Tt(t,e,r){var n=t.length-1;if(r&&e===n)return t.pop(),t;for(var i=Array(n),o=0,u=0;n>u;u++)u===e&&(o=1),i[u]=t[u+o];return i}function Bt(t){var e=Pt();if(null===t||void 0===t)return e;if(Wt(t))return t;var r=n(t),i=r.size;return 0===i?e:(ft(i),i>0&&vr>i?Nt(0,i,pr,null,new Ct(r.toArray())):e.withMutations(function(t){t.setSize(i),r.forEach(function(e,r){return t.set(r,e)})}))}function Wt(t){
|
||||
return!(!t||!t[Vr])}function Ct(t,e){this.array=t,this.ownerID=e}function Jt(t,e){function r(t,e,r){return 0===e?n(t,r):i(t,e,r)}function n(t,r){var n=r===s?a&&a.array:t&&t.array,i=r>o?0:o-r,h=u-r;return h>vr&&(h=vr),function(){if(i===h)return Xr;var t=e?--h:i++;return n&&n[t]}}function i(t,n,i){var s,a=t&&t.array,h=i>o?0:o-i>>n,f=(u-i>>n)+1;return f>vr&&(f=vr),function(){for(;;){if(s){var t=s();if(t!==Xr)return t;s=null}if(h===f)return Xr;var o=e?--f:h++;s=r(a&&a[o],n-pr,i+(o<<n))}}}var o=t._origin,u=t._capacity,s=Gt(u),a=t._tail;return r(t._root,t._level,0)}function Nt(t,e,r,n,i,o,u){var s=Object.create(Yr);return s.size=e-t,s._origin=t,s._capacity=e,s._level=r,s._root=n,s._tail=i,s.__ownerID=o,s.__hash=u,s.__altered=!1,s}function Pt(){return Qr||(Qr=Nt(0,0,pr))}function Ht(t,e,r){if(e=l(t,e),e!==e)return t;if(e>=t.size||0>e)return t.withMutations(function(t){0>e?Xt(t,e).set(0,r):Xt(t,0,e+1).set(e,r)});e+=t._origin;var n=t._tail,i=t._root,o=f(mr);return e>=Gt(t._capacity)?n=Vt(n,t.__ownerID,0,e,r,o):i=Vt(i,t.__ownerID,t._level,e,r,o),o.value?t.__ownerID?(t._root=i,t._tail=n,t.__hash=void 0,t.__altered=!0,t):Nt(t._origin,t._capacity,t._level,i,n):t}function Vt(t,e,r,n,i,o){var u=n>>>r&lr,s=t&&t.array.length>u;if(!s&&void 0===i)return t;var a;if(r>0){var h=t&&t.array[u],f=Vt(h,e,r-pr,n,i,o);return f===h?t:(a=Yt(t,e),a.array[u]=f,a)}return s&&t.array[u]===i?t:(c(o),a=Yt(t,e),void 0===i&&u===a.array.length-1?a.array.pop():a.array[u]=i,a)}function Yt(t,e){return e&&t&&e===t.ownerID?t:new Ct(t?t.array.slice():[],e)}function Qt(t,e){if(e>=Gt(t._capacity))return t._tail;if(1<<t._level+pr>e){for(var r=t._root,n=t._level;r&&n>0;)r=r.array[e>>>n&lr],n-=pr;return r}}function Xt(t,e,r){void 0!==e&&(e=0|e),void 0!==r&&(r=0|r);var n=t.__ownerID||new _,i=t._origin,o=t._capacity,u=i+e,s=void 0===r?o:0>r?o+r:i+r;if(u===i&&s===o)return t;if(u>=s)return t.clear();for(var a=t._level,h=t._root,f=0;0>u+f;)h=new Ct(h&&h.array.length?[void 0,h]:[],n),a+=pr,f+=1<<a;f&&(u+=f,i+=f,s+=f,o+=f);for(var c=Gt(o),p=Gt(s);p>=1<<a+pr;)h=new Ct(h&&h.array.length?[h]:[],n),
|
||||
a+=pr;var v=t._tail,l=c>p?Qt(t,s-1):p>c?new Ct([],n):v;if(v&&p>c&&o>u&&v.array.length){h=Yt(h,n);for(var y=h,d=a;d>pr;d-=pr){var m=c>>>d&lr;y=y.array[m]=Yt(y.array[m],n)}y.array[c>>>pr&lr]=v}if(o>s&&(l=l&&l.removeAfter(n,0,s)),u>=p)u-=p,s-=p,a=pr,h=null,l=l&&l.removeBefore(n,0,u);else if(u>i||c>p){for(f=0;h;){var g=u>>>a&lr;if(g!==p>>>a&lr)break;g&&(f+=(1<<a)*g),a-=pr,h=h.array[g]}h&&u>i&&(h=h.removeBefore(n,a,u-f)),h&&c>p&&(h=h.removeAfter(n,a,p-f)),f&&(u-=f,s-=f)}return t.__ownerID?(t.size=s-u,t._origin=u,t._capacity=s,t._level=a,t._root=h,t._tail=l,t.__hash=void 0,t.__altered=!0,t):Nt(u,s,a,h,l)}function Ft(t,e,r){for(var i=[],u=0,s=0;r.length>s;s++){var a=r[s],h=n(a);h.size>u&&(u=h.size),o(a)||(h=h.map(function(t){return H(t)})),i.push(h)}return u>t.size&&(t=t.setSize(u)),jt(t,e,i)}function Gt(t){return vr>t?0:t-1>>>pr<<pr}function Zt(t){return null===t||void 0===t?ee():$t(t)?t:ee().withMutations(function(e){var n=r(t);ft(n.size),n.forEach(function(t,r){return e.set(r,t)})})}function $t(t){return _t(t)&&h(t)}function te(t,e,r,n){var i=Object.create(Zt.prototype);return i.size=t?t.size:0,i._map=t,i._list=e,i.__ownerID=r,i.__hash=n,i}function ee(){return Fr||(Fr=te(zt(),Pt()))}function re(t,e,r){var n,i,o=t._map,u=t._list,s=o.get(e),a=void 0!==s;if(r===yr){if(!a)return t;u.size>=vr&&u.size>=2*o.size?(i=u.filter(function(t,e){return void 0!==t&&s!==e}),n=i.toKeyedSeq().map(function(t){return t[0]}).flip().toMap(),t.__ownerID&&(n.__ownerID=i.__ownerID=t.__ownerID)):(n=o.remove(e),i=s===u.size-1?u.pop():u.set(s,void 0))}else if(a){if(r===u.get(s)[1])return t;n=o,i=u.set(s,[e,r])}else n=o.set(e,u.size),i=u.set(u.size,[e,r]);return t.__ownerID?(t.size=n.size,t._map=n,t._list=i,t.__hash=void 0,t):te(n,i)}function ne(t,e){this._iter=t,this._useKeys=e,this.size=t.size}function ie(t){this._iter=t,this.size=t.size}function oe(t){this._iter=t,this.size=t.size}function ue(t){this._iter=t,this.size=t.size}function se(t){var e=Ee(t);return e._iter=t,e.size=t.size,e.flip=function(){return t},e.reverse=function(){var e=t.reverse.apply(this);
|
||||
return e.flip=function(){return t.reverse()},e},e.has=function(e){return t.includes(e)},e.includes=function(e){return t.has(e)},e.cacheResult=Oe,e.__iterateUncached=function(e,r){var n=this;return t.__iterate(function(t,r){return e(r,t,n)!==!1},r)},e.__iteratorUncached=function(e,r){if(e===Sr){var n=t.__iterator(e,r);return new S(function(){var t=n.next();if(!t.done){var e=t.value[0];t.value[0]=t.value[1],t.value[1]=e}return t})}return t.__iterator(e===wr?gr:wr,r)},e}function ae(t,e,r){var n=Ee(t);return n.size=t.size,n.has=function(e){return t.has(e)},n.get=function(n,i){var o=t.get(n,yr);return o===yr?i:e.call(r,o,n,t)},n.__iterateUncached=function(n,i){var o=this;return t.__iterate(function(t,i,u){return n(e.call(r,t,i,u),i,o)!==!1},i)},n.__iteratorUncached=function(n,i){var o=t.__iterator(Sr,i);return new S(function(){var i=o.next();if(i.done)return i;var u=i.value,s=u[0];return z(n,s,e.call(r,u[1],s,t),i)})},n}function he(t,e){var r=Ee(t);return r._iter=t,r.size=t.size,r.reverse=function(){return t},t.flip&&(r.flip=function(){var e=se(t);return e.reverse=function(){return t.flip()},e}),r.get=function(r,n){return t.get(e?r:-1-r,n)},r.has=function(r){return t.has(e?r:-1-r)},r.includes=function(e){return t.includes(e)},r.cacheResult=Oe,r.__iterate=function(e,r){var n=this;return t.__iterate(function(t,r){return e(t,r,n)},!r)},r.__iterator=function(e,r){return t.__iterator(e,!r)},r}function fe(t,e,r,n){var i=Ee(t);return n&&(i.has=function(n){var i=t.get(n,yr);return i!==yr&&!!e.call(r,i,n,t)},i.get=function(n,i){var o=t.get(n,yr);return o!==yr&&e.call(r,o,n,t)?o:i}),i.__iterateUncached=function(i,o){var u=this,s=0;return t.__iterate(function(t,o,a){return e.call(r,t,o,a)?(s++,i(t,n?o:s-1,u)):void 0},o),s},i.__iteratorUncached=function(i,o){var u=t.__iterator(Sr,o),s=0;return new S(function(){for(;;){var o=u.next();if(o.done)return o;var a=o.value,h=a[0],f=a[1];if(e.call(r,f,h,t))return z(i,n?h:s++,f,o)}})},i}function ce(t,e,r){var n=ct().asMutable();return t.__iterate(function(i,o){n.update(e.call(r,i,o,t),0,function(t){
|
||||
return t+1})}),n.asImmutable()}function _e(t,e,r){var n=u(t),i=(h(t)?Zt():ct()).asMutable();t.__iterate(function(o,u){i.update(e.call(r,o,u,t),function(t){return t=t||[],t.push(n?[u,o]:o),t})});var o=Me(t);return i.map(function(e){return be(t,o(e))})}function pe(t,e,r,n){var i=t.size;if(void 0!==e&&(e=0|e),void 0!==r&&(r=r===1/0?i:0|r),d(e,r,i))return t;var o=m(e,i),u=g(r,i);if(o!==o||u!==u)return pe(t.toSeq().cacheResult(),e,r,n);var s,a=u-o;a===a&&(s=0>a?0:a);var h=Ee(t);return h.size=0===s?s:t.size&&s||void 0,!n&&L(t)&&s>=0&&(h.get=function(e,r){return e=l(this,e),e>=0&&s>e?t.get(e+o,r):r}),h.__iterateUncached=function(e,r){var i=this;if(0===s)return 0;if(r)return this.cacheResult().__iterate(e,r);var u=0,a=!0,h=0;return t.__iterate(function(t,r){return a&&(a=u++<o)?void 0:(h++,e(t,n?r:h-1,i)!==!1&&h!==s)}),h},h.__iteratorUncached=function(e,r){if(0!==s&&r)return this.cacheResult().__iterator(e,r);var i=0!==s&&t.__iterator(e,r),u=0,a=0;return new S(function(){for(;u++<o;)i.next();if(++a>s)return I();var t=i.next();return n||e===wr?t:e===gr?z(e,a-1,void 0,t):z(e,a-1,t.value[1],t)})},h}function ve(t,e,r){var n=Ee(t);return n.__iterateUncached=function(n,i){var o=this;if(i)return this.cacheResult().__iterate(n,i);var u=0;return t.__iterate(function(t,i,s){return e.call(r,t,i,s)&&++u&&n(t,i,o)}),u},n.__iteratorUncached=function(n,i){var o=this;if(i)return this.cacheResult().__iterator(n,i);var u=t.__iterator(Sr,i),s=!0;return new S(function(){if(!s)return I();var t=u.next();if(t.done)return t;var i=t.value,a=i[0],h=i[1];return e.call(r,h,a,o)?n===Sr?t:z(n,a,h,t):(s=!1,I())})},n}function le(t,e,r,n){var i=Ee(t);return i.__iterateUncached=function(i,o){var u=this;if(o)return this.cacheResult().__iterate(i,o);var s=!0,a=0;return t.__iterate(function(t,o,h){return s&&(s=e.call(r,t,o,h))?void 0:(a++,i(t,n?o:a-1,u))}),a},i.__iteratorUncached=function(i,o){var u=this;if(o)return this.cacheResult().__iterator(i,o);var s=t.__iterator(Sr,o),a=!0,h=0;return new S(function(){var t,o,f;do{if(t=s.next(),t.done)return n||i===wr?t:i===gr?z(i,h++,void 0,t):z(i,h++,t.value[1],t);
|
||||
var c=t.value;o=c[0],f=c[1],a&&(a=e.call(r,f,o,u))}while(a);return i===Sr?t:z(i,o,f,t)})},i}function ye(t,e){var n=u(t),i=[t].concat(e).map(function(t){return o(t)?n&&(t=r(t)):t=n?B(t):W(Array.isArray(t)?t:[t]),t}).filter(function(t){return 0!==t.size});if(0===i.length)return t;if(1===i.length){var a=i[0];if(a===t||n&&u(a)||s(t)&&s(a))return a}var h=new j(i);return n?h=h.toKeyedSeq():s(t)||(h=h.toSetSeq()),h=h.flatten(!0),h.size=i.reduce(function(t,e){if(void 0!==t){var r=e.size;if(void 0!==r)return t+r}},0),h}function de(t,e,r){var n=Ee(t);return n.__iterateUncached=function(n,i){function u(t,h){var f=this;t.__iterate(function(t,i){return(!e||e>h)&&o(t)?u(t,h+1):n(t,r?i:s++,f)===!1&&(a=!0),!a},i)}var s=0,a=!1;return u(t,0),s},n.__iteratorUncached=function(n,i){var u=t.__iterator(n,i),s=[],a=0;return new S(function(){for(;u;){var t=u.next();if(t.done===!1){var h=t.value;if(n===Sr&&(h=h[1]),e&&!(e>s.length)||!o(h))return r?t:z(n,a++,h,t);s.push(u),u=h.__iterator(n,i)}else u=s.pop()}return I()})},n}function me(t,e,r){var n=Me(t);return t.toSeq().map(function(i,o){return n(e.call(r,i,o,t))}).flatten(!0)}function ge(t,e){var r=Ee(t);return r.size=t.size&&2*t.size-1,r.__iterateUncached=function(r,n){var i=this,o=0;return t.__iterate(function(t,n){return(!o||r(e,o++,i)!==!1)&&r(t,o++,i)!==!1},n),o},r.__iteratorUncached=function(r,n){var i,o=t.__iterator(wr,n),u=0;return new S(function(){return(!i||u%2)&&(i=o.next(),i.done)?i:u%2?z(r,u++,e):z(r,u++,i.value,i)})},r}function we(t,e,r){e||(e=xe);var n=u(t),i=0,o=t.toSeq().map(function(e,n){return[n,e,i++,r?r(e,n,t):e]}).toArray();return o.sort(function(t,r){return e(t[3],r[3])||t[2]-r[2]}).forEach(n?function(t,e){o[e].length=2}:function(t,e){o[e]=t[1]}),n?x(o):s(t)?k(o):A(o)}function Se(t,e,r){if(e||(e=xe),r){var n=t.toSeq().map(function(e,n){return[e,r(e,n,t)]}).reduce(function(t,r){return ze(e,t[1],r[1])?r:t});return n&&n[0]}return t.reduce(function(t,r){return ze(e,t,r)?r:t})}function ze(t,e,r){var n=t(r,e);return 0===n&&r!==e&&(void 0===r||null===r||r!==r)||n>0}function Ie(t,r,n){
|
||||
var i=Ee(t);return i.size=new j(n).map(function(t){return t.size}).min(),i.__iterate=function(t,e){for(var r,n=this.__iterator(wr,e),i=0;!(r=n.next()).done&&t(r.value,i++,this)!==!1;);return i},i.__iteratorUncached=function(t,i){var o=n.map(function(t){return t=e(t),D(i?t.reverse():t)}),u=0,s=!1;return new S(function(){var e;return s||(e=o.map(function(t){return t.next()}),s=e.some(function(t){return t.done})),s?I():z(t,u++,r.apply(null,e.map(function(t){return t.value})))})},i}function be(t,e){return L(t)?e:t.constructor(e)}function qe(t){if(t!==Object(t))throw new TypeError("Expected [K, V] tuple: "+t)}function De(t){return ft(t.size),v(t)}function Me(t){return u(t)?r:s(t)?n:i}function Ee(t){return Object.create((u(t)?x:s(t)?k:A).prototype)}function Oe(){return this._iter.cacheResult?(this._iter.cacheResult(),this.size=this._iter.size,this):O.prototype.cacheResult.call(this)}function xe(t,e){return t>e?1:e>t?-1:0}function ke(t){var r=D(t);if(!r){if(!E(t))throw new TypeError("Expected iterable or array-like: "+t);r=D(e(t))}return r}function Ae(t,e){var r,n=function(o){if(o instanceof n)return o;if(!(this instanceof n))return new n(o);if(!r){r=!0;var u=Object.keys(t);Ue(i,u),i.size=u.length,i._name=e,i._keys=u,i._defaultValues=t}this._map=ct(o)},i=n.prototype=Object.create(Gr);return i.constructor=n,n}function je(t,e,r){var n=Object.create(Object.getPrototypeOf(t));return n._map=e,n.__ownerID=r,n}function Re(t){return t._name||t.constructor.name||"Record"}function Ue(t,e){try{e.forEach(Ke.bind(void 0,t))}catch(r){}}function Ke(t,e){Object.defineProperty(t,e,{get:function(){return this.get(e)},set:function(t){Z(this.__ownerID,"Cannot set on an immutable record."),this.set(e,t)}})}function Le(t){return null===t||void 0===t?Ce():Te(t)&&!h(t)?t:Ce().withMutations(function(e){var r=i(t);ft(r.size),r.forEach(function(t){return e.add(t)})})}function Te(t){return!(!t||!t[Zr])}function Be(t,e){return t.__ownerID?(t.size=e.size,t._map=e,t):e===t._map?t:0===e.size?t.__empty():t.__make(e)}function We(t,e){var r=Object.create($r);
|
||||
return r.size=t?t.size:0,r._map=t,r.__ownerID=e,r}function Ce(){return tn||(tn=We(zt()))}function Je(t){return null===t||void 0===t?He():Ne(t)?t:He().withMutations(function(e){var r=i(t);ft(r.size),r.forEach(function(t){return e.add(t)})})}function Ne(t){return Te(t)&&h(t)}function Pe(t,e){var r=Object.create(en);return r.size=t?t.size:0,r._map=t,r.__ownerID=e,r}function He(){return rn||(rn=Pe(ee()))}function Ve(t){return null===t||void 0===t?Xe():Ye(t)?t:Xe().unshiftAll(t)}function Ye(t){return!(!t||!t[nn])}function Qe(t,e,r,n){var i=Object.create(on);return i.size=t,i._head=e,i.__ownerID=r,i.__hash=n,i.__altered=!1,i}function Xe(){return un||(un=Qe(0))}function Fe(t,e){var r=function(r){t.prototype[r]=e[r]};return Object.keys(e).forEach(r),Object.getOwnPropertySymbols&&Object.getOwnPropertySymbols(e).forEach(r),t}function Ge(t,e){return e}function Ze(t,e){return[e,t]}function $e(t){return function(){return!t.apply(this,arguments)}}function tr(t){return function(){return-t.apply(this,arguments)}}function er(t){return"string"==typeof t?JSON.stringify(t):t+""}function rr(){return p(arguments)}function nr(t,e){return e>t?1:t>e?-1:0}function ir(t){if(t.size===1/0)return 0;var e=h(t),r=u(t),n=e?1:0,i=t.__iterate(r?e?function(t,e){n=31*n+ur(ot(t),ot(e))|0}:function(t,e){n=n+ur(ot(t),ot(e))|0}:e?function(t){n=31*n+ot(t)|0}:function(t){n=n+ot(t)|0});return or(i,n)}function or(t,e){return e=xr(e,3432918353),e=xr(e<<15|e>>>-15,461845907),e=xr(e<<13|e>>>-13,5),e=(e+3864292196|0)^t,e=xr(e^e>>>16,2246822507),e=xr(e^e>>>13,3266489909),e=it(e^e>>>16)}function ur(t,e){return t^e+2654435769+(t<<6)+(t>>2)|0}var sr=Array.prototype.slice;t(r,e),t(n,e),t(i,e),e.isIterable=o,e.isKeyed=u,e.isIndexed=s,e.isAssociative=a,e.isOrdered=h,e.Keyed=r,e.Indexed=n,e.Set=i;var ar="@@__IMMUTABLE_ITERABLE__@@",hr="@@__IMMUTABLE_KEYED__@@",fr="@@__IMMUTABLE_INDEXED__@@",cr="@@__IMMUTABLE_ORDERED__@@",_r="delete",pr=5,vr=1<<pr,lr=vr-1,yr={},dr={value:!1},mr={value:!1},gr=0,wr=1,Sr=2,zr="function"==typeof Symbol&&Symbol.iterator,Ir="@@iterator",br=zr||Ir;
|
||||
S.prototype.toString=function(){return"[Iterator]"},S.KEYS=gr,S.VALUES=wr,S.ENTRIES=Sr,S.prototype.inspect=S.prototype.toSource=function(){return""+this},S.prototype[br]=function(){return this},t(O,e),O.of=function(){return O(arguments)},O.prototype.toSeq=function(){return this},O.prototype.toString=function(){return this.__toString("Seq {","}")},O.prototype.cacheResult=function(){return!this._cache&&this.__iterateUncached&&(this._cache=this.entrySeq().toArray(),this.size=this._cache.length),this},O.prototype.__iterate=function(t,e){return N(this,t,e,!0)},O.prototype.__iterator=function(t,e){return P(this,t,e,!0)},t(x,O),x.prototype.toKeyedSeq=function(){return this},t(k,O),k.of=function(){return k(arguments)},k.prototype.toIndexedSeq=function(){return this},k.prototype.toString=function(){return this.__toString("Seq [","]")},k.prototype.__iterate=function(t,e){return N(this,t,e,!1)},k.prototype.__iterator=function(t,e){return P(this,t,e,!1)},t(A,O),A.of=function(){return A(arguments)},A.prototype.toSetSeq=function(){return this},O.isSeq=L,O.Keyed=x,O.Set=A,O.Indexed=k;var qr="@@__IMMUTABLE_SEQ__@@";O.prototype[qr]=!0,t(j,k),j.prototype.get=function(t,e){return this.has(t)?this._array[l(this,t)]:e},j.prototype.__iterate=function(t,e){for(var r=this._array,n=r.length-1,i=0;n>=i;i++)if(t(r[e?n-i:i],i,this)===!1)return i+1;return i},j.prototype.__iterator=function(t,e){var r=this._array,n=r.length-1,i=0;return new S(function(){return i>n?I():z(t,i,r[e?n-i++:i++])})},t(R,x),R.prototype.get=function(t,e){return void 0===e||this.has(t)?this._object[t]:e},R.prototype.has=function(t){return this._object.hasOwnProperty(t)},R.prototype.__iterate=function(t,e){for(var r=this._object,n=this._keys,i=n.length-1,o=0;i>=o;o++){var u=n[e?i-o:o];if(t(r[u],u,this)===!1)return o+1}return o},R.prototype.__iterator=function(t,e){var r=this._object,n=this._keys,i=n.length-1,o=0;return new S(function(){var u=n[e?i-o:o];return o++>i?I():z(t,u,r[u])})},R.prototype[cr]=!0,t(U,k),U.prototype.__iterateUncached=function(t,e){if(e)return this.cacheResult().__iterate(t,e);
|
||||
var r=this._iterable,n=D(r),i=0;if(q(n))for(var o;!(o=n.next()).done&&t(o.value,i++,this)!==!1;);return i},U.prototype.__iteratorUncached=function(t,e){if(e)return this.cacheResult().__iterator(t,e);var r=this._iterable,n=D(r);if(!q(n))return new S(I);var i=0;return new S(function(){var e=n.next();return e.done?e:z(t,i++,e.value)})},t(K,k),K.prototype.__iterateUncached=function(t,e){if(e)return this.cacheResult().__iterate(t,e);for(var r=this._iterator,n=this._iteratorCache,i=0;n.length>i;)if(t(n[i],i++,this)===!1)return i;for(var o;!(o=r.next()).done;){var u=o.value;if(n[i]=u,t(u,i++,this)===!1)break}return i},K.prototype.__iteratorUncached=function(t,e){if(e)return this.cacheResult().__iterator(t,e);var r=this._iterator,n=this._iteratorCache,i=0;return new S(function(){if(i>=n.length){var e=r.next();if(e.done)return e;n[i]=e.value}return z(t,i,n[i++])})};var Dr;t(G,k),G.prototype.toString=function(){return 0===this.size?"Repeat []":"Repeat [ "+this._value+" "+this.size+" times ]"},G.prototype.get=function(t,e){return this.has(t)?this._value:e},G.prototype.includes=function(t){return X(this._value,t)},G.prototype.slice=function(t,e){var r=this.size;return d(t,e,r)?this:new G(this._value,g(e,r)-m(t,r))},G.prototype.reverse=function(){return this},G.prototype.indexOf=function(t){return X(this._value,t)?0:-1},G.prototype.lastIndexOf=function(t){return X(this._value,t)?this.size:-1},G.prototype.__iterate=function(t,e){for(var r=0;this.size>r;r++)if(t(this._value,r,this)===!1)return r+1;return r},G.prototype.__iterator=function(t,e){var r=this,n=0;return new S(function(){return r.size>n?z(t,n++,r._value):I()})},G.prototype.equals=function(t){return t instanceof G?X(this._value,t._value):F(t)};var Mr;t($,k),$.prototype.toString=function(){return 0===this.size?"Range []":"Range [ "+this._start+"..."+this._end+(1!==this._step?" by "+this._step:"")+" ]"},$.prototype.get=function(t,e){return this.has(t)?this._start+l(this,t)*this._step:e},$.prototype.includes=function(t){var e=(t-this._start)/this._step;return e>=0&&this.size>e&&e===Math.floor(e);
|
||||
},$.prototype.slice=function(t,e){return d(t,e,this.size)?this:(t=m(t,this.size),e=g(e,this.size),t>=e?new $(0,0):new $(this.get(t,this._end),this.get(e,this._end),this._step))},$.prototype.indexOf=function(t){var e=t-this._start;if(e%this._step===0){var r=e/this._step;if(r>=0&&this.size>r)return r}return-1},$.prototype.lastIndexOf=function(t){return this.indexOf(t)},$.prototype.__iterate=function(t,e){for(var r=this.size-1,n=this._step,i=e?this._start+r*n:this._start,o=0;r>=o;o++){if(t(i,o,this)===!1)return o+1;i+=e?-n:n}return o},$.prototype.__iterator=function(t,e){var r=this.size-1,n=this._step,i=e?this._start+r*n:this._start,o=0;return new S(function(){var u=i;return i+=e?-n:n,o>r?I():z(t,o++,u)})},$.prototype.equals=function(t){return t instanceof $?this._start===t._start&&this._end===t._end&&this._step===t._step:F(this,t)};var Er;t(tt,e),t(et,tt),t(rt,tt),t(nt,tt),tt.Keyed=et,tt.Indexed=rt,tt.Set=nt;var Or,xr="function"==typeof Math.imul&&-2===Math.imul(4294967295,2)?Math.imul:function(t,e){t=0|t,e=0|e;var r=65535&t,n=65535&e;return r*n+((t>>>16)*n+r*(e>>>16)<<16>>>0)|0},kr=Object.isExtensible,Ar=function(){try{return Object.defineProperty({},"@",{}),!0}catch(t){return!1}}(),jr="function"==typeof WeakMap;jr&&(Or=new WeakMap);var Rr=0,Ur="__immutablehash__";"function"==typeof Symbol&&(Ur=Symbol(Ur));var Kr=16,Lr=255,Tr=0,Br={};t(ct,et),ct.of=function(){var t=sr.call(arguments,0);return zt().withMutations(function(e){for(var r=0;t.length>r;r+=2){if(r+1>=t.length)throw Error("Missing value for key: "+t[r]);e.set(t[r],t[r+1])}})},ct.prototype.toString=function(){return this.__toString("Map {","}")},ct.prototype.get=function(t,e){return this._root?this._root.get(0,void 0,t,e):e},ct.prototype.set=function(t,e){return It(this,t,e)},ct.prototype.setIn=function(t,e){return this.updateIn(t,yr,function(){return e})},ct.prototype.remove=function(t){return It(this,t,yr)},ct.prototype.deleteIn=function(t){return this.updateIn(t,function(){return yr})},ct.prototype.update=function(t,e,r){return 1===arguments.length?t(this):this.updateIn([t],e,r);
|
||||
},ct.prototype.updateIn=function(t,e,r){r||(r=e,e=void 0);var n=Rt(this,ke(t),e,r);return n===yr?void 0:n},ct.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._root=null,this.__hash=void 0,this.__altered=!0,this):zt()},ct.prototype.merge=function(){return xt(this,void 0,arguments)},ct.prototype.mergeWith=function(t){var e=sr.call(arguments,1);return xt(this,t,e)},ct.prototype.mergeIn=function(t){var e=sr.call(arguments,1);return this.updateIn(t,zt(),function(t){return"function"==typeof t.merge?t.merge.apply(t,e):e[e.length-1]})},ct.prototype.mergeDeep=function(){return xt(this,kt,arguments)},ct.prototype.mergeDeepWith=function(t){var e=sr.call(arguments,1);return xt(this,At(t),e)},ct.prototype.mergeDeepIn=function(t){var e=sr.call(arguments,1);return this.updateIn(t,zt(),function(t){return"function"==typeof t.mergeDeep?t.mergeDeep.apply(t,e):e[e.length-1]})},ct.prototype.sort=function(t){return Zt(we(this,t))},ct.prototype.sortBy=function(t,e){return Zt(we(this,e,t))},ct.prototype.withMutations=function(t){var e=this.asMutable();return t(e),e.wasAltered()?e.__ensureOwner(this.__ownerID):this},ct.prototype.asMutable=function(){return this.__ownerID?this:this.__ensureOwner(new _)},ct.prototype.asImmutable=function(){return this.__ensureOwner()},ct.prototype.wasAltered=function(){return this.__altered},ct.prototype.__iterator=function(t,e){return new mt(this,t,e)},ct.prototype.__iterate=function(t,e){var r=this,n=0;return this._root&&this._root.iterate(function(e){return n++,t(e[1],e[0],r)},e),n},ct.prototype.__ensureOwner=function(t){return t===this.__ownerID?this:t?St(this.size,this._root,t,this.__hash):(this.__ownerID=t,this.__altered=!1,this)},ct.isMap=_t;var Wr="@@__IMMUTABLE_MAP__@@",Cr=ct.prototype;Cr[Wr]=!0,Cr[_r]=Cr.remove,Cr.removeIn=Cr.deleteIn,pt.prototype.get=function(t,e,r,n){for(var i=this.entries,o=0,u=i.length;u>o;o++)if(X(r,i[o][0]))return i[o][1];return n},pt.prototype.update=function(t,e,r,n,i,o,u){for(var s=i===yr,a=this.entries,h=0,f=a.length;f>h&&!X(n,a[h][0]);h++);
|
||||
var _=f>h;if(_?a[h][1]===i:s)return this;if(c(u),(s||!_)&&c(o),!s||1!==a.length){if(!_&&!s&&a.length>=Nr)return Mt(t,a,n,i);var v=t&&t===this.ownerID,l=v?a:p(a);return _?s?h===f-1?l.pop():l[h]=l.pop():l[h]=[n,i]:l.push([n,i]),v?(this.entries=l,this):new pt(t,l)}},vt.prototype.get=function(t,e,r,n){void 0===e&&(e=ot(r));var i=1<<((0===t?e:e>>>t)&lr),o=this.bitmap;return 0===(o&i)?n:this.nodes[Ut(o&i-1)].get(t+pr,e,r,n)},vt.prototype.update=function(t,e,r,n,i,o,u){void 0===r&&(r=ot(n));var s=(0===e?r:r>>>e)&lr,a=1<<s,h=this.bitmap,f=0!==(h&a);if(!f&&i===yr)return this;var c=Ut(h&a-1),_=this.nodes,p=f?_[c]:void 0,v=bt(p,t,e+pr,r,n,i,o,u);if(v===p)return this;if(!f&&v&&_.length>=Pr)return Ot(t,_,h,s,v);if(f&&!v&&2===_.length&&qt(_[1^c]))return _[1^c];if(f&&v&&1===_.length&&qt(v))return v;var l=t&&t===this.ownerID,y=f?v?h:h^a:h|a,d=f?v?Kt(_,c,v,l):Tt(_,c,l):Lt(_,c,v,l);return l?(this.bitmap=y,this.nodes=d,this):new vt(t,y,d)},lt.prototype.get=function(t,e,r,n){void 0===e&&(e=ot(r));var i=(0===t?e:e>>>t)&lr,o=this.nodes[i];return o?o.get(t+pr,e,r,n):n},lt.prototype.update=function(t,e,r,n,i,o,u){void 0===r&&(r=ot(n));var s=(0===e?r:r>>>e)&lr,a=i===yr,h=this.nodes,f=h[s];if(a&&!f)return this;var c=bt(f,t,e+pr,r,n,i,o,u);if(c===f)return this;var _=this.count;if(f){if(!c&&(_--,Hr>_))return Et(t,h,_,s)}else _++;var p=t&&t===this.ownerID,v=Kt(h,s,c,p);return p?(this.count=_,this.nodes=v,this):new lt(t,_,v)},yt.prototype.get=function(t,e,r,n){for(var i=this.entries,o=0,u=i.length;u>o;o++)if(X(r,i[o][0]))return i[o][1];return n},yt.prototype.update=function(t,e,r,n,i,o,u){void 0===r&&(r=ot(n));var s=i===yr;if(r!==this.keyHash)return s?this:(c(u),c(o),Dt(this,t,e,r,[n,i]));for(var a=this.entries,h=0,f=a.length;f>h&&!X(n,a[h][0]);h++);var _=f>h;if(_?a[h][1]===i:s)return this;if(c(u),(s||!_)&&c(o),s&&2===f)return new dt(t,this.keyHash,a[1^h]);var v=t&&t===this.ownerID,l=v?a:p(a);return _?s?h===f-1?l.pop():l[h]=l.pop():l[h]=[n,i]:l.push([n,i]),v?(this.entries=l,this):new yt(t,this.keyHash,l)},dt.prototype.get=function(t,e,r,n){return X(r,this.entry[0])?this.entry[1]:n;
|
||||
},dt.prototype.update=function(t,e,r,n,i,o,u){var s=i===yr,a=X(n,this.entry[0]);return(a?i===this.entry[1]:s)?this:(c(u),s?void c(o):a?t&&t===this.ownerID?(this.entry[1]=i,this):new dt(t,this.keyHash,[n,i]):(c(o),Dt(this,t,e,ot(n),[n,i])))},pt.prototype.iterate=yt.prototype.iterate=function(t,e){for(var r=this.entries,n=0,i=r.length-1;i>=n;n++)if(t(r[e?i-n:n])===!1)return!1},vt.prototype.iterate=lt.prototype.iterate=function(t,e){for(var r=this.nodes,n=0,i=r.length-1;i>=n;n++){var o=r[e?i-n:n];if(o&&o.iterate(t,e)===!1)return!1}},dt.prototype.iterate=function(t,e){return t(this.entry)},t(mt,S),mt.prototype.next=function(){for(var t=this._type,e=this._stack;e;){var r,n=e.node,i=e.index++;if(n.entry){if(0===i)return gt(t,n.entry)}else if(n.entries){if(r=n.entries.length-1,r>=i)return gt(t,n.entries[this._reverse?r-i:i])}else if(r=n.nodes.length-1,r>=i){var o=n.nodes[this._reverse?r-i:i];if(o){if(o.entry)return gt(t,o.entry);e=this._stack=wt(o,e)}continue}e=this._stack=this._stack.__prev}return I()};var Jr,Nr=vr/4,Pr=vr/2,Hr=vr/4;t(Bt,rt),Bt.of=function(){return this(arguments)},Bt.prototype.toString=function(){return this.__toString("List [","]")},Bt.prototype.get=function(t,e){if(t=l(this,t),t>=0&&this.size>t){t+=this._origin;var r=Qt(this,t);return r&&r.array[t&lr]}return e},Bt.prototype.set=function(t,e){return Ht(this,t,e)},Bt.prototype.remove=function(t){return this.has(t)?0===t?this.shift():t===this.size-1?this.pop():this.splice(t,1):this},Bt.prototype.insert=function(t,e){return this.splice(t,0,e)},Bt.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=this._origin=this._capacity=0,this._level=pr,this._root=this._tail=null,this.__hash=void 0,this.__altered=!0,this):Pt()},Bt.prototype.push=function(){var t=arguments,e=this.size;return this.withMutations(function(r){Xt(r,0,e+t.length);for(var n=0;t.length>n;n++)r.set(e+n,t[n])})},Bt.prototype.pop=function(){return Xt(this,0,-1)},Bt.prototype.unshift=function(){var t=arguments;return this.withMutations(function(e){Xt(e,-t.length);for(var r=0;t.length>r;r++)e.set(r,t[r]);
|
||||
})},Bt.prototype.shift=function(){return Xt(this,1)},Bt.prototype.merge=function(){return Ft(this,void 0,arguments)},Bt.prototype.mergeWith=function(t){var e=sr.call(arguments,1);return Ft(this,t,e)},Bt.prototype.mergeDeep=function(){return Ft(this,kt,arguments)},Bt.prototype.mergeDeepWith=function(t){var e=sr.call(arguments,1);return Ft(this,At(t),e)},Bt.prototype.setSize=function(t){return Xt(this,0,t)},Bt.prototype.slice=function(t,e){var r=this.size;return d(t,e,r)?this:Xt(this,m(t,r),g(e,r))},Bt.prototype.__iterator=function(t,e){var r=0,n=Jt(this,e);return new S(function(){var e=n();return e===Xr?I():z(t,r++,e)})},Bt.prototype.__iterate=function(t,e){for(var r,n=0,i=Jt(this,e);(r=i())!==Xr&&t(r,n++,this)!==!1;);return n},Bt.prototype.__ensureOwner=function(t){return t===this.__ownerID?this:t?Nt(this._origin,this._capacity,this._level,this._root,this._tail,t,this.__hash):(this.__ownerID=t,this)},Bt.isList=Wt;var Vr="@@__IMMUTABLE_LIST__@@",Yr=Bt.prototype;Yr[Vr]=!0,Yr[_r]=Yr.remove,Yr.setIn=Cr.setIn,Yr.deleteIn=Yr.removeIn=Cr.removeIn,Yr.update=Cr.update,Yr.updateIn=Cr.updateIn,Yr.mergeIn=Cr.mergeIn,Yr.mergeDeepIn=Cr.mergeDeepIn,Yr.withMutations=Cr.withMutations,Yr.asMutable=Cr.asMutable,Yr.asImmutable=Cr.asImmutable,Yr.wasAltered=Cr.wasAltered,Ct.prototype.removeBefore=function(t,e,r){if(r===e?1<<e:0===this.array.length)return this;var n=r>>>e&lr;if(n>=this.array.length)return new Ct([],t);var i,o=0===n;if(e>0){var u=this.array[n];if(i=u&&u.removeBefore(t,e-pr,r),i===u&&o)return this}if(o&&!i)return this;var s=Yt(this,t);if(!o)for(var a=0;n>a;a++)s.array[a]=void 0;return i&&(s.array[n]=i),s},Ct.prototype.removeAfter=function(t,e,r){if(r===(e?1<<e:0)||0===this.array.length)return this;var n=r-1>>>e&lr;if(n>=this.array.length)return this;var i;if(e>0){var o=this.array[n];if(i=o&&o.removeAfter(t,e-pr,r),i===o&&n===this.array.length-1)return this}var u=Yt(this,t);return u.array.splice(n+1),i&&(u.array[n]=i),u};var Qr,Xr={};t(Zt,ct),Zt.of=function(){return this(arguments)},Zt.prototype.toString=function(){return this.__toString("OrderedMap {","}");
|
||||
},Zt.prototype.get=function(t,e){var r=this._map.get(t);return void 0!==r?this._list.get(r)[1]:e},Zt.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._map.clear(),this._list.clear(),this):ee()},Zt.prototype.set=function(t,e){return re(this,t,e)},Zt.prototype.remove=function(t){return re(this,t,yr)},Zt.prototype.wasAltered=function(){return this._map.wasAltered()||this._list.wasAltered()},Zt.prototype.__iterate=function(t,e){var r=this;return this._list.__iterate(function(e){return e&&t(e[1],e[0],r)},e)},Zt.prototype.__iterator=function(t,e){return this._list.fromEntrySeq().__iterator(t,e)},Zt.prototype.__ensureOwner=function(t){if(t===this.__ownerID)return this;var e=this._map.__ensureOwner(t),r=this._list.__ensureOwner(t);return t?te(e,r,t,this.__hash):(this.__ownerID=t,this._map=e,this._list=r,this)},Zt.isOrderedMap=$t,Zt.prototype[cr]=!0,Zt.prototype[_r]=Zt.prototype.remove;var Fr;t(ne,x),ne.prototype.get=function(t,e){return this._iter.get(t,e)},ne.prototype.has=function(t){return this._iter.has(t)},ne.prototype.valueSeq=function(){return this._iter.valueSeq()},ne.prototype.reverse=function(){var t=this,e=he(this,!0);return this._useKeys||(e.valueSeq=function(){return t._iter.toSeq().reverse()}),e},ne.prototype.map=function(t,e){var r=this,n=ae(this,t,e);return this._useKeys||(n.valueSeq=function(){return r._iter.toSeq().map(t,e)}),n},ne.prototype.__iterate=function(t,e){var r,n=this;return this._iter.__iterate(this._useKeys?function(e,r){return t(e,r,n)}:(r=e?De(this):0,function(i){return t(i,e?--r:r++,n)}),e)},ne.prototype.__iterator=function(t,e){if(this._useKeys)return this._iter.__iterator(t,e);var r=this._iter.__iterator(wr,e),n=e?De(this):0;return new S(function(){var i=r.next();return i.done?i:z(t,e?--n:n++,i.value,i)})},ne.prototype[cr]=!0,t(ie,k),ie.prototype.includes=function(t){return this._iter.includes(t)},ie.prototype.__iterate=function(t,e){var r=this,n=0;return this._iter.__iterate(function(e){return t(e,n++,r)},e)},ie.prototype.__iterator=function(t,e){var r=this._iter.__iterator(wr,e),n=0;
|
||||
return new S(function(){var e=r.next();return e.done?e:z(t,n++,e.value,e)})},t(oe,A),oe.prototype.has=function(t){return this._iter.includes(t)},oe.prototype.__iterate=function(t,e){var r=this;return this._iter.__iterate(function(e){return t(e,e,r)},e)},oe.prototype.__iterator=function(t,e){var r=this._iter.__iterator(wr,e);return new S(function(){var e=r.next();return e.done?e:z(t,e.value,e.value,e)})},t(ue,x),ue.prototype.entrySeq=function(){return this._iter.toSeq()},ue.prototype.__iterate=function(t,e){var r=this;return this._iter.__iterate(function(e){if(e){qe(e);var n=o(e);return t(n?e.get(1):e[1],n?e.get(0):e[0],r)}},e)},ue.prototype.__iterator=function(t,e){var r=this._iter.__iterator(wr,e);return new S(function(){for(;;){var e=r.next();if(e.done)return e;var n=e.value;if(n){qe(n);var i=o(n);return z(t,i?n.get(0):n[0],i?n.get(1):n[1],e)}}})},ie.prototype.cacheResult=ne.prototype.cacheResult=oe.prototype.cacheResult=ue.prototype.cacheResult=Oe,t(Ae,et),Ae.prototype.toString=function(){return this.__toString(Re(this)+" {","}")},Ae.prototype.has=function(t){return this._defaultValues.hasOwnProperty(t)},Ae.prototype.get=function(t,e){if(!this.has(t))return e;var r=this._defaultValues[t];return this._map?this._map.get(t,r):r},Ae.prototype.clear=function(){if(this.__ownerID)return this._map&&this._map.clear(),this;var t=this.constructor;return t._empty||(t._empty=je(this,zt()))},Ae.prototype.set=function(t,e){if(!this.has(t))throw Error('Cannot set unknown key "'+t+'" on '+Re(this));if(this._map&&!this._map.has(t)){var r=this._defaultValues[t];if(e===r)return this}var n=this._map&&this._map.set(t,e);return this.__ownerID||n===this._map?this:je(this,n)},Ae.prototype.remove=function(t){if(!this.has(t))return this;var e=this._map&&this._map.remove(t);return this.__ownerID||e===this._map?this:je(this,e)},Ae.prototype.wasAltered=function(){return this._map.wasAltered()},Ae.prototype.__iterator=function(t,e){var n=this;return r(this._defaultValues).map(function(t,e){return n.get(e)}).__iterator(t,e)},Ae.prototype.__iterate=function(t,e){
|
||||
var n=this;return r(this._defaultValues).map(function(t,e){return n.get(e)}).__iterate(t,e)},Ae.prototype.__ensureOwner=function(t){if(t===this.__ownerID)return this;var e=this._map&&this._map.__ensureOwner(t);return t?je(this,e,t):(this.__ownerID=t,this._map=e,this)};var Gr=Ae.prototype;Gr[_r]=Gr.remove,Gr.deleteIn=Gr.removeIn=Cr.removeIn,Gr.merge=Cr.merge,Gr.mergeWith=Cr.mergeWith,Gr.mergeIn=Cr.mergeIn,Gr.mergeDeep=Cr.mergeDeep,Gr.mergeDeepWith=Cr.mergeDeepWith,Gr.mergeDeepIn=Cr.mergeDeepIn,Gr.setIn=Cr.setIn,Gr.update=Cr.update,Gr.updateIn=Cr.updateIn,Gr.withMutations=Cr.withMutations,Gr.asMutable=Cr.asMutable,Gr.asImmutable=Cr.asImmutable,t(Le,nt),Le.of=function(){return this(arguments)},Le.fromKeys=function(t){return this(r(t).keySeq())},Le.prototype.toString=function(){return this.__toString("Set {","}")},Le.prototype.has=function(t){return this._map.has(t)},Le.prototype.add=function(t){return Be(this,this._map.set(t,!0))},Le.prototype.remove=function(t){return Be(this,this._map.remove(t))},Le.prototype.clear=function(){return Be(this,this._map.clear())},Le.prototype.union=function(){var t=sr.call(arguments,0);return t=t.filter(function(t){return 0!==t.size}),0===t.length?this:0!==this.size||this.__ownerID||1!==t.length?this.withMutations(function(e){for(var r=0;t.length>r;r++)i(t[r]).forEach(function(t){return e.add(t)})}):this.constructor(t[0])},Le.prototype.intersect=function(){var t=sr.call(arguments,0);if(0===t.length)return this;t=t.map(function(t){return i(t)});var e=this;return this.withMutations(function(r){e.forEach(function(e){t.every(function(t){return t.includes(e)})||r.remove(e)})})},Le.prototype.subtract=function(){var t=sr.call(arguments,0);if(0===t.length)return this;t=t.map(function(t){return i(t)});var e=this;return this.withMutations(function(r){e.forEach(function(e){t.some(function(t){return t.includes(e)})&&r.remove(e)})})},Le.prototype.merge=function(){return this.union.apply(this,arguments)},Le.prototype.mergeWith=function(t){var e=sr.call(arguments,1);return this.union.apply(this,e)},
|
||||
Le.prototype.sort=function(t){return Je(we(this,t))},Le.prototype.sortBy=function(t,e){return Je(we(this,e,t))},Le.prototype.wasAltered=function(){return this._map.wasAltered()},Le.prototype.__iterate=function(t,e){var r=this;return this._map.__iterate(function(e,n){return t(n,n,r)},e)},Le.prototype.__iterator=function(t,e){return this._map.map(function(t,e){return e}).__iterator(t,e)},Le.prototype.__ensureOwner=function(t){if(t===this.__ownerID)return this;var e=this._map.__ensureOwner(t);return t?this.__make(e,t):(this.__ownerID=t,this._map=e,this)},Le.isSet=Te;var Zr="@@__IMMUTABLE_SET__@@",$r=Le.prototype;$r[Zr]=!0,$r[_r]=$r.remove,$r.mergeDeep=$r.merge,$r.mergeDeepWith=$r.mergeWith,$r.withMutations=Cr.withMutations,$r.asMutable=Cr.asMutable,$r.asImmutable=Cr.asImmutable,$r.__empty=Ce,$r.__make=We;var tn;t(Je,Le),Je.of=function(){return this(arguments)},Je.fromKeys=function(t){return this(r(t).keySeq())},Je.prototype.toString=function(){return this.__toString("OrderedSet {","}")},Je.isOrderedSet=Ne;var en=Je.prototype;en[cr]=!0,en.__empty=He,en.__make=Pe;var rn;t(Ve,rt),Ve.of=function(){return this(arguments)},Ve.prototype.toString=function(){return this.__toString("Stack [","]")},Ve.prototype.get=function(t,e){var r=this._head;for(t=l(this,t);r&&t--;)r=r.next;return r?r.value:e},Ve.prototype.peek=function(){return this._head&&this._head.value},Ve.prototype.push=function(){if(0===arguments.length)return this;for(var t=this.size+arguments.length,e=this._head,r=arguments.length-1;r>=0;r--)e={value:arguments[r],next:e};return this.__ownerID?(this.size=t,this._head=e,this.__hash=void 0,this.__altered=!0,this):Qe(t,e)},Ve.prototype.pushAll=function(t){if(t=n(t),0===t.size)return this;ft(t.size);var e=this.size,r=this._head;return t.reverse().forEach(function(t){e++,r={value:t,next:r}}),this.__ownerID?(this.size=e,this._head=r,this.__hash=void 0,this.__altered=!0,this):Qe(e,r)},Ve.prototype.pop=function(){return this.slice(1)},Ve.prototype.unshift=function(){return this.push.apply(this,arguments)},Ve.prototype.unshiftAll=function(t){
|
||||
return this.pushAll(t)},Ve.prototype.shift=function(){return this.pop.apply(this,arguments)},Ve.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._head=void 0,this.__hash=void 0,this.__altered=!0,this):Xe()},Ve.prototype.slice=function(t,e){if(d(t,e,this.size))return this;var r=m(t,this.size),n=g(e,this.size);if(n!==this.size)return rt.prototype.slice.call(this,t,e);for(var i=this.size-r,o=this._head;r--;)o=o.next;return this.__ownerID?(this.size=i,this._head=o,this.__hash=void 0,this.__altered=!0,this):Qe(i,o)},Ve.prototype.__ensureOwner=function(t){return t===this.__ownerID?this:t?Qe(this.size,this._head,t,this.__hash):(this.__ownerID=t,this.__altered=!1,this)},Ve.prototype.__iterate=function(t,e){if(e)return this.reverse().__iterate(t);for(var r=0,n=this._head;n&&t(n.value,r++,this)!==!1;)n=n.next;return r},Ve.prototype.__iterator=function(t,e){if(e)return this.reverse().__iterator(t);var r=0,n=this._head;return new S(function(){if(n){var e=n.value;return n=n.next,z(t,r++,e)}return I()})},Ve.isStack=Ye;var nn="@@__IMMUTABLE_STACK__@@",on=Ve.prototype;on[nn]=!0,on.withMutations=Cr.withMutations,on.asMutable=Cr.asMutable,on.asImmutable=Cr.asImmutable,on.wasAltered=Cr.wasAltered;var un;e.Iterator=S,Fe(e,{toArray:function(){ft(this.size);var t=Array(this.size||0);return this.valueSeq().__iterate(function(e,r){t[r]=e}),t},toIndexedSeq:function(){return new ie(this)},toJS:function(){return this.toSeq().map(function(t){return t&&"function"==typeof t.toJS?t.toJS():t}).__toJS()},toJSON:function(){return this.toSeq().map(function(t){return t&&"function"==typeof t.toJSON?t.toJSON():t}).__toJS()},toKeyedSeq:function(){return new ne(this,!0)},toMap:function(){return ct(this.toKeyedSeq())},toObject:function(){ft(this.size);var t={};return this.__iterate(function(e,r){t[r]=e}),t},toOrderedMap:function(){return Zt(this.toKeyedSeq())},toOrderedSet:function(){return Je(u(this)?this.valueSeq():this)},toSet:function(){return Le(u(this)?this.valueSeq():this)},toSetSeq:function(){return new oe(this);
|
||||
},toSeq:function(){return s(this)?this.toIndexedSeq():u(this)?this.toKeyedSeq():this.toSetSeq()},toStack:function(){return Ve(u(this)?this.valueSeq():this)},toList:function(){return Bt(u(this)?this.valueSeq():this)},toString:function(){return"[Iterable]"},__toString:function(t,e){return 0===this.size?t+e:t+" "+this.toSeq().map(this.__toStringMapper).join(", ")+" "+e},concat:function(){var t=sr.call(arguments,0);return be(this,ye(this,t))},includes:function(t){return this.some(function(e){return X(e,t)})},entries:function(){return this.__iterator(Sr)},every:function(t,e){ft(this.size);var r=!0;return this.__iterate(function(n,i,o){return t.call(e,n,i,o)?void 0:(r=!1,!1)}),r},filter:function(t,e){return be(this,fe(this,t,e,!0))},find:function(t,e,r){var n=this.findEntry(t,e);return n?n[1]:r},forEach:function(t,e){return ft(this.size),this.__iterate(e?t.bind(e):t)},join:function(t){ft(this.size),t=void 0!==t?""+t:",";var e="",r=!0;return this.__iterate(function(n){r?r=!1:e+=t,e+=null!==n&&void 0!==n?""+n:""}),e},keys:function(){return this.__iterator(gr)},map:function(t,e){return be(this,ae(this,t,e))},reduce:function(t,e,r){ft(this.size);var n,i;return arguments.length<2?i=!0:n=e,this.__iterate(function(e,o,u){i?(i=!1,n=e):n=t.call(r,n,e,o,u)}),n},reduceRight:function(t,e,r){var n=this.toKeyedSeq().reverse();return n.reduce.apply(n,arguments)},reverse:function(){return be(this,he(this,!0))},slice:function(t,e){return be(this,pe(this,t,e,!0))},some:function(t,e){return!this.every($e(t),e)},sort:function(t){return be(this,we(this,t))},values:function(){return this.__iterator(wr)},butLast:function(){return this.slice(0,-1)},isEmpty:function(){return void 0!==this.size?0===this.size:!this.some(function(){return!0})},count:function(t,e){return v(t?this.toSeq().filter(t,e):this)},countBy:function(t,e){return ce(this,t,e)},equals:function(t){return F(this,t)},entrySeq:function(){var t=this;if(t._cache)return new j(t._cache);var e=t.toSeq().map(Ze).toIndexedSeq();return e.fromEntrySeq=function(){return t.toSeq()},e},filterNot:function(t,e){
|
||||
return this.filter($e(t),e)},findEntry:function(t,e,r){var n=r;return this.__iterate(function(r,i,o){return t.call(e,r,i,o)?(n=[i,r],!1):void 0}),n},findKey:function(t,e){var r=this.findEntry(t,e);return r&&r[0]},findLast:function(t,e,r){return this.toKeyedSeq().reverse().find(t,e,r)},findLastEntry:function(t,e,r){return this.toKeyedSeq().reverse().findEntry(t,e,r)},findLastKey:function(t,e){return this.toKeyedSeq().reverse().findKey(t,e)},first:function(){return this.find(y)},flatMap:function(t,e){return be(this,me(this,t,e))},flatten:function(t){return be(this,de(this,t,!0))},fromEntrySeq:function(){return new ue(this)},get:function(t,e){return this.find(function(e,r){return X(r,t)},void 0,e)},getIn:function(t,e){for(var r,n=this,i=ke(t);!(r=i.next()).done;){var o=r.value;if(n=n&&n.get?n.get(o,yr):yr,n===yr)return e}return n},groupBy:function(t,e){return _e(this,t,e)},has:function(t){return this.get(t,yr)!==yr},hasIn:function(t){return this.getIn(t,yr)!==yr},isSubset:function(t){return t="function"==typeof t.includes?t:e(t),this.every(function(e){return t.includes(e)})},isSuperset:function(t){return t="function"==typeof t.isSubset?t:e(t),t.isSubset(this)},keyOf:function(t){return this.findKey(function(e){return X(e,t)})},keySeq:function(){return this.toSeq().map(Ge).toIndexedSeq()},last:function(){return this.toSeq().reverse().first()},lastKeyOf:function(t){return this.toKeyedSeq().reverse().keyOf(t)},max:function(t){return Se(this,t)},maxBy:function(t,e){return Se(this,e,t)},min:function(t){return Se(this,t?tr(t):nr)},minBy:function(t,e){return Se(this,e?tr(e):nr,t)},rest:function(){return this.slice(1)},skip:function(t){return this.slice(Math.max(0,t))},skipLast:function(t){return be(this,this.toSeq().reverse().skip(t).reverse())},skipWhile:function(t,e){return be(this,le(this,t,e,!0))},skipUntil:function(t,e){return this.skipWhile($e(t),e)},sortBy:function(t,e){return be(this,we(this,e,t))},take:function(t){return this.slice(0,Math.max(0,t))},takeLast:function(t){return be(this,this.toSeq().reverse().take(t).reverse());
|
||||
},takeWhile:function(t,e){return be(this,ve(this,t,e))},takeUntil:function(t,e){return this.takeWhile($e(t),e)},valueSeq:function(){return this.toIndexedSeq()},hashCode:function(){return this.__hash||(this.__hash=ir(this))}});var sn=e.prototype;sn[ar]=!0,sn[br]=sn.values,sn.__toJS=sn.toArray,sn.__toStringMapper=er,sn.inspect=sn.toSource=function(){return""+this},sn.chain=sn.flatMap,sn.contains=sn.includes,Fe(r,{flip:function(){return be(this,se(this))},mapEntries:function(t,e){var r=this,n=0;return be(this,this.toSeq().map(function(i,o){return t.call(e,[o,i],n++,r)}).fromEntrySeq())},mapKeys:function(t,e){var r=this;return be(this,this.toSeq().flip().map(function(n,i){return t.call(e,n,i,r)}).flip())}});var an=r.prototype;an[hr]=!0,an[br]=sn.entries,an.__toJS=sn.toObject,an.__toStringMapper=function(t,e){return JSON.stringify(e)+": "+er(t)},Fe(n,{toKeyedSeq:function(){return new ne(this,!1)},filter:function(t,e){return be(this,fe(this,t,e,!1))},findIndex:function(t,e){var r=this.findEntry(t,e);return r?r[0]:-1},indexOf:function(t){var e=this.keyOf(t);return void 0===e?-1:e},lastIndexOf:function(t){var e=this.lastKeyOf(t);return void 0===e?-1:e},reverse:function(){return be(this,he(this,!1))},slice:function(t,e){return be(this,pe(this,t,e,!1))},splice:function(t,e){var r=arguments.length;if(e=Math.max(0|e,0),0===r||2===r&&!e)return this;t=m(t,0>t?this.count():this.size);var n=this.slice(0,t);return be(this,1===r?n:n.concat(p(arguments,2),this.slice(t+e)))},findLastIndex:function(t,e){var r=this.findLastEntry(t,e);return r?r[0]:-1},first:function(){return this.get(0)},flatten:function(t){return be(this,de(this,t,!1))},get:function(t,e){return t=l(this,t),0>t||this.size===1/0||void 0!==this.size&&t>this.size?e:this.find(function(e,r){return r===t},void 0,e)},has:function(t){return t=l(this,t),t>=0&&(void 0!==this.size?this.size===1/0||this.size>t:-1!==this.indexOf(t))},interpose:function(t){return be(this,ge(this,t))},interleave:function(){var t=[this].concat(p(arguments)),e=Ie(this.toSeq(),k.of,t),r=e.flatten(!0);return e.size&&(r.size=e.size*t.length),
|
||||
be(this,r)},keySeq:function(){return $(0,this.size)},last:function(){return this.get(-1)},skipWhile:function(t,e){return be(this,le(this,t,e,!1))},zip:function(){var t=[this].concat(p(arguments));return be(this,Ie(this,rr,t))},zipWith:function(t){var e=p(arguments);return e[0]=this,be(this,Ie(this,t,e))}}),n.prototype[fr]=!0,n.prototype[cr]=!0,Fe(i,{get:function(t,e){return this.has(t)?t:e},includes:function(t){return this.has(t)},keySeq:function(){return this.valueSeq()}}),i.prototype.has=sn.includes,i.prototype.contains=i.prototype.includes,Fe(x,r.prototype),Fe(k,n.prototype),Fe(A,i.prototype),Fe(et,r.prototype),Fe(rt,n.prototype),Fe(nt,i.prototype);var hn={Iterable:e,Seq:O,Collection:tt,Map:ct,OrderedMap:Zt,List:Bt,Stack:Ve,Set:Le,OrderedSet:Je,Record:Ae,Range:$,Repeat:G,is:X,fromJS:H};return hn});
|
||||
@@ -3,20 +3,39 @@
|
||||
var currentPath = window.location.protocol + "//" + window.location.host + window.location.pathname;
|
||||
var specURL = currentPath + '?format=openapi';
|
||||
var redoc = document.createElement("redoc");
|
||||
redoc.setAttribute("spec-url", specURL);
|
||||
|
||||
var redocSettings = JSON.parse(document.getElementById('redoc-settings').innerHTML);
|
||||
if (redocSettings.lazyRendering) {
|
||||
redoc.setAttribute("lazy-rendering", '');
|
||||
if (redocSettings.url) {
|
||||
specURL = redocSettings.url;
|
||||
}
|
||||
if (redocSettings.pathInMiddle) {
|
||||
redoc.setAttribute("path-in-middle-panel", '');
|
||||
delete redocSettings.url;
|
||||
if (redocSettings.fetchSchemaWithQuery) {
|
||||
var query = new URLSearchParams(window.location.search || '').entries();
|
||||
var url = specURL.split('?');
|
||||
var usp = new URLSearchParams(url[1] || '');
|
||||
for (var it = query.next(); !it.done; it = query.next()) {
|
||||
usp.set(it.value[0], it.value[1]);
|
||||
}
|
||||
url[1] = usp.toString();
|
||||
specURL = url[1] ? url.join('?') : url[0];
|
||||
}
|
||||
if (redocSettings.hideHostname) {
|
||||
redoc.setAttribute("hide-hostname", '');
|
||||
delete redocSettings.fetchSchemaWithQuery;
|
||||
|
||||
redoc.setAttribute("spec-url", specURL);
|
||||
|
||||
function camelToKebab(str) {
|
||||
return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
||||
}
|
||||
redoc.setAttribute("expand-responses", redocSettings.expandResponses);
|
||||
document.body.appendChild(redoc);
|
||||
|
||||
for (var p in redocSettings) {
|
||||
if (redocSettings.hasOwnProperty(p)) {
|
||||
if (redocSettings[p] !== null && redocSettings[p] !== undefined && redocSettings[p] !== false) {
|
||||
redoc.setAttribute(camelToKebab(p), redocSettings[p].toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
document.body.replaceChild(redoc, document.getElementById('redoc-placeholder'));
|
||||
|
||||
function hideEmptyVersion() {
|
||||
// 'span.api-info-version' is for redoc 1.x, 'div.api-info span' is for redoc 2-alpha
|
||||
@@ -29,8 +48,8 @@ function hideEmptyVersion() {
|
||||
var versionString = apiVersion.innerText;
|
||||
if (versionString) {
|
||||
// trim spaces and surrounding ()
|
||||
versionString = versionString.replace(/ /g,'');
|
||||
versionString = versionString.replace(/(^\()|(\)$)/g,'');
|
||||
versionString = versionString.replace(/ /g, '');
|
||||
versionString = versionString.replace(/(^\()|(\)$)/g, '');
|
||||
}
|
||||
|
||||
if (!versionString) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 4.9 KiB |
+30
-42
File diff suppressed because one or more lines are too long
@@ -19,10 +19,6 @@ body.swagger-body {
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
#django-session-auth {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 445 B |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,22 +1,52 @@
|
||||
"use strict";
|
||||
var currentPath = window.location.protocol + "//" + window.location.host + window.location.pathname;
|
||||
var specURL = currentPath + '?format=openapi';
|
||||
var defaultSpecUrl = currentPath + '?format=openapi';
|
||||
|
||||
// load the saved authorization state from localStorage; ImmutableJS is used for consistency with swagger-ui state
|
||||
var savedAuth = Immutable.fromJS({});
|
||||
|
||||
// global SwaggerUI config object; can be changed directly or by hooking initSwaggerUiConfig
|
||||
var swaggerUiConfig = {
|
||||
url: defaultSpecUrl,
|
||||
dom_id: '#swagger-ui',
|
||||
displayRequestDuration: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout",
|
||||
filter: true,
|
||||
requestInterceptor: function (request) {
|
||||
var headers = request.headers || {};
|
||||
var csrftoken = document.querySelector("[name=csrfmiddlewaretoken]");
|
||||
if (csrftoken) {
|
||||
headers["X-CSRFToken"] = csrftoken.value;
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
};
|
||||
|
||||
function patchSwaggerUi() {
|
||||
var authWrapper = document.querySelector('.auth-wrapper');
|
||||
var authorizeButton = document.querySelector('.auth-wrapper .authorize');
|
||||
var djangoSessionAuth = document.querySelector('#django-session-auth');
|
||||
if (document.querySelector('.auth-wrapper #django-session-auth')) {
|
||||
console.log("WARNING: session auth already patched; skipping patchSwaggerUi()");
|
||||
return;
|
||||
}
|
||||
|
||||
var authWrapper = document.querySelector('.auth-wrapper');
|
||||
var authorizeButton = document.querySelector('.auth-wrapper .authorize');
|
||||
var djangoSessionAuth = document.querySelector('#django-session-auth');
|
||||
|
||||
if (!djangoSessionAuth) {
|
||||
console.log("WARNING: session auth disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
djangoSessionAuth = djangoSessionAuth.cloneNode(true);
|
||||
authWrapper.insertBefore(djangoSessionAuth, authorizeButton);
|
||||
djangoSessionAuth.classList.remove("hidden");
|
||||
|
||||
var divider = document.createElement("div");
|
||||
divider.classList.add("divider");
|
||||
authWrapper.insertBefore(divider, authorizeButton);
|
||||
}
|
||||
|
||||
function initSwaggerUi() {
|
||||
@@ -24,59 +54,324 @@ function initSwaggerUi() {
|
||||
console.log("WARNING: skipping initSwaggerUi() because window.ui is already defined");
|
||||
return;
|
||||
}
|
||||
var swaggerConfig = {
|
||||
url: specURL,
|
||||
dom_id: '#swagger-ui',
|
||||
displayOperationId: true,
|
||||
displayRequestDuration: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout",
|
||||
filter: true,
|
||||
requestInterceptor: function (request) {
|
||||
var headers = request.headers || {};
|
||||
var csrftoken = document.querySelector("[name=csrfmiddlewaretoken]");
|
||||
if (csrftoken) {
|
||||
headers["X-CSRFToken"] = csrftoken.value;
|
||||
}
|
||||
return request;
|
||||
}
|
||||
};
|
||||
if (document.querySelector('.auth-wrapper .authorize')) {
|
||||
patchSwaggerUi();
|
||||
}
|
||||
else {
|
||||
insertionQ('.auth-wrapper .authorize').every(patchSwaggerUi);
|
||||
}
|
||||
|
||||
var swaggerSettings = JSON.parse(document.getElementById('swagger-settings').innerHTML);
|
||||
if (!('oauth2RedirectUrl' in swaggerSettings)) {
|
||||
var oauth2RedirectUrl = document.getElementById('oauth2-redirect-url');
|
||||
if (oauth2RedirectUrl) {
|
||||
swaggerSettings['oauth2RedirectUrl'] = oauth2RedirectUrl.href;
|
||||
oauth2RedirectUrl.parentNode.removeChild(oauth2RedirectUrl);
|
||||
|
||||
var oauth2RedirectUrl = document.getElementById('oauth2-redirect-url');
|
||||
if (oauth2RedirectUrl) {
|
||||
if (!('oauth2RedirectUrl' in swaggerSettings)) {
|
||||
if (oauth2RedirectUrl) {
|
||||
swaggerSettings['oauth2RedirectUrl'] = oauth2RedirectUrl.href;
|
||||
}
|
||||
}
|
||||
oauth2RedirectUrl.parentNode.removeChild(oauth2RedirectUrl);
|
||||
}
|
||||
|
||||
console.log(swaggerSettings);
|
||||
for (var p in swaggerSettings) {
|
||||
if (swaggerSettings.hasOwnProperty(p)) {
|
||||
swaggerConfig[p] = swaggerSettings[p];
|
||||
}
|
||||
}
|
||||
window.ui = SwaggerUIBundle(swaggerConfig);
|
||||
|
||||
console.log('swaggerSettings', swaggerSettings);
|
||||
var oauth2Config = JSON.parse(document.getElementById('oauth2-config').innerHTML);
|
||||
console.log(oauth2Config);
|
||||
console.log('oauth2Config', oauth2Config);
|
||||
|
||||
initSwaggerUiConfig(swaggerSettings, oauth2Config);
|
||||
window.ui = SwaggerUIBundle(swaggerUiConfig);
|
||||
window.ui.initOAuth(oauth2Config);
|
||||
}
|
||||
|
||||
window.onload = function () {
|
||||
initSwaggerUi();
|
||||
};
|
||||
/**
|
||||
* Initialize the global swaggerUiConfig with any given additional settings.
|
||||
* @param swaggerSettings SWAGGER_SETTINGS from Django settings
|
||||
* @param oauth2Settings OAUTH2_CONFIG from Django settings
|
||||
*/
|
||||
function initSwaggerUiConfig(swaggerSettings, oauth2Settings) {
|
||||
var persistAuth = swaggerSettings.persistAuth;
|
||||
var refetchWithAuth = swaggerSettings.refetchWithAuth;
|
||||
var refetchOnLogout = swaggerSettings.refetchOnLogout;
|
||||
var fetchSchemaWithQuery = swaggerSettings.fetchSchemaWithQuery;
|
||||
delete swaggerSettings['persistAuth'];
|
||||
delete swaggerSettings['refetchWithAuth'];
|
||||
delete swaggerSettings['refetchOnLogout'];
|
||||
delete swaggerSettings['fetchSchemaWithQuery'];
|
||||
|
||||
if (document.querySelector('.auth-wrapper .authorize')) {
|
||||
patchSwaggerUi();
|
||||
for (var p in swaggerSettings) {
|
||||
if (swaggerSettings.hasOwnProperty(p)) {
|
||||
swaggerUiConfig[p] = swaggerSettings[p];
|
||||
}
|
||||
}
|
||||
|
||||
var specURL = swaggerUiConfig.url;
|
||||
if (fetchSchemaWithQuery) {
|
||||
// only add query params from document for the first spec request
|
||||
// this ensures we otherwise honor the spec selector box which might be manually modified
|
||||
var query = new URLSearchParams(window.location.search || '').entries();
|
||||
for (var it = query.next(); !it.done; it = query.next()) {
|
||||
specURL = setQueryParam(specURL, it.value[0], it.value[1]);
|
||||
}
|
||||
}
|
||||
if (persistAuth) {
|
||||
try {
|
||||
savedAuth = Immutable.fromJS(JSON.parse(localStorage.getItem("drf-yasg-auth")) || {});
|
||||
} catch (e) {
|
||||
localStorage.removeItem("drf-yasg-auth");
|
||||
}
|
||||
}
|
||||
if (refetchWithAuth) {
|
||||
specURL = applyAuth(savedAuth, specURL) || specURL;
|
||||
}
|
||||
swaggerUiConfig.url = specURL;
|
||||
|
||||
if (persistAuth || refetchWithAuth) {
|
||||
var hookedAuth = false;
|
||||
|
||||
var oldOnComplete = swaggerUiConfig.onComplete;
|
||||
swaggerUiConfig.onComplete = function () {
|
||||
if (persistAuth) {
|
||||
preauthorizeAll(savedAuth, window.ui);
|
||||
}
|
||||
|
||||
if (!hookedAuth) {
|
||||
hookAuthActions(window.ui, persistAuth, refetchWithAuth, refetchOnLogout);
|
||||
hookedAuth = true;
|
||||
}
|
||||
if (oldOnComplete) {
|
||||
oldOnComplete();
|
||||
}
|
||||
};
|
||||
|
||||
var specRequestsInFlight = {};
|
||||
var oldRequestInterceptor = swaggerUiConfig.requestInterceptor;
|
||||
swaggerUiConfig.requestInterceptor = function (request) {
|
||||
var headers = request.headers || {};
|
||||
if (request.loadSpec) {
|
||||
var newUrl = request.url;
|
||||
if (refetchWithAuth) {
|
||||
newUrl = applyAuth(savedAuth, newUrl, headers) || newUrl;
|
||||
}
|
||||
|
||||
if (newUrl !== request.url) {
|
||||
request.url = newUrl;
|
||||
|
||||
if (window.ui) {
|
||||
// this visually updates the spec url before the request is done, i.e. while loading
|
||||
window.ui.specActions.updateUrl(request.url);
|
||||
} else {
|
||||
// setTimeout is needed here because the request interceptor can be called *during*
|
||||
// window.ui initialization (by the SwaggerUIBundle constructor)
|
||||
setTimeout(function () {
|
||||
window.ui.specActions.updateUrl(request.url);
|
||||
});
|
||||
}
|
||||
|
||||
// need to manually remember requests for spec urls because
|
||||
// responseInterceptor has no reference to the request...
|
||||
var absUrl = new URL(request.url, currentPath);
|
||||
specRequestsInFlight[absUrl.href] = request.url;
|
||||
}
|
||||
}
|
||||
|
||||
if (oldRequestInterceptor) {
|
||||
request = oldRequestInterceptor(request);
|
||||
}
|
||||
return request;
|
||||
};
|
||||
|
||||
var oldResponseInterceptor = swaggerUiConfig.responseInterceptor;
|
||||
swaggerUiConfig.responseInterceptor = function (response) {
|
||||
var absUrl = new URL(response.url, currentPath);
|
||||
console.log("response", response);
|
||||
if (absUrl.href in specRequestsInFlight) {
|
||||
var setToUrl = specRequestsInFlight[absUrl.href];
|
||||
delete specRequestsInFlight[absUrl.href];
|
||||
if (response.ok) {
|
||||
// need setTimeout here because swagger-ui insists to call updateUrl
|
||||
// with the initial request url after the response...
|
||||
setTimeout(function () {
|
||||
var currentUrl = new URL(window.ui.specSelectors.url(), currentPath);
|
||||
if (currentUrl.href !== absUrl.href) {
|
||||
window.ui.specActions.updateUrl(setToUrl);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (oldResponseInterceptor) {
|
||||
response = oldResponseInterceptor(response);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
insertionQ('.auth-wrapper .authorize').every(patchSwaggerUi);
|
||||
|
||||
function _usp(url, fn) {
|
||||
url = url.split('?');
|
||||
var usp = new URLSearchParams(url[1] || '');
|
||||
fn(usp);
|
||||
url[1] = usp.toString();
|
||||
return url[1] ? url.join('?') : url[0];
|
||||
}
|
||||
|
||||
function setQueryParam(url, key, value) {
|
||||
return _usp(url, function (usp) {
|
||||
usp.set(key, value);
|
||||
});
|
||||
}
|
||||
|
||||
function removeQueryParam(url, key) {
|
||||
return _usp(url, function (usp) {
|
||||
usp.delete(key);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Call sui.preauthorize### for all authorizations in authorization.
|
||||
* @param authorization authorization object {key => authScheme} saved from authActions.authorize
|
||||
* @param sui SwaggerUI or SwaggerUIBundle instance
|
||||
*/
|
||||
function preauthorizeAll(authorization, sui) {
|
||||
authorization.valueSeq().forEach(function (authScheme) {
|
||||
var schemeName = authScheme.get("name"), schemeType = authScheme.getIn(["schema", "type"]);
|
||||
if (schemeType === "basic" && schemeName) {
|
||||
var username = authScheme.getIn(["value", "username"]);
|
||||
var password = authScheme.getIn(["value", "password"]);
|
||||
if (username && password) {
|
||||
sui.preauthorizeBasic(schemeName, username, password);
|
||||
}
|
||||
} else if (schemeType === "apiKey" && schemeName) {
|
||||
var key = authScheme.get("value");
|
||||
if (key) {
|
||||
sui.preauthorizeApiKey(schemeName, key);
|
||||
}
|
||||
} else {
|
||||
// TODO: OAuth2
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually apply auth headers from the given auth object.
|
||||
* @param {object} authorization authorization object {key => authScheme} saved from authActions.authorize
|
||||
* @param {string} requestUrl the request url
|
||||
* @param {object} requestHeaders target headers, modified in place by the function
|
||||
* @return string new request url
|
||||
*/
|
||||
function applyAuth(authorization, requestUrl, requestHeaders) {
|
||||
authorization.valueSeq().forEach(function (authScheme) {
|
||||
requestHeaders = requestHeaders || {};
|
||||
var schemeName = authScheme.get("name"), schemeType = authScheme.getIn(["schema", "type"]);
|
||||
if (schemeType === "basic" && schemeName) {
|
||||
var username = authScheme.getIn(["value", "username"]);
|
||||
var password = authScheme.getIn(["value", "password"]);
|
||||
if (username && password) {
|
||||
requestHeaders["Authorization"] = "Basic " + btoa(username + ":" + password);
|
||||
}
|
||||
} else if (schemeType === "apiKey" && schemeName) {
|
||||
var _in = authScheme.getIn(["schema", "in"]), paramName = authScheme.getIn(["schema", "name"]);
|
||||
var key = authScheme.get("value");
|
||||
if (key && paramName) {
|
||||
if (_in === "header") {
|
||||
requestHeaders[paramName] = key;
|
||||
}
|
||||
if (_in === "query") {
|
||||
if (requestUrl) {
|
||||
requestUrl = setQueryParam(requestUrl, paramName, key);
|
||||
}
|
||||
else {
|
||||
console.warn("WARNING: cannot apply apiKey query parameter via interceptor");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// TODO: OAuth2
|
||||
}
|
||||
});
|
||||
|
||||
return requestUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given authorization scheme from the url.
|
||||
* @param {object} authorization authorization object {key => authScheme} containing schemes to deauthorize
|
||||
* @param {string} requestUrl request url
|
||||
* @return string new request url
|
||||
*/
|
||||
function deauthUrl(authorization, requestUrl) {
|
||||
authorization.valueSeq().forEach(function (authScheme) {
|
||||
var schemeType = authScheme.getIn(["schema", "type"]);
|
||||
if (schemeType === "apiKey") {
|
||||
var _in = authScheme.getIn(["schema", "in"]), paramName = authScheme.getIn(["schema", "name"]);
|
||||
if (_in === "query" && requestUrl && paramName) {
|
||||
requestUrl = removeQueryParam(requestUrl, paramName);
|
||||
}
|
||||
} else {
|
||||
// TODO: OAuth2?
|
||||
}
|
||||
});
|
||||
return requestUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook the authorize and logout actions of SwaggerUI.
|
||||
* The hooks are used to persist authorization data and trigger schema refetch.
|
||||
* @param sui SwaggerUI or SwaggerUIBundle instance
|
||||
* @param {boolean} persistAuth true to save auth to local storage
|
||||
* @param {boolean} refetchWithAuth true to trigger schema fetch on login
|
||||
* @param {boolean} refetchOnLogout true to trigger schema fetch on logout
|
||||
*/
|
||||
function hookAuthActions(sui, persistAuth, refetchWithAuth, refetchOnLogout) {
|
||||
if (!persistAuth && !refetchWithAuth) {
|
||||
// nothing to do
|
||||
return;
|
||||
}
|
||||
|
||||
var originalAuthorize = sui.authActions.authorize;
|
||||
sui.authActions.authorize = function (authorization) {
|
||||
originalAuthorize(authorization);
|
||||
// authorization is map of scheme name to scheme object
|
||||
// need to use ImmutableJS because schema is already an ImmutableJS object
|
||||
var newAuths = Immutable.fromJS(authorization);
|
||||
savedAuth = savedAuth.merge(newAuths);
|
||||
|
||||
if (refetchWithAuth) {
|
||||
var url = sui.specSelectors.url();
|
||||
url = applyAuth(savedAuth, url) || url;
|
||||
sui.specActions.updateUrl(url);
|
||||
sui.specActions.download();
|
||||
sui.authActions.showDefinitions(); // hide authorize dialog
|
||||
}
|
||||
if (persistAuth) {
|
||||
localStorage.setItem("drf-yasg-auth", JSON.stringify(savedAuth.toJSON()));
|
||||
}
|
||||
};
|
||||
|
||||
var originalLogout = sui.authActions.logout;
|
||||
sui.authActions.logout = function (authorization) {
|
||||
// stash logged out methods for use with deauthUrl
|
||||
var loggedOut = savedAuth.filter(function (val, key) {
|
||||
return authorization.indexOf(key) !== -1;
|
||||
}).mapEntries(function (entry) {
|
||||
return [entry[0], entry[1].set("value", null)]
|
||||
});
|
||||
// remove logged out methods from savedAuth
|
||||
savedAuth = savedAuth.filter(function (val, key) {
|
||||
return authorization.indexOf(key) === -1;
|
||||
});
|
||||
|
||||
if (refetchWithAuth) {
|
||||
var url = sui.specSelectors.url();
|
||||
url = deauthUrl(loggedOut, url) || url;
|
||||
sui.specActions.updateUrl(url);
|
||||
sui.specActions.download(url);
|
||||
sui.authActions.showDefinitions(); // hide authorize dialog
|
||||
}
|
||||
if (persistAuth) {
|
||||
localStorage.setItem("drf-yasg-auth", JSON.stringify(savedAuth.toJSON()));
|
||||
}
|
||||
originalLogout(authorization);
|
||||
};
|
||||
}
|
||||
|
||||
window.addEventListener('load', initSwaggerUi);
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,18 @@
|
||||
{% load static %}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{{ title }}</title>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'drf-yasg/style.css' %}"/>
|
||||
</head>
|
||||
<body>
|
||||
<script id="redoc-settings" type="application/json">{{ redoc_settings | safe }}</script>
|
||||
|
||||
<script src="{% static 'drf-yasg/insQ.min.js' %}"></script>
|
||||
<script src="{% static 'drf-yasg/redoc-init.js' %}"> </script>
|
||||
<script src="{% static 'drf-yasg/redoc-old/redoc.min.js' %}"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -2,17 +2,48 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{{ title }}</title>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{% block title %}{{ title }}{% endblock %}</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'drf-yasg/style.css' %}"/>
|
||||
{% block extra_head %}
|
||||
{# -- Add any extra HTML heads tags here - except scripts and styles -- #}
|
||||
{% endblock %}
|
||||
|
||||
{% block favicon %}
|
||||
{# -- Maybe replace the favicon -- #}
|
||||
<link rel="icon" type="image/png" href="{% static 'drf-yasg/redoc/redoc-logo.png' %}"/>
|
||||
{% endblock %}
|
||||
|
||||
{% block main_styles %}
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'drf-yasg/style.css' %}"/>
|
||||
{% endblock %}
|
||||
{% block extra_styles %}
|
||||
{# -- Add any additional CSS scripts here -- #}
|
||||
{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
<script id="redoc-settings" type="application/json">{{ redoc_settings | safe }}</script>
|
||||
|
||||
{% block extra_body %}
|
||||
{# -- Add any header/body markup here (rendered BEFORE the swagger-ui/redoc element) -- #}
|
||||
{% endblock %}
|
||||
|
||||
<div id="redoc-placeholder"></div>
|
||||
|
||||
{% block footer %}
|
||||
{# -- Add any footer markup here (rendered AFTER the swagger-ui/redoc element) -- #}
|
||||
{% endblock %}
|
||||
|
||||
<script id="redoc-settings" type="application/json">{{ redoc_settings | safe }}</script>
|
||||
|
||||
{% block main_scripts %}
|
||||
<script src="{% static 'drf-yasg/insQ.min.js' %}"></script>
|
||||
<script src="{% static 'drf-yasg/redoc-init.js' %}"> </script>
|
||||
<script src="{% static 'drf-yasg/url-polyfill.min.js' %}"></script>
|
||||
<script src="{% static 'drf-yasg/redoc-init.js' %}"></script>
|
||||
<script src="{% static 'drf-yasg/redoc/redoc.min.js' %}"></script>
|
||||
{% endblock %}
|
||||
{% block extra_scripts %}
|
||||
{# -- Add any additional scripts here -- #}
|
||||
{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,98 +1,91 @@
|
||||
<!-- HTML for static distribution bundle build -->
|
||||
{% load static %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{{ title }}</title>
|
||||
<meta charset="utf-8"/>
|
||||
<title>{% block title %}{{ title }}{% endblock %}</title>
|
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700">
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'drf-yasg/style.css' %}"/>
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'drf-yasg/swagger-ui-dist/swagger-ui.css' %}">
|
||||
<link rel="icon" type="image/png" href="{% static 'drf-yasg/swagger-ui-dist/favicon-32x32.png' %}" sizes="32x32"/>
|
||||
<link rel="icon" type="image/png" href="{% static 'drf-yasg/swagger-ui-dist/favicon-16x16.png' %}" sizes="16x16"/>
|
||||
{% block extra_head %}
|
||||
{# -- Add any extra HTML heads tags here - except scripts and styles -- #}
|
||||
{% endblock %}
|
||||
|
||||
{% block favicon %}
|
||||
{# -- Maybe replace the favicon -- #}
|
||||
<link rel="icon" type="image/png" href="{% static 'drf-yasg/swagger-ui-dist/favicon-32x32.png' %}"/>
|
||||
{% endblock %}
|
||||
|
||||
{% block main_styles %}
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'drf-yasg/style.css' %}"/>
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'drf-yasg/swagger-ui-dist/swagger-ui.css' %}">
|
||||
{% endblock %}
|
||||
{% block extra_styles %}
|
||||
{# -- Add any additional CSS scripts here -- #}
|
||||
{% endblock %}
|
||||
</head>
|
||||
|
||||
<body class="swagger-body">
|
||||
|
||||
<svg class="swagger-defs" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<symbol viewBox="0 0 20 20" id="unlocked">
|
||||
<path
|
||||
d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z"></path>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 20 20" id="locked">
|
||||
<path
|
||||
d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8zM12 8H8V5.199C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8z"></path>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 20 20" id="close">
|
||||
<path
|
||||
d="M14.348 14.849c-.469.469-1.229.469-1.697 0L10 11.819l-2.651 3.029c-.469.469-1.229.469-1.697 0-.469-.469-.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-.469-.469-.469-1.228 0-1.697.469-.469 1.228-.469 1.697 0L10 8.183l2.651-3.031c.469-.469 1.228-.469 1.697 0 .469.469.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c.469.469.469 1.229 0 1.698z"></path>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 20 20" id="large-arrow">
|
||||
<path
|
||||
d="M13.25 10L6.109 2.58c-.268-.27-.268-.707 0-.979.268-.27.701-.27.969 0l7.83 7.908c.268.271.268.709 0 .979l-7.83 7.908c-.268.271-.701.27-.969 0-.268-.269-.268-.707 0-.979L13.25 10z"></path>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 20 20" id="large-arrow-down">
|
||||
<path
|
||||
d="M17.418 6.109c.272-.268.709-.268.979 0s.271.701 0 .969l-7.908 7.83c-.27.268-.707.268-.979 0l-7.908-7.83c-.27-.268-.27-.701 0-.969.271-.268.709-.268.979 0L10 13.25l7.418-7.141z"></path>
|
||||
</symbol>
|
||||
|
||||
|
||||
<symbol viewBox="0 0 24 24" id="jump-to">
|
||||
<path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.41L5.83 13H21V7z"></path>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 24 24" id="expand">
|
||||
<path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"></path>
|
||||
</symbol>
|
||||
|
||||
</defs>
|
||||
</svg>
|
||||
{% block extra_body %}
|
||||
{# -- Add any header/body markup here (rendered BEFORE the swagger-ui/redoc element) -- #}
|
||||
{% endblock %}
|
||||
|
||||
<div id="swagger-ui"></div>
|
||||
<div id="spec-error" class="hidden alert alert-danger"></div>
|
||||
|
||||
{% block footer %}
|
||||
{# -- Add any footer markup here (rendered AFTER the swagger-ui/redoc element) -- #}
|
||||
{% endblock %}
|
||||
|
||||
<script id="swagger-settings" type="application/json">{{ swagger_settings | safe }}</script>
|
||||
<script id="oauth2-config" type="application/json">{{ oauth2_config | safe }}</script>
|
||||
|
||||
<script src="{% static 'drf-yasg/swagger-ui-dist/swagger-ui-bundle.js' %}"></script>
|
||||
<script src="{% static 'drf-yasg/swagger-ui-dist/swagger-ui-standalone-preset.js' %}"></script>
|
||||
<script src="{% static 'drf-yasg/insQ.min.js' %}"></script>
|
||||
<script src="{% static 'drf-yasg/swagger-ui-init.js' %}"></script>
|
||||
{% block main_scripts %}
|
||||
<script src="{% static 'drf-yasg/swagger-ui-dist/swagger-ui-bundle.js' %}"></script>
|
||||
<script src="{% static 'drf-yasg/swagger-ui-dist/swagger-ui-standalone-preset.js' %}"></script>
|
||||
<script src="{% static 'drf-yasg/insQ.min.js' %}"></script>
|
||||
<script src="{% static 'drf-yasg/immutable.min.js' %}"></script>
|
||||
<script src="{% static 'drf-yasg/url-polyfill.min.js' %}"></script>
|
||||
<script src="{% static 'drf-yasg/swagger-ui-init.js' %}"></script>
|
||||
{% endblock %}
|
||||
{% block extra_scripts %}
|
||||
{# -- Add any additional scripts here -- #}
|
||||
{% endblock %}
|
||||
|
||||
<a id="oauth2-redirect-url" href="{% static 'drf-yasg/swagger-ui-dist/oauth2-redirect.html' %}" class="hidden"></a>
|
||||
|
||||
<div id="django-session-auth" class="hidden">
|
||||
{% if USE_SESSION_AUTH %}
|
||||
{% csrf_token %}
|
||||
{% if request.user.is_authenticated %}
|
||||
<div class="hello">
|
||||
<span class="django-session">Django</span> <span class="label label-primary">{{ request.user }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if USE_SESSION_AUTH %}
|
||||
<div id="django-session-auth" class="hidden">
|
||||
{% block session_auth_button %}
|
||||
{% csrf_token %}
|
||||
|
||||
{% if request.user.is_authenticated %}
|
||||
<div class='btn authorize'>
|
||||
<a id="auth" class="header__btn" href="{{ LOGOUT_URL }}?next={{ request.path }}" data-sw-translate>
|
||||
Django Logout
|
||||
</a>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class='btn authorize'>
|
||||
<a id="auth" class="header__btn" href="{{ LOGIN_URL }}?next={{ request.path }}" data-sw-translate>
|
||||
Django Login
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% block user_context_message %}
|
||||
{% if request.user.is_authenticated %}
|
||||
<div class="hello">
|
||||
<span class="django-session">Django</span> <span
|
||||
class="label label-primary">{{ request.user }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% if request.user.is_authenticated %}
|
||||
<div class='btn authorize'>
|
||||
<a id="auth" class="header__btn" href="{{ LOGOUT_URL }}?next={{ request.path }}" data-sw-translate>
|
||||
{% block django_logout_message %}
|
||||
Django Logout
|
||||
{% endblock %}
|
||||
</a>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class='btn authorize'>
|
||||
<a id="auth" class="header__btn" href="{{ LOGIN_URL }}?next={{ request.path }}" data-sw-translate>
|
||||
{% block django_login_message %}
|
||||
Django Login
|
||||
{% endblock %}
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
+24
-6
@@ -11,7 +11,7 @@ from rest_framework.settings import api_settings as rest_framework_settings
|
||||
from rest_framework.utils import encoders, json
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from drf_yasg.app_settings import swagger_settings
|
||||
from .app_settings import swagger_settings
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -50,7 +50,7 @@ def swagger_auto_schema(method=None, methods=None, auto_schema=unset, request_bo
|
||||
the `manual_parameters` argument.
|
||||
|
||||
If a ``Serializer`` class or instance is given, it will be automatically converted into a :class:`.Schema`
|
||||
used as a ``body`` :class:`.Parameter`, or into a list of ``form`` :class:`.Parameter`\ s, as appropriate.
|
||||
used as a ``body`` :class:`.Parameter`, or into a list of ``form`` :class:`.Parameter`\\ s, as appropriate.
|
||||
|
||||
:param .Serializer query_serializer: if you use a ``Serializer`` to parse query parameters, you can pass it here
|
||||
and have :class:`.Parameter` objects be generated automatically from it.
|
||||
@@ -63,7 +63,7 @@ def swagger_auto_schema(method=None, methods=None, auto_schema=unset, request_bo
|
||||
|
||||
:param list[.Parameter] manual_parameters: a list of manual parameters to override the automatically generated ones
|
||||
|
||||
:class:`.Parameter`\ s are identified by their (``name``, ``in``) combination, and any parameters given
|
||||
:class:`.Parameter`\\ s are identified by their (``name``, ``in``) combination, and any parameters given
|
||||
here will fully override automatically generated parameters if they collide.
|
||||
|
||||
It is an error to supply ``form`` parameters when the request does not consume form-data.
|
||||
@@ -107,6 +107,8 @@ def swagger_auto_schema(method=None, methods=None, auto_schema=unset, request_bo
|
||||
'query_serializer': query_serializer,
|
||||
'manual_parameters': manual_parameters,
|
||||
'operation_id': operation_id,
|
||||
'operation_summary': operation_summary,
|
||||
'deprecated': deprecated,
|
||||
'operation_description': operation_description,
|
||||
'security': security,
|
||||
'responses': responses,
|
||||
@@ -120,7 +122,7 @@ def swagger_auto_schema(method=None, methods=None, auto_schema=unset, request_bo
|
||||
data.update(extra_overrides)
|
||||
if not data: # pragma: no cover
|
||||
# no overrides to set, no use in doing more work
|
||||
return
|
||||
return view_method
|
||||
|
||||
# if the method is an @action, it will have a bind_to_methods attribute, or a mapping attribute for drf>3.8
|
||||
bind_to_methods = getattr(view_method, 'bind_to_methods', [])
|
||||
@@ -252,10 +254,26 @@ def param_list_to_odict(parameters):
|
||||
return result
|
||||
|
||||
|
||||
def merge_params(parameters, overrides):
|
||||
"""Merge `overrides` into `parameters`. This is the same as appending `overrides` to `parameters`, but any element
|
||||
of `parameters` whose ``(name, in_)`` tuple collides with an element in `overrides` is replaced by it.
|
||||
|
||||
Raises an ``AssertionError`` if either list contains duplicate parameters.
|
||||
|
||||
:param list[.Parameter] parameters: initial parameters
|
||||
:param list[.Parameter] overrides: overriding parameters
|
||||
:return: merged list
|
||||
:rtype: list[.Parameter]
|
||||
"""
|
||||
parameters = param_list_to_odict(parameters)
|
||||
parameters.update(param_list_to_odict(overrides))
|
||||
return list(parameters.values())
|
||||
|
||||
|
||||
def filter_none(obj):
|
||||
"""Remove ``None`` values from tuples, lists or dictionaries. Return other objects as-is.
|
||||
|
||||
:param obj:
|
||||
:param obj: the object
|
||||
:return: collection with ``None`` values removed
|
||||
"""
|
||||
if obj is None:
|
||||
@@ -402,7 +420,7 @@ def get_field_default(field):
|
||||
"called; 'default' will not be set on schema", field, exc_info=True)
|
||||
default = serializers.empty
|
||||
|
||||
if default is not serializers.empty:
|
||||
if default is not serializers.empty and default is not None:
|
||||
try:
|
||||
default = field.to_representation(default)
|
||||
# JSON roundtrip ensures that the value is valid JSON;
|
||||
|
||||
+17
-6
@@ -11,12 +11,16 @@ from rest_framework.settings import api_settings
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from .app_settings import swagger_settings
|
||||
from .renderers import OpenAPIRenderer, ReDocRenderer, SwaggerJSONRenderer, SwaggerUIRenderer, SwaggerYAMLRenderer
|
||||
from .renderers import (
|
||||
OpenAPIRenderer, ReDocOldRenderer, ReDocRenderer, SwaggerJSONRenderer, SwaggerUIRenderer, SwaggerYAMLRenderer,
|
||||
_SpecRenderer
|
||||
)
|
||||
|
||||
SPEC_RENDERERS = (SwaggerYAMLRenderer, SwaggerJSONRenderer, OpenAPIRenderer)
|
||||
UI_RENDERERS = {
|
||||
'swagger': (SwaggerUIRenderer, ReDocRenderer),
|
||||
'redoc': (ReDocRenderer, SwaggerUIRenderer),
|
||||
'redoc-old': (ReDocOldRenderer, ReDocRenderer, SwaggerUIRenderer),
|
||||
}
|
||||
|
||||
|
||||
@@ -45,9 +49,7 @@ def deferred_never_cache(view_func):
|
||||
|
||||
|
||||
def get_schema_view(info=None, url=None, patterns=None, urlconf=None, public=False, validators=None,
|
||||
generator_class=swagger_settings.DEFAULT_GENERATOR_CLASS,
|
||||
authentication_classes=api_settings.DEFAULT_AUTHENTICATION_CLASSES,
|
||||
permission_classes=api_settings.DEFAULT_PERMISSION_CLASSES):
|
||||
generator_class=None, authentication_classes=None, permission_classes=None):
|
||||
"""Create a SchemaView class with default renderers and generators.
|
||||
|
||||
:param .Info info: information about the API; if omitted, defaults to :ref:`DEFAULT_INFO <default-swagger-settings>`
|
||||
@@ -63,9 +65,13 @@ def get_schema_view(info=None, url=None, patterns=None, urlconf=None, public=Fal
|
||||
:rtype: type[.SchemaView]
|
||||
"""
|
||||
_public = public
|
||||
_generator_class = generator_class
|
||||
_generator_class = generator_class or swagger_settings.DEFAULT_GENERATOR_CLASS
|
||||
_auth_classes = authentication_classes
|
||||
if _auth_classes is None:
|
||||
_auth_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
|
||||
_perm_classes = permission_classes
|
||||
if _perm_classes is None:
|
||||
_perm_classes = api_settings.DEFAULT_PERMISSION_CLASSES
|
||||
info = info or swagger_settings.DEFAULT_INFO
|
||||
validators = validators or []
|
||||
_spec_renderers = tuple(renderer.with_validators(validators) for renderer in SPEC_RENDERERS)
|
||||
@@ -80,7 +86,12 @@ def get_schema_view(info=None, url=None, patterns=None, urlconf=None, public=Fal
|
||||
renderer_classes = _spec_renderers
|
||||
|
||||
def get(self, request, version='', format=None):
|
||||
generator = self.generator_class(info, request.version or version or '', url, patterns, urlconf)
|
||||
version = request.version or version or ''
|
||||
if isinstance(request.accepted_renderer, _SpecRenderer):
|
||||
generator = self.generator_class(info, version, url, patterns, urlconf)
|
||||
else:
|
||||
generator = self.generator_class(info, version, url, patterns=[])
|
||||
|
||||
schema = generator.get_schema(request, self.public)
|
||||
if schema is None:
|
||||
raise exceptions.PermissionDenied() # pragma: no cover
|
||||
|
||||
@@ -33,7 +33,12 @@ class ArticleSerializer(serializers.ModelSerializer):
|
||||
|
||||
|
||||
class ImageUploadSerializer(serializers.Serializer):
|
||||
what_am_i_doing = serializers.RegexField(regex=r"^69$", help_text="test", default="69")
|
||||
what_am_i_doing = serializers.RegexField(
|
||||
regex=r"^69$",
|
||||
help_text="test",
|
||||
default="69",
|
||||
allow_null=True
|
||||
)
|
||||
image_styles = serializers.ListSerializer(
|
||||
child=serializers.ChoiceField(choices=['wide', 'tall', 'thumb', 'social']),
|
||||
help_text="Parameter with Items"
|
||||
|
||||
@@ -15,7 +15,7 @@ from articles.models import Article
|
||||
from drf_yasg import openapi
|
||||
from drf_yasg.app_settings import swagger_settings
|
||||
from drf_yasg.inspectors import CoreAPICompatInspector, FieldInspector, NotHandled, SwaggerAutoSchema
|
||||
from drf_yasg.utils import swagger_auto_schema
|
||||
from drf_yasg.utils import no_body, swagger_auto_schema
|
||||
|
||||
|
||||
class DjangoFilterDescriptionInspector(CoreAPICompatInspector):
|
||||
@@ -133,11 +133,13 @@ class ArticleViewSet(viewsets.ModelViewSet):
|
||||
"""
|
||||
pass
|
||||
|
||||
@swagger_auto_schema(request_body=no_body, operation_id='no_body_test')
|
||||
def update(self, request, *args, **kwargs):
|
||||
"""update method docstring"""
|
||||
return super(ArticleViewSet, self).update(request, *args, **kwargs)
|
||||
|
||||
@swagger_auto_schema(operation_description="partial_update description override", responses={404: 'slug not found'})
|
||||
@swagger_auto_schema(operation_description="partial_update description override", responses={404: 'slug not found'},
|
||||
operation_summary='partial_update summary', deprecated=True)
|
||||
def partial_update(self, request, *args, **kwargs):
|
||||
"""partial_update method docstring"""
|
||||
return super(ArticleViewSet, self).partial_update(request, *args, **kwargs)
|
||||
|
||||
@@ -46,6 +46,10 @@ class SnippetList(generics.ListCreateAPIView):
|
||||
),
|
||||
)
|
||||
def delete(self, *args, **kwargs):
|
||||
"""summary from docstring
|
||||
|
||||
description body is here, summary is not included
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import os
|
||||
|
||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||
from django.urls import reverse_lazy
|
||||
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
ALLOWED_HOSTS = [
|
||||
@@ -47,7 +49,7 @@ ROOT_URLCONF = 'testproj.urls'
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [],
|
||||
'DIRS': [os.path.join(BASE_DIR, 'testproj', 'templates')],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
@@ -91,8 +93,11 @@ REST_FRAMEWORK = {
|
||||
# drf-yasg
|
||||
|
||||
SWAGGER_SETTINGS = {
|
||||
'LOGIN_URL': '/admin/login',
|
||||
'LOGIN_URL': reverse_lazy('admin:login'),
|
||||
'LOGOUT_URL': '/admin/logout',
|
||||
'PERSIST_AUTH': True,
|
||||
'REFETCH_SCHEMA_WITH_AUTH': True,
|
||||
'REFETCH_SCHEMA_ON_LOGOUT': True,
|
||||
|
||||
'DEFAULT_INFO': 'testproj.urls.swagger_info',
|
||||
|
||||
@@ -104,10 +109,19 @@ SWAGGER_SETTINGS = {
|
||||
'type': 'apiKey',
|
||||
'name': 'Authorization',
|
||||
'in': 'header'
|
||||
},
|
||||
'Query': {
|
||||
'type': 'apiKey',
|
||||
'name': 'auth',
|
||||
'in': 'query'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
REDOC_SETTINGS = {
|
||||
'SPEC_URL': ('schema-json', {'format': '.json'}),
|
||||
}
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/1.11/topics/i18n/
|
||||
|
||||
@@ -126,6 +140,9 @@ USE_TZ = True
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
|
||||
STATICFILES_DIRS = [
|
||||
os.path.join(BASE_DIR, 'testproj', 'static'),
|
||||
]
|
||||
|
||||
# Testing
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ urlpatterns = [
|
||||
url(r'^swagger(?P<format>.json|.yaml)$', SchemaView.without_ui(cache_timeout=0), name='schema-json'),
|
||||
url(r'^swagger/$', SchemaView.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
|
||||
url(r'^redoc/$', SchemaView.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
|
||||
url(r'^redoc-old/$', SchemaView.with_ui('redoc-old', cache_timeout=0), name='schema-redoc-old'),
|
||||
|
||||
url(r'^cached/swagger(?P<format>.json|.yaml)$', SchemaView.without_ui(cache_timeout=None), name='cschema-json'),
|
||||
url(r'^cached/swagger/$', SchemaView.with_ui('swagger', cache_timeout=None), name='cschema-swagger-ui'),
|
||||
|
||||
@@ -6,7 +6,7 @@ from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from drf_yasg import openapi
|
||||
from drf_yasg.utils import no_body, swagger_auto_schema
|
||||
from drf_yasg.utils import swagger_auto_schema
|
||||
from users.serializers import UserListQuerySerializer, UserSerializerrr
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ class UserList(APIView):
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
|
||||
@swagger_auto_schema(request_body=no_body, operation_id="users_dummy", operation_description="dummy operation")
|
||||
@swagger_auto_schema(operation_id="users_dummy", operation_description="dummy operation")
|
||||
def patch(self, request):
|
||||
pass
|
||||
|
||||
|
||||
+48
-9
@@ -27,9 +27,14 @@ securityDefinitions:
|
||||
in: header
|
||||
name: Authorization
|
||||
type: apiKey
|
||||
Query:
|
||||
in: query
|
||||
name: auth
|
||||
type: apiKey
|
||||
security:
|
||||
- Basic: []
|
||||
- Bearer: []
|
||||
- Query: []
|
||||
paths:
|
||||
/articles/:
|
||||
get:
|
||||
@@ -134,14 +139,9 @@ paths:
|
||||
tags:
|
||||
- articles
|
||||
put:
|
||||
operationId: articles_update
|
||||
operationId: no_body_test
|
||||
description: update method docstring
|
||||
parameters:
|
||||
- name: data
|
||||
in: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/Article'
|
||||
parameters: []
|
||||
responses:
|
||||
'200':
|
||||
description: ''
|
||||
@@ -151,6 +151,7 @@ paths:
|
||||
- articles
|
||||
patch:
|
||||
operationId: articles_partial_update
|
||||
summary: partial_update summary
|
||||
description: partial_update description override
|
||||
parameters:
|
||||
- name: data
|
||||
@@ -167,6 +168,7 @@ paths:
|
||||
description: slug not found
|
||||
tags:
|
||||
- articles
|
||||
deprecated: true
|
||||
delete:
|
||||
operationId: articles_delete
|
||||
description: destroy method docstring
|
||||
@@ -192,6 +194,8 @@ paths:
|
||||
responses:
|
||||
'200':
|
||||
description: ''
|
||||
schema:
|
||||
$ref: '#/definitions/Article'
|
||||
consumes:
|
||||
- multipart/form-data
|
||||
tags:
|
||||
@@ -208,6 +212,7 @@ paths:
|
||||
pattern: ^69$
|
||||
default: '69'
|
||||
minLength: 1
|
||||
x-nullable: true
|
||||
- name: image_styles
|
||||
in: formData
|
||||
description: Parameter with Items
|
||||
@@ -228,6 +233,8 @@ paths:
|
||||
responses:
|
||||
'201':
|
||||
description: ''
|
||||
schema:
|
||||
$ref: '#/definitions/ImageUpload'
|
||||
consumes:
|
||||
- multipart/form-data
|
||||
tags:
|
||||
@@ -390,7 +397,8 @@ paths:
|
||||
- snippets
|
||||
delete:
|
||||
operationId: snippetsDeleteBulk
|
||||
description: SnippetList classdoc
|
||||
summary: summary from docstring
|
||||
description: description body is here, summary is not included
|
||||
parameters:
|
||||
- name: data
|
||||
in: body
|
||||
@@ -883,6 +891,7 @@ definitions:
|
||||
- 3
|
||||
- 7
|
||||
- 8
|
||||
x-nullable: true
|
||||
group:
|
||||
type: string
|
||||
format: uuid
|
||||
@@ -890,6 +899,33 @@ definitions:
|
||||
type: string
|
||||
format: uuid
|
||||
readOnly: true
|
||||
ImageUpload:
|
||||
required:
|
||||
- image_styles
|
||||
type: object
|
||||
properties:
|
||||
what_am_i_doing:
|
||||
description: test
|
||||
type: string
|
||||
pattern: ^69$
|
||||
default: '69'
|
||||
minLength: 1
|
||||
x-nullable: true
|
||||
image_styles:
|
||||
description: Parameter with Items
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
enum:
|
||||
- wide
|
||||
- tall
|
||||
- thumb
|
||||
- social
|
||||
upload:
|
||||
description: image serializer help_text
|
||||
type: string
|
||||
readOnly: true
|
||||
format: uri
|
||||
Identity:
|
||||
title: Identity
|
||||
type: object
|
||||
@@ -903,12 +939,14 @@ definitions:
|
||||
type: string
|
||||
maxLength: 30
|
||||
minLength: 1
|
||||
x-nullable: true
|
||||
last_name:
|
||||
title: Last name
|
||||
description: <strong>Here's some HTML!</strong>
|
||||
type: string
|
||||
maxLength: 30
|
||||
minLength: 1
|
||||
x-nullable: true
|
||||
Person:
|
||||
required:
|
||||
- identity
|
||||
@@ -1460,6 +1498,7 @@ definitions:
|
||||
type: array
|
||||
items:
|
||||
type: integer
|
||||
x-nullable: true
|
||||
exampleProjects:
|
||||
type: array
|
||||
items:
|
||||
@@ -1524,6 +1563,7 @@ definitions:
|
||||
parent_id:
|
||||
type: integer
|
||||
title: Parent id
|
||||
x-nullable: true
|
||||
TodoTree:
|
||||
required:
|
||||
- title
|
||||
@@ -1599,7 +1639,6 @@ definitions:
|
||||
title: Foo
|
||||
type: string
|
||||
minLength: 1
|
||||
readOnly: true
|
||||
MethodFieldExample:
|
||||
title: Hint example
|
||||
type: object
|
||||
|
||||
@@ -25,8 +25,8 @@ def test_validator_url(swagger_settings, swagger):
|
||||
swagger_settings['VALIDATOR_URL'] = None
|
||||
_check_swagger_setting(swagger, 'validatorUrl', None)
|
||||
|
||||
swagger_settings['VALIDATOR_URL'] = 'not none'
|
||||
_check_swagger_setting(swagger, 'validatorUrl', 'not none')
|
||||
swagger_settings['VALIDATOR_URL'] = 'http://not.none/'
|
||||
_check_swagger_setting(swagger, 'validatorUrl', 'http://not.none/')
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
swagger_settings['VALIDATOR_URL'] = ''
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
[tox]
|
||||
# https://docs.djangoproject.com/en/dev/faq/install/#what-python-version-can-i-use-with-django
|
||||
envlist =
|
||||
py{27,34,35,36}-django111-drf37,
|
||||
py{27,34,35,36}-django111-drf38,
|
||||
py{34,35,36,37}-django20-drf37,
|
||||
py{34,35,36,37}-django20-drf38,
|
||||
py{35,36,37}-django21-drf37,
|
||||
py{35,36,37}-django21-drf38,
|
||||
py{27,34,35,36}-django111-drf{37,38},
|
||||
py{34,35,36,37}-django20-drf{37,38},
|
||||
py{35,36,37}-django21-drf{37,38},
|
||||
djmaster, lint, docs
|
||||
|
||||
[testenv]
|
||||
@@ -33,7 +30,6 @@ commands =
|
||||
[testenv:lint]
|
||||
skip_install = true
|
||||
deps =
|
||||
-rrequirements/setup.txt
|
||||
-rrequirements/lint.txt
|
||||
commands =
|
||||
flake8 src/drf_yasg testproj tests setup.py
|
||||
@@ -63,7 +59,7 @@ not_skip = __init__.py
|
||||
atomic = true
|
||||
multi_line_output = 5
|
||||
line_length = 120
|
||||
known_future_library = future,six
|
||||
known_future_library = six
|
||||
known_standard_library =
|
||||
collections,copy,distutils,functools,inspect,io,json,logging,operator,os,pkg_resources,re,setuptools,sys,
|
||||
types,warnings
|
||||
|
||||
+4
-2
@@ -3,8 +3,10 @@ set -ev
|
||||
npm update
|
||||
|
||||
cp node_modules/redoc/bundles/redoc.standalone.js src/drf_yasg/static/drf-yasg/redoc/redoc.min.js
|
||||
wget https://rebilly.github.io/ReDoc/releases/v1.x.x/redoc.min.js -O src/drf_yasg/static/drf-yasg/redoc-old/redoc.min.js
|
||||
|
||||
cp -r node_modules/swagger-ui-dist src/drf_yasg/static/drf-yasg/
|
||||
pushd src/drf_yasg/static/drf-yasg/swagger-ui-dist/ >/dev/null
|
||||
rm -f package.json .npmignore README.md
|
||||
rm -f index.html *.map
|
||||
rm -f package.json .npmignore README.md favicon-16x16.png
|
||||
rm -f swagger-ui.js index.html *.map
|
||||
popd >/dev/null
|
||||
|
||||
Reference in New Issue
Block a user