Skip to main content
Glama
util.ts4.99 kB
import { Ref, unref } from "vue"; import { BRAND_COLOR_FILTER_HEX_CODES, IconNames, } from "@si/vue-lib/design-system"; import { AttributeTree, AttributeValue, } from "@/workers/types/entity_kind_types"; import { AttributePath } from "@/api/sdf/dal/component"; import { Toggle } from "./logic_composables/toggle_containers"; export type BrandColorKey = keyof typeof BRAND_COLOR_FILTER_HEX_CODES; export const getAssetColor = (name: string) => { const lowerCaseName = name.toLowerCase(); const key = ( Object.keys(BRAND_COLOR_FILTER_HEX_CODES) as BrandColorKey[] ).find((key) => lowerCaseName.startsWith(key.toLowerCase())); return key ? BRAND_COLOR_FILTER_HEX_CODES[key] : BRAND_COLOR_FILTER_HEX_CODES.Custom; // fallback to Custom }; export const pickBrandIconByString = (name: string): IconNames => { if (name.toLowerCase().includes("aws")) return "logo-aws"; else if ( name.toLowerCase().includes("microsoft") || name.toLowerCase().includes("azure") ) { return "logo-azure"; } else if ( name.toLowerCase().includes("google cloud") || name.toLowerCase().includes("gcp") ) { return "logo-google-cloud"; } else if ( name.toLowerCase().includes("digitalocean") || name.toLowerCase().includes("digital ocean") ) { return "logo-digital-ocean"; } else if (name.toLowerCase().includes("coreos")) return "logo-coreos"; else if (name.toLowerCase().includes("docker")) return "logo-docker"; else if (name.toLowerCase().includes("fastly")) return "logo-fastly"; else if (name.toLowerCase().includes("hetzner")) return "logo-hetzner"; else if (name.toLowerCase().includes("kubernetes")) return "logo-k8s"; else return "logo-si"; }; /** * Specify the height of a collapsed grid when its closed (e.g. just enough to show a header) * When its open use the fractional unit so it grows to the available size, sharing the remaining space with other open grid items */ export const gridCollapseStyle = (open: boolean | Ref<boolean, boolean>) => unref(open) ? "1fr" : "2.5em"; /** * Generates the styles for a vertical grid of collapsing panels * * @param gridStates a list of open / closed states that represent the grid items * @returns { gridTemplateRows: string of sizes in the grid order you passed in } */ export const collapsingGridStyles = ( gridStates: (Pick<Toggle, "open"> | undefined)[], ): Record<string, string> => { // NOTE: the optional `gs` and coalesce is for rendering states before template refs are instantiated (that is what the | undefined above represents) const sizes = gridStates.map((gs): string => gridCollapseStyle(gs?.open ?? true), ); return { gridTemplateRows: sizes.join(" "), }; }; // Used in the component page vue components export const findAvsAtPropPath = (data: AttributeTree, parts: string[]) => { const path = parts.join("/"); const propId = Object.keys(data.props).find((pId) => { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const p = data.props[pId]!; if (p.path === path) return true; return false; }); if (!propId) return null; const avIds = Object.keys(data.attributeValues).filter((avId) => { const a = data.attributeValues[avId]; if (a?.propId === propId) return true; return false; }); if (avIds.length === 0) return null; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const prop = data.props[propId]!; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const attributeValues = avIds.map((avId) => data.attributeValues[avId]!); return { prop, attributeValues }; }; export const findAttributeValueInTree = ( tree: AttributeTree, targetPath: AttributePath, ): { attributeValue: AttributeValue; avId: string } | null => { const pathStr = targetPath.toString(); for (const [avId, av] of Object.entries(tree.attributeValues)) { if (av.path === pathStr) { return { attributeValue: av, avId }; } } return null; }; export function objectKeys<T extends object>(obj: T): Array<keyof T> { return Object.keys(obj) as Array<keyof T>; } export const openWorkspaceMigrationDocumentation = () => { globalThis.window?.open( "https://docs.systeminit.com/explanation/workspace-migration", "_blank", ); }; /** * Escapes a string segment for use in a JSON Pointer (RFC 6901). * JSON Pointers use '~' as an escape character: * - '~' must be encoded as '~0' * - '/' must be encoded as '~1' * * @param segment - The string segment to escape * @returns The escaped segment safe for use in a JSON Pointer path * * @example * escapeJsonPointerSegment("test/paul") // returns "test~1paul" * escapeJsonPointerSegment("a~b") // returns "a~0b" * escapeJsonPointerSegment("test/~foo") // returns "test~1~0foo" */ export function escapeJsonPointerSegment(segment: string): string { // Order matters: escape ~ first, then / return segment.replace(/~/g, "~0").replace(/\//g, "~1"); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server