init project
Some checks failed
No response / noResponse (push) Has been cancelled
CI / Continuous releases (push) Has been cancelled
CI / test-dev (macos-latest) (push) Has been cancelled
CI / test-dev (ubuntu-latest) (push) Has been cancelled
CI / test-dev (windows-latest) (push) Has been cancelled
Maintenance / main (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled

This commit is contained in:
how2ice
2025-12-12 14:26:25 +09:00
commit 005cf56baf
43188 changed files with 1079531 additions and 0 deletions

View File

@@ -0,0 +1,221 @@
import { promises as fs } from 'fs';
import { URL } from 'url';
import * as process from 'process';
/**
* @typedef {object} FixtureContext
* @property {URL} fixtureUrl
* @property {object} fixtureTemplateValues
*/
/**
* @param {URL} destinationUrl
* @param {string} templateSource
* @param {Record<string, string>} templateValues
*/
async function writeFromTemplate(destinationUrl, templateSource, templateValues) {
const source = Object.entries(templateValues).reduce((partialCode, [name, value]) => {
return partialCode.replace(`{{{${name}}}}`, value);
}, templateSource);
await fs.writeFile(destinationUrl, source);
}
/**
* @param {FixtureContext} context
*/
async function writeNodeESMFixture(context) {
const { fixtureUrl, fixtureTemplateValues } = context;
const destinationPath = new URL('./node-esm.fixture.js', fixtureUrl);
const templateSource = await fs.readFile(new URL('node-esm.template', fixtureUrl), {
encoding: 'utf8',
});
await writeFromTemplate(destinationPath, templateSource, fixtureTemplateValues);
}
/**
* @param {FixtureContext} context
*/
async function writeNodeCJSFixture(context) {
const { fixtureUrl, fixtureTemplateValues } = context;
const destinationPath = new URL('./node-cjs.fixture.js', fixtureUrl);
const templateSource = await fs.readFile(new URL('node-cjs.template', fixtureUrl), {
encoding: 'utf8',
});
await writeFromTemplate(destinationPath, templateSource, fixtureTemplateValues);
}
/**
* @param {FixtureContext} context
*/
async function writeNextWebpackFixture(context) {
const { fixtureUrl, fixtureTemplateValues } = context;
const destinationUrl = new URL('./pages/next-webpack.fixture.js', fixtureUrl);
const templateSource = await fs.readFile(new URL('./next-webpack.template', fixtureUrl), {
encoding: 'utf8',
});
await writeFromTemplate(destinationUrl, templateSource, fixtureTemplateValues);
}
/**
* @param {FixtureContext} context
*/
async function writeSnowpackFixture(context) {
const { fixtureUrl, fixtureTemplateValues } = context;
const destinationUrl = new URL('./src/snowpack.fixture.js', fixtureUrl);
await fs.mkdir(new URL('.', destinationUrl), { recursive: true });
const templateSource = await fs.readFile(new URL('snowpack.template', fixtureUrl), {
encoding: 'utf8',
});
await writeFromTemplate(destinationUrl, templateSource, fixtureTemplateValues);
}
/**
* @param {FixtureContext} context
*/
async function writeViteFixture(context) {
const { fixtureUrl: fixturePath, fixtureTemplateValues } = context;
const destinationPath = new URL('./vite.fixture.js', fixturePath);
const templateSource = await fs.readFile(new URL('vite.template', fixturePath), {
encoding: 'utf8',
});
await writeFromTemplate(destinationPath, templateSource, fixtureTemplateValues);
}
/**
* @param {FixtureContext} context
*/
async function writeEsbuildFixture(context) {
const { fixtureUrl, fixtureTemplateValues } = context;
const destinationPath = new URL('./esbuild.fixture.js', fixtureUrl);
const templateSource = await fs.readFile(new URL('esbuild.template', fixtureUrl), {
encoding: 'utf8',
});
await writeFromTemplate(destinationPath, templateSource, fixtureTemplateValues);
}
/**
* @param {FixtureContext} context
*/
async function writeGatsbyFixture(context) {
const { fixtureUrl: fixturePath, fixtureTemplateValues } = context;
const destinationPath = new URL('./src/pages/gatsby.fixture.js', fixturePath);
const templateSource = await fs.readFile(new URL('gatsby.template', fixturePath), {
encoding: 'utf8',
});
await writeFromTemplate(destinationPath, templateSource, fixtureTemplateValues);
}
async function readFixtureTemplateValues(fileUrl) {
const code = await fs.readFile(fileUrl, { encoding: 'utf8' });
const importsMatch = code.match(/\/\/ #region imports(.+?)\/\/ #endregion/s);
const [imports] = importsMatch;
const lines = imports.split(/\n+/).filter((line) => {
const trimmed = line.trim();
return trimmed && !trimmed.startsWith('//') && !trimmed.startsWith('/*');
});
const requires = lines
.map((line) => {
const [, specifier, module] = /import (.*) from ['"](.*)['"]/.exec(line);
if (specifier.startsWith('*')) {
return `const ${specifier.replace('* as ', '')} = require('${module}')`;
}
if (specifier.startsWith('{')) {
return `const ${specifier.replace(' as ', ': ')} = require('${module}')`;
}
return `const { default: ${specifier} } = require('${module}')`;
})
.join('\n');
const usageMatch = code.match(/\/\/ #region usage(.+?)\/\/ #endregion/s);
const [usage] = usageMatch;
return { imports, usage, requires };
}
function resolveFixtureUrl(fixtureName) {
return new URL(`../fixtures/${fixtureName}/`, import.meta.url);
}
/**
* @param {object} context
* @param {string} context.fixture
*/
async function run(context) {
const { fixture } = context;
if (fixture === undefined) {
throw new Error(`Usage: ${process.argv[1]} <fixture>`);
}
const fixtureTemplateValues = await readFixtureTemplateValues(
new URL('./fixtureTemplateValues.js', import.meta.url),
);
switch (fixture) {
case 'node-cjs':
await writeNodeCJSFixture({
fixtureUrl: resolveFixtureUrl('node-cjs'),
fixtureTemplateValues,
});
break;
case 'node-esm':
await writeNodeESMFixture({
fixtureUrl: resolveFixtureUrl('node-esm'),
fixtureTemplateValues,
});
break;
case 'next-webpack4':
await writeNextWebpackFixture({
fixtureUrl: resolveFixtureUrl('next-webpack4'),
fixtureTemplateValues,
});
break;
case 'next-webpack5':
await writeNextWebpackFixture({
fixtureUrl: resolveFixtureUrl('next-webpack5'),
fixtureTemplateValues,
});
break;
case 'snowpack':
await writeSnowpackFixture({
fixtureUrl: resolveFixtureUrl('snowpack'),
fixtureTemplateValues,
});
break;
case 'vite':
await writeViteFixture({
fixtureUrl: resolveFixtureUrl('vite'),
fixtureTemplateValues,
});
break;
case 'esbuild':
await writeEsbuildFixture({
fixtureUrl: resolveFixtureUrl('esbuild'),
fixtureTemplateValues,
});
break;
// TODO remove, no longer relevant since https://github.com/mui/material-ui/pull/38567
case 'gatsby':
await writeGatsbyFixture({
fixtureUrl: resolveFixtureUrl('gatsby'),
fixtureTemplateValues,
});
break;
default:
throw new TypeError(`Can't handle fixture '${fixture}'`);
}
}
run({ fixture: process.argv[2] }).catch((error) => {
console.error(error);
process.exit(1);
});

View File

@@ -0,0 +1,138 @@
import * as process from 'process';
import packages from './packages.js';
function isComponent(identifier) {
// Components start with Uppercase letter.
return /^[A-Z]/.test(identifier);
}
function isNamespace(identifier) {
return ['colors', 'styles', 'utils'].includes(identifier);
}
function getMuiLocal(imported, source) {
return `${imported}_${source.split('/')[1]}`;
}
/**
* @param {object} context
* @param {boolean} context.asNamedImport
* @param {string} context.local
* @param {string} context.imported
* @param {string} context.source
*/
function createImport(context) {
const { specifier, imported, local = imported, source } = context;
if (specifier === 'named') {
return `import { ${imported} as ${local} } from '${source}';`;
}
if (specifier === 'namespace') {
return `import * as ${local} from '${source}';`;
}
return `import ${local} from '${source}';`;
}
/**
* @param {NodeJS.WritableStream} outStream
*/
function writeImports(outStream) {
outStream.write(
`${createImport({
local: 'ReactIs',
modules: false,
source: 'react-is',
specifier: 'namespace',
})}\n`,
);
outStream.write('// #region imports\n');
outStream.write('/* eslint-disable import/no-duplicates */\n');
Object.entries(packages).forEach(([packageName, topLevelPackages]) => {
topLevelPackages.forEach((topLevelPackageName) => {
if (isNamespace(topLevelPackageName)) {
outStream.write(
`${createImport({
specifier: 'namespace',
local: `${getMuiLocal(topLevelPackageName, packageName)}__pathImport`,
imported: topLevelPackageName,
source: `${packageName}/${topLevelPackageName}`,
})}\n`,
);
} else {
outStream.write(
`${createImport({
specifier: 'named',
local: getMuiLocal(topLevelPackageName, packageName),
imported: topLevelPackageName,
source: packageName,
})}\n`,
);
outStream.write(
`${createImport({
specifier: 'default',
local: `${getMuiLocal(topLevelPackageName, packageName)}__pathImport`,
source: `${packageName}/${topLevelPackageName}`,
})}\n`,
);
}
});
});
outStream.write('/* eslint-enable import/no-duplicates */\n');
outStream.write('// #endregion\n');
}
function getComponentValidator(localIdentifier) {
return `ReactIs.isValidElementType(${localIdentifier})`;
}
function getNamespaceValidator(localIdentifier) {
return `${localIdentifier} !== null && typeof ${localIdentifier} === 'object'`;
}
function getUnknownValidator(localIdentifier) {
return `${localIdentifier} !== undefined`;
}
/**
* @param {NodeJS.WritableStream} outStream
*/
function writeUsage(outStream) {
outStream.write('\n// #region usage\n');
outStream.write('\n/* eslint-disable no-console */');
Object.entries(packages).forEach(([packageName, topLevelPackages]) => {
topLevelPackages.forEach((topLevelPackageName) => {
let getValidator = getUnknownValidator;
if (isNamespace(topLevelPackageName)) {
getValidator = getNamespaceValidator;
} else if (isComponent(topLevelPackageName)) {
getValidator = getComponentValidator;
}
if (!isNamespace(topLevelPackageName)) {
outStream.write(
`console.assert(${getValidator(
getMuiLocal(topLevelPackageName, packageName),
)}, '${topLevelPackageName} named import is not consumable.');\n`,
);
}
outStream.write(
`console.assert(${getValidator(
`${getMuiLocal(topLevelPackageName, packageName)}__pathImport`,
)}, '${topLevelPackageName} path import is not consumable.');\n`,
);
});
});
outStream.write('/* eslint-enable no-console */\n');
outStream.write('// #endregion\n');
}
async function main() {
const outStream = process.stdout;
writeImports(outStream);
writeUsage(outStream);
}
main().catch((error) => {
console.error(error);
process.exit(1);
});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
{
"type": "module"
}

206
test/bundling/scripts/packages.js generated Normal file
View File

@@ -0,0 +1,206 @@
export default {
'@mui/material': [
'Accordion',
'AccordionActions',
'AccordionDetails',
'AccordionSummary',
'Alert',
'AlertTitle',
'AppBar',
'Autocomplete',
'Avatar',
'Backdrop',
'Badge',
'BottomNavigation',
'BottomNavigationAction',
'Box',
'Breadcrumbs',
'Button',
'ButtonBase',
'ButtonGroup',
'Card',
'CardActionArea',
'CardActions',
'CardContent',
'CardHeader',
'CardMedia',
'Checkbox',
'Chip',
'CircularProgress',
'ClickAwayListener',
'Collapse',
'colors',
'Container',
'CssBaseline',
'Dialog',
'DialogActions',
'DialogContent',
'DialogContentText',
'DialogTitle',
'Divider',
'Drawer',
'Fab',
'Fade',
'FilledInput',
'FormControl',
'FormControlLabel',
'FormGroup',
'FormHelperText',
'FormLabel',
'Grid',
'Grow',
'Icon',
'IconButton',
'ImageList',
'ImageListItem',
'ImageListItemBar',
'Input',
'InputAdornment',
'InputBase',
'InputLabel',
'LinearProgress',
'Link',
'List',
'ListItem',
'ListItemAvatar',
'ListItemIcon',
'ListItemSecondaryAction',
'ListItemText',
'ListSubheader',
'Menu',
'MenuItem',
'MenuList',
'MobileStepper',
'Modal',
'NativeSelect',
'NoSsr',
'OutlinedInput',
'Pagination',
'PaginationItem',
'Paper',
'Popover',
'Popper',
'Portal',
'Radio',
'RadioGroup',
'Rating',
'ScopedCssBaseline',
'Select',
'Skeleton',
'Slide',
'Slider',
'Snackbar',
'SnackbarContent',
'SpeedDial',
'SpeedDialAction',
'SpeedDialIcon',
'Step',
'StepButton',
'StepConnector',
'StepContent',
'StepIcon',
'StepLabel',
'Stepper',
'styles',
'SvgIcon',
'SwipeableDrawer',
'Switch',
'Tab',
'Table',
'TableBody',
'TableCell',
'TableContainer',
'TableFooter',
'TableHead',
'TablePagination',
'TablePaginationActions',
'TableRow',
'TableSortLabel',
'Tabs',
'TabScrollButton',
'TextareaAutosize',
'TextField',
'ToggleButton',
'ToggleButtonGroup',
'Toolbar',
'Tooltip',
'Typography',
'Unstable_TrapFocus',
'useAutocomplete',
'useMediaQuery',
'usePagination',
'useScrollTrigger',
'utils',
'Zoom',
],
'@mui/icons-material': [
// Icons are generated.
// So the behavior of a single item should be equivalent to all icons.
'Accessibility',
],
'@mui/lab': [
'Alert',
'AlertTitle',
'Autocomplete',
'AvatarGroup',
'LoadingButton',
'Pagination',
'PaginationItem',
'Rating',
'Skeleton',
'SpeedDial',
'SpeedDialAction',
'SpeedDialIcon',
'TabContext',
'TabList',
'TabPanel',
// types only
// 'themeAugmentation',
'Timeline',
'TimelineConnector',
'TimelineContent',
'TimelineDot',
'TimelineItem',
'TimelineOppositeContent',
'TimelineSeparator',
'ToggleButton',
'ToggleButtonGroup',
'TreeItem',
'TreeView',
'useAutocomplete',
],
'@mui/system': [
'borders',
'breakpoints',
'compose',
'display',
'flexbox',
'grid',
// private
// 'memoize',
// 'merge',
'palette',
'positions',
// private
// 'responsivePropType',
'shadows',
'sizing',
'spacing',
'style',
// private
// 'styleFunctionSx',
'typography',
],
'@mui/utils': [
'chainPropTypes',
'deepmerge',
'elementAcceptingRef',
'elementTypeAcceptingRef',
'exactProp',
'formatMuiErrorMessage',
'getDisplayName',
'HTMLElementType',
'ponyfillGlobal',
'refType',
],
};