@upleveled/preflight 7.0.3 → 7.0.5

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.
@@ -1,6 +1,6 @@
1
1
  import { Listr } from 'listr2';
2
2
  import { promises, existsSync } from 'node:fs';
3
- import { execaCommand } from 'execa';
3
+ import { execa } from 'execa';
4
4
  import chalk from 'chalk';
5
5
  import path, { sep, dirname } from 'node:path';
6
6
  import { createRequire } from 'node:module';
@@ -9,9 +9,9 @@ import semver from 'semver';
9
9
  import cheerio from 'cheerio';
10
10
  import fetch from 'node-fetch';
11
11
  import userAgents from 'top-user-agents';
12
- import { URL, fileURLToPath } from 'node:url';
13
12
  import algoliasearch from 'algoliasearch';
14
13
  import pReduce from 'p-reduce';
14
+ import { URL, fileURLToPath } from 'node:url';
15
15
  import os from 'node:os';
16
16
 
17
17
  // https://www.compart.com/en/unicode/U+2800
@@ -24,9 +24,9 @@ function commandExample(command) {
24
24
  async function isDrone() {
25
25
  const {
26
26
  stdout
27
- } = await execaCommand('cat /etc/os-release', {
27
+ } = await execa({
28
28
  reject: false
29
- });
29
+ })`cat /etc/os-release`;
30
30
  return /Alpine Linux/.test(stdout);
31
31
  }
32
32
 
@@ -34,14 +34,14 @@ const title = 'All changes committed to Git';
34
34
  async function allChangesCommittedToGit() {
35
35
  const {
36
36
  stdout: replSlug
37
- } = await execaCommand('echo $REPL_SLUG');
37
+ } = await execa`echo $REPL_SLUG`;
38
38
  const isRunningInReplIt = replSlug !== '';
39
39
  if (isRunningInReplIt) {
40
40
  await promises.writeFile('.git/info/exclude', '.replit\n');
41
41
  }
