# Querying a SDTF graph

## Introduction

Your token system can be more complex than it seems. You will often need to interact with your token graph to transform a specific set of design tokens within a Specify configuration.

This article will help you understand how you can query your token graph to select a specific set of tokens.

## Compatible parsers

* [filter](https://docs.specifyapp.com/reference/parsers/filter)
* [change-case](https://docs.specifyapp.com/reference/parsers/change-case)
* [convert-color](https://docs.specifyapp.com/reference/parsers/convert-color)
* [convert-dimension](https://docs.specifyapp.com/reference/parsers/convert-dimension)

## Query structure

Every Query holds a single a `where` property being an object, to select one branch of the graph, or an array of objects, to select many branches of the graph (OR statement).

```typescript
Type Query = { where: Where | Array<Where> }
```

The `where` property splits in 3 kinds: token, group, collection - offering a dedicated set of options to match against the given kind.

The `name` property accepts a RegExp for a value. These resources will help you debug your regular expressions:

* <https://regex101.com/>
* <https://regexr.com/>

### Where Token

```typescript
type WhereToken = {
  token: 
    | string
    | {
      name?: string;
      description?: string?;
    }
  select: 
    | true
    | {
      token?: boolean;
      parents?:
        | true
        | {
          groups?: true;
          collections?: true;
        }
    }
}
```

### Where Group

```typescript
type WhereGroup = {
  group: string;
  select: 
    | true
    | {
      group?: boolean;
      parents?:
        | true
        | {
          groups?: true;
          collections?: true;
        }
      children:
        | true
        | {
          groups?: true;
          collections?: true;
          tokens?: true;
        }
    }
}
```

### Where Collection

```typescript
type WhereCollection = {
  collection: string;
  select: 
    | true
    | {
      collection?: boolean;
      parents?:
        | true
        | {
          groups?: true;
        }
      children:
        | true
        | {
          groups?: true;
          tokens?: true;
        }
    }
}
```

## Use cases

### Select tokens from a specific collection

{% tabs %}
{% tab title="Input" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
<strong>  "primitive": {
</strong>    "$description": "`primitive` is a group used for semantic grouping.",
    "spacing": {
      "1": {
        "$type": "dimension",
        "$value": {
          "default": {
            "value": 4,
            "unit": "px"
          }
        }
      }
    }
  },
<strong>  "Colors": {
</strong>    "$description": "`Colors` is a collection.",
    "$collection": {
      "$modes": [
        "default"
      ]
    },
    "black": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#000000",
          "alpha": 1
        }
      }
    },
    "white": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#FFFFFF",
          "alpha": 1
        }
      }
    }
  }
}
</code></pre>

{% endtab %}

{% tab title="Config" %}
{% code title=".specifyrc.json" lineNumbers="true" %}

```json
{
  "version": "2",
  "repository": "@organization/repository",
  "personalAccessToken": "<your-personal-access-token>",
  "rules": [
    {
      "name": "Get tokens from collection named 'Colors'",
      "parsers": [
        {
          "name": "filter",
          "options": {
            "query": {
              "where": {
                "collection": "^Colors$",
                "select": {
                  "parents": true,
                  "children": true
                }
              }
            }
          }
        }
      ]
    }
  ]
}
```

{% endcode %}
{% endtab %}

{% tab title="Output" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
<strong>  "Colors": {
</strong>    "$collection": {
      "$modes": [
        "default"
      ]
    },
    "black": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#000000",
          "alpha": 1
        }
      }
    },
    "white": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#FFFFFF",
          "alpha": 1
        }
      }
    }
  }
}
</code></pre>

{% endtab %}
{% endtabs %}

### Select tokens from several collections matching a naming pattern

{% tabs %}
{% tab title="Input" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
<strong>  "primitive": {
</strong>    "$description": "`primitive` is a group used for semantic grouping.",
    "spacing": {
      "1": {
        "$type": "dimension",
        "$description": "`primitive.spacing.1` is a dimension token without modes.",
        "$value": {
          "default": {
            "value": 4,
            "unit": "px"
          }
        }
      }
    }
  },
<strong>  "Core - Colors": {
</strong>    "$collection": {
      "$modes": [
        "default"
      ]
    },
    "black": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#000000",
          "alpha": 1
        }
      }
    },
    "white": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#FFFFFF",
          "alpha": 1
        }
      }
    }
  },
