Skip to content

Commit

Permalink
Adds multi instance and versioning handler to Docusaurus V3 (#683)
Browse files Browse the repository at this point in the history
raiindev authored Apr 5, 2024
1 parent 791f454 commit 03d6053
Showing 6 changed files with 1,170 additions and 364 deletions.
23 changes: 12 additions & 11 deletions packages/plugin-docusaurus-v3/package.json
Original file line number Diff line number Diff line change
@@ -21,32 +21,33 @@
"watch": "tsc --watch"
},
"dependencies": {
"@docusaurus/plugin-content-docs": "^3.0.1",
"@docusaurus/theme-common": "^3.0.1",
"@orama/highlight": "^0.1.2",
"@orama/highlight": "^0.1.5",
"@orama/orama": "workspace:*",
"@orama/plugin-analytics": "workspace:*",
"@orama/plugin-parsedoc": "workspace:*",
"@orama/searchbox": "1.0.0-beta.13",
"@orama/searchbox": "^1.0.0-rc13",
"@oramacloud/client": "^1.0.14",
"github-slugger": "^2.0.0",
"gray-matter": "^4.0.3",
"jsdom": "^23.0.1",
"jsdom": "^23.2.0",
"markdown-it": "^13.0.2",
"pako": "^2.1.0",
"vfile-message": "^3.1.4",
"tslib": "^2.6.0"
"tslib": "^2.6.2",
"vfile-message": "^3.1.4"
},
"devDependencies": {
"@docusaurus/types": "^3.0.1",
"@types/jsdom": "^21.1.6",
"@types/markdown-it": "^13.0.7",
"@types/pako": "^2.0.0",
"@types/pako": "^2.0.3",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
"@docusaurus/plugin-content-docs": ">= 3.2.0",
"@docusaurus/theme-common": ">= 3.2.0",
"@docusaurus/types": ">= 3.2.0",
"react": ">= 18.0.0",
"react-dom": ">= 18.0.0"
},
"publishConfig": {
"access": "public"
309 changes: 200 additions & 109 deletions packages/plugin-docusaurus-v3/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,167 +1,228 @@
import { readFileSync, writeFileSync } from 'node:fs'
import type { Plugin } from '@docusaurus/types'
import { cp } from 'node:fs/promises'
import { gzip as gzipCB } from 'node:zlib'
import { promisify } from 'node:util'
import { resolve } from 'node:path'
import { readFileSync, writeFileSync } from "node:fs"
import type { Plugin } from "@docusaurus/types"
import { cp } from "node:fs/promises"
import { gzip } from "pako"
import { resolve } from "node:path"
// @ts-ignore
import { presets } from '@orama/searchbox'
import { create, insertMultiple, save } from '@orama/orama'
import { JSDOM } from 'jsdom'
import MarkdownIt from 'markdown-it'
import matter from 'gray-matter'
import { LoadedContent, type LoadedVersion } from '@docusaurus/plugin-content-docs'
import { presets } from "@orama/searchbox"
import { create, insertMultiple, save } from "@orama/orama"
import { JSDOM } from "jsdom"
import MarkdownIt from "markdown-it"
import matter from "gray-matter"
import { checkIndexAccess, createSnapshot, deployIndex } from "./utils"

type CloudConfig = {
deploy: boolean,
endpoint: string
indexId: string,
oramaCloudAPIKey?: string
public_api_key: string,
}

type PluginOptions = {
analytics?: {
enabled: boolean
apiKey: string
indexId: string
}
},
cloud?: CloudConfig
}

