/** * @fileoverview Shared Figma types: `JsonRecord`, `FigmaAuthMode`, `FigmaAuthInput`, `FigmaUserRef`, `FigmaNodeSummary`, `FigmaFileSummary`, `FigmaFileMeta`, `FigmaNodeBundle`, and related shapes. * Import from `kody:@kody/figma/types` when typing Figma helpers. Default export returns a type-name catalog. * * @example * import { type FigmaAuthMode } from 'kody:@kody/figma/types' */ export type JsonRecord = Record export type FigmaAuthMode = 'oauth' | 'pat' export type FigmaAuthInput = { /** Saved OAuth integration name. Defaults to `figma`. */ integrationName?: string /** Alias of `integrationName`. */ integration?: string /** * Short account alias. `work` → `figma-work`. Values that already start * with `figma-` are used as-is. `default` / `figma` / omitted → `figma`. */ account?: string /** User secret name for a personal or plan access token. Defaults to `figmaPat`. */ secretName?: string /** Force OAuth or PAT auth when both exist. */ auth?: FigmaAuthMode } export type FigmaUserRef = { id: string handle: string | null } export type FigmaNodeSummary = { id: string name: string type: string visible: boolean children: Array } export type FigmaFileSummary = { fileKey: string name: string lastModified: string | null version: string | null role: string | null editorType: string | null thumbnailUrl: string | null document: FigmaNodeSummary | null componentCount: number styleCount: number } export type FigmaFileMeta = { fileKey: string name: string lastModified: string | null thumbnailUrl: string | null creator: FigmaUserRef | null lastTouchedBy: FigmaUserRef | null folderName: string | null editorType: string | null role: string | null version: string | null linkAccess: string | null url: string | null } export type FigmaNodeBundle = { id: string document: FigmaNodeSummary | null componentCount: number styleCount: number } export type FigmaComment = { id: string message: string | null fileKey: string parentId: string | null createdAt: string | null resolvedAt: string | null orderId: string | null user: FigmaUserRef | null clientMeta: JsonRecord | null reactions: Array<{ emoji: string; count: number }> } export type FigmaComponent = { key: string fileKey: string | null nodeId: string | null name: string description: string | null thumbnailUrl: string | null containingFrameName: string | null createdAt: string | null updatedAt: string | null } export type FigmaStyle = { key: string fileKey: string | null nodeId: string | null name: string description: string | null styleType: string | null thumbnailUrl: string | null createdAt: string | null updatedAt: string | null } export type FigmaImageMap = { fileKey: string images: Array<{ nodeId: string; url: string | null }> error: string | null } export type FigmaImageFill = { hash: string url: string } export type DryRunResult = { dryRun: true wouldCall: T } /** * Shared Figma types and parsing helpers for this package. * Import from `kody:@kody/figma/types` when typing other Figma exports. * * @returns Catalog of exported type/helper names for agent discovery. * * @example * import types from 'kody:@kody/figma/types' * const catalog = await types() */ export function requireRecord(value: unknown, label: string): JsonRecord { if (!value || typeof value !== 'object' || Array.isArray(value)) { throw new Error(`${label} must be an object.`) } return value as JsonRecord } export function requireString( value: unknown, label: string, options: { allowEmpty?: boolean } = {}, ): string { if (typeof value !== 'string' || (!options.allowEmpty && value.trim().length === 0)) { throw new Error( `${label} must be ${options.allowEmpty ? 'a string' : 'a non-empty string'}.`, ) } return options.allowEmpty ? value : value.trim() } export function optionalString(value: unknown, label: string): string | undefined { if (value === undefined || value === null) return undefined return requireString(value, label) } export function optionalBoolean(value: unknown, label: string): boolean | undefined { if (value === undefined) return undefined if (typeof value !== 'boolean') throw new Error(`${label} must be a boolean.`) return value } export function optionalNumber(value: unknown, label: string): number | undefined { if (value === undefined || value === null) return undefined if (typeof value !== 'number' || Number.isNaN(value)) { throw new Error(`${label} must be a number.`) } return value } export function clampInt( value: unknown, min: number, max: number, fallback: number, label = 'limit', ): number { if (value === undefined || value === null) return fallback if (typeof value !== 'number' || !Number.isInteger(value)) { throw new Error(`${label} must be an integer.`) } if (value < min || value > max) { throw new Error(`${label} must be between ${min} and ${max}.`) } return value } export function compactRecord(value: T): T { const output: JsonRecord = {} for (const [key, item] of Object.entries(value)) { if (item === undefined) continue output[key] = item } return output as T } export function requireStringArray(value: unknown, label: string): Array { if (typeof value === 'string') { return value .split(',') .map((item) => item.trim()) .filter((item) => item.length > 0) } if (!Array.isArray(value) || value.length === 0) { throw new Error(`${label} must be a non-empty string or array of strings.`) } return value.map((item, index) => requireString(item, `${label}[${index}]`)) } export function optionalStringArray(value: unknown, label: string): Array | undefined { if (value === undefined || value === null) return undefined return requireStringArray(value, label) } /** * Shared Figma types for this package: `JsonRecord`, `FigmaAuthMode`, `FigmaAuthInput`, `FigmaUserRef`, `FigmaNodeSummary`, `FigmaFileSummary`, `FigmaFileMeta`, `FigmaNodeBundle`, and related shapes. * Import from `kody:@kody/figma/types` when typing Figma helpers without pulling runtime clients. * * @returns Catalog of exported type names for agent discovery. * * @example * import types from 'kody:@kody/figma/types' * const catalog = await types() */ export default async function typesOverview() { return { auth: ['FigmaAuthInput', 'FigmaAuthMode'], models: [ 'FigmaFileSummary', 'FigmaFileMeta', 'FigmaNodeSummary', 'FigmaComment', 'FigmaComponent', 'FigmaStyle', 'FigmaImageMap', ], } }