UNPKG

@bsv/overlay-express

Version:
517 lines (453 loc) 16.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); /* eslint-disable */ const generalGuide_md_js_1 = __importDefault(require("./generalGuide.md.js")); exports.default = (config = {}) => { const { host = '', faviconUrl = 'https://bsvblockchain.org/favicon.ico', backgroundColor = '#191919', primaryTextColor = '#f0f0f0', primaryColor = '#3b6efb', secondaryColor = '#001242', fontFamily = 'Helvetica, Arial, sans-serif', headingFontFamily = 'Helvetica, Arial, sans-serif', additionalStyles = '', sectionBackgroundColor = '#323940', linkColor = '#579DFF', hoverColor = '#3A4147', borderColor = '#B6C2CF', secondaryBackgroundColor = '#f8f8f8', secondaryTextColor = '#0e0e0e', defaultContent = generalGuide_md_js_1.default } = config; return `<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>Overlay Services</title> <link rel="icon" type="image/x-icon" href="${faviconUrl}"> <style> :root { --background-color: ${backgroundColor}; --primary-color: ${primaryColor}; --secondary-color: ${secondaryColor}; --font-family: ${fontFamily}; --heading-font-family: ${headingFontFamily}; --section-background-color: ${sectionBackgroundColor}; --link-color: ${linkColor}; --hover-color: ${hoverColor}; --border-color: ${borderColor}; --secondary-background-color: ${secondaryBackgroundColor}; --secondary-text-color: ${secondaryTextColor}; --primary-text-color: ${primaryTextColor}; } body { font-family: var(--font-family); background-color: var(--background-color); margin: 0; padding: 0; color: var(--primary-text-color); } h1, h2, h3 { font-family: var(--heading-font-family); } p { line-height: 1.5; } .welcome { background-clip: text; color: transparent; background-image: linear-gradient(90deg, var(--primary-color), var(--secondary-color)); cursor: pointer; } a { color: var(--link-color); text-decoration: none; } a:hover { color: var(--secondary-color); } .main { display: flex; flex-direction: row; height: 100vh; overflow: hidden; } .column_right { padding: 1.5em; overflow-y: auto; } .column_left { padding: 15px 15px 15px 35px; overflow-y: auto; width: 360px; background-color: var(--secondary-background-color); color: var(--secondary-text-color); } .column_right { width: calc(100% - 360px); } #documentation_container { padding: 0 8em; margin: 0; } /* List styles */ .list-item { margin: 0; } .list-item a { display: block; width: 100%; padding: 0.5em 0.75em; background-color: transparent; border-radius: 5px; transition: background-color 0.3s; text-decoration: none; color: inherit; font-weight: 500; cursor: pointer; } .list-item a:hover, .list-item a.active { background: var(--primary-color) linear-gradient(90deg, var(--primary-color), var(--secondary-color)); color: white; cursor: pointer; border-radius: 8px 0 0 8px; } ul#manager_list, ul#provider_list, ul#external_list { list-style-type: none; padding-left: 0; margin-top: 0.5em; } /* Detail styles */ .detail-header { display: flex; align-items: center; margin-bottom: 1em; } .detail-icon { width: 60px; height: 60px; margin-right: 1em; } .detail-text { display: flex; flex-direction: column; } .detail-title { margin: 0; } .detail-description, .detail-version, .detail-info { margin: 0.2em 0; } .detail-info a { color: var(--link-color); } /* Code highlighting styles */ pre { position: relative; padding: 1em; border-radius: 5px; overflow: auto; background-color: #282c34; margin: 1em 0; } pre[data-language]:before { content: attr(data-language); position: absolute; top: 0; right: 0; padding: 0.25em 0.5em; font-size: 0.75em; color: #abb2bf; background-color: #3e4451; border-radius: 0 0 0 4px; text-transform: uppercase; } code { font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 0.9em; } /* Inline code */ p code, li code { background-color: #3e4451; padding: 0.2em 0.4em; border-radius: 3px; white-space: nowrap; } /* Responsive design */ @media screen and (max-width: 850px) { .main { flex-direction: column; } .column_left { max-height: 30vh; } .column_left, .column_right { width: 90%; margin: 0; padding: 0 5%; } #documentation_container { margin: 0; padding: 0; } } ${additionalStyles} </style> <script src="https://cdn.jsdelivr.net/npm/showdown@2.0.3/dist/showdown.min.js"></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.7.0/build/styles/atom-one-dark.min.css"> <script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.7.0/build/highlight.min.js"></script> <script> const faviconUrl = '${faviconUrl}'; const showdown = window.showdown; window.hljs.configure({ languages: ['typescript', 'javascript', 'json', 'html', 'css', 'bash', 'markdown'] }); const Convert = (md) => { let converter = new showdown.Converter({ ghCompatibleHeaderId: true, simpleLineBreaks: true, ghMentions: true, tables: true, tasklists: true, strikethrough: true, parseImgDimensions: true, simplifiedAutoLink: true }); // Set to use GitHub flavor markdown converter.setFlavor('github'); // Set language detection for code blocks converter.setOption('ghCodeBlocks', true); converter.setOption('omitExtraWLInCodeBlocks', true); converter.setOption('literalMidWordUnderscores', true); converter.setOption('parseImgDimensions', true); // Add custom extension for adding language-specific class to code blocks const codeExtension = () => [ { type: 'output', filter: function(text) { return text.replace(/<pre><code\s*class="([^"]*)">(.*?)<\\/code><\\/pre>/gs, function(match, language, content) { if (language) { // Clean up the language identifier const lang = language.replace('language-', '').trim(); return \`<pre data-language="\${lang}"><code class="language-\${lang} hljs">\${content}</code></pre>\`; } else { return \`<pre><code class="hljs">\${content}</code></pre>\`; } }); } } ]; // Add the extension converter.addExtension(codeExtension()); const html = converter.makeHtml(md); return html; }; window.returnHome = () => { if (!window.defaultHtml) { let newStuff = Convert(${defaultContent}); window.defaultHtml = newStuff; } document.getElementById('documentation_container').innerHTML = window.defaultHtml; window.location.hash = ''; document.querySelectorAll('.list-item a').forEach(item => { item.classList.remove('active'); }); }; // Function to apply syntax highlighting after content is inserted const applyHighlighting = () => { document.querySelectorAll('pre code').forEach(block => { const blockElement = block; // Check for language class const classList = Array.from(blockElement.classList); const langClass = classList.find(cls => cls.startsWith('language-')); if (langClass) { const language = langClass.replace('language-', ''); // Set language label on the parent pre element const preElement = blockElement.parentElement; if (preElement) { preElement.setAttribute('data-language', language); } } // Apply highlighting to all code blocks try { // @ts-ignore - hljs is loaded from CDN window.hljs.highlightElement(blockElement); } catch (e) { console.error('Error highlighting code:', e); } }); }; let managersData = {}; let providersData = {}; // Function to update URL hash and highlight selected item const updateSelectedItem = (type, id) => { // Update URL hash window.location.hash = \`\${type}/\${id}\`; // Remove active class from all list items document.querySelectorAll('.list-item a').forEach(item => { item.classList.remove('active'); }); // Add active class to selected item const selector = \`[data-\${type}="\${id}"]\`; const selectedItem = document.querySelector(selector); if (selectedItem) { selectedItem.classList.add('active'); } }; // @ts-ignore - Adding custom property to window window.managerDocumentation = async (manager) => { try { let res = await fetch(\`${host}/getDocumentationForTopicManager?manager=\${manager}\`); let docs = await res.text(); let managerReadme = Convert(docs); let managerData = managersData[manager]; let iconURL = managerData.iconURL || faviconUrl; document.getElementById('documentation_container').innerHTML = managerReadme; applyHighlighting(); // Update active item and URL updateSelectedItem('manager', manager); } catch (error) { console.error('Error fetching manager documentation:', error); } }; // @ts-ignore - Adding custom property to window window.topicDocumentation = async (provider) => { try { let res = await fetch(\`${host}/getDocumentationForLookupServiceProvider?lookupService=\${provider}\`); let docs = await res.text(); let providerReadme = Convert(docs); let providerData = providersData[provider]; let iconURL = providerData.iconURL || faviconUrl; document.getElementById('documentation_container').innerHTML = providerReadme; applyHighlighting(); // Update active item and URL updateSelectedItem('provider', provider); } catch (error) { console.error('Error fetching provider documentation:', error); } }; // Function to parse hash and load appropriate content const handleUrlHash = () => { const hash = window.location.hash.substring(1); // Remove the # character if (hash) { const [type, id] = hash.split('/'); if (type && id) { if (type === 'manager') { // Check if managers data is loaded if (Object.keys(managersData).length > 0 && managersData[id]) { window.managerDocumentation(id); } } else if (type === 'provider') { // Check if providers data is loaded if (Object.keys(providersData).length > 0 && providersData[id]) { window.topicDocumentation(id); } } } } }; document.addEventListener('DOMContentLoaded', () => { let managersLoaded = false; let providersLoaded = false; // Check if both managers and providers are loaded before handling hash const checkAllLoaded = () => { if (managersLoaded && providersLoaded) { handleUrlHash(); } }; fetch('${host}/listTopicManagers') .then(res => res.json()) .then(managers => { managersData = managers; const managerList = document.getElementById('manager_list'); Object.keys(managers).forEach(manager => { let managerData = managers[manager]; let li = document.createElement('li'); li.className = 'list-item'; li.innerHTML = \` <a data-manager="\${manager}" onclick="window.managerDocumentation('\${manager}')"> \${managerData.name} </a> \`; managerList.appendChild(li); }); managersLoaded = true; checkAllLoaded(); }) .catch(() => { let message = document.createElement('h4'); message.innerText = 'Something went wrong!'; manager_list.insertBefore(message, manager_list.children[0]); managersLoaded = true; checkAllLoaded(); }); fetch('${host}/listLookupServiceProviders') .then(res => res.json()) .then(providers => { providersData = providers; const providerList = document.getElementById('provider_list'); Object.keys(providers).forEach(provider => { let providerData = providers[provider]; let li = document.createElement('li'); li.className = 'list-item'; li.innerHTML = \` <a data-provider="\${provider}" onclick="window.topicDocumentation('\${provider}')"> \${providerData.name} </a> \`; providerList.appendChild(li); }); providersLoaded = true; checkAllLoaded(); }) .catch(() => { let message = document.createElement('h4'); message.innerText = 'Something went wrong!'; provider_list.insertBefore(message, provider_list.children[0]); providersLoaded = true; checkAllLoaded(); }); // Check URL hash to see if we should load specific documentation const checkUrlHash = () => { const hash = window.location.hash.substring(1); // Remove the # symbol if (hash) { const parts = hash.split('/'); if (parts.length === 2) { const type = parts[0]; const id = parts[1]; if (type === 'manager' && id && managersData[id]) { window.managerDocumentation(id); } else if (type === 'provider' && id && providersData[id]) { window.topicDocumentation(id); } } } else { // Display default message when no manager or provider is selected returnHome(); } }; // Listen for hash changes window.addEventListener('hashchange', checkUrlHash); // Check hash on initial page load checkUrlHash(); }); </script> </head> <body> <div class="main"> <div class="column_left"> <div class="page_head"> <h1 class="welcome" onclick="window.returnHome()">Overlay Services</h1> </div> <div class="topic_container"> <h3>Topic Managers</h3> <ul id="manager_list"></ul> </div> <div class="provider_container"> <h3>Lookup Services</h3> <ul id="provider_list"></ul> </div> <div> <h3>External Links</h3> <ul id="external_list"> <li class="list-item"><a href="https://github.com/bsv-blockchain/overlay-services" target="_blank">Overlay Services GitHub</a></li> <li class="list-item"><a href="https://bsv.brc.dev/transactions/0076" target="_blank">BRC-76 GASP</a></li> <li class="list-item"><a href="https://fast.brc.dev" target="_blank">Quick Start for App Developers</a></li> </ul> </div> </div> <div class="column_right"> <div id="documentation_container"></div> </div> </div> </body> </html>`; }; //# sourceMappingURL=makeUserInterface.js.map