figma-json-tree 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/README.md +172 -0
  2. package/dist/cli/index.js +1138 -0
  3. package/dist/cli/index.js.map +1 -0
  4. package/dist/figma-html.js +95 -0
  5. package/dist/figma-html.js.map +1 -0
  6. package/dist/figma-json-fetch.js +53 -0
  7. package/dist/figma-json-fetch.js.map +1 -0
  8. package/dist/figma-tree.js +808 -0
  9. package/dist/figma-tree.js.map +1 -0
  10. package/dist/types/cli/args.d.ts +27 -0
  11. package/dist/types/cli/args.d.ts.map +1 -0
  12. package/dist/types/cli/commands/download.d.ts +4 -0
  13. package/dist/types/cli/commands/download.d.ts.map +1 -0
  14. package/dist/types/cli/commands/export.d.ts +3 -0
  15. package/dist/types/cli/commands/export.d.ts.map +1 -0
  16. package/dist/types/cli/commands/query.d.ts +3 -0
  17. package/dist/types/cli/commands/query.d.ts.map +1 -0
  18. package/dist/types/cli/env.d.ts +2 -0
  19. package/dist/types/cli/env.d.ts.map +1 -0
  20. package/dist/types/cli/html/input.d.ts +5 -0
  21. package/dist/types/cli/html/input.d.ts.map +1 -0
  22. package/dist/types/cli/index.d.ts +3 -0
  23. package/dist/types/cli/index.d.ts.map +1 -0
  24. package/dist/types/cli/output.d.ts +4 -0
  25. package/dist/types/cli/output.d.ts.map +1 -0
  26. package/dist/types/cli/run.d.ts +8 -0
  27. package/dist/types/cli/run.d.ts.map +1 -0
  28. package/dist/types/figma-html/attributes.d.ts +4 -0
  29. package/dist/types/figma-html/attributes.d.ts.map +1 -0
  30. package/dist/types/figma-html/classes.d.ts +3 -0
  31. package/dist/types/figma-html/classes.d.ts.map +1 -0
  32. package/dist/types/figma-html/escape.d.ts +2 -0
  33. package/dist/types/figma-html/escape.d.ts.map +1 -0
  34. package/dist/types/figma-html/index.d.ts +3 -0
  35. package/dist/types/figma-html/index.d.ts.map +1 -0
  36. package/dist/types/figma-html/renderer.d.ts +5 -0
  37. package/dist/types/figma-html/renderer.d.ts.map +1 -0
  38. package/dist/types/figma-html/types.d.ts +4 -0
  39. package/dist/types/figma-html/types.d.ts.map +1 -0
  40. package/dist/types/figma-html/validate.d.ts +3 -0
  41. package/dist/types/figma-html/validate.d.ts.map +1 -0
  42. package/dist/types/figma-json-fetch/client.d.ts +8 -0
  43. package/dist/types/figma-json-fetch/client.d.ts.map +1 -0
  44. package/dist/types/figma-json-fetch/endpoints.d.ts +3 -0
  45. package/dist/types/figma-json-fetch/endpoints.d.ts.map +1 -0
  46. package/dist/types/figma-json-fetch/errors.d.ts +7 -0
  47. package/dist/types/figma-json-fetch/errors.d.ts.map +1 -0
  48. package/dist/types/figma-json-fetch/index.d.ts +4 -0
  49. package/dist/types/figma-json-fetch/index.d.ts.map +1 -0
  50. package/dist/types/figma-json-fetch/request.d.ts +3 -0
  51. package/dist/types/figma-json-fetch/request.d.ts.map +1 -0
  52. package/dist/types/figma-json-fetch/types.d.ts +9 -0
  53. package/dist/types/figma-json-fetch/types.d.ts.map +1 -0
  54. package/dist/types/figma-tree/index.d.ts +10 -0
  55. package/dist/types/figma-tree/index.d.ts.map +1 -0
  56. package/dist/types/figma-tree/input/normalize.d.ts +11 -0
  57. package/dist/types/figma-tree/input/normalize.d.ts.map +1 -0
  58. package/dist/types/figma-tree/ir/converters/diagnostics.d.ts +3 -0
  59. package/dist/types/figma-tree/ir/converters/diagnostics.d.ts.map +1 -0
  60. package/dist/types/figma-tree/ir/converters/layout.d.ts +4 -0
  61. package/dist/types/figma-tree/ir/converters/layout.d.ts.map +1 -0
  62. package/dist/types/figma-tree/ir/converters/style.d.ts +6 -0
  63. package/dist/types/figma-tree/ir/converters/style.d.ts.map +1 -0
  64. package/dist/types/figma-tree/ir/converters/text.d.ts +4 -0
  65. package/dist/types/figma-tree/ir/converters/text.d.ts.map +1 -0
  66. package/dist/types/figma-tree/ir/model/document.d.ts +12 -0
  67. package/dist/types/figma-tree/ir/model/document.d.ts.map +1 -0
  68. package/dist/types/figma-tree/ir/model/types.d.ts +61 -0
  69. package/dist/types/figma-tree/ir/model/types.d.ts.map +1 -0
  70. package/dist/types/figma-tree/ir/pipeline.d.ts +5 -0
  71. package/dist/types/figma-tree/ir/pipeline.d.ts.map +1 -0
  72. package/dist/types/figma-tree/ir/plugins/run.d.ts +11 -0
  73. package/dist/types/figma-tree/ir/plugins/run.d.ts.map +1 -0
  74. package/dist/types/figma-tree/model/types.d.ts +30 -0
  75. package/dist/types/figma-tree/model/types.d.ts.map +1 -0
  76. package/dist/types/figma-tree/model/value.d.ts +4 -0
  77. package/dist/types/figma-tree/model/value.d.ts.map +1 -0
  78. package/dist/types/figma-tree/selector/match.d.ts +4 -0
  79. package/dist/types/figma-tree/selector/match.d.ts.map +1 -0
  80. package/dist/types/figma-tree/selector/parser.d.ts +3 -0
  81. package/dist/types/figma-tree/selector/parser.d.ts.map +1 -0
  82. package/dist/types/figma-tree/selector/types.d.ts +24 -0
  83. package/dist/types/figma-tree/selector/types.d.ts.map +1 -0
  84. package/dist/types/figma-tree/tailwind/convert.d.ts +3 -0
  85. package/dist/types/figma-tree/tailwind/convert.d.ts.map +1 -0
  86. package/dist/types/figma-tree/tailwind/style.d.ts +6 -0
  87. package/dist/types/figma-tree/tailwind/style.d.ts.map +1 -0
  88. package/dist/types/figma-tree/tree/figma-tree.d.ts +39 -0
  89. package/dist/types/figma-tree/tree/figma-tree.d.ts.map +1 -0
  90. package/dist/types/figma-tree/tree/records.d.ts +5 -0
  91. package/dist/types/figma-tree/tree/records.d.ts.map +1 -0
  92. package/docs/api.md +89 -0
  93. package/docs/architecture.md +70 -0
  94. package/docs/html.md +90 -0
  95. package/docs/ir.md +84 -0
  96. package/docs/verification.md +33 -0
  97. package/package.json +57 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"figma-tree.js","names":[],"sources":["../src/figma-tree/model/value.ts","../src/figma-tree/input/normalize.ts","../src/figma-tree/tailwind/style.ts","../src/figma-tree/tailwind/convert.ts","../src/figma-tree/ir/model/document.ts","../src/figma-tree/ir/plugins/run.ts","../src/figma-tree/selector/types.ts","../src/figma-tree/tree/records.ts","../src/figma-tree/ir/converters/style.ts","../src/figma-tree/ir/converters/diagnostics.ts","../src/figma-tree/ir/converters/layout.ts","../src/figma-tree/ir/converters/text.ts","../src/figma-tree/ir/pipeline.ts","../src/figma-tree/selector/match.ts","../src/figma-tree/selector/parser.ts","../src/figma-tree/tree/figma-tree.ts"],"sourcesContent":["export function isObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\nexport function deepFreeze<T>(value: T): T {\n const pending: unknown[] = [value]\n const seen = new WeakSet<object>()\n while (pending.length) {\n const current = pending.pop()\n if (current === null || typeof current !== 'object' || seen.has(current)) continue\n seen.add(current)\n for (const child of Object.values(current)) pending.push(child)\n Object.freeze(current)\n }\n return value\n}\n\nexport function numberValue(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined\n}\n","import type { ComponentMetadata, Diagnostic, FigmaNodeData } from '../model/types.js'\nimport { deepFreeze, isObject } from '../model/value.js'\n\nexport class FigmaInputError extends Error {\n override name = 'FigmaInputError'\n}\n\nexport interface NormalizedInput {\n roots: FigmaNodeData[]\n components: Map<string, ComponentMetadata>\n diagnostics: Diagnostic[]\n}\n\nfunction addComponents(target: Map<string, ComponentMetadata>, value: unknown): void {\n if (!isObject(value)) return\n for (const [id, metadata] of Object.entries(value)) {\n if (isObject(metadata)) target.set(id, metadata)\n }\n}\n\nfunction validateNodes(roots: unknown[]): asserts roots is FigmaNodeData[] {\n const pending = [...roots]\n const seen = new WeakSet<object>()\n while (pending.length) {\n const node = pending.pop()\n if (\n !isObject(node) ||\n typeof node.id !== 'string' ||\n typeof node.name !== 'string' ||\n typeof node.type !== 'string'\n ) {\n throw new FigmaInputError('Each node must contain string id, name and type fields')\n }\n if (seen.has(node))\n throw new FigmaInputError('Input must be a JSON tree without cyclic or shared node objects')\n seen.add(node)\n if (node.children === undefined) continue\n if (!Array.isArray(node.children))\n throw new FigmaInputError(`Invalid children for node ${node.id}`)\n for (const child of node.children) pending.push(child)\n }\n}\n\nexport function normalizeInput(input: unknown): NormalizedInput {\n if (!isObject(input)) throw new FigmaInputError('Expected a parsed Figma response or node object')\n const components = new Map<string, ComponentMetadata>()\n const diagnostics: Diagnostic[] = []\n const roots: unknown[] = []\n addComponents(components, input.components)\n if (typeof input.type === 'string') roots.push(input)\n else if (isObject(input.document)) roots.push(input.document)\n else if (isObject(input.nodes)) {\n for (const [id, entry] of Object.entries(input.nodes)) {\n if (entry === null) {\n diagnostics.push({\n code: 'missing-node',\n nodeId: id,\n message: 'Figma returned null for this node',\n })\n } else if (isObject(entry) && isObject(entry.document)) {\n roots.push(entry.document)\n addComponents(components, entry.components)\n } else throw new FigmaInputError(`Invalid node response entry: ${id}`)\n }\n } else throw new FigmaInputError('Expected document, nodes, or a single node')\n validateNodes(roots)\n try {\n const copied = structuredClone({ roots, components, diagnostics })\n deepFreeze(copied.roots)\n for (const metadata of copied.components.values()) deepFreeze(metadata)\n return copied\n } catch (error) {\n throw new FigmaInputError(\n `Input must be structured-cloneable JSON: ${error instanceof Error ? error.message : 'invalid value'}`,\n )\n }\n}\n","import type { CSSStyle } from '../ir/model/types.js'\n\nconst keywords: Record<string, Record<string, string>> = {\n display: { flex: 'flex', none: 'hidden' },\n position: { relative: 'relative', absolute: 'absolute' },\n boxSizing: { 'border-box': 'box-border' },\n flexDirection: { row: 'flex-row', column: 'flex-col' },\n flexWrap: { wrap: 'flex-wrap' },\n justifyContent: {\n 'flex-start': 'justify-start',\n 'flex-end': 'justify-end',\n center: 'justify-center',\n 'space-between': 'justify-between',\n },\n alignItems: {\n 'flex-start': 'items-start',\n 'flex-end': 'items-end',\n center: 'items-center',\n baseline: 'items-baseline',\n },\n alignContent: { 'space-between': 'content-between' },\n alignSelf: { stretch: 'self-stretch' },\n overflow: { hidden: 'overflow-hidden' },\n borderStyle: { solid: 'border-solid' },\n textAlign: {\n left: 'text-left',\n right: 'text-right',\n center: 'text-center',\n justify: 'text-justify',\n },\n fontStyle: { italic: 'italic' },\n textDecorationLine: { underline: 'underline', 'line-through': 'line-through' },\n textTransform: { uppercase: 'uppercase', lowercase: 'lowercase', capitalize: 'capitalize' },\n whiteSpace: { 'pre-wrap': 'whitespace-pre-wrap' },\n flexGrow: { '1': 'grow' },\n flexShrink: { '0': 'shrink-0' },\n width: { '100%': 'w-full', 'fit-content': 'w-fit' },\n height: { '100%': 'h-full', 'fit-content': 'h-fit' },\n}\n\nconst prefixes: Record<string, string> = {\n width: 'w',\n height: 'h',\n minWidth: 'min-w',\n maxWidth: 'max-w',\n minHeight: 'min-h',\n maxHeight: 'max-h',\n left: 'left',\n top: 'top',\n gap: 'gap',\n rowGap: 'gap-y',\n columnGap: 'gap-x',\n paddingTop: 'pt',\n paddingRight: 'pr',\n paddingBottom: 'pb',\n paddingLeft: 'pl',\n borderRadius: 'rounded',\n borderTopLeftRadius: 'rounded-tl',\n borderTopRightRadius: 'rounded-tr',\n borderBottomLeftRadius: 'rounded-bl',\n borderBottomRightRadius: 'rounded-br',\n borderWidth: 'border',\n borderTopWidth: 'border-t',\n borderRightWidth: 'border-r',\n borderBottomWidth: 'border-b',\n borderLeftWidth: 'border-l',\n backgroundColor: 'bg',\n color: 'text',\n borderColor: 'border',\n fontSize: 'text',\n fontWeight: 'font',\n lineHeight: 'leading',\n letterSpacing: 'tracking',\n opacity: 'opacity',\n flexBasis: 'basis',\n}\n\nfunction arbitraryClass(property: string, value: string | number): string | undefined {\n const prefix = prefixes[property]\n const literal = String(value)\n // Unrepresentable/custom CSS remains inline instead of emitting a broken class.\n if (!prefix || /[\\s[\\]_'\"\\\\;]/.test(literal)) return undefined\n const hint = property === 'fontSize' ? 'length:' : property === 'fontWeight' ? 'number:' : ''\n return `${prefix}-[${hint}${literal}]`\n}\n\nexport function convertCSS(style: CSSStyle): { className: string; style: CSSStyle } {\n const classes: string[] = []\n const residual: CSSStyle = {}\n for (const [property, value] of Object.entries(style)) {\n const className = keywords[property]?.[String(value)] ?? arbitraryClass(property, value)\n if (className) classes.push(className)\n else residual[property] = value\n }\n return { className: [...new Set(classes)].join(' '), style: residual }\n}\n","import type { IRData, IRNode, TailwindIR, TailwindNode } from '../ir/model/types.js'\nimport { convertCSS } from './style.js'\n\nexport function convertToTailwind(data: IRData): TailwindIR {\n const input = structuredClone(data)\n const records: IRNode[] = []\n const stack = [input.root]\n while (stack.length) {\n const node = stack.pop()!\n records.push(node)\n for (const child of node.children) stack.push(child)\n }\n const converted = new Map<IRNode, TailwindNode>()\n for (const node of records.reverse()) {\n converted.set(node, {\n ...node,\n ...convertCSS(node.style),\n children: node.children.map(child => converted.get(child)!),\n })\n }\n return {\n schemaVersion: 1,\n target: 'tailwind-v4',\n root: converted.get(input.root)!,\n diagnostics: input.diagnostics,\n }\n}\n","import type { DeepReadonly } from '../../model/types.js'\nimport { deepFreeze } from '../../model/value.js'\nimport { convertToTailwind } from '../../tailwind/convert.js'\nimport type { IRData, TailwindIR } from './types.js'\n\nexport class IRDocument {\n readonly #data: IRData\n\n constructor(data: IRData) {\n this.#data = deepFreeze(structuredClone(data))\n }\n\n get schemaVersion(): 1 {\n return 1\n }\n get root(): DeepReadonly<IRData['root']> {\n return this.#data.root as unknown as DeepReadonly<IRData['root']>\n }\n get diagnostics(): DeepReadonly<IRData['diagnostics']> {\n return this.#data.diagnostics\n }\n toJSON(): IRData {\n return structuredClone(this.#data)\n }\n toTailwind(): TailwindIR {\n return convertToTailwind(this.#data)\n }\n}\n","import type { DeepReadonly, NodeRecord } from '../../model/types.js'\nimport { deepFreeze, isObject } from '../../model/value.js'\nimport type { IRNode, IRPlugin, IRPluginContext } from '../model/types.js'\n\nexport class IRPluginError extends Error {\n override name = 'IRPluginError'\n constructor(\n readonly pluginName: string,\n readonly nodeId: string,\n cause: unknown,\n ) {\n super(`IR plugin \"${pluginName}\" failed for node ${nodeId}`, { cause })\n }\n}\n\nexport function validateIRNode(node: unknown): asserts node is IRNode {\n if (\n !isObject(node) ||\n !isObject(node.source) ||\n typeof node.source.id !== 'string' ||\n typeof node.source.name !== 'string' ||\n typeof node.source.type !== 'string' ||\n !['container', 'text', 'shape', 'instance', 'unknown'].includes(String(node.kind)) ||\n typeof node.visible !== 'boolean' ||\n !Array.isArray(node.children) ||\n !isObject(node.layout) ||\n !['none', 'horizontal', 'vertical'].includes(String(node.layout.mode)) ||\n typeof node.layout.wrap !== 'boolean' ||\n !isObject(node.size) ||\n !['FIXED', 'HUG', 'FILL'].includes(String(node.size.widthMode)) ||\n !['FIXED', 'HUG', 'FILL'].includes(String(node.size.heightMode)) ||\n !isObject(node.style) ||\n !isObject(node.extensions)\n )\n throw new TypeError('Plugin must return a standard IRNode')\n for (const value of Object.values(node.style)) {\n if (typeof value !== 'string' && (typeof value !== 'number' || !Number.isFinite(value)))\n throw new TypeError('Invalid IR style value')\n }\n for (const axis of ['width', 'height']) {\n const value = node.size[axis]\n if (value !== undefined && (typeof value !== 'number' || !Number.isFinite(value)))\n throw new TypeError('Invalid IR size')\n }\n if (node.text !== undefined && (!isObject(node.text) || typeof node.text.characters !== 'string'))\n throw new TypeError('Invalid IR text')\n}\n\nfunction validateJSON(value: unknown, ancestors = new Set<object>()): void {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') return\n if (typeof value === 'number' && Number.isFinite(value)) return\n if (\n typeof value !== 'object' ||\n (!Array.isArray(value) &&\n Object.getPrototypeOf(value) !== Object.prototype &&\n Object.getPrototypeOf(value) !== null)\n )\n throw new TypeError('Extensions must contain JSON values')\n if (ancestors.has(value)) throw new TypeError('Cyclic extension value')\n ancestors.add(value)\n for (const child of Object.values(value)) validateJSON(child, ancestors)\n ancestors.delete(value)\n}\n\nfunction validatePluginTree(node: unknown): asserts node is IRNode {\n const pending: unknown[] = [node]\n const seen = new Set<unknown>()\n while (pending.length) {\n const current = pending.pop()\n if (seen.has(current)) throw new TypeError('IR children must form a tree')\n seen.add(current)\n validateIRNode(current)\n validateJSON(current.extensions)\n for (const child of current.children) pending.push(child)\n }\n}\n\nexport function runPlugins(\n initial: IRNode,\n record: NodeRecord,\n plugins: readonly IRPlugin[],\n): IRNode {\n const context: IRPluginContext = Object.freeze({\n source: record.source,\n parent: record.parent?.source,\n component: record.component,\n })\n return plugins.reduce((current, plugin) => {\n try {\n const result: unknown = plugin.transform(\n deepFreeze(current) as unknown as DeepReadonly<IRNode>,\n context,\n )\n validatePluginTree(result)\n return structuredClone(result)\n } catch (cause) {\n throw new IRPluginError(plugin.name, record.source.id, cause)\n }\n }, initial)\n}\n","export const attributes = ['id', 'name', 'type', 'visible', 'componentName'] as const\nexport type Attribute = (typeof attributes)[number]\nexport interface QueryCondition {\n id?: string | RegExp\n name?: string | RegExp\n type?: string | RegExp\n visible?: boolean\n componentName?: string | RegExp\n}\nexport type Selector = string | QueryCondition\nexport interface AttributeTest {\n key: Attribute\n operator: 'exists' | '=' | '*=' | '^=' | '$=' | 'regex'\n value?: string | boolean | RegExp\n}\nexport interface SelectorPart {\n type?: string\n tests: AttributeTest[]\n relation?: 'descendant' | 'child'\n}\nexport class SelectorSyntaxError extends Error {\n override name = 'SelectorSyntaxError'\n}\n","import type { NormalizedInput } from '../input/normalize.js'\nimport type { DeepReadonly, FigmaNodeData, NodeRecord } from '../model/types.js'\n\nexport function* walk(roots: readonly NodeRecord[]): Generator<NodeRecord> {\n const stack = [...roots].reverse()\n while (stack.length) {\n const node = stack.pop()!\n yield node\n for (let i = node.children.length - 1; i >= 0; i--) stack.push(node.children[i]!)\n }\n}\n\nfunction localComponentNames(roots: readonly FigmaNodeData[]): Map<string, string> {\n const names = new Map<string, string>()\n const stack: DeepReadonly<FigmaNodeData>[] = [...roots]\n while (stack.length) {\n const node = stack.pop()!\n if (node.type === 'COMPONENT') names.set(node.id, node.name)\n for (const child of node.children ?? []) stack.push(child)\n }\n return names\n}\n\nexport function buildRecords(input: NormalizedInput): NodeRecord[] {\n const names = localComponentNames(input.roots)\n const roots: NodeRecord[] = []\n const stack = input.roots\n .map(source => ({\n source: source as DeepReadonly<FigmaNodeData>,\n parent: undefined as NodeRecord | undefined,\n }))\n .reverse()\n while (stack.length) {\n const { source, parent } = stack.pop()!\n const componentId = typeof source.componentId === 'string' ? source.componentId : undefined\n const component = componentId ? input.components.get(componentId) : undefined\n const componentName = component?.name ?? (componentId ? names.get(componentId) : undefined)\n const record: NodeRecord = { source, parent, children: [], componentName, component }\n if (parent) parent.children.push(record)\n else roots.push(record)\n const children = source.children ?? []\n for (let i = children.length - 1; i >= 0; i--)\n stack.push({ source: children[i]!, parent: record })\n }\n return roots\n}\n","import type { DeepReadonly, FigmaNodeData } from '../../model/types.js'\nimport { isObject, numberValue } from '../../model/value.js'\nimport type { CSSStyle } from '../model/types.js'\n\nfunction channel(value: unknown): number {\n return Math.round(Math.max(0, Math.min(1, numberValue(value) ?? 0)) * 255)\n}\n\nexport function solidColor(paint: unknown): string | undefined {\n if (!isObject(paint) || paint.type !== 'SOLID' || !isObject(paint.color)) return undefined\n const { color } = paint\n const alpha = Math.max(\n 0,\n Math.min(1, (numberValue(color.a) ?? 1) * (numberValue(paint.opacity) ?? 1)),\n )\n return `rgba(${channel(color.r)},${channel(color.g)},${channel(color.b)},${Number(alpha.toFixed(6))})`\n}\n\nexport function visiblePaints(value: unknown): Record<string, unknown>[] {\n return Array.isArray(value)\n ? value.filter(\n (paint): paint is Record<string, unknown> => isObject(paint) && paint.visible !== false,\n )\n : []\n}\n\nexport function convertStyle(node: DeepReadonly<FigmaNodeData>): CSSStyle {\n const style: CSSStyle = {}\n const fills = visiblePaints(node.fills)\n const fill = fills.length === 1 ? solidColor(fills[0]) : undefined\n if (fill) style[node.type === 'TEXT' ? 'color' : 'backgroundColor'] = fill\n const strokes = visiblePaints(node.strokes)\n const stroke = strokes.length === 1 ? solidColor(strokes[0]) : undefined\n if (stroke) {\n style.borderColor = stroke\n style.borderStyle = 'solid'\n const weight = numberValue(node.strokeWeight)\n if (weight !== undefined) style.borderWidth = `${weight}px`\n if (isObject(node.individualStrokeWeights)) {\n for (const [side, property] of Object.entries({\n top: 'borderTopWidth',\n right: 'borderRightWidth',\n bottom: 'borderBottomWidth',\n left: 'borderLeftWidth',\n })) {\n const value = numberValue(node.individualStrokeWeights[side])\n if (value !== undefined) style[property] = `${value}px`\n }\n }\n }\n const radius = numberValue(node.cornerRadius)\n if (radius !== undefined) style.borderRadius = `${radius}px`\n if (Array.isArray(node.rectangleCornerRadii)) {\n const corners = [\n 'borderTopLeftRadius',\n 'borderTopRightRadius',\n 'borderBottomRightRadius',\n 'borderBottomLeftRadius',\n ]\n node.rectangleCornerRadii.forEach((value, index) => {\n if (corners[index] && numberValue(value) !== undefined) style[corners[index]!] = `${value}px`\n })\n }\n if (node.type === 'ELLIPSE') style.borderRadius = '50%'\n const opacity = numberValue(node.opacity)\n if (opacity !== undefined) style.opacity = opacity\n if (node.visible === false) style.display = 'none'\n return style\n}\n","import type { Diagnostic, NodeRecord } from '../../model/types.js'\nimport { isObject } from '../../model/value.js'\nimport { visiblePaints } from './style.js'\n\nexport function unsupportedProperties(record: NodeRecord, unknownKind: boolean): Diagnostic[] {\n const node = record.source\n const properties: string[] = []\n if (unknownKind) properties.push('type')\n for (const key of ['fills', 'strokes']) {\n const paints = visiblePaints(node[key])\n if (paints.length > 1 || paints.some(paint => paint.type !== 'SOLID')) properties.push(key)\n }\n if (\n Array.isArray(node.effects) &&\n node.effects.some(effect => isObject(effect) && effect.visible !== false)\n )\n properties.push('effects')\n if (isObject(node.styleOverrideTable) && Object.keys(node.styleOverrideTable).length)\n properties.push('styleOverrideTable')\n if (\n node.type === 'VECTOR' ||\n node.type === 'BOOLEAN_OPERATION' ||\n node.type === 'STAR' ||\n node.type === 'REGULAR_POLYGON' ||\n node.type === 'LINE'\n )\n properties.push('vectorGeometry')\n if (node.layoutMode === 'GRID') properties.push('layoutMode')\n if (typeof node.rotation === 'number' && node.rotation !== 0) properties.push('rotation')\n if (typeof node.itemSpacing === 'number' && node.itemSpacing < 0) properties.push('itemSpacing')\n if (visiblePaints(node.strokes).length && node.strokeAlign && node.strokeAlign !== 'INSIDE')\n properties.push('strokeAlign')\n if (node.isMask === true) properties.push('isMask')\n if (typeof node.cornerSmoothing === 'number' && node.cornerSmoothing > 0)\n properties.push('cornerSmoothing')\n return properties.map(property => ({\n code: 'unsupported-property',\n nodeId: node.id,\n property,\n message: `${property} is not fully represented in the basic IR`,\n }))\n}\n","import type { NodeRecord } from '../../model/types.js'\nimport { isObject, numberValue } from '../../model/value.js'\nimport type { CSSStyle, IRNode, SizeMode } from '../model/types.js'\n\nfunction sizingMode(value: unknown, fallback: SizeMode): SizeMode {\n return value === 'FIXED' || value === 'HUG' || value === 'FILL' ? value : fallback\n}\n\nfunction legacyMode(record: NodeRecord, axis: 'width' | 'height'): SizeMode {\n const horizontal = record.source.layoutMode === 'HORIZONTAL'\n const primary = (axis === 'width') === horizontal\n const own = primary ? record.source.primaryAxisSizingMode : record.source.counterAxisSizingMode\n const parentHorizontal = record.parent?.source.layoutMode === 'HORIZONTAL'\n const parentPrimary = (axis === 'width') === parentHorizontal\n if (\n record.parent?.source.layoutMode === 'HORIZONTAL' ||\n record.parent?.source.layoutMode === 'VERTICAL'\n ) {\n if (parentPrimary && record.source.layoutGrow === 1) return 'FILL'\n if (!parentPrimary && record.source.layoutAlign === 'STRETCH') return 'FILL'\n }\n return own === 'AUTO' ? 'HUG' : 'FIXED'\n}\n\nfunction dimensions(record: NodeRecord): IRNode['size'] {\n const box = isObject(record.source.absoluteBoundingBox) ? record.source.absoluteBoundingBox : {}\n const size = isObject(record.source.size) ? record.source.size : {}\n return {\n width: numberValue(size.x) ?? numberValue(box.width),\n height: numberValue(size.y) ?? numberValue(box.height),\n widthMode: sizingMode(record.source.layoutSizingHorizontal, legacyMode(record, 'width')),\n heightMode: sizingMode(record.source.layoutSizingVertical, legacyMode(record, 'height')),\n }\n}\n\nfunction applyDimension(\n style: CSSStyle,\n axis: 'width' | 'height',\n value: number | undefined,\n mode: SizeMode,\n record: NodeRecord,\n isRoot: boolean,\n): void {\n if (mode === 'FIXED') {\n if (value !== undefined) style[axis] = `${value}px`\n } else if (mode === 'HUG') style[axis] = 'fit-content'\n else {\n const parentAxis = record.parent?.source.layoutMode === 'HORIZONTAL' ? 'width' : 'height'\n const parentIsFlex = ['HORIZONTAL', 'VERTICAL'].includes(\n String(record.parent?.source.layoutMode),\n )\n if (!isRoot && parentIsFlex && parentAxis === axis) {\n style.flexGrow = 1\n style.flexBasis = '0px'\n style[axis === 'width' ? 'minWidth' : 'minHeight'] = '0px'\n } else if (!isRoot && parentIsFlex) style.alignSelf = 'stretch'\n else style[axis] = '100%'\n }\n}\n\nfunction autoLayoutStyle(record: NodeRecord): CSSStyle {\n const node = record.source\n if (node.layoutMode !== 'HORIZONTAL' && node.layoutMode !== 'VERTICAL') return {}\n const style: CSSStyle = {\n display: 'flex',\n flexDirection: node.layoutMode === 'HORIZONTAL' ? 'row' : 'column',\n }\n const primary: Record<string, string> = {\n MIN: 'flex-start',\n MAX: 'flex-end',\n CENTER: 'center',\n SPACE_BETWEEN: 'space-between',\n }\n const counter: Record<string, string> = {\n MIN: 'flex-start',\n MAX: 'flex-end',\n CENTER: 'center',\n BASELINE: 'baseline',\n }\n if (typeof node.primaryAxisAlignItems === 'string')\n style.justifyContent = primary[node.primaryAxisAlignItems] ?? 'flex-start'\n if (typeof node.counterAxisAlignItems === 'string')\n style.alignItems = counter[node.counterAxisAlignItems] ?? 'flex-start'\n else style.alignItems = 'flex-start'\n const gap = numberValue(node.itemSpacing)\n if (gap !== undefined && gap >= 0) style.gap = `${gap}px`\n for (const key of ['paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft'] as const) {\n const value = numberValue(node[key])\n if (value !== undefined) style[key] = `${value}px`\n }\n if (node.layoutWrap === 'WRAP') {\n style.flexWrap = 'wrap'\n const counterGap = numberValue(node.counterAxisSpacing)\n if (counterGap !== undefined && counterGap >= 0)\n style[node.layoutMode === 'HORIZONTAL' ? 'rowGap' : 'columnGap'] = `${counterGap}px`\n if (node.counterAxisAlignContent === 'SPACE_BETWEEN') style.alignContent = 'space-between'\n }\n return style\n}\n\nfunction positioning(record: NodeRecord, isRoot: boolean): CSSStyle {\n if (isRoot) return { position: 'relative' }\n const parent = record.parent?.source\n const absolute =\n record.source.layoutPositioning === 'ABSOLUTE' ||\n (parent && parent.layoutMode !== 'HORIZONTAL' && parent.layoutMode !== 'VERTICAL')\n if (!absolute) return { position: 'relative', flexShrink: 0 }\n const box = isObject(record.source.absoluteBoundingBox) ? record.source.absoluteBoundingBox : {}\n const parentBox = isObject(parent?.absoluteBoundingBox) ? parent.absoluteBoundingBox : {}\n const x = numberValue(box.x)\n const y = numberValue(box.y)\n return {\n position: 'absolute',\n ...(x !== undefined ? { left: `${x - (numberValue(parentBox.x) ?? 0)}px` } : {}),\n ...(y !== undefined ? { top: `${y - (numberValue(parentBox.y) ?? 0)}px` } : {}),\n }\n}\n\nexport function convertLayout(\n record: NodeRecord,\n isRoot: boolean,\n): Pick<IRNode, 'size' | 'layout' | 'style'> {\n const size = dimensions(record)\n const style: CSSStyle = {\n boxSizing: 'border-box',\n ...positioning(record, isRoot),\n ...autoLayoutStyle(record),\n }\n applyDimension(style, 'width', size.width, size.widthMode, record, isRoot)\n applyDimension(style, 'height', size.height, size.heightMode, record, isRoot)\n for (const key of ['minWidth', 'maxWidth', 'minHeight', 'maxHeight'] as const) {\n const value = numberValue(record.source[key])\n if (value !== undefined) style[key] = `${value}px`\n }\n if (record.source.clipsContent === true) style.overflow = 'hidden'\n return {\n size,\n layout: {\n mode:\n record.source.layoutMode === 'HORIZONTAL'\n ? 'horizontal'\n : record.source.layoutMode === 'VERTICAL'\n ? 'vertical'\n : 'none',\n wrap: record.source.layoutWrap === 'WRAP',\n },\n style,\n }\n}\n","import type { DeepReadonly, FigmaNodeData } from '../../model/types.js'\nimport { isObject, numberValue } from '../../model/value.js'\nimport type { CSSStyle } from '../model/types.js'\n\nexport function convertText(node: DeepReadonly<FigmaNodeData>): CSSStyle {\n if (node.type !== 'TEXT') return {}\n const input = isObject(node.style) ? node.style : {}\n const style: CSSStyle = { whiteSpace: 'pre-wrap' }\n if (typeof input.fontFamily === 'string') style.fontFamily = input.fontFamily\n const size = numberValue(input.fontSize)\n const weight = numberValue(input.fontWeight)\n if (size !== undefined) style.fontSize = `${size}px`\n if (weight !== undefined) style.fontWeight = weight\n if (input.italic === true) style.fontStyle = 'italic'\n if (typeof input.textAlignHorizontal === 'string') {\n const align: Record<string, string> = {\n LEFT: 'left',\n RIGHT: 'right',\n CENTER: 'center',\n JUSTIFIED: 'justify',\n }\n if (align[input.textAlignHorizontal]) style.textAlign = align[input.textAlignHorizontal]!\n }\n const lineHeight = numberValue(input.lineHeightPx)\n if (\n input.lineHeightUnit === 'FONT_SIZE_%' &&\n numberValue(input.lineHeightPercentFontSize) !== undefined\n )\n style.lineHeight = `${input.lineHeightPercentFontSize}%`\n else if (lineHeight !== undefined) style.lineHeight = `${lineHeight}px`\n const letterSpacing = numberValue(input.letterSpacing)\n if (letterSpacing !== undefined) style.letterSpacing = `${letterSpacing}px`\n if (input.textDecoration === 'UNDERLINE') style.textDecorationLine = 'underline'\n if (input.textDecoration === 'STRIKETHROUGH') style.textDecorationLine = 'line-through'\n const textCase: Record<string, string> = {\n UPPER: 'uppercase',\n LOWER: 'lowercase',\n TITLE: 'capitalize',\n }\n if (typeof input.textCase === 'string' && textCase[input.textCase])\n style.textTransform = textCase[input.textCase]!\n return style\n}\n","import type { Diagnostic, NodeRecord } from '../model/types.js'\nimport { walk } from '../tree/records.js'\nimport { unsupportedProperties } from './converters/diagnostics.js'\nimport { convertLayout } from './converters/layout.js'\nimport { convertStyle } from './converters/style.js'\nimport { convertText } from './converters/text.js'\nimport { IRDocument } from './model/document.js'\nimport type { IRNode, IRPlugin } from './model/types.js'\nimport { runPlugins } from './plugins/run.js'\n\nfunction nodeKind(type: string): IRNode['kind'] {\n if (type === 'TEXT') return 'text'\n if (type === 'INSTANCE') return 'instance'\n if (\n ['DOCUMENT', 'CANVAS', 'FRAME', 'GROUP', 'COMPONENT', 'COMPONENT_SET', 'SECTION'].includes(type)\n )\n return 'container'\n if (\n [\n 'RECTANGLE',\n 'ELLIPSE',\n 'LINE',\n 'VECTOR',\n 'BOOLEAN_OPERATION',\n 'STAR',\n 'REGULAR_POLYGON',\n ].includes(type)\n )\n return 'shape'\n return 'unknown'\n}\n\nfunction convertNode(record: NodeRecord, children: IRNode[], isRoot: boolean): IRNode {\n const source = record.source\n const layout = convertLayout(record, isRoot)\n return {\n source: {\n id: source.id,\n name: source.name,\n type: source.type,\n ...(record.componentName ? { componentName: record.componentName } : {}),\n },\n kind: nodeKind(source.type),\n visible: source.visible !== false,\n ...layout,\n style: { ...layout.style, ...convertText(source), ...convertStyle(source) },\n ...(source.type === 'TEXT'\n ? { text: { characters: typeof source.characters === 'string' ? source.characters : '' } }\n : {}),\n children,\n extensions: {},\n }\n}\n\nexport function convertToIR(root: NodeRecord, plugins: readonly IRPlugin[]): IRDocument {\n const records = [...walk([root])]\n const converted = new Map<NodeRecord, IRNode>()\n const diagnostics: Diagnostic[] = []\n for (const record of [...records].reverse()) {\n const initial = convertNode(\n record,\n record.children.map(child => converted.get(child)!),\n record === root,\n )\n converted.set(record, runPlugins(initial, record, plugins))\n }\n for (const record of records)\n diagnostics.push(...unsupportedProperties(record, nodeKind(record.source.type) === 'unknown'))\n return new IRDocument({ schemaVersion: 1, root: converted.get(root)!, diagnostics })\n}\n","import type { NodeRecord } from '../model/types.js'\nimport type { AttributeTest, SelectorPart } from './types.js'\n\nfunction readAttribute(node: NodeRecord, key: AttributeTest['key']): unknown {\n if (key === 'componentName') return node.componentName\n if (key === 'visible') return node.source.visible ?? true\n return node.source[key]\n}\n\nfunction matchesAttribute(node: NodeRecord, test: AttributeTest): boolean {\n const actual = readAttribute(node, test.key)\n if (test.operator === 'exists') return actual !== undefined\n if (test.operator === '=') return actual === test.value\n if (typeof actual !== 'string') return false\n if (test.operator === 'regex') {\n const regex = test.value as RegExp\n return new RegExp(regex.source, regex.flags).test(actual)\n }\n const expected = test.value as string\n if (test.operator === '*=') return actual.includes(expected)\n if (test.operator === '^=') return actual.startsWith(expected)\n return actual.endsWith(expected)\n}\n\nfunction matchesPart(node: NodeRecord, part: SelectorPart): boolean {\n return (\n (!part.type || node.source.type === part.type) &&\n part.tests.every(test => matchesAttribute(node, test))\n )\n}\n\nexport function matchesSelector(\n node: NodeRecord,\n parts: readonly SelectorPart[],\n boundary?: NodeRecord,\n): boolean {\n const pending: { node: NodeRecord; index: number }[] = [{ node, index: parts.length - 1 }]\n while (pending.length) {\n const current = pending.pop()!\n const part = parts[current.index]!\n if (current.node === boundary || !matchesPart(current.node, part)) continue\n if (current.index === 0) return true\n let parent = current.node.parent\n while (parent && parent !== boundary) {\n pending.push({ node: parent, index: current.index - 1 })\n if (part.relation === 'child') break\n parent = parent.parent\n }\n }\n return false\n}\n","import type { Attribute, AttributeTest, Selector, SelectorPart } from './types.js'\nimport { attributes, SelectorSyntaxError } from './types.js'\n\n/** Scan compounds without splitting quoted attribute values. */\nfunction splitSelector(selector: string): { text: string; relation?: 'descendant' | 'child' }[] {\n const parts: { text: string; relation?: 'descendant' | 'child' }[] = []\n let cursor = 0\n let relation: 'descendant' | 'child' | undefined\n while (cursor < selector.length) {\n while (/\\s/.test(selector[cursor] ?? '') && cursor < selector.length) cursor++\n const start = cursor\n let bracket = false\n let quote = ''\n while (cursor < selector.length) {\n const char = selector[cursor]!\n if (quote) {\n if (char === '\\\\') cursor++\n else if (char === quote) quote = ''\n } else if (char === '\"' || char === \"'\") quote = char\n else if (char === '[') {\n if (bracket) throw new SelectorSyntaxError('Nested brackets are not supported')\n bracket = true\n } else if (char === ']') {\n if (!bracket) throw new SelectorSyntaxError('Unexpected closing bracket')\n bracket = false\n } else if (!bracket && (char === '>' || /\\s/.test(char))) break\n cursor++\n }\n if (quote || bracket) throw new SelectorSyntaxError('Unclosed attribute or quoted value')\n if (cursor === start) throw new SelectorSyntaxError('Expected a selector before combinator')\n parts.push({ text: selector.slice(start, cursor), relation })\n while (cursor < selector.length && /\\s/.test(selector[cursor]!)) cursor++\n if (cursor === selector.length) break\n relation = selector[cursor] === '>' ? 'child' : 'descendant'\n if (relation === 'child') {\n cursor++\n while (cursor < selector.length && /\\s/.test(selector[cursor]!)) cursor++\n if (cursor === selector.length) throw new SelectorSyntaxError('Expected selector after >')\n }\n }\n return parts\n}\n\nfunction assertAttribute(key: string): asserts key is Attribute {\n if (!(attributes as readonly string[]).includes(key))\n throw new SelectorSyntaxError(`Unsupported attribute: ${key}`)\n}\n\nfunction parseAttribute(body: string): AttributeTest {\n const match = /^\\s*([A-Za-z][A-Za-z0-9]*)\\s*(?:(\\*=|\\^=|\\$=|=)\\s*(.*?)\\s*)?$/.exec(body)\n if (!match) throw new SelectorSyntaxError(`Invalid attribute: [${body}]`)\n const key = match[1]!\n assertAttribute(key)\n const operator = match[2] as AttributeTest['operator'] | undefined\n if (!operator) return { key, operator: 'exists' }\n const raw = match[3]!\n if (key === 'visible') {\n if (operator !== '=' || !/^(true|false)$/.test(raw))\n throw new SelectorSyntaxError('visible requires an unquoted boolean equality')\n return { key, operator, value: raw === 'true' }\n }\n const quoted = /^([\"'])([\\s\\S]*)\\1$/.exec(raw)\n if (!quoted) throw new SelectorSyntaxError('String attribute values must be quoted')\n const inner = quoted[2]!\n let value = ''\n for (let i = 0; i < inner.length; i++) {\n if (inner[i] === '\\\\') {\n if (i + 1 === inner.length) throw new SelectorSyntaxError('Incomplete escape')\n value += inner[++i]\n } else {\n if (inner[i] === quoted[1]) throw new SelectorSyntaxError('Unescaped quote in attribute')\n value += inner[i]\n }\n }\n return { key, operator, value }\n}\n\nfunction parseCompound(text: string): Omit<SelectorPart, 'relation'> {\n const typeMatch = /^(\\*|[A-Z][A-Z0-9_]*)/.exec(text)\n const type = typeMatch?.[1]\n let cursor = type?.length ?? 0\n const tests: AttributeTest[] = []\n while (cursor < text.length) {\n if (text[cursor] !== '[')\n throw new SelectorSyntaxError(`Unsupported selector near: ${text.slice(cursor)}`)\n const start = ++cursor\n let quote = ''\n while (cursor < text.length) {\n const char = text[cursor]!\n if (quote) {\n if (char === '\\\\') cursor++\n else if (char === quote) quote = ''\n } else if (char === '\"' || char === \"'\") quote = char\n else if (char === ']') break\n cursor++\n }\n tests.push(parseAttribute(text.slice(start, cursor)))\n cursor++\n }\n if (!type && !tests.length) throw new SelectorSyntaxError('Empty selector')\n return { type: type === '*' ? undefined : type, tests }\n}\n\nexport function parseSelector(selector: Selector): SelectorPart[] {\n if (typeof selector === 'string') {\n if (!selector.trim()) throw new SelectorSyntaxError('Empty selector')\n return splitSelector(selector.trim()).map(({ text, relation }) => ({\n ...parseCompound(text),\n relation,\n }))\n }\n if (!selector || typeof selector !== 'object' || Array.isArray(selector))\n throw new SelectorSyntaxError('Expected a string or condition object')\n const tests = Object.entries(selector).map(([key, value]): AttributeTest => {\n assertAttribute(key)\n if (\n key === 'visible'\n ? typeof value !== 'boolean'\n : typeof value !== 'string' && !(value instanceof RegExp)\n ) {\n throw new SelectorSyntaxError(`Invalid condition for ${key}`)\n }\n return { key, operator: value instanceof RegExp ? 'regex' : '=', value }\n })\n return [{ tests }]\n}\n","import { normalizeInput } from '../input/normalize.js'\nimport type { IRDocument } from '../ir/model/document.js'\nimport type { IROptions, IRPlugin } from '../ir/model/types.js'\nimport { convertToIR } from '../ir/pipeline.js'\nimport type { DeepReadonly, Diagnostic, FigmaNodeData, NodeRecord } from '../model/types.js'\nimport { deepFreeze } from '../model/value.js'\nimport { matchesSelector } from '../selector/match.js'\nimport { parseSelector } from '../selector/parser.js'\nimport type { Selector } from '../selector/types.js'\nimport { buildRecords, walk } from './records.js'\n\nexport interface FigmaTreeOptions {\n irPlugins?: readonly IRPlugin[]\n}\n\nclass TreeContext {\n readonly #wrappers = new WeakMap<NodeRecord, FigmaNode>()\n constructor(readonly plugins: readonly IRPlugin[]) {}\n wrap(record: NodeRecord): FigmaNode {\n let wrapper = this.#wrappers.get(record)\n if (!wrapper) {\n wrapper = new FigmaNode(record, this)\n this.#wrappers.set(record, wrapper)\n }\n return wrapper\n }\n *search(\n roots: readonly NodeRecord[],\n selector: Selector,\n boundary?: NodeRecord,\n ): Generator<FigmaNode> {\n const parts = parseSelector(selector)\n const seen = new Set<string>()\n for (const record of walk(roots)) {\n if (!seen.has(record.source.id) && matchesSelector(record, parts, boundary)) {\n seen.add(record.source.id)\n yield this.wrap(record)\n }\n }\n }\n}\n\nexport class FigmaNode {\n readonly #record: NodeRecord\n readonly #context: TreeContext\n /** @internal Obtain nodes through FigmaTree queries. */\n constructor(record: NodeRecord, context: TreeContext) {\n this.#record = record\n this.#context = context\n }\n get id(): string {\n return this.#record.source.id\n }\n get name(): string {\n return this.#record.source.name\n }\n get type(): string {\n return this.#record.source.type\n }\n get componentName(): string | undefined {\n return this.#record.componentName\n }\n get children(): readonly FigmaNode[] {\n return Object.freeze(this.#record.children.map(child => this.#context.wrap(child)))\n }\n query(selector: Selector): FigmaNode | undefined {\n return this.#context.search(this.#record.children, selector, this.#record).next().value\n }\n queryAll(selector: Selector): FigmaNode[] {\n return [...this.#context.search(this.#record.children, selector, this.#record)]\n }\n toJSON(): FigmaNodeData {\n return structuredClone(this.#record.source) as FigmaNodeData\n }\n toIR(options: IROptions = {}): IRDocument {\n return convertToIR(this.#record, [...this.#context.plugins, ...(options.plugins ?? [])])\n }\n}\n\nexport class FigmaTree {\n readonly #records: NodeRecord[]\n readonly #context: TreeContext\n readonly diagnostics: DeepReadonly<Diagnostic[]>\n private constructor(input: unknown, options: FigmaTreeOptions) {\n const normalized = normalizeInput(input)\n this.#records = buildRecords(normalized)\n this.#context = new TreeContext(Object.freeze([...(options.irPlugins ?? [])]))\n this.diagnostics = deepFreeze(normalized.diagnostics)\n }\n static fromJson(input: unknown, options: FigmaTreeOptions = {}): FigmaTree {\n return new FigmaTree(input, options)\n }\n get roots(): readonly FigmaNode[] {\n return Object.freeze(this.#records.map(record => this.#context.wrap(record)))\n }\n query(selector: Selector): FigmaNode | undefined {\n return this.#context.search(this.#records, selector).next().value\n }\n queryAll(selector: Selector): FigmaNode[] {\n return [...this.#context.search(this.#records, selector)]\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { Selector } from '../figma-tree/index.js';
2
+ import type { HTMLStyles } from './html/input.js';
3
+ export interface DownloadArgs {
4
+ command: 'download';
5
+ fileKey: string;
6
+ nodeIds?: string[];
7
+ out?: string;
8
+ force: boolean;
9
+ }
10
+ export interface QueryArgs {
11
+ command: 'query' | 'queryAll';
12
+ input: string;
13
+ selector: Selector;
14
+ out?: string;
15
+ force: boolean;
16
+ }
17
+ export interface ExportArgs {
18
+ command: 'export';
19
+ input: string;
20
+ selector?: string;
21
+ styles?: HTMLStyles;
22
+ out?: string;
23
+ force: boolean;
24
+ }
25
+ export declare const HELP = "Usage:\n figma-json-tree download --file FILE_KEY [--nodes 49:7390,49:7391] [--out file.json] [--force]\n figma-json-tree query --input file.json --selector 'FRAME[name=\"Hover Card\"]' [--out node.json] [--force]\n figma-json-tree queryAll --input file.json --selector '[name=\"Hover Card\"]' [--out nodes.json] [--force]\n figma-json-tree queryAll --input file.json --name-regex '^ToBe' [--regex-flags i]\n figma-json-tree export --input file.json --selector 'FRAME[name=\"Hover Card\"]' --format html [--styles inline|tailwind] [--out page.html] [--force]\n figma-json-tree export --input design.ir.json --format html [--styles tailwind]\n\nUse either --selector or --name-regex. --regex-flags applies only to --name-regex.\nquery returns the first original subtree or null; queryAll returns an array (possibly empty).\nInputs: parsed file/node API responses or a single subtree saved as JSON.\nAuthentication: FIGMA_TOKEN is required only for download. Queries and exports read local files.\nexport accepts original Figma JSON, standard IR or Tailwind IR and exports one root.\nFor export, --format defaults to html. Styles default to inline (Tailwind for Tailwind IR).\nexport returns body contents only: no doctype, html, head, body, style or script tags.\nTailwind exports contain classes and residual inline styles; the host project builds the CSS.\nWithout --out, JSON or exported HTML is written to stdout. Existing files require --force.\n";
26
+ export declare function parseArgs(args: string[]): DownloadArgs | QueryArgs | ExportArgs | 'help';
27
+ //# sourceMappingURL=args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../../src/cli/args.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,UAAU,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,OAAO,GAAG,UAAU,CAAA;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,QAAQ,CAAA;IAClB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,QAAQ,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,OAAO,CAAA;CACf;AAED,eAAO,MAAM,IAAI,q7CAiBhB,CAAA;AAqGD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAOxF"}
@@ -0,0 +1,4 @@
1
+ import type { FigmaClient } from '../../figma-json-fetch/index.js';
2
+ import type { DownloadArgs } from '../args.js';
3
+ export declare function download(args: DownloadArgs, client: FigmaClient, stdout: (text: string) => void): Promise<void>;
4
+ //# sourceMappingURL=download.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/download.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAA;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAG9C,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAC7B,OAAO,CAAC,IAAI,CAAC,CAKf"}
@@ -0,0 +1,3 @@
1
+ import type { ExportArgs } from '../args.js';
2
+ export declare function exportHTML(args: ExportArgs, stdout: (text: string) => void, stderr: (text: string) => void): Promise<void>;
3
+ //# sourceMappingURL=export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/export.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAI5C,wBAAsB,UAAU,CAC9B,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,EAC9B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAC7B,OAAO,CAAC,IAAI,CAAC,CASf"}
@@ -0,0 +1,3 @@
1
+ import type { QueryArgs } from '../args.js';
2
+ export declare function query(args: QueryArgs, stdout: (text: string) => void): Promise<void>;
3
+ //# sourceMappingURL=query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/query.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAG3C,wBAAsB,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAO1F"}
@@ -0,0 +1,2 @@
1
+ export declare function readToken(env: NodeJS.ProcessEnv): string;
2
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../../src/cli/env.ts"],"names":[],"mappings":"AAAA,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAIxD"}
@@ -0,0 +1,5 @@
1
+ import type { HTMLInput } from '../../figma-html/index.js';
2
+ import type { Selector } from '../../figma-tree/index.js';
3
+ export type HTMLStyles = 'inline' | 'tailwind';
4
+ export declare function prepareHTMLInput(input: unknown, selector?: Selector, styles?: HTMLStyles): HTMLInput;
5
+ //# sourceMappingURL=input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../../src/cli/html/input.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAE1D,OAAO,KAAK,EAAU,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AAGjE,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,UAAU,CAAA;AAsB9C,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,OAAO,EACd,QAAQ,CAAC,EAAE,QAAQ,EACnB,MAAM,CAAC,EAAE,UAAU,GAClB,SAAS,CAeX"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ export declare function writeJSON(value: unknown, path: string | undefined, force: boolean, stdout: (text: string) => void): Promise<void>;
2
+ export declare function writeText(text: string, path: string | undefined, force: boolean, stdout: (text: string) => void): Promise<void>;
3
+ export declare function safeErrorMessage(error: unknown, token?: string): string;
4
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../../src/cli/output.ts"],"names":[],"mappings":"AAEA,wBAAsB,SAAS,CAC7B,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAC7B,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,wBAAsB,SAAS,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAC7B,OAAO,CAAC,IAAI,CAAC,CAGf;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAGvE"}
@@ -0,0 +1,8 @@
1
+ export interface CLIEnvironment {
2
+ env: NodeJS.ProcessEnv;
3
+ stdout: (text: string) => void;
4
+ stderr: (text: string) => void;
5
+ fetch?: typeof globalThis.fetch;
6
+ }
7
+ export declare function runCLI(args: string[], environment: CLIEnvironment): Promise<number>;
8
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/cli/run.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC,UAAU,CAAA;IACtB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9B,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;CAChC;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAqBzF"}
@@ -0,0 +1,4 @@
1
+ import type { HTMLNode } from './types.js';
2
+ export declare function serializeStyle(style: HTMLNode['style']): string;
3
+ export declare function renderAttributes(node: HTMLNode, tailwind: boolean): string;
4
+ //# sourceMappingURL=attributes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attributes.d.ts","sourceRoot":"","sources":["../../../src/figma-html/attributes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAQ1C,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,MAAM,CAI/D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,CAY1E"}
@@ -0,0 +1,3 @@
1
+ /** Round numeric arbitrary values only; preserve selectors, URLs and custom names. */
2
+ export declare function formatTailwindClasses(className: string): string;
3
+ //# sourceMappingURL=classes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classes.d.ts","sourceRoot":"","sources":["../../../src/figma-html/classes.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAM/D"}
@@ -0,0 +1,2 @@
1
+ export declare function escapeHTML(value: string): string;
2
+ //# sourceMappingURL=escape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"escape.d.ts","sourceRoot":"","sources":["../../../src/figma-html/escape.ts"],"names":[],"mappings":"AAQA,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD"}
@@ -0,0 +1,3 @@
1
+ export { collectTailwindClasses, renderHTML } from './renderer.js';
2
+ export type { HTMLInput } from './types.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/figma-html/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAClE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA"}
@@ -0,0 +1,5 @@
1
+ import type { HTMLInput } from './types.js';
2
+ /** One neutral div per IR node; no inferred interactions or semantic controls. */
3
+ export declare function renderHTML(input: HTMLInput): string;
4
+ export declare function collectTailwindClasses(input: HTMLInput): string[];
5
+ //# sourceMappingURL=renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../../src/figma-html/renderer.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAY,MAAM,YAAY,CAAA;AAGrD,kFAAkF;AAClF,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAkBnD;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,EAAE,CAcjE"}
@@ -0,0 +1,4 @@
1
+ import type { DeepReadonly, IRData, IRNode, TailwindIR, TailwindNode } from '../figma-tree/index.js';
2
+ export type HTMLInput = DeepReadonly<IRData | TailwindIR>;
3
+ export type HTMLNode = DeepReadonly<IRNode | TailwindNode>;
4
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/figma-html/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAEpG,MAAM,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,GAAG,UAAU,CAAC,CAAA;AACzD,MAAM,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,GAAG,YAAY,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { HTMLInput } from './types.js';
2
+ export declare function assertHTMLInput(input: unknown): asserts input is HTMLInput;
3
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/figma-html/validate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAY,MAAM,YAAY,CAAA;AAyCrD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,SAAS,CAmB1E"}
@@ -0,0 +1,8 @@
1
+ import type { FigmaClientOptions, GetFileNodesResponse, GetFileResponse, RequestOptions } from './types.js';
2
+ export declare class FigmaClient {
3
+ #private;
4
+ constructor(options: FigmaClientOptions);
5
+ getFile(fileKey: string, options?: RequestOptions): Promise<GetFileResponse>;
6
+ getNodes(fileKey: string, nodeIds: readonly string[], options?: RequestOptions): Promise<GetFileNodesResponse>;
7
+ }
8
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/figma-json-fetch/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,EACf,cAAc,EACf,MAAM,YAAY,CAAA;AAEnB,qBAAa,WAAW;;gBAGV,OAAO,EAAE,kBAAkB;IAMvC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,eAAe,CAAC;IAGhF,QAAQ,CACN,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,oBAAoB,CAAC;CAGjC"}
@@ -0,0 +1,3 @@
1
+ export declare function fileEndpoint(fileKey: string): URL;
2
+ export declare function nodesEndpoint(fileKey: string, nodeIds: readonly string[]): URL;
3
+ //# sourceMappingURL=endpoints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoints.d.ts","sourceRoot":"","sources":["../../../src/figma-json-fetch/endpoints.ts"],"names":[],"mappings":"AAEA,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,GAAG,CAGjD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,GAAG,CAO9E"}
@@ -0,0 +1,7 @@
1
+ export declare class FigmaHTTPError extends Error {
2
+ readonly status: number;
3
+ readonly retryAfter: string | null;
4
+ name: string;
5
+ constructor(status: number, retryAfter: string | null);
6
+ }
7
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/figma-json-fetch/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,cAAe,SAAQ,KAAK;IAGrC,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAH3B,IAAI,SAAmB;gBAErB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GAAG,IAAI;CAMrC"}
@@ -0,0 +1,4 @@
1
+ export { FigmaClient } from './client.js';
2
+ export { FigmaHTTPError } from './errors.js';
3
+ export type { FigmaClientOptions, GetFileNodesResponse, GetFileResponse, RequestOptions, } from './types.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/figma-json-fetch/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,YAAY,EACV,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,EACf,cAAc,GACf,MAAM,YAAY,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { RequestOptions } from './types.js';
2
+ export declare function requestJSON<T>(fetcher: typeof globalThis.fetch, url: URL, token: string, options: RequestOptions): Promise<T>;
3
+ //# sourceMappingURL=request.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../../src/figma-json-fetch/request.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhD,wBAAsB,WAAW,CAAC,CAAC,EACjC,OAAO,EAAE,OAAO,UAAU,CAAC,KAAK,EAChC,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,CAAC,CAAC,CAQZ"}
@@ -0,0 +1,9 @@
1
+ export type { GetFileNodesResponse, GetFileResponse } from '@figma/rest-api-spec';
2
+ export interface FigmaClientOptions {
3
+ token: string;
4
+ fetch?: typeof globalThis.fetch;
5
+ }
6
+ export interface RequestOptions {
7
+ signal?: AbortSignal;
8
+ }
9
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/figma-json-fetch/types.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAEjF,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;CAChC;AACD,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB"}
@@ -0,0 +1,10 @@
1
+ export { FigmaInputError } from './input/normalize.js';
2
+ export { IRDocument } from './ir/model/document.js';
3
+ export type { CSSStyle, IRData, IRNode, IROptions, IRPlugin, IRPluginContext, JSONValue, TailwindIR, TailwindNode, } from './ir/model/types.js';
4
+ export { IRPluginError } from './ir/plugins/run.js';
5
+ export type { ComponentMetadata, DeepReadonly, Diagnostic, FigmaNodeData, FigmaRESTNode, } from './model/types.js';
6
+ export type { QueryCondition, Selector } from './selector/types.js';
7
+ export { SelectorSyntaxError } from './selector/types.js';
8
+ export type { FigmaTreeOptions } from './tree/figma-tree.js';
9
+ export { FigmaNode, FigmaTree } from './tree/figma-tree.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/figma-tree/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACnD,YAAY,EACV,QAAQ,EACR,MAAM,EACN,MAAM,EACN,SAAS,EACT,QAAQ,EACR,eAAe,EACf,SAAS,EACT,UAAU,EACV,YAAY,GACb,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,YAAY,EACV,iBAAiB,EACjB,YAAY,EACZ,UAAU,EACV,aAAa,EACb,aAAa,GACd,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AACzD,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA"}
@@ -0,0 +1,11 @@
1
+ import type { ComponentMetadata, Diagnostic, FigmaNodeData } from '../model/types.js';
2
+ export declare class FigmaInputError extends Error {
3
+ name: string;
4
+ }
5
+ export interface NormalizedInput {
6
+ roots: FigmaNodeData[];
7
+ components: Map<string, ComponentMetadata>;
8
+ diagnostics: Diagnostic[];
9
+ }
10
+ export declare function normalizeInput(input: unknown): NormalizedInput;
11
+ //# sourceMappingURL=normalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../../src/figma-tree/input/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAGrF,qBAAa,eAAgB,SAAQ,KAAK;IAC/B,IAAI,SAAoB;CAClC;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,aAAa,EAAE,CAAA;IACtB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAA;IAC1C,WAAW,EAAE,UAAU,EAAE,CAAA;CAC1B;AAgCD,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAiC9D"}
@@ -0,0 +1,3 @@
1
+ import type { Diagnostic, NodeRecord } from '../../model/types.js';
2
+ export declare function unsupportedProperties(record: NodeRecord, unknownKind: boolean): Diagnostic[];
3
+ //# sourceMappingURL=diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../../../../src/figma-tree/ir/converters/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAIlE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,GAAG,UAAU,EAAE,CAqC5F"}
@@ -0,0 +1,4 @@
1
+ import type { NodeRecord } from '../../model/types.js';
2
+ import type { IRNode } from '../model/types.js';
3
+ export declare function convertLayout(record: NodeRecord, isRoot: boolean): Pick<IRNode, 'size' | 'layout' | 'style'>;
4
+ //# sourceMappingURL=layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../../src/figma-tree/ir/converters/layout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAEtD,OAAO,KAAK,EAAY,MAAM,EAAY,MAAM,mBAAmB,CAAA;AAoHnE,wBAAgB,aAAa,CAC3B,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,OAAO,GACd,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC,CA2B3C"}
@@ -0,0 +1,6 @@
1
+ import type { DeepReadonly, FigmaNodeData } from '../../model/types.js';
2
+ import type { CSSStyle } from '../model/types.js';
3
+ export declare function solidColor(paint: unknown): string | undefined;
4
+ export declare function visiblePaints(value: unknown): Record<string, unknown>[];
5
+ export declare function convertStyle(node: DeepReadonly<FigmaNodeData>): CSSStyle;
6
+ //# sourceMappingURL=style.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../../../../src/figma-tree/ir/converters/style.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEvE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAMjD,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAQ7D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAMvE;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,aAAa,CAAC,GAAG,QAAQ,CA0CxE"}
@@ -0,0 +1,4 @@
1
+ import type { DeepReadonly, FigmaNodeData } from '../../model/types.js';
2
+ import type { CSSStyle } from '../model/types.js';
3
+ export declare function convertText(node: DeepReadonly<FigmaNodeData>): CSSStyle;
4
+ //# sourceMappingURL=text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../../../src/figma-tree/ir/converters/text.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEvE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAEjD,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,CAAC,aAAa,CAAC,GAAG,QAAQ,CAsCvE"}
@@ -0,0 +1,12 @@
1
+ import type { DeepReadonly } from '../../model/types.js';
2
+ import type { IRData, TailwindIR } from './types.js';
3
+ export declare class IRDocument {
4
+ #private;
5
+ constructor(data: IRData);
6
+ get schemaVersion(): 1;
7
+ get root(): DeepReadonly<IRData['root']>;
8
+ get diagnostics(): DeepReadonly<IRData['diagnostics']>;
9
+ toJSON(): IRData;
10
+ toTailwind(): TailwindIR;
11
+ }
12
+ //# sourceMappingURL=document.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../../../../src/figma-tree/ir/model/document.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAGxD,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEpD,qBAAa,UAAU;;gBAGT,IAAI,EAAE,MAAM;IAIxB,IAAI,aAAa,IAAI,CAAC,CAErB;IACD,IAAI,IAAI,IAAI,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAEvC;IACD,IAAI,WAAW,IAAI,YAAY,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAErD;IACD,MAAM,IAAI,MAAM;IAGhB,UAAU,IAAI,UAAU;CAGzB"}
@@ -0,0 +1,61 @@
1
+ import type { ComponentMetadata, DeepReadonly, Diagnostic, FigmaNodeData } from '../../model/types.js';
2
+ export type JSONValue = null | boolean | number | string | JSONValue[] | {
3
+ [key: string]: JSONValue;
4
+ };
5
+ export type CSSStyle = Record<string, string | number>;
6
+ export type SizeMode = 'FIXED' | 'HUG' | 'FILL';
7
+ export interface IRNode {
8
+ source: {
9
+ id: string;
10
+ name: string;
11
+ type: string;
12
+ componentName?: string;
13
+ };
14
+ kind: 'container' | 'text' | 'shape' | 'instance' | 'unknown';
15
+ visible: boolean;
16
+ layout: {
17
+ mode: 'none' | 'horizontal' | 'vertical';
18
+ wrap: boolean;
19
+ };
20
+ size: {
21
+ width?: number;
22
+ height?: number;
23
+ widthMode: SizeMode;
24
+ heightMode: SizeMode;
25
+ };
26
+ style: CSSStyle;
27
+ text?: {
28
+ characters: string;
29
+ };
30
+ children: IRNode[];
31
+ extensions: Record<string, JSONValue>;
32
+ }
33
+ export interface IRPluginContext {
34
+ readonly source: DeepReadonly<FigmaNodeData>;
35
+ readonly parent?: DeepReadonly<FigmaNodeData>;
36
+ readonly component?: ComponentMetadata;
37
+ }
38
+ export interface IRPlugin {
39
+ readonly name: string;
40
+ transform(node: DeepReadonly<IRNode>, context: IRPluginContext): DeepReadonly<IRNode>;
41
+ }
42
+ export interface IROptions {
43
+ plugins?: readonly IRPlugin[];
44
+ }
45
+ export interface IRData {
46
+ schemaVersion: 1;
47
+ root: IRNode;
48
+ diagnostics: Diagnostic[];
49
+ }
50
+ export interface TailwindNode extends Omit<IRNode, 'children' | 'style'> {
51
+ className: string;
52
+ style: CSSStyle;
53
+ children: TailwindNode[];
54
+ }
55
+ export interface TailwindIR {
56
+ schemaVersion: 1;
57
+ target: 'tailwind-v4';
58
+ root: TailwindNode;
59
+ diagnostics: Diagnostic[];
60
+ }
61
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/figma-tree/ir/model/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,YAAY,EACZ,UAAU,EACV,aAAa,EACd,MAAM,sBAAsB,CAAA;AAE7B,MAAM,MAAM,SAAS,GACjB,IAAI,GACJ,OAAO,GACP,MAAM,GACN,MAAM,GACN,SAAS,EAAE,GACX;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAA;AAChC,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAA;AACtD,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAA;AAC/C,MAAM,WAAW,MAAM;IACrB,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC1E,IAAI,EAAE,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,CAAA;IAC7D,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,UAAU,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAA;IACnE,IAAI,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,QAAQ,CAAC;QAAC,UAAU,EAAE,QAAQ,CAAA;KAAE,CAAA;IACpF,KAAK,EAAE,QAAQ,CAAA;IACf,IAAI,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAA;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;CACtC;AACD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC,aAAa,CAAC,CAAA;IAC5C,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC,aAAa,CAAC,CAAA;IAC7C,QAAQ,CAAC,SAAS,CAAC,EAAE,iBAAiB,CAAA;CACvC;AACD,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,eAAe,GAAG,YAAY,CAAC,MAAM,CAAC,CAAA;CACtF;AACD,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAA;CAC9B;AACD,MAAM,WAAW,MAAM;IACrB,aAAa,EAAE,CAAC,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,UAAU,EAAE,CAAA;CAC1B;AACD,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC;IACtE,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,QAAQ,CAAA;IACf,QAAQ,EAAE,YAAY,EAAE,CAAA;CACzB;AACD,MAAM,WAAW,UAAU;IACzB,aAAa,EAAE,CAAC,CAAA;IAChB,MAAM,EAAE,aAAa,CAAA;IACrB,IAAI,EAAE,YAAY,CAAA;IAClB,WAAW,EAAE,UAAU,EAAE,CAAA;CAC1B"}
@@ -0,0 +1,5 @@
1
+ import type { NodeRecord } from '../model/types.js';
2
+ import { IRDocument } from './model/document.js';
3
+ import type { IRPlugin } from './model/types.js';
4
+ export declare function convertToIR(root: NodeRecord, plugins: readonly IRPlugin[]): IRDocument;
5
+ //# sourceMappingURL=pipeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../../../src/figma-tree/ir/pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAM/D,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,KAAK,EAAU,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AA+CxD,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,QAAQ,EAAE,GAAG,UAAU,CAetF"}