ascorbic / astro-loaders

Astro loaders
https://astro-loaders.netlify.app
25 stars 3 forks source link

@ascorbic/airtable-loader: `multipleLookupValues` and `formula` aren't always `string` type #47

Open inbn opened 1 week ago

inbn commented 1 week ago

Hi, first of all, thanks for this project – I'm loving being able to use my Airtable data in Astro.

The error I'm getting is in the airtableTypeToZodType function when using multipleLookupValues and formula fields:

InvalidContentEntryDataError: componentExamples → rec009nfVAzhubwTP data does not match collection schema.
Design system published.0: Expected type `"string"`, received "boolean"
Component published.0: Expected type `"string"`, received "boolean"
Published: Expected type `"string"`, received "number"

I believe this is because the code incorrectly assumes the result of multipleLookupValues is always an array of strings, and the result of formula is always a string.

Looking at the fields that are erroring, the result type is not a string:

[
  {
    type: "multipleLookupValues",
    options: {
      isValid: true,
      recordLinkFieldId: "fldVrQ8hneihrxV9Y",
      fieldIdInLinkedTable: "fldKJS9QJH0PwcGcr",
      result: {
        type: "checkbox",
        options: {
          icon: "check",
          color: "greenBright",
        },
      },
    },
    id: "fldGLWt5wBKpd44gT",
    name: "Design system published",
  },
  {
    type: "multipleLookupValues",
    options: {
      isValid: true,
      recordLinkFieldId: "fld7b4a6Ss2vsiui5",
      fieldIdInLinkedTable: "fldhR8p3HCKpvr7xL",
      result: {
        type: "checkbox",
        options: {
          icon: "check",
          color: "greenBright",
        },
      },
    },
    id: "fldyNEwrd5J93G6qk",
    name: "Component published",
  },
  {
    type: "formula",
    options: {
      isValid: true,
      formula: "IF(AND({fldyNEwrd5J93G6qk} != 0, {fldGLWt5wBKpd44gT} != 0), 1, 0)",
      referencedFieldIds: [
        "fldyNEwrd5J93G6qk",
        "fldGLWt5wBKpd44gT",
      ],
      result: {
        type: "number",
        options: {
          precision: 0,
        },
      },
    },
    id: "fldPocgI70tYaZHMw",
    name: "Published",
  },
]

Adding a check for options.result.type then setting the type based upon that fixes the error.

I've added this logic to the top of the airtableTypeToZodType function which fixes my individual use case. However, there's probably further work required to check all the other field types which could potentially contain non-string values.


if (type === "multipleLookupValues" && options?.result?.type) {
  const resultType = options.result.type;

  if (resultType === "checkbox") {
    return z.array(z.boolean());
  }
  if (resultType === "number") {
    return z.array(z.number());
  }
  if (resultType === "string") {
    return z.array(z.string());
  }
}

if (options?.result?.type) {
  const resultType = options.result.type;

  if (resultType === "checkbox") {
    return z.boolean(); 
  }
  if (resultType === "number") {
    return z.number(); 
  }
  if (resultType === "string") {
    return z.string(); 
  }
}

I'll try to put together a PR once I have time to test further.

ascorbic commented 3 days ago

Thanks for the report. It would be great if you could do a PR. If not then I'll look into it when I get a chance.