Skip to content

Instantly share code, notes, and snippets.

@geovannimp
Last active May 8, 2024 23:21
Show Gist options
  • Save geovannimp/bf54348bdfb06c9b75ed4901cf3a24fa to your computer and use it in GitHub Desktop.
Save geovannimp/bf54348bdfb06c9b75ed4901cf3a24fa to your computer and use it in GitHub Desktop.
cSpell package.json dictionary

cSpell package.json dictionary with monorepo support

Create the following files in the .vscode folder of your repo

.vscode/cspell.json

{
  "import": ["./cspell-node.config.cjs"]
}

.vscode/cspell-node.config.cjs

const fs = require('fs');
const path = require('path');

/**
 * Search for `package.json`
 * @param {string} from - search `from` directory.
 * @returns {string} - path to package.json
 */
function findNearestPackageJson(from) {
  from = path.resolve(from);
  const parent = path.dirname(from);
  if (!from || parent === from) {
    return;
  }

  const pkg = path.join(from, 'package.json');
  if (fs.existsSync(pkg)) {
    return pkg;
  }
  return findNearestPackageJson(parent);
}

/**
 * Load the nearest package.json
 * @param {string} cwd
 * @returns
 */
function loadPackage(cwd) {
  const pkgFile = findNearestPackageJson(cwd);
  console.log('found: %o', pkgFile);
  if (!pkgFile) return;
  return JSON.parse(fs.readFileSync(pkgFile, 'utf-8'));
}

const getWorkspaces = (cwd, _package) => {
  return _package.workspaces
    ? _package.workspaces.flatMap((folder) => {
        return folder.endsWith('*')
          ? fs
              .readdirSync(folder.replace('*', ''), { withFileTypes: true })
              .filter((dirent) => dirent.isDirectory())
              .map((dirent) => path.join(dirent.path, dirent.name))
          : folder;
      })
    : [];
};

function determinePackageNamesAndMethods(cwd = process.cwd()) {
  const _package = loadPackage(cwd) || {};
  const workspaces = getWorkspaces(cwd, _package);

  const rootPackageNames = Object.keys(_package.dependencies || {}).concat(
    Object.keys(_package.devDependencies || {})
  );
  const workspacePackageNames = workspaces.flatMap(
    determinePackageNamesAndMethods
  );

  const nameSet = new Set();

  for (const packageName of [...rootPackageNames, ...workspacePackageNames]) {
    nameSet.add(...packageName.replace('@', '').split('/'));
  }

  return [...nameSet];
}

module.exports = {
  words: determinePackageNamesAndMethods(),
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment