@mui/internal-code-infra 0.0.4-canary.7 → 0.0.4-canary.70

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +19 -8
  3. package/build/babel-config.d.mts +11 -3
  4. package/build/brokenLinksChecker/crawlWorker.d.mts +1 -0
  5. package/build/brokenLinksChecker/index.d.mts +45 -2
  6. package/build/changelog/types.d.ts +1 -1
  7. package/build/cli/cmdArgosPush.d.mts +2 -2
  8. package/build/cli/cmdBuild.d.mts +3 -2
  9. package/build/cli/cmdCopyFiles.d.mts +2 -2
  10. package/build/cli/cmdExtractErrorCodes.d.mts +2 -2
  11. package/build/cli/cmdGenerateChangelog.d.mts +2 -2
  12. package/build/cli/cmdGithubAuth.d.mts +2 -2
  13. package/build/cli/cmdListWorkspaces.d.mts +6 -4
  14. package/build/cli/cmdNetlifyIgnore.d.mts +3 -2
  15. package/build/cli/cmdPublish.d.mts +4 -2
  16. package/build/cli/cmdPublishCanary.d.mts +3 -3
  17. package/build/cli/cmdPublishNewPackage.d.mts +4 -2
  18. package/build/cli/cmdSetVersionOverrides.d.mts +2 -2
  19. package/build/cli/cmdVale.d.mts +46 -0
  20. package/build/cli/cmdValidateBuiltTypes.d.mts +2 -2
  21. package/build/eslint/baseConfig.d.mts +3 -1
  22. package/build/eslint/mui/rules/disallow-react-api-in-server-components.d.mts +2 -2
  23. package/build/eslint/mui/rules/docgen-ignore-before-comment.d.mts +2 -2
  24. package/build/eslint/mui/rules/no-floating-cleanup.d.mts +5 -0
  25. package/build/eslint/mui/rules/no-guarded-throw.d.mts +31 -0
  26. package/build/eslint/mui/rules/no-presentation-role.d.mts +5 -0
  27. package/build/eslint/mui/rules/no-restricted-resolved-imports.d.mts +2 -2
  28. package/build/eslint/mui/rules/nodeEnvUtils.d.mts +18 -0
  29. package/build/remark/config.d.mts +43 -0
  30. package/build/remark/createLintTester.d.mts +10 -0
  31. package/build/remark/firstBlockHeading.d.mts +4 -0
  32. package/build/remark/gitDiff.d.mts +2 -0
  33. package/build/remark/noSpaceInLinks.d.mts +2 -0
  34. package/build/remark/straightQuotes.d.mts +2 -0
  35. package/build/remark/tableAlignment.d.mts +2 -0
  36. package/build/remark/terminalLanguage.d.mts +2 -0
  37. package/build/utils/babel.d.mts +1 -1
  38. package/build/utils/build.d.mts +56 -37
  39. package/build/utils/github.d.mts +1 -1
  40. package/build/utils/pnpm.d.mts +81 -2
  41. package/build/utils/testUtils.d.mts +7 -0
  42. package/build/utils/typescript.d.mts +6 -16
  43. package/package.json +60 -38
  44. package/src/babel-config.mjs +9 -3
  45. package/src/brokenLinksChecker/__fixtures__/static-site/index.html +1 -0
  46. package/src/brokenLinksChecker/__fixtures__/static-site/invalid-html.html +15 -0
  47. package/src/brokenLinksChecker/crawlWorker.mjs +217 -0
  48. package/src/brokenLinksChecker/index.mjs +263 -188
  49. package/src/brokenLinksChecker/index.test.ts +50 -13
  50. package/src/changelog/categorizeCommits.test.ts +5 -5
  51. package/src/changelog/fetchChangelogs.mjs +6 -2
  52. package/src/changelog/parseCommitLabels.test.ts +5 -5
  53. package/src/changelog/renderChangelog.mjs +1 -1
  54. package/src/changelog/types.ts +1 -1
  55. package/src/cli/cmdBuild.mjs +51 -85
  56. package/src/cli/cmdListWorkspaces.mjs +12 -27
  57. package/src/cli/cmdNetlifyIgnore.mjs +34 -93
  58. package/src/cli/cmdPublish.mjs +55 -15
  59. package/src/cli/cmdPublishCanary.mjs +128 -132
  60. package/src/cli/cmdPublishNewPackage.mjs +27 -6
  61. package/src/cli/cmdSetVersionOverrides.mjs +8 -9
  62. package/src/cli/cmdVale.mjs +513 -0
  63. package/src/cli/cmdVale.test.mjs +644 -0
  64. package/src/cli/index.mjs +2 -0
  65. package/src/cli/packageJson.d.ts +1 -1
  66. package/src/eslint/baseConfig.mjs +51 -19
  67. package/src/eslint/docsConfig.mjs +2 -1
  68. package/src/eslint/mui/config.mjs +22 -3
  69. package/src/eslint/mui/index.mjs +6 -0
  70. package/src/eslint/mui/rules/no-floating-cleanup.mjs +187 -0
  71. package/src/eslint/mui/rules/no-floating-cleanup.test.mjs +141 -0
  72. package/src/eslint/mui/rules/no-guarded-throw.mjs +115 -0
  73. package/src/eslint/mui/rules/no-guarded-throw.test.mjs +206 -0
  74. package/src/eslint/mui/rules/no-presentation-role.mjs +60 -0
  75. package/src/eslint/mui/rules/no-presentation-role.test.mjs +33 -0
  76. package/src/eslint/mui/rules/nodeEnvUtils.mjs +52 -0
  77. package/src/eslint/mui/rules/require-dev-wrapper.mjs +25 -40
  78. package/src/estree-typescript.d.ts +1 -1
  79. package/src/remark/config.mjs +157 -0
  80. package/src/remark/createLintTester.mjs +19 -0
  81. package/src/remark/firstBlockHeading.mjs +87 -0
  82. package/src/remark/firstBlockHeading.test.mjs +107 -0
  83. package/src/remark/gitDiff.mjs +43 -0
  84. package/src/remark/gitDiff.test.mjs +45 -0
  85. package/src/remark/noSpaceInLinks.mjs +42 -0
  86. package/src/remark/noSpaceInLinks.test.mjs +22 -0
  87. package/src/remark/straightQuotes.mjs +31 -0
  88. package/src/remark/straightQuotes.test.mjs +25 -0
  89. package/src/remark/tableAlignment.mjs +23 -0
  90. package/src/remark/tableAlignment.test.mjs +28 -0
  91. package/src/remark/terminalLanguage.mjs +19 -0
  92. package/src/remark/terminalLanguage.test.mjs +17 -0
  93. package/src/untyped-plugins.d.ts +11 -11
  94. package/src/utils/build.mjs +604 -270
  95. package/src/utils/build.test.mjs +1079 -521
  96. package/src/utils/git.mjs +16 -7
  97. package/src/utils/pnpm.mjs +255 -3
  98. package/src/utils/pnpm.test.mjs +731 -0
  99. package/src/utils/testUtils.mjs +18 -0
  100. package/src/utils/typescript.mjs +23 -42
  101. package/src/utils/typescript.test.mjs +234 -273
  102. package/vale/.vale.ini +1 -0
  103. package/vale/styles/MUI/CorrectReferenceAllCases.yml +43 -0
  104. package/vale/styles/MUI/CorrectRererenceCased.yml +14 -0
  105. package/vale/styles/MUI/GoogleLatin.yml +11 -0
  106. package/vale/styles/MUI/MuiBrandName.yml +22 -0
  107. package/vale/styles/MUI/NoBritish.yml +112 -0
  108. package/vale/styles/MUI/NoCompanyName.yml +17 -0
  109. package/build/markdownlint/duplicate-h1.d.mts +0 -56
  110. package/build/markdownlint/git-diff.d.mts +0 -11
  111. package/build/markdownlint/index.d.mts +0 -52
  112. package/build/markdownlint/straight-quotes.d.mts +0 -11
  113. package/build/markdownlint/table-alignment.d.mts +0 -11
  114. package/build/markdownlint/terminal-language.d.mts +0 -11
  115. package/src/markdownlint/duplicate-h1.mjs +0 -69
  116. package/src/markdownlint/git-diff.mjs +0 -31
  117. package/src/markdownlint/index.mjs +0 -62
  118. package/src/markdownlint/straight-quotes.mjs +0 -26
  119. package/src/markdownlint/table-alignment.mjs +0 -42
  120. package/src/markdownlint/terminal-language.mjs +0 -19
@@ -6,111 +6,39 @@
6
6
  * @typedef {Object} Args
7
7
  * @property {string[]} workspaces - List of workspace names to process
8
8
  * @property {boolean} [check] - Check mode - error if the generated content differs from current
9
+ * @property {string} [baseBranch] - Branch to compare PRs against (default: master)
9
10
  */
10
11
 
11
12
  import * as fs from 'node:fs/promises';
12
13
  import * as path from 'node:path';
13
14
  import { findWorkspaceDir } from '@pnpm/find-workspace-dir';
14
15
  import { toPosixPath } from '../utils/path.mjs';
15
- import { getWorkspacePackages } from '../utils/pnpm.mjs';
16
+ import { getTransitiveDependencies, getWorkspacePackages } from '../utils/pnpm.mjs';
16
17
 
17
18
  /**
18
- * Get all workspace dependencies (direct and transitive) from a package
19
- * @param {string} packageName - Package name
20
- * @param {Map<string, string>} workspaceMap - Map of workspace name to path
21
- * @param {Map<string, Promise<Set<string>>>} cache - Cache of package resolution promises
22
- * @returns {Promise<Set<string>>} Set of workspace package names (dependencies only, not including the package itself)
23
- */
24
- async function getWorkspaceDependenciesRecursive(packageName, workspaceMap, cache) {
25
- // Check cache first
26
- const cached = cache.get(packageName);
27
- if (cached) {
28
- return cached;
29
- }
30
-
31
- // Create the resolution promise
32
- const promise = (async () => {
33
- const packagePath = workspaceMap.get(packageName);
34
- if (!packagePath) {
35
- throw new Error(`Workspace "${packageName}" not found in the repository`);
36
- }
37
-
38
- const packageJsonPath = path.join(packagePath, 'package.json');
39
- const content = await fs.readFile(packageJsonPath, 'utf8');
40
- const packageJson = JSON.parse(content);
41
-
42
- // Collect all dependency names
43
- /** @type {Set<string>} */
44
- const allDeps = new Set();
45
- if (packageJson.dependencies) {
46
- Object.keys(packageJson.dependencies).forEach((dep) => allDeps.add(dep));
47
- }
48
- if (packageJson.devDependencies) {
49
- Object.keys(packageJson.devDependencies).forEach((dep) => allDeps.add(dep));
50
- }
51
- if (packageJson.peerDependencies) {
52
- Object.keys(packageJson.peerDependencies).forEach((dep) => allDeps.add(dep));
53
- }
54
-
55
- // Filter to only workspace dependencies
56
- const workspaceDeps = Array.from(allDeps).filter((dep) => workspaceMap.has(dep));
57
-
58
- // Recursively process workspace dependencies in parallel
59
- const recursiveResults = await Promise.all(
60
- workspaceDeps.map(async (dep) => {
61
- return getWorkspaceDependenciesRecursive(dep, workspaceMap, cache);
62
- }),
63
- );
64
-
65
- // Merge all results using flatMap
66
- return new Set(recursiveResults.flatMap((result) => Array.from(result)).concat(workspaceDeps));
67
- })();
68
-
69
- // Store in cache before returning
70
- cache.set(packageName, promise);
71
-
72
- return promise;
73
- }
74
-
75
- /**
76
- * Get transitive workspace dependencies for a list of workspace names
77
- * @param {string[]} workspaceNames - Array of workspace names
78
- * @param {Map<string, string>} workspaceMap - Map of workspace name to path
79
- * @returns {Promise<Set<string>>} Set of workspace package names (including requested packages and all their dependencies)
80
- */
81
- async function getTransitiveDependencies(workspaceNames, workspaceMap) {
82
- // Shared cache for all workspace dependency resolution
83
- const cache = new Map();
84
-
85
- // Validate all workspace names exist
86
- for (const workspaceName of workspaceNames) {
87
- if (!workspaceMap.has(workspaceName)) {
88
- throw new Error(`Workspace "${workspaceName}" not found in the repository`);
89
- }
90
- }
91
-
92
- // Process each requested workspace in parallel
93
- const workspaceResults = await Promise.all(
94
- workspaceNames.map((workspaceName) =>
95
- getWorkspaceDependenciesRecursive(workspaceName, workspaceMap, cache),
96
- ),
97
- );
98
-
99
- // Merge all results using flatMap and add the original package names
100
- return new Set(workspaceNames.concat(workspaceResults.flatMap((result) => Array.from(result))));
101
- }
102
-
103
- /**
104
- * Generate the ignore command string for netlify.toml
19
+ * Generate the ignore command string for netlify.toml.
20
+ *
21
+ * Production and branch deploys (every Netlify $CONTEXT other than
22
+ * "deploy-preview") always build, so downstream plugins (e.g. e2e triggers)
23
+ * run on every deploy and catch regressions in external dependencies even
24
+ * when the commit doesn't touch the watched paths.
25
+ *
26
+ * Only deploy-previews (PR previews) are eligible to be skipped: they diff
27
+ * against the merge-base with origin/<baseBranch>. This way a PR rebase whose
28
+ * head commit doesn't touch the watched paths still rebuilds when the PR as a
29
+ * whole introduces changes to them — otherwise downstream plugins silently
30
+ * never run.
31
+ *
105
32
  * @param {string[]} paths - Array of paths to include in the ignore command
106
33
  * @param {string} packagePath - Absolute path to the package directory
107
34
  * @param {string} workspaceRoot - Absolute path to the workspace root
35
+ * @param {string} baseBranch - Branch to compare PRs against
108
36
  * @returns {string} The ignore command string
109
37
  */
