@@ -18,7 +18,7 @@ import {
1818 createService ,
1919 upsertSchema ,
2020} from "../../../dataconnect/client" ;
21- import { Schema , Service , File , MAIN_SCHEMA_ID , mainSchema } from "../../../dataconnect/types" ;
21+ import { Schema , Service , File , MAIN_SCHEMA_ID , isMainSchema } from "../../../dataconnect/types" ;
2222import { parseCloudSQLInstanceName , parseServiceName } from "../../../dataconnect/names" ;
2323import { logger } from "../../../logger" ;
2424import { readTemplateSync } from "../../../templates" ;
@@ -48,6 +48,7 @@ const DATACONNECT_YAML_TEMPLATE = readTemplateSync("init/dataconnect/dataconnect
4848const DATACONNECT_WEBHOOKS_YAML_TEMPLATE = readTemplateSync (
4949 "init/dataconnect/dataconnect-fdcwebhooks.yaml" ,
5050) ;
51+ const SECONDARY_SCHEMA_YAML_TEMPLATE = readTemplateSync ( "init/dataconnect/secondary_schema.yaml" ) ;
5152const CONNECTOR_YAML_TEMPLATE = readTemplateSync ( "init/dataconnect/connector.yaml" ) ;
5253const SCHEMA_TEMPLATE = readTemplateSync ( "init/dataconnect/schema.gql" ) ;
5354const QUERIES_TEMPLATE = readTemplateSync ( "init/dataconnect/queries.gql" ) ;
@@ -83,6 +84,11 @@ export interface ServiceGQL {
8384 path : string ;
8485 files : File [ ] ;
8586 } [ ] ;
87+ secondarySchemaGqls ?: {
88+ id : string ;
89+ files : File [ ] ;
90+ uri : string ;
91+ } [ ] ;
8692 seedDataGql ?: string ;
8793}
8894
@@ -406,10 +412,13 @@ async function writeFiles(
406412 options : any ,
407413) : Promise < void > {
408414 const dir : string = config . get ( "dataconnect.source" ) || "dataconnect" ;
409- const subbedDataconnectYaml = subDataconnectYamlValues ( {
410- ...info ,
411- connectorDirs : serviceGql . connectors . map ( ( c ) => c . path ) ,
412- } ) ;
415+ const subbedDataconnectYaml = subDataconnectYamlValues (
416+ {
417+ ...info ,
418+ connectorDirs : serviceGql . connectors . map ( ( c ) => c . path ) ,
419+ } ,
420+ serviceGql . secondarySchemaGqls ?. map ( ( sch ) => ( { id : sch . id , uri : sch . uri } ) ) ,
421+ ) ;
413422 config . set ( "dataconnect" , { source : dir } ) ;
414423 await config . askWriteProjectFile (
415424 join ( dir , "dataconnect.yaml" ) ,
@@ -435,6 +444,17 @@ async function writeFiles(
435444 // Even if the schema is empty, lets give them an empty .gql file to get started.
436445 fs . ensureFileSync ( join ( dir , "schema" , "schema.gql" ) ) ;
437446 }
447+ if ( serviceGql . secondarySchemaGqls ?. length ) {
448+ for ( const sch of serviceGql . secondarySchemaGqls ) {
449+ for ( const f of sch . files ) {
450+ await config . askWriteProjectFile (
451+ join ( dir , `schema_${ sch . id } ` , f . path ) ,
452+ f . content ,
453+ ! ! options . force ,
454+ ) ;
455+ }
456+ }
457+ }
438458
439459 for ( const c of serviceGql . connectors ) {
440460 await writeConnectorFiles ( config , c , options ) ;
@@ -468,23 +488,54 @@ async function writeConnectorFiles(
468488 }
469489}
470490
471- function subDataconnectYamlValues ( replacementValues : {
472- serviceId : string ;
473- cloudSqlInstanceId : string ;
474- cloudSqlDatabase : string ;
475- connectorDirs : string [ ] ;
476- locationId : string ;
477- } ) : string {
491+ function subDataconnectYamlValues (
492+ replacementValues : {
493+ serviceId : string ;
494+ cloudSqlInstanceId : string ;
495+ cloudSqlDatabase : string ;
496+ connectorDirs : string [ ] ;
497+ locationId : string ;
498+ } ,
499+ secondarySchemas ?: {
500+ id : string ;
501+ uri : string ;
502+ } [ ] ,
503+ ) : string {
478504 const replacements : Record < string , string > = {
479505 serviceId : "__serviceId__" ,
480506 locationId : "__location__" ,
481507 cloudSqlDatabase : "__cloudSqlDatabase__" ,
482508 cloudSqlInstanceId : "__cloudSqlInstanceId__" ,
483509 connectorDirs : "__connectorDirs__" ,
510+ secondarySchemaId : "__secondarySchemaId__" ,
511+ secondarySchemaSource : "__secondarySchemaSource__" ,
512+ secondarySchemaUri : "__secondarySchemaUri__" ,
484513 } ;
485514 let replaced = experiments . isEnabled ( "fdcwebhooks" )
486515 ? DATACONNECT_WEBHOOKS_YAML_TEMPLATE
487516 : DATACONNECT_YAML_TEMPLATE ;
517+ if ( secondarySchemas && secondarySchemas . length > 0 ) {
518+ let secondaryReplaced = "" ;
519+ for ( const schema of secondarySchemas ) {
520+ secondaryReplaced += SECONDARY_SCHEMA_YAML_TEMPLATE ;
521+ secondaryReplaced = secondaryReplaced . replace (
522+ replacements . secondarySchemaId ,
523+ JSON . stringify ( schema . id ) ,
524+ ) ;
525+ secondaryReplaced = secondaryReplaced . replace (
526+ replacements . secondarySchemaSource ,
527+ `"./schema_${ schema . id } "` ,
528+ ) ;
529+ secondaryReplaced = secondaryReplaced . replace (
530+ replacements . secondarySchemaUri ,
531+ JSON . stringify ( schema . uri ) ,
532+ ) ;
533+ }
534+ replaced = replaced . replace ( "#__secondarySchemaPlaceholder__\n" , secondaryReplaced ) ;
535+ } else {
536+ // If no secondary schemas, remove the secondary schema placeholder.
537+ replaced = replaced . replace ( "#__secondarySchemaPlaceholder__\n" , "" ) ;
538+ }
488539 for ( const [ k , v ] of Object . entries ( replacementValues ) ) {
489540 replaced = replaced . replace ( replacements [ k ] , JSON . stringify ( v ) ) ;
490541 }
@@ -552,17 +603,30 @@ async function downloadService(info: RequiredInfo, serviceName: string): Promise
552603 } ,
553604 ] ,
554605 } ;
555- const mainSch = mainSchema ( schemas ) ;
556- const primaryDatasource = mainSch . datasources . find ( ( d ) => d . postgresql ) ;
557- if ( primaryDatasource ?. postgresql ?. cloudSql ?. instance ) {
558- const instanceName = parseCloudSQLInstanceName ( primaryDatasource . postgresql . cloudSql . instance ) ;
559- info . cloudSqlInstanceId = instanceName . instanceId ;
560- }
561- // TODO: Update dataconnect.yaml with downloaded secondary schemas as well.
562- if ( mainSch . source . files ?. length ) {
563- info . serviceGql . schemaGql = mainSch . source . files ;
606+ for ( const sch of schemas ) {
607+ if ( isMainSchema ( sch ) ) {
608+ const primaryDatasource = sch . datasources . find ( ( d ) => d . postgresql ) ;
609+ if ( primaryDatasource ?. postgresql ?. cloudSql ?. instance ) {
610+ const instanceName = parseCloudSQLInstanceName (
611+ primaryDatasource . postgresql . cloudSql . instance ,
612+ ) ;
613+ info . cloudSqlInstanceId = instanceName . instanceId ;
614+ }
615+ info . cloudSqlDatabase = primaryDatasource ?. postgresql ?. database ?? "" ;
616+ if ( sch . source . files ?. length ) {
617+ info . serviceGql . schemaGql = sch . source . files ;
618+ }
619+ } else {
620+ if ( ! info . serviceGql . secondarySchemaGqls ) {
621+ info . serviceGql . secondarySchemaGqls = [ ] ;
622+ }
623+ info . serviceGql . secondarySchemaGqls . push ( {
624+ id : sch . name . split ( "/" ) . pop ( ) ! ,
625+ files : sch . source . files || [ ] ,
626+ uri : sch . datasources [ 0 ] . httpGraphql ?. uri ?? "" ,
627+ } ) ;
628+ }
564629 }
565- info . cloudSqlDatabase = primaryDatasource ?. postgresql ?. database ?? "" ;
566630 const connectors = await listConnectors ( serviceName , [
567631 "connectors.name" ,
568632 "connectors.source.files" ,
0 commit comments