@@ -126,30 +126,94 @@ class Resources {
126126        return  models . Base . Model . raw_knex . fetchAll ( modelOptions ) ; 
127127    } 
128128
129+     _prepareModelSync ( model ,  resourceConfig )  { 
130+         const  exclude  =  resourceConfig . modelOptions . exclude ; 
131+         const  withRelatedFields  =  resourceConfig . modelOptions . withRelatedFields ; 
132+         const  obj  =  _ . omit ( model . toJSON ( ) ,  exclude ) ; 
133+ 
134+         if  ( withRelatedFields )  { 
135+             _ . each ( withRelatedFields ,  ( fields ,  key )  =>  { 
136+                 if  ( ! obj [ key ] )  { 
137+                     return ; 
138+                 } 
139+ 
140+                 obj [ key ]  =  _ . map ( obj [ key ] ,  ( relation )  =>  { 
141+                     const  relationToReturn  =  { } ; 
142+ 
143+                     _ . each ( fields ,  ( field )  =>  { 
144+                         const  fieldSanitized  =  field . replace ( / ^ \w + ./ ,  '' ) ; 
145+                         relationToReturn [ fieldSanitized ]  =  relation [ fieldSanitized ] ; 
146+                     } ) ; 
147+ 
148+                     return  relationToReturn ; 
149+                 } ) ; 
150+             } ) ; 
151+ 
152+             const  withRelatedPrimary  =  resourceConfig . modelOptions . withRelatedPrimary ; 
153+ 
154+             if  ( withRelatedPrimary )  { 
155+                 _ . each ( withRelatedPrimary ,  ( relation ,  primaryKey )  =>  { 
156+                     if  ( ! obj [ primaryKey ]  ||  ! obj [ relation ] )  { 
157+                         return ; 
158+                     } 
159+ 
160+                     const  targetTagKeys  =  Object . keys ( obj [ relation ] . find ( ( item )  =>  { 
161+                         return  item . id  ===  obj [ primaryKey ] . id ; 
162+                     } ) ) ; 
163+                     obj [ primaryKey ]  =  _ . pick ( obj [ primaryKey ] ,  targetTagKeys ) ; 
164+                 } ) ; 
165+             } 
166+         } 
167+ 
168+         return  obj ; 
169+     } 
170+ 
129171    _onResourceAdded ( type ,  model )  { 
172+         debug ( '_onResourceAdded' ,  type ) ; 
173+ 
130174        const  resourceConfig  =  _ . find ( this . resourcesConfig ,  { type : type } ) ; 
131175
132-         return  Promise . resolve ( ) 
133-             . then ( ( )  =>  { 
134-                 return  this . _fetchSingle ( resourceConfig ,  model . id ) ; 
135-             } ) 
136-             . then ( ( [ dbResource ] )  =>  { 
137-                 if  ( dbResource )  { 
138-                     const  resource  =  new  Resource ( type ,  dbResource ) ; 
139- 
140-                     debug ( '_onResourceAdded' ,  type ) ; 
141-                     this . data [ type ] . push ( resource ) ; 
142- 
143-                     this . queue . start ( { 
144-                         event : 'added' , 
145-                         action : 'added:'  +  model . id , 
146-                         eventData : { 
147-                             id : model . id , 
148-                             type : type 
149-                         } 
150-                     } ) ; 
176+         // NOTE: synchronous handling for post and pages so that their URL is available without a delay 
177+         //       for more context and future improvements check https://github.com/TryGhost/Ghost/issues/10360 
178+         if  ( [ 'posts' ,  'pages' ] . includes ( type ) )  { 
179+             const  obj  =  this . _prepareModelSync ( model ,  resourceConfig ) ; 
180+ 
181+             const  resource  =  new  Resource ( type ,  obj ) ; 
182+ 
183+             debug ( '_onResourceAdded' ,  type ) ; 
184+             this . data [ type ] . push ( resource ) ; 
185+ 
186+             this . queue . start ( { 
187+                 event : 'added' , 
188+                 action : 'added:'  +  model . id , 
189+                 eventData : { 
190+                     id : model . id , 
191+                     type : type 
151192                } 
152193            } ) ; 
194+         }  else  { 
195+             return  Promise . resolve ( ) 
196+                 . then ( ( )  =>  { 
197+                     return  this . _fetchSingle ( resourceConfig ,  model . id ) ; 
198+                 } ) 
199+                 . then ( ( [ dbResource ] )  =>  { 
200+                     if  ( dbResource )  { 
201+                         const  resource  =  new  Resource ( type ,  dbResource ) ; 
202+ 
203+                         debug ( '_onResourceAdded' ,  type ) ; 
204+                         this . data [ type ] . push ( resource ) ; 
205+ 
206+                         this . queue . start ( { 
207+                             event : 'added' , 
208+                             action : 'added:'  +  model . id , 
209+                             eventData : { 
210+                                 id : model . id , 
211+                                 type : type 
212+                             } 
213+                         } ) ; 
214+                     } 
215+                 } ) ; 
216+         } 
153217    } 
154218
155219    /** 
@@ -171,36 +235,67 @@ class Resources {
171235
172236        const  resourceConfig  =  _ . find ( this . resourcesConfig ,  { type : type } ) ; 
173237
174-         return   Promise . resolve ( ) 
175-             . then ( ( )   =>   { 
176-                  return   this . _fetchSingle ( resourceConfig ,   model . id ) ; 
177-             } ) 
178-             . then ( ( [ dbResource ] )   =>  { 
179-                 const   resource   =   this . data [ type ] . find ( resource   =>   ( resource . data . id   ===   model . id ) ) ; 
238+         // NOTE: synchronous handling for post and pages so that their URL is available without a delay 
239+         //        for more context and future improvements check https://github.com/TryGhost/Ghost/issues/10360 
240+         if   ( [ 'posts' ,   'pages' ] . includes ( type ) )   { 
241+             this . data [ type ] . every ( ( resource )   =>   { 
242+                  if   ( resource . data . id   ===   model . id )  { 
243+                      const   obj   =   this . _prepareModelSync ( model ,   resourceConfig ) ; 
180244
181-                 if  ( resource  &&  dbResource )  { 
182-                     resource . update ( dbResource ) ; 
245+                     resource . update ( obj ) ; 
183246
184247                    // CASE: pretend it was added 
185248                    if  ( ! resource . isReserved ( ) )  { 
186249                        this . queue . start ( { 
187250                            event : 'added' , 
188-                             action : 'added:'  +  dbResource . id , 
251+                             action : 'added:'  +  model . id , 
189252                            eventData : { 
190-                                 id : dbResource . id , 
253+                                 id : model . id , 
191254                                type : type 
192255                            } 
193256                        } ) ; 
194257                    } 
195-                 }  else  if  ( ! resource  &&  dbResource )  { 
196-                     this . _onResourceAdded ( type ,  model ) ; 
197-                 }  else  if  ( resource  &&  ! dbResource )  { 
198-                     this . _onResourceRemoved ( type ,  model ) ; 
258+ 
259+                     // break! 
260+                     return  false ; 
199261                } 
262+ 
263+                 return  true ; 
200264            } ) ; 
265+         }  else  { 
266+             return  Promise . resolve ( ) 
267+                 . then ( ( )  =>  { 
268+                     return  this . _fetchSingle ( resourceConfig ,  model . id ) ; 
269+                 } ) 
270+                 . then ( ( [ dbResource ] )  =>  { 
271+                     const  resource  =  this . data [ type ] . find ( resource  =>  ( resource . data . id  ===  model . id ) ) ; 
272+ 
273+                     if  ( resource  &&  dbResource )  { 
274+                         resource . update ( dbResource ) ; 
275+ 
276+                         // CASE: pretend it was added 
277+                         if  ( ! resource . isReserved ( ) )  { 
278+                             this . queue . start ( { 
279+                                 event : 'added' , 
280+                                 action : 'added:'  +  dbResource . id , 
281+                                 eventData : { 
282+                                     id : dbResource . id , 
283+                                     type : type 
284+                                 } 
285+                             } ) ; 
286+                         } 
287+                     }  else  if  ( ! resource  &&  dbResource )  { 
288+                         this . _onResourceAdded ( type ,  model ) ; 
289+                     }  else  if  ( resource  &&  ! dbResource )  { 
290+                         this . _onResourceRemoved ( type ,  model ) ; 
291+                     } 
292+                 } ) ; 
293+         } 
201294    } 
202295
203296    _onResourceRemoved ( type ,  model )  { 
297+         debug ( '_onResourceRemoved' ,  type ) ; 
298+ 
204299        let  index  =  null ; 
205300        let  resource ; 
206301
0 commit comments