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),
})
}