sanity-io / sanity-algolia

Utilities for indexing Sanity documents in Algolia
MIT License
67 stars 16 forks source link

webhookSync Type Error: Argument of type `import(".../node_modules/@sanity/client/sanityClient").SanityClient'` is not assignable to parameter of type `'import(".../next-sanity/node_modules/@sanity/client/sanityClient").SanityClient'` #19

Closed lukastransom closed 2 years ago

lukastransom commented 2 years ago

I'm getting this TypeScript error on the first parameter to the webhookSync method from the sanityAlgolia instance:

Argument of type 'import("/Users/lut/webdev/sanity/restaurant-project/node_modules/@sanity/client/sanityClient").SanityClient' is not assignable to parameter of type 'import("/Users/lut/webdev/sanity/restaurant-project/node_modules/next-sanity/node_modules/@sanity/client/sanityClient").SanityClient'.
  The types returned by 'config(...)' are incompatible between these types.
    Type 'ClientConfig' is missing the following properties from type 'SanityClient': clone, config, withConfig, clientConfig, and 22 more.ts(2345)

I'm not sure if this is a next-sanity issue or a sanity-algolia issue. I'm only importing from @sanity/client (not next-sanity). Any ideas as to why it's referencing two different paths? Why should the path be relevant to the type? "/Users/lut/webdev/sanity/restaurant-project/node_modules/@sanity/client/sanityClient" vs "/Users/lut/webdev/sanity/restaurant-project/node_modules/next-sanity/node_modules/@sanity/client/sanityClient"

My pages/api/search/webhook.ts looks like this:

/**
 * Reference: https://hdoro.dev/integrating-sanity-io-algolia
 */
import createSanityClient from '@sanity/client'
import indexer from 'sanity-algolia'
import { VercelRequest, VercelResponse } from '@vercel/node'
import { algoliaInstance, LOCATION_PROJECTION } from './index-locations'

const options = {
  dataset: process.env.SANITY_PROJECT_DATASET,
  projectId: process.env.SANITY_PROJECT_ID,
  useCdn: process.env.NODE_ENV === 'production',
  apiVersion: '2022-02-06',
}

export const sanityClient = createSanityClient(options)

const algoliaIndex = process.env.NEXT_PUBLIC_ALGOLIA_INDEX_LOCATIONS
const algoliaSecret = process.env.ALGOLIA_SECRET

export default async function handler(req: VercelRequest, res: VercelResponse) {
  const passphrase = req?.query?.passphrase

  // Reject request if passphrase is not passed with request
  if (passphrase !== algoliaSecret) {
    res.status(401).send('🔐 Not Authenticated')
    return
  }

  // Only accept JSON requests
  if (req.headers['content-type'] !== 'application/json') {
    res.status(400)
    res.send('📥 Bad request')
    return
  }

  const index = algoliaInstance.initIndex(algoliaIndex)
  const sanityAlgolia = indexer(
    {
      location: {
        index,
        // The projection is the piece of the GROQ query
        // where we determine what data to fetch
        projection: LOCATION_PROJECTION,
      },
      // 💡 Could have many other document types here!
    },

    // Serializer function for manipulating documents with Javascript
    // I'm not using it as GROQ is doing all the work
    (document) => {
      console.log('🧮 Processed:', document.title, document._id)
      return document
    }

    // Optional: Visibility function to determine which document should be included
    // (document) => !['unapproved'].includes(document.status),
  )

  const ids = {
    created: req.body.ids.created.filter((id) => !!id),
    updated: req.body.ids.updated.filter((id) => !!id),
    deleted: req.body.ids.deleted.filter((id) => !!id),
  }

  // Now let `sanityAlgolia` do the heavy lifting
  return sanityAlgolia
    .webhookSync(sanityClient, { ids }) // <-- this is where the ts error is on 'sanityClient'
    .then(() => res.status(200).send('🎉 Success'))
    .catch(() => res.status(500).send('❌ Something went wrong'))
}

This was working, but now the TS errors are failing the build so it can't deploy from Vercel.

jleknes commented 2 years ago

I experienced the same problem, and solved it by adding this snippet to package.json:

  "resolutions": {
    "@sanity/client": "^3.1.0"
  }

However, this might have negative side effects, so I think that a much better solution is that sanity-algolia releases a new version with updates dependencies.

3200pro commented 2 years ago

@lukastransom, Did anything work for you regarding a solution? I ran into the same error. Also, would you mind posting the basics of your projection? I'd like to compare to my setup if possible.

runeb commented 2 years ago

@lukastransom Have you installed @sanity/client as a dependency in your project? Since you are directly using it yourself you should also declare it as a direct dependency and import resolution should pick it up. These other sanity clients that next-sanity and sanity-algolia uses are of different versions and used by them internally.

lukastransom commented 2 years ago

@3200pro Since it's just a TS error (the JS code itself works fine), I ended up just adding a // @ts-nocheck to the top of the file.

@runeb Yes, I'm seeing "@sanity/client": "^3.1.0" in my dependencies section of package.json (indeed, in the front-end/non-studio portion of my repo). Even still, the TS error persists 😞 Let me know if there's anything else I should check!

runeb commented 2 years ago

@lukastransom Thanks for the update. I've released a new tagged version which seeks to clean up these dependency issues. Can you try

sanity-algolia@type-deps-fix

and let me know if that fixes your issues?

lukastransom commented 2 years ago

@runeb Thanks for the follow up—It worked!

I did npm i sanity-algolia@type-deps-fix which boosted my version to "sanity-algolia": "^1.0.3", resulting in no more TS errors visible in VS Code or in my Vercel deploy builds.

alexghr commented 2 years ago

Hey @runeb, the patched version does indeed fix the type error. Any chance you could get this published under latest as well in order to make it default? :smile: