@@ -156,6 +156,17 @@ let staticComponentFiles: Map<string, string> | null = null
156156 */
157157const integrationPathOwners = new Map < string , Pick < BlockConfig , 'type' | 'preview' > > ( )
158158
159+ /**
160+ * Owning block(s) for each `components/triggers/{provider}/{id}.json` file,
161+ * recorded at build time by inverting each block's `triggers.available`.
162+ * External-trigger paths are keyed on the trigger id + provider (not a block
163+ * type), so — like integration paths — they need this lookup for the stamp-time
164+ * visibility filter. A trigger can be reachable from more than one block (e.g. a
165+ * GA block and its preview successor), so this holds an array and the trigger is
166+ * hidden only when EVERY owning block is hidden.
167+ */
168+ const triggerPathOwners = new Map < string , Array < Pick < BlockConfig , 'type' | 'preview' > > > ( )
169+
159170/**
160171 * Per-request visibility filter for the shared static files: hides files whose
161172 * owning block is gated for this viewer (unrevealed preview blocks — the
@@ -168,6 +179,10 @@ function isStaticFileHidden(path: string, vis: BlockVisibilityState | null): boo
168179 const config = BLOCK_REGISTRY [ blockMatch [ 1 ] ! ]
169180 return config ? isHiddenUnder ( vis , config ) : false
170181 }
182+ const triggerOwners = triggerPathOwners . get ( path )
183+ if ( triggerOwners ) {
184+ return triggerOwners . length > 0 && triggerOwners . every ( ( owner ) => isHiddenUnder ( vis , owner ) )
185+ }
171186 const owner = integrationPathOwners . get ( path )
172187 return owner ? isHiddenUnder ( vis , owner ) : false
173188}
@@ -353,6 +368,21 @@ function getStaticComponentFiles(): Map<string, string> {
353368 files . set ( `components/triggers/sim/${ block . type } .json` , serializeBuiltinTriggerSchema ( block ) )
354369 }
355370
371+ // Attribute each external trigger to its owning block(s) by inverting
372+ // `triggers.available` — the same block-visibility rules that gate a block's
373+ // schema file then gate its triggers' schema files at stamp time.
374+ for ( const block of allBlocks ) {
375+ for ( const triggerId of block . triggers ?. available ?? [ ] ) {
376+ const trigger = TRIGGER_REGISTRY [ triggerId ]
377+ if ( ! trigger ) continue
378+ const path = `components/triggers/${ trigger . provider } /${ triggerId } .json`
379+ const owners = triggerPathOwners . get ( path )
380+ const owner = { type : block . type , preview : block . preview }
381+ if ( owners ) owners . push ( owner )
382+ else triggerPathOwners . set ( path , [ owner ] )
383+ }
384+ }
385+
356386 let externalTriggerCount = 0
357387 for ( const [ triggerId , trigger ] of Object . entries ( TRIGGER_REGISTRY ) ) {
358388 const path = `components/triggers/${ trigger . provider } /${ triggerId } .json`
@@ -373,12 +403,18 @@ function getStaticComponentFiles(): Map<string, string> {
373403 provider : 'sim' ,
374404 description : b . description ,
375405 } ) ) ,
376- Object . entries ( TRIGGER_REGISTRY ) . map ( ( [ id , t ] ) => ( {
377- id,
378- name : t . name ,
379- provider : t . provider ,
380- description : t . description ,
381- } ) )
406+ // Same for external triggers: a trigger owned solely by preview blocks is
407+ // hidden under the null (no-viewer) state this shared file is built with.
408+ Object . entries ( TRIGGER_REGISTRY )
409+ . filter (
410+ ( [ id , t ] ) => ! isStaticFileHidden ( `components/triggers/${ t . provider } /${ id } .json` , null )
411+ )
412+ . map ( ( [ id , t ] ) => ( {
413+ id,
414+ name : t . name ,
415+ provider : t . provider ,
416+ description : t . description ,
417+ } ) )
382418 )
383419 )
384420
0 commit comments