@netlify/framework-info
Advanced tools
Comparing version 0.2.0 to 0.3.0
@@ -10,6 +10,36 @@ # Changelog | ||
## [v0.2.0](https://github.com/netlify/framework-info/compare/v0.1.3...v0.2.0) | ||
## [v0.3.0](https://github.com/netlify/framework-info/compare/v0.2.0...v0.3.0) | ||
### Merged | ||
- chore: add commit linting [`#55`](https://github.com/netlify/framework-info/pull/55) | ||
- chore: add pr labeler [`#54`](https://github.com/netlify/framework-info/pull/54) | ||
- chore: fix version script [`#53`](https://github.com/netlify/framework-info/pull/53) | ||
- feat: add quasar-v0.17 [`#52`](https://github.com/netlify/framework-info/pull/52) | ||
- feat: add docusaurus v2 [`#51`](https://github.com/netlify/framework-info/pull/51) | ||
- fix(docusaurus): add missing BROWSER env variable [`#50`](https://github.com/netlify/framework-info/pull/50) | ||
- chore: gitignore vscode [`#49`](https://github.com/netlify/framework-info/pull/49) | ||
- fix(jsdoc): use typedef instead of dot notation [`#48`](https://github.com/netlify/framework-info/pull/48) | ||
- chore: apply eslint config node [`#47`](https://github.com/netlify/framework-info/pull/47) | ||
- fix(contributing): use correct repo name [`#45`](https://github.com/netlify/framework-info/pull/45) | ||
- chore: use eslint config node [`#46`](https://github.com/netlify/framework-info/pull/46) | ||
- chore(deps): lock file maintenance [`#43`](https://github.com/netlify/framework-info/pull/43) | ||
- chore(deps): lock file maintenance [`#39`](https://github.com/netlify/framework-info/pull/39) | ||
- chore(deps): lock file maintenance [`#38`](https://github.com/netlify/framework-info/pull/38) | ||
- chore(deps): lock file maintenance [`#37`](https://github.com/netlify/framework-info/pull/37) | ||
- chore(deps): lock file maintenance [`#36`](https://github.com/netlify/framework-info/pull/36) | ||
- github tools: fix fossa workflow file [`#35`](https://github.com/netlify/framework-info/pull/35) | ||
- chore(deps): lock file maintenance [`#34`](https://github.com/netlify/framework-info/pull/34) | ||
- Add `--fail` flag to `curl` for Codecov [`#33`](https://github.com/netlify/framework-info/pull/33) | ||
### Commits | ||
- Fix lock file [`a1d7de4`](https://github.com/netlify/framework-info/commit/a1d7de4c64f9e70f14635aab7aaa3f71d15aa3e4) | ||
- fix github actions workflow file for fossa | ||
[`9ab34c1`](https://github.com/netlify/framework-info/commit/9ab34c165dd8efeb582a94f16f0f842c52a6f3dc) | ||
## [v0.2.0](https://github.com/netlify/framework-info/compare/v0.1.3...v0.2.0) - 2020-10-29 | ||
### Merged | ||
- Add `hasFramework()` [`#31`](https://github.com/netlify/framework-info/pull/31) | ||
@@ -16,0 +46,0 @@ - chore(deps): update dependency eslint-config-prettier to v6.14.0 |
{ | ||
"name": "@netlify/framework-info", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"description": "Framework detection utility", | ||
@@ -17,11 +17,19 @@ "main": "./src/main.js", | ||
"test": "npm run format && npm run test:dev", | ||
"format": "run-s format:*", | ||
"format:lint": "eslint --ignore-path .gitignore --fix --cache --format=codeframe --max-warnings=0 \"src/**/*.js\" \"test/*.js\" \"test/helpers/**/*.js\"", | ||
"format:prettier": "prettier --ignore-path .gitignore --write --loglevel warn \"{src,test}/**/*.js\" \"*.{js,md,yml,json}\" \"!package-lock.json\"", | ||
"format": "run-s format:check-fix:*", | ||
"format:ci": "run-s format:check:*", | ||
"format:check-fix:lint": "run-e format:check:lint format:fix:lint", | ||
"format:check:lint": "cross-env-shell eslint $npm_package_scriptsArgs_eslint", | ||
"format:fix:lint": "cross-env-shell eslint --fix $npm_package_scriptsArgs_eslint", | ||
"format:check-fix:prettier": "run-e format:check:prettier format:fix:prettier", | ||
"format:check:prettier": "cross-env-shell prettier --check $npm_package_scriptsArgs_prettier", | ||
"format:fix:prettier": "cross-env-shell prettier --write $npm_package_scriptsArgs_prettier", | ||
"test:dev": "ava", | ||
"test:ci": "nyc -r lcovonly -r text -r json ava", | ||
"version": "auto-changelog -p --template keepachangelog --breaking-pattern breaking && npm run format:prettier && git add CHANGELOG.md" | ||
"changelog:create": "auto-changelog -p --template keepachangelog --breaking-pattern breaking", | ||
"changelog:add": "git add CHANGELOG.md", | ||
"version": "run-s changelog:create format:fix:* changelog:add" | ||
}, | ||
"husky": { | ||
"hooks": { | ||
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS", | ||
"pre-push": "npm run format" | ||
@@ -59,2 +67,6 @@ } | ||
}, | ||
"scriptsArgs": { | ||
"eslint": "--ignore-path .gitignore --cache --format=codeframe --max-warnings=0 \"src/**/*.js\" \"test/*.js\" \"test/helpers/**/*.js\"", | ||
"prettier": "--ignore-path .gitignore --loglevel warn \"{src,test}/**/*.js\" \"*.{js,md,yml,json}\" \"!package-lock.json\"" | ||
}, | ||
"dependencies": { | ||
@@ -70,2 +82,5 @@ "filter-obj": "^2.0.1", | ||
"devDependencies": { | ||
"@commitlint/cli": "^11.0.0", | ||
"@commitlint/config-conventional": "^11.0.0", | ||
"@netlify/eslint-config-node": "^1.1.3", | ||
"ajv": "^6.12.3", | ||
@@ -76,7 +91,2 @@ "auto-changelog": "^2.2.0", | ||
"del": "^5.1.0", | ||
"eslint": "^6.8.0", | ||
"eslint-config-prettier": "^6.11.0", | ||
"eslint-plugin-import": "^2.22.0", | ||
"eslint-plugin-node": "^11.1.0", | ||
"eslint-plugin-prettier": "^3.1.4", | ||
"execa": "^3.4.0", | ||
@@ -88,3 +98,2 @@ "get-bin-path": "^4.0.1", | ||
"nyc": "^15.0.0", | ||
"prettier": "^1.19.1", | ||
"test-each": "^1.8.0", | ||
@@ -91,0 +100,0 @@ "tmp-promise": "^3.0.2" |
@@ -9,3 +9,3 @@ #!/usr/bin/env node | ||
// CLI entry point | ||
const runCli = async function() { | ||
const runCli = async function () { | ||
const { projectDir, long, ignoredWatchCommand } = parseArgs() | ||
@@ -23,9 +23,4 @@ | ||
const parseArgs = function() { | ||
return yargs | ||
.command('* [projectDir]') | ||
.options(OPTIONS) | ||
.usage(USAGE) | ||
.strict() | ||
.parse() | ||
const parseArgs = function () { | ||
return yargs.command('* [projectDir]').options(OPTIONS).usage(USAGE).strict().parse() | ||
} | ||
@@ -38,8 +33,8 @@ | ||
describe: `Show more information about each framework. | ||
The output will be a JSON array.` | ||
The output will be a JSON array.`, | ||
}, | ||
ignoredWatchCommand: { | ||
string: true, | ||
describe: 'When detecting the watch command, ignore `package.json` `scripts` whose value includes this string.' | ||
} | ||
describe: 'When detecting the watch command, ignore `package.json` `scripts` whose value includes this string.', | ||
}, | ||
} | ||
@@ -51,3 +46,3 @@ | ||
const serializeFrameworks = function(frameworks, long) { | ||
const serializeFrameworks = function (frameworks, long) { | ||
if (long) { | ||
@@ -66,3 +61,3 @@ return JSON.stringify(frameworks, null, 2) | ||
const getName = function({ name }) { | ||
const getName = function ({ name }) { | ||
return name | ||
@@ -69,0 +64,0 @@ } |
@@ -9,3 +9,3 @@ const locatePath = require('locate-path') | ||
// - if `framework.configFiles` is set, one of the files must exist | ||
const usesFramework = async function( | ||
const usesFramework = async function ( | ||
{ | ||
@@ -15,6 +15,6 @@ detect: { | ||
excludedNpmDependencies: frameworkExcludedNpmDependencies, | ||
configFiles | ||
} | ||
configFiles, | ||
}, | ||
}, | ||
{ projectDir, npmDependencies } | ||
{ projectDir, npmDependencies }, | ||
) { | ||
@@ -28,17 +28,19 @@ return ( | ||
const usesNpmDependencies = function(frameworkNpmDependencies, npmDependencies) { | ||
const usesNpmDependencies = function (frameworkNpmDependencies, npmDependencies) { | ||
return ( | ||
frameworkNpmDependencies.length === 0 || | ||
frameworkNpmDependencies.some(frameworkNpmDependency => npmDependencies.includes(frameworkNpmDependency)) | ||
frameworkNpmDependencies.some((frameworkNpmDependency) => npmDependencies.includes(frameworkNpmDependency)) | ||
) | ||
} | ||
const lacksExcludedNpmDependencies = function(frameworkExcludedNpmDependencies, npmDependencies) { | ||
const lacksExcludedNpmDependencies = function (frameworkExcludedNpmDependencies, npmDependencies) { | ||
return ( | ||
frameworkExcludedNpmDependencies.length === 0 || | ||
frameworkExcludedNpmDependencies.every(frameworkNpmDependency => !npmDependencies.includes(frameworkNpmDependency)) | ||
frameworkExcludedNpmDependencies.every( | ||
(frameworkNpmDependency) => !npmDependencies.includes(frameworkNpmDependency), | ||
) | ||
) | ||
} | ||
const usesConfigFiles = async function(configFiles, projectDir) { | ||
const usesConfigFiles = async function (configFiles, projectDir) { | ||
return configFiles.length === 0 || (await locatePath(configFiles, { type: 'file', cwd: projectDir })) !== undefined | ||
@@ -45,0 +47,0 @@ } |
@@ -14,3 +14,3 @@ { | ||
}, | ||
"env": {} | ||
"env": { "BROWSER": "none" } | ||
} |
@@ -1,2 +0,2 @@ | ||
/* eslint-disable import/order */ | ||
/* eslint-disable node/global-require,import/order,import/max-dependencies */ | ||
// We purposely order the following array to ensure the most relevant framework | ||
@@ -33,5 +33,7 @@ // is always first, if several frameworks are detected at once | ||
require('./brunch.json'), | ||
require('./parcel.json') | ||
require('./parcel.json'), | ||
] | ||
/* eslint-enable node/global-require,import/order,import/max-dependencies */ | ||
module.exports = { FRAMEWORKS } |
@@ -11,22 +11,34 @@ const pFilter = require('p-filter') | ||
/** | ||
* @typedef {object} Options | ||
* @property {string} [projectDir=process.cwd()] - Project's directory | ||
* @property {string} [ignoredWatchCommand] - When guessing the watch command, ignore `package.json` `scripts` whose value includes this string | ||
*/ | ||
/** | ||
* @typedef {object} Watch | ||
* @property {string} commands - Build command, in watch mode. There might be several alternatives | ||
* @property {string} directory - Relative path to the directory where files are built, in watch mode | ||
* @property {number} port - Server port | ||
*/ | ||
/** | ||
* @typedef {object} Framework | ||
* @property {string} name - Name such as `"gatsby"` | ||
* @property {string} category - Category among `"static_site_generator"`, `"frontend_framework"` and `"build_tool"` | ||
* @property {Watch} watch - Information about the build command, in watch mode. | ||
* @property {object} env - Environment variables that should be set when calling the watch command | ||
*/ | ||
/** | ||
* Return all the frameworks used by a project. | ||
* | ||
* @param {object} [options] - Options | ||
* @param {string} [flags.projectDir=process.cwd()] - Project's directory | ||
* @param {string} [flags.ignoredWatchCommand] - When guessing the watch command, ignore `package.json` `scripts` whose value includes this string | ||
* @param {Options} [options] - Options | ||
* | ||
* @returns {object[]} frameworks - Frameworks used by a project | ||
* @returns {string} frameworks[].name - Name such as `"gatsby"` | ||
* @returns {string} frameworks[].category -Category among `"static_site_generator"`, `"frontend_framework"` and `"build_tool"` | ||
* @returns {object} frameworks[].watch - Information about the build command, in watch mode. | ||
* @returns {string[]} frameworks[].watch.commands - Build command, in watch mode. There might be several alternatives | ||
* @returns {string} frameworks[].watch.directory - Relative path to the directory where files are built, in watch mode | ||
* @returns {number} frameworks[].watch.port - Server port | ||
* @returns {object} frameworks[].env - Environment variables that should be set when calling the watch command | ||
* @returns {Framework[]} frameworks - Frameworks used by a project | ||
*/ | ||
const listFrameworks = async function(opts) { | ||
const listFrameworks = async function (opts) { | ||
const { projectDir, ignoredWatchCommand } = getOptions(opts) | ||
const { npmDependencies, scripts, runScriptCommand } = await getProjectInfo({ projectDir, ignoredWatchCommand }) | ||
const frameworks = await pFilter(FRAMEWORKS, framework => usesFramework(framework, { projectDir, npmDependencies })) | ||
const frameworkInfos = frameworks.map(framework => getFrameworkInfo(framework, { scripts, runScriptCommand })) | ||
const frameworks = await pFilter(FRAMEWORKS, (framework) => usesFramework(framework, { projectDir, npmDependencies })) | ||
const frameworkInfos = frameworks.map((framework) => getFrameworkInfo(framework, { scripts, runScriptCommand })) | ||
return frameworkInfos | ||
@@ -39,9 +51,7 @@ } | ||
* @param {string} frameworkName - Name such as `"gatsby"` | ||
* @param {object} [options] - Options | ||
* @param {string} [flags.projectDir=process.cwd()] - Project's directory | ||
* @param {string} [flags.ignoredWatchCommand] - When guessing the watch command, ignore `package.json` `scripts` whose value includes this string | ||
* @param {Options} [options] - Options | ||
* | ||
* @returns {boolean} result - Whether the project uses this framework | ||
*/ | ||
const hasFramework = async function(frameworkName, opts) { | ||
const hasFramework = async function (frameworkName, opts) { | ||
const framework = getFrameworkByName(frameworkName) | ||
@@ -58,16 +68,7 @@ const { projectDir, ignoredWatchCommand } = getOptions(opts) | ||
* @param {string} frameworkName - Name such as `"gatsby"` | ||
* @param {object} [options] - Options | ||
* @param {string} [flags.projectDir=process.cwd()] - Project's directory | ||
* @param {string} [flags.ignoredWatchCommand] - When guessing the watch command, ignore `package.json` `scripts` whose value includes this string | ||
* @param {Options} [options] - Options | ||
* | ||
* @returns {object} framework - Framework used by a project | ||
* @returns {string} framework.name - Name such as `"gatsby"` | ||
* @returns {string} framework.category -Category among `"static_site_generator"`, `"frontend_framework"` and `"build_tool"` | ||
* @returns {object} framework.watch - Information about the build command, in watch mode. | ||
* @returns {string[]} framework.watch.commands - Build command, in watch mode. There might be several alternatives | ||
* @returns {string} framework.watch.directory - Relative path to the directory where files are built, in watch mode | ||
* @returns {number} framework.watch.port - Server port | ||
* @returns {object} framework.env - Environment variables that should be set when calling the watch command | ||
* @returns {Framework} framework - Framework used by a project | ||
*/ | ||
const getFramework = async function(frameworkName, opts) { | ||
const getFramework = async function (frameworkName, opts) { | ||
const framework = getFrameworkByName(frameworkName) | ||
@@ -80,3 +81,3 @@ const { projectDir, ignoredWatchCommand } = getOptions(opts) | ||
const getFrameworkByName = function(frameworkName) { | ||
const getFrameworkByName = function (frameworkName) { | ||
const framework = FRAMEWORKS.find(({ name }) => name === frameworkName) | ||
@@ -90,7 +91,7 @@ if (framework === undefined) { | ||
const getFrameworkName = function({ name }) { | ||
const getFrameworkName = function ({ name }) { | ||
return name | ||
} | ||
const getProjectInfo = async function({ projectDir, ignoredWatchCommand }) { | ||
const getProjectInfo = async function ({ projectDir, ignoredWatchCommand }) { | ||
const { packageJsonPath, npmDependencies, scripts } = await getPackageJsonContent({ projectDir, ignoredWatchCommand }) | ||
@@ -101,5 +102,5 @@ const runScriptCommand = await getRunScriptCommand({ projectDir, packageJsonPath }) | ||
const getFrameworkInfo = function( | ||
const getFrameworkInfo = function ( | ||
{ name, category, watch: { command: frameworkWatchCommand, directory, port }, env }, | ||
{ scripts, runScriptCommand } | ||
{ scripts, runScriptCommand }, | ||
) { | ||
@@ -106,0 +107,0 @@ const watchCommands = getWatchCommands({ frameworkWatchCommand, scripts, runScriptCommand }) |
const process = require('process') | ||
// Retrieve main options | ||
const getOptions = function({ projectDir = process.cwd(), ignoredWatchCommand } = {}) { | ||
const getOptions = function ({ projectDir = process.cwd(), ignoredWatchCommand } = {}) { | ||
return { projectDir, ignoredWatchCommand } | ||
@@ -6,0 +6,0 @@ } |
@@ -7,3 +7,3 @@ const filterObj = require('filter-obj') | ||
// `dependencies|devDependencies` and `scripts` fields | ||
const getPackageJsonContent = async function({ projectDir, ignoredWatchCommand }) { | ||
const getPackageJsonContent = async function ({ projectDir, ignoredWatchCommand }) { | ||
const { packageJson, packageJsonPath } = await getPackageJson(projectDir) | ||
@@ -19,3 +19,3 @@ if (packageJson === undefined) { | ||
const getPackageJson = async function(projectDir) { | ||
const getPackageJson = async function (projectDir) { | ||
try { | ||
@@ -40,7 +40,7 @@ const result = await readPkgUp({ cwd: projectDir, normalize: false }) | ||
// Retrieve `package.json` `dependencies` and `devDependencies` names | ||
const getNpmDependencies = function({ dependencies, devDependencies }) { | ||
const getNpmDependencies = function ({ dependencies, devDependencies }) { | ||
return [...getObjectKeys(dependencies), ...getObjectKeys(devDependencies)] | ||
} | ||
const getObjectKeys = function(value) { | ||
const getObjectKeys = function (value) { | ||
if (!isPlainObj(value)) { | ||
@@ -54,3 +54,3 @@ return [] | ||
// Retrieve `package.json` `scripts` | ||
const getScripts = function({ scripts }, ignoredWatchCommand) { | ||
const getScripts = function ({ scripts }, ignoredWatchCommand) { | ||
if (!isPlainObj(scripts)) { | ||
@@ -65,3 +65,3 @@ return {} | ||
const isValidScript = function(key, value) { | ||
const isValidScript = function (key, value) { | ||
return typeof value === 'string' | ||
@@ -71,3 +71,3 @@ } | ||
// Exclude any script that includes `ignoredWatchCommand` | ||
const removeIgnoredWatchCommand = function(scripts, ignoredWatchCommand) { | ||
const removeIgnoredWatchCommand = function (scripts, ignoredWatchCommand) { | ||
if (ignoredWatchCommand === undefined) { | ||
@@ -74,0 +74,0 @@ return scripts |
@@ -6,3 +6,3 @@ const { dirname } = require('path') | ||
// Retrieve the command to run `package.json` `scripts` commands | ||
const getRunScriptCommand = async function({ projectDir, packageJsonPath = projectDir }) { | ||
const getRunScriptCommand = async function ({ projectDir, packageJsonPath = projectDir }) { | ||
if (await pathExists(`${dirname(packageJsonPath)}/yarn.lock`)) { | ||
@@ -9,0 +9,0 @@ return 'yarn' |
@@ -6,5 +6,5 @@ // Retrieve framework's watch commands. | ||
// - `framework.watch.command` | ||
const getWatchCommands = function({ frameworkWatchCommand, scripts, runScriptCommand }) { | ||
const getWatchCommands = function ({ frameworkWatchCommand, scripts, runScriptCommand }) { | ||
const scriptWatchCommands = getScriptWatchCommands(scripts, frameworkWatchCommand).map( | ||
scriptName => `${runScriptCommand} ${scriptName}` | ||
(scriptName) => `${runScriptCommand} ${scriptName}`, | ||
) | ||
@@ -18,3 +18,3 @@ if (scriptWatchCommands.length !== 0) { | ||
const getScriptWatchCommands = function(scripts, frameworkWatchCommand) { | ||
const getScriptWatchCommands = function (scripts, frameworkWatchCommand) { | ||
const preferredScripts = getPreferredScripts(scripts, frameworkWatchCommand) | ||
@@ -28,3 +28,3 @@ if (preferredScripts.length !== 0) { | ||
const getPreferredScripts = function(scripts, frameworkWatchCommand) { | ||
const getPreferredScripts = function (scripts, frameworkWatchCommand) { | ||
return Object.entries(scripts) | ||
@@ -35,3 +35,3 @@ .filter(([, scriptValue]) => scriptValue.includes(frameworkWatchCommand)) | ||
const getEntryKey = function([key]) { | ||
const getEntryKey = function ([key]) { | ||
return key | ||
@@ -41,8 +41,8 @@ } | ||
// Check if the npm script is likely to contain a watch command | ||
const isNpmWatchScript = function(scriptName) { | ||
return NPM_WATCH_SCRIPTS.some(watchScriptName => matchesNpmWatchScript(scriptName, watchScriptName)) | ||
const isNpmWatchScript = function (scriptName) { | ||
return NPM_WATCH_SCRIPTS.some((watchScriptName) => matchesNpmWatchScript(scriptName, watchScriptName)) | ||
} | ||
// We also match script names like `docs:dev` | ||
const matchesNpmWatchScript = function(scriptName, watchScriptName) { | ||
const matchesNpmWatchScript = function (scriptName, watchScriptName) { | ||
return scriptName === watchScriptName || scriptName.endsWith(`:${watchScriptName}`) | ||
@@ -49,0 +49,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
37246
16
38
719
1