Repository: gatsbyjs/gatsby
File: packages/gatsby-source-contentful/src/extend-node-type.js (JavaScript)

Code before:
      },
      json: {
        type: GraphQLString,
        deprecationReason: `This field is deprecated, please use 'raw' instead. @todo add link to migration steps.`,
      },
      references: {
        type: [`ContentfulReference`],
        async resolve(source, args, context, info) {
          const parent = await context.nodeModel.findRootNodeAncestor(source)

          const rawReferences = { Entry: new Set(), Asset: new Set() }

          // Locate all Contentful Links within the rich text data
          const traverse = obj => {
            for (let k in obj) {
              const value = obj[k]
              if (value && value.sys && value.sys.type === `Link`) {
                rawReferences[value.sys.linkType].add(value.sys.contentful_id)
              } else if (value && typeof value === `object`) {
                traverse(value)
              }
            }
          }

          traverse(JSON.parse(source.raw))

          if (!rawReferences.Entry.size && !rawReferences.Asset.size) {
            return []
          }

          const rawEntries = Array.from(rawReferences.Entry)
          const rawAssets = Array.from(rawReferences.Asset)

          // Query for referenced nodes
          const resultEntries = await context.nodeModel.runQuery({
            query: {
              filter: {
                contentful_id: { in: rawEntries },
              },
            },
            type: `ContentfulEntry`,
          })

          const resultAssets = await context.nodeModel.runQuery({
            query: {
              filter: {
                contentful_id: { in: rawAssets },
              },
            },
            type: `ContentfulAsset`,
          })

Review comment (suggestion):
I'd swap this around
```suggestion
              if (value && typeof value === `object`) {
                if (value.sys?.type === `Link`) {
                  rawReferences[value.sys.linkType].add(value.sys.contentful_id)
                } else
                  traverse(value)
                }
              }
```

Code after:
  if (type.name.match(/contentful.*RichTextNode/)) {
    return {
      nodeType: {
        type: GraphQLString,
        deprecationReason: `This field is deprecated, please use 'raw' instead. @todo add link to migration steps.`,
      },
      json: {
        type: GraphQLString,
        deprecationReason: `This field is deprecated, please use 'raw' instead. @todo add link to migration steps.`,
      },
      references: {
        type: [`ContentfulReference`],
        async resolve(source, args, context, info) {
          const parent = await context.nodeModel.findRootNodeAncestor(source)

          const rawReferences = { Entry: new Set(), Asset: new Set() }

          // Locate all Contentful Links within the rich text data
          const traverse = obj => {
            for (let k in obj) {
              const value = obj[k]
              if (value && value.sys && value.sys.type === `Link`) {
                rawReferences[value.sys.linkType].add(value.sys.contentful_id)
              } else if (value && typeof value === `object`) {
                traverse(value)
              }
            }
          }

          traverse(JSON.parse(source.raw))

          if (!rawReferences.Entry.size && !rawReferences.Asset.size) {
            return []
          }

          const rawEntries = Array.from(rawReferences.Entry)
          const rawAssets = Array.from(rawReferences.Asset)

          // Query for referenced nodes
          const resultEntries = await context.nodeModel.runQuery({
            query: {
              filter: {
                contentful_id: { in: rawEntries },
              },
            },
            type: `ContentfulEntry`,
          })

          const resultAssets = await context.nodeModel.runQuery({
            query: {
              filter: {