@@ -319,6 +319,10 @@ export function schemaToOpenAPI(
319319
320320 const deprecated = keys . includes ( 'deprecated' ) || ! ! schema . deprecated ;
321321 const isPrivate = keys . includes ( 'private' ) ;
322+ const isPublic = keys . includes ( 'public' ) ;
323+ if ( isPrivate && isPublic ) {
324+ throw new Error ( 'Cannot use both @public and @private on the same schema field' ) ;
325+ }
322326 const description = schema . comment ?. description ?? schema . description ;
323327
324328 const defaultOpenAPIObject = {
@@ -343,7 +347,7 @@ export function schemaToOpenAPI(
343347 ...( writeOnly ? { writeOnly : true } : { } ) ,
344348 ...( format ? { format } : { } ) ,
345349 ...( title ? { title } : { } ) ,
346- ...( isPrivate ? { 'x-internal' : true } : { } ) ,
350+ ...( isPrivate ? { 'x-internal' : true } : isPublic ? { 'x-internal' : false } : { } ) ,
347351 } ;
348352
349353 return defaultOpenAPIObject ;
@@ -362,13 +366,20 @@ function routeToOpenAPI(
362366 const operationId = jsdoc . tags ?. operationId ;
363367 const tag = jsdoc . tags ?. tag ?? '' ;
364368 const isInternal = jsdoc . tags ?. private !== undefined ;
369+ const isPublic = jsdoc . tags ?. public !== undefined ;
370+ if ( isInternal && isPublic ) {
371+ throw new Error (
372+ `Cannot use both @public and @private on route ${ route . method . toUpperCase ( ) } ${ route . path } ` ,
373+ ) ;
374+ }
365375 const isUnstable = jsdoc . tags ?. unstable !== undefined ;
366376 const example = jsdoc . tags ?. example ;
367377
368378 const knownTags = new Set ( [
369379 'operationId' ,
370380 'summary' ,
371381 'private' ,
382+ 'public' ,
372383 'unstable' ,
373384 'example' ,
374385 'tag' ,
@@ -406,7 +417,11 @@ function routeToOpenAPI(
406417 ...( jsdoc . description !== undefined ? { description : jsdoc . description } : { } ) ,
407418 ...( operationId !== undefined ? { operationId } : { } ) ,
408419 ...( tag !== '' ? { tags : [ tag ] } : { } ) ,
409- ...( isInternal ? { 'x-internal' : true } : { } ) ,
420+ ...( isInternal
421+ ? { 'x-internal' : true }
422+ : isPublic
423+ ? { 'x-internal' : false }
424+ : { } ) ,
410425 ...( isUnstable ? { 'x-unstable' : true } : { } ) ,
411426 ...( Object . keys ( unknownTagsObject ) . length > 0
412427 ? { 'x-unknown-tags' : unknownTagsObject }
@@ -419,8 +434,9 @@ function routeToOpenAPI(
419434 delete schema . description ;
420435 }
421436
422- const isPrivate = schema && 'x-internal' in schema ;
423- if ( isPrivate ) {
437+ const hasInternalFlag = schema && 'x-internal' in schema ;
438+ const internalValue = hasInternalFlag ? schema [ 'x-internal' ] : undefined ;
439+ if ( hasInternalFlag ) {
424440 delete schema [ 'x-internal' ] ;
425441 }
426442
@@ -430,7 +446,7 @@ function routeToOpenAPI(
430446 ? { description : p . schema . comment . description }
431447 : { } ) ,
432448 in : p . type ,
433- ...( isPrivate ? { 'x-internal' : true } : { } ) ,
449+ ...( hasInternalFlag ? { 'x-internal' : internalValue } : { } ) ,
434450 ...( p . required ? { required : true } : { } ) ,
435451 ...( p . explode ? { style : 'form' , explode : true } : { } ) ,
436452 schema : schema as any , // TODO: Something to disallow arrays
0 commit comments