@sanity/import
Version:
Import documents to a Sanity dataset
95 lines (94 loc) • 5.14 kB
JavaScript
import createDebug from 'debug';
import { absolutifyPaths, getAssetRefs, unsetAssetRefs } from './assetRefs.js';
import { assignArrayKeys } from './assignArrayKeys.js';
import { assignDocumentId } from './assignDocumentId.js';
import { batchDocuments } from './batchDocuments.js';
import { documentHasError } from './documentHasErrors.js';
import { importBatches } from './importBatches.js';
import { cleanupReferences, getStrongRefs, strengthenReferences, weakenStrongRefs } from './references.js';
import { uploadAssets } from './uploadAssets.js';
import { ensureUniqueIds } from './util/ensureUniqueIds.js';
import { validateAssetMapForReplacementChars } from './util/validateReplacementCharacters.js';
import { validateAssetDocuments } from './validateAssetDocuments.js';
import { validateCdrDatasets } from './validateCdrDatasets.js';
const debug = createDebug('sanity:import:array');
async function importDocuments(documents, options) {
options.onProgress({
step: 'Reading/validating data file'
});
for (const [i, doc] of documents.entries()){
documentHasError(doc, i);
}
// Validate assetMap for replacement characters
if (options.assetMap && options.allowReplacementCharacters !== true) {
validateAssetMapForReplacementChars(options.assetMap);
}
// Validate that there are no duplicate IDs in the documents
ensureUniqueIds(documents);
// Ensure that any cross-dataset references has datasets to point to
if (!options.skipCrossDatasetReferences) {
await validateCdrDatasets(documents, options);
}
let filteredDocuments = documents;
// Always filter out system documents unless explicitly allowed.
// Release system documents are an exception to this flag.
if (options.allowSystemDocuments !== true) {
filteredDocuments = documents.filter((doc)=>doc._id?.startsWith('_.releases.') || !doc._id?.startsWith('_.'));
}
// Replace relative asset paths if one is defined
// (file://./images/foo-bar.png -> file:///abs/olute/images/foo-bar.png)
const absPathed = filteredDocuments.map((doc)=>absolutifyPaths(doc, options.assetsBase));
// Assign document IDs for document that do not have one. This is necessary
// for us to strengthen references and import assets properly.
const ided = absPathed.map((doc)=>assignDocumentId(doc));
// User might not have applied `_key` on array elements which are objects;
// if this is the case, generate random keys to help realtime engine
const keyed = ided.map((doc)=>assignArrayKeys(doc));
// Sanity prefers to have a `_type` on every object. Make sure references
// has `_type` set to `reference`, and that there are no `_projectId` keys
const docs = keyed.map((doc)=>cleanupReferences(doc, options));
// Find references that will need strengthening when import is done
const strongRefs = docs.map((doc)=>getStrongRefs(doc)).filter((ref)=>ref !== null);
// Extract asset references from the documents
const assetRefs = docs.flatMap((doc)=>getAssetRefs(doc));
// Remove asset references from the documents
const assetless = docs.map((doc)=>unsetAssetRefs(doc));
// Make strong references weak so they can be imported in any order
const weakened = assetless.map((doc)=>weakenStrongRefs(doc));
// Create batches of documents to import. Try to keep batches below a certain
// byte-size (since document may vary greatly in size depending on type etc)
const batches = batchDocuments(weakened);
// Ensure that we don't reference missing assets, or assets in different datasets
debug('Validating asset documents');
await validateAssetDocuments(docs, options);
// Trigger actual import process
debug('Starting import of documents');
const { count: docsImported, importedIds } = await importBatches(batches, options);
// When using createIfNotExists (--missing), only upload assets for documents
// that were actually created. Documents that already existed in the dataset
// are assumed to already have their assets in place.
let filteredAssetRefs = assetRefs;
if (options.operation === 'createIfNotExists') {
const importedIdSet = new Set(importedIds);
filteredAssetRefs = assetRefs.filter((ref)=>importedIdSet.has(ref.documentId));
const skipped = assetRefs.length - filteredAssetRefs.length;
if (skipped > 0) {
debug('Skipping %d asset refs for %d already-existing documents', skipped, skipped);
}
}
// Documents are imported, now proceed with post-import operations
debug('Uploading assets');
const { failures: assetWarnings } = await uploadAssets(filteredAssetRefs, options);
// Strengthen references
debug('Strengthening references');
await strengthenReferences(strongRefs, options);
// Return number of documents imported
return {
numDocs: docsImported,
warnings: assetWarnings.map((warning)=>({
message: `Failed to upload asset: ${warning.url}`
}))
};
}
export { importDocuments };
//# sourceMappingURL=importFromArray.js.map