Last active
July 21, 2023 09:46
-
-
Save juice49/d40223d9a450a9f07215cc91a570441c to your computer and use it in GitHub Desktop.
Upload Sanity images with tags
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
import { type SanityDocument, type Reference } from 'sanity' | |
import { type UploadBody, type SanityImageAssetDocument } from '@sanity/client' | |
import { getCliClient } from 'sanity/cli' | |
const client = getCliClient() | |
interface Tag extends SanityDocument { | |
_type: 'media.tag' | |
name: { | |
_type: 'slug' | |
current: string | |
} | |
} | |
interface Options { | |
source: UploadBody | |
filename: string | |
tagNames?: string[] | |
} | |
async function uploadImage({ | |
source, | |
filename, | |
tagNames = [], | |
}: Options): Promise<SanityImageAssetDocument> { | |
const [tagIds, asset] = await Promise.all([ | |
getTagIdsByName(tagNames), | |
client.assets.upload('image', source, { | |
filename, | |
}), | |
]) | |
return client | |
.patch(asset._id) | |
.set({ | |
'opt.media.tags': getTagReferences(tagIds), | |
}) | |
.commit() | |
} | |
async function getTagIdsByName(names: string[]): Promise<string[]> { | |
const existingTags = await client.fetch<Tag[]>( | |
'*[_type == "media.tag" && name.current in $names]', | |
{ | |
names, | |
}, | |
) | |
const newTagIds = await createNonExistentTags(names, existingTags) | |
return existingTags.reduce((tagIds, { _id }) => { | |
return [...tagIds, _id] | |
}, newTagIds) | |
} | |
async function createNonExistentTags( | |
names: string[], | |
existingTags: Tag[], | |
): Promise<string[]> { | |
const existingTagNames = existingTags.map(({ name }) => name.current) | |
const nonExistentNames = names.filter( | |
name => !existingTagNames.includes(name), | |
) | |
const operations = nonExistentNames.reduce((transaction, nonExistentName) => { | |
return transaction.create({ | |
_type: 'media.tag', | |
name: { | |
current: nonExistentName, | |
}, | |
}) | |
}, client.transaction()) | |
const response = await operations.commit() | |
return response.documentIds | |
} | |
function getTagReferences(tagIds: string[]): Reference[] { | |
return tagIds.map(tagId => ({ | |
_type: 'reference', | |
_ref: tagId, | |
_weak: true, | |
})) | |
} |
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
import { createReadStream } from 'node:fs' | |
import path from 'node:path' | |
;(async () => { | |
await uploadImage({ | |
source: createReadStream(path.join(__dirname, 'capybara-squad.jpg')), | |
filename: 'capybara-squad.jpg', | |
// If the tags don't yet exist, they'll be created. The tag references will then be | |
// set on the uploaded image asset document. | |
tagNames: ['capybara', 'friendship'], | |
}) | |
})() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment