generated from sanity-io/sanity-template-nextjs-clean
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontent-migrate.ts
More file actions
142 lines (126 loc) · 4.04 KB
/
content-migrate.ts
File metadata and controls
142 lines (126 loc) · 4.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import { htmlToBlocks } from '@sanity/block-tools'
import { Schema } from '@sanity/schema'
import axios from 'axios'
// import dotenv
import dotenv from 'dotenv'
import fs from 'fs'
import { JSDOM } from 'jsdom'
import { marked } from 'marked'
import path from 'path'
dotenv.config({
path: '.env.local',
})
import schema from './sanity.config'
const sanitySchema = Schema.compile(schema.schema)
const blockContentType = sanitySchema
.get('post')
.fields.find((field) => field.name === 'body').type
const CONTENTFUL_ACCESS_TOKEN = '_jjIusyTNDJpTSjYGtwXaWgy8PUmtEc5UOhquiZ-wXU'
/**
* Goal is to migrate content from Contentful to Sanity.
* We'll do this by fetching content from Contentful and then storing as NDJSON file in a format that Sanity can import.
*/
// https://cdn.contentful.com/spaces/{space_id}/environments/{environment_id}/entries?access_token=
const contentful = axios.create({
baseURL: 'https://cdn.contentful.com/spaces/hoagspxz8z3s/environments/master',
headers: {
Authorization: `Bearer ${CONTENTFUL_ACCESS_TOKEN}`,
},
})
const fetchContent = async () => {
const { data } = await contentful.get('/entries')
return data
}
// markdown to portable text
const convertMarkdownToPortableText = (markdown: string) => {
const html = marked.parse(markdown)
const blocks = htmlToBlocks(html, blockContentType, {
parseHtml: (html) => new JSDOM(html).window.document,
rules: [
// Special rule for code blocks
{
deserialize(element, next, block) {
const el = element as HTMLElement
// if it's an anchor we might need to rewrite local paths.
if (el.tagName?.toLowerCase() === 'a') {
const href = el.getAttribute('href')
if (
href &&
!href.startsWith('http') &&
!href.startsWith('/post') &&
!href.startsWith('#')
) {
// if href starts with / replace it with nothing.
const text = (
href.startsWith('/') ? href.substring(1) : href
).replace('/', '-')
el.setAttribute('href', `/post/${text}`)
return next(el)
}
}
if (el.tagName?.toLowerCase() != 'pre') {
return undefined
}
const code = el.children[0]
if (!code) {
return undefined
}
const language = code.getAttribute('class')?.replace('language-', '')
console.log(language)
const text = code.textContent
// Return this as an own block (via block helper function), instead of appending it to a default block's children
return block({
_type: 'code',
language: language,
code: text,
})
},
},
],
})
return blocks
}
const main = async () => {
const content = await fetchContent()
const redirects: {
source: string
destination: string
permanent: boolean
}[] = []
const items = content.items
.filter((item) => {
return item.sys.contentType.sys.id === 'blogPost'
})
.map((item) => {
if (item.fields.content) {
const portableText = convertMarkdownToPortableText(item.fields.content)
redirects.push({
source: `/${item.fields.permalink}`,
destination: `/post/${item.fields.permalink.replaceAll('/', '-')}`,
permanent: true,
})
return {
_type: 'post',
_id: item.sys.id,
_createdAt: item.sys.createdAt,
_updatedAt: item.sys.updatedAt,
title: item.fields.title,
slug: {
_type: 'slug',
current: item.fields.permalink.replaceAll('/', '-'),
},
body: portableText,
}
}
console.log(`No content for ${item.sys.id} - ${item.fields.title}`)
})
fs.writeFileSync(
path.join(__dirname, 'content.ndjson'),
items.map((item) => JSON.stringify(item)).join('\n'),
)
fs.writeFileSync(
path.join(__dirname, 'redirects.json'),
JSON.stringify(redirects),
)
}
main()