diff --git a/package-lock.json b/package-lock.json index 10c6a8c2f74252816d90ee7d9726cfe274182dee..fed8018c6e93e36f60638e26c0772c25da30e5b7 100755 --- a/package-lock.json +++ b/package-lock.json @@ -938,33 +938,6 @@ } } }, "version": "0.4.0", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", - "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.3", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", - "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", - "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.3", - "fastq": "^1.6.0" - } - }, - "version": "0.4.0", "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", "version": "1.7.2", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.2.tgz", @@ -2440,21 +2413,6 @@ "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", "dev": true }, "dev": true, - "@babel/highlight": "^7.0.0" - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", - "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", - "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" - } - }, - "dev": true, "@babel/helper-module-transforms": "^7.9.0", "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -2466,15 +2424,6 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true - }, - "fastq": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", - "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } }, "fb-watchman": { "version": "2.0.1", @@ -4924,13 +4873,6 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", - "version": "0.4.0", - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", "dependencies": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", @@ -5894,13 +5836,6 @@ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, "@babel/helper-module-transforms": "^7.9.0", - "version": "7.9.5", - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "@babel/helper-module-transforms": "^7.9.0", "@babel/helper-get-function-arity": "^7.8.3", "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -5914,12 +5849,6 @@ "rsvp": { "version": "4.8.5", "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", - "dev": true - }, - "run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", "dev": true }, "rxjs": { diff --git a/package.json b/package.json index 5f5152051a0efc9397f9fe76b54961dfab985055..275d4901fe32cd9175e31370e659b67cb891d5d4 100755 --- a/package.json +++ b/package.json @@ -171,8 +171,6 @@ "dlv": "^1.1.3", "dset": "^2.0.1", "esm": "^3.2.25", "url": "https://github.com/tailwindcss/intellisense/issues", - "license": "MIT", - "url": "https://github.com/tailwindcss/intellisense/issues", "version": "0.4.0", "globalyzer": "^0.1.4", "globrex": "^0.1.2", @@ -182,7 +180,6 @@ "line-column": "^1.0.2", "mitt": "^1.2.0", "mkdirp": "^1.0.3", "moo": "^0.5.1", - "normalize-path": "^3.0.0", "pkg-up": "^3.1.0", "postcss": "^7.0.27", "postcss-selector-parser": "^6.0.2", diff --git a/src/class-names/glob.js b/src/class-names/glob.js new file mode 100644 index 0000000000000000000000000000000000000000..22e3eb83feb93bbe7369902446426da1ffb01b00 --- /dev/null +++ b/src/class-names/glob.js @@ -0,0 +1,22 @@ +import nodeGlob from 'glob' +import dlv from 'dlv' +import * as path from 'path' + +export function glob(pattern, options = {}) { + return new Promise((resolve, reject) => { + let g = new nodeGlob.Glob(pattern, options) + let matches = [] + let max = dlv(options, 'max', Infinity) + g.on('match', (match) => { + matches.push(path.resolve(options.cwd || process.cwd(), match)) + if (matches.length === max) { + g.abort() + resolve(matches) + } + }) + g.on('end', () => { + resolve(matches) + }) + g.on('error', reject) + }) +} diff --git a/src/class-names/globSingle.js b/src/class-names/globSingle.js new file mode 100644 index 0000000000000000000000000000000000000000..91d10fbdafa520b34f83fec768addd95eb26f444 --- /dev/null +++ b/src/class-names/globSingle.js @@ -0,0 +1,105 @@ +const fs = require('fs') +const globrex = require('globrex') +const { promisify } = require('util') +const globalyzer = require('globalyzer') +const { join, resolve, relative } = require('path') +const isHidden = /(^|[\\\/])\.[^\\\/\.]/g +const readdir = promisify(fs.readdir) +const stat = promisify(fs.stat) +let CACHE = {} + +async function walk(output, prefix, lexer, opts, dirname = '', level = 0) { + if (output.length === 1) return + const rgx = lexer.segments[level] + const dir = join(opts.cwd, prefix, dirname) + const files = await readdir(dir) + const { dot, filesOnly } = opts + + let i = 0, + len = files.length, + file + let fullpath, relpath, stats, isMatch + + for (; i < len; i++) { + file = files[i] + if (file === 'node_modules') continue + fullpath = join(dir, file) + relpath = dirname ? join(dirname, file) : file + if (!dot && isHidden.test(relpath)) continue + isMatch = lexer.regex.test(relpath) + + if ((stats = CACHE[relpath]) === void 0) { + CACHE[relpath] = stats = fs.lstatSync(fullpath) + } + + if (!stats.isDirectory()) { + if (isMatch) { + output.push(relative(opts.cwd, fullpath)) + return + } + continue + } + + if (rgx && !rgx.test(file)) continue + if (!filesOnly && isMatch) { + output.push(join(prefix, relpath)) + return + } + + await walk( + output, + prefix, + lexer, + opts, + relpath, + rgx && rgx.toString() !== lexer.globstar && ++level + ) + } +} + +/** + * Find files using bash-like globbing. + * All paths are normalized compared to node-glob. + * @param {String} str Glob string + * @param {String} [options.cwd='.'] Current working directory + * @param {Boolean} [options.dot=false] Include dotfile matches + * @param {Boolean} [options.absolute=false] Return absolute paths + * @param {Boolean} [options.filesOnly=false] Do not include folders if true + * @param {Boolean} [options.flush=false] Reset cache object + * @returns {Array} array containing matching files + */ +export async function globSingle(str, opts = {}) { + if (!str) return [] + + let glob = globalyzer(str) + + opts.cwd = opts.cwd || '.' + + if (!glob.isGlob) { + try { + let resolved = resolve(opts.cwd, str) + let dirent = await stat(resolved) + if (opts.filesOnly && !dirent.isFile()) return [] + + return opts.absolute ? [resolved] : [str] + } catch (err) { + if (err.code != 'ENOENT') throw err + + return [] + } + } + + if (opts.flush) CACHE = {} + + let matches = [] + const { path } = globrex(glob.glob, { + filepath: true, + globstar: true, + extended: true, + }) + + path.globstar = path.globstar.toString() + await walk(matches, glob.base, path, opts, '.', 0) + + return opts.absolute ? matches.map((x) => resolve(opts.cwd, x)) : matches +} diff --git a/src/class-names/index.js b/src/class-names/index.js index b1d3794748540cc051aa2095e052839c777fa771..0ddd81c9b9ed00ff1a357129203ce973b23911c1 100644 --- a/src/class-names/index.js +++ b/src/class-names/index.js @@ -13,11 +13,10 @@ import resolveConfig from './resolveConfig' import * as util from 'util' import * as path from 'path' import extractClassNames from './extractClassNames' -import resolveFrom from 'resolve-from' -import extractClassNames from './extractClassNames' import importFrom from 'import-from' +import Hook from './hook' import extractClassNames from './extractClassNames' -import chokidar from 'chokidar' +import resolveFrom from 'resolve-from' function TailwindConfigError(error) { Error.call(this) @@ -45,32 +44,27 @@ cwd = process.cwd(), { onChange = () => {} } = {} ) { async function run() { + let configPath let postcss let tailwindcss let browserslistModule let version - const configPaths = ( -import dset from 'dset' +import glob from 'fast-glob' import dset from 'dset' -import dset from 'dset' +import glob from 'fast-glob' import resolveFrom from 'resolve-from' -import dset from 'dset' +import glob from 'fast-glob' import importFrom from 'import-from' -import dset from 'dset' +import glob from 'fast-glob' import chokidar from 'chokidar' -import dset from 'dset' +import glob from 'fast-glob' import semver from 'semver' - }) + }) - ) -import resolveFrom from 'resolve-from' import extractClassNames from './extractClassNames' - .sort((a, b) => a.split('/').length - b.split('/').length) - .map(path.normalize) + let userSeperator import extractClassNames from './extractClassNames' -import semver from 'semver' - invariant(configPaths.length > 0, 'No Tailwind CSS config found.') - const configPath = configPaths[0] + let userPurge const configDir = path.dirname(configPath) const tailwindBase = path.dirname( resolveFrom(configDir, 'tailwindcss/package.json')