Per-Kristian Nordnes
Fullstack developer at Sanity.io
Migration script to normalize Portable Text blocks across your whole dataset
import sanityClient from "part:@sanity/base&client";
import { normalizeBlock } from "@sanity/block-tools";
import { extractWithPath } from"@sanity/mutator";
// Act on all documents
const query = "*[]";
// Adjust the decorators to the set you want to allow
const allowedDecorators = [
"strong",
"em",
"code",
"underline",
"strike-through",
"sub",
"sup"
];
function convertPath(pathArr) {
return pathArr
.map(part => {
if (Number.isInteger(part)) {
return `[${part}]`;
}
return `.${part}`;
})
.join("")
.substring(1);
}
client.fetch(query).then(results => {
const patchedDocuments = [];
results.forEach(async result => {
const matches = extractWithPath('..[_type=="block"]', result);
let patch = client.patch(result._id);
matches.forEach(match => {
const block = match.value;
const path = convertPath(match.path);
const normalizedBlock = normalizeBlock(block, { allowedDecorators });
const patchData = { [path]: normalizedBlock };
patch = patch.set(patchData);
});
const patchLength = patch.operations.set
? Object.keys(patch.operations.set).length
: 0;
if (patchLength > 0) {
patchedDocuments.push(result._id);
await patch.commit();
console.log(
`Patched ${patchLength} blocks in document ${result._id}`
);
}
});
console.log(
`Patched ${patchedDocuments.length} documents with ids: ${JSON.stringify(
patchedDocuments,
null,
2
)}`
);
});
NOTE: We have shipped content migration tooling for Sanity (v3.27.0) that makes the approach described here. Check out the documentation and cheat sheet for learning how to do this with the proper tooling.
This migration script will go through all your documents, look for all Portable Text blocks and filter out decorators that aren't present in the allowedDecorators array. It will build a transaction of patches to update these blocks.
You can run this script with sanity exec normalizeAllBlocks.js --with-user-token
. It might be wise to export your dataset first since this script changes data.
Fullstack developer at Sanity.io
Do something with a uploaded file and populate a field in the document based on that
Go to Populate fields with data from a file upload