feat: expose plugins and presets on SwaggerUI global symbol (#9189)
Part of this commit is also: - complete plugins consolidation - complete presets consolidation - build system consolidation Refs #9188
This commit is contained in:
@@ -1,24 +0,0 @@
|
||||
import { pascalCaseFilename } from "core/utils"
|
||||
import SafeRender from "core/plugins/safe-render"
|
||||
|
||||
const request = require.context(".", true, /\.jsx?$/)
|
||||
|
||||
const allPlugins = {}
|
||||
|
||||
export default allPlugins
|
||||
|
||||
request.keys().forEach( function( key ){
|
||||
if( key === "./index.js" ) {
|
||||
return
|
||||
}
|
||||
|
||||
// if( key.slice(2).indexOf("/") > -1) {
|
||||
// // skip files in subdirs
|
||||
// return
|
||||
// }
|
||||
|
||||
let mod = request(key)
|
||||
allPlugins[pascalCaseFilename(key)] = mod.default ? mod.default : mod
|
||||
})
|
||||
|
||||
allPlugins.SafeRender = SafeRender
|
||||
@@ -1,110 +0,0 @@
|
||||
import { createSelector } from "reselect"
|
||||
import { Map } from "immutable"
|
||||
import win from "../window"
|
||||
|
||||
export default function downloadUrlPlugin (toolbox) {
|
||||
let { fn } = toolbox
|
||||
|
||||
const actions = {
|
||||
download: (url)=> ({ errActions, specSelectors, specActions, getConfigs }) => {
|
||||
let { fetch } = fn
|
||||
const config = getConfigs()
|
||||
url = url || specSelectors.url()
|
||||
specActions.updateLoadingStatus("loading")
|
||||
errActions.clear({source: "fetch"})
|
||||
fetch({
|
||||
url,
|
||||
loadSpec: true,
|
||||
requestInterceptor: config.requestInterceptor || (a => a),
|
||||
responseInterceptor: config.responseInterceptor || (a => a),
|
||||
credentials: "same-origin",
|
||||
headers: {
|
||||
"Accept": "application/json,*/*"
|
||||
}
|
||||
}).then(next,next)
|
||||
|
||||
function next(res) {
|
||||
if(res instanceof Error || res.status >= 400) {
|
||||
specActions.updateLoadingStatus("failed")
|
||||
errActions.newThrownErr(Object.assign( new Error((res.message || res.statusText) + " " + url), {source: "fetch"}))
|
||||
// Check if the failure was possibly due to CORS or mixed content
|
||||
if (!res.status && res instanceof Error) checkPossibleFailReasons()
|
||||
return
|
||||
}
|
||||
specActions.updateLoadingStatus("success")
|
||||
specActions.updateSpec(res.text)
|
||||
if(specSelectors.url() !== url) {
|
||||
specActions.updateUrl(url)
|
||||
}
|
||||
}
|
||||
|
||||
function checkPossibleFailReasons() {
|
||||
try {
|
||||
let specUrl
|
||||
|
||||
if("URL" in win ) {
|
||||
specUrl = new URL(url)
|
||||
} else {
|
||||
// legacy browser, use <a href> to parse the URL
|
||||
specUrl = document.createElement("a")
|
||||
specUrl.href = url
|
||||
}
|
||||
|
||||
if(specUrl.protocol !== "https:" && win.location.protocol === "https:") {
|
||||
const error = Object.assign(
|
||||
new Error(`Possible mixed-content issue? The page was loaded over https:// but a ${specUrl.protocol}// URL was specified. Check that you are not attempting to load mixed content.`),
|
||||
{source: "fetch"}
|
||||
)
|
||||
errActions.newThrownErr(error)
|
||||
return
|
||||
}
|
||||
if(specUrl.origin !== win.location.origin) {
|
||||
const error = Object.assign(
|
||||
new Error(`Possible cross-origin (CORS) issue? The URL origin (${specUrl.origin}) does not match the page (${win.location.origin}). Check the server returns the correct 'Access-Control-Allow-*' headers.`),
|
||||
{source: "fetch"}
|
||||
)
|
||||
errActions.newThrownErr(error)
|
||||
}
|
||||
} catch (e) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
updateLoadingStatus: (status) => {
|
||||
let enums = [null, "loading", "failed", "success", "failedConfig"]
|
||||
if(enums.indexOf(status) === -1) {
|
||||
console.error(`Error: ${status} is not one of ${JSON.stringify(enums)}`)
|
||||
}
|
||||
|
||||
return {
|
||||
type: "spec_update_loading_status",
|
||||
payload: status
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let reducers = {
|
||||
"spec_update_loading_status": (state, action) => {
|
||||
return (typeof action.payload === "string")
|
||||
? state.set("loadingStatus", action.payload)
|
||||
: state
|
||||
}
|
||||
}
|
||||
|
||||
let selectors = {
|
||||
loadingStatus: createSelector(
|
||||
state => {
|
||||
return state || Map()
|
||||
},
|
||||
spec => spec.get("loadingStatus") || null
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
statePlugins: {
|
||||
spec: { actions, reducers, selectors }
|
||||
}
|
||||
}
|
||||
}
|
||||
126
src/core/plugins/download-url/index.js
Normal file
126
src/core/plugins/download-url/index.js
Normal file
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import { createSelector } from "reselect"
|
||||
import { Map } from "immutable"
|
||||
import win from "core/window"
|
||||
|
||||
export default function downloadUrlPlugin(toolbox) {
|
||||
let { fn } = toolbox
|
||||
|
||||
const actions = {
|
||||
download:
|
||||
(url) =>
|
||||
({ errActions, specSelectors, specActions, getConfigs }) => {
|
||||
let { fetch } = fn
|
||||
const config = getConfigs()
|
||||
url = url || specSelectors.url()
|
||||
specActions.updateLoadingStatus("loading")
|
||||
errActions.clear({ source: "fetch" })
|
||||
fetch({
|
||||
url,
|
||||
loadSpec: true,
|
||||
requestInterceptor: config.requestInterceptor || ((a) => a),
|
||||
responseInterceptor: config.responseInterceptor || ((a) => a),
|
||||
credentials: "same-origin",
|
||||
headers: {
|
||||
Accept: "application/json,*/*",
|
||||
},
|
||||
}).then(next, next)
|
||||
|
||||
function next(res) {
|
||||
if (res instanceof Error || res.status >= 400) {
|
||||
specActions.updateLoadingStatus("failed")
|
||||
errActions.newThrownErr(
|
||||
Object.assign(
|
||||
new Error((res.message || res.statusText) + " " + url),
|
||||
{ source: "fetch" }
|
||||
)
|
||||
)
|
||||
// Check if the failure was possibly due to CORS or mixed content
|
||||
if (!res.status && res instanceof Error) checkPossibleFailReasons()
|
||||
return
|
||||
}
|
||||
specActions.updateLoadingStatus("success")
|
||||
specActions.updateSpec(res.text)
|
||||
if (specSelectors.url() !== url) {
|
||||
specActions.updateUrl(url)
|
||||
}
|
||||
}
|
||||
|
||||
function checkPossibleFailReasons() {
|
||||
try {
|
||||
let specUrl
|
||||
|
||||
if ("URL" in win) {
|
||||
specUrl = new URL(url)
|
||||
} else {
|
||||
// legacy browser, use <a href> to parse the URL
|
||||
specUrl = document.createElement("a")
|
||||
specUrl.href = url
|
||||
}
|
||||
|
||||
if (
|
||||
specUrl.protocol !== "https:" &&
|
||||
win.location.protocol === "https:"
|
||||
) {
|
||||
const error = Object.assign(
|
||||
new Error(
|
||||
`Possible mixed-content issue? The page was loaded over https:// but a ${specUrl.protocol}// URL was specified. Check that you are not attempting to load mixed content.`
|
||||
),
|
||||
{ source: "fetch" }
|
||||
)
|
||||
errActions.newThrownErr(error)
|
||||
return
|
||||
}
|
||||
if (specUrl.origin !== win.location.origin) {
|
||||
const error = Object.assign(
|
||||
new Error(
|
||||
`Possible cross-origin (CORS) issue? The URL origin (${specUrl.origin}) does not match the page (${win.location.origin}). Check the server returns the correct 'Access-Control-Allow-*' headers.`
|
||||
),
|
||||
{ source: "fetch" }
|
||||
)
|
||||
errActions.newThrownErr(error)
|
||||
}
|
||||
} catch (e) {
|
||||
return
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
updateLoadingStatus: (status) => {
|
||||
let enums = [null, "loading", "failed", "success", "failedConfig"]
|
||||
if (enums.indexOf(status) === -1) {
|
||||
console.error(`Error: ${status} is not one of ${JSON.stringify(enums)}`)
|
||||
}
|
||||
|
||||
return {
|
||||
type: "spec_update_loading_status",
|
||||
payload: status,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
let reducers = {
|
||||
spec_update_loading_status: (state, action) => {
|
||||
return typeof action.payload === "string"
|
||||
? state.set("loadingStatus", action.payload)
|
||||
: state
|
||||
},
|
||||
}
|
||||
|
||||
let selectors = {
|
||||
loadingStatus: createSelector(
|
||||
(state) => {
|
||||
return state || Map()
|
||||
},
|
||||
(spec) => spec.get("loadingStatus") || null
|
||||
),
|
||||
}
|
||||
|
||||
return {
|
||||
statePlugins: {
|
||||
spec: { actions, reducers, selectors },
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import isEmpty from "lodash/isEmpty"
|
||||
import isPlainObject from "lodash/isPlainObject"
|
||||
|
||||
import { objectify, normalizeArray } from "core/utils"
|
||||
import memoizeN from "../../../../../helpers/memoizeN"
|
||||
import memoizeN from "core/utils/memoizeN"
|
||||
import typeMap from "./types/index"
|
||||
import { getType } from "./core/type"
|
||||
import { typeCast } from "./core/utils"
|
||||
|
||||
@@ -5,7 +5,7 @@ import { OrderedMap, Map, List } from "immutable"
|
||||
import { createSelector } from "reselect"
|
||||
|
||||
import { getDefaultRequestBodyValue } from "./components/request-body"
|
||||
import { stringify } from "../../utils"
|
||||
import { stringify } from "core/utils"
|
||||
|
||||
// Helpers
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import win from "../../window"
|
||||
import { Map } from "immutable"
|
||||
import win from "../../window"
|
||||
|
||||
|
||||
/**
|
||||
* if duplicate key name existed from FormData entries,
|
||||
|
||||
@@ -2,8 +2,7 @@ import XML from "xml"
|
||||
import RandExp from "randexp"
|
||||
import isEmpty from "lodash/isEmpty"
|
||||
import { objectify, isFunc, normalizeArray, deeplyStripKey } from "core/utils"
|
||||
|
||||
import memoizeN from "../../../../helpers/memoizeN"
|
||||
import memoizeN from "core/utils/memoizeN"
|
||||
|
||||
const generateStringFromRegex = (pattern) => {
|
||||
try {
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import reducers from "./reducers"
|
||||
import * as actions from "./actions"
|
||||
import * as selectors from "./selectors"
|
||||
import * as wrapActions from "./wrap-actions"
|
||||
|
||||
export default function() {
|
||||
return {
|
||||
statePlugins: {
|
||||
spec: {
|
||||
wrapActions,
|
||||
reducers,
|
||||
actions,
|
||||
selectors
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const SpecPlugin = () => ({
|
||||
statePlugins: {
|
||||
spec: {
|
||||
wrapActions: { ...wrapActions },
|
||||
reducers: { ...reducers },
|
||||
actions: { ...actions },
|
||||
selectors: { ...selectors },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export default SpecPlugin
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { fromJS, List } from "immutable"
|
||||
import { fromJSOrdered, validateParam, paramToValue } from "core/utils"
|
||||
import win from "../../window"
|
||||
import { fromJSOrdered, validateParam, paramToValue, paramToIdentifier } from "core/utils"
|
||||
import win from "core/window"
|
||||
|
||||
// selector-in-reducer is suboptimal, but `operationWithMeta` is more of a helper
|
||||
import {
|
||||
@@ -27,7 +27,6 @@ import {
|
||||
CLEAR_VALIDATE_PARAMS,
|
||||
SET_SCHEME
|
||||
} from "./actions"
|
||||
import { paramToIdentifier } from "../../utils"
|
||||
|
||||
export default {
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { createSelector } from "reselect"
|
||||
import { sorters } from "core/utils"
|
||||
import { sorters, paramToIdentifier } from "core/utils"
|
||||
import { fromJS, Set, Map, OrderedMap, List } from "immutable"
|
||||
import { paramToIdentifier } from "../../utils"
|
||||
|
||||
const DEFAULT_TAG = "default"
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { memoize } from "core/utils"
|
||||
|
||||
import memoizeN from "core/utils/memoizeN"
|
||||
import { getComponent, render, withMappedContainer } from "./root-injects"
|
||||
import { getDisplayName } from "./fn"
|
||||
import memoizeN from "../../../helpers/memoizeN"
|
||||
|
||||
const memoizeForGetComponent = (fn) => {
|
||||
const resolver = (...args) => JSON.stringify(args)
|
||||
|
||||
Reference in New Issue
Block a user