Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions src/generators/jsx-ast/constants.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand Down Expand Up @@ -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 },
];
65 changes: 65 additions & 0 deletions src/generators/jsx-ast/utils/__tests__/buildContent.test.mjs
Original file line number Diff line number Diff line change
@@ -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');
});
});
37 changes: 28 additions & 9 deletions src/generators/jsx-ast/utils/buildContent.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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
Expand All @@ -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: <XYZ>" 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',
});
}
Expand Down
Loading