コンテンツにスキップ

プラグインコンポーネントキャプチャの送信

メソッド

この API は REST の方法論に従います。

HTTP メソッド

POST: プラグインが観測したコンポーネントキャプチャを送信します — component_capture イベントをエンキューし、ワーカーのレジストリマージにルーティングします。

このエンドポイントが存在する理由

POST …/wf2des/components の背後にある REST スイープは、デザインシステムライブラリを読むことができません。リモートコンポーネントはそのインスタンス越しにしか見えないため、スイープは publish key を持たないローカルの双子を断片的なバリアント軸とともに作ってしまいます。そして component_key を持たないレジストリ文書は、プラグインでは一切マテリアライズできません。実プロジェクトでは 279 件のレジストリ文書のうち 106 件がバリアントデータを持たず、そのうち 56 件は軸を宣言しているにもかかわらず、という状態でした。

プラグインは Figma の内部から正規のメインコンポーネントを読めます(getMainComponentAsync は、REST が 403 を返すコンポーネントについてもメインの id・名前・publish key・コンポーネントセット id・バリアント値を返します)。したがってこれらのキャプチャが component_key と variant_properties の 正規のソース です。

ワーカーはこれらを 単調に(monotonically) マージします — より豊富なキャプチャが勝ち、ローカルコンポーネントのスイープ由来フィールド(text_slots / image_slots / default_size)は決して上書きされず、provenance: "plugin-observed" によって後続のスイープがレコードを格下げできないようになります。

命名規則

一貫性と可読性のため、リクエスト / レスポンスの JSON ノードは camelCase、SQS ペイロードのノードは snake_case を使用します。

リクエストとレスポンス

ヘッダー

リクエストヘッダー

  • Authorization
  • Content-Type
  • Accept
  • Accept-language

レスポンスヘッダー

  • Content-Type

コンポーネントキャプチャの送信

URI

POST /api/v1/organizations/{organization_id}/projects/{project_id}/wf2des/component-captures

パスパラメータ

名前 型 必須 説明
organization_id integer 必須 組織 ID
project_id integer 必須 プロジェクト ID

リクエストボディ

リクエストボディは JSON です。

{
  "figmaFileKey": "abc123XYZ",
  "captures": [
    {
      "kind": "set",
      "nodeId": "10:300",
      "setKey": "a1b2c3d4e5f6",
      "componentName": "Button",
      "componentKeys": ["k1", "k2"],
      "axes": { "Size": ["S", "M"], "State": ["default", "disabled"] },
      "defaults": { "Size": "M", "State": "default" },
      "textProps": ["Label#1:0"],
      "variants": [
        {
          "variantProps": { "Size": "M", "State": "default" },
          "size": { "w": 120, "h": 40 },
          "textSlots": [{ "layerPath": "Label", "defaultText": "Button" }],
          "nestedComponents": ["Icon"],
          "appearance": ["fill: #FF6214", "radius: 8"],
          "layoutShape": { "units": 2, "columns": 2, "rows": 1 }
        }
      ],
      "setName": "Button",
      "provenance": "plugin-observed"
    }
  ]
}

リクエストパラメータ

名前 型 必須 説明
figmaFileKey string 必須 キャプチャ対象コンポーネントが存在するファイル。Figma 逐語。
captures object[] 必須 プラグインの scanSelection() 出力 — 観測した COMPONENT_SET / COMPONENT ごとに 1 件、1 件以上。

キャプチャオブジェクト

名前 型 必須 説明
kind string (enum) 必須 set = COMPONENT_SET(バリアント軸は axes)、standalone = 単体 COMPONENT。
nodeId string 必須 COMPONENT_SET(または単体 COMPONENT)のノード ID。
setKey string | null 必須 COMPONENT_SET の publish key。単体または未公開の場合は null。
componentName string 必須 Figma が報告するセット(またはコンポーネント)名。
componentKeys string[] 必須 セット内コンポーネント(または単一コンポーネント)の publish key。
axes object (string→string[]) 必須 バリアント軸名 → 取りうる選択肢。正規(authoritative) — スイープの断片を置き換える。
defaults object (string→string) 必須 バリアント軸名 → デフォルト値。
textProps string[] 必須 バリアント以外の BOOLEAN / TEXT / INSTANCE_SWAP コンポーネントプロパティ名。
variants object[] 任意 バリアントごとの記述。デフォルトは []。部分的である場合がある — 到達可能ならセット全体、そうでなければ観測できたバリアントのみ。
setName string | null 任意 到達可能な場合の COMPONENT_SET の実名。デフォルトは null。スイープはリモート文書を「見えたインスタンス」の名前で命名するため、実コンポーネント名をレジストリに保持できるのはこのフィールドによる。
provenance string (literal) 必須 常に plugin-observed。Figma 内部から読まれたことを示し、後続スイープによる格下げを防ぐ。

