Nested object don't always validate

did:plc:3mdq56yhyqq5k6d4guztheaf opened this 29d ago 1 comments
did:plc:3mdq56yhyqq5k6d4guztheaf opened 29d ago

Nested objects are not necessarily supported by Lexicon validators. Currently e.g. atcute does not, which is used on https://pdsls.dev/. Also see https://github.com/bluesky-social/atproto-website/issues/470 for more details.

A Node.js script to validate Lexicons with atcute can be found at https://gist.github.com/vmx/4aaeaec4c61fb3b05d423eed0b4dcea4

Here's an example:

/// A social media post post
record post {
    // The text of the post
    text: string,
    /// The number of reactions to that post
    numReactions: {
        /// Number of likes
        likes: integer,
        /// Number of reposts
        reposts: integer,
    },
}

Currently converts to:

{
  "$type": "com.atproto.lexicon.schema",
  "lexicon": 1,
  "id": "com.example.post",
  "defs": {
    "main": {
      "type": "record",
      "description": "A social media post post",
      "key": "tid",
      "record": {
        "type": "object",
        "required": [],
        "properties": {
          "text": {
            "type": "string"
          },
          "numReactions": {
            "type": "object",
            "required": [],
            "properties": {
              "likes": {
                "type": "integer",
                "description": "Number of likes"
              },
              "reposts": {
                "type": "integer",
                "description": "Number of reposts"
              }
            },
            "description": "The number of reactions to that post"
          }
        }
      }
    }
  }
}

To make it validate with atcute, it needs to be something like:

{
  "$type": "com.atproto.lexicon.schema",
  "lexicon": 1,
  "id": "com.example.post",
  "defs": {
    "main": {
      "type": "record",
      "description": "A social media post post",
      "key": "tid",
      "record": {
        "type": "object",
        "required": [],
        "properties": {
          "text": {
            "type": "string"
          },
          "numReactions": {
            "type": "ref",
            "ref": "#numReactions",
            "description": "The number of reactions to that post"
          }
        }
      }
    },
    "numReactions": {
      "type": "object",
      "required": [],
      "properties": {
        "likes": {
          "type": "integer",
          "description": "Number of likes"
        },
        "reposts": {
          "type": "integer",
          "description": "Number of reposts"
        }
      }
    }
  }
}

Which corresponds to this MLF version:

/// A social media post post
record post {
    // The text of the post
    text: string,
    /// The number of reactions to that post
    numReactions: numReactions,
}

def type numReactions = {
    /// Number of likes
    likes: integer,
    /// Number of reposts
    reposts: integer,
};

The Lexicon version could potentially be auto-generated. But I'm not sure if that's desired. You can fix it by doing it manually as the MLF version above shows.

I've mostly opened this issue for people running into errors on https://pdsls.dev/ that their schema doesn't validate. You will get an error like:

Invalid lexicon: defs.main.record.properties.numReactions.type: invalid_literal (expected: ["boolean","integer","string","bytes","cid-link","blob","ref","union","unknown","array"])

One option could be to output a warning when nested objects are used until it's officially decided whether it's valid or not. Though I'm not sure if that's even needed.

Feel free to close this issue if you think no action is needed.

No activity yet.

cospan · schematic version control on atproto built on AT Protocol