11const contentful = require ( `contentful` )
22const crypto = require ( `crypto` )
3+ const stringify = require ( "json-stringify-safe" )
4+
5+ const digest = str => crypto . createHash ( `md5` ) . update ( str ) . digest ( `hex` )
36
47const typePrefix = `contentful__`
58const conflictFieldPrefix = `contentful`
@@ -58,6 +61,19 @@ exports.sourceNodes = async (
5861 console . log ( `assets fetched` , assets . items . length )
5962 console . timeEnd ( `fetch Contentful data` )
6063
64+ // Create map of not resolvable ids so we can filter them out while creating
65+ // links.
66+ const notResolvable = new Map ( )
67+ entryList . forEach ( ents => {
68+ if ( ents . errors ) {
69+ ents . errors . forEach ( error => {
70+ if ( error . sys . id === `notResolvable` ) {
71+ notResolvable . set ( error . details . id , error . details )
72+ }
73+ } )
74+ }
75+ } )
76+
6177 const contentTypeItems = contentTypes . items
6278
6379 // Build foreign reference map before starting to insert any nodes
@@ -75,6 +91,11 @@ exports.sourceNodes = async (
7591 entryItemFieldValue [ 0 ] . sys . id
7692 ) {
7793 entryItemFieldValue . forEach ( v => {
94+ // Don't create link to an unresolvable field.
95+ if ( notResolvable . has ( v . sys . id ) ) {
96+ return
97+ }
98+
7899 if ( ! foreignReferenceMap [ v . sys . id ] ) {
79100 foreignReferenceMap [ v . sys . id ] = [ ]
80101 }
@@ -87,7 +108,8 @@ exports.sourceNodes = async (
87108 } else if (
88109 entryItemFieldValue . sys &&
89110 entryItemFieldValue . sys . type &&
90- entryItemFieldValue . sys . id
111+ entryItemFieldValue . sys . id &&
112+ ! notResolvable . has ( entryItemFieldValue . sys . id )
91113 ) {
92114 if ( ! foreignReferenceMap [ entryItemFieldValue . sys . id ] ) {
93115 foreignReferenceMap [ entryItemFieldValue . sys . id ] = [ ]
@@ -101,6 +123,26 @@ exports.sourceNodes = async (
101123 } )
102124 } )
103125
126+ function createTextNode ( node , text , createNode ) {
127+ const textNode = {
128+ id : `${ node . id } TextNode` ,
129+ parent : node . id ,
130+ children : [ ] ,
131+ text,
132+ internal : {
133+ type : `ComponentDescription` ,
134+ mediaType : `text/x-markdown` ,
135+ content : text ,
136+ contentDigest : digest ( text ) ,
137+ } ,
138+ }
139+
140+ node . children = node . children . concat ( [ textNode . id ] )
141+ createNode ( textNode )
142+
143+ return textNode . id
144+ }
145+
104146 contentTypeItems . forEach ( ( contentTypeItem , i ) => {
105147 const contentTypeItemId = contentTypeItem . sys . id
106148
@@ -138,13 +180,17 @@ exports.sourceNodes = async (
138180 ) {
139181 entryItemFields [
140182 `${ entryItemFieldKey } ___NODE`
141- ] = entryItemFieldValue . map ( v => v . sys . id )
183+ ] = entryItemFieldValue
184+ . filter ( v => ! notResolvable . has ( v . sys . id ) )
185+ . map ( v => v . sys . id )
186+
142187 delete entryItemFields [ entryItemFieldKey ]
143188 }
144189 } else if (
145190 entryItemFieldValue . sys &&
146191 entryItemFieldValue . sys . type &&
147- entryItemFieldValue . sys . id
192+ entryItemFieldValue . sys . id &&
193+ ! notResolvable . has ( entryItemFieldValue . sys . id )
148194 ) {
149195 entryItemFields [ `${ entryItemFieldKey } ___NODE` ] =
150196 entryItemFieldValue . sys . id
@@ -167,30 +213,42 @@ exports.sourceNodes = async (
167213 } )
168214 }
169215
170- const entryNode = {
216+ let entryNode = {
171217 id : entryItem . sys . id ,
172218 parent : contentTypeItemId ,
173219 children : [ ] ,
174- ...entryItemFields ,
175220 internal : {
176221 type : `${ makeTypeName ( contentTypeItemId ) } ` ,
177- content : JSON . stringify ( entryItem ) ,
178222 mediaType : `application/json` ,
179223 } ,
180224 }
181225
226+ // Replace text fields with text nodes so we can process their markdown
227+ // into HTML.
228+ Object . keys ( entryItemFields ) . forEach ( entryItemFieldKey => {
229+ if ( entryItemFieldKey === `text` ) {
230+ entryItemFields [ `${ entryItemFieldKey } ___NODE` ] = createTextNode (
231+ entryNode ,
232+ entryItemFields [ entryItemFieldKey ] ,
233+ createNode
234+ )
235+
236+ delete entryItemFields [ entryItemFieldKey ]
237+ }
238+ } )
239+
240+ entryNode = { ...entryItemFields , ...entryNode }
241+
182242 // Get content digest of node.
183- const contentDigest = crypto
184- . createHash ( `md5` )
185- . update ( JSON . stringify ( entryNode ) )
186- . digest ( `hex` )
243+ const contentDigest = digest ( stringify ( entryNode ) )
187244
188245 entryNode . internal . contentDigest = contentDigest
189246
190247 return entryNode
191248 } )
249+
192250 // Create a node for each content type
193- const contentTypeItemStr = JSON . stringify ( contentTypeItem )
251+ const contentTypeItemStr = stringify ( contentTypeItem )
194252
195253 const contentTypeNode = {
196254 id : contentTypeItemId ,
@@ -201,16 +259,12 @@ exports.sourceNodes = async (
201259 description : contentTypeItem . description ,
202260 internal : {
203261 type : `${ makeTypeName ( `ContentType` ) } ` ,
204- content : contentTypeItemStr ,
205- mediaType : `application/json` ,
262+ mediaType : `text/x-contentful` ,
206263 } ,
207264 }
208265
209266 // Get content digest of node.
210- const contentDigest = crypto
211- . createHash ( `md5` )
212- . update ( JSON . stringify ( contentTypeNode ) )
213- . digest ( `hex` )
267+ const contentDigest = digest ( stringify ( contentTypeNode ) )
214268
215269 contentTypeNode . internal . contentDigest = contentDigest
216270
@@ -222,7 +276,7 @@ exports.sourceNodes = async (
222276
223277 assets . items . forEach ( assetItem => {
224278 // Create a node for each asset. They may be referenced by Entries
225- const assetItemStr = JSON . stringify ( assetItem )
279+ const assetItemStr = stringify ( assetItem )
226280
227281 const assetNode = {
228282 id : assetItem . sys . id ,
@@ -231,16 +285,12 @@ exports.sourceNodes = async (
231285 ...assetItem . fields ,
232286 internal : {
233287 type : `${ makeTypeName ( `Asset` ) } ` ,
234- content : assetItemStr ,
235- mediaType : `application/json` ,
288+ mediaType : `text/x-contentful` ,
236289 } ,
237290 }
238291
239292 // Get content digest of node.
240- const contentDigest = crypto
241- . createHash ( `md5` )
242- . update ( JSON . stringify ( assetNode ) )
243- . digest ( `hex` )
293+ const contentDigest = digest ( stringify ( assetNode ) )
244294
245295 assetNode . internal . contentDigest = contentDigest
246296
0 commit comments