UNPKG

@useorbis/db-sdk

Version:

Orbis' Typescript SDK for building open-data experiences.

150 lines (149 loc) 4.39 kB
import { OrbisError } from "../util/results.js"; function buildUrl(node, route) { const _route = route.startsWith("/") ? route : "/" + route; return node.gateway + _route; } async function apiFetch(node, route, opts) { if (node.key) { if (opts) { opts.headers = { ...(opts.headers || {}), "x-orbis-api-key": node.key, }; } } const url = buildUrl(node, route); return fetch(url, opts); } async function ping(node) { const response = await apiFetch(node, "/api/ping"); const text = await response.text(); if (text === "pong") { return true; } return false; } async function fetchMetadata(node) { const response = await apiFetch(node, "/api/metadata"); return (await response.json()); } export async function queryDatabase(node, jsonQuery, env) { const environment = env || node.env; const response = await apiFetch(node, "/api/db/query/json", { method: "POST", headers: { "Content-type": "application/json", }, body: JSON.stringify({ jsonQuery, env: environment }), }); if (![200, 404].includes(response.status)) { throw new OrbisError(`Error querying database. Status code: ${response.status || "Unknown"} (${response.statusText || response.status || ""})`, { node, query: jsonQuery, environment }); } const { data = [] } = await response.json(); return { columns: data.length ? Object.keys(data[0]) : [], rows: data, }; } export class OrbisNode { node; constructor(node) { this.node = node; } get env() { return this.node.env; } async query(jsonQuery, env) { return queryDatabase(this.node, jsonQuery, env); } async fetch(route, opts) { return apiFetch(this.node, route, opts); } async ping() { return { pong: await ping(this.node), node: this.node, }; } async metadata(forceRefresh = false) { if (this.node.metadata && !forceRefresh) { const { metadata, ...node } = this.node; return { metadata, node, }; } try { const result = await fetchMetadata(this.node); this.node.metadata = result; const { metadata, ...node } = this.node; return { metadata, node, }; } catch (e) { console.log("Couldn't retrieve metadata for this OrbisDB instance."); return { metadata: null, node: this.node, }; } } async models() { const { metadata, ...node } = await this.metadata(); return { models: metadata?.models, node, }; } async plugins() { const { metadata, ...node } = await this.metadata(); return { plugins: metadata?.plugins, node, }; } // Add a method to get the human-readable table name for a model ID async getTableName(id) { const { metadata, ...node } = await this.metadata(); return { tableName: metadata?.models_mapping[id], node, }; } // Add a method to get the model ID for a human-readable table name async getTableModelId(tableName) { const { metadata, ...node } = this.node; const modelsMapping = metadata?.models_mapping; const modelId = Object.keys(modelsMapping || {}).find((key) => { return modelsMapping && tableName === modelsMapping[key]; }); return { modelId, node, }; } } export class OrbisNodeManager { #nodes; #currentNode; constructor(nodes) { if (!nodes.length) { throw "[OrbisNodeManager] You must provide at least one (1) OrbisNode configuration."; } this.#nodes = nodes.map(({ gateway, key, env }, index) => new OrbisNode({ gateway: gateway.replace(/\/$/, ""), isPrimary: index === 0, key, env, })); this.#currentNode = this.#nodes[0]; } get nodes() { return this.#nodes; } get active() { return this.#currentNode; } }