<strong>  "Core - Spacing": {
</strong>    "$collection": {
      "$modes": [
        "default"
      ]
    },
    "space-1": {
      "$type": "spacing",
      "$value": {
        "default": { "value": 1, "unit": "px" }
      }
    },
    "space-2": {
      "$type": "spacing",
      "$value": {
        "default": { "value": 2, "unit": "px" }
      }
    }
  }
}
</code></pre>

{% endtab %}

{% tab title="Config" %}
{% code title=".specifyrc.json" lineNumbers="true" %}

```json
{
  "version": "2",
  "repository": "@organization/repository",
  "personalAccessToken": "<your-personal-access-token>",
  "rules": [
    {
      "name": "Get tokens from all collections whose names contain 'Core'",
      "parsers": [
        {
          "name": "filter",
          "options": {
            "where": {
              "collection": "Core",
              "select": {
                "collection": true,
                "children": {
                  "tokens": true
                }
              }
            }
          }
        }
      ]
    }
  ]
}
```

{% endcode %}
{% endtab %}

{% tab title="Output" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
<strong>  "Core - Colors": {
</strong>    "$collection": {
      "$modes": [
        "default"
      ]
    },
    "black": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#000000",
          "alpha": 1
        }
      }
    },
    "white": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#FFFFFF",
          "alpha": 1
        }
      }
    }
  },
<strong>  "Core - Spacing": {
</strong>    "$collection": {
      "$modes": [
        "default"
      ]
    },
    "space-1": {
      "$type": "spacing",
      "$value": {
        "default": {
          "value": 1,
          "unit": "px"
        }
      }
    },
    "space-2": {
      "$type": "spacing",
      "$value": {
        "default": {
          "value": 2,
          "unit": "px"
        }
      }
    }
  }
}
</code></pre>

{% endtab %}
{% endtabs %}

### Select tokens from a specific group

{% tabs %}
{% tab title="Input" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
<strong>  "primitive": {
</strong>    "$description": "`primitive` is a group used for semantic grouping.",
    "spacing": {
      "1": {
        "$type": "dimension",
        "$description": "`primitive.spacing.1` is a dimension token without modes.",
        "$value": {
          "default": {
            "value": 4,
            "unit": "px"
          }
        }
      }
    },
    "font": {
      "interBold": {
        "$type": "font",
        "$value": {
          "default": {
            "family": "Inter",
            "postScriptName": "Inter Bold",
            "weight": "bold",
            "style": "normal",
            "files": [
              {
                "format": "ttf",
                "url": "https://static.specifyapp.com/sdtf-seeds/inter-bold.ttf",
                "provider": "Specify"
              }
            ]
          }
        }
      }
    }
  },
<strong>  "Text Styles": {
</strong>    "heading": {
      "$type": "textStyle",
      "$value": {
        "default": {
          "font": {
            "$alias": "primitive.font.interBold",
            "$mode": "default"
          },
          "color": null,
          "fontSize": {
            "value": 32,
            "unit": "px"
          },
          "lineHeight": {
            "value": 40,
            "unit": "px"
          },
          "fontFeatures": null,
          "letterSpacing": null,
          "paragraphSpacing": null,
          "textAlignHorizontal": null,
          "textAlignVertical": null,
          "textDecoration": null,
          "textIndent": null,
          "textTransform": null
        }
      }
    },
    "display": {
      "$type": "textStyle",
      "$value": {
        "default": {
          "font": {
            "$alias": "primitive.font.interBold",
            "$mode": "default"
          },
          "color": null,
          "fontSize": {
            "value": 56,
            "unit": "px"
          },
          "lineHeight": {
            "value": 64,
            "unit": "px"
          },
          "fontFeatures": null,
          "letterSpacing": {
            "value": -1,
            "unit": "px"
          },
          "paragraphSpacing": null,
          "textAlignHorizontal": null,
          "textAlignVertical": null,
          "textDecoration": null,
          "textIndent": null,
          "textTransform": null
        }
      }
    }
  }
}
</code></pre>

{% endtab %}

{% tab title="Config" %}
{% code title=".specifyrc.json" lineNumbers="true" %}

```json
{
  "version": "2",
  "repository": "@organization/repository",
  "personalAccessToken": "<your-personal-access-token>",
  "rules": [
    {
      "name": "Get tokens from the group named 'Text Styles'",
      "parsers": [
        {
          "name": "filter",
          "options": {
            "query": {
              "where": {
                "group": "^Text Styles$",
                "select": {
                  "parents": true,
                  "children": true
                }
              }
            }
          }
        }
      ]
    }
  ]
}
```

