Skip to content

Instantly share code, notes, and snippets.

@3200pro
Created September 16, 2022 21:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 3200pro/914d24141f453e56408a0faa5482f9f6 to your computer and use it in GitHub Desktop.
Save 3200pro/914d24141f453e56408a0faa5482f9f6 to your computer and use it in GitHub Desktop.
Sanity Client: Migrate Document Type
import client from 'part:@sanity/base/client';
// Run this script with: `sanity exec --with-user-token scripts/migrate-document-type.js`
const OLD_TYPE = 'siteTool';
const NEW_TYPE = 'site.tool';
const fetchDocuments = () =>
client.fetch(
`*[_type == $oldType][0...10] {..., "incomingReferences": *[references(^._id)]{...}}`,
{ oldType: OLD_TYPE }
);
const buildMutations = (docs) => {
const mutations = [];
docs.forEach((doc) => {
console.log('movie', doc._id);
// Updating an document _type field isn't allowed, we have to create a new and delete the old
const newDocId = `${doc._id}-migrated`;
const newDocument = { ...doc, ...{ _id: newDocId, _type: NEW_TYPE } };
delete newDocument.incomingReferences;
delete newDocument._rev;
mutations.push({ create: newDocument });
// Patch each of the incoming references
doc.incomingReferences.forEach((referencingDocument) => {
console.log('ref', referencingDocument._id);
// ⚠️ We're assuming the field is named the same as the type!
// There might be another structure involved, perhaps an array, that needs patching
const updatedReference = {
[NEW_TYPE]: {
_ref: newDocId,
_type: 'reference'
}
};
mutations.push({
id: referencingDocument._id,
patch: {
set: updatedReference,
unset: [OLD_TYPE],
ifRevisionID: referencingDocument._rev
}
});
});
// Apply the delete mutation after references have been changed
mutations.push({ delete: doc._id });
});
return mutations.filter(Boolean);
};
const createTransaction = (mutations) => {
return mutations.reduce((tx, mutation) => {
if (mutation.patch) {
return tx.patch(mutation.id, mutation.patch);
}
if (mutation.delete) {
return tx.delete(mutation.delete);
}
if (mutation.create) {
return tx.createIfNotExists(mutation.create);
}
}, client.transaction());
};
const migrateNextBatch = async () => {
const documents = await fetchDocuments();
if (documents.length === 0) {
console.log('No more documents to migrate!');
return null;
}
const mutations = buildMutations(documents);
const transaction = createTransaction(mutations);
await transaction.commit();
return migrateNextBatch();
};
migrateNextBatch().catch((err) => {
console.error(JSON.stringify(err, null, 2));
process.exit(1);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment