Created
February 14, 2022 16:33
-
-
Save squamuglia/771be284c7f6ce6c5bb92a1f01489979 to your computer and use it in GitHub Desktop.
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 fetch from "node-fetch" | |
import sanityClient from "@sanity/client" | |
import * as fs from "fs" | |
import { fetchAPI } from "./fetchApi" | |
import gql from "graphql-tag" | |
const API_URL = "[add yours here]" | |
export async function fetchAPI(query, { variables = null } = {}) { | |
const QUERY = typeof query === "string" ? query : query?.loc.source.body | |
try { | |
const res = await fetch(API_URL, { | |
method: "POST", | |
headers: { "Content-Type": "application/json" }, | |
body: JSON.stringify({ | |
query: QUERY, | |
variables, | |
}), | |
}) | |
const json = await res.json() | |
if (json.errors) { | |
console.error(json.errors) | |
throw new Error("Failed to fetch API") | |
} | |
return json.data | |
} catch (err) { | |
console.error(err) | |
} | |
} | |
/** | |
* To run these scripts, use sanity exec bin/migrate.ts --with-user-token | |
*/ | |
const client = sanityClient({ | |
projectId: "[Add yours here]", | |
dataset: "production", | |
apiVersion: "2021-06-07", | |
useCdn: false, | |
token: | |
"[Add yours here]" | |
}) | |
const migratePosts = async () => { | |
const query = gql` | |
query { | |
posts(first: 1000) { | |
edges { | |
node { | |
postId | |
title | |
title_spanish | |
excerpt | |
slug | |
date | |
featuredImage { | |
node { | |
mediaItemUrl | |
altText | |
} | |
} | |
categories { | |
edges { | |
node { | |
name | |
} | |
} | |
} | |
tags { | |
edges { | |
node { | |
name | |
} | |
} | |
} | |
content | |
content_spanish | |
} | |
} | |
} | |
} | |
` | |
const data = await fetchAPI(query) | |
const edges = data.posts.edges | |
for (const edge of edges) { | |
try { | |
const { node } = edge | |
const filename = node?.featuredImage?.node.mediaItemUrl.split("/").pop() | |
let imageDocument | |
if (filename) { | |
const file = `bin/fne-site-uploads/${filename}` | |
// @ts-ignore | |
imageDocument = await client.assets.upload( | |
"image", | |
fs.createReadStream(file), | |
{ filename } | |
) | |
} | |
const doc = { | |
_id: node.slug, | |
_type: "post", | |
mainImage: imageDocument | |
? { | |
_type: "image", | |
asset: { | |
_ref: imageDocument._id, | |
_type: "reference", | |
}, | |
} | |
: undefined, | |
slug: { | |
_type: "slug", | |
current: node.slug, | |
}, | |
publishedAt: node.date, | |
title: { | |
_type: "localizedString", | |
en: node.title, | |
es: node.title_spanish ?? node.title, | |
}, | |
legacyContent: { | |
_type: "localizedString", | |
en: node.content, | |
es: node.content_spanish ?? node.content, | |
}, | |
} | |
await client.createOrReplace(doc) | |
// Sanity has a limit of 25 reqs/s | |
await new Promise((res) => setTimeout(() => res(null), 1000 / 25)) | |
console.log(`created post: ${doc._id}`) | |
} catch (e) { | |
console.error("Error creating doc: ", e) | |
} | |
} | |
console.log("Upload complete") | |
} | |
const migratePages = async () => { | |
const query = gql` | |
query { | |
pages(first: 1000) { | |
edges { | |
node { | |
pageId | |
title | |
slug | |
date | |
featuredImage { | |
node { | |
mediaItemUrl | |
altText | |
} | |
} | |
content | |
} | |
} | |
} | |
} | |
` | |
const data = await fetchAPI(query) | |
const edges = data.pages.edges | |
for (const edge of edges) { | |
try { | |
const { node } = edge | |
const filename = node?.featuredImage?.node.mediaItemUrl.split("/").pop() | |
let imageDocument | |
if (filename) { | |
const file = `bin/fne-site-uploads/${filename}` | |
// @ts-ignore | |
imageDocument = await client.assets.upload( | |
"image", | |
fs.createReadStream(file), | |
{ filename } | |
) | |
} | |
const doc = { | |
_id: node.slug, | |
_type: "page", | |
_createdAt: node.date, | |
mainImage: imageDocument | |
? { | |
_type: "image", | |
asset: { | |
_ref: imageDocument._id, | |
_type: "reference", | |
}, | |
} | |
: undefined, | |
slug: { | |
_type: "slug", | |
current: node.slug, | |
}, | |
publishedAt: node.date, | |
title: { | |
_type: "localizedString", | |
en: node.title, | |
es: node.title, | |
}, | |
legacyContent: { | |
_type: "localizedString", | |
en: node.content, | |
es: node.content, | |
}, | |
} | |
await client.createOrReplace(doc) | |
// Sanity has a limit of 25 reqs/s | |
await new Promise((res) => setTimeout(() => res(null), 1000 / 25)) | |
console.log(`created page: ${doc._id}`) | |
} catch (e) { | |
console.error("Error creating doc: ", e) | |
} | |
} | |
console.log("Upload complete") | |
} | |
const migrateMembers = async () => { | |
const query = gql` | |
query { | |
members(first: 100) { | |
nodes { | |
slug | |
memberDetails { | |
order | |
name | |
position | |
project | |
team | |
image { | |
mediaItemUrl | |
altText | |
title | |
} | |
} | |
} | |
} | |
} | |
` | |
const data = await fetchAPI(query) | |
const nodes = data.members.nodes | |
for (const node of nodes) { | |
try { | |
const { memberDetails } = node | |
const filename = memberDetails?.image?.mediaItemUrl.split("/").pop() | |
let image | |
if (filename) { | |
const file = `bin/fne-site-uploads/${filename}` | |
// @ts-ignore | |
const imageDocument = await client.assets.upload( | |
"image", | |
fs.createReadStream(file), | |
{ filename } | |
) | |
image = imageDocument | |
? { | |
mainImage: { | |
_type: "image", | |
asset: { | |
_ref: imageDocument._id, | |
_type: "reference", | |
}, | |
}, | |
} | |
: {} | |
} | |
const doc = { | |
_id: node.slug, | |
_type: "member", | |
email: memberDetails.email, | |
name: memberDetails.name, | |
position: memberDetails.position, | |
team: memberDetails.team, | |
...image, | |
} | |
await client.createOrReplace(doc) | |
// Sanity has a limit of 25 reqs/s | |
await new Promise((res) => setTimeout(() => res(null), 1000 / 25)) | |
console.log(`created doc: ${doc._id}`) | |
} catch (e) { | |
console.error("Error creating doc: ", e) | |
} | |
} | |
console.log("Upload complete") | |
} | |
const patchProjectDates = async () => { | |
const query = gql` | |
query { | |
posts(first: 1000, where: { categoryName: "projects" }) { | |
edges { | |
node { | |
slug | |
date | |
} | |
} | |
} | |
} | |
` | |
const data = await fetchAPI(query) | |
const edges = data.posts.edges | |
for (const edge of edges) { | |
try { | |
const { node } = edge | |
const date = new Date(node.date).toISOString() | |
await client | |
.patch(`project_${node.slug}`) // Document ID to patch | |
.set({ _createdAt: date, publishedAt: date }) // Shallow merge | |
.commit() // Perform the patch and return a promise | |
console.log(`created posts: ${node.slug}`) | |
} catch (e) { | |
console.error("Error creating patch: ", e) | |
} | |
} | |
console.log("Upload complete") | |
} | |
const migrateProjects = async () => { | |
const query = gql` | |
query { | |
posts(first: 1000, where: { categoryName: "projects" }) { | |
edges { | |
node { | |
title | |
title_spanish | |
slug | |
date | |
content | |
content_spanish | |
featuredImage { | |
node { | |
mediaItemUrl | |
altText | |
} | |
} | |
location { | |
location { | |
latitude | |
longitude | |
} | |
} | |
} | |
} | |
} | |
} | |
` | |
const data = await fetchAPI(query) | |
const edges = data.posts.edges | |
for (const edge of edges) { | |
try { | |
const { node } = edge | |
const filename = node?.featuredImage?.node.mediaItemUrl.split("/").pop() | |
const date = new Date(node.date).toISOString() | |
let imageDocument | |
if (filename) { | |
const file = `bin/fne-site-uploads/${filename}` | |
// @ts-ignore | |
imageDocument = await client.assets.upload( | |
"image", | |
fs.createReadStream(file), | |
{ filename } | |
) | |
} | |
const doc = { | |
_id: `project_${node.slug}`, | |
_type: "project", | |
mainImage: imageDocument | |
? { | |
_type: "image", | |
asset: { | |
_ref: imageDocument._id, | |
_type: "reference", | |
}, | |
} | |
: undefined, | |
slug: { | |
_type: "slug", | |
current: `project/${node.slug}`, | |
}, | |
publishedAt: date, | |
location: node.location?.location?.latitude | |
? { | |
_type: "geopoint", | |
lat: node.location.location.latitude, | |
lng: node.location.location.longitude, | |
} | |
: undefined, | |
title: { | |
_type: "localizedString", | |
en: node.title, | |
es: node.title, | |
}, | |
legacyContent: { | |
_type: "localizedString", | |
en: node.content, | |
es: node.content, | |
}, | |
} | |
await client.createOrReplace(doc) | |
console.log(`created project: ${doc._id}`) | |
} catch (e) { | |
console.error("Error creating doc: ", e.message) | |
} | |
} | |
console.log("Upload complete") | |
} | |
const deleteProjectPosts = async () => { | |
const query = gql` | |
query { | |
posts(first: 1000, where: { categoryName: "projects" }) { | |
edges { | |
node { | |
slug | |
} | |
} | |
} | |
} | |
` | |
const data = await fetchAPI(query) | |
const edges = data.posts.edges | |
for (const edge of edges) { | |
try { | |
const { node } = edge | |
await client.delete(node.slug) | |
console.log(`delete project post: ${node.slug}`) | |
} catch (e) { | |
console.error("Error creating doc: ", e.message) | |
} | |
} | |
console.log("Upload complete") | |
} | |
const patchProjectSlugs = async () => { | |
const query = gql` | |
query { | |
posts(first: 1000, where: { categoryName: "projects" }) { | |
edges { | |
node { | |
slug | |
} | |
} | |
} | |
} | |
` | |
const data = await fetchAPI(query) | |
const edges = data.posts.edges | |
for (const edge of edges) { | |
try { | |
const { node } = edge | |
await client | |
.patch(`project_${node.slug}`) // Document ID to patch | |
.set({ slug: { current: node.slug } }) // Shallow merge | |
.commit() // Perform the patch and return a promise | |
console.log(`patched posts: ${node.slug}`) | |
} catch (e) { | |
console.error("Error creating patch: ", e) | |
} | |
} | |
console.log("Upload complete") | |
} | |
const run = (fn: () => Promise<any>) => { | |
console.log(`Starting ${fn.name}`) | |
fn().catch((err) => { | |
console.error(err) | |
process.exit(1) | |
}) | |
} | |
const runAll = (...fns: (() => Promise<any>)[]) => { | |
for (const fn of fns) { | |
console.log(`Starting ${fn.name}`) | |
fn().catch((err) => { | |
console.error(err) | |
process.exit(1) | |
}) | |
} | |
} | |
// run these in the below order | |
runAll(patchProjectSlugs) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment