@mui/internal-code-infra 0.0.3-canary.7 → 0.0.3-canary.8

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/internal-code-infra",
3
- "version": "0.0.3-canary.7",
3
+ "version": "0.0.3-canary.8",
4
4
  "description": "Infra scripts and configs to be used across MUI repos.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -93,7 +93,7 @@
93
93
  "publishConfig": {
94
94
  "access": "public"
95
95
  },
96
- "gitSha": "509594de98a145e15241d136d9cd7b3fc4016f9a",
96
+ "gitSha": "0224fd29f46991b95d9489c62cd138e10dccd65a",
97
97
  "scripts": {
98
98
  "typescript": "tsc -p tsconfig.json",
99
99
  "test": "pnpm -w test --project @mui/internal-code-infra",
@@ -1,9 +1,13 @@
1
1
  /* eslint-disable no-console */
2
+ import { findWorkspaceDir } from '@pnpm/find-workspace-dir';
2
3
  import { $ } from 'execa';
4
+ import { globby } from 'globby';
3
5
  import set from 'lodash-es/set.js';
4
6
  import * as fs from 'node:fs/promises';
5
7
  import * as path from 'node:path';
6
- import { getOutExtension, isMjsBuild, validatePkgJson } from '../utils/build.mjs';
8
+ import { sep as posixSep } from 'node:path/posix';
9
+
10
+ import { getOutExtension, isMjsBuild, mapConcurrently, validatePkgJson } from '../utils/build.mjs';
7
11
 
8
12
  /**
9
13
  * @typedef {Object} Args
@@ -18,6 +22,7 @@ import { getOutExtension, isMjsBuild, validatePkgJson } from '../utils/build.mjs
18
22
  * @property {boolean} skipPackageJson - Whether to skip generating the package.json file in the bundle output.
19
23
  * @property {boolean} skipMainCheck - Whether to skip checking for main field in package.json.
20
24
  * @property {string[]} ignore - Globs to be ignored by Babel.
25
+ * @property {string[]} [copy] - Files/Directories to be copied. Can be a glob pattern.
21
26
  */
22
27
 
23
28
  const validBundles = [
@@ -298,6 +303,13 @@ export default /** @type {import('yargs').CommandModule<{}, Args>} */ ({
298
303
  type: 'boolean',
299
304
  default: false,
300
305
  description: 'Skip checking for main field in package.json.',
306
+ })
307
+ .option('copy', {
308
+ type: 'string',
309
+ array: true,
310
+ description:
311
+ 'Files/Directories to be copied to the output directory. Can be a glob pattern.',
312
+ default: [],
301
313
  });
302
314
  },
303
315
  async handler(args) {
@@ -442,5 +454,144 @@ export default /** @type {import('yargs').CommandModule<{}, Args>} */ ({
442
454
  outputDir: buildDir,
443
455
  addTypes: buildTypes,
444
456
  });
457
+
458
+ await copyHandler({
459
+ cwd,
460
+ globs: args.copy ?? [],
461
+ buildDir,
462
+ verbose: args.verbose,
463
+ });
445
464
  },
446
465
  });
