Skip to content

Built for people who want to own their automations. Join the waitlist for an invite.

Package listing

@kody/figma

src/get-file.ts

71 lines · 2.5 KB · TypeScript
import { figmaRequest } from './client.ts'
import { mapFile } from './models.ts'
import { normalizeNodeIds, parseFileKey } from './setup.ts'
import type { FigmaAuthInput, FigmaFileSummary } from './types.ts'
import {
	clampInt,
	compactRecord,
	optionalString,
	optionalStringArray,
	requireRecord,
} from './types.ts'
import { requireAuthMode } from './auth.ts'

export type GetFileInput = FigmaAuthInput & {
	/** File key, or a figma.com file/design/board URL. */
	fileKey: string
	/** Optional node ids. Hyphenated URL ids (`1-2`) are accepted. */
	ids?: Array<string> | string
	/** Document traversal depth. Defaults to 1 (pages only) to keep payloads slim. */
	depth?: number
	version?: string
	geometry?: 'paths'
}

/**
 * Load slim Figma file JSON (name, pages, component/style counts).
 * Defaults to `depth: 1`. Use `./get-file-nodes` for specific layers.
 * @example
 * import getFile from 'kody:@kody/figma/get-file'
 * const file = await getFile({ fileKey: 'abc123' })
 */
export async function getFile(input: GetFileInput): Promise<FigmaFileSummary> {
	const fileKey = parseFileKey(input.fileKey)
	const ids = optionalStringArray(input.ids, 'ids')
	const result = await figmaRequest<unknown>({
		...input,
		operation: 'files.read',
		path: `/v1/files/${encodeURIComponent(fileKey)}`,
		query: compactRecord({
			ids: ids ? normalizeNodeIds(ids).join(',') : undefined,
			depth: clampInt(input.depth, 1, 8, 1, 'depth'),
			version: optionalString(input.version, 'version'),
			geometry: optionalString(input.geometry, 'geometry'),
		}),
	})
	return mapFile(fileKey, result.body)
}

/**
 * Load slim Figma file JSON (name, pages, component/style counts).
 * @example
 * import getFile from 'kody:@kody/figma/get-file'
 * const file = await getFile({ fileKey: 'https://www.figma.com/design/abc123/Name' })
 */
export default async function getFileEntrypoint(
	params: Partial<GetFileInput> & Record<string, unknown> = {},
) {
	const input = requireRecord(params, 'get-file')
	return getFile({
		fileKey: String(input.fileKey ?? input.fileUrl ?? ''),
		ids: input.ids as GetFileInput['ids'],
		depth: input.depth as number | undefined,
		version: optionalString(input.version, 'version'),
		geometry: optionalString(input.geometry, 'geometry') as GetFileInput['geometry'],
		integrationName: optionalString(input.integrationName, 'integrationName'),
		integration: optionalString(input.integration, 'integration'),
		account: optionalString(input.account, 'account'),
		secretName: optionalString(input.secretName, 'secretName'),
		auth: requireAuthMode(input.auth),
	})
}