@@ -381,6 +381,7 @@ async function openapiFilter(oaObj, options) {
381381 // Filter out object matching the inverse "tags"
382382 if (
383383 inverseFilterArray . length > 0 &&
384+ inverseFilterFlags . length === 0 &&
384385 this . key === 'tags' &&
385386 ! inverseFilterArray . some ( i => node . includes ( i ) ) &&
386387 this . parent . parent !== undefined
@@ -390,7 +391,12 @@ async function openapiFilter(oaObj, options) {
390391 }
391392
392393 // Filter out the top level tags matching the inverse "tags"
393- if ( inverseFilterArray . length > 0 && this . key === 'tags' && this . parent . parent === undefined ) {
394+ if (
395+ inverseFilterArray . length > 0 &&
396+ inverseFilterFlags . length === 0 &&
397+ this . key === 'tags' &&
398+ this . parent . parent === undefined
399+ ) {
394400 // debugFilterStep = 'Filter - inverse top tags'
395401 node = node . filter ( value => inverseFilterArray . includes ( value . name ) ) ;
396402 this . update ( node ) ;
@@ -437,6 +443,7 @@ async function openapiFilter(oaObj, options) {
437443 // Keep fields matching the inverseFlags array
438444 if (
439445 inverseFilterFlags . length > 0 &&
446+ inverseFilterArray . length === 0 &&
440447 ( this . path [ 0 ] === 'tags' || this . path [ 0 ] === 'x-tagGroups' ) &&
441448 this . level === 1
442449 ) {
@@ -551,23 +558,36 @@ async function openapiFilter(oaObj, options) {
551558 }
552559 }
553560
554- // Filter out operations not matching inverseFilterArray
555- if ( inverseFilterArray . length > 0 && this . parent && this . parent . parent && this . parent . parent . key === 'paths' ) {
556- if ( node . tags === undefined || ! inverseFilterArray . some ( i => node . tags . includes ( i ) ) ) {
557- this . delete ( ) ;
558- }
559- }
560-
561- // Keep fields matching the inverseFlags
562- if ( inverseFilterFlags . length > 0 && this . path [ 0 ] === 'paths' && this . level === 3 ) {
563- const itmObj = node ;
564- const matchesInverseFlag = inverseFilterFlags . some ( flagKey => {
565- return itmObj . hasOwnProperty ( flagKey ) ;
566- } ) ;
567-
568- if ( ! matchesInverseFlag ) {
569- // debugFilterStep = 'Filter - Single field - inverseFlags'
570- this . remove ( ) ;
561+ // Filter operations for inverseTags / inverseFlags.
562+ // When both are configured, treat them as a union (keep if either matches).
563+ if (
564+ this . path [ 0 ] === 'paths' &&
565+ this . level === 3 &&
566+ this . parent &&
567+ this . parent . parent &&
568+ this . parent . parent . key === 'paths'
569+ ) {
570+ const hasInverseTags = inverseFilterArray . length > 0 ;
571+ const hasInverseFlags = inverseFilterFlags . length > 0 ;
572+ if ( hasInverseTags || hasInverseFlags ) {
573+ const operation = node || { } ;
574+ const matchesInverseTag =
575+ hasInverseTags && Array . isArray ( operation . tags )
576+ ? inverseFilterArray . some ( i => operation . tags . includes ( i ) )
577+ : false ;
578+ const matchesInverseFlag = hasInverseFlags
579+ ? inverseFilterFlags . some ( flagKey => operation . hasOwnProperty ( flagKey ) )
580+ : false ;
581+ const shouldKeep =
582+ hasInverseTags && hasInverseFlags
583+ ? matchesInverseTag || matchesInverseFlag
584+ : hasInverseTags
585+ ? matchesInverseTag
586+ : matchesInverseFlag ;
587+
588+ if ( ! shouldKeep ) {
589+ this . delete ( ) ;
590+ }
571591 }
572592 }
573593
@@ -636,6 +656,25 @@ async function openapiFilter(oaObj, options) {
636656 }
637657 } ) ;
638658
659+ // Keep top-level tags that are still referenced by remaining operations.
660+ // Apply this only when inverseTags and inverseFlags are both configured.
661+ // (inverseFlags-only mode should preserve the existing flagged-tag behavior.)
662+ if ( Array . isArray ( jsonObj . tags ) && inverseFilterArray . length > 0 && inverseFilterFlags . length > 0 ) {
663+ const usedTags = new Set ( ) ;
664+ if ( jsonObj . paths && typeof jsonObj . paths === 'object' ) {
665+ Object . values ( jsonObj . paths ) . forEach ( pathItem => {
666+ if ( pathItem && typeof pathItem === 'object' ) {
667+ Object . values ( pathItem ) . forEach ( operation => {
668+ if ( operation && typeof operation === 'object' && Array . isArray ( operation . tags ) ) {
669+ operation . tags . forEach ( tag => usedTags . add ( tag ) ) ;
670+ }
671+ } ) ;
672+ }
673+ } ) ;
674+ }
675+ jsonObj . tags = jsonObj . tags . filter ( tagObj => tagObj && usedTags . has ( tagObj . name ) ) ;
676+ }
677+
639678 // Calculate comps.meta.total at the end
640679 // comps.meta.total = Object.keys(comps.schemas).length +
641680 // Object.keys(comps.responses).length +
0 commit comments