@@ -226,9 +226,15 @@ export class CubeSymbols {
226226 return ;
227227 }
228228
229- const types = [ 'measures' , 'dimensions' , 'segments' ] ;
229+ const memberSets = {
230+ resolvedMembers : new Set ( ) ,
231+ allMembers : new Set ( ) ,
232+ } ;
233+
234+ const types = [ 'measures' , 'dimensions' , 'segments' , 'hierarchies' ] ;
230235 for ( const type of types ) {
231- const cubeIncludes = cube . cubes && this . membersFromCubes ( cube , cube . cubes , type , errorReporter , splitViews ) || [ ] ;
236+ const cubeIncludes = cube . cubes && this . membersFromCubes ( cube , cube . cubes , type , errorReporter , splitViews , memberSets ) || [ ] ;
237+
232238 const includes = cube . includes && this . membersFromIncludeExclude ( cube . includes , cube . name , type ) || [ ] ;
233239 const excludes = cube . excludes && this . membersFromIncludeExclude ( cube . excludes , cube . name , type ) || [ ] ;
234240
@@ -245,18 +251,23 @@ export class CubeSymbols {
245251 const split = it . member . split ( '.' ) ;
246252 const memberPath = this . pathFromArray ( [ split [ split . length - 2 ] , split [ split . length - 1 ] ] ) ;
247253 return {
254+ type,
248255 memberPath,
249256 name : it . name
250257 } ;
251258 } ) ) ) ] ;
252259 }
260+
261+ [ ...memberSets . allMembers ] . filter ( it => ! memberSets . resolvedMembers . has ( it ) ) . forEach ( it => {
262+ errorReporter . error ( `Member '${ it } ' is included in '${ cube . name } ' but not defined in any cube` ) ;
263+ } ) ;
253264 }
254265
255266 applyIncludeMembers ( includeMembers , cube , type , errorReporter ) {
256267 for ( const [ memberName , memberDefinition ] of includeMembers ) {
257268 if ( cube [ type ] ?. [ memberName ] ) {
258269 errorReporter . error ( `Included member '${ memberName } ' conflicts with existing member of '${ cube . name } '. Please consider excluding this member.` ) ;
259- } else {
270+ } else if ( type !== 'hierarchies' ) {
260271 cube [ type ] [ memberName ] = memberDefinition ;
261272 }
262273 }
@@ -265,7 +276,7 @@ export class CubeSymbols {
265276 /**
266277 * @protected
267278 */
268- membersFromCubes ( parentCube , cubes , type , errorReporter , splitViews ) {
279+ membersFromCubes ( parentCube , cubes , type , errorReporter , splitViews , memberSets ) {
269280 return R . unnest ( cubes . map ( cubeInclude => {
270281 const fullPath = this . evaluateReferences ( null , cubeInclude . joinPath , { collectJoinHints : true } ) ;
271282 const split = fullPath . split ( '.' ) ;
@@ -277,37 +288,43 @@ export class CubeSymbols {
277288
278289 if ( cubeInclude . includes === '*' ) {
279290 const membersObj = this . symbols [ cubeReference ] ?. cubeObj ( ) ?. [ type ] || { } ;
280- includes = Object . keys ( membersObj ) . map ( memberName => ( { member : `${ fullPath } .${ memberName } ` , name : fullMemberName ( memberName ) } ) ) ;
291+ if ( Array . isArray ( membersObj ) ) {
292+ includes = membersObj . map ( it => ( { member : `${ fullPath } .${ it . name } ` , name : fullMemberName ( it . name ) } ) ) ;
293+ } else {
294+ includes = Object . keys ( membersObj ) . map ( memberName => ( { member : `${ fullPath } .${ memberName } ` , name : fullMemberName ( memberName ) } ) ) ;
295+ }
281296 } else {
282297 includes = cubeInclude . includes . map ( include => {
283298 const member = include . alias || include ;
284- if ( member . indexOf ( '.' ) !== - 1 ) {
299+
300+ if ( member . includes ( '.' ) ) {
285301 errorReporter . error ( `Paths aren't allowed in cube includes but '${ member } ' provided as include member` ) ;
286302 }
287303
288304 const name = fullMemberName ( include . alias || member ) ;
289- if ( include . name ) {
290- const resolvedMember = this . symbols [ cubeReference ] ?. cubeObj ( ) ?. [ type ] ?. [ include . name ] ;
291- return resolvedMember ? {
292- member : `${ fullPath } .${ include . name } ` ,
293- name,
294- } : undefined ;
295- } else {
296- const resolvedMember = this . symbols [ cubeReference ] ?. cubeObj ( ) ?. [ type ] ?. [ include ] ;
297- return resolvedMember ? {
298- member : `${ fullPath } .${ include } ` ,
299- name
300- } : undefined ;
305+ memberSets . allMembers . add ( name ) ;
306+
307+ const includedMemberName = include . name || include ;
308+
309+ const resolvedMember = this . getResolvedMember ( type , cubeReference , includedMemberName ) ? {
310+ member : `${ fullPath } .${ includedMemberName } ` ,
311+ name,
312+ } : undefined ;
313+
314+ if ( resolvedMember ) {
315+ memberSets . resolvedMembers . add ( name ) ;
301316 }
317+
318+ return resolvedMember ;
302319 } ) ;
303320 }
304321
305322 const excludes = ( cubeInclude . excludes || [ ] ) . map ( exclude => {
306- if ( exclude . indexOf ( '.' ) !== - 1 ) {
323+ if ( exclude . includes ( '.' ) ) {
307324 errorReporter . error ( `Paths aren't allowed in cube excludes but '${ exclude } ' provided as exclude member` ) ;
308325 }
309326
310- const resolvedMember = this . symbols [ cubeReference ] ?. cubeObj ( ) ?. [ type ] ?. [ exclude ] ;
327+ const resolvedMember = this . getResolvedMember ( type , cubeReference , exclude ) ;
311328 return resolvedMember ? {
312329 member : `${ fullPath } .${ exclude } `
313330 } : undefined ;
@@ -356,21 +373,32 @@ export class CubeSymbols {
356373 const membersObj = this . symbols [ path [ 0 ] ] ?. cubeObj ( ) ?. [ type ] || { } ;
357374 return Object . keys ( membersObj ) . map ( memberName => ( { member : `${ ref } .${ memberName } ` } ) ) ;
358375 } else if ( path . length === 2 ) {
359- const resolvedMember = this . symbols [ path [ 0 ] ] ?. cubeObj ( ) ?. [ type ] ?. [ path [ 1 ] ] ;
376+ const resolvedMember = this . getResolvedMember ( type , path [ 0 ] , path [ 1 ] ) ;
360377 return resolvedMember ? [ { member : ref } ] : undefined ;
361378 } else {
362379 throw new Error ( `Unexpected path length ${ path . length } for ${ ref } ` ) ;
363380 }
364381 } ) ) . filter ( Boolean ) ;
365382 }
366383
384+ /**
385+ * @protected
386+ */
387+ getResolvedMember ( type , cubeName , memberName ) {
388+ if ( Array . isArray ( this . symbols [ cubeName ] ?. cubeObj ( ) ?. [ type ] ) ) {
389+ return this . symbols [ cubeName ] ?. cubeObj ( ) ?. [ type ] ?. find ( ( it ) => it . name === memberName ) ;
390+ }
391+
392+ return this . symbols [ cubeName ] ?. cubeObj ( ) ?. [ type ] ?. [ memberName ] ;
393+ }
394+
367395 /**
368396 * @protected
369397 */
370398 generateIncludeMembers ( members , cubeName , type ) {
371399 return members . map ( memberRef => {
372400 const path = memberRef . member . split ( '.' ) ;
373- const resolvedMember = this . symbols [ path [ path . length - 2 ] ] ?. cubeObj ( ) ?. [ type ] ?. [ path [ path . length - 1 ] ] ;
401+ const resolvedMember = this . getResolvedMember ( type , path [ path . length - 2 ] , path [ path . length - 1 ] ) ;
374402 if ( ! resolvedMember ) {
375403 throw new Error ( `Can't resolve '${ memberRef . member } ' while generating include members` ) ;
376404 }
@@ -404,6 +432,11 @@ export class CubeSymbols {
404432 meta : resolvedMember . meta ,
405433 description : resolvedMember . description ,
406434 } ;
435+ } else if ( type === 'hierarchies' ) {
436+ memberDefinition = {
437+ title : resolvedMember . title ,
438+ levels : resolvedMember . levels ,
439+ } ;
407440 } else {
408441 throw new Error ( `Unexpected member type: ${ type } ` ) ;
409442 }
@@ -458,6 +491,7 @@ export class CubeSymbols {
458491 name
459492 ) ;
460493 // eslint-disable-next-line no-underscore-dangle
494+ // if (resolvedSymbol && resolvedSymbol._objectWithResolvedProperties) {
461495 if ( resolvedSymbol . _objectWithResolvedProperties ) {
462496 return resolvedSymbol ;
463497 }
0 commit comments