diff options
Diffstat (limited to 'node_modules/doiuse/utils')
| -rw-r--r-- | node_modules/doiuse/utils/getFiles.js | 19 | ||||
| -rw-r--r-- | node_modules/doiuse/utils/kebabToCamel.js | 8 | ||||
| -rw-r--r-- | node_modules/doiuse/utils/util.js | 79 |
3 files changed, 106 insertions, 0 deletions
diff --git a/node_modules/doiuse/utils/getFiles.js b/node_modules/doiuse/utils/getFiles.js new file mode 100644 index 00000000..3e939420 --- /dev/null +++ b/node_modules/doiuse/utils/getFiles.js @@ -0,0 +1,19 @@ +import { readdir } from 'node:fs/promises'; +import { resolve } from 'node:path'; + +/** + * recursively get all files in a directory + * @param {string} directory the directory to read + * @yields {string} the path to each file + * @return {AsyncGenerator<string>} the path to each file + */ +export async function* getFiles(directory) { + for (const entry of await readdir(directory, { withFileTypes: true })) { + const path = resolve(directory, entry.name); + if (entry.isDirectory()) { + yield* getFiles(path); + } else { + yield path; + } + } +} diff --git a/node_modules/doiuse/utils/kebabToCamel.js b/node_modules/doiuse/utils/kebabToCamel.js new file mode 100644 index 00000000..c7237c3c --- /dev/null +++ b/node_modules/doiuse/utils/kebabToCamel.js @@ -0,0 +1,8 @@ +/** + * given a kebab-case string, returns a camelCase string + * @param {string} kebab the kebab-case string + * @return {string} the camelCase string + */ +export function kebabToCamel(kebab) { + return kebab.replaceAll(/-([a-z])/g, (match, letter) => letter.toUpperCase()); +} diff --git a/node_modules/doiuse/utils/util.js b/node_modules/doiuse/utils/util.js new file mode 100644 index 00000000..e9b323e9 --- /dev/null +++ b/node_modules/doiuse/utils/util.js @@ -0,0 +1,79 @@ +import { agents } from 'caniuse-lite'; + +/** @typedef {RegExp|string|((value:string) => boolean)} FeatureCheck */ + +/** + * @param {string} browserKey + * @param {string[]} [versions] + * @return {string} + */ +export function formatBrowserName(browserKey, versions) { + const entry = agents[browserKey]; + const browserName = entry ? entry.browser : null; + if (!versions) { + return browserName || ''; + } + return (`${browserName} (${versions.join(',')})`); +} + +/** + * + * @param {FeatureCheck|FeatureCheck[]} check + * @param {?string|undefined} candidate + */ +export function performFeatureCheck(check, candidate) { + if (check == null || candidate == null) return false; + if (check instanceof RegExp) { + return check.test(candidate); + } + switch (typeof check) { + case 'string': + return candidate.includes(check); + case 'function': + return check(candidate); + case 'boolean': + return check; + case 'object': + if (Array.isArray(check)) { + return check.some((c) => performFeatureCheck(c, candidate)); + } + // Fallthrough + default: + console.error(check); + throw new TypeError(`Unexpected feature check: ${check}`); + } +} + +/** + * @param {FeatureCheck|FeatureCheck[]} selector + * @return {(rule:import('postcss').ChildNode) => boolean} + */ +export function checkSelector(selector) { + return (rule) => rule.type === 'rule' + && performFeatureCheck(selector, rule.selector); +} + +/** + * @param {FeatureCheck|FeatureCheck[]} [name] + * @param {FeatureCheck|FeatureCheck[]} [parameters] + * @return {(rule:import('postcss').ChildNode) => boolean} + */ +export function checkAtRule(name, parameters) { + return (rule) => rule.type === 'atrule' + && performFeatureCheck(name, rule.name) + && (!parameters || performFeatureCheck(parameters, rule.params)); +} + +/** + * @see https://drafts.csswg.org/css-values/#lengths + * @see https://drafts.csswg.org/css-values/#number-value + * @param {string[]} units + * @return {(rule:import('postcss').ChildNode) => boolean} + */ +export function checkCSSLengthUnits(...units) { + const regexp = new RegExp(`(\\+-)?[\\d.]*\\.?\\d+(e(\\+-)?\\d+)?(${units.join('|')})`, 'i'); + return (rule) => ( + (rule.type === 'decl') ? performFeatureCheck(regexp, rule.value) + : ((rule.type === 'atrule') ? performFeatureCheck(regexp, rule.params) + : false)); +} |
