it("decode url encoded components", function() { win.location.search = "?foo=foo%20bar" expect(parseSearch()).toEqual({foo: "foo bar"}) })
it("works with keys and values", function() { win.location.search = "?foo=fooval&bar&baz=bazval" expect(parseSearch()).toEqual({foo: "fooval", bar: "", baz: "bazval"}) })
it("works with only one key", function() { win.location.search = "?foo" expect(parseSearch()).toEqual({foo: ""}) })
it("works with empty search", function() { win.location.search = "" expect(parseSearch()).toEqual({}) })
module.exports = function SwaggerUI(opts) { win.versions = win.versions || {} win.versions.swaggerUi = { version: PACKAGE_VERSION, gitRevision: GIT_COMMIT, gitDirty: GIT_DIRTY, buildTimestamp: BUILD_TIME, machine: HOSTNAME } const defaults = { // Some general settings, that we floated to the top dom_id: null, domNode: null, spec: {}, url: "", urls: null, layout: "BaseLayout", docExpansion: "list", maxDisplayedTags: null, filter: null, validatorUrl: "https://online.swagger.io/validator", configs: {}, custom: {}, displayOperationId: false, displayRequestDuration: false, deepLinking: false, requestInterceptor: (a => a), responseInterceptor: (a => a), showMutatedRequest: true, defaultModelRendering: "example", defaultModelExpandDepth: 1, defaultModelsExpandDepth: 1, showExtensions: 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. presets: [ ApisPreset ], // Plugins; ( loaded after presets ) plugins: [ ], // Initial state initialState: { }, // Inline Plugin fn: { }, components: { }, } let queryConfig = parseSearch() const domNode = opts.domNode delete opts.domNode const constructorConfig = deepExtend({}, defaults, opts, queryConfig) const storeConfigs = { system: { configs: constructorConfig.configs }, plugins: constructorConfig.presets, state: deepExtend({ layout: { layout: constructorConfig.layout, filter: constructorConfig.filter }, spec: { spec: "", url: constructorConfig.url } }, constructorConfig.initialState) } if(constructorConfig.initialState) { // if the user sets a key as `undefined`, that signals to us that we // should delete the key entirely. // known usage: Swagger-Editor validate plugin tests for (var key in constructorConfig.initialState) { if( constructorConfig.initialState.hasOwnProperty(key) && constructorConfig.initialState[key] === undefined ) { delete storeConfigs.state[key] } } } let inlinePlugin = ()=> { return { fn: constructorConfig.fn, components: constructorConfig.components, state: constructorConfig.state, } } var store = new System(storeConfigs) store.register([constructorConfig.plugins, inlinePlugin]) var system = store.getSystem() const downloadSpec = (fetchedConfig) => { if(typeof constructorConfig !== "object") { return system } let localConfig = system.specSelectors.getLocalConfig ? system.specSelectors.getLocalConfig() : {} let mergedConfig = deepExtend({}, localConfig, constructorConfig, fetchedConfig || {}, queryConfig) // deep extend mangles domNode, we need to set it manually if(domNode) { mergedConfig.domNode = domNode } store.setConfigs(mergedConfig) if (fetchedConfig !== null) { if (!queryConfig.url && typeof mergedConfig.spec === "object" && Object.keys(mergedConfig.spec).length) { system.specActions.updateUrl("") system.specActions.updateLoadingStatus("success") system.specActions.updateSpec(JSON.stringify(mergedConfig.spec)) } else if (system.specActions.download && mergedConfig.url) { system.specActions.updateUrl(mergedConfig.url) system.specActions.download(mergedConfig.url) } } if(mergedConfig.domNode) { system.render(mergedConfig.domNode, "App") } else if(mergedConfig.dom_id) { let domNode = document.querySelector(mergedConfig.dom_id) system.render(domNode, "App") } else if(mergedConfig.dom_id === null || mergedConfig.domNode === null) { // do nothing // this is useful for testing that does not need to do any rendering } else { console.error("Skipped rendering: no `dom_id` or `domNode` was specified") } return system } let configUrl = queryConfig.config || constructorConfig.configUrl if (!configUrl || !system.specActions.getConfigByUrl || system.specActions.getConfigByUrl && !system.specActions.getConfigByUrl(configUrl, downloadSpec)) { return downloadSpec() } return system }
module.exports = function SwaggerUI(opts) { win.versions = win.versions || {} win.versions.swaggerUi = { version: PACKAGE_VERSION, gitRevision: GIT_COMMIT, gitDirty: GIT_DIRTY, buildTimestamp: BUILD_TIME, machine: HOSTNAME } const defaults = { // Some general settings, that we floated to the top dom_id: null, domNode: null, spec: {}, url: "", urls: null, layout: "BaseLayout", docExpansion: "list", maxDisplayedTags: null, filter: null, validatorUrl: "https://online.swagger.io/validator", configs: {}, custom: {}, displayOperationId: false, displayRequestDuration: false, deepLinking: 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. presets: [ ApisPreset ], // Plugins; ( loaded after presets ) plugins: [ ], // Inline Plugin fn: { }, components: { }, state: { }, // Override some core configs... at your own risk store: { }, } let queryConfig = parseSearch() const constructorConfig = deepExtend({}, defaults, opts, queryConfig) const storeConfigs = deepExtend({}, constructorConfig.store, { system: { configs: constructorConfig.configs }, plugins: constructorConfig.presets, state: { layout: { layout: constructorConfig.layout, filter: constructorConfig.filter }, spec: { spec: "", url: constructorConfig.url } } }) let inlinePlugin = ()=> { return { fn: constructorConfig.fn, components: constructorConfig.components, state: constructorConfig.state, } } var store = new System(storeConfigs) store.register([constructorConfig.plugins, inlinePlugin]) var system = store.getSystem() 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({}, localConfig, constructorConfig, fetchedConfig || {}, queryConfig) // deep extend mangles domNode, we need to set it manually if(opts.domNode) { mergedConfig.domNode = opts.domNode } store.setConfigs(mergedConfig) if (fetchedConfig !== null) { if (!queryConfig.url && typeof mergedConfig.spec === "object" && Object.keys(mergedConfig.spec).length) { system.specActions.updateUrl("") system.specActions.updateLoadingStatus("success") system.specActions.updateSpec(JSON.stringify(mergedConfig.spec)) } else if (system.specActions.download && mergedConfig.url) { system.specActions.updateUrl(mergedConfig.url) system.specActions.download(mergedConfig.url) } } if(mergedConfig.domNode) { system.render(mergedConfig.domNode, "App") } else if(mergedConfig.dom_id) { let domNode = document.querySelector(mergedConfig.dom_id) system.render(domNode, "App") } else { console.error("Skipped rendering: no `dom_id` or `domNode` was specified") } return system } let configUrl = queryConfig.config || constructorConfig.configUrl if (!configUrl || !system.specActions.getConfigByUrl || system.specActions.getConfigByUrl && !system.specActions.getConfigByUrl(configUrl, downloadSpec)) { return downloadSpec() } return system }