110
- function generateIgnoreCommand(paths, packagePath, workspaceRoot) {
38
+ function generateIgnoreCommand(paths, packagePath, workspaceRoot, baseBranch) {
111
39
  const relFromBase = `${toPosixPath(path.relative(packagePath, workspaceRoot))}/`;
112
40
  const pathsStr = paths.join(' ');
113
- return ` ignore = "cd ${relFromBase} && git diff --quiet $CACHED_COMMIT_REF $COMMIT_REF ${pathsStr}"`;
41
+ return ` ignore = """cd ${relFromBase} && [ "$CONTEXT" = "deploy-preview" ] && git fetch origin ${baseBranch} --depth=500 -q && git diff --quiet FETCH_HEAD...$COMMIT_REF -- ${pathsStr}"""`;
114
42
  }
115
43
 
116
44
  /**
@@ -180,6 +108,12 @@ export default /** @type {import('yargs').CommandModule<{}, Args>} */ ({
180
108
  default: false,
181
109
  describe: 'Check if the netlify.toml needs updating without modifying it',
182
110
  })
111
+ .option('base-branch', {
112
+ type: 'string',
113
+ default: 'master',
114
+ describe:
115
+ "Branch to compare PRs against (the site's production branch on Netlify). Production and branch deploys always rebuild regardless of this value.",
116
+ })
183
117
  .example('$0 netlify-ignore @mui/internal-docs-infra', 'Update netlify.toml for a workspace')
184
118
  .example(
185
119
  '$0 netlify-ignore @mui/internal-docs-infra @mui/internal-code-infra',
@@ -191,7 +125,7 @@ export default /** @type {import('yargs').CommandModule<{}, Args>} */ ({
191
125
  );
192
126
  },
193
127
  handler: async (argv) => {
194
- const { workspaces, check = false } = argv;
128
+ const { workspaces, check = false, baseBranch = 'master' } = argv;
195
129
 
196
130
  // Get the workspace root
197
131
  const workspaceRoot = await findWorkspaceDir(process.cwd());
@@ -220,7 +154,9 @@ export default /** @type {import('yargs').CommandModule<{}, Args>} */ ({
220
154
  console.log(`Processing ${workspaceName}...`);
221
155
 
222
156
  // Get transitive dependencies for this specific workspace
223
- const dependencyNames = await getTransitiveDependencies([workspaceName], workspaceMap);
157
+ const dependencyNames = await getTransitiveDependencies([workspaceName], {
158
+ workspacePathByName: workspaceMap,
159
+ });
224
160
 
225
161
  // Convert package names to relative paths (normalize to POSIX separators for git)
226
162
  const relativePaths = Array.from(dependencyNames)
@@ -241,7 +177,12 @@ export default /** @type {import('yargs').CommandModule<{}, Args>} */ ({
241
177
  const allPaths = [...relativePaths, 'pnpm-lock.yaml'];
242
178
 
243
179
  // Generate the ignore command for this workspace
244
- const newIgnoreCommand = generateIgnoreCommand(allPaths, workspacePath, workspaceRoot);
180
+ const newIgnoreCommand = generateIgnoreCommand(
181
+ allPaths,
182
+ workspacePath,
183
+ workspaceRoot,
184
+ baseBranch,
185
+ );
245
186
 
246
187
  // Update or check the netlify.toml file
247
188
  await updateNetlifyToml(tomlPath, newIgnoreCommand, check);
@@ -5,6 +5,7 @@
5
5
  /**
6
6
  * @typedef {import('../utils/pnpm.mjs').PublicPackage} PublicPackage
7
7
  * @typedef {import('../utils/pnpm.mjs').PublishOptions} PublishOptions
8
+ * @typedef {import('../utils/pnpm.mjs').PublishSummaryEntry} PublishSummaryEntry
8
9
  */
9
10
 
10
11
  import select from '@inquirer/select';
@@ -17,7 +18,11 @@ import * as fs from 'node:fs/promises';
17
18
  import * as semver from 'semver';
18
19
 
19
20
  import { persistentAuthStrategy } from '../utils/github.mjs';
20
- import { getWorkspacePackages, publishPackages } from '../utils/pnpm.mjs';
21
+ import {
22
+ getWorkspacePackages,
23
+ publishPackages,
24
+ validatePublishDependencies,
25
+ } from '../utils/pnpm.mjs';
21
26
  import { getCurrentGitSha, getRepositoryInfo } from '../utils/git.mjs';
22
27
 
23
28
  const isCI = envCI().isCi;
@@ -33,6 +38,7 @@ function getOctokit() {
33
38
  * @property {string} tag NPM dist tag to publish to
34
39
  * @property {boolean} ci Runs in CI environment
35
40
  * @property {string} [sha] Git SHA to use for the GitHub release workflow (local only)
41
+ * @property {string[]} [filter] Same as filtering packages with --filter in pnpm. Only publish packages matching the filter. See https://pnpm.io/filtering.
36
42
  */
37
43
 
38
44
  /**
@@ -40,7 +46,10 @@ function getOctokit() {
40
46
  * @returns {Promise<string | null>} Version string
41
47
  */
42
48
  async function getReleaseVersion() {
43
- const result = await $`pnpm pkg get version`;
49
+ // `--json` is required: pnpm 11 returns the raw value (e.g. `9.4.0`) for a
50
+ // single field without it, which is not valid JSON. The flag forces quoted
51
+ // output (`"9.4.0"`) across pnpm 9/10/11.
52
+ const result = await $`pnpm pkg get version --json`;
44
53
  const version = JSON.parse(result.stdout.trim());
45
54
  return semver.valid(version);
46
55
  }
@@ -189,18 +198,11 @@ async function validateGitHubRelease(version) {
189
198
  * Publish packages to npm
190
199
  * @param {PublicPackage[]} packages - Packages to publish
191
200
  * @param {PublishOptions} options - Publishing options
192
- * @returns {Promise<void>}
201
+ * @returns {Promise<PublishSummaryEntry[]>}
193
202
  */
194
203
  async function publishToNpm(packages, options) {
195
- console.log('\nšŸ“¦ Publishing packages to npm...');
196
- console.log(`šŸ“‹ Found ${packages.length} packages:`);
197
- packages.forEach((pkg) => {
198
- console.log(` • ${pkg.name}@${pkg.version}`);
199
- });
200
-
201
204
  // Use pnpm's built-in duplicate checking - no need to check versions ourselves
202
- await publishPackages(packages, options);
203
- console.log('āœ… Successfully published to npm');
205
+ return publishPackages(packages, options);
204
206
  }
205
207
 
206
208
  /**
@@ -260,10 +262,16 @@ export default /** @type {import('yargs').CommandModule<{}, Args>} */ ({
260
262
  .option('sha', {
261
263
  type: 'string',
262
264
  description: 'Git SHA to use for the GitHub release workflow (local only)',
265
+ })
266
+ .option('filter', {
267
+ type: 'string',
268
+ array: true,
269
+ description:
270
+ 'Same as filtering packages with --filter in pnpm. Only publish packages matching the filter. See https://pnpm.io/filtering.',
263
271
  });
264
272
  },
265
273
  handler: async (argv) => {
266
- const { dryRun = false, githubRelease = false, tag = 'latest', sha } = argv;
274
+ const { dryRun = false, githubRelease = false, tag = 'latest', sha, filter = [] } = argv;
267
275
 
268
276
  if (isCI && !argv.ci) {
269
277
  console.error(
@@ -290,13 +298,34 @@ export default /** @type {import('yargs').CommandModule<{}, Args>} */ ({
290
298
  // Get all packages
291
299
  console.log('šŸ” Discovering all workspace packages...');
292
300
 
293
- const allPackages = await getWorkspacePackages({ publicOnly: true });
301
+ const allPackages = await getWorkspacePackages({ publicOnly: true, filter });
294
302
 
295
303
  if (allPackages.length === 0) {
296
- console.log('āš ļø No public packages found in workspace');
304
+ console.log(
305
+ `āš ļø No publishable packages found in workspace${filter.length > 0 ? ` matching filter "${filter.join(', ')}"` : ''}`,
306
+ );
297
307
  return;
298
308
  }
299
309
 
310
+ if (filter.length > 0) {
311
+ console.log('šŸ” Validating workspace dependencies for filtered packages...');
312
+
313
+ const { issues } = await validatePublishDependencies(allPackages);
314
+
315
+ if (issues.length > 0) {
316
+ throw new Error(
317
+ `Invalid dependencies structure of packages to be published -
318
+ ${issues.join('\n ')}
319
+ `,
320
+ {
321
+ cause: issues,
322
+ },
323
+ );
324
+ }
325
+
326
+ console.log('āœ… All workspace dependency requirements satisfied');
327
+ }
328
+
300
329
  // Get version from root package.json
301
330
  const version = await getReleaseVersion();
302
331
 
@@ -323,7 +352,18 @@ export default /** @type {import('yargs').CommandModule<{}, Args>} */ ({
323
352
 
324
353
  // Publish to npm (pnpm handles duplicate checking automatically)
325
354
  // No git checks, we'll do our own
326
- await publishToNpm(allPackages, { dryRun, noGitChecks: true, tag });
355
+ console.log('\nšŸ“¦ Publishing packages to npm...');
356
+ const publishedPackages = await publishToNpm(allPackages, { dryRun, noGitChecks: true, tag });
357
+
358
+ if (publishedPackages.length === 0) {
359
+ console.log('ā„¹ļø No packages were published (all may already be up to date on npm)');
360
+ console.log('\nšŸ Nothing to publish, skipping git tag and GitHub release.');
361
+ return;
362
+ }
363
+
364
+ publishedPackages.forEach((pkg) => {
365
+ console.log(`āœ… Published ${pkg.name}@${pkg.version}`);
366
+ });
327
367
 
328
368
  await createGitTag(version, dryRun);
329
369