6
6
pipeToNodeWritable,
7
7
} = require ( `react-dom/server` )
8
8
const { ServerLocation, Router, isRedirect } = require ( `@gatsbyjs/reach-router` )
9
- const { merge, flattenDeep , replace } = require ( `lodash ` )
9
+ const merge = require ( `deepmerge ` )
10
10
const { StaticQueryContext } = require ( `gatsby` )
11
11
const fs = require ( `fs` )
12
+ const { WritableAsPromise } = require ( `./server-utils/writable-as-promise` )
12
13
13
14
const { RouteAnnouncerProps } = require ( `./route-announcer-props` )
14
15
const { apiRunner, apiRunnerAsync } = require ( `./api-runner-ssr` )
@@ -65,29 +66,40 @@ const getAppDataUrl = () =>
65
66
const createElement = React . createElement
66
67
67
68
export const sanitizeComponents = components => {
68
- const componentsArray = ensureArray ( components )
69
+ const componentsArray = [ ] . concat ( components ) . flat ( Infinity ) . filter ( Boolean )
70
+
69
71
return componentsArray . map ( component => {
70
72
// Ensure manifest is always loaded from content server
71
73
// And not asset server when an assetPrefix is used
72
74
if ( __ASSET_PREFIX__ && component . props . rel === `manifest` ) {
73
75
return React . cloneElement ( component , {
74
- href : replace ( component . props . href , __ASSET_PREFIX__ , `` ) ,
76
+ href : component . props . href . replace ( __ASSET_PREFIX__ , `` ) ,
75
77
} )
76
78
}
77
79
return component
78
80
} )
79
81
}
80
82
81
- const ensureArray = components => {
82
- if ( Array . isArray ( components ) ) {
83
- // remove falsy items and flatten
84
- return flattenDeep (
85
- components . filter ( val => ( Array . isArray ( val ) ? val . length > 0 : val ) )
86
- )
87
- } else {
88
- // we also accept single components, so we need to handle this case as well
89
- return components ? [ components ] : [ ]
83
+ function deepMerge ( a , b ) {
84
+ const combineMerge = ( target , source , options ) => {
85
+ const destination = target . slice ( )
86
+
87
+ source . forEach ( ( item , index ) => {
88
+ if ( typeof destination [ index ] === `undefined` ) {
89
+ destination [ index ] = options . cloneUnlessOtherwiseSpecified (
90
+ item ,
91
+ options
92
+ )
93
+ } else if ( options . isMergeableObject ( item ) ) {
94
+ destination [ index ] = merge ( target [ index ] , item , options )
95
+ } else if ( target . indexOf ( item ) === - 1 ) {
96
+ destination . push ( item )
97
+ }
98
+ } )
99
+ return destination
90
100
}
101
+
102
+ return merge ( a , b , { arrayMerge : combineMerge } )
91
103
}
92
104
93
105
export default async function staticPage ( {
@@ -149,11 +161,13 @@ export default async function staticPage({
149
161
}
150
162
151
163
const setHtmlAttributes = attributes => {
152
- htmlAttributes = merge ( htmlAttributes , attributes )
164
+ // TODO - we should remove deep merges
165
+ htmlAttributes = deepMerge ( htmlAttributes , attributes )
153
166
}
154
167
155
168
const setBodyAttributes = attributes => {
156
- bodyAttributes = merge ( bodyAttributes , attributes )
169
+ // TODO - we should remove deep merges
170
+ bodyAttributes = deepMerge ( bodyAttributes , attributes )
157
171
}
158
172
159
173
const setPreBodyComponents = components => {
@@ -169,7 +183,8 @@ export default async function staticPage({
169
183
}
170
184
171
185
const setBodyProps = props => {
172
- bodyProps = merge ( { } , bodyProps , props )
186
+ // TODO - we should remove deep merges
187
+ bodyProps = deepMerge ( { } , bodyProps , props )
173
188
}
174
189
175
190
const getHeadComponents = ( ) => headComponents
@@ -266,9 +281,6 @@ export default async function staticPage({
266
281
try {
267
282
// react 18 enabled
268
283
if ( pipeToNodeWritable ) {
269
- const {
270
- WritableAsPromise,
271
- } = require ( `./server-utils/writable-as-promise` )
272
284
const writableStream = new WritableAsPromise ( )
273
285
const { startWriting } = pipeToNodeWritable (
274
286
bodyComponent ,
0 commit comments