@upleveled/preflight 2.1.0-0 → 2.1.0

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.
@@ -60,8 +60,6 @@ var allChangesCommittedToGit$1 = {
60
60
  'default': allChangesCommittedToGit
61
61
  };
62
62
 
63
- const errorKey = 'errorCount';
64
- const warningKey = 'warningCount';
65
63
  const title$1 = 'ESLint';
66
64
  async function eslintCheck() {
67
65
  try {
@@ -70,15 +68,33 @@ async function eslintCheck() {
70
68
  const {
71
69
  stdout
72
70
  } = error;
73
- // If no ESLint problems detected, throw the error
74
- if (!new RegExp(`"${errorKey}":|"${warningKey}":`).test(stdout)) {
71
+ let eslintResults;
72
+ try {
73
+ eslintResults = JSON.parse(stdout)
74
+ // Filter out results with no problems, which the ESLint CLI
75
+ // still reports with the `--format json` flag
76
+ .filter(eslintResult => {
77
+ return eslintResult.errorCount > 0 || eslintResult.warningCount > 0;
78
+ });
79
+ } catch (parseError) {
75
80
  throw error;
76
81
  }
82
+ if (eslintResults.length < 1 || !eslintResults.every(result => 'errorCount' in result && 'warningCount' in result)) {
83
+ throw new Error(`Unexpected shape of ESLint JSON related to .errorCount and .warningCount properties - please report this to the UpLeveled engineering team, including the following output:
84
+ ${stdout}
85
+ `);
86
+ }
77
87
  throw new Error(`ESLint problems found in the following files:
78
- ${JSON.parse(stdout).filter(eslintResult => !(eslintResult[errorKey] === 0 && eslintResult[warningKey] === 0))
88
+ ${eslintResults
79
89
  // Make paths relative to the project:
80
- // before: /home/projects/next-student-project/app/api/hello/route.js
81
- // after: app/api/hello/route.js
90
+ //
91
+ // Before:
92
+ // macOS / Linux: /home/projects/next-student-project/app/api/hello/route.js
93
+ // Windows: C:\Users\Lukas\projects\next-student-project\app\api\hello\route.js
94
+ //
95
+ // After:
96
+ // macOS / Linux: app/api/hello/route.js
97
+ // Windows: app\api\hello\route.js
82
98
  .map(({
83
99
  filePath
84
100
  }) => filePath.replace(`${process.cwd()}${sep}`, '')).join('\n')}
@@ -230,7 +246,7 @@ const preflightPackageJson = /*#__PURE__*/JSON.parse(await /*#__PURE__*/promises
230
246
 
231
247
  const title$5 = 'Next.js project has sharp installed';
232
248
  function nextJsProjectHasSharpInstalled() {
233
- const dependenciesPackageNames = Object.keys(projectPackageJson.dependencies);
249
+ const dependenciesPackageNames = Object.keys(projectPackageJson.dependencies || {});
234
250
  if (dependenciesPackageNames.includes('next') && !dependenciesPackageNames.includes('sharp')) {
235
251
  throw new Error(`Next.js projects should have sharp installed for better image optimization. Install it with:
236
252
 
@@ -257,11 +273,7 @@ const title$6 = 'No dependencies without types';
257
273
  //
258
274
  // https://learn.upleveled.io/courses/btcmp-l-webfs-gen-0/modules/122-cheatsheet-css-in-js/#eslint-errors-with-styled-components
259
275
  async function noDependenciesWithoutTypes() {
260
- const {
261
- devDependencies = {},
262
- dependencies = {}
263
- } = projectPackageJson;
264
- const dependenciesWithMissingTypes = await pReduce(Object.keys(dependencies), async (filteredDependencies, dependency) => {
276
+ const dependenciesWithMissingTypes = await pReduce(Object.keys(projectPackageJson.dependencies || {}), async (filteredDependencies, dependency) => {
265
277
  var _results$types;
266
278
  // Return early here because:
267
279
  // - Algolia reports "ObjectID does not exist" for `@upleveled/react-scripts`
@@ -291,7 +303,7 @@ async function noDependenciesWithoutTypes() {
291
303
  const definitelyTypedPackageName = (_results$types = results.types) == null ? void 0 : _results$types.definitelyTyped;
292
304
  if (definitelyTypedPackageName) {
293
305
  // If a matching `@types/<package name>` has been already installed in devDependencies, bail out
294
- if (Object.keys(devDependencies).includes(definitelyTypedPackageName)) {
306
+ if (Object.keys(projectPackageJson.devDependencies || {}).includes(definitelyTypedPackageName)) {
295
307
  return filteredDependencies;
296
308
  }
297
309
  filteredDependencies.push([dependency, definitelyTypedPackageName]);
@@ -368,7 +380,7 @@ async function noUnusedAndMissingDependencies() {
368
380
  * https://github.com/depcheck/depcheck/issues/789
369
381
  */
370
382
  const missingDependenciesStdoutFiltered = missingDependenciesStdout.split('\n').filter(missingDependency => {
371
- return !(missingDependency.includes('./.eslintrc.cjs') && ['@next/eslint-plugin-next', '@typescript-eslint/eslint-plugin', '@typescript-eslint/parser', 'eslint-plugin-upleveled', 'eslint-config-react-app', 'eslint-import-resolver-typescript', 'eslint-plugin-import', 'eslint-plugin-jsx-a11y', 'eslint-plugin-jsx-expressions', 'eslint-plugin-react-hooks', 'eslint-plugin-react', 'eslint-plugin-security', 'eslint-plugin-sonarjs', 'eslint-plugin-unicorn'].some(excludedDependency => missingDependency.includes(excludedDependency)));
383
+ return !(missingDependency.includes(`.${sep}.eslintrc.cjs`) && ['@next/eslint-plugin-next', '@typescript-eslint/eslint-plugin', '@typescript-eslint/parser', 'eslint-plugin-upleveled', 'eslint-config-react-app', 'eslint-import-resolver-typescript', 'eslint-plugin-import', 'eslint-plugin-jsx-a11y', 'eslint-plugin-jsx-expressions', 'eslint-plugin-react-hooks', 'eslint-plugin-react', 'eslint-plugin-security', 'eslint-plugin-sonarjs', 'eslint-plugin-unicorn'].some(excludedDependency => missingDependency.includes(excludedDependency)));
372
384
  }).join('\n');
373
385
  if (missingDependenciesStdoutFiltered) {
374
386
  messages.push(`Missing dependencies found:
@@ -472,22 +484,19 @@ async function prettierCheck() {
472
484
  if (!stdout || stderrWithoutPackageJsonWarning) {
473
485
  throw error;
474
486
  }
475
- const ignoredFilePatterns = [
476
- // File from create-react-app not matching our formatting
477
- // https://github.com/facebook/create-react-app/blob/fdbde1f3c256b43d5386b5ae3a75083dbd8f0aff/packages/cra-template/template/src/reportWebVitals.js
478
- /src[/\\]reportWebVitals\.js$/,
479
- // Files from create-next-app not matching our formatting
480
- // https://github.com/vercel/next.js/blob/5a73859fe8d3659d52e169f97188ae422e0d2ace/packages/create-next-app/templates/default/pages/api/hello.js
481
- /pages[/\\]api[/\\]hello\.js$/,
482
- // https://github.com/vercel/next.js/blob/aacfa79ddf88e4e1488b63ac253af27110f0a151/packages/create-next-app/templates/default/pages/_app.js
483
- /pages[/\\]_app\.js$/];
484
487
  const unformattedFiles = normalizeNewline(stdout).split('\n')
485
- // Make paths relative to the project instead of Preflight, eg:
486
- // before: ../../../../../../projects/random-color-generator-react-app/src/reportWebVitals.js
487
- // after: src/reportWebVitals.js
488
+ // Make paths relative to the project:
489
+ //
490
+ // Before:
491
+ // macOS / Linux: ../../../../../../projects/random-color-generator-react-app/src/reportWebVitals.js
492
+ // Windows: ..\..\..\..\..\..\..\..\..\..\..\projects\random-color-generator-react-app\src\reportWebVitals.js
493
+ //
494
+ // After:
495
+ // macOS / Linux: src/reportWebVitals.js
496
+ // Windows: src\reportWebVitals.js
488
497
  .map(file => {
489
498
  return file.replace(`${relative(dirname(fileURLToPath(import.meta.url)), process.cwd())}${sep}`, '');
490
- }).filter(file => !ignoredFilePatterns.some(ignoredFilePattern => ignoredFilePattern.test(file)));
499
+ });
491
500
  if (unformattedFiles.length > 0) {
492
501
  throw new Error(`Prettier has not been run in the following files:
493
502
  ${unformattedFiles.join('\n')}
@@ -528,7 +537,6 @@ var projectFolderNameMatchesCorrectFormat$1 = {
528
537
  'default': projectFolderNameMatchesCorrectFormat
529
538
  };
530
539
 
531
- const errorKey$1 = 'errored';
532
540
  const supportedStylelintFileExtensions = ['css', 'sass', 'scss', 'less', 'js', 'tsx', 'jsx'];
533
541
  const title$d = 'Stylelint';
534
542
  async function stylelintCheck() {
@@ -538,15 +546,28 @@ async function stylelintCheck() {
538
546
  const {
539
547
  stdout
540
548
  } = error;
541
- // If no Stylelint errors detected, throw the error
542
- if (!new RegExp(`"${errorKey$1}":`).test(stdout)) {
549
+ let stylelintResults;
550
+ try {
551
+ stylelintResults = JSON.parse(stdout).filter(stylelintResult => stylelintResult.errored === true);
552
+ } catch (parseError) {
543
553
  throw error;
544
554
  }
555
+ if (stylelintResults.length < 1 || !stylelintResults.every(result => 'errored' in result)) {
556
+ throw new Error(`Unexpected shape of Stylelint JSON related to .errored properties - please report this to the UpLeveled engineering team, including the following output:
557
+ ${stdout}
558
+ `);
559
+ }
545
560
  throw new Error(`Stylelint problems found in the following files:
546
- ${JSON.parse(stdout).filter(stylelintResult => stylelintResult[errorKey$1] === true)
561
+ ${stylelintResults
547
562
  // Make paths relative to the project:
548
- // before: /home/projects/random-color-generator-react-app/src/index.css
549
- // after: src/index.css
563
+ //
564
+ // Before:
565
+ // macOS / Linux: /home/projects/random-color-generator-react-app/src/index.css
566
+ // Windows: C:\Users\Lukas\projects\random-color-generator-react-app\src\index.css
567
+ //
568
+ // After:
569
+ // macOS / Linux: src/index.css
570
+ // Windows: src\index.css
550
571
  .map(({
551
572
  source
552
573
  }) => source.replace(`${process.cwd()}${sep}`, '')).join('\n')}
@@ -1 +1 @@
1
- {"version":3,"file":"preflight.esm.js","sources":["../src/util/commandExample.ts","../src/util/isDrone.ts","../src/checks/allChangesCommittedToGit.ts","../src/checks/eslint.ts","../src/checks/eslintConfigIsValid.ts","../src/util/randomUserAgent.ts","../src/checks/linkOnGithubAbout.ts","../src/util/normalizeNewline.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 default 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/isDrone';\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\nconst errorKey = 'errorCount' as const;\nconst warningKey = 'warningCount' as const;\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 // If no ESLint problems detected, throw the error\n if (!new RegExp(`\"${errorKey}\":|\"${warningKey}\":`).test(stdout)) {\n throw error;\n }\n\n throw new Error(\n `ESLint problems found in the following files:\n ${(JSON.parse(stdout) as ESLint.LintResult[])\n .filter(\n (eslintResult) =>\n !(eslintResult[errorKey] === 0 && eslintResult[warningKey] === 0),\n )\n // Make paths relative to the project:\n // before: /home/projects/next-student-project/app/api/hello/route.js\n // after: 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;\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 (err) {}\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('./.eslintrc.cjs', 'utf-8')).trim() ===\n `/** @type {import('@typescript-eslint/utils').TSESLint.Linter.Config} */\nconst config = {\n extends: ['upleveled'],\n};\n\nmodule.exports = config;`;\n } catch (err) {\n throw new Error(\n `Error reading your .eslintrc.cjs 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 .eslintrc.cjs 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 default 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 default function normalizeNewline(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 normalizeNewline from '../util/normalizeNewline';\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 = normalizeNewline(\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 { devDependencies = {}, dependencies = {} } = projectPackageJson;\n\n const dependenciesWithMissingTypes = await pReduce(\n Object.keys(dependencies),\n async (filteredDependencies: [string, string][], dependency: string) => {\n // Return early here because:\n // - Algolia reports \"ObjectID does not exist\" for `@upleveled/react-scripts`\n // - `@upleveled/react-scripts` has no types to install\n if (dependency === '@upleveled/react-scripts') {\n return filteredDependencies;\n }\n\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 (err) {}\n\n let indexDTsPath;\n\n try {\n indexDTsPath = require.resolve(`${dependency}/index.d.ts`);\n } catch (err) {}\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 const results = await index.getObject<AlgoliaObj>(dependency, {\n attributesToRetrieve: ['types'],\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 (Object.keys(devDependencies).includes(definitelyTypedPackageName)) {\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\nconst { stdout: preflightBinPath } = await execaCommand(`pnpm bin`, {\n cwd: dirname(fileURLToPath(import.meta.url)),\n});\n\nexport default preflightBinPath;\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 // Unused dependency detected in create-react-app\n '@testing-library/user-event',\n\n // Tailwind CSS\n '@tailwindcss/jit',\n 'autoprefixer',\n 'postcss',\n 'tailwindcss',\n\n // Sass (eg. in create-react-app)\n 'sass',\n\n // ESLint configuration\n 'babel-eslint',\n 'eslint-config-next',\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 'babel-jest',\n 'cypress',\n 'jest',\n 'jest-environment-jsdom',\n 'jest-puppeteer',\n 'playwright',\n 'puppeteer',\n\n // TypeScript\n 'typescript',\n '@types/*',\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 /**\n * Temporary workaround to filter out eslint-config-upleveled peer dependencies\n * not listed in `package.json`, which are flagged as missing dependencies by depcheck\n *\n * TODO: Remove this variable once this depcheck issue is fixed:\n * https://github.com/depcheck/depcheck/issues/789\n */\n const missingDependenciesStdoutFiltered = missingDependenciesStdout\n .split('\\n')\n .filter((missingDependency) => {\n return !(\n missingDependency.includes('./.eslintrc.cjs') &&\n [\n '@next/eslint-plugin-next',\n '@typescript-eslint/eslint-plugin',\n '@typescript-eslint/parser',\n 'eslint-plugin-upleveled',\n 'eslint-config-react-app',\n 'eslint-import-resolver-typescript',\n 'eslint-plugin-import',\n 'eslint-plugin-jsx-a11y',\n 'eslint-plugin-jsx-expressions',\n 'eslint-plugin-react-hooks',\n 'eslint-plugin-react',\n 'eslint-plugin-security',\n 'eslint-plugin-sonarjs',\n 'eslint-plugin-unicorn',\n ].some((excludedDependency) =>\n missingDependency.includes(excludedDependency),\n )\n );\n })\n .join('\\n');\n\n if (missingDependenciesStdoutFiltered) {\n messages.push(`Missing dependencies found:\n ${missingDependenciesStdoutFiltered\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\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 { dirname, relative, sep } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { execaCommand } from 'execa';\nimport normalizeNewline from '../util/normalizeNewline';\n\nexport const title = 'Prettier';\n\nexport default async function prettierCheck() {\n try {\n await execaCommand(\n `../node_modules/.bin/prettier --list-different ${process.cwd()}/**/*.{js,jsx,ts,jsx} --ignore-path ${process.cwd()}/.eslintignore --config ${process.cwd()}/prettier.config.cjs --end-of-line auto`,\n { cwd: dirname(fileURLToPath(import.meta.url)) },\n );\n } catch (error) {\n const { stdout, stderr } = error as { stdout: string; stderr: string };\n\n const stderrWithoutPackageJsonWarning = stderr.replace(\n /warning [/.\\\\]*package\\.json: No license field[\\r\\n]*/g,\n '',\n );\n\n if (!stdout || stderrWithoutPackageJsonWarning) {\n throw error;\n }\n\n const ignoredFilePatterns = [\n // File from create-react-app not matching our formatting\n // https://github.com/facebook/create-react-app/blob/fdbde1f3c256b43d5386b5ae3a75083dbd8f0aff/packages/cra-template/template/src/reportWebVitals.js\n /src[/\\\\]reportWebVitals\\.js$/,\n\n // Files from create-next-app not matching our formatting\n // https://github.com/vercel/next.js/blob/5a73859fe8d3659d52e169f97188ae422e0d2ace/packages/create-next-app/templates/default/pages/api/hello.js\n /pages[/\\\\]api[/\\\\]hello\\.js$/,\n // https://github.com/vercel/next.js/blob/aacfa79ddf88e4e1488b63ac253af27110f0a151/packages/create-next-app/templates/default/pages/_app.js\n /pages[/\\\\]_app\\.js$/,\n ];\n\n const unformattedFiles = normalizeNewline(stdout)\n .split('\\n')\n // Make paths relative to the project instead of Preflight, eg:\n // before: ../../../../../../projects/random-color-generator-react-app/src/reportWebVitals.js\n // after: src/reportWebVitals.js\n .map((file) => {\n return file.replace(\n `${relative(\n dirname(fileURLToPath(import.meta.url)),\n process.cwd(),\n )}${sep}`,\n '',\n );\n })\n .filter(\n (file) =>\n !ignoredFilePatterns.some((ignoredFilePattern) =>\n ignoredFilePattern.test(file),\n ),\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 In some very uncommon cases (this probably doesn't apply to you), the mismatch may come from inconsistent end of line characters. Read more here: https://github.com/upleveled/answers/issues/31\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\nconst errorKey = 'errored' as const;\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 // If no Stylelint errors detected, throw the error\n if (!new RegExp(`\"${errorKey}\":`).test(stdout)) {\n throw error;\n }\n\n throw new Error(\n `Stylelint problems found in the following files:\n ${(JSON.parse(stdout) as LintResult[])\n .filter((stylelintResult) => stylelintResult[errorKey] === true)\n // Make paths relative to the project:\n // before: /home/projects/random-color-generator-react-app/src/index.css\n // after: 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;\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 (err) {}\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.cjs', 'utf-8')).trim() ===\n `/** @type { import('stylelint').Config } */\nconst config = {\n extends: ['stylelint-config-upleveled'],\n};\n\nmodule.exports = config;`;\n } catch (err) {\n throw new Error(\n `Error reading your stylelint.config.cjs 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.cjs 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 } 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 = [\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\nawait new Listr(listrTasks, {\n exitOnError: false,\n rendererOptions: {\n collapseErrors: false,\n removeEmptyLines: false,\n formatOutput: 'wrap',\n },\n fallbackRenderer: 'verbose',\n concurrent: 5,\n}).run();\n"],"names":["emptyBrailleCharacter","commandExample","command","chalk","dim","isDrone","stdout","execaCommand","reject","test","title","allChangesCommittedToGit","replSlug","isRunningInReplIt","fs","writeFile","onlyPnpmLockModifiedOnDrone","trim","Error","errorKey","warningKey","eslintCheck","error","RegExp","JSON","parse","filter","eslintResult","map","filePath","replace","process","cwd","sep","join","require","createRequire","eslintConfigIsValid","remoteVersion","localVersion","eslintConfigPackageJsonPath","resolve","readFile","version","err","semver","gt","eslintConfigMatches","eslintDisableOccurrences","path","readdirp","directoryFilter","fileFilter","fileContents","push","length","randomUserAgent","randomIndex","Math","floor","random","userAgents","linkOnGithubAbout","repoUrl","html","fetch","text","$","cheerio","load","urlInAboutSection","nextAll","children","next","attr","response","headers","ok","status","statusText","CRLF","normalizeNewline","input","TypeError","nodeModulesIgnoredFromGit","nodeModulesInGitignore","split","reduce","found","line","projectPackageJson","preflightPackageJson","URL","import","meta","url","nextJsProjectHasSharpInstalled","dependenciesPackageNames","Object","keys","dependencies","includes","client","algoliasearch","index","initIndex","noDependenciesWithoutTypes","devDependencies","dependenciesWithMissingTypes","pReduce","filteredDependencies","dependency","packageJsonPath","modulePackageJson","indexDTsPath","existsSync","results","getObject","attributesToRetrieve","definitelyTypedPackageName","_results$types","types","definitelyTyped","preflightBinPath","dirname","fileURLToPath","noUnusedAndMissingDependencies","ignoredPackagePatterns","startsWith","unusedDependenciesStdout","missingDependenciesStdout","messages","str","missingDependenciesStdoutFiltered","missingDependency","some","excludedDependency","noExtraneousFilesCommittedToGit","noSecretsCommittedToGit","preflightIsLatestVersion","os","platform","prettierCheck","stderr","stderrWithoutPackageJsonWarning","ignoredFilePatterns","unformattedFiles","file","relative","ignoredFilePattern","projectFolderNameMatchesCorrectFormat","currentDirectoryName","basename","lowercaseHyphenedDirectoryName","toLowerCase","replaceAll","supportedStylelintFileExtensions","stylelintCheck","stylelintResult","source","stylelintConfigIsValid","stylelintConfigPackageJsonPath","stylelintConfigMatches","stylelintDisableOccurrences","fileExtension","useSinglePackageManager","projectDependencies","console","log","listrTasks","task","ctx","newListr","eslint","stylelint","prettier","module","default","Listr","exitOnError","rendererOptions","collapseErrors","removeEmptyLines","formatOutput","fallbackRenderer","concurrent","run"],"mappings":"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"}
1
+ {"version":3,"file":"preflight.esm.js","sources":["../src/util/commandExample.ts","../src/util/isDrone.ts","../src/checks/allChangesCommittedToGit.ts","../src/checks/eslint.ts","../src/checks/eslintConfigIsValid.ts","../src/util/randomUserAgent.ts","../src/checks/linkOnGithubAbout.ts","../src/util/normalizeNewline.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 default 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/isDrone';\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;\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 (err) {}\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('./.eslintrc.cjs', 'utf-8')).trim() ===\n `/** @type {import('@typescript-eslint/utils').TSESLint.Linter.Config} */\nconst config = {\n extends: ['upleveled'],\n};\n\nmodule.exports = config;`;\n } catch (err) {\n throw new Error(\n `Error reading your .eslintrc.cjs 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 .eslintrc.cjs 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 default 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 default function normalizeNewline(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 normalizeNewline from '../util/normalizeNewline';\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 = normalizeNewline(\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 // Return early here because:\n // - Algolia reports \"ObjectID does not exist\" for `@upleveled/react-scripts`\n // - `@upleveled/react-scripts` has no types to install\n if (dependency === '@upleveled/react-scripts') {\n return filteredDependencies;\n }\n\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 (err) {}\n\n let indexDTsPath;\n\n try {\n indexDTsPath = require.resolve(`${dependency}/index.d.ts`);\n } catch (err) {}\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 const results = await index.getObject<AlgoliaObj>(dependency, {\n attributesToRetrieve: ['types'],\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\nconst { stdout: preflightBinPath } = await execaCommand(`pnpm bin`, {\n cwd: dirname(fileURLToPath(import.meta.url)),\n});\n\nexport default preflightBinPath;\n","import { sep } from 'node:path';\nimport { 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 // Unused dependency detected in create-react-app\n '@testing-library/user-event',\n\n // Tailwind CSS\n '@tailwindcss/jit',\n 'autoprefixer',\n 'postcss',\n 'tailwindcss',\n\n // Sass (eg. in create-react-app)\n 'sass',\n\n // ESLint configuration\n 'babel-eslint',\n 'eslint-config-next',\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 'babel-jest',\n 'cypress',\n 'jest',\n 'jest-environment-jsdom',\n 'jest-puppeteer',\n 'playwright',\n 'puppeteer',\n\n // TypeScript\n 'typescript',\n '@types/*',\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 /**\n * Temporary workaround to filter out eslint-config-upleveled peer dependencies\n * not listed in `package.json`, which are flagged as missing dependencies by depcheck\n *\n * TODO: Remove this variable once this depcheck issue is fixed:\n * https://github.com/depcheck/depcheck/issues/789\n */\n const missingDependenciesStdoutFiltered = missingDependenciesStdout\n .split('\\n')\n .filter((missingDependency) => {\n return !(\n missingDependency.includes(`.${sep}.eslintrc.cjs`) &&\n [\n '@next/eslint-plugin-next',\n '@typescript-eslint/eslint-plugin',\n '@typescript-eslint/parser',\n 'eslint-plugin-upleveled',\n 'eslint-config-react-app',\n 'eslint-import-resolver-typescript',\n 'eslint-plugin-import',\n 'eslint-plugin-jsx-a11y',\n 'eslint-plugin-jsx-expressions',\n 'eslint-plugin-react-hooks',\n 'eslint-plugin-react',\n 'eslint-plugin-security',\n 'eslint-plugin-sonarjs',\n 'eslint-plugin-unicorn',\n ].some((excludedDependency) =>\n missingDependency.includes(excludedDependency),\n )\n );\n })\n .join('\\n');\n\n if (missingDependenciesStdoutFiltered) {\n messages.push(`Missing dependencies found:\n ${missingDependenciesStdoutFiltered\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\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 { dirname, relative, sep } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { execaCommand } from 'execa';\nimport normalizeNewline from '../util/normalizeNewline';\n\nexport const title = 'Prettier';\n\nexport default async function prettierCheck() {\n try {\n await execaCommand(\n `../node_modules/.bin/prettier --list-different ${process.cwd()}/**/*.{js,jsx,ts,jsx} --ignore-path ${process.cwd()}/.eslintignore --config ${process.cwd()}/prettier.config.cjs --end-of-line auto`,\n { cwd: dirname(fileURLToPath(import.meta.url)) },\n );\n } catch (error) {\n const { stdout, stderr } = error as { stdout: string; stderr: string };\n\n const stderrWithoutPackageJsonWarning = stderr.replace(\n /warning [/.\\\\]*package\\.json: No license field[\\r\\n]*/g,\n '',\n );\n\n if (!stdout || stderrWithoutPackageJsonWarning) {\n throw error;\n }\n\n const unformattedFiles = normalizeNewline(stdout)\n .split('\\n')\n // Make paths relative to the project:\n //\n // Before:\n // macOS / Linux: ../../../../../../projects/random-color-generator-react-app/src/reportWebVitals.js\n // Windows: ..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\projects\\random-color-generator-react-app\\src\\reportWebVitals.js\n //\n // After:\n // macOS / Linux: src/reportWebVitals.js\n // Windows: src\\reportWebVitals.js\n .map((file) => {\n return file.replace(\n `${relative(\n dirname(fileURLToPath(import.meta.url)),\n process.cwd(),\n )}${sep}`,\n '',\n );\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 In some very uncommon cases (this probably doesn't apply to you), the mismatch may come from inconsistent end of line characters. Read more here: https://github.com/upleveled/answers/issues/31\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;\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 (err) {}\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.cjs', 'utf-8')).trim() ===\n `/** @type { import('stylelint').Config } */\nconst config = {\n extends: ['stylelint-config-upleveled'],\n};\n\nmodule.exports = config;`;\n } catch (err) {\n throw new Error(\n `Error reading your stylelint.config.cjs 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.cjs 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 } 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 = [\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\nawait new Listr(listrTasks, {\n exitOnError: false,\n rendererOptions: {\n collapseErrors: false,\n removeEmptyLines: false,\n formatOutput: 'wrap',\n },\n fallbackRenderer: 'verbose',\n concurrent: 5,\n}).run();\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","err","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","normalizeNewline","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","definitelyTypedPackageName","_results$types","types","definitelyTyped","devDependencies","preflightBinPath","dirname","fileURLToPath","noUnusedAndMissingDependencies","ignoredPackagePatterns","startsWith","unusedDependenciesStdout","missingDependenciesStdout","messages","str","missingDependenciesStdoutFiltered","missingDependency","some","excludedDependency","noExtraneousFilesCommittedToGit","noSecretsCommittedToGit","preflightIsLatestVersion","os","platform","prettierCheck","stderr","stderrWithoutPackageJsonWarning","unformattedFiles","file","relative","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","Listr","exitOnError","rendererOptions","collapseErrors","removeEmptyLines","formatOutput","fallbackRenderer","concurrent","run"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@upleveled/preflight",
3
- "version": "2.1.0-0",
3
+ "version": "2.1.0",
4
4
  "repository": "upleveled/preflight",
5
5
  "license": "MIT",
6
6
  "author": "UpLeveled (https://github.com/upleveled)",
@@ -2,9 +2,6 @@ import { sep } from 'node:path';
2
2
  import { ESLint } from 'eslint';
3
3
  import { execaCommand } from 'execa';
4
4
 
5
- const errorKey = 'errorCount' as const;
6
- const warningKey = 'warningCount' as const;
7
-
8
5
  export const title = 'ESLint';
9
6
 
10
7
  export default async function eslintCheck() {
@@ -13,21 +10,44 @@ export default async function eslintCheck() {
13
10
  } catch (error) {
14
11
  const { stdout } = error as { stdout: string };
15
12
 
16
- // If no ESLint problems detected, throw the error
17
- if (!new RegExp(`"${errorKey}":|"${warningKey}":`).test(stdout)) {
13
+ let eslintResults;
14
+
15
+ try {
16
+ eslintResults = (JSON.parse(stdout) as ESLint.LintResult[])
17
+ // Filter out results with no problems, which the ESLint CLI
18
+ // still reports with the `--format json` flag
19
+ .filter((eslintResult) => {
20
+ return eslintResult.errorCount > 0 || eslintResult.warningCount > 0;
21
+ });
22
+ } catch (parseError) {
18
23
  throw error;
19
24
  }
20
25
 
26
+ if (
27
+ eslintResults.length < 1 ||
28
+ !eslintResults.every(
29
+ (result) => 'errorCount' in result && 'warningCount' in result,
30
+ )
31
+ ) {
32
+ throw new Error(
33
+ `Unexpected shape of ESLint JSON related to .errorCount and .warningCount properties - please report this to the UpLeveled engineering team, including the following output:
34
+ ${stdout}
35
+ `,
36
+ );
37
+ }
38
+
21
39
  throw new Error(
22
40
  `ESLint problems found in the following files:
23
- ${(JSON.parse(stdout) as ESLint.LintResult[])
24
- .filter(
25
- (eslintResult) =>
26
- !(eslintResult[errorKey] === 0 && eslintResult[warningKey] === 0),
27
- )
41
+ ${eslintResults
28
42
  // Make paths relative to the project:
29
- // before: /home/projects/next-student-project/app/api/hello/route.js
30
- // after: app/api/hello/route.js
43
+ //
44
+ // Before:
45
+ // macOS / Linux: /home/projects/next-student-project/app/api/hello/route.js
46
+ // Windows: C:\Users\Lukas\projects\next-student-project\app\api\hello\route.js
47
+ //
48
+ // After:
49
+ // macOS / Linux: app/api/hello/route.js
50
+ // Windows: app\api\hello\route.js
31
51
  .map(({ filePath }) => filePath.replace(`${process.cwd()}${sep}`, ''))
32
52
  .join('\n')}
33
53
 
@@ -5,7 +5,7 @@ export const title = 'Next.js project has sharp installed';
5
5
 
6
6
  export default function nextJsProjectHasSharpInstalled() {
7
7
  const dependenciesPackageNames = Object.keys(
8
- projectPackageJson.dependencies!,
8
+ projectPackageJson.dependencies || {},
9
9
  );
10
10
  if (
11
11
  dependenciesPackageNames.includes('next') &&
@@ -30,10 +30,8 @@ export const title = 'No dependencies without types';
30
30
  //
31
31
  // https://learn.upleveled.io/courses/btcmp-l-webfs-gen-0/modules/122-cheatsheet-css-in-js/#eslint-errors-with-styled-components
32
32
  export default async function noDependenciesWithoutTypes() {
33
- const { devDependencies = {}, dependencies = {} } = projectPackageJson;
34
-
35
33
  const dependenciesWithMissingTypes = await pReduce(
36
- Object.keys(dependencies),
34
+ Object.keys(projectPackageJson.dependencies || {}),
37
35
  async (filteredDependencies: [string, string][], dependency: string) => {
38
36
  // Return early here because:
39
37
  // - Algolia reports "ObjectID does not exist" for `@upleveled/react-scripts`
@@ -74,7 +72,11 @@ export default async function noDependenciesWithoutTypes() {
74
72
 
75
73
  if (definitelyTypedPackageName) {
76
74
  // If a matching `@types/<package name>` has been already installed in devDependencies, bail out
77
- if (Object.keys(devDependencies).includes(definitelyTypedPackageName)) {
75
+ if (
76
+ Object.keys(projectPackageJson.devDependencies || {}).includes(
77
+ definitelyTypedPackageName,
78
+ )
79
+ ) {
78
80
  return filteredDependencies;
79
81
  }
80
82
 
@@ -1,3 +1,4 @@
1
+ import { sep } from 'node:path';
1
2
  import { execaCommand } from 'execa';
2
3
  import commandExample from '../../util/commandExample';
3
4
  import preflightBinPath from '../../util/preflightBinPath';
@@ -95,7 +96,7 @@ export default async function noUnusedAndMissingDependencies() {
95
96
  .split('\n')
96
97
  .filter((missingDependency) => {
97
98
  return !(
98
- missingDependency.includes('./.eslintrc.cjs') &&
99
+ missingDependency.includes(`.${sep}.eslintrc.cjs`) &&
99
100
  [
100
101
  '@next/eslint-plugin-next',
101
102
  '@typescript-eslint/eslint-plugin',
@@ -23,23 +23,17 @@ export default async function prettierCheck() {
23
23
  throw error;
24
24
  }
25
25
 
26
- const ignoredFilePatterns = [
27
- // File from create-react-app not matching our formatting
28
- // https://github.com/facebook/create-react-app/blob/fdbde1f3c256b43d5386b5ae3a75083dbd8f0aff/packages/cra-template/template/src/reportWebVitals.js
29
- /src[/\\]reportWebVitals\.js$/,
30
-
31
- // Files from create-next-app not matching our formatting
32
- // https://github.com/vercel/next.js/blob/5a73859fe8d3659d52e169f97188ae422e0d2ace/packages/create-next-app/templates/default/pages/api/hello.js
33
- /pages[/\\]api[/\\]hello\.js$/,
34
- // https://github.com/vercel/next.js/blob/aacfa79ddf88e4e1488b63ac253af27110f0a151/packages/create-next-app/templates/default/pages/_app.js
35
- /pages[/\\]_app\.js$/,
36
- ];
37
-
38
26
  const unformattedFiles = normalizeNewline(stdout)
39
27
  .split('\n')
40
- // Make paths relative to the project instead of Preflight, eg:
41
- // before: ../../../../../../projects/random-color-generator-react-app/src/reportWebVitals.js
42
- // after: src/reportWebVitals.js
28
+ // Make paths relative to the project:
29
+ //
30
+ // Before:
31
+ // macOS / Linux: ../../../../../../projects/random-color-generator-react-app/src/reportWebVitals.js
32
+ // Windows: ..\..\..\..\..\..\..\..\..\..\..\projects\random-color-generator-react-app\src\reportWebVitals.js
33
+ //
34
+ // After:
35
+ // macOS / Linux: src/reportWebVitals.js
36
+ // Windows: src\reportWebVitals.js
43
37
  .map((file) => {
44
38
  return file.replace(
45
39
  `${relative(
@@ -48,13 +42,7 @@ export default async function prettierCheck() {
48
42
  )}${sep}`,
49
43
  '',
50
44
  );
51
- })
52
- .filter(
53
- (file) =>
54
- !ignoredFilePatterns.some((ignoredFilePattern) =>
55
- ignoredFilePattern.test(file),
56
- ),
57
- );
45
+ });
58
46
 
59
47
  if (unformattedFiles.length > 0) {
60
48
  throw new Error(
@@ -2,8 +2,6 @@ import { sep } from 'node:path';
2
2
  import { execaCommand } from 'execa';
3
3
  import { LintResult } from 'stylelint';
4
4
 
5
- const errorKey = 'errored' as const;
6
-
7
5
  export const supportedStylelintFileExtensions = [
8
6
  'css',
9
7
  'sass',
@@ -26,18 +24,39 @@ export default async function stylelintCheck() {
26
24
  } catch (error) {
27
25
  const { stdout } = error as { stdout: string };
28
26
 
29
- // If no Stylelint errors detected, throw the error
30
- if (!new RegExp(`"${errorKey}":`).test(stdout)) {
27
+ let stylelintResults;
28
+
29
+ try {
30
+ stylelintResults = (JSON.parse(stdout) as LintResult[]).filter(
31
+ (stylelintResult) => stylelintResult.errored === true,
32
+ );
33
+ } catch (parseError) {
31
34
  throw error;
32
35
  }
33
36
 
37
+ if (
38
+ stylelintResults.length < 1 ||
39
+ !stylelintResults.every((result) => 'errored' in result)
40
+ ) {
41
+ throw new Error(
42
+ `Unexpected shape of Stylelint JSON related to .errored properties - please report this to the UpLeveled engineering team, including the following output:
43
+ ${stdout}
44
+ `,
45
+ );
46
+ }
47
+
34
48
  throw new Error(
35
49
  `Stylelint problems found in the following files:
36
- ${(JSON.parse(stdout) as LintResult[])
37
- .filter((stylelintResult) => stylelintResult[errorKey] === true)
50
+ ${stylelintResults
38
51
  // Make paths relative to the project:
39
- // before: /home/projects/random-color-generator-react-app/src/index.css
40
- // after: src/index.css
52
+ //
53
+ // Before:
54
+ // macOS / Linux: /home/projects/random-color-generator-react-app/src/index.css
55
+ // Windows: C:\Users\Lukas\projects\random-color-generator-react-app\src\index.css
56
+ //
57
+ // After:
58
+ // macOS / Linux: src/index.css
59
+ // Windows: src\index.css
41
60
  .map(({ source }) => source!.replace(`${process.cwd()}${sep}`, ''))
42
61
  .join('\n')}
43
62