From df57c7aff4776fe1255ab46cbc0616866fb20622 Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Sat, 13 Dec 2025 11:46:12 +0100 Subject: [PATCH] feat(web-generator): update deprecation alertbox Co-Authored-By: Aviv Keller Co-Authored-By: Claudio Wunder --- src/generators/jsx-ast/constants.mjs | 26 ++++++-- .../utils/__tests__/buildContent.test.mjs | 65 +++++++++++++++++++ src/generators/jsx-ast/utils/buildContent.mjs | 37 ++++++++--- 3 files changed, 115 insertions(+), 13 deletions(-) create mode 100644 src/generators/jsx-ast/utils/__tests__/buildContent.test.mjs diff --git a/src/generators/jsx-ast/constants.mjs b/src/generators/jsx-ast/constants.mjs index 5db182a3..e392d56c 100644 --- a/src/generators/jsx-ast/constants.mjs +++ b/src/generators/jsx-ast/constants.mjs @@ -5,11 +5,21 @@ import { JSX_IMPORTS } from '../web/constants.mjs'; * * @see https://nodejs.org/api/documentation.html#stability-index */ + +// Alert level constants — prefer importing from UI library if available +// but not available for now +export const ALERT_LEVELS = { + DANGER: 'danger', + WARNING: 'warning', + INFO: 'info', + SUCCESS: 'success', +}; + export const STABILITY_LEVELS = [ - 'danger', // (0) Deprecated - 'warning', // (1) Experimental - 'success', // (2) Stable - 'info', // (3) Legacy + ALERT_LEVELS.DANGER, // (0) Deprecated + ALERT_LEVELS.WARNING, // (1) Experimental + ALERT_LEVELS.SUCCESS, // (2) Stable + ALERT_LEVELS.INFO, // (3) Legacy ]; // How deep should the Table of Contents go? @@ -151,4 +161,12 @@ export const TYPES_WITH_METHOD_SIGNATURES = [ 'classMethod', ]; +// Regex to trim leading whitespace and colons from strings export const TRIMMABLE_PADDING_REGEX = /^[\s:]+/; + +// Patterns to map deprecation "Type" text to AlertBox levels. +// Order matters: first match wins. +export const DEPRECATION_TYPE_PATTERNS = [ + { pattern: /^(Documentation|Compilation)/i, level: ALERT_LEVELS.INFO }, + { pattern: /^(Runtime|Application)/i, level: ALERT_LEVELS.WARNING }, +]; diff --git a/src/generators/jsx-ast/utils/__tests__/buildContent.test.mjs b/src/generators/jsx-ast/utils/__tests__/buildContent.test.mjs new file mode 100644 index 00000000..ccc86999 --- /dev/null +++ b/src/generators/jsx-ast/utils/__tests__/buildContent.test.mjs @@ -0,0 +1,65 @@ +import assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; + +import { transformHeadingNode } from '../buildContent.mjs'; + +const heading = { + type: 'heading', + depth: 3, + data: { type: 'misc', slug: 's', text: 'Heading' }, + children: [{ type: 'text', value: 'Heading' }], +}; + +const makeParent = typeText => ({ + children: [ + heading, + { + type: 'paragraph', + children: [{ type: 'text', value: `Type: ${typeText}` }], + }, + ], +}); + +describe('transformHeadingNode (deprecation Type -> AlertBox level)', () => { + it('maps documentation/compilation to info', () => { + const entry = { api: 'deprecations' }; + const parent = makeParent('Documentation'); + const node = parent.children[0]; + + transformHeadingNode(entry, {}, node, 0, parent); + + const alert = parent.children[1]; + const levelAttr = alert.attributes.find(a => a.name === 'level'); + + assert.equal(alert.name, 'AlertBox'); + assert.equal(levelAttr.value, 'info'); + }); + + it('maps runtime/application to warning', () => { + const entry = { api: 'deprecations' }; + const parent = makeParent('Runtime'); + const node = parent.children[0]; + + transformHeadingNode(entry, {}, node, 0, parent); + + const alert = parent.children[1]; + const levelAttr = alert.attributes.find(a => a.name === 'level'); + + assert.equal(alert.name, 'AlertBox'); + assert.equal(levelAttr.value, 'warning'); + }); + + it('falls back to danger for unknown types', () => { + const entry = { api: 'deprecations' }; + const parent = makeParent('SomeOtherThing'); + const node = parent.children[0]; + + transformHeadingNode(entry, {}, node, 0, parent); + + const alert = parent.children[1]; + const levelAttr = alert.attributes.find(a => a.name === 'level'); + + assert.equal(alert.name, 'AlertBox'); + assert.equal(levelAttr.value, 'danger'); + }); +}); diff --git a/src/generators/jsx-ast/utils/buildContent.mjs b/src/generators/jsx-ast/utils/buildContent.mjs index 51d9b10c..0fcffa19 100644 --- a/src/generators/jsx-ast/utils/buildContent.mjs +++ b/src/generators/jsx-ast/utils/buildContent.mjs @@ -16,6 +16,8 @@ import { LIFECYCLE_LABELS, INTERNATIONALIZABLE, STABILITY_PREFIX_LENGTH, + DEPRECATION_TYPE_PATTERNS, + ALERT_LEVELS, TYPES_WITH_METHOD_SIGNATURES, TYPE_PREFIX_LENGTH, } from '../constants.mjs'; @@ -163,6 +165,18 @@ export const transformStabilityNode = (node, index, parent) => { return [SKIP]; }; +/** + * Maps deprecation type text to AlertBox level + * + * @param {string} typeText - The deprecation type text + * @returns {string} The corresponding AlertBox level + */ +const getLevelFromDeprecationType = typeText => { + const match = DEPRECATION_TYPE_PATTERNS.find(p => p.pattern.test(typeText)); + + return match ? match.level : ALERT_LEVELS.DANGER; +}; + /** * Transforms a heading node by injecting metadata, source links, and signatures. * @param {ApiDocMetadataEntry} entry - The API metadata entry @@ -180,16 +194,21 @@ export const transformHeadingNode = (entry, remark, node, index, parent) => { if (entry.api === 'deprecations' && node.depth === 3) { // On the 'deprecations.md' page, "Type: " turns into an AlertBox + // Extract the nodes representing the type text + const { node } = slice( + parent.children[index + 1], + TYPE_PREFIX_LENGTH, + undefined, + { textHandling: { boundaries: 'preserve' } } + ); + + // Then retrieve its children to be the AlertBox content + const { children: sliced } = node; + parent.children[index + 1] = createJSXElement(JSX_IMPORTS.AlertBox.name, { - children: slice( - parent.children[index + 1], - TYPE_PREFIX_LENGTH, - undefined, - { - textHandling: { boundaries: 'preserve' }, - } - ).node.children, - level: 'danger', + children: sliced, + // we assume sliced[0] is a text node here that contains the type text + level: getLevelFromDeprecationType(sliced[0].value), title: 'Type', }); }