バリアントオブジェクト

名前 型 必須 説明
variantProps object (string→string) 必須 このバリアント自身の軸値。バリアント COMPONENT の名前からパースされる。
size { w, h } 必須 このバリアント自身のバウンディングサイズ。
textSlots object[] 必須 { layerPath, defaultText } — このバリアントの テキストレイヤー。セット内のバリアントは異なるレイヤーを持つ。
nestedComponents string[] 必須 このバリアントが含むインスタンスレイヤー名(各インスタンスで走査は停止)。
appearance string[] 任意 このバリアントの見た目を、自ノードから読んだ事実として列挙 — 塗り、境界線(プレースホルダを慣習的に示す破線を含む)、角丸、そもそも内容を持つか否か。デフォルトは []。
layoutShape { units, columns, rows } | null 任意 このバリアントがセルを並べるグリッド。規則的なタイリングでない場合は null。他のすべてが同一のバリアントを識別できる唯一のフィールド — 同じ 6 セルを一方は 2 列、他方は 3 列で並べるコンテナなど。

レスポンス

レスポンスは JSON です(HTTP ステータス: 202 Accepted)。

{
  "eventRunId": "0190f3a1-2c4e-7b8d-9e0f-1a2b3c4d5e72",
  "figmaFileKey": "abc123XYZ",
  "captureCount": 1
}

レスポンスフィールド

名前 型 説明
eventRunId string GET …/wf2des/events/{eventRunId}/status をポーリングして進行状況を取得する。
figmaFileKey string リクエストのエコー。
captureCount integer ワーカーへ転送されたキャプチャ件数。

認証

認証は Amazon Cognito が発行する JSON Web Token(JWT)で行われます。加えて、呼び出し元はプロジェクトへの Write 権限を保持している必要があります。

エラーハンドリング

説明 ステータスコード ステータス名
不正なボディ(captures が空、またはスキーマ不適合のキャプチャ) 400 Bad Request
認証情報の欠落 401 Unauthorized
権限不足(プロジェクトへの Write 権限なし) 403 Forbidden
プロジェクトまたは組織が見つからない 404 Not Found
SQS 送信の失敗 500 Internal Server Error

処理フロー

  1. パスパラメータから組織 ID とプロジェクト ID を、リクエストボディを取得する。
  2. ユーザーがプロジェクトへの Write 権限を持つことを検証する。
  3. 新しい eventRunId を採番する。
  4. 各キャプチャを snake_case 化し、component_capture イベントを wf2des-events SQS キューへ送信する。
  5. ポーリング用ハンドルと転送件数とともに 202 を返す。

非同期処理

component_capture イベントはワーカーのレジストリマージにルーティングされ、各キャプチャを design_component へ upsert します。キャプチャは component_key と variant_properties で 勝ち、ワーカーは軸ごとにマージし、ローカルコンポーネントのスイープ由来スロットデータには触れません。

これは 内部 実行です — ai-status Webhook も PostgreSQL 効果もありません。

SQS ペイロード

フィールド名はワーカーの ComponentCapture / VariantProfile モデルに合わせて snake_case 化されます。

{
  "event_type": "component_capture",
  "organization_id": 1,
  "project_id": 7,
  "event_run_id": "0190f3a1-2c4e-7b8d-9e0f-1a2b3c4d5e72",
  "figma_file_key": "abc123XYZ",
  "captures": [
    {
      "kind": "set",
      "node_id": "10:300",
      "set_key": "a1b2c3d4e5f6",
      "component_name": "Button",
      "component_keys": ["k1", "k2"],
      "axes": { "Size": ["S", "M"] },
      "defaults": { "Size": "M" },
      "text_props": ["Label#1:0"],
      "variants": [
        {
          "variant_props": { "Size": "M" },
          "size": { "w": 120, "h": 40 },
          "text_slots": [{ "layer_path": "Label", "default_text": "Button" }],
          "nested_components": ["Icon"]
        }
      ]
    }
  ]
}