This repository has been archived by the owner on Apr 12, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add snippet to migrate PT to plain text
- Loading branch information
1 parent
a34f85d
commit ec065dc
Showing
1 changed file
with
71 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/* eslint-disable no-console */ | ||
import client from 'part:@sanity/base/client' | ||
|
||
// Run this script with: `sanity exec --with-user-token migrations/migratePortableTextToPlainText.js` | ||
// | ||
// This example shows how you may write a migration script that migrates Portable Text | ||
// into plain text on a specific document type (author). | ||
// This will migrate documents in batches of 100 and continue patching until no more documents are | ||
// returned from the query. | ||
// | ||
// This script can safely be run, even if documents are being concurrently modified by others. | ||
// If a document gets modified in the time between fetch => submit patch, this script will fail, | ||
// but can safely be re-run multiple times until it eventually runs out of documents to migrate. | ||
|
||
// A few things to note: | ||
// - This script will exit if any of the mutations fail due to a revision mismatch (which means the | ||
// document was edited between fetch => update) | ||
// - The query must eventually return an empty set, or else this script will continue indefinitely | ||
|
||
// Fetching documents that matches the precondition for the migration. | ||
// NOTE: This query should eventually return an empty set of documents to mark the migration | ||
// as complete | ||
|
||
function blocksToText(blocks) { | ||
return blocks | ||
.filter((blk) => blk.type === 'block') | ||
.map((block) => { | ||
return block.children.map((child) => child.text).join('') | ||
}) | ||
.join('\n\n') | ||
} | ||
|
||
const fetchDocuments = () => | ||
client.fetch(`*[_type == 'author' && defined(bio) && bio._type === 'array'][0...100] {_id, _rev, name}`) | ||
|
||
const buildPatches = (docs) => | ||
docs.map((doc) => ({ | ||
id: doc._id, | ||
patch: { | ||
set: {bio: {text: blocksToText(doc.bio), _type: 'text'}}, | ||
// this will cause the migration to fail if any of the documents has been | ||
// modified since it was fetched. | ||
ifRevisionID: doc._rev, | ||
}, | ||
})) | ||
|
||
const createTransaction = (patches) => | ||
patches.reduce((tx, patch) => tx.patch(patch.id, patch.patch), client.transaction()) | ||
|
||
const commitTransaction = (tx) => tx.commit() | ||
|
||
const migrateNextBatch = async () => { | ||
const documents = await fetchDocuments() | ||
const patches = buildPatches(documents) | ||
if (patches.length === 0) { | ||
console.log('No more documents to migrate!') | ||
return null | ||
} | ||
console.log( | ||
`Migrating batch:\n %s`, | ||
patches.map((patch) => `${patch.id} => ${JSON.stringify(patch.patch)}`).join('\n') | ||
) | ||
const transaction = createTransaction(patches) | ||
await commitTransaction(transaction) | ||
return migrateNextBatch() | ||
} | ||
|
||
migrateNextBatch().catch((err) => { | ||
console.error(err) | ||
process.exit(1) | ||
}) |