import { figmaRequest } from './client.ts' import { mapImageMap } from './models.ts' import { normalizeNodeIds, parseFileKey } from './setup.ts' import type { FigmaAuthInput, FigmaImageMap } from './types.ts' import { compactRecord, optionalBoolean, optionalNumber, optionalString, requireRecord, requireStringArray, } from './types.ts' import { requireAuthMode } from './auth.ts' export type GetImagesInput = FigmaAuthInput & { /** File key, or a figma.com file/design/board URL. */ fileKey: string /** Node ids to render. Hyphenated URL ids (`1-2`) are accepted. */ ids: Array | string format?: 'jpg' | 'png' | 'svg' | 'pdf' scale?: number svgOutlineText?: boolean svgIncludeId?: boolean svgSimplifyStroke?: boolean useAbsoluteBounds?: boolean version?: string } /** * Render images for nodes in a Figma file. Needs `file_content:read`. * @example * import getImages from 'kody:@kody/figma/get-images' * const { images } = await getImages({ fileKey: 'abc123', ids: ['12:34'], format: 'png' }) */ export async function getImages(input: GetImagesInput): Promise { const fileKey = parseFileKey(input.fileKey) const ids = normalizeNodeIds(requireStringArray(input.ids, 'ids')) const format = optionalString(input.format, 'format') if (format && format !== 'jpg' && format !== 'png' && format !== 'svg' && format !== 'pdf') { throw new Error('format must be jpg, png, svg, or pdf.') } const scale = optionalNumber(input.scale, 'scale') if (scale !== undefined && (scale < 0.01 || scale > 4)) { throw new Error('scale must be between 0.01 and 4.') } const result = await figmaRequest({ ...input, operation: 'files.read', path: `/v1/images/${encodeURIComponent(fileKey)}`, query: compactRecord({ ids: ids.join(','), format, scale, svg_outline_text: optionalBoolean(input.svgOutlineText, 'svgOutlineText'), svg_include_id: optionalBoolean(input.svgIncludeId, 'svgIncludeId'), svg_simplify_stroke: optionalBoolean(input.svgSimplifyStroke, 'svgSimplifyStroke'), use_absolute_bounds: optionalBoolean(input.useAbsoluteBounds, 'useAbsoluteBounds'), version: optionalString(input.version, 'version'), }), }) return mapImageMap(fileKey, result.body) } /** * Render images for nodes in a Figma file. * @example * import getImages from 'kody:@kody/figma/get-images' * const result = await getImages({ fileKey: 'abc123', ids: '1-2', format: 'png' }) */ export default async function getImagesEntrypoint( params: Partial & Record = {}, ) { const input = requireRecord(params, 'get-images') return getImages({ fileKey: String(input.fileKey ?? input.fileUrl ?? ''), ids: input.ids as GetImagesInput['ids'], format: optionalString(input.format, 'format') as GetImagesInput['format'], scale: input.scale as number | undefined, svgOutlineText: optionalBoolean(input.svgOutlineText, 'svgOutlineText'), svgIncludeId: optionalBoolean(input.svgIncludeId, 'svgIncludeId'), svgSimplifyStroke: optionalBoolean(input.svgSimplifyStroke, 'svgSimplifyStroke'), useAbsoluteBounds: optionalBoolean(input.useAbsoluteBounds, 'useAbsoluteBounds'), version: optionalString(input.version, 'version'), integrationName: optionalString(input.integrationName, 'integrationName'), integration: optionalString(input.integration, 'integration'), account: optionalString(input.account, 'account'), secretName: optionalString(input.secretName, 'secretName'), auth: requireAuthMode(input.auth), }) }