diff --git a/.babelrc b/.babelrc index 192a0cf..94d275f 100644 --- a/.babelrc +++ b/.babelrc @@ -1,8 +1,9 @@ { "plugins": [ - "transform-es2015-modules-commonjs", - "transform-export-extensions", - "transform-es2015-destructuring", - "transform-es2015-parameters" + "@babel/plugin-transform-modules-commonjs", + "@babel/plugin-proposal-export-default-from", + "@babel/plugin-proposal-export-namespace-from", + "@babel/plugin-transform-destructuring", + "@babel/plugin-transform-parameters" ] } diff --git a/.eslintignore b/.eslintignore index 60af708..a843dc4 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1 @@ -./test/fixtures +test/fixtures diff --git a/.travis.yml b/.travis.yml index 8f0d49a..d02ea0f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,8 +4,12 @@ node_js: - 7 - 6 - 5 +script: + - npm run lint + - npm run test + - npm run build after_success: - - semantic-release pre && npm publish && semantic-release post + - semantic-release notifications: email: false sudo: false diff --git a/LICENSE b/LICENSE index 7e84ea3..f09b8a2 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2016, Gajus Kuizinas (http://gajus.com/) +Copyright (c) 2020, Gajus Kuizinas (http://gajus.com/) All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/package.json b/package.json index 7212176..ce1ff87 100644 --- a/package.json +++ b/package.json @@ -6,27 +6,28 @@ }, "bin": "./dist/bin/create-index.js", "dependencies": { - "chalk": "^1.1.3", - "glob": "^7.1.1", - "lodash": "^4.16.6", - "moment": "^2.15.2", - "yargs": "^6.3.0" + "chalk": "^4.0.0", + "glob": "^7.1.6", + "lodash": "^4.17.15", + "moment": "^2.25.3", + "yargs": "^15.3.1" }, "description": "Creates ES6 ./index.js file in target directories that imports and exports all sibling files and directories.", "devDependencies": { - "babel-cli": "^6.18.0", - "babel-plugin-transform-es2015-destructuring": "^6.18.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.18.0", - "babel-plugin-transform-es2015-parameters": "^6.18.0", - "babel-plugin-transform-export-extensions": "^6.8.0", - "babel-register": "^6.18.0", - "chai": "^3.5.0", - "cross-env": "^3.1.3", - "eslint": "^3.9.1", - "eslint-config-canonical": "^4.0.0", - "husky": "^0.11.9", - "mocha": "^3.1.2", - "semantic-release": "^6.3.2" + "@babel/cli": "^7.0.0", + "@babel/core": "^7.0.0", + "@babel/plugin-proposal-export-default-from": "^7.0.0", + "@babel/plugin-proposal-export-namespace-from": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/register": "^7.0.0", + "chai": "^4.2.0", + "eslint": "^7.0.0", + "eslint-config-canonical": "^20.0.4", + "husky": "^4.2.5", + "mocha": "^7.1.2", + "semantic-release": "^17.0.7" }, "engines": { "node": ">=5" @@ -43,12 +44,16 @@ "type": "git", "url": "https://github.com/gajus/create-index" }, + "husky": { + "hooks": { + "pre-commit": "npm run test" + } + }, "scripts": { - "build": "cross-env NODE_ENV=production babel --source-maps --copy-files ./src --out-dir ./dist", + "build": "rm -fr ./dist && NODE_ENV=production babel --source-maps --copy-files ./src --out-dir ./dist", "create-index": "node ./dist/bin/create-index ./src/utilities", - "lint": "cross-env NODE_ENV=development eslint ./src ./tests", - "precommit": "npm run test", - "test": "npm run build && npm run lint && cross-env NODE_ENV=development mocha --compilers js:babel-register" + "lint": "NODE_ENV=development eslint ./src ./test", + "test": "NODE_ENV=development mocha --require @babel/register" }, - "version": "1.1.0" + "version": "0.0.0-development" } diff --git a/src/bin/create-index.js b/src/bin/create-index.js index ba5a102..fa01413 100644 --- a/src/bin/create-index.js +++ b/src/bin/create-index.js @@ -1,8 +1,10 @@ #!/usr/bin/env node +/* eslint-disable filenames/match-regex */ + import yargs from 'yargs'; import { - writeIndexCli + writeIndexCli, } from '../utilities'; const argv = yargs @@ -12,66 +14,66 @@ const argv = yargs alias: 'r', default: false, description: 'Create/update index files recursively. Halts on any unsafe "index.js" files.', - type: 'boolean' - } + type: 'boolean', + }, }) .options({ ignoreUnsafe: { alias: 'i', default: false, description: 'Ignores unsafe "index.js" files instead of halting.', - type: 'boolean' - } + type: 'boolean', + }, }) .options({ ignoreDirectories: { alias: 'd', default: false, description: 'Ignores importing directories into the index file, even if they have a safe "index.js".', - type: 'boolean' - } + type: 'boolean', + }, }) .options({ update: { alias: 'u', default: false, description: 'Updates only previously created index files (recursively).', - type: 'boolean' - } + type: 'boolean', + }, }) .options({ banner: { description: 'Add a custom banner at the top of the index file', - type: 'string' - } + type: 'string', + }, }) .options({ extensions: { alias: 'x', default: ['js'], description: 'Allows some extensions to be parsed as valid source. First extension will always be preferred to homonyms with another allowed extension.', - type: 'array' - } + type: 'array', + }, }) .options({ outputFile: { alias: 'o', default: 'index.js', description: 'Output file', - type: 'string' - } + type: 'string', + }, }) .example( 'create-index ./src ./src/utilities', - 'Creates or updates an existing create-index index file in the target (./src, ./src/utilities) directories.' + 'Creates or updates an existing create-index index file in the target (./src, ./src/utilities) directories.', ) .example( 'create-index --update ./src ./tests', - 'Finds all create-index index files in the target directories and descending directories. Updates found index files.' + 'Finds all create-index index files in the target directories and descending directories. Updates found index files.', ) .example( 'create-index ./src --extensions js jsx', - 'Creates or updates an existing create-index index file in the target (./src) directory for both .js and .jsx extensions.' + 'Creates or updates an existing create-index index file in the target (./src) directory for both .js and .jsx extensions.', ) .argv; @@ -80,7 +82,7 @@ writeIndexCli(argv._, { extensions: argv.extensions, ignoreDirectories: argv.ignoreDirectories, ignoreUnsafe: argv.ignoreUnsafe, - recursive: argv.recursive, outputFile: argv.outputFile, - updateIndex: argv.update + recursive: argv.recursive, + updateIndex: argv.update, }); diff --git a/src/index.js b/src/index.js index 47e3103..a5a240a 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,4 @@ export { findIndexFiles, - writeIndex + writeIndex, } from './utilities'; diff --git a/src/utilities/constants.js b/src/utilities/constants.js index acdc67c..bf67538 100644 --- a/src/utilities/constants.js +++ b/src/utilities/constants.js @@ -1,2 +1 @@ -// eslint-disable-next-line export const CREATE_INDEX_PATTERN = /(?:^|[\n\r]+)\/\/ @create-index\s?({.*})?[\n\r]+/; diff --git a/src/utilities/findIndexFiles.js b/src/utilities/findIndexFiles.js index a27b855..6e19b04 100644 --- a/src/utilities/findIndexFiles.js +++ b/src/utilities/findIndexFiles.js @@ -4,7 +4,8 @@ import glob from 'glob'; import validateTargetDirectory from './validateTargetDirectory'; export default (directoryPath, options = {}) => { - let fileName, targetDirectories; + let fileName; + let targetDirectories; fileName = options.fileName || 'index.js'; fileName = './**/' + fileName; @@ -13,8 +14,8 @@ export default (directoryPath, options = {}) => { targetDirectories = _.filter(targetDirectories, (targetDirectoryPath) => { return validateTargetDirectory(path.dirname(targetDirectoryPath), { + outputFile: options.fileName, silent: options.silent, - outputFile: options.fileName }); }); diff --git a/src/utilities/hasIndex.js b/src/utilities/hasIndex.js index e8dc4f5..953a9d2 100644 --- a/src/utilities/hasIndex.js +++ b/src/utilities/hasIndex.js @@ -8,7 +8,7 @@ export default (directoryPath, options = {}) => { fs.statSync(indexPath); return true; - } catch (error) { + } catch { return false; } }; diff --git a/src/utilities/log.js b/src/utilities/log.js index 06b6601..88a2fde 100644 --- a/src/utilities/log.js +++ b/src/utilities/log.js @@ -2,6 +2,6 @@ import chalk from 'chalk'; import moment from 'moment'; export default (...append) => { - // eslint-disable-next-line + // eslint-disable-next-line no-console console.log(chalk.dim('[' + moment().format('HH:mm:ss') + ']'), ...append); }; diff --git a/src/utilities/readDirectory.js b/src/utilities/readDirectory.js index ddf5f41..d984ad8 100644 --- a/src/utilities/readDirectory.js +++ b/src/utilities/readDirectory.js @@ -17,7 +17,7 @@ const hasMultipleExtensions = (fileName) => { }; const isSafeName = (fileName) => { - return /^[a-z_][a-z0-9._]*$/i.test(fileName); + return /^[_a-z][\w.]*$/i.test(fileName); }; const stripExtension = (fileName) => { @@ -27,7 +27,7 @@ const stripExtension = (fileName) => { return fileName; } - return fileName.substr(0, pos); + return fileName.slice(0, Math.max(0, pos)); }; const removeDuplicates = (files, preferredExtension) => { @@ -79,7 +79,7 @@ export default (directoryPath, options = {}) => { const { extensions = ['js'], config = {}, - ignoreDirectories = false + ignoreDirectories = false, } = options; let children; @@ -106,8 +106,8 @@ export default (directoryPath, options = {}) => { return false; } - if (!isDirectory && !extensions.some((ext) => { - return _.endsWith(fileName, '.' + ext); + if (!isDirectory && !extensions.some((extension) => { + return _.endsWith(fileName, '.' + extension); })) { return false; } diff --git a/src/utilities/readIndexConfig.js b/src/utilities/readIndexConfig.js index b702b73..d6c14b4 100644 --- a/src/utilities/readIndexConfig.js +++ b/src/utilities/readIndexConfig.js @@ -21,10 +21,10 @@ export default (directoryPath, options = {}) => { try { config = JSON.parse(configLine); - } catch (error) { + } catch { throw new Error( '"' + indexPath + '" contains invalid configuration object.\n' + - 'Configuration object must be a valid JSON.' + 'Configuration object must be a valid JSON.', ); } diff --git a/src/utilities/validateTargetDirectory.js b/src/utilities/validateTargetDirectory.js index 7649234..e8a780f 100644 --- a/src/utilities/validateTargetDirectory.js +++ b/src/utilities/validateTargetDirectory.js @@ -8,7 +8,7 @@ export default (targetDirectory, options = {}) => { try { stats = fs.statSync(targetDirectory); - } catch (error) { + } catch { if (silent) { return false; } else { @@ -28,7 +28,7 @@ export default (targetDirectory, options = {}) => { try { fs.statSync(indexFilePath); - } catch (error) { + } catch { return true; } diff --git a/src/utilities/writeIndex.js b/src/utilities/writeIndex.js index 27e65aa..8d0902b 100644 --- a/src/utilities/writeIndex.js +++ b/src/utilities/writeIndex.js @@ -10,7 +10,8 @@ import sortByDepth from './sortByDepth'; export default (directoryPaths, options = {}) => { const sortedDirectoryPaths = sortByDepth(directoryPaths) .filter((directoryPath) => { - return validateTargetDirectory(directoryPath, {silent: options.ignoreUnsafe, outputFile: options.outputFile}); + return validateTargetDirectory(directoryPath, {outputFile: options.outputFile, + silent: options.ignoreUnsafe}); }); _.forEach(sortedDirectoryPaths, (directoryPath) => { diff --git a/src/utilities/writeIndexCli.js b/src/utilities/writeIndexCli.js index e69bd87..5575d5d 100644 --- a/src/utilities/writeIndexCli.js +++ b/src/utilities/writeIndexCli.js @@ -26,10 +26,10 @@ export default (directoryPaths, options = {}) => { } if (options.updateIndex || options.recursive) { - sortedDirectoryPaths = _.map(sortedDirectoryPaths, (dir) => { - return findIndexFiles(dir, { + sortedDirectoryPaths = _.map(sortedDirectoryPaths, (directory) => { + return findIndexFiles(directory, { fileName: options.updateIndex ? options.outputFile || 'index.js' : '*', - silent: options.updateIndex || options.ignoreUnsafe + silent: options.updateIndex || options.ignoreUnsafe, }); }); sortedDirectoryPaths = _.flatten(sortedDirectoryPaths); @@ -40,7 +40,8 @@ export default (directoryPaths, options = {}) => { } sortedDirectoryPaths = sortedDirectoryPaths.filter((directoryPath) => { - return validateTargetDirectory(directoryPath, {silent: options.ignoreUnsafe, outputFile: options.outputFile}); + return validateTargetDirectory(directoryPath, {outputFile: options.outputFile, + silent: options.ignoreUnsafe}); }); _.forEach(sortedDirectoryPaths, (directoryPath) => { @@ -52,12 +53,12 @@ export default (directoryPaths, options = {}) => { config, extensions: options.extensions, ignoreDirectories: options.ignoreDirectories, - silent: options.ignoreUnsafe + silent: options.ignoreUnsafe, }); const indexCode = createIndexCode(siblings, { banner: options.banner, - config + config, }); const indexFilePath = path.resolve(directoryPath, options.outputFile || 'index.js'); @@ -65,12 +66,12 @@ export default (directoryPaths, options = {}) => { try { existingIndexCode = fs.readFileSync(indexFilePath, 'utf8'); - /* eslint-disable no-empty */ - } catch (error) { + /* eslint-disable no-empty */ + } catch { } - /* eslint-enable no-empty */ + /* eslint-enable no-empty */ fs.writeFileSync(indexFilePath, indexCode); diff --git a/test/.eslintrc b/test/.eslintrc new file mode 100644 index 0000000..7d7251b --- /dev/null +++ b/test/.eslintrc @@ -0,0 +1,3 @@ +{ + "extends": "canonical/mocha" +} diff --git a/test/createIndexCode.js b/test/createIndexCode.js index d9b259b..ba707ed 100644 --- a/test/createIndexCode.js +++ b/test/createIndexCode.js @@ -1,7 +1,7 @@ /* eslint-disable no-restricted-syntax */ import { - expect + expect, } from 'chai'; import createIndexCode from '../src/utilities/createIndexCode'; import codeExample from './codeExample'; @@ -60,7 +60,7 @@ export { default as foo } from './foo'; context('with config', () => { it('should append config', () => { const config = { - ignore: ['/^zoo/'] + ignore: ['/^zoo/'], }; const indexCode = createIndexCode(['foo', 'bar'], {config}); diff --git a/test/findIndexFiles.js b/test/findIndexFiles.js index 4323eed..783158c 100644 --- a/test/findIndexFiles.js +++ b/test/findIndexFiles.js @@ -1,6 +1,6 @@ import path from 'path'; import { - expect + expect, } from 'chai'; import glob from 'glob'; import findIndexFiles from '../src/utilities/findIndexFiles'; diff --git a/test/readDirectory.js b/test/readDirectory.js index 90c1fd0..6847950 100644 --- a/test/readDirectory.js +++ b/test/readDirectory.js @@ -1,6 +1,6 @@ import path from 'path'; import { - expect + expect, } from 'chai'; import readDirectory from '../src/utilities/readDirectory'; @@ -71,7 +71,7 @@ describe('readDirectory()', () => { }); context('target directory contains non js files, and allowing only jsx', () => { it('prefers file', () => { - const options = { extensions: ['jsx'] }; + const options = {extensions: ['jsx']}; const names = readDirectory(path.resolve(fixturesPath, 'children-files-alt-extension'), options); expect(names).to.deep.equal(['bar.jsx']); @@ -79,7 +79,7 @@ describe('readDirectory()', () => { }); context('target directory contains non js files, and allowing both js and jsx', () => { it('prefers file', () => { - const options = { extensions: ['js', 'jsx'] }; + const options = {extensions: ['js', 'jsx']}; const names = readDirectory(path.resolve(fixturesPath, 'children-files-alt-extension'), options); expect(names).to.deep.equal(['bar.jsx', 'present.js']); @@ -87,7 +87,7 @@ describe('readDirectory()', () => { }); context('target directory contains homonyms files, and allowing both js and jsx, will prefer JS as it is first extension listed', () => { it('prefers file', () => { - const options = { extensions: ['js', 'jsx'] }; + const options = {extensions: ['js', 'jsx']}; const names = readDirectory(path.resolve(fixturesPath, 'children-files-alt-extension-with-homonyms'), options); expect(names).to.deep.equal(['bar.js', 'present.js']); @@ -95,7 +95,7 @@ describe('readDirectory()', () => { }); context('target directory contains homonyms files, and allowing both js and jsx, will prefer JSX as it is first extension listed', () => { it('prefers file', () => { - const options = { extensions: ['jsx', 'js'] }; + const options = {extensions: ['jsx', 'js']}; const names = readDirectory(path.resolve(fixturesPath, 'children-files-alt-extension-with-homonyms'), options); expect(names).to.deep.equal(['bar.jsx', 'present.js']); diff --git a/test/readIndexConfig.js b/test/readIndexConfig.js index 8592db5..f8c8bc4 100644 --- a/test/readIndexConfig.js +++ b/test/readIndexConfig.js @@ -1,6 +1,6 @@ import path from 'path'; import { - expect + expect, } from 'chai'; import readIndexConfig from '../src/utilities/readIndexConfig'; @@ -8,15 +8,15 @@ const fixtures = { noIndex: path.resolve(__dirname, 'fixtures/read-index-config/no-index'), withConfig: path.resolve(__dirname, 'fixtures/read-index-config/with-config'), withInvalidConfig: path.resolve(__dirname, 'fixtures/read-index-config/with-invalid-config'), - withoutConfig: path.resolve(__dirname, 'fixtures/read-index-config/without-config') + withoutConfig: path.resolve(__dirname, 'fixtures/read-index-config/without-config'), }; const expectedValues = { noIndex: {}, withConfig: { - ignore: ['/foo.js$/'] + ignore: ['/foo.js$/'], }, - withoutConfig: {} + withoutConfig: {}, }; describe('readIndexConfig()', () => { diff --git a/test/sortByDepth.js b/test/sortByDepth.js index 64059a0..9173c69 100644 --- a/test/sortByDepth.js +++ b/test/sortByDepth.js @@ -1,7 +1,7 @@ import { - expect + expect, } from 'chai'; -import sortByDepth from './../src/utilities/sortByDepth'; +import sortByDepth from '../src/utilities/sortByDepth'; describe('sortByDepth()', () => { it('sorts from deepest to the most shallow', () => { @@ -9,7 +9,7 @@ describe('sortByDepth()', () => { '/b', '/a', '/a/b/c', - '/a/b' + '/a/b', ]; const sortedPaths = sortByDepth(paths); diff --git a/test/validateTargetDirectory.js b/test/validateTargetDirectory.js index 44f7c55..56ddd2c 100644 --- a/test/validateTargetDirectory.js +++ b/test/validateTargetDirectory.js @@ -2,7 +2,7 @@ import path from 'path'; import { - expect + expect, } from 'chai'; import validateTargetDirectory from '../src/utilities/validateTargetDirectory'; diff --git a/test/writeIndex.js b/test/writeIndex.js index be947bb..a03a00a 100644 --- a/test/writeIndex.js +++ b/test/writeIndex.js @@ -3,7 +3,7 @@ import fs from 'fs'; import path from 'path'; import { - expect + expect, } from 'chai'; import writeIndex from '../src/utilities/writeIndex'; import codeExample from './codeExample'; @@ -40,7 +40,7 @@ export { default as foo } from './foo.js'; it('creates index with config in target directory', () => { const indexFilePath = path.resolve(fixturesPath, 'with-config/index.js'); - // eslint-disable-next-line + // eslint-disable-next-line quotes const ignoredExportLine = `export { default as bar } from './bar.js';`; appendToFile(indexFilePath, ignoredExportLine);