diff --git a/src/build/open-api/types.ts b/src/build/open-api/types.ts index 3ed36b1a07cb1..d9311e252f701 100644 --- a/src/build/open-api/types.ts +++ b/src/build/open-api/types.ts @@ -72,6 +72,7 @@ export type DeRefedOpenAPI = { description?: string; security?: any; servers?: ServerMeta[]; + 'x-sentry-experimental'?: boolean; }; }; }; diff --git a/src/build/resolveOpenAPI.ts b/src/build/resolveOpenAPI.ts index 4b4cf9b1a9b30..6f8d6a27cf6dc 100644 --- a/src/build/resolveOpenAPI.ts +++ b/src/build/resolveOpenAPI.ts @@ -64,6 +64,7 @@ export type API = { apiPath: string; bodyParameters: APIParameter[]; deprecated: boolean; + experimental: boolean; method: string; name: string; pathParameters: APIParameter[]; @@ -97,6 +98,11 @@ function slugify(s: string): string { const DEPRECATED_PREFIX_REGEX = /^\(DEPRECATED\)\s*/; +// Sentry prepends this notice to the description of every experimental operation, so +// that consumers with no badge of their own still warn the reader. We render a badge, +// so strip it rather than saying the same thing twice. +const EXPERIMENTAL_NOTICE_REGEX = /^\*\*Experimental:\*\*[^\n]*\n+/; + function isDeprecatedOperationId(operationId: string | undefined): boolean { return operationId ? DEPRECATED_PREFIX_REGEX.test(operationId) : false; } @@ -135,6 +141,7 @@ async function apiCategoriesUncached(): Promise { const isDeprecated = isDeprecatedOperationId(apiData.operationId) || isDeprecatedOperationId(apiData.summary); + const isExperimental = apiData['x-sentry-experimental'] === true; const titleSource = apiData.summary || apiData.operationId || ''; const cleanName = stripDeprecatedPrefix(titleSource); @@ -148,12 +155,15 @@ async function apiCategoriesUncached(): Promise { method, name: cleanName, deprecated: isDeprecated, + experimental: isExperimental, server, slug: slugify(cleanName), summary: apiData.summary ? stripDeprecatedPrefix(apiData.summary) : apiData.summary, - descriptionMarkdown: apiData.description, + descriptionMarkdown: isExperimental + ? apiData.description?.replace(EXPERIMENTAL_NOTICE_REGEX, '') + : apiData.description, pathParameters: (apiData.parameters || []).filter( p => p.in === 'path' ) as APIParameter[], diff --git a/src/components/apiPage/index.tsx b/src/components/apiPage/index.tsx index c0caa97bbcfd3..3599b95e160f3 100644 --- a/src/components/apiPage/index.tsx +++ b/src/components/apiPage/index.tsx @@ -125,6 +125,16 @@ export function ApiPage({api}: Props) { }; return ( + {api.experimental && ( +
+ + Experimental + + + This API is under active development and may change. + +
+ )}