@@ -686,9 +686,136 @@ class DataStoreTemplateProvider extends BaseTemplateProvider {
686686 }
687687}
688688
689+ /**
690+ * TemplateProvider that aggregates multiple template providers
691+ */
692+ class CompositeTemplateProvider extends BaseTemplateProvider {
693+ /**
694+ * @param {BaseTemplateProvider[] } providers - an array of template providers
695+ * @param {object } [supportedHashes={}] - an optional map of hash values to validate against
696+ */
697+ constructor ( providers , supportedHashes ) {
698+ super ( supportedHashes ) ;
699+ this . providers = providers ;
700+ }
701+
702+ _getProviderForSet ( setName ) {
703+ return Promise . resolve ( )
704+ . then ( ( ) => Promise . all (
705+ this . providers . map ( provider => Promise . all ( [
706+ Promise . resolve ( provider ) ,
707+ provider . hasSet ( setName )
708+ ] ) )
709+ ) )
710+ . then ( providerList => providerList
711+ . filter ( x => x [ 1 ] )
712+ . map ( x => x [ 0 ] ) )
713+ . then ( ( providers ) => {
714+ if ( providers . length === 0 ) {
715+ return Promise . reject ( new Error (
716+ `Could not find template set "${ setName } "`
717+ ) ) ;
718+ }
719+
720+ return Promise . resolve ( providers [ 0 ] ) ;
721+ } ) ;
722+ }
723+
724+ _getProviderForTemplate ( templatePath ) {
725+ const setName = templatePath . split ( '/' ) [ 0 ] ;
726+ return this . _getProviderForSet ( setName ) ;
727+ }
728+
729+ _getSetProviderPairs ( setListOrName ) {
730+ const initSetList = ( typeof setListOrName === 'string' ) ? [ setListOrName ] : ( setListOrName || [ ] ) ;
731+
732+ return Promise . resolve ( )
733+ . then ( ( ) => ( initSetList . length > 0 ? Promise . resolve ( initSetList ) : this . listSets ( ) ) )
734+ . then ( setList => Promise . all (
735+ setList . map (
736+ setName => this . _getProviderForSet ( setName )
737+ . then ( provider => [ setName , provider ] )
738+ )
739+ ) ) ;
740+ }
741+
742+ _loadTemplate ( templateName ) {
743+ return Promise . resolve ( )
744+ . then ( ( ) => this . _getProviderForTemplate ( templateName ) )
745+ . then ( provider => provider . fetch ( templateName ) ) ;
746+ }
747+
748+ /**
749+ * Delete the template set associated with the supplied set ID
750+ *
751+ * @returns {Promise }
752+ */
753+ removeSet ( setid ) {
754+ return this . _getProviderForSet ( setid )
755+ . then ( provider => provider . removeSet ( setid ) ) ;
756+ }
757+
758+ /**
759+ * Get a list of set names known to the provider
760+ *
761+ * @returns {Promise } Promise resolves to a string array
762+ */
763+ listSets ( ) {
764+ return Promise . all (
765+ this . providers . map ( provider => provider . listSets ( ) )
766+ )
767+ . then ( setLists => [ ...new Set ( setLists . flat ( ) ) ] ) ;
768+ }
769+
770+ /**
771+ * List all templates known to the provider (optionally filtered by the supplied list of set names)
772+ *
773+ * @param {string[] } [setList=[]]
774+ * @returns {Promise } Promise resolves to a string array
775+ */
776+ list ( setList ) {
777+ return this . _getSetProviderPairs ( setList )
778+ . then ( pairs => Promise . all ( pairs . map ( ( [ setName , provider ] ) => provider . list ( setName ) ) ) )
779+ . then ( setLists => setLists . flat ( ) ) ;
780+ }
781+
782+ /**
783+ * Get all schema known to the provider (optionally filtered by the supplied set name)
784+ *
785+ * @param {string } [filteredSetName] - only return data for this template set (instead of all template sets)
786+ * @returns {Promise } Promise resolves to an object containing schema
787+ */
788+ getSchemas ( filteredSetName ) {
789+ return this . _getSetProviderPairs ( filteredSetName )
790+ . then ( pairs => Promise . all ( pairs . map ( ( [ setName , provider ] ) => provider . getSchemas ( setName ) ) ) )
791+ . then ( data => Object . assign ( { } , ...data ) ) ;
792+ }
793+
794+ /**
795+ * Get all data files known to the provider (optionally filtered by the supplied set name)
796+ *
797+ * @param {string } [filteredSetName] - only return data for this template set (instead of all template sets)
798+ * @returns {Promise } Promise resolves to an object containing data files
799+ */
800+ getDataFiles ( filteredSetName ) {
801+ return this . _getSetProviderPairs ( filteredSetName )
802+ . then ( pairs => Promise . all ( pairs . map ( ( [ setName , provider ] ) => provider . getDataFiles ( setName ) ) ) )
803+ . then ( data => Object . assign ( { } , ...data ) ) ;
804+ }
805+
806+ /**
807+ * Clear any cache associated with this provider
808+ */
809+ invalidateCache ( ) {
810+ super . invalidateCache ( ) ;
811+ this . providers . forEach ( provider => provider . invalidateCache ( ) ) ;
812+ }
813+ }
814+
689815module . exports = {
690816 BaseTemplateProvider,
691817 FsTemplateProvider,
692818 FsSingleTemplateProvider,
693- DataStoreTemplateProvider
819+ DataStoreTemplateProvider,
820+ CompositeTemplateProvider
694821} ;
0 commit comments