amzn / style-dictionary

A build system for creating cross-platform styles.
https://styledictionary.com
Apache License 2.0
3.94k stars 559 forks source link

Using parser and transformer throws error #1271

Open jjrodcast opened 4 months ago

jjrodcast commented 4 months ago

I'm working in a configuration for a project that that these files: generic_tokens.sjon and semantic_tokens.json

generic_tokens.json

{
  "black": {
    "0": {
      "$type": "color",
      "$value": "#00000000"
    },
    "85": {
      "$type": "color",
      "$value": "#000000d9"
    }
  },
  "charcoal": {
    "100": {
      "100": {
        "$type": "color",
        "$value": "#eeeeee"
      }
    },
  }
}

and

semantic_tokens.json

{
  "semantic": {
    "ghost": {
      "high": {
        "hover": {
          "$type": "color",
          "$value": "{charcoal.100.100}"
        }
      }
   }
}

I'm using a custom parser to add the color node in the generic_tokens.json so in that way it will be parser by style-dictionary but when I'm trying to execute the build command it throws an error that indicates the next:

Error: 
Reference Errors:
Some token references (1) could not be found.

I understand that this is because i'm changing the structure of the generic_tokens.json adding the color object in the root object, when I manually change the value from the semantic_tokens.json from charcoal.100.100 to color.charcoal.100.100 it works.

How can I solve this problem using a custom transformer, I'm using the transitive:true but it throws the error anyway. Any sample code where can I see some help?

jorenbroekema commented 4 months ago

You can't really solve the way references are resolved using transforms. This is because transforms do not apply to tokens that contain references, unless you have a transitive transform, after which it will first resolve the ref and then defer the transformation until after the references have been resolved. So, that still doesn't allow you to fix the reference in the transformation.

I'm not sure why you're doing what you're doing but wouldn't it make sense to add the color object into the dictionary during the parsing (or preprocessing might make more sense here) lifecycle step in a way that makes the references work? So instead of doing something like:

const obj = ...; // your parsed content without the injected color object
obj.color = colorObject; // instead of this

// do this
obj = { ...obj, ...colorObject };

in that way, whatever props you got inside your injected colorObject are just spread on the root level of the dictionary/parsed file content.

Again, I would recommend using a preprocessor over a parser for this kind of thing, because parsing happens on a per-file basis while it sounds to me like you're just trying to inject something into the dictionary as a whole, which can be done after it's all be parsed and combined into a dictionary object.

jjrodcast commented 4 months ago

Thanks I will check the preprocessors.