diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8c5a03f..eb92fc9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,14 +8,14 @@ jobs: test: strategy: matrix: - node: [18, 20, 22] + node: [18, 20, 22, 24] os: [ubuntu-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - run: git config --global core.autocrlf input - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - name: Use Node.js ${{ matrix.node }} - uses: actions/setup-node@v4 + uses: actions/setup-node@v7 with: node-version: ${{ matrix.node }} - run: npm install diff --git a/index.js b/index.js index 266c912..7cca0e5 100755 --- a/index.js +++ b/index.js @@ -1,6 +1,6 @@ #!/usr/bin/env node -import fs from 'fs-extra' +import fs from 'node:fs/promises' import path from 'path' import prettyHrtime from 'pretty-hrtime' @@ -286,40 +286,38 @@ function css(css, file) { }) async function outputFile(file, string) { - const fileExists = await fs.pathExists(file) + const fileExists = await fs.access(file).then( + () => true, + () => false, + ) const currentValue = fileExists ? await fs.readFile(file, 'utf8') : null if (currentValue === string) return - return fs.outputFile(file, string) + await fs.mkdir(path.dirname(file), { recursive: true }) + return fs.writeFile(file, string) } } function dependencies(results) { if (!Array.isArray(results)) results = [results] - const messages = [] + return results.flatMap((result) => { + if (result.messages.length <= 0) return [] - results.forEach((result) => { - if (result.messages <= 0) return - - result.messages - .filter((msg) => - msg.type === 'dependency' || msg.type === 'dir-dependency' ? msg : '', + return result.messages + .filter( + (msg) => msg.type === 'dependency' || msg.type === 'dir-dependency', ) .map(depGraph.add) - .forEach((dependency) => { + .map((dependency) => { if (dependency.type === 'dir-dependency') { - messages.push( - dependency.glob - ? path.join(dependency.dir, dependency.glob) - : dependency.dir, - ) - } else { - messages.push(dependency.file) + return dependency.glob + ? path.join(dependency.dir, dependency.glob) + : dependency.dir } + + return dependency.file }) }) - - return messages } function printVerbose(message) { diff --git a/package.json b/package.json index 6e1f94e..70194cd 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,6 @@ "dependencies": { "chokidar": "^3.3.0", "dependency-graph": "^1.0.0", - "fs-extra": "^11.0.0", "picocolors": "^1.0.0", "postcss-load-config": "^5.0.0", "postcss-reporter": "^7.0.0", @@ -36,12 +35,12 @@ "coveralls": "^3.0.0", "eslint": "^9.22.0", "eslint-config-problems": "9.0.0", - "globals": "^16.0.0", + "globals": "^17.0.0", "postcss": "^8.0.4", "postcss-import": "^16.0.0", - "prettier": "~3.6.0", + "prettier": "~3.9.0", "sugarss": "^5.0.0", - "uuid": "^11.0.0" + "uuid": "^13.0.0" }, "peerDependencies": { "postcss": "^8.0.0" diff --git a/test/ext.js b/test/ext.js index 329f2c4..675939d 100644 --- a/test/ext.js +++ b/test/ext.js @@ -1,6 +1,6 @@ import test from 'ava' -import fs from 'fs-extra' +import fs from 'node:fs/promises' import path from 'path' import cli from './helpers/cli.js' @@ -20,7 +20,12 @@ test('--ext works', async (t) => { ]) t.falsy(error, stderr) - t.truthy(await fs.pathExists(path.join(dir, 'a.css'))) + t.truthy( + await fs.access(path.join(dir, 'a.css')).then( + () => true, + () => false, + ), + ) }) test('--ext works with no leading dot', async (t) => { @@ -37,5 +42,10 @@ test('--ext works with no leading dot', async (t) => { ]) t.falsy(error, stderr) - t.truthy(await fs.pathExists(path.join(dir, 'a.css'))) + t.truthy( + await fs.access(path.join(dir, 'a.css')).then( + () => true, + () => false, + ), + ) }) diff --git a/test/glob.js b/test/glob.js index 863fc39..38743f7 100644 --- a/test/glob.js +++ b/test/glob.js @@ -30,3 +30,29 @@ test('works with glob patterns', async (t) => { await read('test/fixtures/glob/s.css'), ) }) + +test('works with directory input', async (t) => { + const output = tmp() + + const { error, stderr } = await cli([ + 'test/fixtures/glob', + '-d', + output, + '--no-map', + ]) + + t.falsy(error, stderr) + + t.is( + await read(path.join(output, 'a.css')), + await read('test/fixtures/glob/a.css'), + ) + t.is( + await read(path.join(output, 'b.css')), + await read('test/fixtures/glob/b.css'), + ) + t.is( + await read(path.join(output, 's.css')), + await read('test/fixtures/glob/s.css'), + ) +}) diff --git a/test/helpers/clean.js b/test/helpers/clean.js index 73bb191..7591d7b 100644 --- a/test/helpers/clean.js +++ b/test/helpers/clean.js @@ -1,8 +1,10 @@ -import fs from 'fs-extra' +import fs from 'node:fs/promises' Promise.all([ - fs.emptyDir('./test/fixtures/.tmp/'), - fs.remove('./coverage'), + fs + .rm('./test/fixtures/.tmp/', { recursive: true, force: true }) + .then(() => fs.mkdir('./test/fixtures/.tmp/', { recursive: true })), + fs.rm('./coverage', { recursive: true, force: true }), ]).catch((err) => { console.error(err) process.exit(1) diff --git a/test/helpers/env.js b/test/helpers/env.js index 017df87..0fd9549 100644 --- a/test/helpers/env.js +++ b/test/helpers/env.js @@ -1,18 +1,24 @@ -import fs from 'fs-extra' +import fs from 'node:fs/promises' import path from 'path' import { glob } from 'tinyglobby' import tmp from './tmp.js' -export default function (config, fixtures = '**/*', extension = 'cjs') { +export default async function (config, fixtures = '**/*', extension = 'cjs') { const dir = tmp() - return Promise.all([ - glob(fixtures, { cwd: 'test/fixtures' }).then((list) => { - return list.map((item) => { - return fs.copy(path.join('test/fixtures', item), path.join(dir, item)) - }) + await fs.mkdir(dir, { recursive: true }) + + const list = await glob(fixtures, { cwd: 'test/fixtures' }) + + await Promise.all([ + ...list.map(async (item) => { + const dest = path.join(dir, item) + await fs.mkdir(path.dirname(dest), { recursive: true }) + await fs.copyFile(path.join('test/fixtures', item), dest) }), - fs.outputFile(path.join(dir, `postcss.config.${extension}`), config), - ]).then(() => dir) + fs.writeFile(path.join(dir, `postcss.config.${extension}`), config), + ]) + + return dir } diff --git a/test/helpers/read.js b/test/helpers/read.js index e9939aa..17d969f 100644 --- a/test/helpers/read.js +++ b/test/helpers/read.js @@ -1,4 +1,4 @@ -import fs from 'fs-extra' +import fs from 'node:fs/promises' export default function (path) { return fs.readFile(path, 'utf8').then( diff --git a/test/map.js b/test/map.js index 4783010..a3febb9 100644 --- a/test/map.js +++ b/test/map.js @@ -1,5 +1,5 @@ import test from 'ava' -import fs from 'fs-extra' +import fs from 'node:fs/promises' import cli from './helpers/cli.js' import tmp from './helpers/tmp.js' @@ -35,7 +35,12 @@ test('--map generates external sourcemaps', async (t) => { t.falsy(error, stderr) - t.truthy(await fs.pathExists(output.replace('.css', '.css.map'))) + t.truthy( + await fs.access(output.replace('.css', '.css.map')).then( + () => true, + () => false, + ), + ) }) test('--no-map disables internal sourcemaps', async (t) => { diff --git a/test/replace.js b/test/replace.js index dd24b98..7032493 100644 --- a/test/replace.js +++ b/test/replace.js @@ -1,6 +1,6 @@ import test from 'ava' -import fs from 'fs-extra' +import fs from 'node:fs/promises' import path from 'path' import cli from './helpers/cli.js' @@ -12,9 +12,10 @@ test('--replace works', async (t) => { const output = path.join(dir, 'output.css') + await fs.mkdir(dir, { recursive: true }) await Promise.all([ - fs.copy('test/fixtures/import.css', output), - fs.copy('test/fixtures/a.css', path.join(dir, 'a.css')), + fs.copyFile('test/fixtures/import.css', output), + fs.copyFile('test/fixtures/a.css', path.join(dir, 'a.css')), ]) const { error, stderr } = await cli([ diff --git a/test/stdin.js b/test/stdin.js index a682436..9cdf928 100644 --- a/test/stdin.js +++ b/test/stdin.js @@ -1,6 +1,6 @@ import test from 'ava' -import fs from 'fs-extra' +import { createReadStream } from 'node:fs' import path from 'path' import { exec } from 'child_process' @@ -24,5 +24,5 @@ test.cb('reads from stdin', (t) => { }, ) - fs.createReadStream('test/fixtures/a.css').pipe(cp.stdin) + createReadStream('test/fixtures/a.css').pipe(cp.stdin) }) diff --git a/test/stdout.js b/test/stdout.js index 260180f..b53de43 100644 --- a/test/stdout.js +++ b/test/stdout.js @@ -1,6 +1,6 @@ import test from 'ava' -import fs from 'fs-extra' +import { createReadStream } from 'node:fs' import path from 'path' import { exec } from 'child_process' @@ -23,5 +23,5 @@ test.cb('writes to stdout', (t) => { }, ) - fs.createReadStream('./test/fixtures/a.sss').pipe(cp.stdin) + createReadStream('./test/fixtures/a.sss').pipe(cp.stdin) }) diff --git a/test/unchanged.js b/test/unchanged.js index 4598530..beabdb1 100644 --- a/test/unchanged.js +++ b/test/unchanged.js @@ -1,4 +1,4 @@ -import fs from 'fs-extra' +import fs from 'node:fs/promises' import test from 'ava' import cli from './helpers/cli.js' diff --git a/test/watch.js b/test/watch.js index 357174a..9895a19 100644 --- a/test/watch.js +++ b/test/watch.js @@ -1,6 +1,6 @@ import test from 'ava' -import fs from 'fs-extra' +import fs from 'node:fs/promises' import path from 'path' import { exec, spawn } from 'child_process' import chokidar from 'chokidar' @@ -278,7 +278,6 @@ testCb('--watch watches dependencies', (t) => { // Start postcss-cli: watcher.on('ready', () => { - // Using exec() and quoting "*.css" to test watch's glob handling: cp = exec( `node ${path.resolve( 'index.js', @@ -376,7 +375,6 @@ testCb('--watch watches directory dependencies', (t) => { // Start postcss-cli: watcher.on('ready', () => { - // Using exec() and quoting "*.css" to test watch's glob handling: cp = exec( `node ${path.resolve( 'index.js',