@bramus/caniuse-cli
Advanced tools
Comparing version 1.0.0 to 1.1.0
137
index.js
@@ -9,2 +9,3 @@ #!/usr/bin/env node | ||
const caniuse = require('caniuse-db/fulldata-json/data-2.0.json'); | ||
const bcd = require('@mdn/browser-compat-data'); | ||
@@ -15,2 +16,3 @@ const wrap = wordwrap(80); | ||
const agents = ['chrome', 'edge', 'safari', 'firefox', 'ios_saf', 'and_chr']; | ||
const agents_bcd = ['chrome', 'edge', 'safari', 'firefox', 'safari_ios', 'chrome_android']; | ||
const defaultItemWidth = 10; | ||
@@ -266,7 +268,9 @@ | ||
} = prepStats(item.stats); | ||
console.log(clc.bold(wrap(`${item.title}`))); | ||
console.log(clc.bold(wrap(`${item.title}`))); // @TODO: Strip HTML | ||
console.log(clc.underline(`https://caniuse.com/#feat=${item.key}`)); | ||
console.log(); | ||
console.log(wrap(item.description)); | ||
console.log(); | ||
if (item.description) { | ||
console.log(wrap(item.description)); | ||
console.log(); | ||
} | ||
printTableHeader(columnWidths); | ||
@@ -282,3 +286,3 @@ for (let i = 0; i <= numRows; i++) { | ||
if (matchedNotes) { | ||
if (matchedNotes && matchedNotes.length) { | ||
console.log(); | ||
@@ -291,4 +295,4 @@ console.log('Notes by number:'); | ||
}); | ||
console.log(); | ||
} | ||
console.log(); | ||
}; | ||
@@ -314,2 +318,76 @@ | ||
const convertBCDSupportToCanIUseStat = function convertBCDSupportToCanIUseStat(agent, bcdSupport) { | ||
let versionSupport = []; | ||
// Prefill all versions with no support | ||
const allAgentVersions = caniuse.agents[agent].version_list; | ||
for (const agentVersionEntry of allAgentVersions) { | ||
versionSupport.push({ | ||
support: 'x', | ||
version: agentVersionEntry.version, | ||
}); | ||
} | ||
function process(bcdSupport, versionSupport) { | ||
// This feature was never released if version_added is false | ||
if (bcdSupport.version_added === false) { | ||
return; | ||
} | ||
// When there are multiple updates, BCD stores it as an array | ||
if (Array.isArray(bcdSupport)) { | ||
bcdSupport.forEach(subEntry => process(subEntry, versionSupport)); | ||
return; | ||
} | ||
// This feature was released, now determine the start and end offsets in the versions array | ||
let startIndex = 0; | ||
let endIndex = versionSupport.length - 1; | ||
if (bcdSupport.version_added) { | ||
startIndex = Math.max(startIndex, versionSupport.findIndex(e => e.version === bcdSupport.version_added)); | ||
} | ||
if (bcdSupport.version_removed) { | ||
endIndex = Math.min(endIndex, versionSupport.findIndex(e => e.version === bcdSupport.version_removed) - 1); | ||
} | ||
const supportChar = (bcdSupport.partial_implementation === true) ? 'a' : 'y'; | ||
for (let i = startIndex; i <= endIndex; i++) { | ||
versionSupport[i].support = supportChar; | ||
} | ||
// @TODO: Process prefix, stored in bcdSupport.prefix | ||
// @TODO: Process notes stored in bcdSupport.notes | ||
return versionSupport; | ||
} | ||
process(bcdSupport, versionSupport); | ||
// Return as object | ||
return versionSupport.reduce((toReturn, entry) => { | ||
toReturn[entry.version] = entry.support; | ||
return toReturn; | ||
}, {}); | ||
} | ||
const convertBCDEntryToCanIUseEntry = function convertBCDEntryToCanIUseEntry(entryKey, entryData) { | ||
const toReturn = { | ||
key: entryKey, | ||
title: entryData.description, | ||
description: '', | ||
spec: entryData.spec_url, | ||
notes: '', | ||
notes_by_num: [], | ||
stats: {}, // To be filled on the next few lines … | ||
}; | ||
agents_bcd.forEach((agent_bcd, i) => { | ||
// Map BCD agent to CIU agent | ||
const agent_caniuse = agents[i]; | ||
toReturn.stats[agent_caniuse] = convertBCDSupportToCanIUseStat(agent_caniuse, entryData.support[agent_bcd]); | ||
}); | ||
return toReturn; | ||
}; | ||
/** | ||
@@ -319,21 +397,48 @@ * findResult() returns `caniuse` item matching given name | ||
const findResult = function findResult(name) { | ||
const items = caniuse.data; | ||
// return directly matching item from caniuse | ||
if (caniuse.data[name] !== undefined) { | ||
return caniuse.data[name]; | ||
} | ||
// return directly matching item | ||
if (items[name] !== undefined) { | ||
return items[name]; | ||
// Check BCD | ||
let bcdResults = []; | ||
for (const section of Object.keys(bcd).filter(k => !k.startsWith('__'))) { // css, js, html, … | ||
for (const [subsectionKey, subsection] of Object.entries(bcd[section])) { // at-rules, properties, … | ||
for (const [entryKey, entry] of Object.entries(subsection)) { | ||
if (entryKey == '__compat') { | ||
if (subsectionKey === name || entry.description?.includes(name)) { | ||
bcdResults.push({ | ||
key: `mdn-${section}_${subsectionKey}`, | ||
data: entry | ||
}); | ||
} | ||
} else { | ||
if (entryKey === name || entry['__compat']?.description?.includes(name)) { | ||
bcdResults.push({ | ||
key: `mdn-${section}_${subsectionKey}_${entryKey}`, | ||
data: entry['__compat'] | ||
}); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
// find items matching by keyword or firefox_id | ||
const otherResults = Object.keys(caniuse.data).filter((key) => { | ||
// @TODO: Convert BCD format to CanIUse format | ||
bcdResults = bcdResults.map(bcdResult => convertBCDEntryToCanIUseEntry(bcdResult.key, bcdResult.data)); | ||
// find caniuse items matching by keyword or firefox_id | ||
const caniuseResults = Object.keys(caniuse.data).filter((key) => { | ||
const keywords = parseKeywords(caniuse.data[key].keywords); | ||
return caniuse.data[key].firefox_id === name | ||
|| keywords.indexOf(name) >= 0 | ||
|| keywords.includes(name) | ||
|| key.includes(name) | ||
|| keywords.join(',').includes(name); | ||
}); | ||
}) | ||
.reduce((list, key) => list.concat(caniuse.data[key]), []); | ||
// return array of matches | ||
if (otherResults.length > 0) { | ||
return otherResults.reduce((list, key) => list.concat(caniuse.data[key]), []); | ||
if (caniuseResults.length > 0 || bcdResults.length > 0) { | ||
return [...bcdResults, ...caniuseResults]; | ||
} | ||
@@ -380,3 +485,3 @@ | ||
if (res !== undefined) { | ||
if (res !== undefined && res.length) { | ||
if (Array.isArray(res)) { | ||
@@ -383,0 +488,0 @@ res.forEach((item) => printItem(item)); |
{ | ||
"name": "@bramus/caniuse-cli", | ||
"version": "1.0.0", | ||
"description": "Command line tool for Can I Use", | ||
"version": "1.1.0", | ||
"description": "Command line tool for “Can I Use…” and MDN Browser Compat Data", | ||
"keywords": [ | ||
@@ -10,3 +10,5 @@ "support", | ||
"html5", | ||
"svg" | ||
"svg", | ||
"compat", | ||
"interop" | ||
], | ||
@@ -27,2 +29,3 @@ "main": "index.js", | ||
"dependencies": { | ||
"@mdn/browser-compat-data": "^5.5.50", | ||
"caniuse-db": "^1.0.30001657", | ||
@@ -29,0 +32,0 @@ "cli-color": "^1.4.0", |
# `@bramus/caniuse-cli` | ||
Command line tool for [Can I Use](https://caniuse.com/). | ||
Command line tool for [“Can I Use …”](https://caniuse.com/) and [MDN Browser Compat Data](https://github.com/mdn/browser-compat-data) | ||
@@ -13,7 +13,6 @@  | ||
* Uses [caniuse-db](https://github.com/Fyrd/caniuse) internally, so results are displayed instantly. | ||
* Instant, offline, results powered by [caniuse-db](https://github.com/Fyrd/caniuse) and [`@mdn/browser-compat-data`](https://github.com/mdn/browser-compat-data). | ||
* Collapses versions with the same level of support in the table, just like the [“Can I Use …” website](https://caniuse.com/). | ||
* Shows notes by number. | ||
* Supports tab autocompletion in **zsh**, **bash** and **fish**. | ||
* Version Collapsing in the table | ||
* Shows notes by number | ||
* _(planned)_ MDN BCD integration | ||
@@ -30,2 +29,4 @@ ## Installation | ||
$ caniuse viewport-units | ||
$ caniuse "viewport units" | ||
$ caniuse @property | ||
``` | ||
@@ -32,0 +33,0 @@ |
123071
418
75
5
+ Added@mdn/browser-compat-data@5.6.40(transitive)