Update Function MISC_SERVE_SCALAR_UI
This commit is contained in:
@@ -1 +1,612 @@
|
|||||||
馀鉆琢闳@\由掠@^@
|
SET PATH *LIBL ;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION RESTAPI.MISC_SERVE_SCALAR_UI (
|
||||||
|
P_URL VARCHAR(528) DEFAULT NULL ,
|
||||||
|
P_CONTENT CLOB(104857600) DEFAULT NULL ,
|
||||||
|
P_BASESERVERURL VARCHAR(528) DEFAULT NULL ,
|
||||||
|
P_SOURCES CLOB(104857600) DEFAULT NULL ,
|
||||||
|
P_LAYOUT VARCHAR(32) DEFAULT 'modern' ,
|
||||||
|
P_THEME VARCHAR(32) DEFAULT NULL ,
|
||||||
|
P_DARKMODE SMALLINT DEFAULT NULL ,
|
||||||
|
P_FORCEDARKMODESTATE VARCHAR(16) DEFAULT NULL ,
|
||||||
|
P_DOCUMENTDOWNLOADTYPE VARCHAR(32) DEFAULT NULL ,
|
||||||
|
P_FAVICON VARCHAR(528) DEFAULT NULL ,
|
||||||
|
P_WITHDEFAULTFONTS SMALLINT DEFAULT 1 ,
|
||||||
|
P_CUSTOMCSS CLOB(104857600) DEFAULT NULL ,
|
||||||
|
P_AUTHENTICATION CLOB(104857600) DEFAULT NULL ,
|
||||||
|
P_HIDESIDEBAR SMALLINT DEFAULT 0 ,
|
||||||
|
P_SHOWSIDEBAR SMALLINT DEFAULT 1 ,
|
||||||
|
P_HIDESEARCH SMALLINT DEFAULT 0 ,
|
||||||
|
P_HIDECLIENTBUTTON SMALLINT DEFAULT 0 ,
|
||||||
|
P_HIDEDARKMODETOGGLE SMALLINT DEFAULT 0 ,
|
||||||
|
P_HIDETESTREQUESTBUTTON SMALLINT DEFAULT NULL ,
|
||||||
|
P_HIDEMODELS SMALLINT DEFAULT 0 ,
|
||||||
|
P_SHOWOPERATIONID SMALLINT DEFAULT 0 ,
|
||||||
|
P_EXPANDALLRESPONSES SMALLINT DEFAULT NULL ,
|
||||||
|
P_EXPANDALLMODELSECTIONS SMALLINT DEFAULT NULL ,
|
||||||
|
P_DEFAULTOPENALLTAGS SMALLINT DEFAULT NULL ,
|
||||||
|
P_SHOWDEVELOPERTOOLS VARCHAR(16) DEFAULT 'always' ,
|
||||||
|
P_OPERATIONTITLESOURCE VARCHAR(32) DEFAULT NULL ,
|
||||||
|
P_ORDERREQUIREDPROPERTIESFIRST SMALLINT DEFAULT NULL ,
|
||||||
|
P_ORDERSCHEMAPROPERTIESBY VARCHAR(32) DEFAULT NULL ,
|
||||||
|
P_PATHROUTING CLOB(104857600) DEFAULT NULL ,
|
||||||
|
P_PERSISTAUTH SMALLINT DEFAULT NULL ,
|
||||||
|
P_SEARCHHOTKEY VARCHAR(16) DEFAULT NULL ,
|
||||||
|
P_DEFAULTHTTPCLIENT CLOB(104857600) DEFAULT NULL ,
|
||||||
|
P_TAGSSORTER VARCHAR(32) DEFAULT NULL ,
|
||||||
|
P_OPERATIONSSORTER VARCHAR(32) DEFAULT NULL ,
|
||||||
|
P_FETCH CLOB(104857600) DEFAULT NULL ,
|
||||||
|
P_PROXYURL VARCHAR(528) DEFAULT NULL ,
|
||||||
|
P_SERVERS CLOB(104857600) DEFAULT NULL ,
|
||||||
|
P_HIDDENCLIENTS CLOB(104857600) DEFAULT NULL ,
|
||||||
|
P_ONBEFOREREQUEST CLOB(104857600) DEFAULT NULL ,
|
||||||
|
P_ONREQUESTSENT CLOB(104857600) DEFAULT NULL ,
|
||||||
|
P_ONSHOWMORE CLOB(104857600) DEFAULT NULL ,
|
||||||
|
P_ONLOADED CLOB(104857600) DEFAULT NULL ,
|
||||||
|
P_ONSPECUPDATE CLOB(104857600) DEFAULT NULL ,
|
||||||
|
P_ONDOCUMENTSELECT CLOB(104857600) DEFAULT NULL ,
|
||||||
|
P_ONSERVERCHANGE CLOB(104857600) DEFAULT NULL ,
|
||||||
|
P_ONSIDEBARCLICK CLOB(104857600) DEFAULT NULL ,
|
||||||
|
P_METADATA CLOB(104857600) DEFAULT NULL ,
|
||||||
|
P_PLUGINS CLOB(104857600) DEFAULT NULL ,
|
||||||
|
P_REDIRECT VARCHAR(528) DEFAULT NULL ,
|
||||||
|
P_TELEMETRY SMALLINT DEFAULT 0 ,
|
||||||
|
P_GENERATEHEADINGSLUG CLOB(104857600) DEFAULT NULL ,
|
||||||
|
P_GENERATEOPERATIONSLUG CLOB(104857600) DEFAULT NULL ,
|
||||||
|
P_GENERATETAGSLUG CLOB(104857600) DEFAULT NULL ,
|
||||||
|
P_GENERATEWEBHOOKSLUG CLOB(104857600) DEFAULT NULL ,
|
||||||
|
P_GENERATEMODELSLUG CLOB(104857600) DEFAULT NULL ,
|
||||||
|
P_ISLOADING SMALLINT DEFAULT 1 )
|
||||||
|
RETURNS CLOB(2147483647)
|
||||||
|
LANGUAGE SQL
|
||||||
|
SPECIFIC RESTAPI.MISC_SERVE_SCALAR_UI
|
||||||
|
NOT DETERMINISTIC
|
||||||
|
READS SQL DATA
|
||||||
|
CALLED ON NULL INPUT
|
||||||
|
SET OPTION ALWBLK = *ALLREAD ,
|
||||||
|
ALWCPYDTA = *OPTIMIZE ,
|
||||||
|
COMMIT = *NONE ,
|
||||||
|
DECRESULT = (31, 31, 00) ,
|
||||||
|
DYNDFTCOL = *NO ,
|
||||||
|
DYNUSRPRF = *USER ,
|
||||||
|
SRTSEQ = *HEX
|
||||||
|
BEGIN
|
||||||
|
RETURN
|
||||||
|
( '<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Scalar API Reference - Full Config Playground</title>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap" rel="stylesheet" />
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||||
|
}
|
||||||
|
#app {
|
||||||
|
min-height: 100vh;
|
||||||
|
transition: filter 0.3s ease-in-out;
|
||||||
|
}
|
||||||
|
#app.modal-blur {
|
||||||
|
filter: blur(8px);
|
||||||
|
}
|
||||||
|
|
||||||
|
#modal-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width:100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
display: none;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
#modal-dialog {
|
||||||
|
background-color: white;
|
||||||
|
box-shadow: 0 4px 12px rgba(0,0, 0, 0.15);
|
||||||
|
width: 600px;
|
||||||
|
max-width: 90%;
|
||||||
|
padding: 24px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
#modal-dialog h3 {
|
||||||
|
font-size:1.5em;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 0;
|
||||||
|
color:#333;
|
||||||
|
}
|
||||||
|
#modal-dialog p {
|
||||||
|
font-size: 0.9em;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: #555;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
#input-container {
|
||||||
|
position: relative;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
padding: 12px;
|
||||||
|
min-height: 100px;
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
}
|
||||||
|
#input-placeholder {
|
||||||
|
position: absolute;
|
||||||
|
top: 8px;
|
||||||
|
left: 12px;
|
||||||
|
color: #999;
|
||||||
|
font-size: 1.5em;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
#api-input {
|
||||||
|
width: 100%;
|
||||||
|
height: 100px;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
background: transparent;
|
||||||
|
resize: none;
|
||||||
|
padding-top: 18px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #333;
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 0.85em;
|
||||||
|
}
|
||||||
|
#button-container {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
.modal-btn {
|
||||||
|
padding: 10px 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 0.9em;
|
||||||
|
font-weight: 500;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
#cancel-btn {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
#cancel-btn:hover {
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
}
|
||||||
|
#continue-btn {
|
||||||
|
background-color: #010e1c;
|
||||||
|
border: 1px solid #000000;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
#continue-btn:hover {
|
||||||
|
background-color: #021528;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="modal-overlay">
|
||||||
|
<div id="modal-dialog">
|
||||||
|
<h3>Import API</h3>
|
||||||
|
<p>Paste the contents of your OpenAPI document (YAML/JSON) or a link to its location.</p>
|
||||||
|
<div id="input-container">
|
||||||
|
<span id="input-placeholder">OpenAPI Document or Link</span>
|
||||||
|
<textarea id="api-input"></textarea>
|
||||||
|
</div>
|
||||||
|
<div id="button-container">
|
||||||
|
<button id="cancel-btn" class="modal-btn">Cancel</button>
|
||||||
|
<buttonid="continue-btn" class="modal-btn">Continue</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="app"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function(){
|
||||||
|
"use strict";
|
||||||
|
const ELEMENTS = {
|
||||||
|
app:"#app",
|
||||||
|
modal: "#modal-overlay",
|
||||||
|
input: "#api-input",
|
||||||
|
placeholder: "#input-placeholder",
|
||||||
|
cancelBtn: "#cancel-btn",
|
||||||
|
continueBtn: "#continue-btn"
|
||||||
|
};
|
||||||
|
const WELCOME_SPEC = {
|
||||||
|
openapi: "3.1.0",
|
||||||
|
info: {
|
||||||
|
title: "Welcome to Scalar",
|
||||||
|
description: "Please import an OpenAPI specification using the dialog above",
|
||||||
|
version: "1.0.0"
|
||||||
|
},
|
||||||
|
paths: {}
|
||||||
|
};
|
||||||
|
const DEFAULT_SCALAR_CONFIG = {
|
||||||
|
layout: ' ||
|
||||||
|
COALESCE ( '''' || P_LAYOUT || '''' , '''modern''' ) || ',
|
||||||
|
theme: ' || COALESCE ( '''' || P_THEME || '''' , 'undefined' )
|
||||||
|
|| ',
|
||||||
|
darkMode: ' || COALESCE (
|
||||||
|
CASE
|
||||||
|
WHEN P_DARKMODE = 1 THEN 'true'
|
||||||
|
WHEN P_DARKMODE = 0 THEN 'false'
|
||||||
|
ELSE NULL
|
||||||
|
END , 'undefined' ) || ',
|
||||||
|
forceDarkModeState: ' ||
|
||||||
|
COALESCE ( '''' || P_FORCEDARKMODESTATE || '''' , 'undefined' ) ||
|
||||||
|
',
|
||||||
|
documentDownloadType: ' ||
|
||||||
|
COALESCE ( '''' || P_DOCUMENTDOWNLOADTYPE || '''' , 'undefined' ) ||
|
||||||
|
',
|
||||||
|
favicon: ' ||
|
||||||
|
COALESCE ( '''' || P_FAVICON || '''' , 'undefined' ) || ',
|
||||||
|
withDefaultFonts: ' || COALESCE (
|
||||||
|
CASE
|
||||||
|
WHEN P_WITHDEFAULTFONTS = 1 THEN 'true'
|
||||||
|
ELSE 'false'
|
||||||
|
END , 'true' ) || ',
|
||||||
|
customCss: ' ||
|
||||||
|
COALESCE ( '''' || P_CUSTOMCSS || '''' , 'undefined' ) || ',
|
||||||
|
authentication: ' ||
|
||||||
|
COALESCE ( P_AUTHENTICATION , 'undefined' ) || ',
|
||||||
|
hideSidebar: '|| COALESCE (
|
||||||
|
CASE
|
||||||
|
WHEN P_HIDESIDEBAR = 1 THEN 'true'
|
||||||
|
ELSE 'false'
|
||||||
|
END , 'false' ) || ',
|
||||||
|
showSidebar: ' || COALESCE (
|
||||||
|
CASE
|
||||||
|
WHEN P_SHOWSIDEBAR = 1 THEN 'true'
|
||||||
|
ELSE 'false'
|
||||||
|
END , 'true' ) || ',
|
||||||
|
hideSearch: ' || COALESCE (
|
||||||
|
CASE
|
||||||
|
WHEN P_HIDESEARCH = 1 THEN 'true'
|
||||||
|
ELSE 'false'
|
||||||
|
END , 'false' ) || ',
|
||||||
|
hideClientButton: ' || COALESCE (
|
||||||
|
CASE
|
||||||
|
WHEN P_HIDECLIENTBUTTON = 1 THEN 'true'
|
||||||
|
ELSE 'false'
|
||||||
|
END , 'false' ) || ',
|
||||||
|
hideDarkModeToggle: ' || COALESCE (
|
||||||
|
CASE
|
||||||
|
WHEN P_HIDEDARKMODETOGGLE = 1 THEN 'true'
|
||||||
|
ELSE 'false'
|
||||||
|
END , 'false' ) || ',
|
||||||
|
hideTestRequestButton: ' || COALESCE (
|
||||||
|
CASE
|
||||||
|
WHEN P_HIDETESTREQUESTBUTTON = 1 THEN 'true'
|
||||||
|
WHEN P_HIDETESTREQUESTBUTTON = 0 THEN 'false'
|
||||||
|
ELSE NULL
|
||||||
|
END , 'undefined' ) || ',
|
||||||
|
hideModels: ' || COALESCE (
|
||||||
|
CASE
|
||||||
|
WHEN P_HIDEMODELS = 1 THEN 'true'
|
||||||
|
ELSE 'false'
|
||||||
|
END , 'false' ) || ',
|
||||||
|
showOperationId: ' || COALESCE (
|
||||||
|
CASE
|
||||||
|
WHEN P_SHOWOPERATIONID = 1 THEN 'true'
|
||||||
|
ELSE 'false'
|
||||||
|
END , 'false' ) || ',
|
||||||
|
expandAllResponses: ' || COALESCE (
|
||||||
|
CASE
|
||||||
|
WHEN P_EXPANDALLRESPONSES = 1 THEN 'true'
|
||||||
|
WHEN P_EXPANDALLRESPONSES = 0 THEN 'false'
|
||||||
|
ELSE NULL
|
||||||
|
END , 'undefined' ) || ',
|
||||||
|
expandAllModelSections: ' || COALESCE(
|
||||||
|
CASE
|
||||||
|
WHEN P_EXPANDALLMODELSECTIONS = 1 THEN 'true'
|
||||||
|
WHEN P_EXPANDALLMODELSECTIONS = 0 THEN 'false'
|
||||||
|
ELSE NULL
|
||||||
|
END , 'undefined' ) || ',
|
||||||
|
defaultOpenAllTags: ' || COALESCE (
|
||||||
|
CASE
|
||||||
|
WHEN P_DEFAULTOPENALLTAGS = 1 THEN 'true'
|
||||||
|
WHEN P_DEFAULTOPENALLTAGS = 0 THEN 'false'
|
||||||
|
ELSE NULL
|
||||||
|
END , 'undefined' ) || ',
|
||||||
|
showDeveloperTools: ' ||
|
||||||
|
COALESCE ( '''' || P_SHOWDEVELOPERTOOLS || '''' , '''always''' ) ||
|
||||||
|
',
|
||||||
|
operationTitleSource: ' ||
|
||||||
|
COALESCE ( '''' || P_OPERATIONTITLESOURCE || '''' , 'undefined' ) ||
|
||||||
|
',
|
||||||
|
orderRequiredPropertiesFirst: ' || COALESCE (
|
||||||
|
CASE
|
||||||
|
WHEN P_ORDERREQUIREDPROPERTIESFIRST = 1 THEN 'true'
|
||||||
|
WHEN P_ORDERREQUIREDPROPERTIESFIRST = 0 THEN 'false'
|
||||||
|
ELSE NULL
|
||||||
|
END , 'undefined' ) || ',
|
||||||
|
orderSchemaPropertiesBy: ' ||
|
||||||
|
COALESCE ( '''' || P_ORDERSCHEMAPROPERTIESBY || '''' , 'undefined' )
|
||||||
|
|| ',
|
||||||
|
pathRouting: ' || COALESCE ( P_PATHROUTING , 'undefined' )||
|
||||||
|
',
|
||||||
|
persistAuth: ' || COALESCE (
|
||||||
|
CASE
|
||||||
|
WHEN P_PERSISTAUTH = 1 THEN 'true'
|
||||||
|
WHEN P_PERSISTAUTH = 0 THEN 'false'
|
||||||
|
ELSE NULL
|
||||||
|
END , 'undefined' ) || ',
|
||||||
|
searchHotKey: ' ||
|
||||||
|
COALESCE ( '''' || P_SEARCHHOTKEY || '''' , 'undefined' ) || ',
|
||||||
|
defaultHttpClient: ' ||
|
||||||
|
COALESCE ( P_DEFAULTHTTPCLIENT , 'undefined' ) || ',
|
||||||
|
tagsSorter:' ||
|
||||||
|
COALESCE ( '''' || P_TAGSSORTER || '''' , 'undefined' ) || ',
|
||||||
|
operationsSorter: ' ||
|
||||||
|
COALESCE ( '''' || P_OPERATIONSSORTER || '''' , 'undefined' ) || ',
|
||||||
|
fetch: ' || COALESCE ( P_FETCH , 'undefined' ) || ',
|
||||||
|
proxyUrl: ' ||
|
||||||
|
COALESCE ( '''' || P_PROXYURL || '''' , 'undefined' ) || ',
|
||||||
|
servers: ' || COALESCE ( P_SERVERS , 'undefined' ) || ',
|
||||||
|
hiddenClients: ' || COALESCE ( P_HIDDENCLIENTS , 'undefined' )
|
||||||
|
|| ',
|
||||||
|
onBeforeRequest: ' ||
|
||||||
|
COALESCE ( P_ONBEFOREREQUEST , 'undefined' ) || ',
|
||||||
|
onRequestSent: ' || COALESCE ( P_ONREQUESTSENT , 'undefined' )
|
||||||
|
|| ',
|
||||||
|
onShowMore: ' || COALESCE ( P_ONSHOWMORE , 'undefined' ) || ',
|
||||||
|
onLoaded: ' || COALESCE ( P_ONLOADED , 'undefined' ) || ',
|
||||||
|
onSpecUpdate: ' || COALESCE ( P_ONSPECUPDATE , 'undefined' ) ||',
|
||||||
|
onDocumentSelect: ' ||
|
||||||
|
COALESCE ( P_ONDOCUMENTSELECT , 'undefined' ) || ',
|
||||||
|
onServerChange: ' ||
|
||||||
|
COALESCE ( P_ONSERVERCHANGE , 'undefined' ) || ',
|
||||||
|
onSidebarClick: ' ||
|
||||||
|
COALESCE ( P_ONSIDEBARCLICK , 'undefined' ) || ',
|
||||||
|
metaData: ' ||COALESCE ( P_METADATA , 'undefined' ) || ',
|
||||||
|
plugins: ' || COALESCE ( P_PLUGINS , 'undefined' ) || ',
|
||||||
|
redirect: ' ||
|
||||||
|
COALESCE ( '''' || P_REDIRECT || '''' , 'undefined' ) || ',
|
||||||
|
telemetry: ' || COALESCE (
|
||||||
|
CASE
|
||||||
|
WHEN P_TELEMETRY = 1 THEN 'true'
|
||||||
|
WHEN P_TELEMETRY = 0 THEN 'false'
|
||||||
|
ELSE NULL
|
||||||
|
END , 'undefined' ) || ',
|
||||||
|
generateHeadingSlug: ' ||
|
||||||
|
COALESCE ( P_GENERATEHEADINGSLUG , 'undefined' ) || ',
|
||||||
|
generateOperationSlug: ' ||
|
||||||
|
COALESCE ( P_GENERATEOPERATIONSLUG , 'undefined' ) || ',
|
||||||
|
generateTagSlug: ' ||
|
||||||
|
COALESCE ( P_GENERATETAGSLUG , 'undefined' ) || ',
|
||||||
|
generateWebhookSlug: ' ||
|
||||||
|
COALESCE ( P_GENERATEWEBHOOKSLUG , 'undefined' ) || ',
|
||||||
|
generateModelSlug: ' ||
|
||||||
|
COALESCE ( P_GENERATEMODELSLUG , 'undefined' ) || ',
|
||||||
|
isLoading:' || COALESCE (
|
||||||
|
CASE
|
||||||
|
WHEN P_ISLOADING = 1 THEN 'true'
|
||||||
|
WHEN P_ISLOADING = 0 THEN 'false'
|
||||||
|
ELSE NULL
|
||||||
|
END , 'undefined' ) || '
|
||||||
|
};
|
||||||
|
function getQueryParameter(paramName) {
|
||||||
|
const params = new URLSearchParams(window.location.search);
|
||||||
|
const normalizedName = paramName.toLowerCase();
|
||||||
|
for (const [key, value] of params) {
|
||||||
|
if (key.toLowerCase() === normalizedName) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
function isValidUrl(input) {
|
||||||
|
try {
|
||||||
|
const url = new URL(input);
|
||||||
|
const isHttpProtocol = url.protocol ==="http:" || url.protocol === "https:";
|
||||||
|
const isNotProtocolRelative = !input.startsWith("//");
|
||||||
|
return isHttpProtocol && isNotProtocolRelative;
|
||||||
|
} catch (error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function parseOpenApiContent(input) {
|
||||||
|
const trimmedInput = input.trim();
|
||||||
|
if (trimmedInput.startsWith("{") || trimmedInput.startsWith("[")) {
|
||||||
|
return JSON.parse(trimmedInput);
|
||||||
|
}
|
||||||
|
returntrimmedInput;
|
||||||
|
}
|
||||||
|
function hasValue(value) {
|
||||||
|
return value !== null && value !== undefined && value !== "";
|
||||||
|
}
|
||||||
|
const sqlParameters = {
|
||||||
|
url: "",
|
||||||
|
content: null,
|
||||||
|
sources: null,
|
||||||
|
baseServerURL: null
|
||||||
|
};
|
||||||
|
function determineInitialConfiguration() {
|
||||||
|
const config = {};
|
||||||
|
let showModal = false;
|
||||||
|
const specUrlParam = getQueryParameter("specUrl");
|
||||||
|
if (hasValue(specUrlParam)) {
|
||||||
|
config.url = specUrlParam;
|
||||||
|
return { config, showModal };
|
||||||
|
}
|
||||||
|
if (hasValue(sqlParameters.url)) {
|
||||||
|
config.url = sqlParameters.url;
|
||||||
|
return { config, showModal };
|
||||||
|
}
|
||||||
|
if(hasValue(sqlParameters.content) || hasValue(sqlParameters.sources)) {
|
||||||
|
if (hasValue(sqlParameters.content)) {
|
||||||
|
config.content = sqlParameters.content;
|
||||||
|
}
|
||||||
|
if(hasValue(sqlParameters.sources)) {
|
||||||
|
config.sources = sqlParameters.sources;
|
||||||
|
}
|
||||||
|
return { config, showModal };
|
||||||
|
}
|
||||||
|
config.content = WELCOME_SPEC;
|
||||||
|
showModal = true;
|
||||||
|
return { config, showModal };
|
||||||
|
}
|
||||||
|
const ScalarManager = {
|
||||||
|
instance: null,
|
||||||
|
isInitialized: false,
|
||||||
|
render(userConfig = {}) {
|
||||||
|
const finalConfig = { ...userConfig };
|
||||||
|
if(hasValue(sqlParameters.baseServerURL)) {
|
||||||
|
finalConfig.baseServerURL = sqlParameters.baseServerURL;
|
||||||
|
}
|
||||||
|
if (this.instance) {
|
||||||
|
const appElement = document.querySelector(ELEMENTS.app);
|
||||||
|
if (appElement) {
|
||||||
|
appElement.innerHTML = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.instance = Scalar.createApiReference(ELEMENTS.app, {
|
||||||
|
...DEFAULT_SCALAR_CONFIG,
|
||||||
|
...finalConfig
|
||||||
|
});
|
||||||
|
console.log("Scalar API Reference initialized");
|
||||||
|
},
|
||||||
|
canInitialize() {
|
||||||
|
const isScalarLoaded = typeof Scalar !== "undefined";
|
||||||
|
const isDomReady = document.readyState !== "loading";
|
||||||
|
if (!isScalarLoaded) {
|
||||||
|
console.log("Waiting for Scalar library...");
|
||||||
|
}
|
||||||
|
if (!isDomReady) {
|
||||||
|
console.log("Waiting for DOM...");
|
||||||
|
}
|
||||||
|
return isScalarLoaded && isDomReady;
|
||||||
|
},
|
||||||
|
initialize() {
|
||||||
|
if (this.isInitialized){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this.canInitialize()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.isInitialized = true;
|
||||||
|
console.log("Initializing Scalar application...");
|
||||||
|
const { config, showModal } = determineInitialConfiguration();
|
||||||
|
if (showModal) {
|
||||||
|
ModalManager.show();
|
||||||
|
} else {
|
||||||
|
ModalManager.hide();
|
||||||
|
}
|
||||||
|
this.render(config);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const ModalManager = {
|
||||||
|
elements: {},
|
||||||
|
initialize() {
|
||||||
|
this.elements = {
|
||||||
|
modal: document.getElementById("modal-overlay"),
|
||||||
|
input: document.getElementById("api-input"),
|
||||||
|
placeholder: document.getElementById("input-placeholder"),
|
||||||
|
cancelBtn: document.getElementById("cancel-btn"),
|
||||||
|
continueBtn: document.getElementById("continue-btn")
|
||||||
|
};
|
||||||
|
this.attachEventListeners();
|
||||||
|
},
|
||||||
|
attachEventListeners() {
|
||||||
|
this.elements.input.addEventListener("input", () => {
|
||||||
|
this.updatePlaceholder();
|
||||||
|
});
|
||||||
|
this.elements.cancelBtn.addEventListener("click", () => {
|
||||||
|
this.hide();
|
||||||
|
});
|
||||||
|
this.elements.continueBtn.addEventListener("click", () => {
|
||||||
|
this.handleContinue();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
updatePlaceholder() {
|
||||||
|
const hasInput = this.elements.input.value.length > 0;
|
||||||
|
this.elements.placeholder.style.display = hasInput ? "none" : "block";
|
||||||
|
},
|
||||||
|
show() {
|
||||||
|
this.elements.modal.style.display = "flex";
|
||||||
|
const appElement = document.querySelector(ELEMENTS.app);
|
||||||
|
if (appElement) {
|
||||||
|
appElement.classList.add("modal-blur");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hide() {
|
||||||
|
this.elements.modal.style.display = "none";
|
||||||
|
const appElement = document.querySelector(ELEMENTS.app);
|
||||||
|
if (appElement) {
|
||||||
|
appElement.classList.remove("modal-blur");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleContinue() {
|
||||||
|
const userInput = this.elements.input.value.trim();
|
||||||
|
if (!userInput) {
|
||||||
|
alert("Please enter an OpenAPI document or URL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isValidUrl(userInput)) {
|
||||||
|
this.loadFromUrl(userInput);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.loadFromContent(userInput);
|
||||||
|
},
|
||||||
|
loadFromUrl(url) {
|
||||||
|
ScalarManager.render({ url });
|
||||||
|
this.hide();
|
||||||
|
},
|
||||||
|
loadFromContent(contentString) {
|
||||||
|
try {
|
||||||
|
const content = parseOpenApiContent(contentString);
|
||||||
|
ScalarManager.render({ content });
|
||||||
|
this.hide();
|
||||||
|
} catch (error) {
|
||||||
|
alert("Error parsing content: " + error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const InitializationCoordinator = {
|
||||||
|
state: {
|
||||||
|
domReady: false,
|
||||||
|
scalarLibraryReady: false
|
||||||
|
},
|
||||||
|
tryInitialize() {
|
||||||
|
if(this.state.domReady && this.state.scalarLibraryReady) {
|
||||||
|
ScalarManager.initialize();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
markDomReady() {
|
||||||
|
this.state.domReady = true;
|
||||||
|
this.tryInitialize();
|
||||||
|
},
|
||||||
|
markScalarReady() {
|
||||||
|
this.state.scalarLibraryReady = true;
|
||||||
|
this.tryInitialize();
|
||||||
|
},
|
||||||
|
setup() {
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
this.markDomReady();
|
||||||
|
});
|
||||||
|
window.onScalarLibraryLoaded = () => {
|
||||||
|
this.markScalarReady();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ModalManager.initialize();
|
||||||
|
InitializationCoordinator.setup();
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference/dist/browser/standalone.min.js"
|
||||||
|
onload="window.onScalarLibraryLoaded();"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>' ) ;
|
||||||
|
END ;
|
||||||
|
|
||||||
|
GRANT ALTER , EXECUTE
|
||||||
|
ON SPECIFIC FUNCTION RESTAPI.MISC_SERVE_SCALAR_UI
|
||||||
|
TO AMAPICS WITH GRANT OPTION ;
|
||||||
|
|
||||||
|
GRANT EXECUTE
|
||||||
|
ON SPECIFIC FUNCTION RESTAPI.MISC_SERVE_SCALAR_UI
|
||||||
|
TO PUBLIC ;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user