Skip to content

[code-infra] Move API Docs Builder to internal-scripts #41299

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: v5.x
Choose a base branch
from
Draft
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
6 changes: 6 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -477,5 +477,11 @@ module.exports = {
'import/prefer-default-export': 'off',
},
},
{
files: ['packages/api-docs-builder-core/**/*'],
rules: {
'no-restricted-imports': 'off',
},
},
],
};
2 changes: 1 addition & 1 deletion dangerfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { danger, markdown } from 'danger';
import { exec } from 'child_process';
import { loadComparison } from './scripts/sizeSnapshot';
import replaceUrl from './packages/api-docs-builder/utils/replaceUrl';
import replaceUrl from './packages-internal/scripts/api-docs-builder/utils/replaceUrl';

const circleCIBuildNumber = process.env.CIRCLE_BUILD_NUM;
const circleCIBuildUrl = `https://app.circleci.com/pipelines/github/mui/material-ui/jobs/${circleCIBuildNumber}`;
Expand Down
2 changes: 1 addition & 1 deletion docs/scripts/formattedTSDemos.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const {
} = require('@mui/internal-scripts/typescript-to-proptypes');
const {
createTypeScriptProjectBuilder,
} = require('@mui-internal/api-docs-builder/utils/createTypeScriptProject');
} = require('@mui/internal-scripts/api-docs-builder/utils/createTypeScriptProject');
const yargs = require('yargs');
const { fixBabelGeneratorIssues, fixLineEndings } = require('@mui-internal/docs-utils');
const { default: CORE_TYPESCRIPT_PROJECTS } = require('../../scripts/coreTypeScriptProjects');
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@
"@babel/register": "^7.23.7",
"@mnajdova/enzyme-adapter-react-18": "^0.2.0",
"@mui/internal-scripts": "workspace:^",
"@mui-internal/api-docs-builder": "workspace:^",
"@mui-internal/api-docs-builder-core": "workspace:^",
"@mui-internal/docs-utils": "workspace:^",
"@mui-internal/test-utils": "workspace:^",
Expand Down
4 changes: 4 additions & 0 deletions packages-internal/scripts/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 1.1.0

Added the API Docs Builder module.

## 1.0.1

- Unpinned version of the @mui-internal/docs-utils dependency.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,7 @@ export default async function generateComponentApi(
}