export default function OramaPluginDocusaurus(
ctx: { siteDir: any; generatedFilesDir: any },
options: PluginOptions
): Plugin {
export default function OramaPluginDocusaurus(ctx: {
siteDir: any;
generatedFilesDir: any
}, options: PluginOptions): Plugin {
let versions: any[] = []

return {
name: '@orama/plugin-docusaurus-v3',
name: "@orama/plugin-docusaurus-v3",

getThemePath() {
return '../lib/theme'
return "../lib/theme"
},

getTypeScriptThemePath() {
return '../src/theme'
return "../src/theme"
},

getClientModules() {
return ['../lib/theme/SearchBar/index.css']
return ["../lib/theme/SearchBar/index.css"]
},

async contentLoaded({ actions, allContent }) {
const isDevelopment = process.env.NODE_ENV === 'development'
const pluginContentDocsIds = Object.keys(allContent['docusaurus-plugin-content-docs'] ?? {})
const loadedVersions = (allContent['docusaurus-plugin-content-docs']?.[pluginContentDocsIds[0]] as LoadedContent)
?.loadedVersions
versions = loadedVersions.map((v) => v.versionName)

await Promise.all(
versions.map((version) =>
buildDevSearchData(ctx.siteDir, ctx.generatedFilesDir, allContent, version, pluginContentDocsIds)
)
)

if (isDevelopment) {
actions.setGlobalData({
pluginContentDocsIds,
analytics: options.analytics,
searchData: Object.fromEntries(
await Promise.all(
versions.map(async (version) => {
return [version, readFileSync(indexPath(ctx.generatedFilesDir, version))]
})
)
)
})
} else {
actions.setGlobalData({ pluginContentDocsIds, searchData: {} })
async allContentLoaded({ actions, allContent }) {
const isDevelopment = process.env.NODE_ENV === "development"
let docsInstances: string[] = []
const oramaCloudAPIKey = options.cloud?.oramaCloudAPIKey
const searchDataConfig = [
{
docs: allContent["docusaurus-plugin-content-docs"]
},
{
blogs: allContent["docusaurus-plugin-content-blog"]
},
{
pages: allContent["docusaurus-plugin-content-pages"]
}
]

const deployConfig = options.cloud && {
enabled: options.cloud.deploy,
oramaCloudAPIKey,
indexId: options.cloud.indexId
}
const allOramaDocsPromises: Promise<any>[] = []

searchDataConfig.forEach((config) => {
const [key, value] = Object.entries(config)[0]
switch (key) {
case "docs":
Object.keys(value).forEach((docsInstance: any) => {
const loadedVersions = value?.[docsInstance]?.loadedVersions
versions = loadedVersions.map((v: any) => v.versionName)
docsInstances.push(docsInstance)
versions.flatMap(async (version) => {
const currentVersion = loadedVersions.find((v: any) => v.versionName === version)
allOramaDocsPromises.push(...currentVersion.docs.map((data: any) => generateDocs({
siteDir:ctx.siteDir,
version,
category: docsInstance,
data
})))
})
})
break
case "blogs":
const blogsInstances = Object.keys(value)
blogsInstances.forEach(async (instance) => {
const loadedInstance = value[instance]
allOramaDocsPromises.push(...loadedInstance.blogPosts.map(({ metadata }: any) => generateDocs({
siteDir: ctx.siteDir,
version: "current",
category: "blogs",
data: metadata
})))
})
break
case "pages":
const pagesInstances = Object.keys(value)
pagesInstances.forEach(async (instance) => {
const loadedInstance = value[instance]
allOramaDocsPromises.push(...loadedInstance.map((data: any) => generateDocs({
siteDir: ctx.siteDir,
version: "current",
category: "pages",
data
})))
})
break
}
})

const oramaDocs = [
...await Promise.all(allOramaDocsPromises)
]
.flat()
.map((data) => ({
title: data.title,
content: data.content,
section: data.originalTitle,
version: data.version,
path: data.path,
category: data.category
}))

await deployData({
oramaDocs,
generatedFilesDir: ctx.generatedFilesDir,
version: "current",
deployConfig
})

actions.setGlobalData({
...(isDevelopment && !options.cloud && {
searchData: Object.fromEntries([['current', readFileSync(indexPath(ctx.generatedFilesDir, 'current'))]])
}),
docsInstances,
availableVersions: versions,
analytics: options.analytics,
...(options.cloud && {
endpoint: {
url: options.cloud.endpoint,
key: options.cloud.public_api_key
}
}),
})
},

async postBuild({ outDir }) {
await Promise.all(
versions.map(async (version) => {
return cp(indexPath(ctx.generatedFilesDir, version), indexPath(outDir, version))
})
)
await cp(indexPath(ctx.generatedFilesDir, "current"), indexPath(outDir, "current"))
}
}
}

async function buildDevSearchData(
async function generateDocs({
siteDir,
version,
category,
data
}: {
siteDir: string,
generatedFilesDir: string,
allContent: any,
version: string,
pluginContentDocsIds: string[]
) {
const blogs: any[] = []
const pages: any[] = []
const docs: any[] = []
pluginContentDocsIds.forEach((key) => {
const loadedVersion = allContent['docusaurus-plugin-content-docs']?.[key]?.loadedVersions?.find(
(v: LoadedVersion) => v.versionName === version
)
blogs.push(
...(allContent['docusaurus-plugin-content-blog']?.[key]?.blogPosts?.map(({ metadata }: any) => metadata) ?? [])
)
pages.push(...(allContent['docusaurus-plugin-content-pages']?.[key] ?? []))
docs.push(...(loadedVersion?.docs ?? []))
})

const oramaDocs = [
...(await Promise.all(blogs.map((data: any) => generateDocs(siteDir, data)))),
...(await Promise.all(pages.map((data: any) => generateDocs(siteDir, data)))),
...(await Promise.all(docs.map((data: any) => generateDocs(siteDir, data))))
]
.flat()
.map((data) => ({
title: data.title,
content: data.content,
section: data.originalTitle,
path: data.path,
category: ''
}))

const db = await create({
schema: presets.docs.schema
})

await insertMultiple(db, oramaDocs as any)

const serializedOrama = JSON.stringify(await save(db))
const gzipedOrama = await gzip(serializedOrama)

writeFileSync(indexPath(generatedFilesDir, version), gzipedOrama)
}

async function generateDocs(siteDir: string, { title, permalink, source }: Record<string, string>) {
const fileContent = readFileSync(source.replace('@site', siteDir), 'utf-8')
category: string,
data: Record<string, string>
}) {
const { title, permalink, source } = data
const fileContent = readFileSync(source.replace("@site", siteDir), "utf-8")
const contentWithoutFrontMatter = matter(fileContent).content

return parseHTMLContent({
originalTitle: title,
version,
category,
html: new MarkdownIt().render(contentWithoutFrontMatter),
path: permalink
})
}

function parseHTMLContent({ html, path, originalTitle }: { html: any; path: any; originalTitle: any }) {
function parseHTMLContent({ html, path, originalTitle, version, category }: {
html: any;
path: any;
originalTitle: any,
version: string,
category: string
}) {
const dom = new JSDOM(html)
const document = dom.window.document

const sections: { originalTitle: any; title: string; header: string; content: string; path: any }[] = []
const sections: {
originalTitle: any;
title: string;
header: string;
content: string;
version: string;
category: string;
path: any
}[] = []

const headers = document.querySelectorAll('h1, h2, h3, h4, h5, h6')
const headers = document.querySelectorAll("h1, h2, h3, h4, h5, h6")
headers.forEach((header) => {
const sectionTitle = header.textContent?.trim()
const headerTag = header.tagName.toLowerCase()
let sectionContent = ''
let sectionContent = ""

let sibling = header.nextElementSibling
while (sibling && !['H1', 'H2', 'H3', 'H4', 'H5', 'H6'].includes(sibling.tagName)) {
sectionContent += sibling.textContent?.trim() + '\n'
while (sibling && !["H1", "H2", "H3", "H4", "H5", "H6"].includes(sibling.tagName)) {
sectionContent += sibling.textContent?.trim() + "\n"
sibling = sibling.nextElementSibling
}

sections.push({
originalTitle,
title: sectionTitle ?? '',
title: sectionTitle ?? "",
header: headerTag,
content: sectionContent,
version,
category,
path
})
})
@@ -170,7 +231,37 @@ function parseHTMLContent({ html, path, originalTitle }: { html: any; path: any;
}

function indexPath(outDir: string, version: string) {
return resolve(outDir, 'orama-search-index-@VERSION@.json.gz'.replace('@VERSION@', version))
return resolve(outDir, "orama-search-index-@VERSION@.json.gz".replace("@VERSION@", version))
}

const gzip = promisify(gzipCB)
async function deployData({
oramaDocs,
generatedFilesDir,
version,
deployConfig
}: {
oramaDocs: any[],
generatedFilesDir: string,
version: string,
deployConfig: { indexId: string, enabled: boolean, oramaCloudAPIKey: string | undefined } | undefined
}) {
const { ORAMA_CLOUD_BASE_URL } = process.env
const baseUrl = ORAMA_CLOUD_BASE_URL || "https://cloud.oramasearch.com"

if (deployConfig?.enabled) {
await checkIndexAccess(baseUrl, deployConfig.oramaCloudAPIKey!, deployConfig.indexId!)
await createSnapshot(baseUrl, deployConfig.oramaCloudAPIKey!, deployConfig.indexId!, oramaDocs)
await deployIndex(baseUrl, deployConfig.oramaCloudAPIKey!, deployConfig.indexId!)

} else {
const db = await create({
schema: { ...presets.docs.schema, version: "enum" }
})

await insertMultiple(db, oramaDocs as any)

const serializedOrama = JSON.stringify(await save(db))
const gzipedOrama = gzip(serializedOrama)
writeFileSync(indexPath(generatedFilesDir, version), gzipedOrama)
}
}
116 changes: 4 additions & 112 deletions packages/plugin-docusaurus-v3/src/theme/SearchBar/index.css
Original file line number Diff line number Diff line change
@@ -1,120 +1,12 @@
[data-theme=light] .DocSearch {
--docsearch-muted-color: var(--ifm-color-emphasis-700);
--docsearch-container-background: rgba(94,100,112,.7);
--docsearch-modal-background: var(--ifm-color-secondary-lighter);
--docsearch-searchbox-background: var(--ifm-color-secondary);
--docsearch-searchbox-focus-background: var(--ifm-color-white);
--docsearch-hit-background: var(--ifm-color-white);
--docsearch-footer-background: var(--ifm-color-white)
}

[data-theme=dark] .DocSearch {
--docsearch-text-color: var(--ifm-font-color-base);
--docsearch-muted-color: var(--ifm-color-secondary-darkest);
--docsearch-container-background: rgba(47,55,69,.7);
--docsearch-modal-background: var(--ifm-background-color);
--docsearch-searchbox-background: var(--ifm-background-color);
--docsearch-searchbox-focus-background: var(--ifm-color-black);
--docsearch-hit-background: var(--ifm-color-emphasis-100);
--docsearch-footer-background: var(--ifm-background-surface-color);
--docsearch-key-gradient: linear-gradient(-26.5deg,var(--ifm-color-emphasis-200) 0%,var(--ifm-color-emphasis-100) 100%)
}

.DocSearch-Button-Container,.checkboxList_TMoE,.filterCheckbox_IByC,.showcaseFavoriteHeader_INmp {
align-items: center;
display: flex
}

.DocSearch-Button {
align-items: center;
background: var(--docsearch-searchbox-background);
border: 0;
border-radius: 40px;
color: var(--docsearch-muted-color);
cursor: pointer;
display: flex;
font-weight: 500;
height: 36px;
justify-content: space-between;
padding: 0 8px;
-webkit-user-select: none;
user-select: none
}

.DocSearch-Button:active,.DocSearch-Button:focus,.DocSearch-Button:hover {
background: var(--docsearch-searchbox-focus-background);
box-shadow: var(--docsearch-searchbox-shadow);
color: var(--docsearch-text-color);
outline: 0
}

.DocSearch-Search-Icon {
stroke-width: 1.6
}

.DocSearch-Button .DocSearch-Search-Icon {
color: var(--docsearch-text-color)
}

.DocSearch-Button-Placeholder {
font-size: 1rem;
padding: 0 12px 0 6px
}

.DocSearch-Input,.DocSearch-Link {
-webkit-appearance: none;
font: inherit
}

.DocSearch-Button-Keys {
display: flex;
min-width: calc(40px + .8em)
}

[data-theme=light] .DocSearch-Button-Key {
align-items: center;
background: #fff;
.DocSearch-Button kbd {
border: 0;
border-radius: 3px;
box-shadow: #cdcdcd 0px 3px 6px 0px;
color: var(--docsearch-muted-color);
display: flex;
height: 18px;
justify-content: center;
margin-right: 0.4em;
padding: 0 0 2px;
position: relative;
top: -1px;
width: 20px;
}

[data-theme=dark] .DocSearch-Button-Key {
align-items: center;
background: #4b4b4b;
border: 0;
border-radius: 3px;
box-shadow: var(--docsearch-key-shadow);
color: var(--docsearch-muted-color);
display: flex;
height: 18px;
justify-content: center;
margin-right: 0.4em;
padding: 0 0 2px;
position: relative;
top: -1px;
width: 20px;
}

.DocSearch--active {
overflow: hidden!important
}

.DocSearch-Container {
background-color: var(--docsearch-container-background);
height: 100vh;
left: 0;
position: fixed;
top: 0;
width: 100vw;
z-index: 200
box-shadow: none;
font-size: .8rem !important;
padding: 0 !important;
}
179 changes: 82 additions & 97 deletions packages/plugin-docusaurus-v3/src/theme/SearchBar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,128 +1,113 @@
// @ts-nocheck
import React, { useEffect, useMemo, useState } from 'react'
import useBaseUrl from '@docusaurus/useBaseUrl'
import { useLocation } from '@docusaurus/router'
import useIsBrowser from '@docusaurus/useIsBrowser'
import { useActiveVersion, useVersions } from '@docusaurus/plugin-content-docs/client'
import { useColorMode, useDocsPreferredVersion } from '@docusaurus/theme-common'
import { usePluginData } from '@docusaurus/useGlobalData'
import { ungzip } from 'pako'
import { RegisterSearchBox, presets, signals as $, events } from '@orama/searchbox'
import '@orama/searchbox/dist/index.css'
import React, { useEffect, useState } from "react"
import useBaseUrl from "@docusaurus/useBaseUrl"
import { useLocation } from "@docusaurus/router"
import useIsBrowser from "@docusaurus/useIsBrowser"
import { useActiveVersion } from "@docusaurus/plugin-content-docs/client"
import { useColorMode, useDocsPreferredVersion } from "@docusaurus/theme-common"
import { usePluginData } from "@docusaurus/useGlobalData"
import { ungzip } from "pako"
import { SearchBox, SearchButton, presets } from "@orama/searchbox"
import { OramaClient } from "@oramacloud/client"
import { create, insertMultiple } from "@orama/orama"
import { pluginAnalytics } from "@orama/plugin-analytics"
import "@orama/searchbox/dist/index.css"

export function OramaSearch() {
const [oramaInstance, setOramaInstance] = useState(null)
const [searchBoxConfig, setSearchBoxConfig] = useState(null)
const { pathname } = useLocation()

const { searchData, analytics, pluginContentDocsIds } = usePluginData('@orama/plugin-docusaurus-v3')
const pluginId = pluginContentDocsIds.filter((id: string) => pathname.includes(id))[0] || pluginContentDocsIds[0]
const baseURL = useBaseUrl('orama-search-index-@VERSION@.json.gz')
const {
searchData,
endpoint,
analytics,
docsInstances
} = usePluginData("@orama/plugin-docusaurus-v3")
const pluginId = docsInstances.filter((id: string) => pathname.includes(id))[0] || docsInstances[0]
const baseURL = useBaseUrl("orama-search-index-current.json.gz")
const isBrowser = useIsBrowser()
const { colorMode } = useColorMode()
const activeVersion = useActiveVersion(pluginId)
const versions = useVersions(pluginId)
const { preferredVersion } = useDocsPreferredVersion(pluginId)
const { colorMode } = useColorMode()

const version = useMemo(() => {
if (!isBrowser) {
return undefined
} else if (activeVersion) {
return activeVersion
} else if (preferredVersion) {
return preferredVersion
}

return versions.find((v) => v.isLast) ?? versions[0]
}, [isBrowser, activeVersion, preferredVersion, versions])

useEffect(() => {
$.colorScheme.value = colorMode
}, [colorMode])

useEffect(() => {
window.addEventListener(events.seeItem, (event) => {
try {
const path = event.detail.item.document.path
window.location.pathname = path
} catch (e) {
console.error(e)
}
})

return () => {
window.removeEventListener(events.seeItem, () => {})
}
}, [])
const currentVersion = activeVersion || preferredVersion

useEffect(() => {
async function loadOrama() {
let buffer

if (searchData[version.name]) {
buffer = searchData[version.name].data
if (endpoint) {
setSearchBoxConfig({
oramaInstance: new OramaClient({
endpoint: endpoint.url,
api_key: endpoint.key
})
})
} else {
const searchResponse = await fetch(baseURL.replace('@VERSION@', version.name))
let buffer

if (searchData.current) {
buffer = searchData.current.data
} else {
const searchResponse = await fetch(baseURL)

if (searchResponse.status === 0) {
throw new Error(`Network error: ${await searchResponse.text()}`)
} else if (searchResponse.status !== 200) {
throw new Error(`HTTP error ${searchResponse.status}: ${await searchResponse.text()}`)
}

if (searchResponse.status === 0) {
throw new Error(`Network error: ${await searchResponse.text()}`)
} else if (searchResponse.status !== 200) {
throw new Error(`HTTP error ${searchResponse.status}: ${await searchResponse.text()}`)
buffer = await searchResponse.arrayBuffer()
}

buffer = await searchResponse.arrayBuffer()
}
const deflated = ungzip(buffer, { to: "string" })
const parsedDeflated = JSON.parse(deflated)

const db = await create({
schema: { ...presets.docs.schema, version: "enum" },
plugins: [
...(analytics && [
pluginAnalytics({
apiKey: analytics.apiKey,
indexId: analytics.indexId,
})
] ?? [])
]
})

const deflated = ungzip(buffer, { to: 'string' })
await insertMultiple(db, Object.values(parsedDeflated.docs.docs))

setOramaInstance(deflated)
setSearchBoxConfig({
oramaInstance: db
})
}
}

if (!isBrowser || !version) {
if (!isBrowser) {
return
}

loadOrama(version).catch((error) => {
console.error('Cannot load search index.', error)
loadOrama().catch((error) => {
console.error("Cannot load search index.", error)
})
}, [isBrowser, searchData, baseURL, version])
}, [isBrowser])

useEffect(() => {
if (oramaInstance) {
if (customElements.get('orama-searchbox') === undefined) {
RegisterSearchBox({
oramaInstance,
preset: presets.docs.name,
show: false,
colorScheme: colorMode,
analytics
})
const searchParams = {
...(currentVersion && {
where: {
version: { "eq": currentVersion.name }
}
}
}, [oramaInstance])
})
}

return (
<div>
<button className="DocSearch DocSearch-Button" onClick={() => $.setShow(true)}>
<span className="DocSearch-Button-Container">
<svg width="20" height="20" className="DocSearch-Search-Icon" viewBox="0 0 20 20">
<path
d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z"
stroke="currentColor"
fill="none"
fillRule="evenodd"
strokeLinecap="round"
strokeLinejoin="round"
></path>
</svg>
<span className="DocSearch-Button-Placeholder">Search</span>
</span>
<span className="DocSearch-Button-Keys">
<kbd className="DocSearch-Button-Key"></kbd>
<kbd className="DocSearch-Button-Key">K</kbd>
</span>
</button>

{oramaInstance && <orama-searchbox />}
<SearchButton colorScheme={colorMode} className="DocSearch-Button" />
{searchBoxConfig && (
<SearchBox
{...searchBoxConfig}
colorScheme={colorMode}
searchParams={searchParams}
facetProperty="category"
/>
)}
</div>
)
}
91 changes: 91 additions & 0 deletions packages/plugin-docusaurus-v3/src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
export const restFetcher = async <T = unknown>(url: string, options?: any): Promise<T> => {
const response = await fetch(url, options)

if (response.status === 0) {
throw new Error(`Request failed (network error): ${await response.text()}`)
} else if (response.status >= 400) {
const error = new Error(`Request failed (HTTP error ${response.status})}`)

;(error as any).response = response

throw error
}

return await response.json()
}

export const postFetcher = async <T = unknown>(url: string, body: any, headers?: any): Promise<T> => {
return await restFetcher(url, {
method: 'POST',
headers: {
...headers,
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
})
}

export async function loggedOperation(preMessage: string, fn: () => Promise<any>, postMessage: string) {
if (preMessage != null) {
console.debug(preMessage)
}

try {
const response = await fn()

if (postMessage != null) {
console.debug(postMessage)
}

return response
} catch (error: any) {
throw new Error(`Error: ${error.message}`)
}
}

export async function checkIndexAccess(baseUrl: string, APIKey: string, indexId: string) {
const result = await loggedOperation(
'Start: Check index access',
async () => await restFetcher(
`${baseUrl}/api/v1/indexes/get-index?id=${indexId}`,
{
headers: {
Authorization: `Bearer ${APIKey}`
}
}
),
'End: Check index access (success)'
)

return { endpoint: result?.api_endpoint, api_key: result?.api_key }
}

export async function createSnapshot(baseUrl: string, APIKey: string, indexId: string, documents: any[]) {
await loggedOperation(
'Start: Create snapshot',
async () =>
await postFetcher(
`${baseUrl}/api/v1/webhooks/${indexId}/snapshot`,
documents,
{
Authorization: `Bearer ${APIKey}`
}
),
'End: Create snapshot (success)'
)
}

export async function deployIndex(baseUrl: string, APIKey: string, indexId: string) {
await loggedOperation(
'Start: Deploy index',
async () =>
await postFetcher(
`${baseUrl}/api/v1/webhooks/${indexId}/deploy`,
{},
{
Authorization: `Bearer ${APIKey}`
}
),
'End: Deploy index (success)'
)
}
816 changes: 781 additions & 35 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

0 comments on commit 03d6053

Please sign in to comment.