Skip to content

Commit

Permalink
[export] Fix incorrectly handled rewriting of non-sanity assets
Browse files Browse the repository at this point in the history
  • Loading branch information
rexxars committed Jun 12, 2020
1 parent c0be978 commit a058f82
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 69 deletions.
44 changes: 15 additions & 29 deletions packages/@sanity/export/src/AssetHandler.js
Expand Up @@ -66,7 +66,7 @@ class AssetHandler {
return
}

callback(null, await this.findAndModify(doc, ACTION_REWRITE))
callback(null, this.findAndModify(doc, ACTION_REWRITE))
})

// Called in the case where we don't _want_ assets, so basically just remove all asset documents
Expand All @@ -77,7 +77,7 @@ class AssetHandler {
return
}

callback(null, await this.findAndModify(doc, ACTION_REMOVE))
callback(null, this.findAndModify(doc, ACTION_REMOVE))
})

// Called when we are using raw export mode along with `assets: false`, where we simply
Expand Down Expand Up @@ -224,10 +224,9 @@ class AssetHandler {
return true
}

// eslint-disable-next-line complexity
findAndModify = async (item, action) => {
findAndModify = (item, action) => {
if (Array.isArray(item)) {
const children = await Promise.all(item.map(child => this.findAndModify(child, action)))
const children = item.map(child => this.findAndModify(child, action))
return children.filter(Boolean)
}

Expand All @@ -243,21 +242,11 @@ class AssetHandler {
if (isAsset && action === ACTION_REWRITE) {
const {asset, ...other} = item
const assetId = asset._ref
if (isModernAsset(assetId)) {
const assetType = getAssetType(item)
const filePath = `${assetType}s/${generateFilename(assetId)}`
return {
_sanityAsset: `${assetType}@file://./${filePath}`,
...(await this.findAndModify(other, action))
}
}

// Legacy asset
const type = this.assetsSeen.get(assetId) || (await this.lookupAssetType(assetId))
const filePath = `${type}s/${generateFilename(assetId)}`
const assetType = getAssetType(item)
const filePath = `${assetType}s/${generateFilename(assetId)}`
return {
_sanityAsset: `${type}@file://./${filePath}`,
...(await this.findAndModify(other, action))
_sanityAsset: `${assetType}@file://./${filePath}`,
...this.findAndModify(other, action)
}
}

Expand All @@ -267,8 +256,7 @@ class AssetHandler {
const key = keys[i]
const value = item[key]

// eslint-disable-next-line no-await-in-loop
newItem[key] = await this.findAndModify(value, action)
newItem[key] = this.findAndModify(value, action)

if (typeof newItem[key] === 'undefined') {
delete newItem[key]
Expand All @@ -277,15 +265,10 @@ class AssetHandler {

return newItem
}

lookupAssetType = async assetId => {
const docType = await this.client.fetch('*[_id == $id][0]._type', {id: assetId})
return docType === 'sanity.imageAsset' ? 'image' : 'file'
}
}

function isAssetField(item) {
return item.asset && item.asset._ref
return item.asset && item.asset._ref && isSanityAsset(item.asset._ref)
}

function getAssetType(item) {
Expand All @@ -297,8 +280,11 @@ function getAssetType(item) {
return type || null
}

function isModernAsset(assetId) {
return /^(image|file)/.test(assetId)
function isSanityAsset(assetId) {
return (
/^image-[a-f0-9]{40}-\d+x\d+-[a-z]+$/.test(assetId) ||
/^file-[a-f0-9]{40}-[a-z]+$/.test(assetId)
)
}

function generateFilename(assetId) {
Expand Down
45 changes: 23 additions & 22 deletions packages/@sanity/export/test/AssetHandler.test.js
Expand Up @@ -15,13 +15,14 @@ describe('asset handler', () => {
test('can rewrite documents / queue downloads', done => {
// prettier-ignore
const docs = [
{_id: 'doc1', _type: 'bike', name: 'Scooter', image: {_type: 'image', caption: 'Scooter bike', asset: {_ref: 'image-idx_abc123-3360x840-png'}, nested: {_type: 'image', asset: {_ref: 'image-idx_abc123-3360x840-png'}}}},
{_id: 'doc2', _type: 'bike', name: 'Dupe', image: {_type: 'image', asset: {_ref: 'image-idx_abc123-3360x840-png'}}},
{_id: 'doc3', _type: 'bike', name: 'Tandem', image: {_type: 'image', asset: {_ref: 'image-idx_abc456-310x282-jpg'}}},
{_id: 'old4', _type: 'bike', name: 'Cool', image: {asset: {_ref: 'mzFgq1cvHSEeGscxBsRFoqKG'}}},
{_id: 'doc1', _type: 'bike', name: 'Scooter', image: {_type: 'image', caption: 'Scooter bike', asset: {_ref: 'image-6dcdb82c282dbe0a09ff7a6b58b639732f2fb8de-3360x840-png'}, nested: {_type: 'image', asset: {_ref: 'image-6dcdb82c282dbe0a09ff7a6b58b639732f2fb8de-3360x840-png'}}}},
{_id: 'doc2', _type: 'bike', name: 'Dupe', image: {_type: 'image', asset: {_ref: 'image-6dcdb82c282dbe0a09ff7a6b58b639732f2fb8de-3360x840-png'}}},
{_id: 'doc3', _type: 'bike', name: 'Tandem', image: {_type: 'image', asset: {_ref: 'image-31befc6dfa0315d6c535b8a57e34f86c18eb5f20-310x282-jpg'}}},
{_id: 'datMuxAsset', _type: 'mux.videoAsset', assetId: 'someAssetId'},
{_id: 'refsDatMuxAsset', _type: 'bike', video: {_type: 'mux.video', asset: {_ref: 'datMuxAsset'}}},
{_id: 'mzFgq1cvHSEeGscxBsRFoqKG', _type: 'sanity.imageAsset', url: 'https://cdn.sanity.io/images/__fixtures__/__test__/mzFgq1cvHSEeGscxBsRFoqKG-2048x1364.jpg'},
{_id: 'image-idx_abc123-dads3360x840-png', _type: 'sanity.imageAsset', url: 'https://cdn.sanity.io/images/__fixtures__/__test__/idx_abc123-3360x840.png'},
{_id: 'image-idx_abc456-310x282-jpg', _type: 'sanity.imageAsset', url: 'https://cdn.sanity.io/images/__fixtures__/__test__/idx_abc456-310x282.jpg'},
{_id: 'image-54e9595477915230501dfec656c8e86235bb470a-dads3360x840-png', _type: 'sanity.imageAsset', url: 'https://cdn.sanity.io/images/__fixtures__/__test__/6dcdb82c282dbe0a09ff7a6b58b639732f2fb8de-3360x840.png'},
{_id: 'image-31befc6dfa0315d6c535b8a57e34f86c18eb5f20-310x282-jpg', _type: 'sanity.imageAsset', url: 'https://cdn.sanity.io/images/__fixtures__/__test__/31befc6dfa0315d6c535b8a57e34f86c18eb5f20-310x282.jpg'},
{_id: 'plain', _type: 'bike', name: 'Broom'}
]

Expand All @@ -32,12 +33,14 @@ describe('asset handler', () => {
.pipe(miss.concat(onComplete))

async function onComplete(newDocs) {
expect(newDocs).toHaveLength(5)
expect(newDocs).toHaveLength(6)
expect(docById(newDocs, 'doc1')).toMatchSnapshot('Rewritten asset for doc1')
expect(docById(newDocs, 'doc2')).toMatchSnapshot('Rewritten asset for doc2')
expect(docById(newDocs, 'doc3')).toMatchSnapshot('Rewritten asset for doc3')
expect(docById(newDocs, 'old4')).toMatchSnapshot('Rewritten asset for old4')
expect(docById(newDocs, 'plain')).toMatchSnapshot('Nothing rewritten in assetless doc')
expect(docById(newDocs, 'refsDatMuxAsset')).toMatchSnapshot(
'Nothing rewritten if pattern doesnt match Sanity asset'
)

await assetHandler.finish()
expect(assetHandler.filesWritten).toEqual(3)
Expand All @@ -48,13 +51,12 @@ describe('asset handler', () => {
test('can remove asset documents', done => {
// prettier-ignore
const docs = [
{_id: 'doc1', _type: 'bike', name: 'Scooter', image: {_type: 'image', caption: 'Scooter bike', asset: {_ref: 'image-idx_abc123-3360x840-png'}}},
{_id: 'doc2', _type: 'bike', name: 'Dupe', image: {_type: 'image', asset: {_ref: 'image-idx_abc123-3360x840-png'}}},
{_id: 'doc3', _type: 'bike', name: 'Tandem', image: {_type: 'image', asset: {_ref: 'image-idx_abc456-310x282-jpg'}}},
{_id: 'old4', _type: 'bike', name: 'Cool', image: {asset: {_ref: 'mzFgq1cvHSEeGscxBsRFoqKG'}}},
{_id: 'doc1', _type: 'bike', name: 'Scooter', image: {_type: 'image', caption: 'Scooter bike', asset: {_ref: 'image-6dcdb82c282dbe0a09ff7a6b58b639732f2fb8de-3360x840-png'}}},
{_id: 'doc2', _type: 'bike', name: 'Dupe', image: {_type: 'image', asset: {_ref: 'image-6dcdb82c282dbe0a09ff7a6b58b639732f2fb8de-3360x840-png'}}},
{_id: 'doc3', _type: 'bike', name: 'Tandem', image: {_type: 'image', asset: {_ref: 'image-31befc6dfa0315d6c535b8a57e34f86c18eb5f20-310x282-jpg'}}},
{_id: 'mzFgq1cvHSEeGscxBsRFoqKG', _type: 'sanity.imageAsset', url: 'https://cdn.sanity.io/images/__fixtures__/__test__/mzFgq1cvHSEeGscxBsRFoqKG-2048x1364.jpg'},
{_id: 'image-idx_abc123-3360x840-png', _type: 'sanity.imageAsset', url: 'https://cdn.sanity.io/images/__fixtures__/__test__/idx_abc123-3360x840.png'},
{_id: 'image-idx_abc456-310x282-jpg', _type: 'sanity.imageAsset', url: 'https://cdn.sanity.io/images/__fixtures__/__test__/idx_abc456-310x282.jpg'},
{_id: 'image-6dcdb82c282dbe0a09ff7a6b58b639732f2fb8de-3360x840-png', _type: 'sanity.imageAsset', url: 'https://cdn.sanity.io/images/__fixtures__/__test__/6dcdb82c282dbe0a09ff7a6b58b639732f2fb8de-3360x840.png'},
{_id: 'image-31befc6dfa0315d6c535b8a57e34f86c18eb5f20-310x282-jpg', _type: 'sanity.imageAsset', url: 'https://cdn.sanity.io/images/__fixtures__/__test__/31befc6dfa0315d6c535b8a57e34f86c18eb5f20-310x282.jpg'},
{_id: 'plain', _type: 'bike', name: 'Broom'}
]

Expand All @@ -65,11 +67,10 @@ describe('asset handler', () => {
.pipe(miss.concat(onComplete))

async function onComplete(newDocs) {
expect(newDocs).toHaveLength(5)
expect(newDocs).toHaveLength(4)
expect(docById(newDocs, 'doc1')).toMatchSnapshot('doc1 with no image asset')
expect(docById(newDocs, 'doc2')).toMatchSnapshot('doc2 with no image asset')
expect(docById(newDocs, 'doc3')).toMatchSnapshot('doc3 with no image asset')
expect(docById(newDocs, 'old4')).toMatchSnapshot('old4 with no image asset')
expect(docById(newDocs, 'plain')).toMatchSnapshot('Nothing removed in assetless doc')

await assetHandler.finish()
Expand All @@ -81,7 +82,7 @@ describe('asset handler', () => {
test('downloads assets that are not referenced by documents', done => {
// prettier-ignore
const docs = [
{_id: 'image-idx_abc123-3360x840-png', _type: 'sanity.imageAsset', url: 'https://cdn.sanity.io/images/__fixtures__/__test__/idx_abc123-3360x840.png'},
{_id: 'image-6dcdb82c282dbe0a09ff7a6b58b639732f2fb8de-3360x840-png', _type: 'sanity.imageAsset', url: 'https://cdn.sanity.io/images/__fixtures__/__test__/6dcdb82c282dbe0a09ff7a6b58b639732f2fb8de-3360x840.png'},
{_id: 'mzFgq1cvHSEeGscxBsRFoqKG', _type: 'sanity.imageAsset', url: 'https://cdn.sanity.io/images/__fixtures__/__test__/mzFgq1cvHSEeGscxBsRFoqKG-2048x1364.jpg'},
{_id: 'plain', _type: 'bike', name: 'Broom'}
]
Expand All @@ -105,12 +106,12 @@ describe('asset handler', () => {
test('can skip asset documents', done => {
// prettier-ignore
const docs = [
{_id: 'doc1', _type: 'bike', name: 'Scooter', image: {_type: 'image', caption: 'Scooter bike', asset: {_ref: 'image-idx_abc123-3360x840-png'}}},
{_id: 'doc2', _type: 'bike', name: 'Dupe', image: {_type: 'image', asset: {_ref: 'image-idx_abc123-3360x840-png'}}},
{_id: 'doc3', _type: 'bike', name: 'Tandem', image: {_type: 'image', asset: {_ref: 'image-idx_abc456-310x282-jpg'}}},
{_id: 'doc1', _type: 'bike', name: 'Scooter', image: {_type: 'image', caption: 'Scooter bike', asset: {_ref: 'image-6dcdb82c282dbe0a09ff7a6b58b639732f2fb8de-3360x840-png'}}},
{_id: 'doc2', _type: 'bike', name: 'Dupe', image: {_type: 'image', asset: {_ref: 'image-6dcdb82c282dbe0a09ff7a6b58b639732f2fb8de-3360x840-png'}}},
{_id: 'doc3', _type: 'bike', name: 'Tandem', image: {_type: 'image', asset: {_ref: 'image-31befc6dfa0315d6c535b8a57e34f86c18eb5f20-310x282-jpg'}}},
{_id: 'mzFgq1cvHSEeGscxBsRFoqKG', _type: 'sanity.imageAsset', url: 'https://cdn.sanity.io/images/__fixtures__/__test__/mzFgq1cvHSEeGscxBsRFoqKG-2048x1364.jpg'},
{_id: 'image-idx_abc123-3360x840-png', _type: 'sanity.imageAsset', url: 'https://cdn.sanity.io/images/__fixtures__/__test__/idx_abc123-3360x840.png'},
{_id: 'image-idx_abc456-310x282-jpg', _type: 'sanity.imageAsset', url: 'https://cdn.sanity.io/images/__fixtures__/__test__/idx_abc456-310x282.jpg'},
{_id: 'image-6dcdb82c282dbe0a09ff7a6b58b639732f2fb8de-3360x840-png', _type: 'sanity.imageAsset', url: 'https://cdn.sanity.io/images/__fixtures__/__test__/6dcdb82c282dbe0a09ff7a6b58b639732f2fb8de-3360x840.png'},
{_id: 'image-31befc6dfa0315d6c535b8a57e34f86c18eb5f20-310x282-jpg', _type: 'sanity.imageAsset', url: 'https://cdn.sanity.io/images/__fixtures__/__test__/31befc6dfa0315d6c535b8a57e34f86c18eb5f20-310x282.jpg'},
{_id: 'plain', _type: 'bike', name: 'Broom'}
]

Expand Down
Expand Up @@ -32,11 +32,16 @@ Object {
}
`;

exports[`asset handler can remove asset documents: old4 with no image asset 1`] = `
exports[`asset handler can rewrite documents / queue downloads: Nothing rewritten if pattern doesnt match Sanity asset 1`] = `
Object {
"_id": "old4",
"_id": "refsDatMuxAsset",
"_type": "bike",
"name": "Cool",
"video": Object {
"_type": "mux.video",
"asset": Object {
"_ref": "datMuxAsset",
},
},
}
`;

Expand All @@ -53,11 +58,11 @@ Object {
"_id": "doc1",
"_type": "bike",
"image": Object {
"_sanityAsset": "image@file://./images/idx_abc123-3360x840.png",
"_sanityAsset": "image@file://./images/6dcdb82c282dbe0a09ff7a6b58b639732f2fb8de-3360x840.png",
"_type": "image",
"caption": "Scooter bike",
"nested": Object {
"_sanityAsset": "image@file://./images/idx_abc123-3360x840.png",
"_sanityAsset": "image@file://./images/6dcdb82c282dbe0a09ff7a6b58b639732f2fb8de-3360x840.png",
"_type": "image",
},
},
Expand All @@ -70,7 +75,7 @@ Object {
"_id": "doc2",
"_type": "bike",
"image": Object {
"_sanityAsset": "image@file://./images/idx_abc123-3360x840.png",
"_sanityAsset": "image@file://./images/6dcdb82c282dbe0a09ff7a6b58b639732f2fb8de-3360x840.png",
"_type": "image",
},
"name": "Dupe",
Expand All @@ -82,20 +87,9 @@ Object {
"_id": "doc3",
"_type": "bike",
"image": Object {
"_sanityAsset": "image@file://./images/idx_abc456-310x282.jpg",
"_sanityAsset": "image@file://./images/31befc6dfa0315d6c535b8a57e34f86c18eb5f20-310x282.jpg",
"_type": "image",
},
"name": "Tandem",
}
`;

exports[`asset handler can rewrite documents / queue downloads: Rewritten asset for old4 1`] = `
Object {
"_id": "old4",
"_type": "bike",
"image": Object {
"_sanityAsset": "image@file://./images/mzFgq1cvHSEeGscxBsRFoqKG.bin",
},
"name": "Cool",
}
`;

0 comments on commit a058f82

Please sign in to comment.