try {
const testInfo = await parseTest(reactApi.filename);
const testInfo = await parseTest(reactApi.filename, projectSettings.babelConfigPath);
// no Object.assign to visually check for collisions
reactApi.forwardsRefTo = testInfo.forwardsRefTo;
reactApi.spread = testInfo.spread ?? spread;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,8 @@ export interface ProjectSettings {
* Determines if a given slot or state is a global state
*/
isGlobalClassName: (slotOrState: string) => boolean;
/**
* The absolute path to the babel configuration file
*/
babelConfigPath: string;
}
11 changes: 11 additions & 0 deletions packages-internal/scripts/api-docs-builder/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export { buildApi } from './buildApi';
export type { ProjectSettings } from './ProjectSettings';

export {
default as ComponentApiBuilder,
type ReactApi as ComponentReactApi,
} from './ApiBuilders/ComponentApiBuilder';
export {
default as HookApiBuilder,
type ReactApi as HookReactApi,
} from './ApiBuilders/HookApiBuilder';
17 changes: 17 additions & 0 deletions packages-internal/scripts/api-docs-builder/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"rootDir": "./",
"outDir": "../build/api-docs-builder",
"tsBuildInfoFile": "../build/api-docs-builder/.tsbuildinfo",
"allowJs": true,
"types": ["node", "mocha"]
},
"include": ["./**/*.ts", "./**/*.js"],
"exclude": ["node_modules"],
"references": [
{
"path": "../../../packages/docs-utils/tsconfig.build.json"
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ interface MarkdownPage {
/**
* Returns the markdowns of the documentation in a flat array.
*/
export default function findPagesMarkdown(
directory: string = path.resolve(__dirname, '../../../docs/data'),
pagesMarkdown: MarkdownPage[] = [],
) {
export default function findPagesMarkdown(directory: string, pagesMarkdown: MarkdownPage[] = []) {
const items = fs.readdirSync(directory);

items.forEach((item) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ import * as babel from '@babel/core';
import { readFile } from 'fs-extra';
import glob from 'fast-glob';

const workspaceRoot = path.join(__dirname, '../../../');
const babelConfigPath = path.join(workspaceRoot, 'babel.config.js');

function getTestFilesNames(filepath: string) {
return glob.sync(
path
Expand Down Expand Up @@ -128,7 +125,10 @@ export interface ParseResult {
themeDefaultProps: boolean | undefined | null;
}

export default async function parseTest(componentFilename: string): Promise<ParseResult> {
export default async function parseTest(
componentFilename: string,
babelConfigPath: string,
): Promise<ParseResult> {
const testFilenames = getTestFilesNames(componentFilename);

if (testFilenames.length === 0) {
Expand Down
32 changes: 28 additions & 4 deletions packages-internal/scripts/package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
{
"name": "@mui/internal-scripts",
"version": "1.0.1",
"version": "1.1.0",
"author": "MUI Team",
"description": "Utilities supporting MUI libraries build and docs generation. This is an internal package not meant for general use.",
"main": "build/index.js",
"exports": {
"./typescript-to-proptypes": {
"default": "./build/typescript-to-proptypes/index.js",
"types": "./build/typescript-to-proptypes/index.d.ts"
}
},
"./api-docs-builder": {
"default": "./build/api-docs-builder/index.js",
"types": "./build/api-docs-builder/index.d.ts"
},
"./api-docs-builder/*": "./build/api-docs-builder/*.js"
},
"repository": {
"type": "git",
Expand All @@ -21,35 +26,54 @@
"build": "tsc --build tsconfig.json",
"release:publish": "pnpm build && pnpm publish --tag latest",
"release:publish:dry-run": "pnpm build && pnpm publish --tag latest --registry=\"http://localhost:4873/\"",
"test": "cd ../../ && cross-env NODE_ENV=test mocha --config packages-internal/scripts/typescript-to-proptypes/test/.mocharc.js 'packages-internal/scripts/typescript-to-proptypes/**/*.test.ts'",
"test": "npm run test:ttp && npm run test:adb",
"test:ttp": "cd ../../ && cross-env NODE_ENV=test mocha --config packages-internal/scripts/typescript-to-proptypes/test/.mocharc.js 'packages-internal/scripts/typescript-to-proptypes/**/*.test.ts'",
"test:adb": "cd ../../ && cross-env NODE_ENV=test mocha 'packages-internal/scripts/api-docs-builder/**/*.test.*'",
"typescript": "tsc --build tsconfig.typecheck.json"
},
"dependencies": {
"@babel/core": "^7.23.9",
"@babel/plugin-syntax-class-properties": "^7.12.13",
"@babel/plugin-syntax-jsx": "^7.23.3",
"@babel/plugin-syntax-typescript": "^7.23.3",
"@babel/preset-typescript": "^7.23.3",
"@babel/traverse": "^7.23.9",
"@babel/types": "^7.23.9",
"@mui-internal/docs-utils": "workspace:^",
"@mui/internal-markdown": "^1.0.0",
"ast-types": "^0.14.2",
"doctrine": "^3.0.0",
"fast-glob": "^3.3.2",
"fs-extra": "^11.2.0",
"lodash": "^4.17.21",
"prettier": "^3.2.5",
"react-docgen": "^5.4.3",
"recast": "^0.23.4",
"remark": "^13.0.0",
"typescript": "^5.3.3",
"unist-util-visit": "^2.0.3",
"uuid": "^9.0.1"
},
"devDependencies": {
"@babel/register": "^7.23.7",
"@types/babel__core": "^7.20.5",
"@types/babel__traverse": "^7.20.5",
"@types/chai": "^4.3.11",
"@types/doctrine": "^0.0.9",
"@types/lodash": "^4.14.202",
"@types/mdast": "4.0.3",
"@types/mocha": "^10.0.6",
"@types/node": "^18.19.15",
"@types/prettier": "^2.7.3",
"@types/react-docgen": "workspace:*",
"@types/react": "^18.2.55",
"@types/sinon": "^10.0.20",
"@types/uuid": "^9.0.8",
"chai": "^4.4.1",
"fast-glob": "^3.3.2",
"prettier": "^3.2.5",
"rimraf": "^5.0.5"
"rimraf": "^5.0.5",
"sinon": "^15.2.0"
},
"publishConfig": {
"access": "public"
Expand Down
2 changes: 1 addition & 1 deletion packages-internal/scripts/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"files": [],
"include": [],
"references": [{ "path": "./typescript-to-proptypes" }]
"references": [{ "path": "./api-docs-builder" }, { "path": "./typescript-to-proptypes" }]
}
3 changes: 1 addition & 2 deletions packages/api-docs-builder-core/baseUi/generateApiLinks.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import kebabCase from 'lodash/kebabCase';
import { ReactApi as ComponentReactApi } from '@mui-internal/api-docs-builder/ApiBuilders/ComponentApiBuilder';
import { ReactApi as HookReactApi } from '@mui-internal/api-docs-builder/ApiBuilders/HookApiBuilder';
import { ComponentReactApi, HookReactApi } from '@mui/internal-scripts/api-docs-builder';

/**
* Generates the api links, in a format that would point to the appropriate API tab
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import fs from 'fs';
import path from 'path';
import kebabCase from 'lodash/kebabCase';
import { getHeaders } from '@mui/internal-markdown';
import findPagesMarkdown from '@mui-internal/api-docs-builder/utils/findPagesMarkdown';
import { writePrettifiedFile } from '@mui-internal/api-docs-builder/buildApiUtils';
import findPagesMarkdown from '@mui/internal-scripts/api-docs-builder/utils/findPagesMarkdown';
import { writePrettifiedFile } from '@mui/internal-scripts/api-docs-builder/buildApiUtils';

const WORKSPACE_ROOT = path.resolve(__dirname, '../../..');

export async function generateBaseUIApiPages() {
await Promise.all(
findPagesMarkdown().map(async (markdown) => {
findPagesMarkdown(path.resolve(WORKSPACE_ROOT, 'docs/data')).map(async (markdown) => {
const markdownContent = fs.readFileSync(markdown.filename, 'utf8');
const markdownHeaders = getHeaders(markdownContent) as any;
const pathnameTokens = markdown.pathname.split('/');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ import {
getApiPath,
getSystemComponents,
parseFile,
} from '@mui-internal/api-docs-builder/buildApiUtils';
import findPagesMarkdown from '@mui-internal/api-docs-builder/utils/findPagesMarkdown';
} from '@mui/internal-scripts/api-docs-builder/buildApiUtils';
import findPagesMarkdown from '@mui/internal-scripts/api-docs-builder/utils/findPagesMarkdown';
import { migratedBaseComponents } from './migratedBaseComponents';

const WORKSPACE_ROOT = path.resolve(__dirname, '../../..');

export function getBaseUiDemos(name: string, filename?: string) {
// resolve demos, so that we can getch the API url
const allMarkdowns = findPagesMarkdown()
const allMarkdowns = findPagesMarkdown(path.resolve(WORKSPACE_ROOT, 'docs/data'))
.filter((markdown) => {
if (migratedBaseComponents.some((component) => (filename ?? name).includes(component))) {
return markdown.filename.match(/[\\/]data[\\/]base[\\/]/);
Expand Down
8 changes: 5 additions & 3 deletions packages/api-docs-builder-core/baseUi/getBaseUiHookInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,20 @@ import {
fixPathname,
getApiPath,
parseFile,
} from '@mui-internal/api-docs-builder/buildApiUtils';
import findPagesMarkdown from '@mui-internal/api-docs-builder/utils/findPagesMarkdown';
} from '@mui/internal-scripts/api-docs-builder/buildApiUtils';
import findPagesMarkdown from '@mui/internal-scripts/api-docs-builder/utils/findPagesMarkdown';
import { migratedBaseComponents } from './migratedBaseComponents';

const WORKSPACE_ROOT = path.resolve(__dirname, '../../..');

export function getBaseUiHookInfo(filename: string): HookInfo {
const { name } = extractPackageFile(filename);
let srcInfo: null | ReturnType<ComponentInfo['readFile']> = null;
if (!name) {
throw new Error(`Could not find the hook name from: ${filename}`);
}

const allMarkdowns = findPagesMarkdown()
const allMarkdowns = findPagesMarkdown(path.resolve(WORKSPACE_ROOT, 'docs/data'))
.filter((markdown) => {
if (migratedBaseComponents.some((component) => filename.includes(component))) {
return markdown.filename.match(/[\\/]data[\\/]base[\\/]/);
Expand Down
5 changes: 3 additions & 2 deletions packages/api-docs-builder-core/baseUi/projectSettings.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path from 'path';
import { LANGUAGES } from 'docs/config';
import { ProjectSettings } from '@mui-internal/api-docs-builder';
import findApiPages from '@mui-internal/api-docs-builder/utils/findApiPages';
import { ProjectSettings } from '@mui/internal-scripts/api-docs-builder';
import findApiPages from '@mui/internal-scripts/api-docs-builder/utils/findApiPages';
import {
unstable_generateUtilityClass as generateUtilityClass,
unstable_isGlobalState as isGlobalState,
Expand Down Expand Up @@ -43,4 +43,5 @@ export const projectSettings: ProjectSettings = {
translationPagesDirectory: 'docs/translations/api-docs-base',
generateClassName: generateUtilityClass,
isGlobalClassName: isGlobalState,
babelConfigPath: path.resolve(__dirname, '../../../babel.config.js'),
};
26 changes: 15 additions & 11 deletions packages/api-docs-builder-core/joyUi/getJoyUiComponentInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import {
getMuiName,
getSystemComponents,
parseFile,
} from '@mui-internal/api-docs-builder/buildApiUtils';
import findPagesMarkdown from '@mui-internal/api-docs-builder/utils/findPagesMarkdown';
} from '@mui/internal-scripts/api-docs-builder/buildApiUtils';
import findPagesMarkdown from '@mui/internal-scripts/api-docs-builder/utils/findPagesMarkdown';
import { getBaseUiDemos } from '@mui-internal/api-docs-builder-core/baseUi/getBaseUiComponentInfo';

const WORKSPACE_ROOT = path.resolve(__dirname, '../../..');

export function getJoyUiComponentInfo(filename: string): ComponentInfo {
const { name } = extractPackageFile(filename);
let srcInfo: null | ReturnType<ComponentInfo['readFile']> = null;
Expand Down Expand Up @@ -66,16 +68,18 @@ export function getJoyUiComponentInfo(filename: string): ComponentInfo {
};
},
getDemos: () => {
const allMarkdowns = findPagesMarkdown().map((markdown) => {
const markdownContent = fs.readFileSync(markdown.filename, 'utf8');
const markdownHeaders = getHeaders(markdownContent) as any;
const allMarkdowns = findPagesMarkdown(path.resolve(WORKSPACE_ROOT, 'docs/data')).map(
(markdown) => {
const markdownContent = fs.readFileSync(markdown.filename, 'utf8');
const markdownHeaders = getHeaders(markdownContent) as any;

return {
...markdown,
markdownContent,
components: markdownHeaders.components as string[],
};
});
return {
...markdown,
markdownContent,
components: markdownHeaders.components as string[],
};
},
);
return allMarkdowns
.filter((page) => page.pathname.startsWith('/joy') && page.components.includes(name))
.map((page) => ({
Expand Down
5 changes: 3 additions & 2 deletions packages/api-docs-builder-core/joyUi/projectSettings.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path from 'path';
import { LANGUAGES } from 'docs/config';
import { ProjectSettings } from '@mui-internal/api-docs-builder';
import findApiPages from '@mui-internal/api-docs-builder/utils/findApiPages';
import { ProjectSettings } from '@mui/internal-scripts/api-docs-builder';
import findApiPages from '@mui/internal-scripts/api-docs-builder/utils/findApiPages';
import {
unstable_generateUtilityClass as generateUtilityClass,
unstable_isGlobalState as isGlobalState,
Expand Down Expand Up @@ -33,4 +33,5 @@ export const projectSettings: ProjectSettings = {
translationPagesDirectory: 'docs/translations/api-docs-joy',
generateClassName: generateUtilityClass,
isGlobalClassName: isGlobalState,
babelConfigPath: path.resolve(__dirname, '../../../babel.config.js'),
};
Loading