{% endcode %}
{% endtab %}

{% tab title="Output" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
<strong>  "Text Styles": {
</strong>    "display": {
      "$type": "textStyle",
      "$value": {
        "default": {
          "fontSize": {
            "value": 56,
            "unit": "px"
          },
          "color": null,
          "fontFeatures": null,
          "lineHeight": {
            "value": 64,
            "unit": "px"
          },
          "letterSpacing": {
            "value": -1,
            "unit": "px"
          },
          "paragraphSpacing": null,
          "textAlignHorizontal": null,
          "textAlignVertical": null,
          "textDecoration": null,
          "textIndent": null,
          "textTransform": null,
          "font": {
            "$alias": "primitive.font.interBold",
            "$mode": "default"
          }
        }
      }
    },
    "heading": {
      "$type": "textStyle",
      "$value": {
        "default": {
          "fontSize": {
            "value": 32,
            "unit": "px"
          },
          "color": null,
          "fontFeatures": null,
          "lineHeight": {
            "value": 40,
            "unit": "px"
          },
          "letterSpacing": null,
          "paragraphSpacing": null,
          "textAlignHorizontal": null,
          "textAlignVertical": null,
          "textDecoration": null,
          "textIndent": null,
          "textTransform": null,
          "font": {
            "$alias": "primitive.font.interBold",
            "$mode": "default"
          }
        }
      }
    }
  }
}
</code></pre>

{% endtab %}
{% endtabs %}

### Select tokens of a specific type from a collection

{% tabs %}
{% tab title="Input" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
<strong>  "Android": {
</strong>    "$collection": {
      "$modes": [
        "default"
      ]
    },
    "black": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#000000",
          "alpha": 1
        }
      }
    },
    "white": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#FFFFFF",
          "alpha": 1
        }
      }
    }
  },
  "primitive": {
    "gray": {
      "0": {
        "$type": "color",
        "$value": {
          "default": {
            "model": "hex",
            "hex": "#f8f9fa",
            "alpha": 1
          }
        }
      },
      "9": {
        "$type": "color",
        "$value": {
          "default": {
            "model": "hex",
            "hex": "#212529",
            "alpha": 1
          }
        }
      }
    }
  }
}
</code></pre>

{% endtab %}

{% tab title="Config" %}
{% code title=".specifyrc.json" lineNumbers="true" %}

```json
{
  "version": "2",
  "repository": "@organization/repository",
  "personalAccessToken": "<your-personal-access-token>",
  "rules": [
    {
      "name": "Get color tokens from the 'Android' collection",
      "parsers": [
        {
          "name": "filter",
          "options": {
            "query": {
              "where": {
                "collection": "^Android$",
                "andWhere": {
                  "token": ".*",
                  "withTypes": { "include": ["color"] },
                  "select": {
                    "token": true,
                    "parents": {
                      "collections": true
                    }
                  }
                }
              }            
            }
          }
        }
      ]
    }
  ]
}
```

{% endcode %}
{% endtab %}

{% tab title="Output" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
<strong>  "Android": {
</strong>    "$collection": {
      "$modes": [
        "default"
      ]
    },
    "black": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#000000",
          "alpha": 1
        }
      }
    },
    "white": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#FFFFFF",
          "alpha": 1
        }
      }
    }
  }
}
</code></pre>

{% endtab %}
{% endtabs %}

### Select all tokens from a collection and from groups matching a naming pattern

{% tabs %}
{% tab title="Input" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
  "Android": {
    "$collection": {
      "$modes": [
        "default"
      ]
    },
<strong>    "primitive": {
</strong>      "gray": {
        "$type": "color",
        "$value": {
          "default": {
            "model": "hex",
            "hex": "#f8f9fa",
            "alpha": 1
          }
        }
      }
    },
<strong>    "components": {
</strong>      "black": {
        "$type": "color",
        "$value": {
          "default": {
            "model": "hex",
            "hex": "#000000",
            "alpha": 1
          }
        }
      },
      "white": {
        "$type": "color",
        "$value": {
          "default": {
            "model": "hex",
            "hex": "#FFFFFF",
            "alpha": 1
          }
        }
      }
    }
  }
}
</code></pre>

{% endtab %}

{% tab title="Config" %}
{% code title=".specifyrc.json" lineNumbers="true" %}

```json
{
  "version": "2",
  "repository": "@organization/repository",
  "personalAccessToken": "<your-personal-access-token>",
  "rules": [
    {
      "name": "Get color tokens from the 'Android' collection and from all groups named 'components'",
      "parsers": [
        {
          "name": "filter",
          "options": {
            "query": {
              "where": {
                "collection": "^Android$",
                "andWhere": {
                  "group": "^components$",
                  "andWhere": {
                    "token": ".*",
                    "withTypes": {
                      "include": ["color"]
                    },
                    "select": {
                      "token": true,
                      "parents": true
                    }
                  }
                }
              }
            }
          }
        }
      ]
    }
  ]
}
```

{% endcode %}
{% endtab %}

{% tab title="Output" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
  "Android": {
    "$collection": {
      "$modes": [
        "default"
      ]
    },
<strong>    "components": {
</strong>      "black": {
        "$type": "color",
        "$value": {
          "default": {
            "model": "hex",
            "hex": "#000000",
            "alpha": 1
          }
        }
      },
      "white": {
        "$type": "color",
        "$value": {
          "default": {
            "model": "hex",
            "hex": "#FFFFFF",
            "alpha": 1
          }
        }
      }
    }
  }
}
</code></pre>

{% endtab %}
{% endtabs %}

### Select tokens from several groups with different names

{% tabs %}
{% tab title="Input" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
<strong>  "group1": {
</strong>    "token1": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#000000",
          "alpha": 1
        }
      }
    }
  },
<strong>  "group2": {
</strong>    "token2": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#FFFFFF",
          "alpha": 1
        }
      }
    }
  },
<strong>  "group3": {
</strong>    "token3": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#FFFFFF",
          "alpha": 1
        }
      }
    }
  }
}
</code></pre>

{% endtab %}

{% tab title="Config" %}
{% code title=".specifyrc.json" lineNumbers="true" %}

```json
{
  "version": "2",
  "repository": "@organization/repository",
  "personalAccessToken": "<your-personal-access-token>",
  "rules": [
    {
      "name": "Get tokens from the group named 'Components' and/or from the group named 'Semantic'",
      "parsers": [
        {
          "name": "filter",
          "options": {
            "query": {
              "where": {
                "group": "^group1$|^group2$",
                "andWhere": {
                  "token": ".*",
                  "select": {
                    "token": true,
                    "parents": true
                  }
                }
              }
            }
          }
        }
      ]
    }
  ]
}
```

{% endcode %}
{% endtab %}

{% tab title="Output" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
<strong>  "group1": {
</strong>    "token1": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#000000",
          "alpha": 1
        }
      }
    }
  },
<strong>  "group2": {
</strong>    "token2": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#FFFFFF",
          "alpha": 1
        }
      }
    }
  }
}
</code></pre>

{% endtab %}
{% endtabs %}

### Select design tokens from a specific type

{% tabs %}
{% tab title="Input" %}
{% code lineNumbers="true" %}

```json
{
  "dimensions": {
    "spacing": {
      "1": {
        "$type": "dimension",
        "$value": {
          "default": {
            "value": 4,
            "unit": "px"
          }
        }
      }
    }
  },
  "colors": {
    "black": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#000000",
          "alpha": 1
        }
      }
    }
  }
}
```

{% endcode %}
{% endtab %}

{% tab title="Config" %}
{% code title=".specifyrc.json" lineNumbers="true" %}

```json
{
  "version": "2",
  "repository": "@organization/repository",
  "personalAccessToken": "<your-personal-access-token>",
  "rules": [
    {
      "name": "Get color tokens from the 'Android' collection and from all groups named 'components'",
      "parsers": [
        {
          "name": "filter",
          "options": {
            "query": {
              "where": {
                "token": ".*",
                "withTypes": {
                  "include": [
                    "color"
                  ]
                },
                "select": {
                  "parents": true
                }
              }
            }
          }
        }
      ]
    }
  ]
}
```

{% endcode %}
{% endtab %}

{% tab title="Output" %}
{% code lineNumbers="true" %}

```json
{
  "colors": {
    "black": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#000000",
          "alpha": 1
        }
      }
    }
  }
}
```

{% endcode %}
{% endtab %}
{% endtabs %}
