UNPKG

@sanity/import

Version:

Import documents to a Sanity dataset

95 lines (94 loc) 5.14 kB
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