42
42
  const {
43
43
  stdout
44
- } = await execaCommand('git status --porcelain');
44
+ } = await execa`git status --porcelain`;
45
45
  if (stdout !== '') {
46
46
  const onlyPnpmLockModifiedOnDrone = stdout.trim() === 'M pnpm-lock.yaml' && (await isDrone());
47
47
  throw new Error(`Some changes have not been committed to Git:
@@ -63,7 +63,11 @@ var allChangesCommittedToGit$1 = {
63
63
  const title$1 = 'ESLint';
64
64
  async function eslintCheck() {
65
65
  try {
66
- await execaCommand('pnpm eslint . --max-warnings 0 --format json');
66
+ await execa({
67
+ // Execute binaries in ./node_modules/.bin to avoid pnpm overhead
68
+ // https://github.com/sindresorhus/execa/blob/main/docs/environment.md#local-binaries
69
+ preferLocal: true
70
+ })`eslint . --max-warnings 0 --format json`;
67
71
  } catch (error) {
68
72
  const {
69
73
  stdout
@@ -76,7 +80,7 @@ async function eslintCheck() {
76
80
  .filter(eslintResult => {
77
81
  return eslintResult.errorCount > 0 || eslintResult.warningCount > 0;
78
82
  });
79
- } catch (parseError) {
83
+ } catch {
80
84
  throw error;
81
85
  }
82
86
  if (eslintResults.length < 1 || !eslintResults.every(result => 'errorCount' in result && 'warningCount' in result)) {
@@ -115,12 +119,14 @@ const title$2 = 'ESLint config is latest version';
115
119
  async function eslintConfigIsValid() {
116
120
  const {
117
121
  stdout: remoteVersion
118
- } = await execaCommand('npm show eslint-config-upleveled version');
122
+ } = await execa`npm show eslint-config-upleveled version`;
119
123
  let localVersion;
120
124
  try {
121
125
  const eslintConfigPackageJsonPath = require$1.resolve('eslint-config-upleveled/package.json');
122
126
  localVersion = JSON.parse(await promises.readFile(eslintConfigPackageJsonPath, 'utf-8')).version;
123
- } catch (error) {}
127
+ } catch {
128
+ // Swallow error
129
+ }
124
130
  if (typeof localVersion === 'undefined') {
125
131
  throw new Error(`The UpLeveled ESLint Config has not been installed - please install using the instructions on https://www.npmjs.com/package/eslint-config-upleveled
126
132
  `);
@@ -132,7 +138,7 @@ async function eslintConfigIsValid() {
132
138
  let eslintConfigMatches;
133
139
  try {
134
140
  eslintConfigMatches = (await promises.readFile('./eslint.config.js', 'utf-8')).trim() === "export { default } from 'eslint-config-upleveled';";
135
- } catch (error) {
141
+ } catch {
136
142
  throw new Error(`Error reading your eslint.config.js file - please delete the file if it exists and reinstall the config using the instructions on https://www.npmjs.com/package/eslint-config-upleveled
137
143
  `);
138
144
  }
@@ -176,7 +182,7 @@ const title$3 = 'GitHub repo has deployed project link under About';
176
182
  async function linkOnGithubAbout() {
177
183
  const {
178
184
  stdout
179
- } = await execaCommand('git remote get-url origin');
185
+ } = await execa`git remote get-url origin`;
180
186
  const repoUrl = stdout.replace('git@github.com:', 'https://github.com/').replace('.git', '');
181
187
  const html = await (await fetch(repoUrl)).text();
182
188
  const $ = cheerio.load(html);
@@ -215,13 +221,13 @@ function normalizeNewlines(input) {
215
221
 
216
222
  const title$4 = 'node_modules/ folder ignored in Git';
217
223
  async function nodeModulesIgnoredFromGit() {
218
- if ((await execaCommand('git ls-files node_modules/')).stdout !== '') {
224
+ if ((await execa`git ls-files node_modules/`).stdout !== '') {
219
225
  throw new Error(`node_modules/ folder committed to Git. Remove it using:
220
226
 
221
227
  ${commandExample('git rm -r --cached node_modules')}
222
228
  `);
223
229
  }
224
- if ((await execaCommand('git ls-files .gitignore')).stdout !== '.gitignore') {
230
+ if ((await execa`git ls-files .gitignore`).stdout !== '.gitignore') {
225
231
  throw new Error('.gitignore file not found');
226
232
  }
227
233
  const nodeModulesInGitignore = normalizeNewlines(await promises.readFile('./.gitignore', 'utf8')).split('\n').reduce((found, line) => found || /^\/?node_modules\/?$/.test(line), false);
@@ -239,17 +245,6 @@ var nodeModulesIgnoredFromGit$1 = {
239
245
  const projectPackageJson = /*#__PURE__*/JSON.parse(await /*#__PURE__*/promises.readFile('package.json', 'utf-8'));
240
246
  const preflightPackageJson = /*#__PURE__*/JSON.parse(await /*#__PURE__*/promises.readFile( /*#__PURE__*/new URL('../package.json', import.meta.url), 'utf-8'));
241
247
 
242
- const title$5 = 'Next.js project has sharp installed';
243
- function nextJsProjectHasSharpInstalled() {
244
- const dependenciesPackageNames = Object.keys(projectPackageJson.dependencies || {});
245
- if (dependenciesPackageNames.includes('next') && !dependenciesPackageNames.includes('sharp')) {
246
- throw new Error(`Next.js projects should have sharp installed for better image optimization. Install it with:
247
-
248
- ${commandExample('pnpm add sharp')}
249
- `);
250
- }
251
- }
252
-
253
248
  const client = /*#__PURE__*/algoliasearch(
254
249
  // Application ID and API key specific to UpLeveled
255
250
  // Preflight. Please don't use anywhere else without
@@ -258,7 +253,7 @@ const client = /*#__PURE__*/algoliasearch(
258
253
  // Application ID
259
254
  'ec73550aa8b2936dab436d4e02144784');
260
255
  const index = /*#__PURE__*/client.initIndex('npm-search');
261
- const title$6 = 'No dependencies without types';
256
+ const title$5 = 'No dependencies without types';
262
257
  // This is a naive check for matching @types/<pkg name> packages
263
258
  // that the student hasn't yet installed. It is not intended to
264
259
  // be an exhaustive check for any types for all packages.
@@ -277,11 +272,15 @@ async function noDependenciesWithoutTypes() {
277
272
  if ('types' in modulePackageJson || 'typings' in modulePackageJson) {
278
273
  return filteredDependencies;
279
274
  }
280
- } catch (error) {}
275
+ } catch {
276
+ // Swallow error
277
+ }
281
278
  let indexDTsPath;
282
279
  try {
283
280
  indexDTsPath = require.resolve(`${dependency}/index.d.ts`);
284
- } catch (error) {}
281
+ } catch {
282
+ // Swallow error
283
+ }
285
284
  // If the index.d.ts file exists inside the module's directory, bail out
286
285
  if (indexDTsPath && existsSync(indexDTsPath)) {
287
286
  return filteredDependencies;
@@ -319,11 +318,11 @@ async function noDependenciesWithoutTypes() {
319
318
 
320
319
  const {
321
320
  stdout: preflightBinPath
322
- } = await /*#__PURE__*/execaCommand(`pnpm bin`, {
321
+ } = await /*#__PURE__*/execa({
323
322
  cwd: /*#__PURE__*/dirname( /*#__PURE__*/fileURLToPath(import.meta.url))
324
- });
323
+ })`pnpm bin`;
325
324
 
326
- const title$7 = 'No unused dependencies';
325
+ const title$6 = 'No unused dependencies';
327
326
  async function noUnusedAndMissingDependencies() {
328
327
  const ignoredPackagePatterns = [
329
328
  // Unused dependency detected in https://github.com/upleveled/next-portfolio-dev
@@ -358,7 +357,7 @@ async function noUnusedAndMissingDependencies() {
358
357
  // Next.js
359
358
  'sharp'].join(',');
360
359
  try {
361
- await execaCommand(`${preflightBinPath}/depcheck --ignores="${ignoredPackagePatterns}"`);
360
+ await execa`${preflightBinPath}/depcheck --ignores="${ignoredPackagePatterns}"`;
362
361
  } catch (error) {
363
362
  const {
364
363
  stdout
@@ -390,11 +389,11 @@ async function noUnusedAndMissingDependencies() {
390
389
  }
391
390
  }
392
391
 
393
- const title$8 = 'No extraneous files committed to Git';
392
+ const title$7 = 'No extraneous files committed to Git';
394
393
  async function noExtraneousFilesCommittedToGit() {
395
394
  const {
396
395
  stdout
397
- } = await execaCommand('git ls-files .DS_Store yarn-error.log npm-debug.log');
396
+ } = await execa`git ls-files .DS_Store yarn-error.log npm-debug.log`;
398
397
  if (stdout !== '') {
399
398
  throw new Error(`Extraneous files committed to Git:
400
399
  ${stdout}
@@ -410,15 +409,15 @@ async function noExtraneousFilesCommittedToGit() {
410
409
 
411
410
  var noExtraneousFilesCommittedToGit$1 = {
412
411
  __proto__: null,
413
- title: title$8,
412
+ title: title$7,
414
413
  'default': noExtraneousFilesCommittedToGit
415
414
  };
416
415
 
417
- const title$9 = 'No secrets committed to Git';
416
+ const title$8 = 'No secrets committed to Git';
418
417
  async function noSecretsCommittedToGit() {
419
418
  const {
420
419
  stdout
421
- } = await execaCommand('git ls-files .env .env*.local');
420
+ } = await execa`git ls-files .env .env*.local`;
422
421
  if (stdout !== '') {
423
422
  throw new Error(`Secrets committed to Git 😱:
424
423
  ${stdout}
@@ -440,15 +439,15 @@ async function noSecretsCommittedToGit() {
440
439
 
441
440
  var noSecretsCommittedToGit$1 = {
442
441
  __proto__: null,
443
- title: title$9,
442
+ title: title$8,
444
443
  'default': noSecretsCommittedToGit
445
444
  };
446
445
 
447
- const title$a = 'Preflight is latest version';
446
+ const title$9 = 'Preflight is latest version';
448
447
  async function preflightIsLatestVersion() {
449
448
  const {
450
449
  stdout: remoteVersion
451
- } = await execaCommand('npm show @upleveled/preflight version');
450
+ } = await execa`npm show @upleveled/preflight version`;
452
451
  if (semver.gt(remoteVersion, preflightPackageJson.version)) {
453
452
  throw new Error(`Your current version of Preflight (${preflightPackageJson.version}) is older than the latest version ${remoteVersion} - upgrade with:
454
453
 
@@ -459,14 +458,18 @@ async function preflightIsLatestVersion() {
459
458
 
460
459
  var preflightIsLatestVersion$1 = {
461
460
  __proto__: null,
462
- title: title$a,
461
+ title: title$9,
463
462
  'default': preflightIsLatestVersion
464
463
  };
465
464
 
466
- const title$b = 'Prettier';
465
+ const title$a = 'Prettier';
467
466
  async function prettierCheck() {
468
467
  try {
469
- await execaCommand('pnpm prettier "**/*.{js,jsx,ts,tsx,css,scss,sql}" --list-different --end-of-line auto');
468
+ await execa({
469
+ // Execute binaries in ./node_modules/.bin to avoid pnpm overhead
470
+ // https://github.com/sindresorhus/execa/blob/main/docs/environment.md#local-binaries
471
+ preferLocal: true
472
+ })`prettier "**/*.{js,jsx,ts,tsx,css,scss,sql}" --list-different --end-of-line auto`;
470
473
  } catch (error) {
471
474
  const {
472
475
  stdout,
@@ -488,11 +491,11 @@ async function prettierCheck() {
488
491
 
489
492
  var prettier = {
490
493
  __proto__: null,
491
- title: title$b,
494
+ title: title$a,
492
495
  'default': prettierCheck
493
496
  };
494
497
 
495
- const title$c = 'Project folder name matches correct format';
498
+ const title$b = 'Project folder name matches correct format';
496
499
  function projectFolderNameMatchesCorrectFormat() {
497
500
  const currentDirectoryName = path.basename(process.cwd());
498
501
  const lowercaseHyphenedDirectoryName = currentDirectoryName.toLowerCase().replaceAll(' ', '-');
@@ -510,15 +513,19 @@ function projectFolderNameMatchesCorrectFormat() {
510
513
 
511
514
  var projectFolderNameMatchesCorrectFormat$1 = {
512
515
  __proto__: null,
513
- title: title$c,
516
+ title: title$b,
514
517
  'default': projectFolderNameMatchesCorrectFormat
515
518
  };
516
519
 
517
520
  const supportedStylelintFileExtensions = ['css', 'sass', 'scss', 'less', 'js', 'tsx', 'jsx'];
518
- const title$d = 'Stylelint';
521
+ const title$c = 'Stylelint';
519
522
  async function stylelintCheck() {
520
523
  try {
521
- await execaCommand(`pnpm stylelint **/*.{${supportedStylelintFileExtensions.join(',')}} --max-warnings 0 --formatter json`);
524
+ await execa({
525
+ // Execute binaries in ./node_modules/.bin to avoid pnpm overhead
526
+ // https://github.com/sindresorhus/execa/blob/main/docs/environment.md#local-binaries
527
+ preferLocal: true
528
+ })`stylelint **/*.{${supportedStylelintFileExtensions.join(',')}} --max-warnings 0 --formatter json`;
522
529
  } catch (error) {
523
530
  const {
524
531
  stdout
@@ -526,7 +533,7 @@ async function stylelintCheck() {
526
533
  let stylelintResults;
527
534
  try {
528
535
  stylelintResults = JSON.parse(stdout).filter(stylelintResult => stylelintResult.errored === true);
529
- } catch (parseError) {
536
+ } catch {
530
537
  throw error;
531
538
  }
532
539
  if (stylelintResults.length < 1 || !stylelintResults.every(result => 'errored' in result)) {
@@ -557,21 +564,23 @@ async function stylelintCheck() {
557
564
  var stylelint = {
558
565
  __proto__: null,
559
566
  supportedStylelintFileExtensions: supportedStylelintFileExtensions,
560
- title: title$d,
567
+ title: title$c,
561
568
  'default': stylelintCheck
562
569
  };
563
570
 
564
571
  const require$2 = /*#__PURE__*/createRequire(`${/*#__PURE__*/process.cwd()}/`);
565
- const title$e = 'Stylelint config is latest version';
572
+ const title$d = 'Stylelint config is latest version';
566
573
  async function stylelintConfigIsValid() {
567
574
  const {
568
575
  stdout: remoteVersion
569
- } = await execaCommand('npm show stylelint-config-upleveled version');
576
+ } = await execa`npm show stylelint-config-upleveled version`;
570
577
  let localVersion;
571
578
  try {
572
579
  const stylelintConfigPackageJsonPath = require$2.resolve('stylelint-config-upleveled/package.json');
573
580
  localVersion = JSON.parse(await promises.readFile(stylelintConfigPackageJsonPath, 'utf-8')).version;
574
- } catch (error) {}
581
+ } catch {
582
+ // Swallow error
583
+ }
575
584
  if (typeof localVersion === 'undefined') {
576
585
  throw new Error(`The UpLeveled Stylelint Config has not been installed - please install using the instructions on https://www.npmjs.com/package/eslint-config-upleveled
577
586
  `);
@@ -589,7 +598,7 @@ const config = {
589
598
  };
590
599
 
591
600
  export default config;`;
592
- } catch (error) {
601
+ } catch {
593
602
  throw new Error(`Error reading your stylelint.config.js file - please delete the file if it exists and reinstall the config using the instructions on https://www.npmjs.com/package/eslint-config-upleveled
594
603
  `);
595
604
  }
@@ -620,15 +629,15 @@ export default config;`;
620
629
 
621
630
  var stylelintConfigIsValid$1 = {
622
631
  __proto__: null,
623
- title: title$e,
632
+ title: title$d,
624
633
  'default': stylelintConfigIsValid
625
634
  };
626
635
 
627
- const title$f = 'Use single package manager';
636
+ const title$e = 'Use single package manager';
628
637
  async function useSinglePackageManager() {
629
638
  const {
630
639
  stdout
631
- } = await execaCommand('git ls-files package-lock.json yarn.lock');
640
+ } = await execa`git ls-files package-lock.json yarn.lock`;
632
641
  if (stdout !== '') {
633
642
  throw new Error(`package-lock.json or yarn.lock file committed to Git. Remove it with:
634
643
 
@@ -647,7 +656,7 @@ async function useSinglePackageManager() {
647
656
 
648
657
  var useSinglePackageManager$1 = {
649
658
  __proto__: null,
650
- title: title$f,
659
+ title: title$e,
651
660
  'default': useSinglePackageManager
652
661
  };
653
662
 
@@ -665,14 +674,11 @@ projectFolderNameMatchesCorrectFormat$1,
665
674
  // Dependencies
666
675
  {
667
676
  title: 'No dependency problems',
668
- task: (ctx, task) => task.newListr([...(!Object.keys(projectDependencies).includes('next') ? [] : [{
669
- title: title$5,
670
- task: nextJsProjectHasSharpInstalled
671
- }]), {
672
- title: title$7,
677
+ task: (ctx, task) => task.newListr([{
678
+ title: title$6,
673
679
  task: noUnusedAndMissingDependencies
674
680
  }, {
675
- title: title$6,
681
+ title: title$5,
676
682
  task: noDependenciesWithoutTypes
677
683
  }])
678
684
  },
@@ -1 +1 @@
1
- {"version":3,"file":"preflight.esm.js","sources":["../src/util/commandExample.ts","../src/util/drone.ts","../src/checks/allChangesCommittedToGit.ts","../src/checks/eslint.ts","../src/checks/eslintConfigIsValid.ts","../src/util/randomUserAgent.ts","../src/checks/linkOnGithubAbout.ts","../src/util/crossPlatform.ts","../src/checks/nodeModulesIgnoredFromGit.ts","../src/util/packageJson.ts","../src/checks/noDependencyProblems/nextJsProjectHasSharpInstalled.ts","../src/checks/noDependencyProblems/noDependenciesWithoutTypes.ts","../src/util/preflightBinPath.ts","../src/checks/noDependencyProblems/noUnusedDependencies.ts","../src/checks/noExtraneousFilesCommittedToGit.ts","../src/checks/noSecretsCommittedToGit.ts","../src/checks/preflightIsLatestVersion.ts","../src/checks/prettier.ts","../src/checks/projectFolderNameMatchesCorrectFormat.ts","../src/checks/stylelint.ts","../src/checks/stylelintConfigIsValid.ts","../src/checks/useSinglePackageManager.ts","../src/index.ts"],"sourcesContent":["import chalk from 'chalk';\n\n// https://www.compart.com/en/unicode/U+2800\n// eslint-disable-next-line security/detect-bidi-characters -- Intentional use of unusual character for formatting\nconst emptyBrailleCharacter = '‎';\n\nexport function commandExample(command: string) {\n return `${emptyBrailleCharacter} ${chalk.dim('$')} ${command}`;\n}\n","import { execaCommand } from 'execa';\n\nexport async function isDrone() {\n const { stdout } = await execaCommand('cat /etc/os-release', {\n reject: false,\n });\n return /Alpine Linux/.test(stdout);\n}\n","import { promises as fs } from 'node:fs';\nimport { execaCommand } from 'execa';\nimport { commandExample } from '../util/commandExample';\nimport { isDrone } from '../util/drone';\n\nexport const title = 'All changes committed to Git';\n\nexport default async function allChangesCommittedToGit() {\n const { stdout: replSlug } = await execaCommand('echo $REPL_SLUG');\n\n const isRunningInReplIt = replSlug !== '';\n\n if (isRunningInReplIt) {\n await fs.writeFile('.git/info/exclude', '.replit\\n');\n }\n\n const { stdout } = await execaCommand('git status --porcelain');\n\n if (stdout !== '') {\n const onlyPnpmLockModifiedOnDrone =\n stdout.trim() === 'M pnpm-lock.yaml' && (await isDrone());\n throw new Error(\n `Some changes have not been committed to Git:\n ${stdout}${\n onlyPnpmLockModifiedOnDrone\n ? `\n\n The only file with changes is the pnpm-lock.yaml file, indicating that npm was incorrectly used in addition to pnpm (eg. an \"npm install\" command was run). To fix this, force regeneration of the pnpm-lock.yaml file locally with the following command and then commit the changes:\n\n ${commandExample('pnpm install --force')}`\n : ''\n }\n `,\n );\n }\n}\n","import { sep } from 'node:path';\nimport { ESLint } from 'eslint';\nimport { execaCommand } from 'execa';\n\nexport const title = 'ESLint';\n\nexport default async function eslintCheck() {\n try {\n await execaCommand('pnpm eslint . --max-warnings 0 --format json');\n } catch (error) {\n const { stdout } = error as { stdout: string };\n\n let eslintResults;\n\n try {\n eslintResults = (JSON.parse(stdout) as ESLint.LintResult[])\n // Filter out results with no problems, which the ESLint CLI\n // still reports with the `--format json` flag\n .filter((eslintResult) => {\n return eslintResult.errorCount > 0 || eslintResult.warningCount > 0;\n });\n } catch (parseError) {\n throw error;\n }\n\n if (\n eslintResults.length < 1 ||\n !eslintResults.every(\n (result) => 'errorCount' in result && 'warningCount' in result,\n )\n ) {\n throw new Error(\n `Unexpected shape of ESLint JSON related to .errorCount and .warningCount properties - please report this to the UpLeveled engineering team, including the following output:\n ${stdout}\n `,\n );\n }\n\n throw new Error(\n `ESLint problems found in the following files:\n ${eslintResults\n // Make paths relative to the project:\n //\n // Before:\n // macOS / Linux: /home/projects/next-student-project/app/api/hello/route.js\n // Windows: C:\\Users\\Lukas\\projects\\next-student-project\\app\\api\\hello\\route.js\n //\n // After:\n // macOS / Linux: app/api/hello/route.js\n // Windows: app\\api\\hello\\route.js\n .map(({ filePath }) => filePath.replace(`${process.cwd()}${sep}`, ''))\n .join('\\n')}\n\n Open these files in your editor - there should be problems to fix\n `,\n );\n }\n}\n","import { promises as fs } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { execaCommand } from 'execa';\nimport readdirp from 'readdirp';\nimport semver from 'semver';\n\nconst require = createRequire(`${process.cwd()}/`);\n\nexport const title = 'ESLint config is latest version';\n\nexport default async function eslintConfigIsValid() {\n const { stdout: remoteVersion } = await execaCommand(\n 'npm show eslint-config-upleveled version',\n );\n\n let localVersion: string | undefined;\n\n try {\n const eslintConfigPackageJsonPath = require.resolve(\n 'eslint-config-upleveled/package.json',\n );\n\n localVersion = JSON.parse(\n await fs.readFile(eslintConfigPackageJsonPath, 'utf-8'),\n ).version;\n } catch (error) {}\n\n if (typeof localVersion === 'undefined') {\n throw new Error(\n `The UpLeveled ESLint Config has not been installed - please install using the instructions on https://www.npmjs.com/package/eslint-config-upleveled\n `,\n );\n }\n\n if (semver.gt(remoteVersion, localVersion)) {\n throw new Error(\n `Your current version of the UpLeveled ESLint Config (${localVersion}) is older than the latest version ${remoteVersion} - upgrade by running all lines of the install instructions on https://www.npmjs.com/package/eslint-config-upleveled\n `,\n );\n }\n\n let eslintConfigMatches;\n\n try {\n eslintConfigMatches =\n (await fs.readFile('./eslint.config.js', 'utf-8')).trim() ===\n \"export { default } from 'eslint-config-upleveled';\";\n } catch (error) {\n throw new Error(\n `Error reading your eslint.config.js file - please delete the file if it exists and reinstall the config using the instructions on https://www.npmjs.com/package/eslint-config-upleveled\n `,\n );\n }\n\n if (!eslintConfigMatches) {\n throw new Error(\n `Your eslint.config.js file does not match the configuration file template - please delete the file and reinstall the config using the instructions on https://www.npmjs.com/package/eslint-config-upleveled\n `,\n );\n }\n\n const eslintDisableOccurrences = [];\n\n for await (const { path } of readdirp('.', {\n directoryFilter: ['!.git', '!.next', '!node_modules'],\n fileFilter: ['*.js', '*.jsx', '*.ts', '*.tsx'],\n })) {\n const fileContents = await fs.readFile(path, 'utf-8');\n if (/eslint-disable|eslint [a-z0-9@/-]+: (0|off)/.test(fileContents)) {\n eslintDisableOccurrences.push(path);\n }\n }\n\n if (eslintDisableOccurrences.length > 0) {\n throw new Error(\n `ESLint has been disabled in the following files:\n ${eslintDisableOccurrences.join('\\n')}\n\n Remove all comments disabling or modifying ESLint rule configuration (eg. eslint-disable and eslint-disable-next-line comments) and fix the problems\n `,\n );\n }\n}\n","import userAgents from 'top-user-agents';\n\nexport function randomUserAgent() {\n const randomIndex = Math.floor(Math.random() * (userAgents.length - 1));\n return userAgents[randomIndex]!;\n}\n","import cheerio from 'cheerio';\nimport type { Element } from 'domhandler';\nimport { execaCommand } from 'execa';\nimport fetch from 'node-fetch';\nimport { randomUserAgent } from '../util/randomUserAgent';\n\nexport const title = 'GitHub repo has deployed project link under About';\n\nexport default async function linkOnGithubAbout() {\n const { stdout } = await execaCommand('git remote get-url origin');\n\n const repoUrl = stdout\n .replace('git@github.com:', 'https://github.com/')\n .replace('.git', '');\n\n const html = await (await fetch(repoUrl)).text();\n\n const $ = cheerio.load(html);\n\n const urlInAboutSection = $('h2')\n .filter(function (this: Element) {\n return $(this).text().trim() === 'About';\n })\n .nextAll('div')\n .filter(function (this: Element) {\n return $(this).children('.octicon.octicon-link').length > 0;\n })\n .children('.octicon.octicon-link')\n .next()\n .children('a[href]')\n .attr('href');\n\n if (!urlInAboutSection) {\n throw new Error(\n `Deployed project link not found in About section on ${repoUrl}. Click on the cog symbol to the right of the About heading and paste the Repl.it / Netlify / Fly.io link in the Website box.`,\n );\n }\n\n const response = await fetch(urlInAboutSection, {\n headers: {\n // For repl.it\n 'user-agent': randomUserAgent(),\n },\n });\n\n if (!response.ok) {\n throw new Error(\n `Project link in About section on ${repoUrl} is not returning a proper status code: the link returns status code ${response.status} (${response.statusText}).`,\n );\n }\n}\n","const CRLF = '\\r\\n';\n\nexport function normalizeNewlines(input: string) {\n if (typeof input !== 'string') {\n throw new TypeError(`Expected a \\`string\\`, got \\`${typeof input}\\``);\n }\n\n return input.replace(new RegExp(CRLF, 'g'), '\\n');\n}\n","import { promises as fs } from 'node:fs';\nimport { execaCommand } from 'execa';\nimport { commandExample } from '../util/commandExample';\nimport { normalizeNewlines } from '../util/crossPlatform';\n\nexport const title = 'node_modules/ folder ignored in Git';\n\nexport default async function nodeModulesIgnoredFromGit() {\n if ((await execaCommand('git ls-files node_modules/')).stdout !== '') {\n throw new Error(\n `node_modules/ folder committed to Git. Remove it using:\n\n ${commandExample('git rm -r --cached node_modules')}\n `,\n );\n }\n\n if ((await execaCommand('git ls-files .gitignore')).stdout !== '.gitignore') {\n throw new Error('.gitignore file not found');\n }\n\n const nodeModulesInGitignore = normalizeNewlines(\n await fs.readFile('./.gitignore', 'utf8'),\n )\n .split('\\n')\n .reduce((found, line) => found || /^\\/?node_modules\\/?$/.test(line), false);\n\n if (!nodeModulesInGitignore) {\n throw new Error('node_modules not found in .gitignore');\n }\n}\n","import { promises as fs } from 'node:fs';\nimport { URL } from 'node:url';\n\ntype PackageJson = {\n name: string;\n version: string;\n description?: string;\n keywords?: string;\n homepage?: string;\n bugs?: {\n email?: string;\n url?: string;\n };\n license?: string;\n author?:\n | string\n | {\n name: string;\n email?: string;\n url?: string;\n };\n contributors?:\n | string[]\n | {\n name: string;\n email?: string;\n url?: string;\n }[];\n files?: string[];\n main?: string;\n browser?: string;\n bin?: Record<string, string>;\n man?: string;\n directories?: {\n lib?: string;\n bin?: string;\n man?: string;\n doc?: string;\n example?: string;\n test?: string;\n };\n repository?: {\n type?: 'git';\n url?: string;\n directory?: string;\n };\n scripts?: Record<string, string>;\n config?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n optionalDependencies?: Record<string, string>;\n bundledDependencies?: string[];\n engines?: Record<string, string>;\n os?: string[];\n cpu?: string[];\n};\n\nexport const projectPackageJson = JSON.parse(\n await fs.readFile('package.json', 'utf-8'),\n) as PackageJson;\n\nexport const preflightPackageJson = JSON.parse(\n await fs.readFile(new URL('../package.json', import.meta.url), 'utf-8'),\n) as PackageJson;\n","import { commandExample } from '../../util/commandExample';\nimport { projectPackageJson } from '../../util/packageJson';\n\nexport const title = 'Next.js project has sharp installed';\n\nexport default function nextJsProjectHasSharpInstalled() {\n const dependenciesPackageNames = Object.keys(\n projectPackageJson.dependencies || {},\n );\n if (\n dependenciesPackageNames.includes('next') &&\n !dependenciesPackageNames.includes('sharp')\n ) {\n throw new Error(\n `Next.js projects should have sharp installed for better image optimization. Install it with:\n\n ${commandExample('pnpm add sharp')}\n `,\n );\n }\n}\n","import { existsSync, promises as fs } from 'node:fs';\nimport algoliasearch from 'algoliasearch';\nimport pReduce from 'p-reduce';\nimport { commandExample } from '../../util/commandExample';\nimport { projectPackageJson } from '../../util/packageJson';\n\nconst client = algoliasearch(\n // Application ID and API key specific to UpLeveled\n // Preflight. Please don't use anywhere else without\n // asking Algolia's permission.\n 'OFCNCOG2CU', // Application ID\n 'ec73550aa8b2936dab436d4e02144784', // API Key\n);\nconst index = client.initIndex('npm-search');\n\ninterface AlgoliaObj {\n types?: {\n definitelyTyped?: string;\n };\n}\n\nexport const title = 'No dependencies without types';\n\n// This is a naive check for matching @types/<pkg name> packages\n// that the student hasn't yet installed. It is not intended to\n// be an exhaustive check for any types for all packages.\n//\n// It attempts to address scenarios such as this with\n// `styled-components`:\n//\n// https://learn.upleveled.io/courses/btcmp-l-webfs-gen-0/modules/122-cheatsheet-css-in-js/#eslint-errors-with-styled-components\nexport default async function noDependenciesWithoutTypes() {\n const dependenciesWithMissingTypes = await pReduce(\n Object.keys(projectPackageJson.dependencies || {}),\n async (filteredDependencies: [string, string][], dependency: string) => {\n try {\n const packageJsonPath = require.resolve(`${dependency}/package.json`);\n\n const modulePackageJson = JSON.parse(\n await fs.readFile(packageJsonPath, 'utf-8'),\n );\n\n // If the keys \"types\" or \"typings\" are in the module's `package.json`, bail out\n if ('types' in modulePackageJson || 'typings' in modulePackageJson) {\n return filteredDependencies;\n }\n } catch (error) {}\n\n let indexDTsPath;\n\n try {\n indexDTsPath = require.resolve(`${dependency}/index.d.ts`);\n } catch (error) {}\n\n // If the index.d.ts file exists inside the module's directory, bail out\n if (indexDTsPath && existsSync(indexDTsPath)) {\n return filteredDependencies;\n }\n\n let results: AlgoliaObj;\n\n try {\n results = await index.getObject<AlgoliaObj>(dependency, {\n attributesToRetrieve: ['types'],\n });\n } catch (error) {\n // Show dependency name if Algolia's `index.getObject()` throws with an\n // error message (such as the error message \"ObjectID does not exist\"\n // when a package cannot be found in the index)\n throw new Error(\n `Algolia error for \\`${dependency}\\`: ${(error as Error).message}`,\n );\n }\n\n const definitelyTypedPackageName = results.types?.definitelyTyped;\n\n if (definitelyTypedPackageName) {\n // If a matching `@types/<package name>` has been already installed in devDependencies, bail out\n if (\n Object.keys(projectPackageJson.devDependencies || {}).includes(\n definitelyTypedPackageName,\n )\n ) {\n return filteredDependencies;\n }\n\n filteredDependencies.push([dependency, definitelyTypedPackageName]);\n }\n\n return filteredDependencies;\n },\n [],\n );\n\n if (dependenciesWithMissingTypes.length > 0) {\n throw new Error(\n `Dependencies found without types. Add the missing types with:\n\n ${commandExample(\n `pnpm add --save-dev ${dependenciesWithMissingTypes\n .map(([, definitelyTypedPackageName]) => definitelyTypedPackageName)\n .join(' ')}`,\n )}\n\n If the dependencies above are already in your package.json, check that they have not been incorrectly installed as regular dependencies in the \"dependencies\" object - they should be installed inside \"devDependencies\" (using the --save-dev flag mentioned above). To fix this situation, remove the dependencies and run the command above exactly.\n `,\n );\n }\n}\n","import { dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { execaCommand } from 'execa';\n\nexport const { stdout: preflightBinPath } = await execaCommand(`pnpm bin`, {\n cwd: dirname(fileURLToPath(import.meta.url)),\n});\n","import { execaCommand } from 'execa';\nimport { commandExample } from '../../util/commandExample';\nimport { preflightBinPath } from '../../util/preflightBinPath';\n\nexport const title = 'No unused dependencies';\n\nexport default async function noUnusedAndMissingDependencies() {\n const ignoredPackagePatterns = [\n // Unused dependency detected in https://github.com/upleveled/next-portfolio-dev\n '@graphql-codegen/cli',\n\n // Tailwind CSS\n '@tailwindcss/jit',\n 'autoprefixer',\n 'postcss',\n 'tailwindcss',\n\n // Sass (eg. in Next.js)\n 'sass',\n\n // Prettier and plugins\n 'prettier',\n 'prettier-plugin-*',\n\n // ESLint configuration\n '@ts-safeql/eslint-plugin',\n 'libpg-query',\n\n // TODO: Remove this once depcheck issue is fixed:\n // PR: https://github.com/depcheck/depcheck/pull/790\n // Issue: https://github.com/depcheck/depcheck/issues/791\n //\n // Stylelint configuration\n 'stylelint',\n 'stylelint-config-upleveled',\n\n // Testing\n '@testing-library/user-event',\n 'jest',\n 'jest-environment-jsdom',\n 'playwright',\n\n // `expect` required for proper types with `@testing-library/jest-dom` with `@jest/globals` and pnpm\n // https://github.com/testing-library/jest-dom/issues/123#issuecomment-1536828385\n // TODO: Remove when we switch from Jest to Vitest\n 'expect',\n\n // `ts-node` required for jest.config.ts\n // https://jestjs.io/docs/29.6/configuration#:~:text=To%20read%20TypeScript%20configuration%20files%20Jest%20requires%20ts%2Dnode.%20Make%20sure%20it%20is%20installed%20in%20your%20project\n // TODO: Remove when usage of tsx is allowed\n // https://github.com/jestjs/jest/issues/11989\n 'ts-node',\n\n // TypeScript\n 'typescript',\n '@types/*',\n 'tsx',\n\n // Next.js\n 'sharp',\n ].join(',');\n\n try {\n await execaCommand(\n `${preflightBinPath}/depcheck --ignores=\"${ignoredPackagePatterns}\"`,\n );\n } catch (error) {\n const { stdout } = error as { stdout: string };\n if (\n !stdout.startsWith('Unused dependencies') &&\n !stdout.startsWith('Unused devDependencies') &&\n !stdout.startsWith('Missing dependencies')\n ) {\n throw error;\n }\n\n const [unusedDependenciesStdout, missingDependenciesStdout] = stdout.split(\n 'Missing dependencies',\n );\n\n const messages = [];\n\n if (unusedDependenciesStdout) {\n messages.push(`Unused dependencies found:\n ${unusedDependenciesStdout\n .split('\\n')\n .filter((str: string) => str.includes('* '))\n .join('\\n')}\n\n Remove these dependencies by running the following command for each dependency:\n\n ${commandExample('pnpm remove <dependency name here>')}\n `);\n }\n\n if (missingDependenciesStdout) {\n messages.push(`Missing dependencies found:\n ${missingDependenciesStdout\n .split('\\n')\n .filter((str: string) => str.includes('* '))\n .join('\\n')}\n\n Add these missing dependencies by running the following command for each dependency:\n\n ${commandExample('pnpm add <dependency name here>')}\n `);\n }\n\n if (messages.length > 0) throw new Error(messages.join('\\n\\n'));\n }\n}\n","import { execaCommand } from 'execa';\nimport { commandExample } from '../util/commandExample';\n\nexport const title = 'No extraneous files committed to Git';\n\nexport default async function noExtraneousFilesCommittedToGit() {\n const { stdout } = await execaCommand(\n 'git ls-files .DS_Store yarn-error.log npm-debug.log',\n );\n\n if (stdout !== '') {\n throw new Error(\n `Extraneous files committed to Git:\n ${stdout}\n\n Remove these files from your repo by running the following command for each file:\n\n ${commandExample('git rm --cached <filename here>')}\n\n Once you've removed all files, make sure that it doesn't happen again by adding the filenames above to your .gitignore file.\n `,\n );\n }\n}\n","import { execaCommand } from 'execa';\nimport { commandExample } from '../util/commandExample';\n\nexport const title = 'No secrets committed to Git';\n\nexport default async function noSecretsCommittedToGit() {\n const { stdout } = await execaCommand('git ls-files .env .env*.local');\n\n if (stdout !== '') {\n throw new Error(\n `Secrets committed to Git 😱:\n ${stdout}\n\n Remove these files from your repo by installing BFG from the System Setup Guide (see Optional Software at the bottom) and running it on each of your files like this:\n\n ${commandExample('bfg --delete-files <filename here>')}\n\n Once you've done this for every secret file, then force push to your repository:\n\n ${commandExample('git push --force')}\n\n More info: https://docs.github.com/en/github/authenticating-to-github/removing-sensitive-data-from-a-repository\n\n Finally, make sure that this doesn't happen again by adding the filenames above to your .gitignore file.\n `,\n );\n }\n}\n","import os from 'node:os';\nimport { execaCommand } from 'execa';\nimport semver from 'semver';\nimport { commandExample } from '../util/commandExample';\nimport { preflightPackageJson } from '../util/packageJson';\n\nexport const title = 'Preflight is latest version';\n\nexport default async function preflightIsLatestVersion() {\n const { stdout: remoteVersion } = await execaCommand(\n 'npm show @upleveled/preflight version',\n );\n\n if (semver.gt(remoteVersion, preflightPackageJson.version)) {\n throw new Error(\n `Your current version of Preflight (${\n preflightPackageJson.version\n }) is older than the latest version ${remoteVersion} - upgrade with:\n\n ${commandExample(\n `${\n os.platform() === 'linux' ? 'sudo ' : ''\n }pnpm add --global @upleveled/preflight`,\n )}\n `,\n );\n }\n}\n","import { execaCommand } from 'execa';\nimport { normalizeNewlines } from '../util/crossPlatform';\n\nexport const title = 'Prettier';\n\nexport default async function prettierCheck() {\n try {\n await execaCommand(\n 'pnpm prettier \"**/*.{js,jsx,ts,tsx,css,scss,sql}\" --list-different --end-of-line auto',\n );\n } catch (error) {\n const { stdout, stderr } = error as { stdout: string; stderr: string };\n\n if (!stdout || stderr) {\n throw error;\n }\n\n const unformattedFiles = normalizeNewlines(stdout).split('\\n');\n\n if (unformattedFiles.length > 0) {\n throw new Error(\n `Prettier has not been run in the following files:\n ${unformattedFiles.join('\\n')}\n\n For each of the files above, open the file in your editor and save the file. This will format the file with Prettier, which will cause changes to appear in Git.\n `,\n );\n }\n }\n}\n","import path from 'node:path';\nimport { commandExample } from '../util/commandExample';\n\nexport const title = 'Project folder name matches correct format';\n\nexport default function projectFolderNameMatchesCorrectFormat() {\n const currentDirectoryName = path.basename(process.cwd());\n const lowercaseHyphenedDirectoryName = currentDirectoryName\n .toLowerCase()\n .replaceAll(' ', '-');\n\n if (currentDirectoryName !== lowercaseHyphenedDirectoryName) {\n throw new Error(\n `Project directory name \"${currentDirectoryName}\" doesn't match the correct format (no spaces or uppercase letters).\n\n Rename the directory to the correct name \"${lowercaseHyphenedDirectoryName}\" with the following sequence of commands:\n\n ${commandExample('cd ..')}\n ${commandExample(\n `mv ${currentDirectoryName} ${lowercaseHyphenedDirectoryName}`,\n )}\n ${commandExample(`cd ${lowercaseHyphenedDirectoryName}`)}\n `,\n );\n }\n}\n","import { sep } from 'node:path';\nimport { execaCommand } from 'execa';\nimport { LintResult } from 'stylelint';\n\nexport const supportedStylelintFileExtensions = [\n 'css',\n 'sass',\n 'scss',\n 'less',\n 'js',\n 'tsx',\n 'jsx',\n];\n\nexport const title = 'Stylelint';\n\nexport default async function stylelintCheck() {\n try {\n await execaCommand(\n `pnpm stylelint **/*.{${supportedStylelintFileExtensions.join(\n ',',\n )}} --max-warnings 0 --formatter json`,\n );\n } catch (error) {\n const { stdout } = error as { stdout: string };\n\n let stylelintResults;\n\n try {\n stylelintResults = (JSON.parse(stdout) as LintResult[]).filter(\n (stylelintResult) => stylelintResult.errored === true,\n );\n } catch (parseError) {\n throw error;\n }\n\n if (\n stylelintResults.length < 1 ||\n !stylelintResults.every((result) => 'errored' in result)\n ) {\n throw new Error(\n `Unexpected shape of Stylelint JSON related to .errored properties - please report this to the UpLeveled engineering team, including the following output:\n ${stdout}\n `,\n );\n }\n\n throw new Error(\n `Stylelint problems found in the following files:\n ${stylelintResults\n // Make paths relative to the project:\n //\n // Before:\n // macOS / Linux: /home/projects/random-color-generator-react-app/src/index.css\n // Windows: C:\\Users\\Lukas\\projects\\random-color-generator-react-app\\src\\index.css\n //\n // After:\n // macOS / Linux: src/index.css\n // Windows: src\\index.css\n .map(({ source }) => source!.replace(`${process.cwd()}${sep}`, ''))\n .join('\\n')}\n\n Open these files in your editor - there should be problems to fix\n `,\n );\n }\n}\n","import { promises as fs } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { execaCommand } from 'execa';\nimport readdirp from 'readdirp';\nimport semver from 'semver';\nimport { supportedStylelintFileExtensions } from './stylelint';\n\nconst require = createRequire(`${process.cwd()}/`);\n\nexport const title = 'Stylelint config is latest version';\n\nexport default async function stylelintConfigIsValid() {\n const { stdout: remoteVersion } = await execaCommand(\n 'npm show stylelint-config-upleveled version',\n );\n\n let localVersion: string | undefined;\n\n try {\n const stylelintConfigPackageJsonPath = require.resolve(\n 'stylelint-config-upleveled/package.json',\n );\n\n localVersion = JSON.parse(\n await fs.readFile(stylelintConfigPackageJsonPath, 'utf-8'),\n ).version;\n } catch (error) {}\n\n if (typeof localVersion === 'undefined') {\n throw new Error(\n `The UpLeveled Stylelint Config has not been installed - please install using the instructions on https://www.npmjs.com/package/eslint-config-upleveled\n `,\n );\n }\n\n if (semver.gt(remoteVersion, localVersion)) {\n throw new Error(\n `Your current version of the UpLeveled Stylelint Config (${localVersion}) is older than the latest version ${remoteVersion} - upgrade by running:\n\n pnpm add stylelint-config-upleveled@${remoteVersion}`,\n );\n }\n\n let stylelintConfigMatches;\n\n try {\n stylelintConfigMatches =\n (await fs.readFile('./stylelint.config.js', 'utf-8')).trim() ===\n `/** @type {import('stylelint').Config} */\nconst config = {\n extends: ['stylelint-config-upleveled'],\n};\n\nexport default config;`;\n } catch (error) {\n throw new Error(\n `Error reading your stylelint.config.js file - please delete the file if it exists and reinstall the config using the instructions on https://www.npmjs.com/package/eslint-config-upleveled\n `,\n );\n }\n\n if (!stylelintConfigMatches) {\n throw new Error(\n `Your stylelint.config.js file does not match the configuration file template - please delete the file and reinstall the config using the instructions on https://www.npmjs.com/package/eslint-config-upleveled\n `,\n );\n }\n\n const stylelintDisableOccurrences = [];\n\n for await (const { path } of readdirp('.', {\n directoryFilter: ['!.git', '!.next', '!node_modules'],\n fileFilter: supportedStylelintFileExtensions.map(\n (fileExtension) => `*.${fileExtension}`,\n ),\n })) {\n const fileContents = await fs.readFile(path, 'utf-8');\n if (fileContents.includes('stylelint-disable')) {\n stylelintDisableOccurrences.push(path);\n }\n }\n\n if (stylelintDisableOccurrences.length > 0) {\n throw new Error(\n `Stylelint has been disabled in the following files:\n ${stylelintDisableOccurrences.join('\\n')}\n\n Remove all comments disabling or modifying Stylelint rule configuration (eg. stylelint-disable and stylelint-disable-next-line comments) and fix the problems\n `,\n );\n }\n}\n","import { execaCommand } from 'execa';\nimport { commandExample } from '../util/commandExample';\n\nexport const title = 'Use single package manager';\n\nexport default async function useSinglePackageManager() {\n const { stdout } = await execaCommand(\n 'git ls-files package-lock.json yarn.lock',\n );\n\n if (stdout !== '') {\n throw new Error(\n `package-lock.json or yarn.lock file committed to Git. Remove it with:\n\n ${commandExample('git rm --cached <filename>')}\n\n After you've removed it, you can delete the file with:\n\n ${commandExample('rm <filename>')}\n\n The presence of this file indicates that another package manager was used in addition to pnpm (eg. \"npm install\" or \"yarn add\" was run). In order to avoid issues with the state of the pnpm-lock.yaml file, we suggest also forcing regeneration this file with the following command:\n\n ${commandExample('pnpm install --force')}\n `,\n );\n }\n}\n","import { Listr, ListrTask } from 'listr2';\nimport * as allChangesCommittedToGit from './checks/allChangesCommittedToGit.js';\nimport * as eslint from './checks/eslint.js';\nimport * as eslintConfigIsValid from './checks/eslintConfigIsValid.js';\nimport * as linkOnGithubAbout from './checks/linkOnGithubAbout.js';\nimport * as nodeModulesIgnoredFromGit from './checks/nodeModulesIgnoredFromGit.js';\nimport * as nextJsProjectHasSharpInstalled from './checks/noDependencyProblems/nextJsProjectHasSharpInstalled.js';\nimport * as noDependenciesWithoutTypes from './checks/noDependencyProblems/noDependenciesWithoutTypes.js';\nimport * as noUnusedAndMissingDependencies from './checks/noDependencyProblems/noUnusedDependencies.js';\nimport * as noExtraneousFilesCommittedToGit from './checks/noExtraneousFilesCommittedToGit.js';\nimport * as noSecretsCommittedToGit from './checks/noSecretsCommittedToGit.js';\nimport * as preflightIsLatestVersion from './checks/preflightIsLatestVersion.js';\nimport * as prettier from './checks/prettier.js';\nimport * as projectFolderNameMatchesCorrectFormat from './checks/projectFolderNameMatchesCorrectFormat.js';\nimport * as stylelint from './checks/stylelint.js';\nimport * as stylelintConfigIsValid from './checks/stylelintConfigIsValid.js';\nimport * as useSinglePackageManager from './checks/useSinglePackageManager.js';\nimport { CtxParam } from './types/CtxParam.js';\nimport { TaskParam } from './types/TaskParam.js';\nimport {\n preflightPackageJson,\n projectPackageJson,\n} from './util/packageJson.js';\n\nconst projectDependencies = projectPackageJson.dependencies || {};\n\nconsole.log(`🚀 UpLeveled Preflight v${preflightPackageJson.version}`);\n\nconst listrTasks: ListrTask[] = [\n // ======= Sync Tasks =======\n // Git\n allChangesCommittedToGit,\n nodeModulesIgnoredFromGit,\n noExtraneousFilesCommittedToGit,\n noSecretsCommittedToGit,\n\n // Package managers\n useSinglePackageManager,\n\n // Project setup\n projectFolderNameMatchesCorrectFormat,\n\n // ======= Async Tasks =======\n // Dependencies\n {\n title: 'No dependency problems',\n task: (ctx: CtxParam, task: TaskParam): Listr =>\n task.newListr([\n ...(!Object.keys(projectDependencies).includes('next')\n ? []\n : [\n {\n title: nextJsProjectHasSharpInstalled.title,\n task: nextJsProjectHasSharpInstalled.default,\n },\n ]),\n {\n title: noUnusedAndMissingDependencies.title,\n task: noUnusedAndMissingDependencies.default,\n },\n {\n title: noDependenciesWithoutTypes.title,\n task: noDependenciesWithoutTypes.default,\n },\n ]),\n },\n\n // GitHub\n linkOnGithubAbout,\n\n // Linting\n eslint,\n ...(!(\n '@upleveled/react-scripts' in projectDependencies ||\n 'next' in projectDependencies\n )\n ? []\n : [stylelint]),\n prettier,\n\n // Version and configuration checks\n eslintConfigIsValid,\n ...(!(\n '@upleveled/react-scripts' in projectDependencies ||\n 'next' in projectDependencies\n )\n ? []\n : [stylelintConfigIsValid]),\n preflightIsLatestVersion,\n].map((module) => {\n if ('task' in module) return module;\n return {\n title: module.title,\n task: module.default,\n };\n});\n\nconst tasks = new Listr(listrTasks, {\n exitOnError: false,\n collectErrors: 'minimal',\n rendererOptions: {\n collapseErrors: false,\n removeEmptyLines: false,\n formatOutput: 'wrap',\n },\n fallbackRenderer: 'verbose',\n concurrent: 5,\n});\n\nawait tasks.run();\n\nif (tasks.errors.length > 0) {\n process.exit(1);\n}\n"],"names":["emptyBrailleCharacter","commandExample","command","chalk","dim","isDrone","stdout","execaCommand","reject","test","title","allChangesCommittedToGit","replSlug","isRunningInReplIt","fs","writeFile","onlyPnpmLockModifiedOnDrone","trim","Error","eslintCheck","error","eslintResults","JSON","parse","filter","eslintResult","errorCount","warningCount","parseError","length","every","result","map","filePath","replace","process","cwd","sep","join","require","createRequire","eslintConfigIsValid","remoteVersion","localVersion","eslintConfigPackageJsonPath","resolve","readFile","version","semver","gt","eslintConfigMatches","eslintDisableOccurrences","path","readdirp","directoryFilter","fileFilter","fileContents","push","randomUserAgent","randomIndex","Math","floor","random","userAgents","linkOnGithubAbout","repoUrl","html","fetch","text","$","cheerio","load","urlInAboutSection","nextAll","children","next","attr","response","headers","ok","status","statusText","CRLF","normalizeNewlines","input","TypeError","RegExp","nodeModulesIgnoredFromGit","nodeModulesInGitignore","split","reduce","found","line","projectPackageJson","preflightPackageJson","URL","import","meta","url","nextJsProjectHasSharpInstalled","dependenciesPackageNames","Object","keys","dependencies","includes","client","algoliasearch","index","initIndex","noDependenciesWithoutTypes","dependenciesWithMissingTypes","pReduce","filteredDependencies","dependency","packageJsonPath","modulePackageJson","indexDTsPath","existsSync","results","getObject","attributesToRetrieve","message","definitelyTypedPackageName","_results$types","types","definitelyTyped","devDependencies","preflightBinPath","dirname","fileURLToPath","noUnusedAndMissingDependencies","ignoredPackagePatterns","startsWith","unusedDependenciesStdout","missingDependenciesStdout","messages","str","noExtraneousFilesCommittedToGit","noSecretsCommittedToGit","preflightIsLatestVersion","os","platform","prettierCheck","stderr","unformattedFiles","projectFolderNameMatchesCorrectFormat","currentDirectoryName","basename","lowercaseHyphenedDirectoryName","toLowerCase","replaceAll","supportedStylelintFileExtensions","stylelintCheck","stylelintResults","stylelintResult","errored","source","stylelintConfigIsValid","stylelintConfigPackageJsonPath","stylelintConfigMatches","stylelintDisableOccurrences","fileExtension","useSinglePackageManager","projectDependencies","console","log","listrTasks","task","ctx","newListr","eslint","stylelint","prettier","module","default","tasks","Listr","exitOnError","collectErrors","rendererOptions","collapseErrors","removeEmptyLines","formatOutput","fallbackRenderer","concurrent","run","errors","exit"],"mappings":";;;;;;;;;;;;;;;;AAEA;AACA;AACA,MAAMA,qBAAqB,GAAG,GAAG;SAEjBC,cAAcA,CAACC,OAAe;EAC5C,UAAUF,0BAA0BG,KAAK,CAACC,GAAG,CAAC,GAAG,KAAKF,SAAS;AACjE;;ACNO,eAAeG,OAAOA;EAC3B,MAAM;IAAEC;GAAQ,GAAG,MAAMC,YAAY,CAAC,qBAAqB,EAAE;IAC3DC,MAAM,EAAE;GACT,CAAC;EACF,OAAO,cAAc,CAACC,IAAI,CAACH,MAAM,CAAC;AACpC;;ACFO,MAAMI,KAAK,GAAG,8BAA8B;AAEnD,AAAe,eAAeC,wBAAwBA;EACpD,MAAM;IAAEL,MAAM,EAAEM;GAAU,GAAG,MAAML,YAAY,CAAC,iBAAiB,CAAC;EAElE,MAAMM,iBAAiB,GAAGD,QAAQ,KAAK,EAAE;EAEzC,IAAIC,iBAAiB,EAAE;IACrB,MAAMC,QAAE,CAACC,SAAS,CAAC,mBAAmB,EAAE,WAAW,CAAC;;EAGtD,MAAM;IAAET;GAAQ,GAAG,MAAMC,YAAY,CAAC,wBAAwB,CAAC;EAE/D,IAAID,MAAM,KAAK,EAAE,EAAE;IACjB,MAAMU,2BAA2B,GAC/BV,MAAM,CAACW,IAAI,EAAE,KAAK,kBAAkB,KAAK,MAAMZ,OAAO,EAAE,CAAC;IAC3D,MAAM,IAAIa,KAAK;UAETZ,SACAU,2BAA2B;;;;UAK3Bf,cAAc,CAAC,sBAAsB,GAAG,GACpC;OAEP,CACF;;AAEL;;;;;;;;AC/BO,MAAMS,OAAK,GAAG,QAAQ;AAE7B,AAAe,eAAeS,WAAWA;EACvC,IAAI;IACF,MAAMZ,YAAY,CAAC,+CAA+C,CAAC;GACpE,CAAC,OAAOa,KAAK,EAAE;IACd,MAAM;MAAEd;KAAQ,GAAGc,KAA2B;IAE9C,IAAIC,aAAa;IAEjB,IAAI;MACFA,aAAa,GAAIC,IAAI,CAACC,KAAK,CAACjB,MAAM;;;OAG/BkB,MAAM,CAAEC,YAAY;QACnB,OAAOA,YAAY,CAACC,UAAU,GAAG,CAAC,IAAID,YAAY,CAACE,YAAY,GAAG,CAAC;OACpE,CAAC;KACL,CAAC,OAAOC,UAAU,EAAE;MACnB,MAAMR,KAAK;;IAGb,IACEC,aAAa,CAACQ,MAAM,GAAG,CAAC,IACxB,CAACR,aAAa,CAACS,KAAK,CACjBC,MAAM,IAAK,YAAY,IAAIA,MAAM,IAAI,cAAc,IAAIA,MAAM,CAC/D,EACD;MACA,MAAM,IAAIb,KAAK;YAETZ;SACH,CACF;;IAGH,MAAM,IAAIY,KAAK;UAETG;;;;;;;;;;KAUCW,GAAG,CAAC,CAAC;MAAEC;KAAU,KAAKA,QAAQ,CAACC,OAAO,IAAIC,OAAO,CAACC,GAAG,KAAKC,KAAK,EAAE,EAAE,CAAC,CAAC,CACrEC,IAAI,CAAC,IAAI;;;OAGb,CACF;;AAEL;;;;;;;;ACnDA,MAAMC,SAAO,gBAAGC,aAAa,iBAAIL,OAAO,CAACC,GAAG,KAAK,CAAC;AAElD,AAAO,MAAM1B,OAAK,GAAG,iCAAiC;AAEtD,AAAe,eAAe+B,mBAAmBA;EAC/C,MAAM;IAAEnC,MAAM,EAAEoC;GAAe,GAAG,MAAMnC,YAAY,CAClD,0CAA0C,CAC3C;EAED,IAAIoC,YAAgC;EAEpC,IAAI;IACF,MAAMC,2BAA2B,GAAGL,SAAO,CAACM,OAAO,CACjD,sCAAsC,CACvC;IAEDF,YAAY,GAAGrB,IAAI,CAACC,KAAK,CACvB,MAAMT,QAAE,CAACgC,QAAQ,CAACF,2BAA2B,EAAE,OAAO,CAAC,CACxD,CAACG,OAAO;GACV,CAAC,OAAO3B,KAAK,EAAE;EAEhB,IAAI,OAAOuB,YAAY,KAAK,WAAW,EAAE;IACvC,MAAM,IAAIzB,KAAK;OAEZ,CACF;;EAGH,IAAI8B,MAAM,CAACC,EAAE,CAACP,aAAa,EAAEC,YAAY,CAAC,EAAE;IAC1C,MAAM,IAAIzB,KAAK,yDAC2CyB,kDAAkDD;OACzG,CACF;;EAGH,IAAIQ,mBAAmB;EAEvB,IAAI;IACFA,mBAAmB,GACjB,CAAC,MAAMpC,QAAE,CAACgC,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC,EAAE7B,IAAI,EAAE,KACzD,oDAAoD;GACvD,CAAC,OAAOG,KAAK,EAAE;IACd,MAAM,IAAIF,KAAK;OAEZ,CACF;;EAGH,IAAI,CAACgC,mBAAmB,EAAE;IACxB,MAAM,IAAIhC,KAAK;OAEZ,CACF;;EAGH,MAAMiC,wBAAwB,GAAG,EAAE;EAEnC,WAAW,MAAM;IAAEC;GAAM,IAAIC,QAAQ,CAAC,GAAG,EAAE;IACzCC,eAAe,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,eAAe,CAAC;IACrDC,UAAU,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO;GAC9C,CAAC,EAAE;IACF,MAAMC,YAAY,GAAG,MAAM1C,QAAE,CAACgC,QAAQ,CAACM,IAAI,EAAE,OAAO,CAAC;IACrD,IAAI,6CAA6C,CAAC3C,IAAI,CAAC+C,YAAY,CAAC,EAAE;MACpEL,wBAAwB,CAACM,IAAI,CAACL,IAAI,CAAC;;;EAIvC,IAAID,wBAAwB,CAACtB,MAAM,GAAG,CAAC,EAAE;IACvC,MAAM,IAAIX,KAAK;UAETiC,wBAAwB,CAACb,IAAI,CAAC,IAAI;;;OAGrC,CACF;;AAEL;;;;;;;;SChFgBoB,eAAeA;EAC7B,MAAMC,WAAW,GAAGC,IAAI,CAACC,KAAK,CAACD,IAAI,CAACE,MAAM,EAAE,IAAIC,UAAU,CAAClC,MAAM,GAAG,CAAC,CAAC,CAAC;EACvE,OAAOkC,UAAU,CAACJ,WAAW,CAAE;AACjC;;ACCO,MAAMjD,OAAK,GAAG,mDAAmD;AAExE,AAAe,eAAesD,iBAAiBA;EAC7C,MAAM;IAAE1D;GAAQ,GAAG,MAAMC,YAAY,CAAC,2BAA2B,CAAC;EAElE,MAAM0D,OAAO,GAAG3D,MAAM,CACnB4B,OAAO,CAAC,iBAAiB,EAAE,qBAAqB,CAAC,CACjDA,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;EAEtB,MAAMgC,IAAI,GAAG,MAAM,CAAC,MAAMC,KAAK,CAACF,OAAO,CAAC,EAAEG,IAAI,EAAE;EAEhD,MAAMC,CAAC,GAAGC,OAAO,CAACC,IAAI,CAACL,IAAI,CAAC;EAE5B,MAAMM,iBAAiB,GAAGH,CAAC,CAAC,IAAI,CAAC,CAC9B7C,MAAM,CAAC;IACN,OAAO6C,CAAC,CAAC,IAAI,CAAC,CAACD,IAAI,EAAE,CAACnD,IAAI,EAAE,KAAK,OAAO;GACzC,CAAC,CACDwD,OAAO,CAAC,KAAK,CAAC,CACdjD,MAAM,CAAC;IACN,OAAO6C,CAAC,CAAC,IAAI,CAAC,CAACK,QAAQ,CAAC,uBAAuB,CAAC,CAAC7C,MAAM,GAAG,CAAC;GAC5D,CAAC,CACD6C,QAAQ,CAAC,uBAAuB,CAAC,CACjCC,IAAI,EAAE,CACND,QAAQ,CAAC,SAAS,CAAC,CACnBE,IAAI,CAAC,MAAM,CAAC;EAEf,IAAI,CAACJ,iBAAiB,EAAE;IACtB,MAAM,IAAItD,KAAK,wDAC0C+C,sIAAsI,CAC9L;;EAGH,MAAMY,QAAQ,GAAG,MAAMV,KAAK,CAACK,iBAAiB,EAAE;IAC9CM,OAAO,EAAE;;MAEP,YAAY,EAAEpB,eAAe;;GAEhC,CAAC;EAEF,IAAI,CAACmB,QAAQ,CAACE,EAAE,EAAE;IAChB,MAAM,IAAI7D,KAAK,qCACuB+C,+EAA+EY,QAAQ,CAACG,WAAWH,QAAQ,CAACI,cAAc,CAC/J;;AAEL;;;;;;;;AClDA,MAAMC,IAAI,GAAG,MAAM;AAEnB,SAAgBC,iBAAiBA,CAACC,KAAa;EAC7C,IAAI,OAAOA,KAAK,KAAK,QAAQ,EAAE;IAC7B,MAAM,IAAIC,SAAS,iCAAiC,OAAOD,SAAS,CAAC;;EAGvE,OAAOA,KAAK,CAAClD,OAAO,CAAC,IAAIoD,MAAM,CAACJ,IAAI,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC;AACnD;;ACHO,MAAMxE,OAAK,GAAG,qCAAqC;AAE1D,AAAe,eAAe6E,yBAAyBA;EACrD,IAAI,CAAC,MAAMhF,YAAY,CAAC,4BAA4B,CAAC,EAAED,MAAM,KAAK,EAAE,EAAE;IACpE,MAAM,IAAIY,KAAK;;UAGTjB,cAAc,CAAC,iCAAiC;OACnD,CACF;;EAGH,IAAI,CAAC,MAAMM,YAAY,CAAC,yBAAyB,CAAC,EAAED,MAAM,KAAK,YAAY,EAAE;IAC3E,MAAM,IAAIY,KAAK,CAAC,2BAA2B,CAAC;;EAG9C,MAAMsE,sBAAsB,GAAGL,iBAAiB,CAC9C,MAAMrE,QAAE,CAACgC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,CAC1C,CACE2C,KAAK,CAAC,IAAI,CAAC,CACXC,MAAM,CAAC,CAACC,KAAK,EAAEC,IAAI,KAAKD,KAAK,IAAI,sBAAsB,CAAClF,IAAI,CAACmF,IAAI,CAAC,EAAE,KAAK,CAAC;EAE7E,IAAI,CAACJ,sBAAsB,EAAE;IAC3B,MAAM,IAAItE,KAAK,CAAC,sCAAsC,CAAC;;AAE3D;;;;;;;;AC4BO,MAAM2E,kBAAkB,gBAAGvE,IAAI,CAACC,KAAK,CAC1C,mBAAMT,QAAE,CAACgC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC,CAC5B;AAEhB,AAAO,MAAMgD,oBAAoB,gBAAGxE,IAAI,CAACC,KAAK,CAC5C,mBAAMT,QAAE,CAACgC,QAAQ,eAAC,IAAIiD,GAAG,CAAC,iBAAiB,EAAEC,MAAM,CAACC,IAAI,CAACC,GAAG,CAAC,EAAE,OAAO,CAAC,CACzD;;AC7DT,MAAMxF,OAAK,GAAG,qCAAqC;AAE1D,SAAwByF,8BAA8BA;EACpD,MAAMC,wBAAwB,GAAGC,MAAM,CAACC,IAAI,CAC1CT,kBAAkB,CAACU,YAAY,IAAI,EAAE,CACtC;EACD,IACEH,wBAAwB,CAACI,QAAQ,CAAC,MAAM,CAAC,IACzC,CAACJ,wBAAwB,CAACI,QAAQ,CAAC,OAAO,CAAC,EAC3C;IACA,MAAM,IAAItF,KAAK;;UAGTjB,cAAc,CAAC,gBAAgB;OAClC,CACF;;AAEL;;ACdA,MAAMwG,MAAM,gBAAGC,aAAa;AAC1B;AACA;AACA;AACA,YAAY;AAAE;AACd,kCAAkC,CACnC;AACD,MAAMC,KAAK,gBAAGF,MAAM,CAACG,SAAS,CAAC,YAAY,CAAC;AAQ5C,AAAO,MAAMlG,OAAK,GAAG,+BAA+B;AAEpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,AAAe,eAAemG,0BAA0BA;EACtD,MAAMC,4BAA4B,GAAG,MAAMC,OAAO,CAChDV,MAAM,CAACC,IAAI,CAACT,kBAAkB,CAACU,YAAY,IAAI,EAAE,CAAC,EAClD,OAAOS,oBAAwC,EAAEC,UAAkB;;IACjE,IAAI;MACF,MAAMC,eAAe,GAAG3E,OAAO,CAACM,OAAO,IAAIoE,yBAAyB,CAAC;MAErE,MAAME,iBAAiB,GAAG7F,IAAI,CAACC,KAAK,CAClC,MAAMT,QAAE,CAACgC,QAAQ,CAACoE,eAAe,EAAE,OAAO,CAAC,CAC5C;;MAGD,IAAI,OAAO,IAAIC,iBAAiB,IAAI,SAAS,IAAIA,iBAAiB,EAAE;QAClE,OAAOH,oBAAoB;;KAE9B,CAAC,OAAO5F,KAAK,EAAE;IAEhB,IAAIgG,YAAY;IAEhB,IAAI;MACFA,YAAY,GAAG7E,OAAO,CAACM,OAAO,IAAIoE,uBAAuB,CAAC;KAC3D,CAAC,OAAO7F,KAAK,EAAE;;IAGhB,IAAIgG,YAAY,IAAIC,UAAU,CAACD,YAAY,CAAC,EAAE;MAC5C,OAAOJ,oBAAoB;;IAG7B,IAAIM,OAAmB;IAEvB,IAAI;MACFA,OAAO,GAAG,MAAMX,KAAK,CAACY,SAAS,CAAaN,UAAU,EAAE;QACtDO,oBAAoB,EAAE,CAAC,OAAO;OAC/B,CAAC;KACH,CAAC,OAAOpG,KAAK,EAAE;;;;MAId,MAAM,IAAIF,KAAK,wBACU+F,iBAAkB7F,KAAe,CAACqG,SAAS,CACnE;;IAGH,MAAMC,0BAA0B,IAAAC,cAAA,GAAGL,OAAO,CAACM,KAAK,qBAAbD,cAAA,CAAeE,eAAe;IAEjE,IAAIH,0BAA0B,EAAE;;MAE9B,IACErB,MAAM,CAACC,IAAI,CAACT,kBAAkB,CAACiC,eAAe,IAAI,EAAE,CAAC,CAACtB,QAAQ,CAC5DkB,0BAA0B,CAC3B,EACD;QACA,OAAOV,oBAAoB;;MAG7BA,oBAAoB,CAACvD,IAAI,CAAC,CAACwD,UAAU,EAAES,0BAA0B,CAAC,CAAC;;IAGrE,OAAOV,oBAAoB;GAC5B,EACD,EAAE,CACH;EAED,IAAIF,4BAA4B,CAACjF,MAAM,GAAG,CAAC,EAAE;IAC3C,MAAM,IAAIX,KAAK;;QAGXjB,cAAc,wBACS6G,4BAA4B,CAChD9E,GAAG,CAAC,CAAC,GAAG0F,0BAA0B,CAAC,KAAKA,0BAA0B,CAAC,CACnEpF,IAAI,CAAC,GAAG,GAAG;;;OAIf,CACF;;AAEL;;ACxGO,MAAM;EAAEhC,MAAM,EAAEyH;CAAkB,GAAG,mBAAMxH,YAAY,WAAW,EAAE;EACzE6B,GAAG,eAAE4F,OAAO,eAACC,aAAa,CAACjC,MAAM,CAACC,IAAI,CAACC,GAAG,CAAC;CAC5C,CAAC;;ACFK,MAAMxF,OAAK,GAAG,wBAAwB;AAE7C,AAAe,eAAewH,8BAA8BA;EAC1D,MAAMC,sBAAsB,GAAG;;EAE7B,sBAAsB;;EAGtB,kBAAkB,EAClB,cAAc,EACd,SAAS,EACT,aAAa;;EAGb,MAAM;;EAGN,UAAU,EACV,mBAAmB;;EAGnB,0BAA0B,EAC1B,aAAa;;;;;;EAOb,WAAW,EACX,4BAA4B;;EAG5B,6BAA6B,EAC7B,MAAM,EACN,wBAAwB,EACxB,YAAY;;;;EAKZ,QAAQ;;;;;EAMR,SAAS;;EAGT,YAAY,EACZ,UAAU,EACV,KAAK;;EAGL,OAAO,CACR,CAAC7F,IAAI,CAAC,GAAG,CAAC;EAEX,IAAI;IACF,MAAM/B,YAAY,IACbwH,wCAAwCI,yBAAyB,CACrE;GACF,CAAC,OAAO/G,KAAK,EAAE;IACd,MAAM;MAAEd;KAAQ,GAAGc,KAA2B;IAC9C,IACE,CAACd,MAAM,CAAC8H,UAAU,CAAC,qBAAqB,CAAC,IACzC,CAAC9H,MAAM,CAAC8H,UAAU,CAAC,wBAAwB,CAAC,IAC5C,CAAC9H,MAAM,CAAC8H,UAAU,CAAC,sBAAsB,CAAC,EAC1C;MACA,MAAMhH,KAAK;;IAGb,MAAM,CAACiH,wBAAwB,EAAEC,yBAAyB,CAAC,GAAGhI,MAAM,CAACmF,KAAK,CACxE,sBAAsB,CACvB;IAED,MAAM8C,QAAQ,GAAG,EAAE;IAEnB,IAAIF,wBAAwB,EAAE;MAC5BE,QAAQ,CAAC9E,IAAI;UACT4E,wBAAwB,CACvB5C,KAAK,CAAC,IAAI,CAAC,CACXjE,MAAM,CAAEgH,GAAW,IAAKA,GAAG,CAAChC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAC3ClE,IAAI,CAAC,IAAI;;;;UAIVrC,cAAc,CAAC,oCAAoC;OACtD,CAAC;;IAGJ,IAAIqI,yBAAyB,EAAE;MAC7BC,QAAQ,CAAC9E,IAAI;UACT6E,yBAAyB,CACxB7C,KAAK,CAAC,IAAI,CAAC,CACXjE,MAAM,CAAEgH,GAAW,IAAKA,GAAG,CAAChC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAC3ClE,IAAI,CAAC,IAAI;;;;UAIVrC,cAAc,CAAC,iCAAiC;OACnD,CAAC;;IAGJ,IAAIsI,QAAQ,CAAC1G,MAAM,GAAG,CAAC,EAAE,MAAM,IAAIX,KAAK,CAACqH,QAAQ,CAACjG,IAAI,CAAC,MAAM,CAAC,CAAC;;AAEnE;;AC3GO,MAAM5B,OAAK,GAAG,sCAAsC;AAE3D,AAAe,eAAe+H,+BAA+BA;EAC3D,MAAM;IAAEnI;GAAQ,GAAG,MAAMC,YAAY,CACnC,qDAAqD,CACtD;EAED,IAAID,MAAM,KAAK,EAAE,EAAE;IACjB,MAAM,IAAIY,KAAK;UAETZ;;;;UAIAL,cAAc,CAAC,iCAAiC;;;OAGnD,CACF;;AAEL;;;;;;;;ACpBO,MAAMS,OAAK,GAAG,6BAA6B;AAElD,AAAe,eAAegI,uBAAuBA;EACnD,MAAM;IAAEpI;GAAQ,GAAG,MAAMC,YAAY,CAAC,+BAA+B,CAAC;EAEtE,IAAID,MAAM,KAAK,EAAE,EAAE;IACjB,MAAM,IAAIY,KAAK;UAETZ;;;;UAIAL,cAAc,CAAC,oCAAoC;;;;UAInDA,cAAc,CAAC,kBAAkB;;;;;OAKpC,CACF;;AAEL;;;;;;;;ACrBO,MAAMS,OAAK,GAAG,6BAA6B;AAElD,AAAe,eAAeiI,wBAAwBA;EACpD,MAAM;IAAErI,MAAM,EAAEoC;GAAe,GAAG,MAAMnC,YAAY,CAClD,uCAAuC,CACxC;EAED,IAAIyC,MAAM,CAACC,EAAE,CAACP,aAAa,EAAEoD,oBAAoB,CAAC/C,OAAO,CAAC,EAAE;IAC1D,MAAM,IAAI7B,KAAK,uCAEX4E,oBAAoB,CAAC/C,6CACeL;;UAElCzC,cAAc,IAEZ2I,EAAE,CAACC,QAAQ,EAAE,KAAK,OAAO,GAAG,OAAO,GAAG,0CACA;OAE3C,CACF;;AAEL;;;;;;;;ACxBO,MAAMnI,OAAK,GAAG,UAAU;AAE/B,AAAe,eAAeoI,aAAaA;EACzC,IAAI;IACF,MAAMvI,YAAY,CAChB,uFAAuF,CACxF;GACF,CAAC,OAAOa,KAAK,EAAE;IACd,MAAM;MAAEd,MAAM;MAAEyI;KAAQ,GAAG3H,KAA2C;IAEtE,IAAI,CAACd,MAAM,IAAIyI,MAAM,EAAE;MACrB,MAAM3H,KAAK;;IAGb,MAAM4H,gBAAgB,GAAG7D,iBAAiB,CAAC7E,MAAM,CAAC,CAACmF,KAAK,CAAC,IAAI,CAAC;IAE9D,IAAIuD,gBAAgB,CAACnH,MAAM,GAAG,CAAC,EAAE;MAC/B,MAAM,IAAIX,KAAK;YAET8H,gBAAgB,CAAC1G,IAAI,CAAC,IAAI;;;SAG7B,CACF;;;AAGP;;;;;;;;AC1BO,MAAM5B,OAAK,GAAG,4CAA4C;AAEjE,SAAwBuI,qCAAqCA;EAC3D,MAAMC,oBAAoB,GAAG9F,IAAI,CAAC+F,QAAQ,CAAChH,OAAO,CAACC,GAAG,EAAE,CAAC;EACzD,MAAMgH,8BAA8B,GAAGF,oBAAoB,CACxDG,WAAW,EAAE,CACbC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC;EAEvB,IAAIJ,oBAAoB,KAAKE,8BAA8B,EAAE;IAC3D,MAAM,IAAIlI,KAAK,4BACcgI;;oDAEmBE;;UAE1CnJ,cAAc,CAAC,OAAO;UACtBA,cAAc,OACRiJ,wBAAwBE,gCAAgC;UAE9DnJ,cAAc,OAAOmJ,gCAAgC;OACxD,CACF;;AAEL;;;;;;;;ACrBO,MAAMG,gCAAgC,GAAG,CAC9C,KAAK,EACL,MAAM,EACN,MAAM,EACN,MAAM,EACN,IAAI,EACJ,KAAK,EACL,KAAK,CACN;AAED,AAAO,MAAM7I,OAAK,GAAG,WAAW;AAEhC,AAAe,eAAe8I,cAAcA;EAC1C,IAAI;IACF,MAAMjJ,YAAY,yBACQgJ,gCAAgC,CAACjH,IAAI,CAC3D,GAAG,sCACiC,CACvC;GACF,CAAC,OAAOlB,KAAK,EAAE;IACd,MAAM;MAAEd;KAAQ,GAAGc,KAA2B;IAE9C,IAAIqI,gBAAgB;IAEpB,IAAI;MACFA,gBAAgB,GAAInI,IAAI,CAACC,KAAK,CAACjB,MAAM,CAAkB,CAACkB,MAAM,CAC3DkI,eAAe,IAAKA,eAAe,CAACC,OAAO,KAAK,IAAI,CACtD;KACF,CAAC,OAAO/H,UAAU,EAAE;MACnB,MAAMR,KAAK;;IAGb,IACEqI,gBAAgB,CAAC5H,MAAM,GAAG,CAAC,IAC3B,CAAC4H,gBAAgB,CAAC3H,KAAK,CAAEC,MAAM,IAAK,SAAS,IAAIA,MAAM,CAAC,EACxD;MACA,MAAM,IAAIb,KAAK;YAETZ;SACH,CACF;;IAGH,MAAM,IAAIY,KAAK;UAETuI;;;;;;;;;;KAUCzH,GAAG,CAAC,CAAC;MAAE4H;KAAQ,KAAKA,MAAO,CAAC1H,OAAO,IAAIC,OAAO,CAACC,GAAG,KAAKC,KAAK,EAAE,EAAE,CAAC,CAAC,CAClEC,IAAI,CAAC,IAAI;;;OAGb,CACF;;AAEL;;;;;;;;;AC3DA,MAAMC,SAAO,gBAAGC,aAAa,iBAAIL,OAAO,CAACC,GAAG,KAAK,CAAC;AAElD,AAAO,MAAM1B,OAAK,GAAG,oCAAoC;AAEzD,AAAe,eAAemJ,sBAAsBA;EAClD,MAAM;IAAEvJ,MAAM,EAAEoC;GAAe,GAAG,MAAMnC,YAAY,CAClD,6CAA6C,CAC9C;EAED,IAAIoC,YAAgC;EAEpC,IAAI;IACF,MAAMmH,8BAA8B,GAAGvH,SAAO,CAACM,OAAO,CACpD,yCAAyC,CAC1C;IAEDF,YAAY,GAAGrB,IAAI,CAACC,KAAK,CACvB,MAAMT,QAAE,CAACgC,QAAQ,CAACgH,8BAA8B,EAAE,OAAO,CAAC,CAC3D,CAAC/G,OAAO;GACV,CAAC,OAAO3B,KAAK,EAAE;EAEhB,IAAI,OAAOuB,YAAY,KAAK,WAAW,EAAE;IACvC,MAAM,IAAIzB,KAAK;OAEZ,CACF;;EAGH,IAAI8B,MAAM,CAACC,EAAE,CAACP,aAAa,EAAEC,YAAY,CAAC,EAAE;IAC1C,MAAM,IAAIzB,KAAK,4DAC8CyB,kDAAkDD;;4CAEvEA,eAAe,CACtD;;EAGH,IAAIqH,sBAAsB;EAE1B,IAAI;IACFA,sBAAsB,GACpB,CAAC,MAAMjJ,QAAE,CAACgC,QAAQ,CAAC,uBAAuB,EAAE,OAAO,CAAC,EAAE7B,IAAI,EAAE;;;;;uBAM3C;GACpB,CAAC,OAAOG,KAAK,EAAE;IACd,MAAM,IAAIF,KAAK;OAEZ,CACF;;EAGH,IAAI,CAAC6I,sBAAsB,EAAE;IAC3B,MAAM,IAAI7I,KAAK;OAEZ,CACF;;EAGH,MAAM8I,2BAA2B,GAAG,EAAE;EAEtC,WAAW,MAAM;IAAE5G;GAAM,IAAIC,QAAQ,CAAC,GAAG,EAAE;IACzCC,eAAe,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,eAAe,CAAC;IACrDC,UAAU,EAAEgG,gCAAgC,CAACvH,GAAG,CAC7CiI,aAAa,SAAUA,eAAe;GAE1C,CAAC,EAAE;IACF,MAAMzG,YAAY,GAAG,MAAM1C,QAAE,CAACgC,QAAQ,CAACM,IAAI,EAAE,OAAO,CAAC;IACrD,IAAII,YAAY,CAACgD,QAAQ,CAAC,mBAAmB,CAAC,EAAE;MAC9CwD,2BAA2B,CAACvG,IAAI,CAACL,IAAI,CAAC;;;EAI1C,IAAI4G,2BAA2B,CAACnI,MAAM,GAAG,CAAC,EAAE;IAC1C,MAAM,IAAIX,KAAK;UAET8I,2BAA2B,CAAC1H,IAAI,CAAC,IAAI;;;OAGxC,CACF;;AAEL;;;;;;;;ACxFO,MAAM5B,OAAK,GAAG,4BAA4B;AAEjD,AAAe,eAAewJ,uBAAuBA;EACnD,MAAM;IAAE5J;GAAQ,GAAG,MAAMC,YAAY,CACnC,0CAA0C,CAC3C;EAED,IAAID,MAAM,KAAK,EAAE,EAAE;IACjB,MAAM,IAAIY,KAAK;;UAGTjB,cAAc,CAAC,4BAA4B;;;;UAI3CA,cAAc,CAAC,eAAe;;;;UAI9BA,cAAc,CAAC,sBAAsB;OACxC,CACF;;AAEL;;;;;;;;ACFA,MAAMkK,mBAAmB,GAAGtE,kBAAkB,CAACU,YAAY,IAAI,EAAE;AAEjE6D,OAAO,CAACC,GAAG,4BAA4BvE,oBAAoB,CAAC/C,SAAS,CAAC;AAEtE,MAAMuH,UAAU,gBAAgB;AAC9B;AACA;AACA3J,0BAAwB,EACxB4E,2BAAyB,EACzBkD,iCAA+B,EAC/BC,yBAAuB;AAEvB;AACAwB,yBAAuB;AAEvB;AACAjB,uCAAqC;AAErC;AACA;AACA;EACEvI,KAAK,EAAE,wBAAwB;EAC/B6J,IAAI,EAAEA,CAACC,GAAa,EAAED,IAAe,KACnCA,IAAI,CAACE,QAAQ,CAAC,CACZ,IAAI,CAACpE,MAAM,CAACC,IAAI,CAAC6D,mBAAmB,CAAC,CAAC3D,QAAQ,CAAC,MAAM,CAAC,GAClD,EAAE,GACF,CACE;IACE9F,KAAK,EAAEyF,OAAoC;IAC3CoE,IAAI,EAAEpE;GACP,CACF,CAAC,EACN;IACEzF,KAAK,EAAEwH,OAAoC;IAC3CqC,IAAI,EAAErC;GACP,EACD;IACExH,KAAK,EAAEmG,OAAgC;IACvC0D,IAAI,EAAE1D;GACP,CACF;CACJ;AAED;AACA7C,mBAAiB;AAEjB;AACA0G,MAAM,EACN,IAAI,EACF,0BAA0B,IAAIP,mBAAmB,IACjD,MAAM,IAAIA,mBAAmB,CAC9B,GACG,EAAE,GACF,CAACQ,SAAS,CAAC,CAAC,EAChBC,QAAQ;AAER;AACAnI,qBAAmB,EACnB,IAAI,EACF,0BAA0B,IAAI0H,mBAAmB,IACjD,MAAM,IAAIA,mBAAmB,CAC9B,GACG,EAAE,GACF,CAACN,wBAAsB,CAAC,CAAC,EAC7BlB,0BAAwB,CACzB,CAAC3G,GAAG,CAAE6I,MAAM;EACX,IAAI,MAAM,IAAIA,MAAM,EAAE,OAAOA,MAAM;EACnC,OAAO;IACLnK,KAAK,EAAEmK,MAAM,CAACnK,KAAK;IACnB6J,IAAI,EAAEM,MAAM,CAACC;GACd;AACH,CAAC,CAAC;AAEF,MAAMC,KAAK,gBAAG,IAAIC,KAAK,CAACV,UAAU,EAAE;EAClCW,WAAW,EAAE,KAAK;EAClBC,aAAa,EAAE,SAAS;EACxBC,eAAe,EAAE;IACfC,cAAc,EAAE,KAAK;IACrBC,gBAAgB,EAAE,KAAK;IACvBC,YAAY,EAAE;GACf;EACDC,gBAAgB,EAAE,SAAS;EAC3BC,UAAU,EAAE;CACb,CAAC;AAEF,MAAMT,KAAK,CAACU,GAAG,EAAE;AAEjB,IAAIV,KAAK,CAACW,MAAM,CAAC7J,MAAM,GAAG,CAAC,EAAE;EAC3BM,OAAO,CAACwJ,IAAI,CAAC,CAAC,CAAC;AACjB"}
1
+ {"version":3,"file":"preflight.esm.js","sources":["../src/util/commandExample.ts","../src/util/drone.ts","../src/checks/allChangesCommittedToGit.ts","../src/checks/eslint.ts","../src/checks/eslintConfigIsValid.ts","../src/util/randomUserAgent.ts","../src/checks/linkOnGithubAbout.ts","../src/util/crossPlatform.ts","../src/checks/nodeModulesIgnoredFromGit.ts","../src/util/packageJson.ts","../src/checks/noDependencyProblems/noDependenciesWithoutTypes.ts","../src/util/preflightBinPath.ts","../src/checks/noDependencyProblems/noUnusedDependencies.ts","../src/checks/noExtraneousFilesCommittedToGit.ts","../src/checks/noSecretsCommittedToGit.ts","../src/checks/preflightIsLatestVersion.ts","../src/checks/prettier.ts","../src/checks/projectFolderNameMatchesCorrectFormat.ts","../src/checks/stylelint.ts","../src/checks/stylelintConfigIsValid.ts","../src/checks/useSinglePackageManager.ts","../src/index.ts"],"sourcesContent":["import chalk from 'chalk';\n\n// https://www.compart.com/en/unicode/U+2800\n// eslint-disable-next-line security/detect-bidi-characters -- Intentional use of unusual character for formatting\nconst emptyBrailleCharacter = '‎';\n\nexport function commandExample(command: string) {\n return `${emptyBrailleCharacter} ${chalk.dim('$')} ${command}`;\n}\n","import { execa } from 'execa';\n\nexport async function isDrone() {\n const { stdout } = await execa({\n reject: false,\n })`cat /etc/os-release`;\n return /Alpine Linux/.test(stdout);\n}\n","import { promises as fs } from 'node:fs';\nimport { execa } from 'execa';\nimport { commandExample } from '../util/commandExample';\nimport { isDrone } from '../util/drone';\n\nexport const title = 'All changes committed to Git';\n\nexport default async function allChangesCommittedToGit() {\n const { stdout: replSlug } = await execa`echo $REPL_SLUG`;\n\n const isRunningInReplIt = replSlug !== '';\n\n if (isRunningInReplIt) {\n await fs.writeFile('.git/info/exclude', '.replit\\n');\n }\n\n const { stdout } = await execa`git status --porcelain`;\n\n if (stdout !== '') {\n const onlyPnpmLockModifiedOnDrone =\n stdout.trim() === 'M pnpm-lock.yaml' && (await isDrone());\n throw new Error(\n `Some changes have not been committed to Git:\n ${stdout}${\n onlyPnpmLockModifiedOnDrone\n ? `\n\n The only file with changes is the pnpm-lock.yaml file, indicating that npm was incorrectly used in addition to pnpm (eg. an \"npm install\" command was run). To fix this, force regeneration of the pnpm-lock.yaml file locally with the following command and then commit the changes:\n\n ${commandExample('pnpm install --force')}`\n : ''\n }\n `,\n );\n }\n}\n","import { sep } from 'node:path';\nimport { ESLint } from 'eslint';\nimport { execa } from 'execa';\n\nexport const title = 'ESLint';\n\nexport default async function eslintCheck() {\n try {\n await execa({\n // Execute binaries in ./node_modules/.bin to avoid pnpm overhead\n // https://github.com/sindresorhus/execa/blob/main/docs/environment.md#local-binaries\n preferLocal: true,\n })`eslint . --max-warnings 0 --format json`;\n } catch (error) {\n const { stdout } = error as { stdout: string };\n\n let eslintResults;\n\n try {\n eslintResults = (JSON.parse(stdout) as ESLint.LintResult[])\n // Filter out results with no problems, which the ESLint CLI\n // still reports with the `--format json` flag\n .filter((eslintResult) => {\n return eslintResult.errorCount > 0 || eslintResult.warningCount > 0;\n });\n } catch {\n throw error;\n }\n\n if (\n eslintResults.length < 1 ||\n !eslintResults.every(\n (result) => 'errorCount' in result && 'warningCount' in result,\n )\n ) {\n throw new Error(\n `Unexpected shape of ESLint JSON related to .errorCount and .warningCount properties - please report this to the UpLeveled engineering team, including the following output:\n ${stdout}\n `,\n );\n }\n\n throw new Error(\n `ESLint problems found in the following files:\n ${eslintResults\n // Make paths relative to the project:\n //\n // Before:\n // macOS / Linux: /home/projects/next-student-project/app/api/hello/route.js\n // Windows: C:\\Users\\Lukas\\projects\\next-student-project\\app\\api\\hello\\route.js\n //\n // After:\n // macOS / Linux: app/api/hello/route.js\n // Windows: app\\api\\hello\\route.js\n .map(({ filePath }) => filePath.replace(`${process.cwd()}${sep}`, ''))\n .join('\\n')}\n\n Open these files in your editor - there should be problems to fix\n `,\n );\n }\n}\n","import { promises as fs } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { execa } from 'execa';\nimport readdirp from 'readdirp';\nimport semver from 'semver';\n\nconst require = createRequire(`${process.cwd()}/`);\n\nexport const title = 'ESLint config is latest version';\n\nexport default async function eslintConfigIsValid() {\n const { stdout: remoteVersion } =\n await execa`npm show eslint-config-upleveled version`;\n\n let localVersion: string | undefined;\n\n try {\n const eslintConfigPackageJsonPath = require.resolve(\n 'eslint-config-upleveled/package.json',\n );\n\n localVersion = JSON.parse(\n await fs.readFile(eslintConfigPackageJsonPath, 'utf-8'),\n ).version;\n } catch {\n // Swallow error\n }\n\n if (typeof localVersion === 'undefined') {\n throw new Error(\n `The UpLeveled ESLint Config has not been installed - please install using the instructions on https://www.npmjs.com/package/eslint-config-upleveled\n `,\n );\n }\n\n if (semver.gt(remoteVersion, localVersion)) {\n throw new Error(\n `Your current version of the UpLeveled ESLint Config (${localVersion}) is older than the latest version ${remoteVersion} - upgrade by running all lines of the install instructions on https://www.npmjs.com/package/eslint-config-upleveled\n `,\n );\n }\n\n let eslintConfigMatches;\n\n try {\n eslintConfigMatches =\n (await fs.readFile('./eslint.config.js', 'utf-8')).trim() ===\n \"export { default } from 'eslint-config-upleveled';\";\n } catch {\n throw new Error(\n `Error reading your eslint.config.js file - please delete the file if it exists and reinstall the config using the instructions on https://www.npmjs.com/package/eslint-config-upleveled\n `,\n );\n }\n\n if (!eslintConfigMatches) {\n throw new Error(\n `Your eslint.config.js file does not match the configuration file template - please delete the file and reinstall the config using the instructions on https://www.npmjs.com/package/eslint-config-upleveled\n `,\n );\n }\n\n const eslintDisableOccurrences = [];\n\n for await (const { path } of readdirp('.', {\n directoryFilter: ['!.git', '!.next', '!node_modules'],\n fileFilter: ['*.js', '*.jsx', '*.ts', '*.tsx'],\n })) {\n const fileContents = await fs.readFile(path, 'utf-8');\n if (/eslint-disable|eslint [a-z0-9@/-]+: (0|off)/.test(fileContents)) {\n eslintDisableOccurrences.push(path);\n }\n }\n\n if (eslintDisableOccurrences.length > 0) {\n throw new Error(\n `ESLint has been disabled in the following files:\n ${eslintDisableOccurrences.join('\\n')}\n\n Remove all comments disabling or modifying ESLint rule configuration (eg. eslint-disable and eslint-disable-next-line comments) and fix the problems\n `,\n );\n }\n}\n","import userAgents from 'top-user-agents';\n\nexport function randomUserAgent() {\n const randomIndex = Math.floor(Math.random() * (userAgents.length - 1));\n return userAgents[randomIndex]!;\n}\n","import cheerio from 'cheerio';\nimport type { Element } from 'domhandler';\nimport { execa } from 'execa';\nimport fetch from 'node-fetch';\nimport { randomUserAgent } from '../util/randomUserAgent';\n\nexport const title = 'GitHub repo has deployed project link under About';\n\nexport default async function linkOnGithubAbout() {\n const { stdout } = await execa`git remote get-url origin`;\n\n const repoUrl = stdout\n .replace('git@github.com:', 'https://github.com/')\n .replace('.git', '');\n\n const html = await (await fetch(repoUrl)).text();\n\n const $ = cheerio.load(html);\n\n const urlInAboutSection = $('h2')\n .filter(function (this: Element) {\n return $(this).text().trim() === 'About';\n })\n .nextAll('div')\n .filter(function (this: Element) {\n return $(this).children('.octicon.octicon-link').length > 0;\n })\n .children('.octicon.octicon-link')\n .next()\n .children('a[href]')\n .attr('href');\n\n if (!urlInAboutSection) {\n throw new Error(\n `Deployed project link not found in About section on ${repoUrl}. Click on the cog symbol to the right of the About heading and paste the Repl.it / Netlify / Fly.io link in the Website box.`,\n );\n }\n\n const response = await fetch(urlInAboutSection, {\n headers: {\n // For repl.it\n 'user-agent': randomUserAgent(),\n },\n });\n\n if (!response.ok) {\n throw new Error(\n `Project link in About section on ${repoUrl} is not returning a proper status code: the link returns status code ${response.status} (${response.statusText}).`,\n );\n }\n}\n","const CRLF = '\\r\\n';\n\nexport function normalizeNewlines(input: string) {\n if (typeof input !== 'string') {\n throw new TypeError(`Expected a \\`string\\`, got \\`${typeof input}\\``);\n }\n\n return input.replace(new RegExp(CRLF, 'g'), '\\n');\n}\n","import { promises as fs } from 'node:fs';\nimport { execa } from 'execa';\nimport { commandExample } from '../util/commandExample';\nimport { normalizeNewlines } from '../util/crossPlatform';\n\nexport const title = 'node_modules/ folder ignored in Git';\n\nexport default async function nodeModulesIgnoredFromGit() {\n if ((await execa`git ls-files node_modules/`).stdout !== '') {\n throw new Error(\n `node_modules/ folder committed to Git. Remove it using:\n\n ${commandExample('git rm -r --cached node_modules')}\n `,\n );\n }\n\n if ((await execa`git ls-files .gitignore`).stdout !== '.gitignore') {\n throw new Error('.gitignore file not found');\n }\n\n const nodeModulesInGitignore = normalizeNewlines(\n await fs.readFile('./.gitignore', 'utf8'),\n )\n .split('\\n')\n .reduce((found, line) => found || /^\\/?node_modules\\/?$/.test(line), false);\n\n if (!nodeModulesInGitignore) {\n throw new Error('node_modules not found in .gitignore');\n }\n}\n","import { promises as fs } from 'node:fs';\nimport { URL } from 'node:url';\n\ntype PackageJson = {\n name: string;\n version: string;\n description?: string;\n keywords?: string;\n homepage?: string;\n bugs?: {\n email?: string;\n url?: string;\n };\n license?: string;\n author?:\n | string\n | {\n name: string;\n email?: string;\n url?: string;\n };\n contributors?:\n | string[]\n | {\n name: string;\n email?: string;\n url?: string;\n }[];\n files?: string[];\n main?: string;\n browser?: string;\n bin?: Record<string, string>;\n man?: string;\n directories?: {\n lib?: string;\n bin?: string;\n man?: string;\n doc?: string;\n example?: string;\n test?: string;\n };\n repository?: {\n type?: 'git';\n url?: string;\n directory?: string;\n };\n scripts?: Record<string, string>;\n config?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n optionalDependencies?: Record<string, string>;\n bundledDependencies?: string[];\n engines?: Record<string, string>;\n os?: string[];\n cpu?: string[];\n};\n\nexport const projectPackageJson = JSON.parse(\n await fs.readFile('package.json', 'utf-8'),\n) as PackageJson;\n\nexport const preflightPackageJson = JSON.parse(\n await fs.readFile(new URL('../package.json', import.meta.url), 'utf-8'),\n) as PackageJson;\n","import { existsSync, promises as fs } from 'node:fs';\nimport algoliasearch from 'algoliasearch';\nimport pReduce from 'p-reduce';\nimport { commandExample } from '../../util/commandExample';\nimport { projectPackageJson } from '../../util/packageJson';\n\nconst client = algoliasearch(\n // Application ID and API key specific to UpLeveled\n // Preflight. Please don't use anywhere else without\n // asking Algolia's permission.\n 'OFCNCOG2CU', // Application ID\n 'ec73550aa8b2936dab436d4e02144784', // API Key\n);\nconst index = client.initIndex('npm-search');\n\ninterface AlgoliaObj {\n types?: {\n definitelyTyped?: string;\n };\n}\n\nexport const title = 'No dependencies without types';\n\n// This is a naive check for matching @types/<pkg name> packages\n// that the student hasn't yet installed. It is not intended to\n// be an exhaustive check for any types for all packages.\n//\n// It attempts to address scenarios such as this with\n// `styled-components`:\n//\n// https://learn.upleveled.io/courses/btcmp-l-webfs-gen-0/modules/122-cheatsheet-css-in-js/#eslint-errors-with-styled-components\nexport default async function noDependenciesWithoutTypes() {\n const dependenciesWithMissingTypes = await pReduce(\n Object.keys(projectPackageJson.dependencies || {}),\n async (filteredDependencies: [string, string][], dependency: string) => {\n try {\n const packageJsonPath = require.resolve(`${dependency}/package.json`);\n\n const modulePackageJson = JSON.parse(\n await fs.readFile(packageJsonPath, 'utf-8'),\n );\n\n // If the keys \"types\" or \"typings\" are in the module's `package.json`, bail out\n if ('types' in modulePackageJson || 'typings' in modulePackageJson) {\n return filteredDependencies;\n }\n } catch {\n // Swallow error\n }\n\n let indexDTsPath;\n\n try {\n indexDTsPath = require.resolve(`${dependency}/index.d.ts`);\n } catch {\n // Swallow error\n }\n\n // If the index.d.ts file exists inside the module's directory, bail out\n if (indexDTsPath && existsSync(indexDTsPath)) {\n return filteredDependencies;\n }\n\n let results: AlgoliaObj;\n\n try {\n results = await index.getObject<AlgoliaObj>(dependency, {\n attributesToRetrieve: ['types'],\n });\n } catch (error) {\n // Show dependency name if Algolia's `index.getObject()` throws with an\n // error message (such as the error message \"ObjectID does not exist\"\n // when a package cannot be found in the index)\n throw new Error(\n `Algolia error for \\`${dependency}\\`: ${(error as Error).message}`,\n );\n }\n\n const definitelyTypedPackageName = results.types?.definitelyTyped;\n\n if (definitelyTypedPackageName) {\n // If a matching `@types/<package name>` has been already installed in devDependencies, bail out\n if (\n Object.keys(projectPackageJson.devDependencies || {}).includes(\n definitelyTypedPackageName,\n )\n ) {\n return filteredDependencies;\n }\n\n filteredDependencies.push([dependency, definitelyTypedPackageName]);\n }\n\n return filteredDependencies;\n },\n [],\n );\n\n if (dependenciesWithMissingTypes.length > 0) {\n throw new Error(\n `Dependencies found without types. Add the missing types with:\n\n ${commandExample(\n `pnpm add --save-dev ${dependenciesWithMissingTypes\n .map(([, definitelyTypedPackageName]) => definitelyTypedPackageName)\n .join(' ')}`,\n )}\n\n If the dependencies above are already in your package.json, check that they have not been incorrectly installed as regular dependencies in the \"dependencies\" object - they should be installed inside \"devDependencies\" (using the --save-dev flag mentioned above). To fix this situation, remove the dependencies and run the command above exactly.\n `,\n );\n }\n}\n","import { dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { execa } from 'execa';\n\nexport const { stdout: preflightBinPath } = await execa({\n cwd: dirname(fileURLToPath(import.meta.url)),\n})`pnpm bin`;\n","import { execa } from 'execa';\nimport { commandExample } from '../../util/commandExample';\nimport { preflightBinPath } from '../../util/preflightBinPath';\n\nexport const title = 'No unused dependencies';\n\nexport default async function noUnusedAndMissingDependencies() {\n const ignoredPackagePatterns = [\n // Unused dependency detected in https://github.com/upleveled/next-portfolio-dev\n '@graphql-codegen/cli',\n\n // Tailwind CSS\n '@tailwindcss/jit',\n 'autoprefixer',\n 'postcss',\n 'tailwindcss',\n\n // Sass (eg. in Next.js)\n 'sass',\n\n // Prettier and plugins\n 'prettier',\n 'prettier-plugin-*',\n\n // ESLint configuration\n '@ts-safeql/eslint-plugin',\n 'libpg-query',\n\n // TODO: Remove this once depcheck issue is fixed:\n // PR: https://github.com/depcheck/depcheck/pull/790\n // Issue: https://github.com/depcheck/depcheck/issues/791\n //\n // Stylelint configuration\n 'stylelint',\n 'stylelint-config-upleveled',\n\n // Testing\n '@testing-library/user-event',\n 'jest',\n 'jest-environment-jsdom',\n 'playwright',\n\n // `expect` required for proper types with `@testing-library/jest-dom` with `@jest/globals` and pnpm\n // https://github.com/testing-library/jest-dom/issues/123#issuecomment-1536828385\n // TODO: Remove when we switch from Jest to Vitest\n 'expect',\n\n // `ts-node` required for jest.config.ts\n // https://jestjs.io/docs/29.6/configuration#:~:text=To%20read%20TypeScript%20configuration%20files%20Jest%20requires%20ts%2Dnode.%20Make%20sure%20it%20is%20installed%20in%20your%20project\n // TODO: Remove when usage of tsx is allowed\n // https://github.com/jestjs/jest/issues/11989\n 'ts-node',\n\n // TypeScript\n 'typescript',\n '@types/*',\n 'tsx',\n\n // Next.js\n 'sharp',\n ].join(',');\n\n try {\n await execa`${preflightBinPath}/depcheck --ignores=\"${ignoredPackagePatterns}\"`;\n } catch (error) {\n const { stdout } = error as { stdout: string };\n if (\n !stdout.startsWith('Unused dependencies') &&\n !stdout.startsWith('Unused devDependencies') &&\n !stdout.startsWith('Missing dependencies')\n ) {\n throw error;\n }\n\n const [unusedDependenciesStdout, missingDependenciesStdout] = stdout.split(\n 'Missing dependencies',\n );\n\n const messages = [];\n\n if (unusedDependenciesStdout) {\n messages.push(`Unused dependencies found:\n ${unusedDependenciesStdout\n .split('\\n')\n .filter((str: string) => str.includes('* '))\n .join('\\n')}\n\n Remove these dependencies by running the following command for each dependency:\n\n ${commandExample('pnpm remove <dependency name here>')}\n `);\n }\n\n if (missingDependenciesStdout) {\n messages.push(`Missing dependencies found:\n ${missingDependenciesStdout\n .split('\\n')\n .filter((str: string) => str.includes('* '))\n .join('\\n')}\n\n Add these missing dependencies by running the following command for each dependency:\n\n ${commandExample('pnpm add <dependency name here>')}\n `);\n }\n\n if (messages.length > 0) throw new Error(messages.join('\\n\\n'));\n }\n}\n","import { execa } from 'execa';\nimport { commandExample } from '../util/commandExample';\n\nexport const title = 'No extraneous files committed to Git';\n\nexport default async function noExtraneousFilesCommittedToGit() {\n const { stdout } =\n await execa`git ls-files .DS_Store yarn-error.log npm-debug.log`;\n\n if (stdout !== '') {\n throw new Error(\n `Extraneous files committed to Git:\n ${stdout}\n\n Remove these files from your repo by running the following command for each file:\n\n ${commandExample('git rm --cached <filename here>')}\n\n Once you've removed all files, make sure that it doesn't happen again by adding the filenames above to your .gitignore file.\n `,\n );\n }\n}\n","import { execa } from 'execa';\nimport { commandExample } from '../util/commandExample';\n\nexport const title = 'No secrets committed to Git';\n\nexport default async function noSecretsCommittedToGit() {\n const { stdout } = await execa`git ls-files .env .env*.local`;\n\n if (stdout !== '') {\n throw new Error(\n `Secrets committed to Git 😱:\n ${stdout}\n\n Remove these files from your repo by installing BFG from the System Setup Guide (see Optional Software at the bottom) and running it on each of your files like this:\n\n ${commandExample('bfg --delete-files <filename here>')}\n\n Once you've done this for every secret file, then force push to your repository:\n\n ${commandExample('git push --force')}\n\n More info: https://docs.github.com/en/github/authenticating-to-github/removing-sensitive-data-from-a-repository\n\n Finally, make sure that this doesn't happen again by adding the filenames above to your .gitignore file.\n `,\n );\n }\n}\n","import os from 'node:os';\nimport { execa } from 'execa';\nimport semver from 'semver';\nimport { commandExample } from '../util/commandExample';\nimport { preflightPackageJson } from '../util/packageJson';\n\nexport const title = 'Preflight is latest version';\n\nexport default async function preflightIsLatestVersion() {\n const { stdout: remoteVersion } =\n await execa`npm show @upleveled/preflight version`;\n\n if (semver.gt(remoteVersion, preflightPackageJson.version)) {\n throw new Error(\n `Your current version of Preflight (${\n preflightPackageJson.version\n }) is older than the latest version ${remoteVersion} - upgrade with:\n\n ${commandExample(\n `${\n os.platform() === 'linux' ? 'sudo ' : ''\n }pnpm add --global @upleveled/preflight`,\n )}\n `,\n );\n }\n}\n","import { execa } from 'execa';\nimport { normalizeNewlines } from '../util/crossPlatform';\n\nexport const title = 'Prettier';\n\nexport default async function prettierCheck() {\n try {\n await execa({\n // Execute binaries in ./node_modules/.bin to avoid pnpm overhead\n // https://github.com/sindresorhus/execa/blob/main/docs/environment.md#local-binaries\n preferLocal: true,\n })`prettier \"**/*.{js,jsx,ts,tsx,css,scss,sql}\" --list-different --end-of-line auto`;\n } catch (error) {\n const { stdout, stderr } = error as { stdout: string; stderr: string };\n\n if (!stdout || stderr) {\n throw error;\n }\n\n const unformattedFiles = normalizeNewlines(stdout).split('\\n');\n\n if (unformattedFiles.length > 0) {\n throw new Error(\n `Prettier has not been run in the following files:\n ${unformattedFiles.join('\\n')}\n\n For each of the files above, open the file in your editor and save the file. This will format the file with Prettier, which will cause changes to appear in Git.\n `,\n );\n }\n }\n}\n","import path from 'node:path';\nimport { commandExample } from '../util/commandExample';\n\nexport const title = 'Project folder name matches correct format';\n\nexport default function projectFolderNameMatchesCorrectFormat() {\n const currentDirectoryName = path.basename(process.cwd());\n const lowercaseHyphenedDirectoryName = currentDirectoryName\n .toLowerCase()\n .replaceAll(' ', '-');\n\n if (currentDirectoryName !== lowercaseHyphenedDirectoryName) {\n throw new Error(\n `Project directory name \"${currentDirectoryName}\" doesn't match the correct format (no spaces or uppercase letters).\n\n Rename the directory to the correct name \"${lowercaseHyphenedDirectoryName}\" with the following sequence of commands:\n\n ${commandExample('cd ..')}\n ${commandExample(\n `mv ${currentDirectoryName} ${lowercaseHyphenedDirectoryName}`,\n )}\n ${commandExample(`cd ${lowercaseHyphenedDirectoryName}`)}\n `,\n );\n }\n}\n","import { sep } from 'node:path';\nimport { execa } from 'execa';\nimport { LintResult } from 'stylelint';\n\nexport const supportedStylelintFileExtensions = [\n 'css',\n 'sass',\n 'scss',\n 'less',\n 'js',\n 'tsx',\n 'jsx',\n];\n\nexport const title = 'Stylelint';\n\nexport default async function stylelintCheck() {\n try {\n await execa({\n // Execute binaries in ./node_modules/.bin to avoid pnpm overhead\n // https://github.com/sindresorhus/execa/blob/main/docs/environment.md#local-binaries\n preferLocal: true,\n })`stylelint **/*.{${supportedStylelintFileExtensions.join(\n ',',\n )}} --max-warnings 0 --formatter json`;\n } catch (error) {\n const { stdout } = error as { stdout: string };\n\n let stylelintResults;\n\n try {\n stylelintResults = (JSON.parse(stdout) as LintResult[]).filter(\n (stylelintResult) => stylelintResult.errored === true,\n );\n } catch {\n throw error;\n }\n\n if (\n stylelintResults.length < 1 ||\n !stylelintResults.every((result) => 'errored' in result)\n ) {\n throw new Error(\n `Unexpected shape of Stylelint JSON related to .errored properties - please report this to the UpLeveled engineering team, including the following output:\n ${stdout}\n `,\n );\n }\n\n throw new Error(\n `Stylelint problems found in the following files:\n ${stylelintResults\n // Make paths relative to the project:\n //\n // Before:\n // macOS / Linux: /home/projects/random-color-generator-react-app/src/index.css\n // Windows: C:\\Users\\Lukas\\projects\\random-color-generator-react-app\\src\\index.css\n //\n // After:\n // macOS / Linux: src/index.css\n // Windows: src\\index.css\n .map(({ source }) => source!.replace(`${process.cwd()}${sep}`, ''))\n .join('\\n')}\n\n Open these files in your editor - there should be problems to fix\n `,\n );\n }\n}\n","import { promises as fs } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { execa } from 'execa';\nimport readdirp from 'readdirp';\nimport semver from 'semver';\nimport { supportedStylelintFileExtensions } from './stylelint';\n\nconst require = createRequire(`${process.cwd()}/`);\n\nexport const title = 'Stylelint config is latest version';\n\nexport default async function stylelintConfigIsValid() {\n const { stdout: remoteVersion } =\n await execa`npm show stylelint-config-upleveled version`;\n\n let localVersion: string | undefined;\n\n try {\n const stylelintConfigPackageJsonPath = require.resolve(\n 'stylelint-config-upleveled/package.json',\n );\n\n localVersion = JSON.parse(\n await fs.readFile(stylelintConfigPackageJsonPath, 'utf-8'),\n ).version;\n } catch {\n // Swallow error\n }\n\n if (typeof localVersion === 'undefined') {\n throw new Error(\n `The UpLeveled Stylelint Config has not been installed - please install using the instructions on https://www.npmjs.com/package/eslint-config-upleveled\n `,\n );\n }\n\n if (semver.gt(remoteVersion, localVersion)) {\n throw new Error(\n `Your current version of the UpLeveled Stylelint Config (${localVersion}) is older than the latest version ${remoteVersion} - upgrade by running:\n\n pnpm add stylelint-config-upleveled@${remoteVersion}`,\n );\n }\n\n let stylelintConfigMatches;\n\n try {\n stylelintConfigMatches =\n (await fs.readFile('./stylelint.config.js', 'utf-8')).trim() ===\n `/** @type {import('stylelint').Config} */\nconst config = {\n extends: ['stylelint-config-upleveled'],\n};\n\nexport default config;`;\n } catch {\n throw new Error(\n `Error reading your stylelint.config.js file - please delete the file if it exists and reinstall the config using the instructions on https://www.npmjs.com/package/eslint-config-upleveled\n `,\n );\n }\n\n if (!stylelintConfigMatches) {\n throw new Error(\n `Your stylelint.config.js file does not match the configuration file template - please delete the file and reinstall the config using the instructions on https://www.npmjs.com/package/eslint-config-upleveled\n `,\n );\n }\n\n const stylelintDisableOccurrences = [];\n\n for await (const { path } of readdirp('.', {\n directoryFilter: ['!.git', '!.next', '!node_modules'],\n fileFilter: supportedStylelintFileExtensions.map(\n (fileExtension) => `*.${fileExtension}`,\n ),\n })) {\n const fileContents = await fs.readFile(path, 'utf-8');\n if (fileContents.includes('stylelint-disable')) {\n stylelintDisableOccurrences.push(path);\n }\n }\n\n if (stylelintDisableOccurrences.length > 0) {\n throw new Error(\n `Stylelint has been disabled in the following files:\n ${stylelintDisableOccurrences.join('\\n')}\n\n Remove all comments disabling or modifying Stylelint rule configuration (eg. stylelint-disable and stylelint-disable-next-line comments) and fix the problems\n `,\n );\n }\n}\n","import { execa } from 'execa';\nimport { commandExample } from '../util/commandExample';\n\nexport const title = 'Use single package manager';\n\nexport default async function useSinglePackageManager() {\n const { stdout } = await execa`git ls-files package-lock.json yarn.lock`;\n\n if (stdout !== '') {\n throw new Error(\n `package-lock.json or yarn.lock file committed to Git. Remove it with:\n\n ${commandExample('git rm --cached <filename>')}\n\n After you've removed it, you can delete the file with:\n\n ${commandExample('rm <filename>')}\n\n The presence of this file indicates that another package manager was used in addition to pnpm (eg. \"npm install\" or \"yarn add\" was run). In order to avoid issues with the state of the pnpm-lock.yaml file, we suggest also forcing regeneration this file with the following command:\n\n ${commandExample('pnpm install --force')}\n `,\n );\n }\n}\n","import { Listr, ListrTask } from 'listr2';\nimport * as allChangesCommittedToGit from './checks/allChangesCommittedToGit.js';\nimport * as eslint from './checks/eslint.js';\nimport * as eslintConfigIsValid from './checks/eslintConfigIsValid.js';\nimport * as linkOnGithubAbout from './checks/linkOnGithubAbout.js';\nimport * as nodeModulesIgnoredFromGit from './checks/nodeModulesIgnoredFromGit.js';\nimport * as noDependenciesWithoutTypes from './checks/noDependencyProblems/noDependenciesWithoutTypes.js';\nimport * as noUnusedAndMissingDependencies from './checks/noDependencyProblems/noUnusedDependencies.js';\nimport * as noExtraneousFilesCommittedToGit from './checks/noExtraneousFilesCommittedToGit.js';\nimport * as noSecretsCommittedToGit from './checks/noSecretsCommittedToGit.js';\nimport * as preflightIsLatestVersion from './checks/preflightIsLatestVersion.js';\nimport * as prettier from './checks/prettier.js';\nimport * as projectFolderNameMatchesCorrectFormat from './checks/projectFolderNameMatchesCorrectFormat.js';\nimport * as stylelint from './checks/stylelint.js';\nimport * as stylelintConfigIsValid from './checks/stylelintConfigIsValid.js';\nimport * as useSinglePackageManager from './checks/useSinglePackageManager.js';\nimport { CtxParam } from './types/CtxParam.js';\nimport { TaskParam } from './types/TaskParam.js';\nimport {\n preflightPackageJson,\n projectPackageJson,\n} from './util/packageJson.js';\n\nconst projectDependencies = projectPackageJson.dependencies || {};\n\nconsole.log(`🚀 UpLeveled Preflight v${preflightPackageJson.version}`);\n\nconst listrTasks: ListrTask[] = [\n // ======= Sync Tasks =======\n // Git\n allChangesCommittedToGit,\n nodeModulesIgnoredFromGit,\n noExtraneousFilesCommittedToGit,\n noSecretsCommittedToGit,\n\n // Package managers\n useSinglePackageManager,\n\n // Project setup\n projectFolderNameMatchesCorrectFormat,\n\n // ======= Async Tasks =======\n // Dependencies\n {\n title: 'No dependency problems',\n task: (ctx: CtxParam, task: TaskParam): Listr =>\n task.newListr([\n {\n title: noUnusedAndMissingDependencies.title,\n task: noUnusedAndMissingDependencies.default,\n },\n {\n title: noDependenciesWithoutTypes.title,\n task: noDependenciesWithoutTypes.default,\n },\n ]),\n },\n\n // GitHub\n linkOnGithubAbout,\n\n // Linting\n eslint,\n ...(!(\n '@upleveled/react-scripts' in projectDependencies ||\n 'next' in projectDependencies\n )\n ? []\n : [stylelint]),\n prettier,\n\n // Version and configuration checks\n eslintConfigIsValid,\n ...(!(\n '@upleveled/react-scripts' in projectDependencies ||\n 'next' in projectDependencies\n )\n ? []\n : [stylelintConfigIsValid]),\n preflightIsLatestVersion,\n].map((module) => {\n if ('task' in module) return module;\n return {\n title: module.title,\n task: module.default,\n };\n});\n\nconst tasks = new Listr(listrTasks, {\n exitOnError: false,\n collectErrors: 'minimal',\n rendererOptions: {\n collapseErrors: false,\n removeEmptyLines: false,\n formatOutput: 'wrap',\n },\n fallbackRenderer: 'verbose',\n concurrent: 5,\n});\n\nawait tasks.run();\n\nif (tasks.errors.length > 0) {\n process.exit(1);\n}\n"],"names":["emptyBrailleCharacter","commandExample","command","chalk","dim","isDrone","stdout","execa","reject","test","title","allChangesCommittedToGit","replSlug","isRunningInReplIt","fs","writeFile","onlyPnpmLockModifiedOnDrone","trim","Error","eslintCheck","preferLocal","error","eslintResults","JSON","parse","filter","eslintResult","errorCount","warningCount","length","every","result","map","filePath","replace","process","cwd","sep","join","require","createRequire","eslintConfigIsValid","remoteVersion","localVersion","eslintConfigPackageJsonPath","resolve","readFile","version","semver","gt","eslintConfigMatches","eslintDisableOccurrences","path","readdirp","directoryFilter","fileFilter","fileContents","push","randomUserAgent","randomIndex","Math","floor","random","userAgents","linkOnGithubAbout","repoUrl","html","fetch","text","$","cheerio","load","urlInAboutSection","nextAll","children","next","attr","response","headers","ok","status","statusText","CRLF","normalizeNewlines","input","TypeError","RegExp","nodeModulesIgnoredFromGit","nodeModulesInGitignore","split","reduce","found","line","projectPackageJson","preflightPackageJson","URL","import","meta","url","client","algoliasearch","index","initIndex","noDependenciesWithoutTypes","dependenciesWithMissingTypes","pReduce","Object","keys","dependencies","filteredDependencies","dependency","packageJsonPath","modulePackageJson","indexDTsPath","existsSync","results","getObject","attributesToRetrieve","message","definitelyTypedPackageName","_results$types","types","definitelyTyped","devDependencies","includes","preflightBinPath","dirname","fileURLToPath","noUnusedAndMissingDependencies","ignoredPackagePatterns","startsWith","unusedDependenciesStdout","missingDependenciesStdout","messages","str","noExtraneousFilesCommittedToGit","noSecretsCommittedToGit","preflightIsLatestVersion","os","platform","prettierCheck","stderr","unformattedFiles","projectFolderNameMatchesCorrectFormat","currentDirectoryName","basename","lowercaseHyphenedDirectoryName","toLowerCase","replaceAll","supportedStylelintFileExtensions","stylelintCheck","stylelintResults","stylelintResult","errored","source","stylelintConfigIsValid","stylelintConfigPackageJsonPath","stylelintConfigMatches","stylelintDisableOccurrences","fileExtension","useSinglePackageManager","projectDependencies","console","log","listrTasks","task","ctx","newListr","eslint","stylelint","prettier","module","default","tasks","Listr","exitOnError","collectErrors","rendererOptions","collapseErrors","removeEmptyLines","formatOutput","fallbackRenderer","concurrent","run","errors","exit"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@upleveled/preflight",
3
- "version": "7.0.3",
3
+ "version": "7.0.5",
4
4
  "repository": "upleveled/preflight",
5
5
  "license": "MIT",
6
6
  "author": "UpLeveled (https://github.com/upleveled)",
@@ -26,38 +26,38 @@
26
26
  ]
27
27
  },
28
28
  "dependencies": {
29
- "@types/eslint": "8.56.9",
29
+ "@types/eslint": "8.56.10",
30
30
  "algoliasearch": "4.23.3",
31
31
  "chalk": "5.3.0",
32
32
  "cheerio": "1.0.0-rc.12",
33
33
  "depcheck": "1.4.7",
34
34
  "domhandler": "5.0.3",
35
- "execa": "8.0.1",
35
+ "execa": "9.1.0",
36
36
  "listr2": "8.2.1",
37
37
  "node-fetch": "3.3.2",
38
38
  "p-reduce": "3.0.0",
39
39
  "patch-package": "8.0.0",
40
40
  "readdirp": "3.6.0",
41
- "semver": "7.6.0",
42
- "top-user-agents": "2.1.19"
41
+ "semver": "7.6.2",
42
+ "top-user-agents": "2.1.22"
43
43
  },
44
44
  "devDependencies": {
45
- "@babel/plugin-transform-modules-commonjs": "7.24.1",
45
+ "@babel/plugin-transform-modules-commonjs": "7.24.6",
46
46
  "@jest/globals": "29.7.0",
47
- "@size-limit/file": "11.1.2",
47
+ "@size-limit/file": "11.1.4",
48
48
  "@types/babel__core": "7.20.5",
49
49
  "@types/jest": "29.5.12",
50
- "@types/node": "20.12.7",
50
+ "@types/node": "20.12.13",
51
51
  "@types/p-map": "2.0.0",
52
52
  "@types/semver": "7.5.8",
53
53
  "babel-jest": "29.7.0",
54
- "eslint": "9.0.0",
55
- "eslint-config-upleveled": "8.0.1",
54
+ "eslint": "9.3.0",
55
+ "eslint-config-upleveled": "8.1.9",
56
56
  "p-map": "7.0.2",
57
57
  "postinstall-postinstall": "2.1.0",
58
58
  "prettier": "3.2.5",
59
- "size-limit": "11.1.2",
60
- "stylelint": "16.3.1",
59
+ "size-limit": "11.1.4",
60
+ "stylelint": "16.6.1",
61
61
  "tsdx": "0.14.1",
62
62
  "tslib": "2.6.2",
63
63
  "typescript": "5.4.5"
@@ -1,12 +1,12 @@
1
1
  import { promises as fs } from 'node:fs';
2
- import { execaCommand } from 'execa';
2
+ import { execa } from 'execa';
3
3
  import { commandExample } from '../util/commandExample';
4
4
  import { isDrone } from '../util/drone';
5
5
 
6
6
  export const title = 'All changes committed to Git';
7
7
 
8
8
  export default async function allChangesCommittedToGit() {
9
- const { stdout: replSlug } = await execaCommand('echo $REPL_SLUG');
9
+ const { stdout: replSlug } = await execa`echo $REPL_SLUG`;
10
10
 
11
11
  const isRunningInReplIt = replSlug !== '';
12
12
 
@@ -14,7 +14,7 @@ export default async function allChangesCommittedToGit() {
14
14
  await fs.writeFile('.git/info/exclude', '.replit\n');
15
15
  }
16
16
 
17
- const { stdout } = await execaCommand('git status --porcelain');
17
+ const { stdout } = await execa`git status --porcelain`;
18
18
 
19
19
  if (stdout !== '') {
20
20
  const onlyPnpmLockModifiedOnDrone =
@@ -1,12 +1,16 @@
1
1
  import { sep } from 'node:path';
2
2
  import { ESLint } from 'eslint';
3
- import { execaCommand } from 'execa';
3
+ import { execa } from 'execa';
4
4
 
5
5
  export const title = 'ESLint';
6
6
 
7
7
  export default async function eslintCheck() {
8
8
  try {
9
- await execaCommand('pnpm eslint . --max-warnings 0 --format json');
9
+ await execa({
10
+ // Execute binaries in ./node_modules/.bin to avoid pnpm overhead
11
+ // https://github.com/sindresorhus/execa/blob/main/docs/environment.md#local-binaries
12
+ preferLocal: true,
13
+ })`eslint . --max-warnings 0 --format json`;
10
14
  } catch (error) {
11
15
  const { stdout } = error as { stdout: string };
12
16
 
@@ -19,7 +23,7 @@ export default async function eslintCheck() {
19
23
  .filter((eslintResult) => {
20
24
  return eslintResult.errorCount > 0 || eslintResult.warningCount > 0;
21
25
  });
22
- } catch (parseError) {
26
+ } catch {
23
27
  throw error;
24
28
  }
25
29
 
@@ -1,6 +1,6 @@
1
1
  import { promises as fs } from 'node:fs';
2
2
  import { createRequire } from 'node:module';
3
- import { execaCommand } from 'execa';
3
+ import { execa } from 'execa';
4
4
  import readdirp from 'readdirp';
5
5
  import semver from 'semver';
6
6
 
@@ -9,9 +9,8 @@ const require = createRequire(`${process.cwd()}/`);
9
9
  export const title = 'ESLint config is latest version';
10
10
 
11
11
  export default async function eslintConfigIsValid() {
12
- const { stdout: remoteVersion } = await execaCommand(
13
- 'npm show eslint-config-upleveled version',
14
- );
12
+ const { stdout: remoteVersion } =
13
+ await execa`npm show eslint-config-upleveled version`;
15
14
 
16
15
  let localVersion: string | undefined;
17
16
 
@@ -23,7 +22,9 @@ export default async function eslintConfigIsValid() {
23
22
  localVersion = JSON.parse(
24
23
  await fs.readFile(eslintConfigPackageJsonPath, 'utf-8'),
25
24
  ).version;
26
- } catch (error) {}
25
+ } catch {
26
+ // Swallow error
27
+ }
27
28
 
28
29
  if (typeof localVersion === 'undefined') {
29
30
  throw new Error(
@@ -45,7 +46,7 @@ export default async function eslintConfigIsValid() {
45
46
  eslintConfigMatches =
46
47
  (await fs.readFile('./eslint.config.js', 'utf-8')).trim() ===
47
48
  "export { default } from 'eslint-config-upleveled';";
48
- } catch (error) {
49
+ } catch {
49
50
  throw new Error(
50
51
  `Error reading your eslint.config.js file - please delete the file if it exists and reinstall the config using the instructions on https://www.npmjs.com/package/eslint-config-upleveled
51
52
  `,
@@ -1,13 +1,13 @@
1
1
  import cheerio from 'cheerio';
2
2
  import type { Element } from 'domhandler';
3
- import { execaCommand } from 'execa';
3
+ import { execa } from 'execa';
4
4
  import fetch from 'node-fetch';
5
5
  import { randomUserAgent } from '../util/randomUserAgent';
6
6
 
7
7
  export const title = 'GitHub repo has deployed project link under About';
8
8
 
9
9
  export default async function linkOnGithubAbout() {
10
- const { stdout } = await execaCommand('git remote get-url origin');
10
+ const { stdout } = await execa`git remote get-url origin`;
11
11
 
12
12
  const repoUrl = stdout
13
13
  .replace('git@github.com:', 'https://github.com/')
@@ -44,13 +44,17 @@ export default async function noDependenciesWithoutTypes() {
44
44
  if ('types' in modulePackageJson || 'typings' in modulePackageJson) {
45
45
  return filteredDependencies;
46
46
  }
47
- } catch (error) {}
47
+ } catch {
48
+ // Swallow error
49
+ }
48
50
 
49
51
  let indexDTsPath;
50
52
 
51
53
  try {
52
54
  indexDTsPath = require.resolve(`${dependency}/index.d.ts`);
53
- } catch (error) {}
55
+ } catch {
56
+ // Swallow error
57
+ }
54
58
 
55
59
  // If the index.d.ts file exists inside the module's directory, bail out
56
60
  if (indexDTsPath && existsSync(indexDTsPath)) {
@@ -1,4 +1,4 @@
1
- import { execaCommand } from 'execa';
1
+ import { execa } from 'execa';
2
2
  import { commandExample } from '../../util/commandExample';
3
3
  import { preflightBinPath } from '../../util/preflightBinPath';
4
4
 
@@ -61,9 +61,7 @@ export default async function noUnusedAndMissingDependencies() {
61
61
  ].join(',');
62
62
 
63
63
  try {
64
- await execaCommand(
65
- `${preflightBinPath}/depcheck --ignores="${ignoredPackagePatterns}"`,
66
- );
64
+ await execa`${preflightBinPath}/depcheck --ignores="${ignoredPackagePatterns}"`;
67
65
  } catch (error) {
68
66
  const { stdout } = error as { stdout: string };
69
67
  if (
@@ -1,12 +1,11 @@
1
- import { execaCommand } from 'execa';
1
+ import { execa } from 'execa';
2
2
  import { commandExample } from '../util/commandExample';
3
3
 
4
4
  export const title = 'No extraneous files committed to Git';
5
5
 
6
6
  export default async function noExtraneousFilesCommittedToGit() {
7
- const { stdout } = await execaCommand(
8
- 'git ls-files .DS_Store yarn-error.log npm-debug.log',
9
- );
7
+ const { stdout } =
8
+ await execa`git ls-files .DS_Store yarn-error.log npm-debug.log`;
10
9
 
11
10
  if (stdout !== '') {
12
11
  throw new Error(
@@ -1,10 +1,10 @@
1
- import { execaCommand } from 'execa';
1
+ import { execa } from 'execa';
2
2
  import { commandExample } from '../util/commandExample';
3
3
 
4
4
  export const title = 'No secrets committed to Git';
5
5
 
6
6
  export default async function noSecretsCommittedToGit() {
7
- const { stdout } = await execaCommand('git ls-files .env .env*.local');
7
+ const { stdout } = await execa`git ls-files .env .env*.local`;
8
8
 
9
9
  if (stdout !== '') {
10
10
  throw new Error(
@@ -1,12 +1,12 @@
1
1
  import { promises as fs } from 'node:fs';
2
- import { execaCommand } from 'execa';
2
+ import { execa } from 'execa';
3
3
  import { commandExample } from '../util/commandExample';
4
4
  import { normalizeNewlines } from '../util/crossPlatform';
5
5
 
6
6
  export const title = 'node_modules/ folder ignored in Git';
7
7
 
8
8
  export default async function nodeModulesIgnoredFromGit() {
9
- if ((await execaCommand('git ls-files node_modules/')).stdout !== '') {
9
+ if ((await execa`git ls-files node_modules/`).stdout !== '') {
10
10
  throw new Error(
11
11
  `node_modules/ folder committed to Git. Remove it using:
12
12
 
@@ -15,7 +15,7 @@ export default async function nodeModulesIgnoredFromGit() {
15
15
  );
16
16
  }
17
17
 
18
- if ((await execaCommand('git ls-files .gitignore')).stdout !== '.gitignore') {
18
+ if ((await execa`git ls-files .gitignore`).stdout !== '.gitignore') {
19
19
  throw new Error('.gitignore file not found');
20
20
  }
21
21
 
@@ -1,5 +1,5 @@
1
1
  import os from 'node:os';
2
- import { execaCommand } from 'execa';
2
+ import { execa } from 'execa';
3
3
  import semver from 'semver';
4
4
  import { commandExample } from '../util/commandExample';
5
5
  import { preflightPackageJson } from '../util/packageJson';
@@ -7,9 +7,8 @@ import { preflightPackageJson } from '../util/packageJson';
7
7
  export const title = 'Preflight is latest version';
8
8
 
9
9
  export default async function preflightIsLatestVersion() {
10
- const { stdout: remoteVersion } = await execaCommand(
11
- 'npm show @upleveled/preflight version',
12
- );
10
+ const { stdout: remoteVersion } =
11
+ await execa`npm show @upleveled/preflight version`;
13
12
 
14
13
  if (semver.gt(remoteVersion, preflightPackageJson.version)) {
15
14
  throw new Error(
@@ -1,13 +1,15 @@
1
- import { execaCommand } from 'execa';
1
+ import { execa } from 'execa';
2
2
  import { normalizeNewlines } from '../util/crossPlatform';
3
3
 
4
4
  export const title = 'Prettier';
5
5
 
6
6
  export default async function prettierCheck() {
7
7
  try {
8
- await execaCommand(
9
- 'pnpm prettier "**/*.{js,jsx,ts,tsx,css,scss,sql}" --list-different --end-of-line auto',
10
- );
8
+ await execa({
9
+ // Execute binaries in ./node_modules/.bin to avoid pnpm overhead
10
+ // https://github.com/sindresorhus/execa/blob/main/docs/environment.md#local-binaries
11
+ preferLocal: true,
12
+ })`prettier "**/*.{js,jsx,ts,tsx,css,scss,sql}" --list-different --end-of-line auto`;
11
13
  } catch (error) {
12
14
  const { stdout, stderr } = error as { stdout: string; stderr: string };
13
15
 
@@ -1,5 +1,5 @@
1
1
  import { sep } from 'node:path';
2
- import { execaCommand } from 'execa';
2
+ import { execa } from 'execa';
3
3
  import { LintResult } from 'stylelint';
4
4
 
5
5
  export const supportedStylelintFileExtensions = [
@@ -16,11 +16,13 @@ export const title = 'Stylelint';
16
16
 
17
17
  export default async function stylelintCheck() {
18
18
  try {
19
- await execaCommand(
20
- `pnpm stylelint **/*.{${supportedStylelintFileExtensions.join(
21
- ',',
22
- )}} --max-warnings 0 --formatter json`,
23
- );
19
+ await execa({
20
+ // Execute binaries in ./node_modules/.bin to avoid pnpm overhead
21
+ // https://github.com/sindresorhus/execa/blob/main/docs/environment.md#local-binaries
22
+ preferLocal: true,
23
+ })`stylelint **/*.{${supportedStylelintFileExtensions.join(
24
+ ',',
25
+ )}} --max-warnings 0 --formatter json`;
24
26
  } catch (error) {
25
27
  const { stdout } = error as { stdout: string };
26
28
 
@@ -30,7 +32,7 @@ export default async function stylelintCheck() {
30
32
  stylelintResults = (JSON.parse(stdout) as LintResult[]).filter(
31
33
  (stylelintResult) => stylelintResult.errored === true,
32
34
  );
33
- } catch (parseError) {
35
+ } catch {
34
36
  throw error;
35
37
  }
36
38
 
@@ -1,6 +1,6 @@
1
1
  import { promises as fs } from 'node:fs';
2
2
  import { createRequire } from 'node:module';
3
- import { execaCommand } from 'execa';
3
+ import { execa } from 'execa';
4
4
  import readdirp from 'readdirp';
5
5
  import semver from 'semver';
6
6
  import { supportedStylelintFileExtensions } from './stylelint';
@@ -10,9 +10,8 @@ const require = createRequire(`${process.cwd()}/`);
10
10
  export const title = 'Stylelint config is latest version';
11
11
 
12
12
  export default async function stylelintConfigIsValid() {
13
- const { stdout: remoteVersion } = await execaCommand(
14
- 'npm show stylelint-config-upleveled version',
15
- );
13
+ const { stdout: remoteVersion } =
14
+ await execa`npm show stylelint-config-upleveled version`;
16
15
 
17
16
  let localVersion: string | undefined;
18
17
 
@@ -24,7 +23,9 @@ export default async function stylelintConfigIsValid() {
24
23
  localVersion = JSON.parse(
25
24
  await fs.readFile(stylelintConfigPackageJsonPath, 'utf-8'),
26
25
  ).version;
27
- } catch (error) {}
26
+ } catch {
27
+ // Swallow error
28
+ }
28
29
 
29
30
  if (typeof localVersion === 'undefined') {
30
31
  throw new Error(
@@ -52,7 +53,7 @@ const config = {
52
53
  };
53
54
 
54
55
  export default config;`;
55
- } catch (error) {
56
+ } catch {
56
57
  throw new Error(
57
58
  `Error reading your stylelint.config.js file - please delete the file if it exists and reinstall the config using the instructions on https://www.npmjs.com/package/eslint-config-upleveled
58
59
  `,
@@ -1,12 +1,10 @@
1
- import { execaCommand } from 'execa';
1
+ import { execa } from 'execa';
2
2
  import { commandExample } from '../util/commandExample';
3
3
 
4
4
  export const title = 'Use single package manager';
5
5
 
6
6
  export default async function useSinglePackageManager() {
7
- const { stdout } = await execaCommand(
8
- 'git ls-files package-lock.json yarn.lock',
9
- );
7
+ const { stdout } = await execa`git ls-files package-lock.json yarn.lock`;
10
8
 
11
9
  if (stdout !== '') {
12
10
  throw new Error(
package/src/index.ts CHANGED
@@ -4,7 +4,6 @@ import * as eslint from './checks/eslint.js';
4
4
  import * as eslintConfigIsValid from './checks/eslintConfigIsValid.js';
5
5
  import * as linkOnGithubAbout from './checks/linkOnGithubAbout.js';
6
6
  import * as nodeModulesIgnoredFromGit from './checks/nodeModulesIgnoredFromGit.js';
7
- import * as nextJsProjectHasSharpInstalled from './checks/noDependencyProblems/nextJsProjectHasSharpInstalled.js';
8
7
  import * as noDependenciesWithoutTypes from './checks/noDependencyProblems/noDependenciesWithoutTypes.js';
9
8
  import * as noUnusedAndMissingDependencies from './checks/noDependencyProblems/noUnusedDependencies.js';
10
9
  import * as noExtraneousFilesCommittedToGit from './checks/noExtraneousFilesCommittedToGit.js';
@@ -46,14 +45,6 @@ const listrTasks: ListrTask[] = [
46
45
  title: 'No dependency problems',
47
46
  task: (ctx: CtxParam, task: TaskParam): Listr =>
48
47
  task.newListr([
49
- ...(!Object.keys(projectDependencies).includes('next')
50
- ? []
51
- : [
52
- {
53
- title: nextJsProjectHasSharpInstalled.title,
54
- task: nextJsProjectHasSharpInstalled.default,
55
- },
56
- ]),
57
48
  {
58
49
  title: noUnusedAndMissingDependencies.title,
59
50
  task: noUnusedAndMissingDependencies.default,
package/src/util/drone.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { execaCommand } from 'execa';
1
+ import { execa } from 'execa';
2
2
 
3
3
  export async function isDrone() {
4
- const { stdout } = await execaCommand('cat /etc/os-release', {
4
+ const { stdout } = await execa({
5
5
  reject: false,
6
- });
6
+ })`cat /etc/os-release`;
7
7
  return /Alpine Linux/.test(stdout);
8
8
  }
@@ -1,7 +1,7 @@
1
1
  import { dirname } from 'node:path';
2
2
  import { fileURLToPath } from 'node:url';
3
- import { execaCommand } from 'execa';
3
+ import { execa } from 'execa';
4
4
 
5
- export const { stdout: preflightBinPath } = await execaCommand(`pnpm bin`, {
5
+ export const { stdout: preflightBinPath } = await execa({
6
6
  cwd: dirname(fileURLToPath(import.meta.url)),
7
- });
7
+ })`pnpm bin`;
@@ -1,2 +0,0 @@
1
- export declare const title = "Next.js project has sharp installed";
2
- export default function nextJsProjectHasSharpInstalled(): void;
@@ -1,21 +0,0 @@
1
- import { commandExample } from '../../util/commandExample';
2
- import { projectPackageJson } from '../../util/packageJson';
3
-
4
- export const title = 'Next.js project has sharp installed';
5
-
6
- export default function nextJsProjectHasSharpInstalled() {
7
- const dependenciesPackageNames = Object.keys(
8
- projectPackageJson.dependencies || {},
9
- );
10
- if (
11
- dependenciesPackageNames.includes('next') &&
12
- !dependenciesPackageNames.includes('sharp')
13
- ) {
14
- throw new Error(
15
- `Next.js projects should have sharp installed for better image optimization. Install it with:
16
-
17
- ${commandExample('pnpm add sharp')}
18
- `,
19
- );
20
- }
21
- }