How to run mutations from Sanity CLI or Vision plugin?

8 replies
Last updated: Nov 10, 2021
Hi all. Just starting out playing with sanity, and I really like the Vision plugin so I have a nice UI for running queries. I know I can’t do mutations here … but is there an easy way to do them from the CLI command? Or do I have to make a small JS script using the client for each one?
AI Update

Great question! Yes, there's definitely an easier way than writing a full script for each mutation you want to test.

The sanity exec command is what you're looking for. It lets you run JavaScript/TypeScript files that can perform mutations (create, patch, delete) with access to an authenticated Sanity client.

Here's how it works:

sanity exec myMutation.js --with-user-token

The --with-user-token flag gives your script an authenticated client with your user permissions, so you can perform mutations just like you would in your application code.

For quick one-off mutations, you can create simple scripts like:

Create a document:

// createPost.js
import {getCliClient} from 'sanity/cli'

const client = getCliClient()

client.create({
  _type: 'post',
  title: 'My new post',
  slug: {current: 'my-new-post'}
}).then(console.log)

Patch a document:

// patchPost.js
import {getCliClient} from 'sanity/cli'

const client = getCliClient()

client.patch('document-id-here')
  .set({title: 'Updated title'})
  .commit()
  .then(console.log)

Delete a document:

// deletePost.js
import {getCliClient} from 'sanity/cli'

const client = getCliClient()

client.delete('document-id-here')
  .then(console.log)

Then run any of these with:

sanity exec createPost.js --with-user-token

You can keep a folder of these small utility scripts for common operations you want to test. It's much more convenient than rebuilding a client each time, and the sanity exec command automatically has access to your project configuration.

Pro tip: Always back up your dataset before running mutation scripts, especially on production data:

sanity dataset export

For more complex bulk operations or migrations, check out the migration tooling which has built-in batching and dry-run capabilities.

Show original thread
8 replies
Hey User! You can see some example of using the CLI for mutations here .
Thanks
user M
… I was actually using the sample from here as a starting point, since I’m trying to subtract 60 days from a datetime field for all my documents (and I don’t think the
dec
mutation will work there?)
What I have:
import sanityClient from 'part:@sanity/base/client'
const client = sanityClient.withConfig({
  apiVersion: '2021-11-01',
})


const fetchDocuments = () =>
  client.fetch(`*[_type == 'deal']{_id, title, publishedDate}[0..1]`)

const buildPatches = docs => {
  return docs.map(doc => {
    console.log(doc.title);
    const pubDate = new Date(doc.publishedDate);
    pubDate.setDate( pubDate.getDate() - 60 );
    return {
      id: doc._id,
      patch: {
        set: {
          publishedDate: pubDate
        }
      }
    }
  })
}

const createTransaction = patches =>
  patches.reduce((tx, patch) => tx.patch(patch.id, patch.patch), client.transaction())

const commitTransaction = tx => tx.commit()

const migrate = async () => {
  const documents = await fetchDocuments()
  const patches = buildPatches(documents)
  console.log(
    `Migrating batch:\n %s`,
    patches.map(patch => `${patch.id} => ${JSON.stringify(patch.patch)}`).join('\n')
  )
  const transaction = createTransaction(patches)
  return await commitTransaction(transaction)
}

migrate().catch(err => {
  console.error(err)
  process.exit(1)
})
Ah, from your question, I thought you were looking for an option besides the JS client.
I was … but that would only work for “non-dynamic” changes, I suppose, right? i.e. if I can define the change I want in a static string (as opposed to something like changing a value based on some other condition).
In any case, I think I’m just up against a permissions issue now. I started a thread here … if you have any ideas!
Yeah, exactly. If you need to use JS to compute something this is the way to go. I think you may want to use the date fns package to perform your subtraction here.
Re your permissions issue, can you DM me your project ID so that I can check your permissions on the backend?

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?