Skip to content
← Public packages

@kody/integrations-sh

Client for the public integrations.sh registry: search, detect, cached surface, and live discover.

src/types.ts

161 lines · 4.4 KB · TypeScript
import { isRecord } from './is-record.ts'
import { isSurfaceKind, type SurfaceKind } from './urls.ts'

export type SearchSurface = {
	kind: SurfaceKind
	slug: string
	url?: string
	icon?: string
}

export type SearchResult = {
	domain: string
	name: string
	description: string
	kinds: Array<SurfaceKind>
	url: string
	surfaces: Array<SearchSurface>
}

export type Credential = {
	type: string
	label?: string
	setup?: string
	generateUrl?: string
	acquisition?: string
}

export type Surface = {
	type: string
	slug?: string
	name?: string
	url?: string
	spec?: string
	docs?: string
	evidence?: Array<string>
}

export type SurfaceDocument = {
	domain: string
	summary: string | null
	description: string | null
	discoveredAt: string | null
	credentials: Record<string, Credential>
	surfaces: Array<Surface>
}

export function stringOrUndefined(value: unknown): string | undefined {
	return typeof value === 'string' && value.length > 0 ? value : undefined
}

export function mapSearchResult(value: unknown): SearchResult | null {
	if (!isRecord(value) || typeof value.domain !== 'string') {
		return null
	}
	const kinds = Array.isArray(value.kinds)
		? value.kinds.filter(isSurfaceKind)
		: []
	const surfaces = Array.isArray(value.surfaces)
		? value.surfaces.flatMap((surface): Array<SearchSurface> => {
				if (!isRecord(surface) || !isSurfaceKind(surface.kind)) {
					return []
				}
				if (typeof surface.slug !== 'string' || surface.slug.length === 0) {
					return []
				}
				return [
					{
						kind: surface.kind,
						slug: surface.slug,
						...(stringOrUndefined(surface.url)
							? { url: stringOrUndefined(surface.url) }
							: {}),
						...(stringOrUndefined(surface.icon)
							? { icon: stringOrUndefined(surface.icon) }
							: {}),
					},
				]
			})
		: []
	return {
		domain: value.domain,
		name: typeof value.name === 'string' ? value.name : value.domain,
		description: typeof value.description === 'string' ? value.description : '',
		kinds,
		url: typeof value.url === 'string' ? value.url : '',
		surfaces,
	}
}

export function mapCredentials(value: unknown): Record<string, Credential> {
	if (!isRecord(value)) {
		return {}
	}
	const mapped: Record<string, Credential> = {}
	for (const [id, entry] of Object.entries(value)) {
		if (!isRecord(entry)) {
			continue
		}
		mapped[id] = {
			type: typeof entry.type === 'string' ? entry.type : '',
			...(stringOrUndefined(entry.label) ? { label: stringOrUndefined(entry.label) } : {}),
			...(stringOrUndefined(entry.setup) ? { setup: stringOrUndefined(entry.setup) } : {}),
			...(stringOrUndefined(entry.generateUrl)
				? { generateUrl: stringOrUndefined(entry.generateUrl) }
				: {}),
			...(stringOrUndefined(entry.acquisition)
				? { acquisition: stringOrUndefined(entry.acquisition) }
				: {}),
		}
	}
	return mapped
}

export function mapSurfaces(value: unknown): Array<Surface> {
	if (!Array.isArray(value)) {
		return []
	}
	return value.flatMap((surface): Array<Surface> => {
		if (!isRecord(surface)) {
			return []
		}
		const basis = isRecord(surface.basis) ? surface.basis : null
		return [
			{
				type: typeof surface.type === 'string' ? surface.type : '',
				...(stringOrUndefined(surface.slug) ? { slug: stringOrUndefined(surface.slug) } : {}),
				...(stringOrUndefined(surface.name) ? { name: stringOrUndefined(surface.name) } : {}),
				...(stringOrUndefined(surface.url) ? { url: stringOrUndefined(surface.url) } : {}),
				...(stringOrUndefined(surface.spec) ? { spec: stringOrUndefined(surface.spec) } : {}),
				...(stringOrUndefined(surface.docs) ? { docs: stringOrUndefined(surface.docs) } : {}),
				...(Array.isArray(basis?.evidence)
					? {
							evidence: basis.evidence.filter(
								(item): item is string => typeof item === 'string',
							),
						}
					: {}),
			},
		]
	})
}

export function mapSurfaceDocument(value: unknown): SurfaceDocument | null {
	if (!isRecord(value) || typeof value.domain !== 'string') {
		return null
	}
	return {
		domain: value.domain,
		summary: typeof value.summary === 'string' ? value.summary : null,
		description: typeof value.description === 'string' ? value.description : null,
		discoveredAt: typeof value.discoveredAt === 'string' ? value.discoveredAt : null,
		credentials: mapCredentials(value.credentials),
		surfaces: mapSurfaces(value.surfaces),
	}
}

export function hasUsableRegistryData(document: SurfaceDocument): boolean {
	return (
		document.surfaces.length > 0 || Object.keys(document.credentials).length > 0
	)
}