Compare commits

..
240 Commits
Author SHA1 Message Date
shockey f23b7044c8 Merge pull request #3222 from shockey/v/3.0.14
v3.0.14, second edition...
2017-06-09 21:37:44 -07:00
Kyle Shockey d043f0e7af Bump version 2017-06-09 21:30:55 -07:00
shockey 72cbcc69e8 Merge pull request #3221 from shockey/v/3.0.14
v/3.0.14
2017-06-09 21:02:05 -07:00
Kyle Shockey e3fa724f87 Rebuild dist 2017-06-09 20:56:33 -07:00
Kyle Shockey 811a0a10e3 v3.0.14 2017-06-09 20:39:50 -07:00
Kyle Shockey 0ab6fde25f Remove problematic package-lock.json (for now) 2017-06-09 20:37:47 -07:00
Tony Tam 99c03cf3bb Merge pull request #3179 from franzwong/master
Copy swagger.json to nginx directory
2017-06-09 11:47:20 -07:00
Tony Tam 071307c61e Merge branch 'master' into master 2017-06-09 11:40:50 -07:00
Tony Tam 08c691894d extract basename from $SWAGGER_JSON file 2017-06-09 11:40:33 -07:00
Tony Tam f6e921f101 Merge pull request #3053 from Yasami/docker-run.sh-eol-lf
Force line endings of docker-run.sh to Unix-style
2017-06-08 13:22:36 -07:00
Tony Tam 6defee4402 Merge branch 'master' into docker-run.sh-eol-lf 2017-06-08 13:16:29 -07:00
Ron d980982942 Merge pull request #3210 from dylancwood/chore-swagger-ui-dist-docs
Documentation: clarify the two different npm packages available
2017-06-08 13:04:25 -07:00
Ron 30686d6975 Merge branch 'master' into chore-swagger-ui-dist-docs 2017-06-08 13:01:29 -07:00
Ron 07076d6064 Merge pull request #3125 from micmro/update-alpine
update Docker base-image to alpine 3.5
2017-06-08 12:57:05 -07:00
Tony Tam 5e6103f0cb Merge branch 'master' into update-alpine 2017-06-08 12:53:50 -07:00
Ron 5a1f824c21 Merge branch 'master' into docker-run.sh-eol-lf 2017-06-08 12:49:43 -07:00
Ron 284f187253 Merge branch 'master' into chore-swagger-ui-dist-docs 2017-06-08 12:24:01 -07:00
Dylan 531e5d1d73 clarify the two different npm packages available for this repo 2017-06-08 12:03:38 -07:00
Anna 60a9dc490f Merge pull request #3207 from bodnia/fix-3191
fixes #3191
2017-06-08 15:46:16 +03:00
Anna Bodnia ee2e82390b fixes #3191 2017-06-08 15:41:06 +03:00
Anna 1dedd44324 Merge pull request #3206 from bodnia/fixes-3172
#3172 added Access-Control-Allow-Origin for auth requests
2017-06-08 14:14:06 +03:00
Anna Bodnia bbf93c5e1f #3172 added Access-Control-Allow-Origin for auth requests 2017-06-08 14:06:30 +03:00
Anna e2b2055b4b Merge pull request #3204 from bodnia/fix-3172
fixes #3172
2017-06-08 12:32:44 +03:00
Anna Bodnia 36b263e230 fixes #3172 2017-06-08 12:19:47 +03:00
shockey e7975e7f3d Merge pull request #3200 from shockey/bug/3199-sanitization-escaping
Markdown quote double-escaping
2017-06-07 13:00:42 -07:00
Kyle Shockey a9d4f5efde Add filter to un-double-escape quotation marks 2017-06-07 12:52:59 -07:00
Kyle Shockey 3189e6101b Fix eslint quotes rule 2017-06-07 12:52:50 -07:00
Kyle Shockey 8919661438 Add failing test 2017-06-07 12:52:35 -07:00
Ron e8d84c02e6 Merge pull request #3195 from gwynjudd/model-expansion
Add support for docExpansion flag to models
2017-06-06 22:51:49 -07:00
shockey 4f7e75f443 Add propTypes validation for getConfig 2017-06-06 22:39:46 -07:00
Gwyn Judd 2d0c660d9f Add support for docExpansion flag to models
Show a more compressed view if docExpansion is set to "none"
2017-06-07 12:26:48 +12:00
shockey 4038b11d69 Merge pull request #3193 from shockey/operation-id-tweaks
CSS fixes for operationId display
2017-06-06 12:13:14 -07:00
Kyle Shockey 97ab51c354 CSS fixes for operationId display 2017-06-06 12:07:37 -07:00
shockey 0fdaeff5e8 Merge pull request #3152 from slate-studio/master
Add operationId to be shown for each operation
2017-06-06 11:36:48 -07:00
Artem 36aa568f0e Update README 2017-06-06 21:30:13 +03:00
shockey c05b66f4d4 Remove displayOperationId as prop to Operations
This appears to be a mistake. Operations should get `displayOperationId` from `getConfigs`, not from a prop.
2017-06-06 11:28:27 -07:00
shockey 68974a95b2 Use destructuring synyax to get displayOperationId 2017-06-06 11:18:42 -07:00
shockey c03210e7d4 Merge branch 'master' into master 2017-06-06 10:48:19 -07:00
Ron e5a9571a72 Merge pull request #3190 from swagger-api/fix-readme
Update README.md
2017-06-06 09:14:56 -07:00
Ron 58acaf681d Update README.md 2017-06-06 09:06:12 -07:00
Artem 78af4e7f9f Merge branch 'operationId'
# Conflicts:
#	src/core/components/operation.jsx
2017-06-06 17:23:04 +03:00
Artem e3f872ad63 Display operationId 2017-06-06 17:21:20 +03:00
Franz Wong 58797025c6 Merge branch 'master' into master 2017-06-06 19:45:35 +09:00
shockey 12dd90f748 Merge pull request #3159 from gwynjudd/doc-expansion
Added support for docExpansion config
2017-06-05 20:17:57 -07:00
Kyle Shockey 09148e478c Remove switching logic from spec specSelector 2017-06-05 20:04:52 -07:00
Kyle Shockey a857e947de Add default value to config constructor 2017-06-05 20:04:35 -07:00
shockey 438546f923 Merge branch 'master' into doc-expansion 2017-06-05 16:12:14 -07:00
Ron ea66055329 Merge pull request #3181 from scottohara/rename-pulse-animation
Use less generic pulse animation name (Fixes #3169)
2017-06-05 09:31:20 -07:00
Ron 2257836114 Merge branch 'master' into rename-pulse-animation 2017-06-05 09:28:33 -07:00
shockey 563a5643e7 Merge pull request #3182 from scottohara/remove-legacy-clear-class
Remove unused legacy clear class (Fixes #3167)
2017-06-05 09:00:29 -07:00
Scott O'Hara af2c890e51 Use less generic pulse animation name (Fixes #3169) 2017-06-05 08:38:39 +10:00
Scott O'Hara eed62339b2 Remove unused legacy clear class (Fixes #3167) 2017-06-05 08:36:49 +10:00
shockey eec04f4ce2 Merge pull request #3180 from shockey/v/3.0.13
v/3.0.13
2017-06-03 00:41:15 -07:00
Kyle Shockey 58422825c9 Rebuild dist 2017-06-03 00:18:15 -07:00
Kyle Shockey 5952bb6cbf Bump fast-json-patch in lockfile 2017-06-03 00:16:44 -07:00
Kyle Shockey b4cb0ce247 Rebuild dist 2017-06-03 00:11:32 -07:00
Kyle Shockey 19f7668b48 Bump declared version and upstream minimum versions 2017-06-02 22:42:18 -07:00
Franz Wong 20e7c0708a Copy swagger.json to nginx directory 2017-06-03 13:01:11 +09:00
shockey f862caa599 Merge pull request #3178 from shockey/build
Rebuild dist
2017-06-02 15:55:09 -07:00
Kyle Shockey c471f59c53 Rebuild dist 2017-06-02 15:49:04 -07:00
shockey 9a08904574 Merge pull request #3165 from shockey/bug/3163-markdown-xss
Sanitize Markdown inputs
2017-06-01 23:47:18 -07:00
Kyle Shockey bec97cfaf5 Fix style error 2017-06-01 22:24:31 -07:00
Kyle Shockey 6ccd037197 Merge branch 'bug/3163-markdown-xss' of github.com:shockey/swagger-ui into bug/3163-markdown-xss 2017-06-01 22:18:37 -07:00
Kyle Shockey af2b1e20f1 Sanitize Markdown inputs 2017-06-01 22:14:44 -07:00
Kyle Shockey 23b1a8aabd Finish rewiring Markdown provider 2017-06-01 21:41:28 -07:00
Kyle Shockey a2eed69ee7 Create providers directory; Markdown provider 2017-06-01 21:37:00 -07:00
Gwyn Judd eb929d3129 Added support for docExpansion config 2017-06-02 09:02:29 +12:00
shockey 6ae7eb4591 Merge branch 'master' into bug/3163-markdown-xss 2017-06-01 09:47:12 -07:00
Kyle Shockey df47e0e956 Disable HTML rendering in React-Markdown 2017-06-01 09:43:13 -07:00
shockey 5752ffcdab Merge pull request #3161 from shockey/ft/dev-server-watch
Dev server: remove 'watch' call, fix HMR
2017-05-31 23:53:38 -07:00
shockey 2bc6c45f83 Merge branch 'master' into ft/dev-server-watch 2017-05-31 18:54:38 -07:00
shockey 01124b07ad Merge pull request #3162 from swagger-api/readme-updates-0531
Update README.md
2017-05-31 18:15:33 -07:00
Kyle Shockey 1280abe737 Merge branch 'ft/dev-server-watch' of github.com:shockey/swagger-ui into ft/dev-server-watch 2017-05-31 18:14:30 -07:00
Kyle Shockey f4d1d28dd8 HMR for dev server 2017-05-31 18:13:43 -07:00
shockey 4dc966870d Update README.md 2017-05-31 17:25:51 -07:00
shockey 1d07a4b764 Merge branch 'master' into ft/dev-server-watch 2017-05-31 17:21:27 -07:00
shockey 65a4f9aaf2 Merge pull request #3160 from shockey/ft/package-lock
Add package-lock.json
2017-05-31 17:19:49 -07:00
shockey fa01f2b45d Merge branch 'master' into ft/package-lock 2017-05-31 17:16:55 -07:00
Kyle Shockey 1b7d94a54b Dev server: remove 'watch' call 2017-05-31 17:11:04 -07:00
Kyle Shockey f583469876 Add package-lock.json 2017-05-31 17:10:37 -07:00
Ron b242917e3e Merge pull request #2886 from gierschv/fix.info-font
fix(info): font for title, li and table
2017-05-31 12:35:02 -07:00
Ron d1c1b000bf Merge branch 'master' into fix.info-font 2017-05-31 12:31:00 -07:00
shockey fdcdb831eb Merge branch 'master' into master 2017-05-31 12:09:14 -07:00
Anna 8eb5461664 Merge pull request #3156 from bodnia/fix-3128-password
#3128 make request-body type default for aouth2 password flow
2017-05-31 18:58:09 +03:00
Anna Bodnia 676fd99960 #3128 make request-body type default for aouth2 password flow 2017-05-31 18:53:45 +03:00
Alexander Kravets adc09b6d5d Merge branch 'master' into master 2017-05-31 18:45:40 +03:00
Artem ed364d3562 Resolve conflicts 2017-05-31 18:43:47 +03:00
Anna 49705f3441 Merge pull request #3155 from bodnia/fix-3128
fix #3128
2017-05-31 18:18:21 +03:00
Artem 78fcf5f0ff Merge branch 'master' of https://github.com/slate-studio/swagger-ui 2017-05-31 17:50:16 +03:00
Artem 5eb006ee3d Refactor code 2017-05-31 17:50:11 +03:00
Anna Bodnia 5f2eaffbc3 fix #3128 2017-05-31 17:31:29 +03:00
Vincent Giersch 0ea14189c0 fix(info): font for title, li and table 2017-05-31 10:46:07 +02:00
Alexander Kravets 914f6991cd Merge branch 'master' into master 2017-05-31 08:47:48 +03:00
Anna 88df65533c Merge pull request #3148 from bodnia/master
typo in README
2017-05-30 14:49:07 +03:00
Anna Bodnia 8340f5d06c typo in README 2017-05-30 14:45:04 +03:00
Michael Mrowetz 6bced2ad48 Merge branch 'master' into update-alpine 2017-05-29 17:07:18 -07:00
Artem 2fd9d9ed25 Change operationId font size 2017-05-29 14:38:21 +03:00
Artem 20d9161e2b Add operationId 2017-05-29 13:31:38 +03:00
shockey 39501c8d82 Merge pull request #3140 from shockey/v/3.0.12
v3.0.12
2017-05-26 19:43:55 -07:00
Kyle Shockey d68dd5f7d6 Rebuild dist 2017-05-26 19:38:03 -07:00
Kyle Shockey 2567e5168d v3.0.12 2017-05-26 19:36:30 -07:00
shockey bf6681c914 Merge pull request #3133 from shockey/ft/dist-npm-packaging
packaging: fix swagger-ui-dist entry point
2017-05-26 00:59:16 -07:00
Michael Mrowetz b9dbfccb8e Merge branch 'master' into update-alpine 2017-05-26 00:03:27 -07:00
Roman Bolshakov b23c999d01 packaging: fix swagger-ui-dist entry point
Entry point was missing. This change allows importing SwaggerUIBundle
and SwaggerUIStandalonePreset directly from package. Correct entry point
is also needed for module bundlers like webpack to perform tree-shaking.
2017-05-25 17:45:01 -07:00
Anna 41d8089d0e Merge pull request #3130 from bodnia/fix-3067
Fix 3067
2017-05-25 18:30:12 +03:00
Anna Bodnia c5d2faa3a2 build 2017-05-25 18:10:40 +03:00
Anna Bodnia df4ea9b3d6 Merge remote-tracking branch 'upstream/master' into fix-3067 2017-05-25 18:06:07 +03:00
Anna Bodnia 62cb9ec581 Read me for modelPropertyMacro, changed for parameterMacro 2017-05-25 18:04:21 +03:00
Michael Mrowetz 494b99ebef update base-image to alpine 3.5 2017-05-25 10:55:38 +09:00
shockey 1db8e498b7 Merge pull request #3116 from Minasokoni/clickfix
Updated click area
2017-05-24 09:01:34 -07:00
Anna Bodnia 918e0e46c0 read me for parameterMacro 2017-05-23 15:36:42 +03:00
Robert Barnwell 760d1eba80 Merge branch 'master' into clickfix 2017-05-22 09:57:19 -07:00
Minasokoni a2a2f76199 updated click area 2017-05-22 09:12:13 -07:00
Anna Bodnia d5b9552a5a removed debugger 2017-05-22 17:13:31 +03:00
shockey 753134ec49 Merge pull request #3114 from shockey/v/3.0.11
v3.0.11
2017-05-19 20:25:59 -07:00
Kyle Shockey 612078ac8c Rebuild dist 2017-05-19 20:17:37 -07:00
Kyle Shockey e45570b6c8 v3.0.11 2017-05-19 20:09:34 -07:00
shockey daef38d2e3 Merge pull request #3092 from Minasokoni/wordwrapfix
Long single line responses wrapped with css
2017-05-19 18:46:28 -07:00
shockey eb8a64a66f Merge branch 'master' into wordwrapfix 2017-05-19 18:43:27 -07:00
Anna Bodnia edfe88d299 modelPropertyMacro, parameterMacro 2017-05-19 18:50:51 +03:00
shockey c66436e7d5 Merge pull request #3108 from swagger-api/shockey-patch-3
Add custom namespace to config whitelist
2017-05-18 23:41:34 -07:00
shockey b530ac8593 Default value for custom key 2017-05-18 23:35:02 -07:00
shockey d30b3a9ba1 Add custom namespace to config whitelist 2017-05-18 23:33:12 -07:00
shockey e326a99001 Merge pull request #3106 from shockey/ft/error-jump-to-line
Jump to Line
2017-05-18 15:32:44 -07:00
Kyle Shockey a28dc13191 Merge branch 'master' of github.com:swagger-api/swagger-ui into ft/error-jump-to-line 2017-05-18 15:21:09 -07:00
Kyle Shockey c942f382fb Rebuild dist 2017-05-18 15:15:01 -07:00
Kyle Shockey b6bb1deab8 Rewire jump to line for Errors component 2017-05-18 15:13:04 -07:00
Anna 6224617984 Merge pull request #3099 from bodnia/fix-3089
fixes #3089
2017-05-17 18:16:31 +03:00
Anna Bodnia b85d9a8c24 fixes #3089 2017-05-17 18:13:04 +03:00
Robert Barnwell b28a649457 Merge branch 'master' into wordwrapfix 2017-05-16 11:38:48 -07:00
Minasokoni bb6bc00012 Long single line responses wrapped 2017-05-16 11:33:59 -07:00
Anna f235430f30 Merge pull request #3049 from furkanayhan/send_redirect_url_for_oauth2
Send redirect url for oauth2
2017-05-16 17:01:28 +03:00
Furkan Ayhan 0c7119e855 Send redirect url when authenticating with oauth2-authorization_code
also fix indentations of files
2017-05-16 16:50:13 +03:00
Anna d64e920665 Merge pull request #3084 from tcaesvk/feature/oauth2-authorize-query
fix OAuth2 authorize issue + remove redundant parameters
2017-05-16 15:18:20 +03:00
김 재석 c81fdaec57 fix lint errors 2017-05-16 15:31:02 +09:00
김 재석 960a99a5ea remove undefined parameters for OAuth2 authorize request 2017-05-16 15:20:58 +09:00
shockey e74989f22e Merge pull request #3077 from shockey/v/3.0.10
v3.0.10
2017-05-14 01:26:49 -07:00
Kyle Shockey 73ed923e28 v3.0.10 2017-05-14 01:10:00 -07:00
Kyle Shockey 599b448f91 Revert "fixes #2922"
This reverts commit 496062f980.
2017-05-13 10:15:38 -07:00
Kyle Shockey 6e40d04741 take advantage of Swagger-Client opId improvements 2017-05-13 09:50:34 -07:00
Anna e80b2f5b3f Merge pull request #3074 from bodnia/issue-2897
Issue 2897
2017-05-12 00:23:21 +03:00
Anna Bodnia 32cd6fe09c readme for configuration of auth 2017-05-11 20:14:49 +03:00
Anna Bodnia 8aebea34c4 add configuration of auth: scope separator, client id, client secret, app name, reaml, additionalQueryParams 2017-05-11 16:30:30 +03:00
Anna 5f6320e754 Merge pull request #3071 from bodnia/fix-3031
fixes #3031
2017-05-11 14:42:32 +03:00
Anna Bodnia 5574a6cb1f fixes #3031 2017-05-11 14:38:34 +03:00
shockey bb2e75da8f Merge pull request #3068 from shockey/bug/3027-gitless-building
try/catch git describe call
2017-05-10 22:11:09 -07:00
shockey ee3669312a Merge branch 'master' into bug/3027-gitless-building 2017-05-10 22:05:36 -07:00
Kyle Shockey c81f51f696 try/catch git describe call, fixes building without git present 2017-05-10 22:03:04 -07:00
Masahide Sakamaki bd44c2161a Merge branch 'master' into docker-run.sh-eol-lf 2017-05-11 12:17:44 +09:00
shockey e2003ae922 Merge pull request #3058 from jmendiara/fix/gitignore
gitignore all npm-debug logs
2017-05-10 13:37:15 -07:00
shockey 0ac0b5ba32 Merge branch 'master' into fix/gitignore 2017-05-10 13:32:45 -07:00
shockey f8381bf907 Merge pull request #3057 from jmendiara/fix/configLocation
Move filterConfigs to core
2017-05-10 11:12:43 -07:00
Javier Mendiara d378d38c12 Merge branch 'master' into fix/gitignore 2017-05-10 18:20:32 +02:00
Javier Mendiara Cañardo 53986d60bc Move filterConfigs to core
Fixes #3056
2017-05-10 18:17:37 +02:00
Anna 5b6f27c7db Merge pull request #3065 from bodnia/fix-2922
#Fixes 2922
2017-05-10 17:11:15 +03:00
Anna Bodnia 47b495b24d build 2017-05-10 17:04:36 +03:00
Anna Bodnia 496062f980 fixes #2922 2017-05-10 17:03:18 +03:00
Anna a920e3ab69 Merge pull request #3064 from bodnia/fix-3045
Fix 3045
2017-05-10 15:30:16 +03:00
Anna Bodnia 14e9fd7b0f built 2017-05-10 15:21:46 +03:00
Anna Bodnia ac4ef3fdd4 fixes #3045 order of configs inheratance 2017-05-10 15:20:32 +03:00
Javier Mendiara Cañardo 2de7b957df gitignore all npm-debug logs
Lot of npm-debugs files can be generated in devs computers, each one with a number suffix
ex:
```sh
npm-debug.log.213131231
npm-debug.log.213131231
npm-debug.log.213131231
```

Adding a wildcard prevents for accidental commits

_Official and default .gitignore for node in github.com: https://github.com/github/gitignore/blob/master/Node.gitignore#L4_
2017-05-09 15:14:14 +02:00
Masahide Sakamaki ef1ff15c89 Set EOL of docker-run.sh to LF 2017-05-08 21:10:51 +09:00
shockey a068f78252 Merge pull request #3043 from shockey/v/3.0.9
v3.0.9
2017-05-05 20:04:54 -07:00
Kyle Shockey 933da1e93a Dist rebuild 2017-05-05 19:56:41 -07:00
Kyle Shockey 3c1a1780a6 v3.0.9 as declared version 2017-05-05 19:51:46 -07:00
Ron bf1bc120fe Merge pull request #3039 from bodnia/config-readme
Readme for Topbar plugin, Configs plugin
2017-05-05 14:54:39 -07:00
Ron fce31afa6c Merge branch 'master' into config-readme 2017-05-05 14:41:46 -07:00
Anna b73063578c Merge pull request #3040 from bodnia/config-plugin-enable
enable configs plugin by default
2017-05-05 17:57:22 +03:00
Anna Bodnia cbd74b0c67 enable configs plugin by default 2017-05-05 17:50:22 +03:00
Anna Bodnia 8e80ca9583 Readme for Topbar plugin, Configs plugin 2017-05-05 17:45:40 +03:00
shockey 3ef50589e9 Merge pull request #3029 from shockey/rebuild
Rebuild dist
2017-05-04 11:09:39 -07:00
Kyle Shockey 1d146394f3 Rebuild dist 2017-05-04 10:57:42 -07:00
shockey e91573af39 Merge pull request #3017 from Minasokoni/searchbar-fix
preventDefault the searchbar
2017-05-04 10:42:38 -07:00
shockey 2cc3e3c2d6 Merge branch 'master' into searchbar-fix 2017-05-04 10:29:14 -07:00
Anna af7a99e901 Merge pull request #3026 from bodnia/fix-2841
fixes #2841
2017-05-04 17:37:38 +03:00
Anna Bodnia 7e1eb4e9a7 fix #2841 2017-05-04 17:18:47 +03:00
Anna 4f0cf53401 Merge pull request #2949 from stefangr/fix_oauth2_scope_checkbox_uniqueness
Make the oauth2 scope checkbox id more unique.
2017-05-04 11:01:13 +03:00
Stefan Grootscholten 073eff4e10 Make the checkbox id more unique.
If the swagger.json defines more than one oauth2 Security scheme with
matching scopes, the id of the scope checkboxes were not unique.
As a result the scope for a second security scheme could not be
selected.

By adding the security scheme name to the id, it becomes more unique.
2017-05-04 09:39:22 +02:00
Robert Barnwell cd7007d557 Merge branch 'master' into searchbar-fix 2017-05-03 14:17:32 -07:00
shockey b76dcc2d4a Merge pull request #3018 from shockey/bug/3016-window-guard
Version stamping updates
2017-05-02 12:43:13 -07:00
Kyle Shockey b2af309cd5 Rebuild dist 2017-05-02 12:24:09 -07:00
Kyle Shockey 7296a054c4 Fix #3016 2017-05-02 12:15:17 -07:00
Minasokoni 6b5063ead1 Merge branch 'searchbar-fix' of github.com:Minasokoni/swagger-ui into searchbar-fix 2017-05-02 11:02:24 -07:00
Minasokoni 018491b4a7 removed semicolon 2017-05-02 11:02:14 -07:00
Robert Barnwell 74b4a3d598 Merge branch 'master' into searchbar-fix 2017-05-02 10:40:31 -07:00
Minasokoni 51b04b3a26 preventDefault the form 2017-05-02 10:38:35 -07:00
shockey f14d8067c4 Merge pull request #3005 from shockey/v/3.0.8
v/3.0.8
2017-04-28 19:55:24 -07:00
Kyle Shockey c08f3c230b v3.0.8 (fixes #2923 #2889) 2017-04-28 19:51:37 -07:00
Kyle Shockey 96f4b65dfa Rebuild dist 2017-04-28 19:40:39 -07:00
Kyle Shockey 69fd57f17f Increment swagger-client version 2017-04-28 18:43:24 -07:00
shockey f85fdb7835 Merge pull request #3004 from shockey/ft/3003-version-info
Add global variable that exposes UI version
2017-04-28 10:46:27 -07:00
Kyle Shockey 15d43886a3 Attach information to version object 2017-04-28 10:41:47 -07:00
Kyle Shockey 0e62d920e8 Merge branch 'master' of github.com:swagger-api/swagger-ui into ft/3003-version-info 2017-04-28 10:29:06 -07:00
Kyle Shockey b6c3f91127 Fix #3003 2017-04-28 10:06:43 -07:00
shockey 11e9bbfdbb Merge pull request #2958 from swagger-api/feature/older-react
Remove object-assign
2017-04-28 09:38:51 -07:00
shockey d2c3078a79 Merge branch 'master' into feature/older-react 2017-04-28 09:21:15 -07:00
shockey dd11740359 Merge pull request #3002 from Minasokoni/searchbar-update
Updated searchbar sizing and added onSubmit func
2017-04-28 09:06:48 -07:00
Robert Barnwell 8a1e447f0f Merge branch 'master' into searchbar-update 2017-04-28 08:39:16 -07:00
Minasokoni ca808e9d18 updated searchbar sizing 2017-04-28 08:36:32 -07:00
Josh Ponelat f5e89dc02e build 2017-04-28 11:19:39 +02:00
Josh Ponelat 2cff912261 remove object-assign dep ( which was missing from package.json ) 2017-04-28 11:17:59 +02:00
shockey 5a5a4d016b Merge pull request #2997 from shockey/Minasokoni-container-name-change
Changed main container className
2017-04-27 20:12:47 -07:00
Kyle Shockey f1f912a46f Merge branch 'master' of github.com:swagger-api/swagger-ui into Minasokoni-container-name-change 2017-04-27 20:04:52 -07:00
Kyle Shockey 518e2ec732 Merge branch 'master' into Minasokoni-container-name-change 2017-04-27 19:57:29 -07:00
Anna 862301e6df Merge pull request #2993 from bodnia/fix-2870
fix #2870
2017-04-27 19:14:16 +02:00
Anna Bodnia 374ac9cbbb fix #2870 2017-04-27 20:09:05 +03:00
Kyle Shockey 7d87c9d680 Fix typo in container classname 2017-04-27 09:09:09 -07:00
Kyle Shockey 78336e99aa Merge branch 'container-name-change' of https://github.com/Minasokoni/swagger-ui into Minasokoni-container-name-change 2017-04-27 09:08:55 -07:00
Anna a7c90e2d77 Merge pull request #2992 from bodnia/fix-2844
#2844 fix accessCode flow
2017-04-27 18:06:12 +02:00
Anna Bodnia 87a23c7c9e fix eslint errors 2017-04-27 19:01:27 +03:00
Anna Bodnia d013e7a05c #2844 fix accessCode flow 2017-04-27 18:55:25 +03:00
Minasokoni 198f9b6874 changed container classname 2017-04-27 08:35:33 -07:00
shockey 210b20eea8 Merge pull request #2985 from swagger-api/shockey-patch-2
Update webpack-dist.config.js
2017-04-26 23:03:20 -07:00
shockey f755f80072 Update webpack-dist.config.js 2017-04-26 22:43:54 -07:00
shockey 8137f25cc7 Merge pull request #2983 from shockey/bug/2937-core-missing-modules
Bug/2937 core missing modules
2017-04-26 19:42:00 -07:00
shockey a8ff714eee Merge branch 'master' into bug/2937-core-missing-modules 2017-04-26 18:34:58 -07:00
Kyle Shockey 494048e809 Fix #2937 2017-04-26 18:23:57 -07:00
Kyle Shockey bcd36ff667 Fix #2937 2017-04-26 18:11:27 -07:00
Ron 38ed6192c3 Merge pull request #2982 from swagger-api/issue_template
new issue_template
2017-04-26 15:58:29 -07:00
Ron b9df212ccc new issue_template 2017-04-26 15:50:35 -07:00
Anna 22dc506b13 Merge pull request #2977 from bodnia/issue-2898
#2898  operationsSorter config description
2017-04-26 17:39:39 +02:00
Anna da7210d328 Merge branch 'master' into issue-2898 2017-04-26 17:33:51 +02:00
Anna ca05b3e255 Merge pull request #2979 from bodnia/fix-oauth2-issue
fixes password, application oauth2 flows
2017-04-26 17:11:23 +02:00
Anna Bodnia 891c321c8a build 2017-04-26 18:06:26 +03:00
Anna Bodnia cecf0670b7 Merge branch 'master' into fix-oauth2-issue
# Conflicts:
#	dist/swagger-ui.css
2017-04-26 17:53:53 +03:00
Anna Bodnia bb73dd49d8 fixes password, application oauth2 flows 2017-04-26 17:50:09 +03:00
Anna Bodnia eab557f470 #2898 operationsSorter config description 2017-04-26 11:53:27 +03:00
shockey ac25a5dac6 Merge pull request #2974 from swagger-api/shockey-patch-1
Update README.md
2017-04-25 13:33:02 -07:00
shockey 073313df6f Merge branch 'master' into shockey-patch-1 2017-04-25 11:23:36 -07:00
shockey 26912b094f Merge pull request #2611 from elopio/snapcraft
Add the packaging metadata to build the swagger-ui snap
2017-04-25 11:23:21 -07:00
shockey 6f6f76caf4 Update README.md 2017-04-25 11:15:54 -07:00
shockey bbb3035bac Merge branch 'master' into snapcraft 2017-04-25 10:23:55 -07:00
shockey 6841732367 Merge pull request #2967 from Minasokoni/textformating
Headers now break onto their own lines
2017-04-25 10:23:06 -07:00
Robert Barnwell 1a417b3c6c Merge branch 'master' into textformating 2017-04-25 00:22:46 -07:00
Minasokoni aa327ed256 headers now break onto their own lines 2017-04-25 00:20:46 -07:00
Leo Arias 808f8d2827 Merge branch 'master' into snapcraft 2017-04-24 21:42:31 -06:00
Ron 4c40fa192b Merge pull request #2957 from deepu105/patch-1
Correct url in README file
2017-04-24 08:24:50 -07:00
Deepu K Sasidharan 2c6bd5d988 Correct url in README file
The npmjs.com/package/swagger-ui-dist url in the readme is wrong as it tries to load within github domain
2017-04-23 11:29:03 +02:00
Leo Arias 6a36b58977 Add the daemon 2017-01-14 05:15:39 +00:00
Leo Arias 7169ea32c9 Add the packaging metadata to build the swagger-ui snap 2017-01-14 04:35:51 +00:00
59 changed files with 759 additions and 334 deletions
+1 -1
View File
@@ -22,7 +22,7 @@
"rules": {
"semi": [2, "never"],
"strict": 0,
"quotes": 2,
"quotes": [2, "double", { "allowTemplateLiterals": true }],
"no-unused-vars": 2,
"no-multi-spaces": 1,
"camelcase": 1,
+1
View File
@@ -0,0 +1 @@
docker-run.sh text eol=lf
+3
View File
@@ -0,0 +1,3 @@
When reporting an issue, please provide the following details:
- swagger-ui version
- a swagger file reproducing the issue
+2 -1
View File
@@ -2,5 +2,6 @@ node_modules
.idea
.deps_check
.DS_Store
npm-debug.log
npm-debug.log*
.eslintcache
package-lock.json
+1 -1
View File
@@ -1,4 +1,4 @@
FROM alpine:3.4
FROM alpine:3.5
MAINTAINER fehguy
+80 -3
View File
@@ -8,6 +8,11 @@
As a brand new version, written from the ground up, there are some known issues and unimplemented features. Check out the [Known Issues](#known-issues) section for more details.
This repo publishes to two different NPM packages:
* [swagger-ui](https://www.npmjs.com/package/swagger-ui) is intended for use as a node module.
* [swagger-ui-dist](https://www.npmjs.com/package/swagger-ui-dist) comes pre-bundled with all dependencies and can be incorporated directly in a webapp.
For the older version of swagger-ui, refer to the [*2.x branch*](https://github.com/swagger-api/swagger-ui/tree/2.x).
## Compatibility
@@ -15,7 +20,8 @@ The OpenAPI Specification has undergone 4 revisions since initial creation in 20
Swagger UI Version | Release Date | OpenAPI Spec compatibility | Notes | Status
------------------ | ------------ | -------------------------- | ----- | ------
3.0.7 | 2017-03-19 | 2.0 | [tag v3.0.7](https://github.com/swagger-api/swagger-ui/tree/v3.0.7) |
3.0.14 | 2017-06-09 | 2.0 | [tag
v3.0.14](https://github.com/swagger-api/swagger-ui/tree/v3.0.14) |
2.2.10 | 2017-01-04 | 1.1, 1.2, 2.0 | [tag v2.2.10](https://github.com/swagger-api/swagger-ui/tree/v2.2.10) |
2.1.5 | 2016-07-20 | 1.1, 1.2, 2.0 | [tag v2.1.5](https://github.com/swagger-api/swagger-ui/tree/v2.1.5) |
2.0.24 | 2014-09-12 | 1.1, 1.2 | [tag v2.0.24](https://github.com/swagger-api/swagger-ui/tree/v2.0.24) |
@@ -35,13 +41,21 @@ docker run -p 80:8080 swaggerapi/swagger-ui
Will start nginx with swagger-ui on port 80.
Or you can provide your own swagger.json on your host
```
docker run -p 80:8080 -e "SWAGGER_JSON=/foo/swagger.json" -v /bar:/foo swaggerapi/swagger-ui
```
##### Prerequisites
- Node 6.x
- NPM 3.x
If you just want to see your specs, open `dist/index.html` in your browser directly from your filesystem.
If you'd like to make modifications to the codebase, run the dev server with: `npm run dev`.
If you'd like to make modifications to the codebase, run the dev server with: `npm run dev`. A development server will open on `3200`.
If you'd like to rebuild the `/dist` folder with your codebase changes, run `npm run build`.
##### Browser support
Swagger UI works in the latest versions of Chrome, Safari, Firefox, Edge and IE11.
@@ -57,6 +71,11 @@ To help with the migration, here are the currently known issues with 3.X. This l
- l10n (translations) is not implemented.
- Relative path support for external files is not implemented.
### Direct use of JS and CSS assets
To include the JS, CSS and image assets directly into a webpage, use the [swagger-ui-dist](https://www.npmjs.com/package/swagger-ui-dist) package.
The root directory of this package contains the contents of the _dist/_ directory of this repo.
As a node module, `swagger-ui-dist` also exports the `swagger-ui-bundle` and `swagger-ui-standalone-preset` objects.
### SwaggerUIBundle
To use swagger-ui's bundles, you should take a look at the [source of swagger-ui html page](https://github.com/swagger-api/swagger-ui/blob/master/dist/index.html) and customize it. This basically requires you to instantiate a SwaggerUi object as below:
@@ -75,7 +94,34 @@ To use swagger-ui's bundles, you should take a look at the [source of swagger-ui
})
```
If you'd like to use the bundle files via npm, check out the [`swagger-ui-dist` package](npmjs.com/package/swagger-ui-dist).
#### OAuth2 configuration
You can configure OAuth2 authorization by calling `initOAuth` method with passed configs under the instance of `SwaggerUIBundle`
default `client_id` and `client_secret`, `realm`, an application name `appName`, `scopeSeparator`, `additionalQueryStringParams`.
Config Name | Description
--- | ---
client_id | Default clientId. MUST be a string
client_secret | Default clientSecret. MUST be a string
realm | realm query parameter (for oauth1) added to `authorizationUrl` and `tokenUrl` . MUST be a string
appName | application name, displayed in authorization popup. MUST be a string
scopeSeparator | scope separator for passing scopes, encoded before calling, default value is a space (encoded value `%20`). MUST be a string
additionalQueryStringParams | Additional query parameters added to `authorizationUrl` and `tokenUrl`. MUST be an object
```
const ui = SwaggerUIBundle({...})
// Method can be called in any place after calling constructor SwaggerUIBundle
ui.initOAuth({
clientId: "your-client-id",
clientSecret: "your-client-secret-if-required",
realm: "your-realms",
appName: "your-app-name",
scopeSeparator: " ",
additionalQueryStringParams: {test: "hello"}
})
```
If you'd like to use the bundle files via npm, check out the [`swagger-ui-dist` package](https://www.npmjs.com/package/swagger-ui-dist).
#### Parameters
@@ -86,8 +132,39 @@ spec | A JSON object describing the OpenAPI Specification. When used, the `url`
validatorUrl | By default, Swagger-UI attempts to validate specs against swagger.io's online validator. You can use this parameter to set a different validator URL, for example for locally deployed validators ([Validator Badge](https://github.com/swagger-api/validator-badge)). Setting it to `null` will disable validation.
dom_id | The id of a dom element inside which SwaggerUi will put the user interface for swagger.
oauth2RedirectUrl | OAuth redirect URL
operationsSorter | Apply a sort to the operation list of each API. It can be 'alpha' (sort by paths alphanumerically), 'method' (sort by HTTP method) or a function (see Array.prototype.sort() to know how sort function works). Default is the order returned by the server unchanged.
configUrl | Configs URL
parameterMacro | MUST be a function. Function to set default value to parameters. Accepts two arguments parameterMacro(operation, parameter). Operation and parameter are objects passed for context, both remain immutable
modelPropertyMacro | MUST be a function. Function to set default values to each property in model. Accepts one argument modelPropertyMacro(property), property is immutable
docExpansion | Controls the default expansion setting for the operations and tags. It can be 'list' (expands only the tags), 'full' (expands the tags and operations) or 'none' (expands nothing). The default is 'list'.
displayOperationId | Controls the display of operationId in operations list. The default is `false`.
### Plugins
#### Topbar plugin
Topbar plugin enables top bar with input for spec path and explore button. By default the plugin is enabled, and to disable it you need to remove Topbar plugin from presets in `src/standalone/index.js`:
```
let preset = [
// TopbarPlugin,
ConfigsPlugin,
() => {
return {
components: { StandaloneLayout }
}
}
]
```
#### Configs plugin
Configs plugin allows to fetch external configs instead of passing them to `SwaggerUIBundle`. Fetched configs support two formats: JSON or yaml. The plugin is enabled by default.
There are three options of passing config:
- add a query parameter `config` with URL to a server where the configs are hosted. For ex. http://petstore.swagger.io/?config=http://localhost:3001/config.yaml
- add a config `configUrl` with URL to SwaggerUIBundle
- change default configs in `swagger-config.yaml` *Note: after changing, the project must be re-built*
These options can be used altogether, the order of inheritance is following (from the lowest priority to the highest):
`swagger-config.yaml` -> config passed to `SwaggerUIBundle` -> config fetched from `configUrl` passed to `SwaggerUIBundle` -> config fetched from URL passed as a query parameter `config`
## CORS Support
+9
View File
@@ -88,6 +88,15 @@ window.onload = function() {
})
window.ui = ui
ui.initOAuth({
clientId: "your-client-id",
clientSecret: "your-client-secret-if-required",
realm: "your-realms",
appName: "your-app-name",
scopeSeparator: " ",
additionalQueryStringParams: {}
})
}
</script>
</body>
+53
View File
@@ -0,0 +1,53 @@
<!doctype html>
<html lang="en-US">
<body onload="run()">
</body>
</html>
<script>
'use strict';
function run () {
var oauth2 = window.opener.swaggerUIRedirectOauth2;
var sentState = oauth2.state;
var redirectUrl = oauth2.redirectUrl;
var isValid, qp, arr;
qp = (window.location.hash || location.search).substring(1);
arr = qp.split("&")
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';})
qp = qp ? JSON.parse('{' + arr.join() + '}',
function (key, value) {
return key === "" ? value : decodeURIComponent(value)
}
) : {}
isValid = qp.state === sentState
if (oauth2.auth.schema.get("flow") === "accessCode" && !oauth2.auth.code) {
if (!isValid) {
oauth2.errCb({
authId: oauth2.auth.name,
source: "auth",
level: "warning",
message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"
});
}
if (qp.code) {
delete oauth2.state;
oauth2.auth.code = qp.code;
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
} else {
oauth2.errCb({
authId: oauth2.auth.name,
source: "auth",
level: "error",
message: "Authorization failed: no accessCode received from the server"
});
}
} else {
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
}
window.close();
}
</script>
+9 -39
View File
@@ -8,11 +8,14 @@
function run () {
var oauth2 = window.opener.swaggerUIRedirectOauth2;
var sentState = oauth2.state;
var isValid, qp;
var redirectUrl = oauth2.redirectUrl;
var isValid, qp, arr;
qp = (window.location.hash || location.search).substring(1);
qp = qp ? JSON.parse('{"' + qp.replace(/&/g, '","').replace(/=/g, '":"') + '"}',
arr = qp.split("&")
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';})
qp = qp ? JSON.parse('{' + arr.join() + '}',
function (key, value) {
return key === "" ? value : decodeURIComponent(value)
}
@@ -33,51 +36,18 @@
if (qp.code) {
delete oauth2.state;
oauth2.auth.code = qp.code;
createForm(oauth2.auth, qp).submit();
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
} else {
oauth2.errCb({
authId: oauth2.auth.name,
source: "auth",
level: "error",
message: "Authorization failed: no accessCode came from the server"
message: "Authorization failed: no accessCode received from the server"
});
window.close();
}
} else {
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid});
window.close();
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
}
window.close();
}
function createForm(auth, qp) {
var form = document.createElement("form");
var schema = auth.schema;
var action = schema.get("tokenUrl");
var name, input;
var fields = {
code: qp.code,
"redirect_uri": location.protocol + "//" + location.host + location.pathname,
"grant_type": "authorization_code",
"client_secret": auth.clientSecret,
"client_id": auth.clientId
}
for ( name in fields ) {
input = document.createElement("input");
input.name = name;
input.value = fields[name];
input.type = "hidden";
form.appendChild(input);
}
form.method = "POST";
form.action = action;
document.body.appendChild(form);
return form;
}
</script>
+44 -41
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"swagger-ui-bundle.js","sources":["webpack:///swagger-ui-bundle.js"],"mappings":"AAAA;AAu/FA;AA6+FA;;;;;;;;;;;;;;;;;;;;;;;;;;AA0dA;;;;;;AAoIA;AAk7FA;AAmtCA;;;;;AA0uIA;AA+4IA;AAm9FA;AA2rGA;AA8lFA;AA2nFA;AAu9CA;AAyhDA;AAqrCA;AAy4EA;AA8/GA;;;;;;;;;;;;;;AA+mJA;AA4mIA;AAquJA;AAwsHA;AAinGA;AAmiEA;AAy4DA;AAm2DA;AA0nBA;;;;;;AA4iFA;AAk0FA;;;;;AA23CA;AA2qFA;AAw2CA;AAglCA;AA0/CA;AAykFA;AA+1FA;;;;;;;;;AAk4CA;AA2zIA;AAk4DA;AAolDA","sourceRoot":""}
{"version":3,"file":"swagger-ui-bundle.js","sources":["webpack:///swagger-ui-bundle.js"],"mappings":"AAAA;AAu/FA;AA6+FA;;;;;;;;;;;;;;;;;;;;;;;;;;AA2TA;;;;;;AAoIA;AAi7FA;AAmtCA;AAi0IA;AA0oJA;AAgiGA;AA0/FA;AAqkFA;AAqjFA;AAk9CA;AA+jDA;AAwrCA;AA0gFA;;;;;AA+zBA;AAsyJA;;;;;;;;;;;;;;AA64EA;AA4mIA;AAquJA;AA2qHA;AA2mGA;AAiiEA;AAq4DA;AAg3DA;AA8NA;;;;;;AAw8FA;AA07FA;;;;;AAi8CA;AAgsFA;AAs2CA;AA+kCA;AAg8CA;AAg/EA;AAu/BA;AAk0FA;;;;;;;;;AAomDA;AA2zIA;AAu7FA;AAmrFA;AA20EA","sourceRoot":""}
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"swagger-ui-standalone-preset.js","sources":["webpack:///swagger-ui-standalone-preset.js"],"mappings":"AAAA;;;;;AA4QA;AAitGA","sourceRoot":""}
{"version":3,"file":"swagger-ui-standalone-preset.js","sources":["webpack:///swagger-ui-standalone-preset.js"],"mappings":"AAAA;;;;;AA8QA;AAmvGA;AAuxFA;;;;;;AAocA;AAkvFA;AAu+CA;AAo+CA;AAgrCA;AAuyEA","sourceRoot":""}
+1 -1
View File
File diff suppressed because one or more lines are too long
+9 -9
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"swagger-ui.js","sources":["webpack:///swagger-ui.js"],"mappings":"AAAA;;;;;;AA4wCA;AAoyHA;AAuxHA;AAy4FA;AA8rCA;AAugCA;AA+hCA;AA24BA","sourceRoot":""}
{"version":3,"file":"swagger-ui.js","sources":["webpack:///swagger-ui.js"],"mappings":"AAAA;;;;;;AA4yCA;AAoyHA;AAmyHA;AAukGA;AA+9BA;AA2jCA;AA0iCA;AAy4BA","sourceRoot":""}
+6 -3
View File
@@ -2,7 +2,8 @@
set -e
INDEX_FILE=/usr/share/nginx/html/index.html
NGINX_ROOT=/usr/share/nginx/html
INDEX_FILE=$NGINX_ROOT/index.html
replace_in_index () {
if [ "$1" != "**None**" ]; then
@@ -30,8 +31,10 @@ if [ "$OAUTH_ADDITIONAL_PARAMS" != "**None**" ]; then
fi
if [[ -f $SWAGGER_JSON ]]; then
sed -i "s|http://petstore.swagger.io/v2/swagger.json|swagger.json|g" $INDEX_FILE
sed -i "s|http://example.com/api|swagger.json|g" $INDEX_FILE
cp $SWAGGER_JSON $NGINX_ROOT
REL_PATH="/$(basename $SWAGGER_JSON)"
sed -i "s|http://petstore.swagger.io/v2/swagger.json|$REL_PATH|g" $INDEX_FILE
sed -i "s|http://example.com/api|$REL_PATH|g" $INDEX_FILE
else
sed -i "s|http://petstore.swagger.io/v2/swagger.json|$API_URL|g" $INDEX_FILE
sed -i "s|http://example.com/api|$API_URL|g" $INDEX_FILE
+21 -1
View File
@@ -4,9 +4,23 @@ var webpack = require('webpack')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var deepExtend = require('deep-extend')
var autoprefixer = require('autoprefixer')
const {gitDescribeSync} = require('git-describe');
var loadersByExtension = require('./build-tools/loadersByExtension')
var pkg = require('./package.json')
let gitInfo
try {
gitInfo = gitDescribeSync(__dirname)
} catch(e) {
gitInfo = {
hash: 'noGit',
dirty: false
}
}
module.exports = function(options) {
// Special options, that have logic in this file
@@ -59,8 +73,14 @@ module.exports = function(options) {
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: specialOptions.minimize ? JSON.stringify('production') : null,
WEBPACK_INLINE_STYLES: !Boolean(specialOptions.separateStylesheets)
WEBPACK_INLINE_STYLES: !Boolean(specialOptions.separateStylesheets)
},
'buildInfo': JSON.stringify({
PACKAGE_VERSION: (pkg.version),
GIT_COMMIT: gitInfo.hash,
GIT_DIRTY: gitInfo.dirty
})
}))
var cssLoader = 'css-loader!postcss-loader'
+8 -4
View File
@@ -1,6 +1,6 @@
{
"name": "swagger-ui",
"version": "3.0.7",
"version": "3.0.14",
"main": "dist/swagger-ui.js",
"repository": "git@github.com:swagger-api/swagger-ui.git",
"contributors": [
@@ -19,7 +19,7 @@
"build-core": "webpack --config webpack-dist.config.js --colors",
"build-standalone": "webpack --config webpack-dist-standalone.config.js --colors",
"predev": "npm install",
"dev": "npm-run-all --parallel hot-server watch open-localhost",
"dev": "npm-run-all --parallel hot-server open-localhost",
"watch": "webpack --config webpack-watch.config.js --watch --progress",
"open-localhost": "node -e 'require(\"open\")(\"http://localhost:3200\")'",
"hot-server": "webpack-dev-server --host 0.0.0.0 --config webpack-hot-dev-server.config.js --inline --hot --progress --content-base dev-helpers/",
@@ -32,14 +32,16 @@
"test": "npm run lint-errors && npm run just-test-in-node",
"test-in-node": "npm run lint-errors && npm run just-test-in-node",
"just-test": "karma start --config karma.conf.js",
"just-test-in-node": "mocha --recursive --compilers js:babel-core/register test/core test/components"
"just-test-in-node": "mocha --recursive --compilers js:babel-core/register test/core test/components test/bugs"
},
"dependencies": {
"babel-polyfill": "^6.23.0",
"base64-js": "^1.2.0",
"brace": "0.7.0",
"deep-extend": "0.4.1",
"expect": "1.20.2",
"getbase": "^2.8.2",
"ieee754": "^1.1.8",
"immutable": "^3.x.x",
"js-yaml": "^3.5.5",
"less": "2.7.1",
@@ -65,9 +67,10 @@
"redux-immutable": "3.0.8",
"redux-logger": "*",
"reselect": "2.5.3",
"sanitize-html": "^1.14.1",
"serialize-error": "2.0.0",
"shallowequal": "0.2.2",
"swagger-client": "^3.0.7",
"swagger-client": "~3.0.14",
"url-parse": "^1.1.8",
"whatwg-fetch": "0.11.1",
"worker-loader": "^0.7.1",
@@ -93,6 +96,7 @@
"eslint-plugin-react": "^6.10.3",
"extract-text-webpack-plugin": "0.8.2",
"file-loader": "0.8.4",
"git-describe": "^4.0.1",
"html-webpack-plugin": "^2.28.0",
"imports-loader": "0.6.5",
"json-loader": "0.5.3",
+28
View File
@@ -0,0 +1,28 @@
name: swagger-ui
version: master
summary: The World's Most Popular API Framework
description: |
Swagger UI is part of the Swagger project. The Swagger project allows you to
produce, visualize and consume your OWN RESTful services. No proxy or 3rd
party services required. Do it your own way.
Swagger UI is a dependency-free collection of HTML, Javascript, and CSS
assets that dynamically generate beautiful documentation and sandbox from a
Swagger-compliant API. Because Swagger UI has no dependencies, you can host
it in any server environment, or on your local machine.
grade: devel
confinement: strict
apps:
swagger-ui:
command: sh -c \"cd $SNAP/lib/node_modules/swagger-ui/dist && http-server -a localhost -p 8080\"
daemon: simple
plugs: [network, network-bind]
parts:
swagger-ui:
source: .
plugin: nodejs
npm-run: [build]
node-packages: [handlebars, http-server]
+1 -2
View File
@@ -53,8 +53,7 @@ export default class ApiKeyAuth extends React.Component {
<h4>Api key authorization<JumpToPath path={[ "securityDefinitions", name ]} /></h4>
{ value && <h6>Authorized</h6>}
<Row>
<Markdown options={{html: true, typographer: true, linkify: true, linkTarget: "_blank"}}
source={ schema.get("description") } />
<Markdown source={ schema.get("description") } />
</Row>
<Row>
<p>Name: <code>{ schema.get("name") }</code></p>
+1 -2
View File
@@ -59,8 +59,7 @@ export default class BasicAuth extends React.Component {
<h4>Basic authorization<JumpToPath path={[ "securityDefinitions", name ]} /></h4>
{ username && <h6>Authorized</h6> }
<Row>
<Markdown options={{html: true, typographer: true, linkify: true, linkTarget: "_blank"}}
source={ schema.get("description") } />
<Markdown source={ schema.get("description") } />
</Row>
<Row>
<label>Username:</label>
+60 -47
View File
@@ -21,14 +21,16 @@ export default class Oauth2 extends React.Component {
constructor(props, context) {
super(props, context)
let { name, schema, authorized } = this.props
let { name, schema, authorized, authSelectors } = this.props
let auth = authorized && authorized.get(name)
let authConfigs = authSelectors.getConfigs() || {}
let username = auth && auth.get("username") || ""
let clientId = auth && auth.get("clientId") || ""
let clientSecret = auth && auth.get("clientSecret") || ""
let passwordType = auth && auth.get("passwordType") || "none"
let clientId = auth && auth.get("clientId") || authConfigs.clientId || ""
let clientSecret = auth && auth.get("clientSecret") || authConfigs.clientSecret || ""
let passwordType = auth && auth.get("passwordType") || "request-body"
this.state = {
appName: authConfigs.appName,
name: name,
schema: schema,
scopes: [],
@@ -41,11 +43,12 @@ export default class Oauth2 extends React.Component {
}
authorize =() => {
let { authActions, errActions, getConfigs } = this.props
let { authActions, errActions, getConfigs, authSelectors } = this.props
let configs = getConfigs()
let authConfigs = authSelectors.getConfigs()
errActions.clear({authId: name,type: "auth", source: "auth"})
oauth2Authorize(this.state, authActions, errActions, configs)
oauth2Authorize({auth: this.state, authActions, errActions, configs, authConfigs })
}
onScopeChange =(e) => {
@@ -94,12 +97,13 @@ export default class Oauth2 extends React.Component {
let isAuthorized = !!authorizedAuth
let errors = errSelectors.allErrors().filter( err => err.get("authId") === name)
let isValid = !errors.filter( err => err.get("source") === "validation").size
let description = schema.get("description")
return (
<div>
<h4>OAuth2.0 <JumpToPath path={[ "securityDefinitions", name ]} /></h4>
<Markdown options={{html: true, typographer: true, linkify: true, linkTarget: "_blank"}}
source={ schema.get("description") } />
{ !this.state.appName ? null : <h5>Application: { this.state.appName } </h5> }
{ description && <Markdown source={ schema.get("description") } /> }
{ isAuthorized && <h6>Authorized</h6> }
@@ -108,50 +112,56 @@ export default class Oauth2 extends React.Component {
<p className="flow">Flow: <code>{ schema.get("flow") }</code></p>
{
flow === PASSWORD && ( !isAuthorized || isAuthorized && this.state.username) && <Row>
<Col tablet={2} desktop={2}>username:</Col>
<Col tablet={10} desktop={10}>
flow !== PASSWORD ? null
: <Row>
<Row>
<label htmlFor="oauth_username">username:</label>
{
isAuthorized ? <code> { this.state.username } </code>
: <Col tablet={10} desktop={10}>
<input id="oauth_username" type="text" data-name="username" onChange={ this.onInputChange }/>
</Col>
}
</Row>
{
isAuthorized ? <span>{ this.state.username }</span>
: <input type="text" data-name="username" onChange={ this.onInputChange }/>
}
</Col>
</Row>
<Row>
<label htmlFor="oauth_password">password:</label>
{
isAuthorized ? <code> ****** </code>
: <Col tablet={10} desktop={10}>
<input id="oauth_password" type="password" data-name="password" onChange={ this.onInputChange }/>
</Col>
}
</Row>
<Row>
<label htmlFor="password_type">type:</label>
{
isAuthorized ? <code> { this.state.passwordType } </code>
: <Col tablet={10} desktop={10}>
<select id="password_type" data-name="passwordType" onChange={ this.onInputChange }>
<option value="request-body">Request body</option>
<option value="basic">Basic auth</option>
<option value="query">Query parameters</option>
</select>
</Col>
}
</Row>
</Row>
}
{
flow === PASSWORD && !isAuthorized && <Row>
<Col tablet={2} desktop={2}>password:</Col>
<Col tablet={10} desktop={10}>
<input type="password" data-name="password" onChange={ this.onInputChange }/>
</Col>
</Row>
}
{
flow === PASSWORD && <Row>
<Col tablet={2} desktop={2}>type:</Col>
<Col tablet={10} desktop={10}>
{
isAuthorized ? <span>{ this.state.passwordType }</span>
: <select data-name="passwordType" onChange={ this.onInputChange }>
<option value="none">None or other</option>
<option value="basic">Basic auth</option>
<option value="request">Request body</option>
</select>
}
</Col>
</Row>
}
{
( flow === APPLICATION || flow === IMPLICIT || flow === ACCESS_CODE || ( flow === PASSWORD && this.state.passwordType!== "none") ) &&
( flow === APPLICATION || flow === IMPLICIT || flow === ACCESS_CODE || ( flow === PASSWORD && this.state.passwordType!== "basic") ) &&
( !isAuthorized || isAuthorized && this.state.clientId) && <Row>
<label htmlFor="client_id">client_id:</label>
{
isAuthorized ? <code> ****** </code>
: <Col tablet={10} desktop={10}>
<input id="client_id" type="text" required={ flow === PASSWORD } data-name="clientId"
<input id="client_id"
type="text"
required={ flow === PASSWORD }
value={ this.state.clientId }
data-name="clientId"
onChange={ this.onInputChange }/>
</Col>
}
@@ -159,12 +169,15 @@ export default class Oauth2 extends React.Component {
}
{
( flow === APPLICATION || flow === ACCESS_CODE || ( flow === PASSWORD && this.state.passwordType!== "none") ) && <Row>
( flow === APPLICATION || flow === ACCESS_CODE || ( flow === PASSWORD && this.state.passwordType!== "basic") ) && <Row>
<label htmlFor="client_secret">client_secret:</label>
{
isAuthorized ? <code> ****** </code>
: <Col tablet={10} desktop={10}>
<input id="client_secret" type="text" data-name="clientSecret"
<input id="client_secret"
value={ this.state.clientSecret }
type="text"
data-name="clientSecret"
onChange={ this.onInputChange }/>
</Col>
}
@@ -180,11 +193,11 @@ export default class Oauth2 extends React.Component {
<Row key={ name }>
<div className="checkbox">
<Input data-value={ name }
id={`${name}-checkbox`}
id={`${name}-checkbox-${this.state.name}`}
disabled={ isAuthorized }
type="checkbox"
onChange={ this.onScopeChange }/>
<label htmlFor={`${name}-checkbox`}>
<label htmlFor={`${name}-checkbox-${this.state.name}`}>
<span className="item"></span>
<div className="text">
<p className="name">{name}</p>
+10 -5
View File
@@ -5,14 +5,18 @@ import Collapse from "react-collapse"
export default class Errors extends React.Component {
static propTypes = {
jumpToLine: PropTypes.func,
editorActions: PropTypes.object,
errSelectors: PropTypes.object.isRequired,
layoutSelectors: PropTypes.object.isRequired,
layoutActions: PropTypes.object.isRequired
}
render() {
let { jumpToLine, errSelectors, layoutSelectors, layoutActions } = this.props
let { editorActions, errSelectors, layoutSelectors, layoutActions } = this.props
if(editorActions && editorActions.jumpToLine) {
var jumpToLine = editorActions.jumpToLine
}
let errors = errSelectors.allErrors()
@@ -37,10 +41,11 @@ export default class Errors extends React.Component {
<Collapse isOpened={ isVisible } animated >
<div className="errors">
{ sortedJSErrors.map((err, i) => {
if(err.get("type") === "thrown") {
let type = err.get("type")
if(type === "thrown" || type === "auth") {
return <ThrownErrorItem key={ i } error={ err.get("error") || err } jumpToLine={jumpToLine} />
}
if(err.get("type") === "spec") {
if(type === "spec") {
return <SpecErrorItem key={ i } error={ err } jumpToLine={jumpToLine} />
}
}) }
@@ -95,7 +100,7 @@ const SpecErrorItem = ( { error, jumpToLine } ) => {
<div>
<h4>{ toTitleCase(error.get("source")) + " " + error.get("level") }&nbsp;{ locationMessage }</h4>
<span style={{ whiteSpace: "pre-line"}}>{ error.get("message") }</span>
<div>
<div style={{ "text-decoration": "underline", "cursor": "pointer" }}>
{ jumpToLine ? (
<a onClick={jumpToLine.bind(null, error.get("line"))}>Jump to line { error.get("line") }</a>
) : null }
+1 -1
View File
@@ -99,7 +99,7 @@ export default class Info extends React.Component {
</hgroup>
<div className="description">
<Markdown options={{html: true, typographer: true, linkify: true, linkTarget: "_blank"}} source={ description } />
<Markdown source={ description } />
</div>
{
+3 -6
View File
@@ -1,13 +1,10 @@
import React, { PropTypes } from "react"
import OriCollapse from "react-collapse"
import _Markdown from "react-remarkable"
function xclass(...args) {
return args.filter(a => !!a).join(" ").trim()
}
export const Markdown = _Markdown
export class Container extends React.Component {
render() {
let { fullscreen, full, ...rest } = this.props
@@ -16,7 +13,7 @@ export class Container extends React.Component {
if(fullscreen)
return <section {...rest}/>
let containerClass = "container" + (full ? "-full" : "")
let containerClass = "swagger-container" + (full ? "-full" : "")
return (
<section {...rest} className={xclass(rest.className, containerClass)}/>
)
@@ -73,7 +70,7 @@ export class Col extends React.Component {
}
}
let classes = xclass(rest.className, "clear", ...classesAr)
let classes = xclass(rest.className, ...classesAr)
return (
<section {...rest} style={{display: hide ? "none": null}} className={classes}/>
@@ -127,7 +124,7 @@ export const Input = (props) => <input {...props} />
export class Select extends React.Component {
static propTypes = {
allowedValues: PropTypes.object,
allowedValues: PropTypes.array,
value: PropTypes.any,
onChange: PropTypes.func,
multiple: PropTypes.bool,
+5 -3
View File
@@ -6,13 +6,15 @@ export default class Models extends Component {
getComponent: PropTypes.func,
specSelectors: PropTypes.object,
layoutSelectors: PropTypes.object,
layoutActions: PropTypes.object
layoutActions: PropTypes.object,
getConfigs: PropTypes.func.isRequired
}
render(){
let { specSelectors, getComponent, layoutSelectors, layoutActions } = this.props
let { specSelectors, getComponent, layoutSelectors, layoutActions, getConfigs } = this.props
let definitions = specSelectors.definitions()
let showModels = layoutSelectors.isShown("models", true)
let { docExpansion } = getConfigs()
let showModels = layoutSelectors.isShown("models", docExpansion === "full" || docExpansion === "list" )
const Model = getComponent("model")
const Collapse = getComponent("Collapse")
+14 -4
View File
@@ -17,6 +17,8 @@ export default class Operation extends React.Component {
allowTryItOut: PropTypes.bool,
displayOperationId: PropTypes.bool,
response: PropTypes.object,
request: PropTypes.object,
@@ -27,13 +29,15 @@ export default class Operation extends React.Component {
specSelectors: PropTypes.object.isRequired,
layoutActions: PropTypes.object.isRequired,
layoutSelectors: PropTypes.object.isRequired,
fn: PropTypes.object.isRequired
fn: PropTypes.object.isRequired,
getConfigs: PropTypes.func.isRequired
}
static defaultProps = {
showSummary: true,
response: null,
allowTryItOut: true,
displayOperationId: false,
}
constructor(props, context) {
@@ -76,8 +80,10 @@ export default class Operation extends React.Component {
}
isShown =() => {
let { layoutSelectors, isShownKey } = this.props
return layoutSelectors.isShown(isShownKey, false ) // Here is where we set the default
let { layoutSelectors, isShownKey, getConfigs } = this.props
let { docExpansion } = getConfigs()
return layoutSelectors.isShown(isShownKey, docExpansion === "full" ) // Here is where we set the default
}
onTryoutClick =() => {
@@ -105,6 +111,7 @@ export default class Operation extends React.Component {
response,
request,
allowTryItOut,
displayOperationId,
fn,
getComponent,
@@ -123,6 +130,7 @@ export default class Operation extends React.Component {
let produces = operation.get("produces")
let schemes = operation.get("schemes")
let parameters = getList(operation, ["parameters"])
let operationId = operation.get("__originalOperationId")
const Responses = getComponent("responses")
const Parameters = getComponent( "parameters" )
@@ -159,6 +167,8 @@ export default class Operation extends React.Component {
</div>
}
{ displayOperationId && operationId ? <span className="opblock-summary-operation-id">{operationId}</span> : null }
{
(!security || !security.count()) ? null :
<AuthorizeOperationBtn authActions={ authActions }
@@ -173,7 +183,7 @@ export default class Operation extends React.Component {
{ description &&
<div className="opblock-description-wrapper">
<div className="opblock-description">
<Markdown options={{html: true, typographer: true, linkify: true, linkTarget: "_blank"}} source={ description } />
<Markdown source={ description } />
</div>
</div>
}
+10 -9
View File
@@ -10,10 +10,7 @@ export default class Operations extends React.Component {
layoutActions: PropTypes.object.isRequired,
authActions: PropTypes.object.isRequired,
authSelectors: PropTypes.object.isRequired,
};
static defaultProps = {
getConfigs: PropTypes.func.isRequired
};
render() {
@@ -25,6 +22,7 @@ export default class Operations extends React.Component {
layoutActions,
authActions,
authSelectors,
getConfigs,
fn
} = this.props
@@ -34,6 +32,7 @@ export default class Operations extends React.Component {
const Collapse = getComponent("Collapse")
let showSummary = layoutSelectors.showSummary()
let { docExpansion, displayOperationId } = getConfigs()
return (
<div>
@@ -43,16 +42,15 @@ export default class Operations extends React.Component {
let tagDescription = tagObj.getIn(["tagDetails", "description"], null)
let isShownKey = ["operations-tag", tag]
let showTag = layoutSelectors.isShown(isShownKey, true)
let showTag = layoutSelectors.isShown(isShownKey, docExpansion === "full" || docExpansion === "list")
return (
<div className={showTag ? "opblock-tag-section is-open" : "opblock-tag-section"} key={"operation-" + tag}>
<h4 className={!tagDescription ? "opblock-tag no-desc" : "opblock-tag" }>
<span onClick={() => layoutActions.show(isShownKey, !showTag)}>{tag}</span>
<h4 onClick={() => layoutActions.show(isShownKey, !showTag)} className={!tagDescription ? "opblock-tag no-desc" : "opblock-tag" }>
<span>{tag}</span>
{ !tagDescription ? null :
<small onClick={() => layoutActions.show(isShownKey, !showTag)} >
<small>
{ tagDescription }
</small>
}
@@ -88,6 +86,8 @@ export default class Operations extends React.Component {
request={ request }
allowTryItOut={allowTryItOut}
displayOperationId={displayOperationId}
specActions={ specActions }
specSelectors={ specSelectors }
@@ -99,6 +99,7 @@ export default class Operations extends React.Component {
getComponent={ getComponent }
fn={fn}
getConfigs={ getConfigs }
/>
}).toArray()
}
+18 -5
View File
@@ -28,11 +28,25 @@ export default class ParameterRow extends Component {
componentWillReceiveProps(props) {
let { specSelectors, pathMethod, param } = props
let example = param.get("example")
let defaultValue = param.get("default")
let parameter = specSelectors.getParameter(pathMethod, param.get("name"))
let value = parameter ? parameter.get("value") : ""
if ( defaultValue !== undefined && value === undefined ) {
this.onChangeWrapper(defaultValue)
let paramValue = parameter ? parameter.get("value") : undefined
let enumValue = parameter ? parameter.get("enum") : undefined
let value
if ( paramValue !== undefined ) {
value = paramValue
} else if ( example !== undefined ) {
value = example
} else if ( defaultValue !== undefined) {
value = defaultValue
} else if ( param.get("required") && enumValue && enumValue.size ) {
value = enumValue.first()
}
if ( value !== undefined ) {
this.onChangeWrapper(value)
}
}
@@ -85,8 +99,7 @@ export default class ParameterRow extends Component {
</td>
<td className="col parameters-col_description">
<Markdown options={{html: true, typographer: true, linkify: true, linkTarget: "_blank"}}
source={ param.get("description") }/>
<Markdown source={ param.get("description") }/>
{(isFormData && !isFormDataSupported) && <div>Error: your browser does not support FormData</div>}
{ bodyParam || !isExecute ? null
+6
View File
@@ -0,0 +1,6 @@
# Providers
Providers are generic bridges to third-party components. They provide two benefits:
1. ability for plugins to override third-party components, because providers are loaded through `getComponent`
2. allows us to avoid painting ourselves into a corner with a third-party component
@@ -0,0 +1,24 @@
import React, { PropTypes } from "react"
import Remarkable from "react-remarkable"
import sanitize from "sanitize-html"
const sanitizeOptions = {
textFilter: function(text) {
return text
.replace(/&quot;/g, "\"")
}
}
function Markdown({ source }) {
const sanitized = sanitize(source, sanitizeOptions)
return <Remarkable
options={{html: true, typographer: true, linkify: true, linkTarget: "_blank"}}
source={sanitized}
></Remarkable>
}
Markdown.propTypes = {
source: PropTypes.string.isRequired
}
export default Markdown
+1 -1
View File
@@ -76,7 +76,7 @@ export default class Response extends React.Component {
<td className="col response-col_description">
<div className="response-col_description__inner">
<Markdown options={{html: true, typographer: true, linkify: true, linkTarget: "_blank"}} source={ response.get( "description" ) } />
<Markdown source={ response.get( "description" ) } />
</div>
{ example ? (
+20 -6
View File
@@ -1,22 +1,34 @@
import deepExtend from "deep-extend"
import System from "core/system"
import win from "core/window"
import ApisPreset from "core/presets/apis"
import * as AllPlugins from "core/plugins/all"
import { filterConfigs } from "plugins/configs"
import { parseSeach } from "core/utils"
import { parseSeach, filterConfigs } from "core/utils"
const CONFIGS = [ "url", "spec", "validatorUrl", "onComplete", "onFailure", "authorizations", "docExpansion",
"apisSorter", "operationsSorter", "supportedSubmitMethods", "dom_id", "defaultModelRendering", "oauth2RedirectUrl",
"showRequestHeaders", "custom", "modelPropertyMacro", "parameterMacro", "displayOperationId" ]
// eslint-disable-next-line no-undef
const { GIT_DIRTY, GIT_COMMIT, PACKAGE_VERSION } = buildInfo
module.exports = function SwaggerUI(opts) {
win.versions = win.versions || {}
win.versions.swaggerUi = `${PACKAGE_VERSION}/${GIT_COMMIT || "unknown"}${GIT_DIRTY ? "-dirty" : ""}`
const defaults = {
// Some general settings, that we floated to the top
dom_id: null,
spec: {},
url: "",
layout: "BaseLayout",
docExpansion: "list",
validatorUrl: "https://online.swagger.io/validator",
configs: {
},
configs: {},
custom: {},
displayOperationId: false,
// Initial set of plugins ( TODO rename this, or refactor - we don't need presets _and_ plugins. Its just there for performance.
// Instead, we can compile the first plugin ( it can be a collection of plugins ), then batch the rest.
@@ -68,14 +80,16 @@ module.exports = function SwaggerUI(opts) {
var system = store.getSystem()
let queryConfig = parseSeach()
system.initOAuth = system.authActions.configureAuth
const downloadSpec = (fetchedConfig) => {
if(typeof constructorConfig !== "object") {
return system
}
let localConfig = system.specSelectors.getLocalConfig ? system.specSelectors.getLocalConfig() : {}
let mergedConfig = deepExtend({}, constructorConfig, localConfig, fetchedConfig || {}, queryConfig)
store.setConfigs(filterConfigs(mergedConfig))
let mergedConfig = deepExtend({}, localConfig, constructorConfig, fetchedConfig || {}, queryConfig)
store.setConfigs(filterConfigs(mergedConfig, CONFIGS))
if (fetchedConfig !== null) {
if (!queryConfig.url && typeof mergedConfig.spec === "object" && Object.keys(mergedConfig.spec).length) {
+1 -1
View File
@@ -69,7 +69,7 @@ export class JsonSchema_string extends Component {
return <Input type="file" className={ errors.length ? "invalid" : ""} onChange={ this.onChange } disabled={isDisabled}/>
}
else {
return <Input type="text" className={ errors.length ? "invalid" : ""} value={value} placeholder={description} onChange={ this.onChange } disabled={isDisabled}/>
return <Input type={ schema.format === "password" ? "password" : "text" } className={ errors.length ? "invalid" : ""} value={value} placeholder={description} onChange={ this.onChange } disabled={isDisabled}/>
}
}
}
+50 -23
View File
@@ -1,27 +1,37 @@
import win from "core/window"
import { btoa } from "core/utils"
export default function authorize ( auth, authActions, errActions, configs ) {
export default function authorize ( { auth, authActions, errActions, configs, authConfigs={} } ) {
let { schema, scopes, name, clientId } = auth
let flow = schema.get("flow")
let query = []
switch (flow) {
case "password":
authActions.authorizePassword(auth)
return
case "application":
authActions.authorizeApplication(auth)
return
case "accessCode":
query.push("response_type=code")
break
case "implicit":
query.push("response_type=token")
break
}
if (typeof clientId === "string") {
query.push("client_id=" + encodeURIComponent(clientId))
}
let redirectUrl = configs.oauth2RedirectUrl
let scopeSeparator = " "
let state = btoa(new Date())
let flow = schema.get("flow")
let url
if (flow === "password") {
authActions.authorizePassword(auth)
return
}
if (flow === "application") {
authActions.authorizeOauth2Application(auth)
return
}
// todo move to parser
if ( !redirectUrl ) {
if (typeof redirectUrl === "undefined") {
errActions.newAuthErr( {
authId: name,
source: "validation",
@@ -30,22 +40,39 @@ export default function authorize ( auth, authActions, errActions, configs ) {
})
return
}
query.push("redirect_uri=" + encodeURIComponent(redirectUrl))
if (flow === "implicit" || flow === "accessCode") {
url = schema.get("authorizationUrl") + "?response_type=" + (flow === "implicit" ? "token" : "code")
if (Array.isArray(scopes) && 0 < scopes.length) {
let scopeSeparator = authConfigs.scopeSeparator || " "
query.push("scope=" + encodeURIComponent(scopes.join(scopeSeparator)))
}
url += "&redirect_uri=" + encodeURIComponent(redirectUrl)
+ "&scope=" + encodeURIComponent(scopes.join(scopeSeparator))
+ "&state=" + encodeURIComponent(state)
+ "&client_id=" + encodeURIComponent(clientId)
let state = btoa(new Date())
query.push("state=" + encodeURIComponent(state))
if (typeof authConfigs.realm !== "undefined") {
query.push("realm=" + encodeURIComponent(authConfigs.realm))
}
let { additionalQueryStringParams } = authConfigs
for (let key in additionalQueryStringParams) {
if (typeof additionalQueryStringParams[key] !== "undefined") {
query.push([key, additionalQueryStringParams[key]].map(encodeURIComponent).join("="))
}
}
let url = [schema.get("authorizationUrl"), query.join("&")].join("?")
// pass action authorizeOauth2 and authentication data through window
// to authorize with oauth2
win.swaggerUIRedirectOauth2 = {
auth: auth,
state: state,
callback: authActions.preAuthorizeOauth2,
redirectUrl: redirectUrl,
callback: flow === "implicit" ? authActions.preAuthorizeImplicit : authActions.authorizeAccessCode,
errCb: errActions.newAuthErr
}
+103 -64
View File
@@ -1,5 +1,5 @@
import win from "core/window"
import { btoa } from "core/utils"
import { btoa, buildFormData } from "core/utils"
export const SHOW_AUTH_POPUP = "show_popup"
export const AUTHORIZE = "authorize"
@@ -7,6 +7,7 @@ export const LOGOUT = "logout"
export const PRE_AUTHORIZE_OAUTH2 = "pre_authorize_oauth2"
export const AUTHORIZE_OAUTH2 = "authorize_oauth2"
export const VALIDATE = "validate"
export const CONFIGURE_AUTH = "configure_auth"
const scopeSeparator = " "
@@ -31,7 +32,7 @@ export function logout(payload) {
}
}
export const preAuthorizeOauth2 = (payload) => ( { authActions, errActions } ) => {
export const preAuthorizeImplicit = (payload) => ( { authActions, errActions } ) => {
let { auth , token, isValid } = payload
let { schema, name } = auth
let flow = schema.get("flow")
@@ -68,72 +69,88 @@ export function authorizeOauth2(payload) {
}
}
export const authorizePassword = ( auth ) => ( { fn, authActions, errActions } ) => {
export const authorizePassword = ( auth ) => ( { authActions } ) => {
let { schema, name, username, password, passwordType, clientId, clientSecret } = auth
let req = {
url: schema.get("tokenUrl"),
method: "post",
headers: {
"content-type": "application/x-www-form-urlencoded"
},
query: {
grant_type: "password",
username,
password,
scopes: encodeURIComponent(auth.scopes.join(scopeSeparator))
let form = {
grant_type: "password",
scopes: encodeURIComponent(auth.scopes.join(scopeSeparator))
}
let query = {}
let headers = {}
if ( passwordType === "basic") {
headers.Authorization = "Basic " + btoa(username + ":" + password)
} else {
Object.assign(form, {username}, {password})
if ( passwordType === "query") {
if ( clientId ) {
query.client_id = clientId
}
if ( clientSecret ) {
query.client_secret = clientSecret
}
} else {
headers.Authorization = "Basic " + btoa(clientId + ":" + clientSecret)
}
}
if ( passwordType === "basic") {
req.headers.authorization = "Basic " + btoa(clientId + ":" + clientSecret)
} else if ( passwordType === "request") {
req.query = Object.assign(req.query, { client_id: clientId, client_secret: clientSecret })
}
return fn.fetch(req)
.then(( response ) => {
let token = JSON.parse(response.data)
let error = token && ( token.error || "" )
let parseError = token && ( token.parseError || "" )
if ( !response.ok ) {
errActions.newAuthErr( {
authId: name,
level: "error",
source: "auth",
message: response.statusText
} )
return
}
if ( error || parseError ) {
errActions.newAuthErr({
authId: name,
level: "error",
source: "auth",
message: JSON.stringify(token)
})
return
}
authActions.authorizeOauth2({ auth, token })
})
.catch(err => { errActions.newAuthErr( err ) })
return authActions.authorizeRequest({ body: buildFormData(form), url: schema.get("tokenUrl"), name, headers, query, auth})
}
export const authorizeOauth2Application = ( auth ) => ( { fn, authActions, errActions } ) => {
export const authorizeApplication = ( auth ) => ( { authActions } ) => {
let { schema, scopes, name, clientId, clientSecret } = auth
let headers = {
Authorization: "Basic " + btoa(clientId + ":" + clientSecret)
}
let form = {
grant_type: "client_credentials",
scope: scopes.join(scopeSeparator)
}
fn.fetch(schema.get("tokenUrl"), {
method: "post", headers: {
"Accept":"application/json, text/plain, */*",
"Content-Type": "application/x-www-form-urlencoded"
},
body: "grant_type=client_credentials" +
"&client_id=" + encodeURIComponent(clientId) +
"&client_secret=" + encodeURIComponent(clientSecret) +
"&scope=" + encodeURIComponent(scopes.join(scopeSeparator))
return authActions.authorizeRequest({body: buildFormData(form), name, url: schema.get("tokenUrl"), auth, headers })
}
export const authorizeAccessCode = ( { auth, redirectUrl } ) => ( { authActions } ) => {
let { schema, name, clientId, clientSecret } = auth
let form = {
grant_type: "authorization_code",
code: auth.code,
client_id: clientId,
client_secret: clientSecret,
redirect_uri: redirectUrl
}
return authActions.authorizeRequest({body: buildFormData(form), name, url: schema.get("tokenUrl"), auth})
}
export const authorizeRequest = ( data ) => ( { fn, authActions, errActions, authSelectors } ) => {
let { body, query={}, headers={}, name, url, auth } = data
let { additionalQueryStringParams } = authSelectors.getConfigs() || {}
let fetchUrl = url
for (let key in additionalQueryStringParams) {
url += "&" + key + "=" + encodeURIComponent(additionalQueryStringParams[key])
}
let _headers = Object.assign({
"Accept":"application/json, text/plain, */*",
"Access-Control-Allow-Origin": "*",
"Content-Type": "application/x-www-form-urlencoded"
}, headers)
fn.fetch({
url: fetchUrl,
method: "post",
headers: _headers,
query: query,
body: body
})
.then(function (response) {
let token = JSON.parse(response.data)
let error = token && ( token.error || "" )
let parseError = token && ( token.parseError || "" )
if ( !response.ok ) {
errActions.newAuthErr( {
authId: name,
@@ -142,12 +159,34 @@ export const authorizeOauth2Application = ( auth ) => ( { fn, authActions, errAc
message: response.statusText
} )
return
} else {
response.json()
.then(function (json){
authActions.authorizeOauth2({ auth, token: json})
})
}
if ( error || parseError ) {
errActions.newAuthErr({
authId: name,
level: "error",
source: "auth",
message: JSON.stringify(token)
})
return
}
authActions.authorizeOauth2({ auth, token})
})
.catch(e => {
let err = new Error(e)
errActions.newAuthErr( {
authId: name,
level: "error",
source: "auth",
message: err.message
} )
})
.catch(err => { errActions.newAuthErr( err ) })
}
export function configureAuth(payload) {
return {
type: CONFIGURE_AUTH,
payload: payload
}
}
+6 -1
View File
@@ -5,7 +5,8 @@ import {
SHOW_AUTH_POPUP,
AUTHORIZE,
AUTHORIZE_OAUTH2,
LOGOUT
LOGOUT,
CONFIGURE_AUTH
} from "./actions"
export default {
@@ -57,5 +58,9 @@ export default {
})
return state.set("authorized", result)
},
[CONFIGURE_AUTH]: (state, { payload } ) =>{
return state.set("configs", payload)
}
}
+5
View File
@@ -79,3 +79,8 @@ export const isAuthorized = ( state, securities ) =>( { authSelectors } ) => {
}).indexOf(false) === -1
}).length
}
export const getConfigs = createSelector(
state,
auth => auth.get( "configs" )
)
+15 -6
View File
@@ -77,7 +77,9 @@ export const parseToJson = (str) => ({specActions, specSelectors, errActions}) =
return specActions.updateJsonSpec(json)
}
export const resolveSpec = (json, url) => ({specActions, specSelectors, errActions, fn: { fetch, resolve, AST }}) => {
export const resolveSpec = (json, url) => ({specActions, specSelectors, errActions, fn: { fetch, resolve, AST }, getConfigs}) => {
const { modelPropertyMacro, parameterMacro } = getConfigs()
if(typeof(json) === "undefined") {
json = specSelectors.specJson()
}
@@ -89,7 +91,7 @@ export const resolveSpec = (json, url) => ({specActions, specSelectors, errActio
let specStr = specSelectors.specStr()
return resolve({fetch, spec: json, baseDoc: url})
return resolve({fetch, spec: json, baseDoc: url, modelPropertyMacro, parameterMacro })
.then( ({spec, errors}) => {
errActions.clear({
type: "thrown"
@@ -186,16 +188,23 @@ export const logRequest = (req) => {
// Actually fire the request via fn.execute
// (For debugging) and ease of testing
export const executeRequest = (req) => ({fn, specActions, specSelectors}) => {
let { pathName, method } = req
let { pathName, method, operation } = req
let op = operation.toJS()
// if url is relative, parseUrl makes it absolute by inferring from `window.location`
req.contextUrl = parseUrl(specSelectors.url()).toString()
let parsedRequest = Object.assign({}, req)
if ( pathName && method ) {
parsedRequest.operationId = method.toLowerCase() + "-" + pathName
if(op && op.operationId) {
req.operationId = op.operationId
} else if(op && pathName && method) {
req.operationId = fn.opId(op, pathName, method)
}
let parsedRequest = Object.assign({}, req)
parsedRequest = fn.buildRequest(parsedRequest)
specActions.setRequest(req.pathName, req.method, parsedRequest)
return fn.execute(req)
-2
View File
@@ -43,8 +43,6 @@ export const specResolved = createSelector(
// Default Spec ( as an object )
export const spec = state => {
let res = specResolved(state)
if(res.count() < 1)
res = specJson(state)
return res
}
+2 -1
View File
@@ -7,7 +7,8 @@ module.exports = function({ configs }) {
buildRequest: Swagger.buildRequest,
execute: Swagger.execute,
resolve: Swagger.resolve,
serializeRes: Swagger.serializeRes
serializeRes: Swagger.serializeRes,
opId: Swagger.helpers.opId
}
}
}
+3
View File
@@ -46,6 +46,8 @@ import Model from "core/components/model"
import Models from "core/components/models"
import TryItOutButton from "core/components/try-it-out-button"
import Markdown from "core/components/providers/markdown"
import BaseLayout from "core/components/layouts/base"
import * as LayoutUtils from "core/components/layout-utils"
@@ -89,6 +91,7 @@ export default function() {
model: Model,
models: Models,
TryItOutButton,
Markdown,
BaseLayout
}
}
+3 -4
View File
@@ -2,7 +2,6 @@ import { createStore, applyMiddleware, bindActionCreators, compose } from "redux
import Im, { fromJS, Map } from "immutable"
import deepExtend from "deep-extend"
import { combineReducers } from "redux-immutable"
import assign from "object-assign"
import serializeError from "serialize-error"
import { NEW_THROWN_ERR } from "corePlugins/err/actions"
import win from "core/window"
@@ -74,7 +73,7 @@ export default class Store {
let dispatch = this.getStore().dispatch
let getState = this.getStore().getState
this.boundSystem = assign({},
this.boundSystem = Object.assign({},
this.getRootInjects(),
this.getWrappedAndBoundActions(dispatch),
this.getBoundSelectors(getState, this.getSystem),
@@ -92,7 +91,7 @@ export default class Store {
}
getRootInjects() {
return assign({
return Object.assign({
getSystem: this.getSystem,
getStore: this.getStore.bind(this),
getComponents: this.getComponents.bind(this),
@@ -251,7 +250,7 @@ export default class Store {
getMapStateToProps() {
return () => {
let obj = assign({}, this.getSystem())
let obj = Object.assign({}, this.getSystem())
return obj
}
}
+25 -2
View File
@@ -1,5 +1,4 @@
import Im from "immutable"
import assign from "object-assign"
import shallowEqual from "shallowequal"
import camelCase from "lodash/camelCase"
@@ -85,7 +84,7 @@ export function objReduce(obj, fn) {
return Object.keys(obj).reduce((newObj, key) => {
let res = fn(obj[key], key)
if(res && typeof res === "object")
assign(newObj, res)
Object.assign(newObj, res)
return newObj
}, {})
}
@@ -566,3 +565,27 @@ export const sorters = {
method: (a, b) => a.get("method").localeCompare(b.get("method"))
}
}
export const buildFormData = (data) => {
let formArr = []
for (let name in data) {
let val = data[name]
if (val !== undefined && val !== "") {
formArr.push([name, "=", encodeURIComponent(val).replace(/%20/g,"+")].join(""))
}
}
return formArr.join("&")
}
export const filterConfigs = (configs, allowed) => {
let i, filteredConfigs = {}
for (i in configs) {
if (allowed.indexOf(i) !== -1) {
filteredConfigs[i] = configs[i]
}
}
return filteredConfigs
}
-17
View File
@@ -1,10 +1,6 @@
import YAML from "js-yaml"
import yamlConfig from "../../../swagger-config.yaml"
const CONFIGS = [ "url", "spec", "validatorUrl", "onComplete", "onFailure", "authorizations", "docExpansion",
"apisSorter", "operationsSorter", "supportedSubmitMethods", "highlightSizeThreshold", "dom_id",
"defaultModelRendering", "oauth2RedirectUrl", "showRequestHeaders" ]
const parseYamlConfig = (yaml, system) => {
try {
return YAML.safeLoad(yaml)
@@ -58,16 +54,3 @@ export default function configPlugin (toolbox) {
}
}
}
export function filterConfigs (configs) {
let i, filteredConfigs = {}
for (i in configs) {
if (CONFIGS.indexOf(i) !== -1) {
filteredConfigs[i] = configs[i]
}
}
return filteredConfigs
}
+4 -3
View File
@@ -19,9 +19,10 @@ export default class Topbar extends React.Component {
this.setState({url: value})
}
downloadUrl = () => {
downloadUrl = (e) => {
this.props.specActions.updateUrl(this.state.url)
this.props.specActions.download(this.state.url)
e.preventDefault()
}
render() {
@@ -43,10 +44,10 @@ export default class Topbar extends React.Component {
<img height="30" width="30" src={ Logo } alt="Swagger UX"/>
<span>swagger</span>
</Link>
<div className="download-url-wrapper">
<form className="download-url-wrapper" onSubmit={this.downloadUrl}>
<input className="download-url-input" type="text" onChange={ this.onUrlChange } value={this.state.url} disabled={isLoading} style={inputStyle} />
<Button className="download-url-button" onClick={ this.downloadUrl }>Explore</Button>
</div>
</form>
</div>
</div>
</div>
+2
View File
@@ -2,11 +2,13 @@ import StandaloneLayout from "./layout"
import "../style/main.scss"
import TopbarPlugin from "plugins/topbar"
import ConfigsPlugin from "plugins/configs"
// the Standalone preset
let preset = [
TopbarPlugin,
ConfigsPlugin,
() => {
return {
components: { StandaloneLayout }
+2 -2
View File
@@ -58,7 +58,7 @@
&.execute
{
animation: pulse 2s infinite;
animation: swagger-ui-pulse 2s infinite;
color: #fff;
border-color: #4990e2;
@@ -66,7 +66,7 @@
}
@keyframes pulse
@keyframes swagger-ui-pulse
{
0%
{
+6 -1
View File
@@ -13,13 +13,18 @@
font-size: 12px;
}
}
p
p, li, table
{
font-size: 14px;
@include text_body();
}
h1, h2, h3, h4, h5
{
@include text_body();
}
code
{
padding: 3px 5px;
+18
View File
@@ -209,6 +209,7 @@ body
}
.opblock-summary-path,
.opblock-summary-operation-id,
.opblock-summary-path__deprecated
{
font-size: 16px;
@@ -247,6 +248,11 @@ body
text-decoration: line-through;
}
.opblock-summary-operation-id
{
font-size: 14px;
}
.opblock-summary-description
{
font-size: 13px;
@@ -492,16 +498,28 @@ body
margin: 0;
padding: 10px;
word-wrap: break-word;
word-break: break-all;
word-break: break-word;
hyphens: auto;
white-space: pre-wrap;
border-radius: 4px;
background: #41444e;
overflow-wrap: break-word;
@include text_code(#fff);
span
{
color: #fff !important;
}
.headerline
{
display: block;
}
}
.scheme-container
+5
View File
@@ -16,6 +16,8 @@
display: flex;
max-width: 300px;
text-decoration: none;
flex: 1;
@@ -33,8 +35,11 @@
{
display: flex;
flex: 3;
input[type=text]
{
width: 100%;
min-width: 350px;
margin: 0;
+6 -1
View File
@@ -1,3 +1,8 @@
This directory is used to build the `swagger-ui-dist` npm package.
This module, `swagger-ui-dist`, exposes Swagger-UI's entire dist folder as a dependency-free npm module. Use `swagger-ui` instead, if you'd like to have npm install dependencies for you.
`SwaggerUIBundle` and `SwaggerUIStandalonePreset` can be imported:
```javascript
import { SwaggerUIBundle, SwaggerUIStandalonePreset } from 'swagger-ui-dist'
```
For anything else, check the [Swagger-UI](https://github.com/swagger-api/swagger-ui) repository.
+1 -1
View File
@@ -18,4 +18,4 @@ else
npm pack .
fi
find . -not -name .npmignore -not -name .npmrc -not -name deploy.sh -not -name package.json -not -name README.md -not -name *.tgz -delete
find . -not -name .npmignore -not -name .npmrc -not -name deploy.sh -not -name index.js -not -name package.json -not -name README.md -not -name *.tgz -delete
+2
View File
@@ -0,0 +1,2 @@
module.exports.SwaggerUIBundle = require('./swagger-ui-bundle.js')
module.exports.SwaggerUIStandalonePreset = require('./swagger-ui-standalone-preset.js')
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "swagger-ui-dist",
"version": "$$VERSION",
"main": "dist/swagger-ui.js",
"main": "index.js",
"repository": "git@github.com:swagger-api/swagger-ui.git",
"contributors": [
"(in alphabetical order)",
+23
View File
@@ -0,0 +1,23 @@
/* eslint-env mocha */
import React from "react"
import expect from "expect"
import { render } from "enzyme"
import Markdown from "components/providers/markdown"
describe("UI-3199: Sanitized Markdown causing code examples to be double escaped", function(){
it("should single-escape quotes", function(){
let str = "" +
"This is a test: \n\n" +
" {\"abc\": \"def\"}\n"
let props = {
source: str
}
let el = render(<Markdown {...props}/>)
expect(el.find("code").first().text()).toEqual("{\"abc\": \"def\"}\n")
expect(el.find("code").first().html()).toEqual("{&quot;abc&quot;: &quot;def&quot;}\n")
})
})
+4 -1
View File
@@ -22,7 +22,10 @@ module.exports = require('./make-webpack-config.js')({
},
externals: function(context, request, cb) {
if(node_modules.indexOf(request) !== -1) {
// webpack injects some stuff into the resulting file,
// these libs need to be pulled in to keep that working.
var exceptionsForWebpack = ["ieee754", "base64-js"]
if(node_modules.indexOf(request) !== -1 || exceptionsForWebpack.indexOf(request) !== -1) {
cb(null, 'commonjs ' + request)
return;
}
+4 -2
View File
@@ -10,11 +10,13 @@ module.exports = require("./make-webpack-config")({
devtool: "eval",
entry: {
'swagger-ui-bundle': [
'webpack/hot/dev-server',
'babel-polyfill',
'./src/core/index.js'
'./src/core/index.js',
],
'swagger-ui-standalone-preset': [
'./src/standalone/index.js'
'webpack/hot/dev-server',
'./src/standalone/index.js',
]
},
output: {