466
+
467
+ /**
468
+ * @param {Object} param0
469
+ * @param {string} param0.cwd - The current working directory.
470
+ * @param {string[]} [param0.globs=[]] - Extra files to copy, can be specified as `source:target` pairs or just `source`.
471
+ * @param {string} param0.buildDir - The build directory to copy to.
472
+ * @param {boolean} [param0.verbose=false] - Whether to suppress output.
473
+ * @returns {Promise<void>}
474
+ */
475
+ async function copyHandler({ cwd, globs = [], buildDir, verbose = false }) {
476
+ /**
477
+ * @type {(string|{targetPath: string; sourcePath: string})[]}
478
+ */
479
+ const defaultFiles = [];
480
+ const workspaceDir = await findWorkspaceDir(cwd);
481
+ if (!workspaceDir) {
482
+ throw new Error('Workspace directory not found');
483
+ }
484
+
485
+ const localOrRootFiles = [
486
+ [path.join(cwd, 'README.md'), path.join(workspaceDir, 'README.md')],
487
+ [path.join(cwd, 'LICENSE'), path.join(workspaceDir, 'LICENSE')],
488
+ [path.join(cwd, 'CHANGELOG.md'), path.join(workspaceDir, 'CHANGELOG.md')],
489
+ ];
490
+ await Promise.all(
491
+ localOrRootFiles.map(async (filesToCopy) => {
492
+ for (const file of filesToCopy) {
493
+ if (
494
+ // eslint-disable-next-line no-await-in-loop
495
+ await fs.stat(file).then(
496
+ () => true,
497
+ () => false,
498
+ )
499
+ ) {
500
+ defaultFiles.push(file);
501
+ break;
502
+ }
503
+ }
504
+ }),
505
+ );
506
+
507
+ if (globs.length) {
508
+ const res = globs.map((globPattern) => {
509
+ const [pattern, baseDir] = globPattern.split(':');
510
+ return { pattern, baseDir };
511
+ });
512
+ /**
513
+ * Avoids redundant globby calls for the same pattern.
514
+ *
515
+ * @type {Map<string, Promise<string[]>>}
516
+ */
517
+ const globToResMap = new Map();
518
+
519
+ const result = await Promise.all(
520
+ res.map(async ({ pattern, baseDir }) => {
521
+ if (!globToResMap.has(pattern)) {
522
+ const promise = globby(pattern, { cwd });
523
+ globToResMap.set(pattern, promise);
524
+ }
525
+ const files = await globToResMap.get(pattern);
526
+ return { files: files ?? [], baseDir };
527
+ }),
528
+ );
529
+ globToResMap.clear();
530
+
531
+ result.forEach(({ files, baseDir }) => {
532
+ files.forEach((file) => {
533
+ const sourcePath = path.resolve(cwd, file);
534
+ // Use posix separator for the relative paths. So devs can only specify globs with `/` even on Windows.
535
+ const pathSegments = file.split(posixSep);
536
+ const relativePath =
537
+ // Use index 2 (when required) since users can also specify paths like `./src/index.js`
538
+ pathSegments.slice(pathSegments[0] === '.' ? 2 : 1).join(posixSep) || file;
539
+ const targetPath = baseDir
540
+ ? path.resolve(buildDir, baseDir, relativePath)
541
+ : path.resolve(buildDir, relativePath);
542
+ defaultFiles.push({ sourcePath, targetPath });
543
+ });
544
+ });
545
+ }
546
+
547
+ if (!defaultFiles.length) {
548
+ if (verbose) {
549
+ console.log('⓿ No files to copy.');
550
+ }
551
+ }
552
+ await mapConcurrently(
553
+ defaultFiles,
554
+ async (file) => {
555
+ if (typeof file === 'string') {
556
+ const sourcePath = file;
557
+ const fileName = path.basename(file);
558
+ const targetPath = path.join(buildDir, fileName);
559
+ await recursiveCopy({ source: sourcePath, target: targetPath, verbose });
560
+ } else {
561
+ await fs.mkdir(path.dirname(file.targetPath), { recursive: true });
562
+ await recursiveCopy({ source: file.sourcePath, target: file.targetPath, verbose });
563
+ }
564
+ },
565
+ 20,
566
+ );
567
+ console.log(`📋 Copied ${defaultFiles.length} files.`);
568
+ }
569
+
570
+ /**
571
+ * Recursively copies files and directories from a source path to a target path.
572
+ *
573
+ * @async
574
+ * @param {Object} options - The options for copying files.
575
+ * @param {string} options.source - The source path to copy from.
576
+ * @param {string} options.target - The target path to copy to.
577
+ * @param {boolean} [options.verbose=true] - If true, suppresses console output.
578
+ * @returns {Promise<boolean>} Resolves when the copy operation is complete.
579
+ * @throws {Error} Throws if an error occurs other than the source not existing.
580
+ */
581
+ async function recursiveCopy({ source, target, verbose = true }) {
582
+ try {
583
+ await fs.cp(source, target, { recursive: true });
584
+ if (verbose) {
585
+ console.log(`Copied ${source} to ${target}`);
586
+ }
587
+ return true;
588
+ } catch (err) {
589
+ if (/** @type {{ code: string }} */ (err).code !== 'ENOENT') {
590
+ throw err;
591
+ }
592
+ if (verbose) {
593
+ console.warn(`Source does not exist: ${source}`);
594
+ }
595
+ throw err;
596
+ }
597
+ }
@@ -8,6 +8,7 @@ import { globby } from 'globby';
8
8
  import * as fs from 'node:fs/promises';
9
9
  import * as os from 'node:os';
10
10
  import * as path from 'node:path';
11
+ import { mapConcurrently } from '../utils/build.mjs';
11
12
 
12
13
  const $$ = $({ stdio: 'inherit' });
13
14
 
@@ -27,7 +28,8 @@ export async function emitDeclarations(tsconfig, outDir) {
27
28
  --emitDeclarationOnly
28
29
  --noEmit false
29
30
  --composite false
30
- --incremental false`;
31
+ --incremental false
32
+ --declarationMap false`;
31
33
  }
32
34
 
33
35
  /**
@@ -80,8 +82,9 @@ async function postProcessDeclarations({ directory }) {
80
82
  [pluginRemoveImports, { test: /\.css$/ }],
81
83
  ];
82
84
 
83
- await Promise.all(
84
- dtsFiles.map(async (dtsFile) => {
85
+ await mapConcurrently(
86
+ dtsFiles,
87
+ async (dtsFile) => {
85
88
  const result = await babel.transformFileAsync(dtsFile, {
86
89
  configFile: false,
87
90
  plugins: babelPlugins,
@@ -92,7 +95,8 @@ async function postProcessDeclarations({ directory }) {
92
95
  } else {
93
96
  console.error('failed to transform', dtsFile);
94
97
  }
95
- }),
98
+ },
99
+ 20,
96
100
  );
97
101
  }
98
102
 
@@ -107,11 +111,13 @@ async function renameDeclarations({ directory }) {
107
111
  return;
108
112
  }
109
113
  console.log(`Renaming d.ts files to d.mts in ${directory}`);
110
- await Promise.all(
111
- dtsFiles.map(async (dtsFile) => {
114
+ await mapConcurrently(
115
+ dtsFiles,
116
+ async (dtsFile) => {
112
117
  const newFileName = dtsFile.replace(/\.d\.ts$/, '.d.mts');
113
118
  await fs.rename(dtsFile, newFileName);
114
- }),
119
+ },
120
+ 20,
115
121
  );
116
122
  }
117
123