diff --git a/.github/workflows/js-lint.yml b/.github/workflows/js-lint.yml deleted file mode 100644 index 5398d30..0000000 --- a/.github/workflows/js-lint.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: JS lint - -on: [push] - -jobs: - build: - name: JS Lint - - strategy: - matrix: - os: [ubuntu-latest] - node: [12.x] - - runs-on: ${{ matrix.os }} - - steps: - - uses: actions/checkout@v2 - - - name: Use Node.js ${{ matrix.node }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node }} - - - uses: pnpm/action-setup@v1.2.1 - with: - version: 5.13.6 - run_install: | - - recursive: false - - - name: Lint - run: pnpm lint diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..2d3e189 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,38 @@ +name: Lint & Test + +on: [push] + +jobs: + build: + name: Lint & Test + + strategy: + matrix: + os: [ubuntu-latest] + node: [14.x] + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v3 + + - uses: pnpm/action-setup@v2.2.2 + with: + version: 7.4.1 + + - name: Use Node.js ${{ matrix.node }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node }} + cache: 'pnpm' + + - run: pnpm install --frozen-lockfile + + - name: Build + run: pnpm build + + - name: Lint + run: pnpm lint + + - name: Test + run: pnpm test diff --git a/package.json b/package.json index cfce24b..2786c23 100644 --- a/package.json +++ b/package.json @@ -36,12 +36,13 @@ "clean": "rm -rf ./dist", "dev": "npm run build -- --watch", "build": "tsup src/index.ts --dts --format cjs,esm --clean", - "lint": "lint-staged", + "lint": "eslint . --ext .ts,.js,.vue", "postinstall": "husky install", "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s", "prepublishOnly": "pinst --disable && npm run build", "postpublish": "PACKAGE_VERSION=$(cat package.json | grep \\\"version\\\" | head -1 | awk -F: '{ print $2 }' | sed 's/[\",]//g' | tr -d '[[:space:]]') && git tag v$PACKAGE_VERSION && git push --tags && pinst --enable", - "release": "node scripts/release.cjs" + "release": "node scripts/release.cjs", + "test": "vitest" }, "dependencies": { "picocolors": "^1.0.0", @@ -67,7 +68,8 @@ "semver": "^7.3.7", "tsup": "^6.1.3", "typescript": "^4.7.4", - "vite": "^3" + "vite": "^3", + "vitest": "^0.21.1" }, "lint-staged": { "*.{js,ts,tsx,jsx,vue}": [ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c48d559..927a0b6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,7 @@ importers: tsup: ^6.1.3 typescript: ^4.7.4 vite: ^3 + vitest: ^0.21.1 dependencies: picocolors: 1.0.0 picomatch: 2.3.1 @@ -44,6 +45,7 @@ importers: tsup: 6.1.3_typescript@4.7.4 typescript: 4.7.4 vite: 3.0.2 + vitest: 0.21.1 example: specifiers: @@ -237,6 +239,16 @@ packages: fastq: 1.13.0 dev: true + /@types/chai-subset/1.3.3: + resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==} + dependencies: + '@types/chai': 4.3.3 + dev: true + + /@types/chai/4.3.3: + resolution: {integrity: sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==} + dev: true + /@types/cross-spawn/6.0.2: resolution: {integrity: sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==} dependencies: @@ -542,6 +554,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /assertion-error/1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + dev: true + /astral-regex/2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} @@ -626,6 +642,19 @@ packages: engines: {node: '>=6'} dev: true + /chai/4.3.6: + resolution: {integrity: sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==} + engines: {node: '>=4'} + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.2 + deep-eql: 3.0.1 + get-func-name: 2.0.0 + loupe: 2.3.4 + pathval: 1.1.1 + type-detect: 4.0.8 + dev: true + /chalk/2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -655,6 +684,10 @@ packages: resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} dev: true + /check-error/1.0.2: + resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==} + dev: true + /chokidar/3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} @@ -1003,6 +1036,13 @@ packages: resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} dev: true + /deep-eql/3.0.1: + resolution: {integrity: sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==} + engines: {node: '>=0.12'} + dependencies: + type-detect: 4.0.8 + dev: true + /deep-is/0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true @@ -1875,6 +1915,10 @@ packages: engines: {node: 6.* || 8.* || >= 10.*} dev: true + /get-func-name/2.0.0: + resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==} + dev: true + /get-intrinsic/1.1.2: resolution: {integrity: sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==} dependencies: @@ -2480,6 +2524,11 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: true + /local-pkg/0.4.2: + resolution: {integrity: sha512-mlERgSPrbxU3BP4qBqAvvwlgW4MTg78iwJdGGnv7kibKjWcJksrG3t6LB5lXI93wXRDvG4NpUgJFmTG4T6rdrg==} + engines: {node: '>=14'} + dev: true + /locate-path/2.0.0: resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} engines: {node: '>=4'} @@ -2536,6 +2585,12 @@ packages: js-tokens: 4.0.0 dev: true + /loupe/2.3.4: + resolution: {integrity: sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==} + dependencies: + get-func-name: 2.0.0 + dev: true + /lru-cache/6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} @@ -2917,6 +2972,10 @@ packages: engines: {node: '>=8'} dev: true + /pathval/1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + dev: true + /picocolors/1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} @@ -3517,6 +3576,16 @@ packages: readable-stream: 3.6.0 dev: true + /tinypool/0.2.4: + resolution: {integrity: sha512-Vs3rhkUH6Qq1t5bqtb816oT+HeJTXfwt2cbPH17sWHIYKTotQIFPk3tf2fgqRrVyMDVOc1EnPgzIxfIulXVzwQ==} + engines: {node: '>=14.0.0'} + dev: true + + /tinyspy/1.0.0: + resolution: {integrity: sha512-FI5B2QdODQYDRjfuLF+OrJ8bjWRMCXokQPcwKm0W3IzcbUmBNv536cQc7eXGoAuXphZwgx1DFbqImwzz08Fnhw==} + engines: {node: '>=14.0.0'} + dev: true + /to-regex-range/5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -3614,6 +3683,11 @@ packages: prelude-ls: 1.2.1 dev: true + /type-detect/4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + dev: true + /type-fest/0.18.1: resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==} engines: {node: '>=10'} @@ -3722,6 +3796,48 @@ packages: fsevents: 2.3.2 dev: true + /vitest/0.21.1: + resolution: {integrity: sha512-WBIxuFmIDPuK47GO6Lu9eNeRMqHj/FWL3dk73OHH3eyPPWPiu+UB3QHLkLK2PEggCqJW4FaWoWg8R68S7p9+9Q==} + engines: {node: '>=v14.16.0'} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@vitest/browser': '*' + '@vitest/ui': '*' + c8: '*' + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + c8: + optional: true + happy-dom: + optional: true + jsdom: + optional: true + dependencies: + '@types/chai': 4.3.3 + '@types/chai-subset': 1.3.3 + '@types/node': 14.18.22 + chai: 4.3.6 + debug: 4.3.4 + local-pkg: 0.4.2 + tinypool: 0.2.4 + tinyspy: 1.0.0 + vite: 3.0.2 + transitivePeerDependencies: + - less + - sass + - stylus + - supports-color + - terser + dev: true + /vue-eslint-parser/9.0.3_eslint@8.20.0: resolution: {integrity: sha512-yL+ZDb+9T0ELG4VIFo/2anAOz8SvBdlqEnQnvJ3M7Scq56DvtjY0VY88bByRZB0D4J0u8olBcfrXTVONXsh4og==} engines: {node: ^14.17.0 || >=16.0.0} diff --git a/src/index.ts b/src/index.ts index dfb2e04..7fafa22 100644 --- a/src/index.ts +++ b/src/index.ts @@ -32,6 +32,10 @@ export interface Config { root?: string } +export function normalizePaths (root: string, path: string | string[]): string[] { + return (Array.isArray(path) ? path : [path]).map(path => resolve(root, path)).map(normalizePath) +} + /** * Allows to automatically reload the page when a watched file changes. */ @@ -46,7 +50,7 @@ export default (paths: string | string[], config: Config = {}): PluginOption => configureServer ({ watcher, ws, config: { logger } }: ViteDevServer) { const { root = process.cwd(), log = true, always = true, delay = 0 } = config - const files = Array.from(paths).map(path => resolve(root, path)).map(normalizePath) + const files = normalizePaths(root, paths) const shouldReload = picomatch(files) const checkReload = (path: string) => { if (shouldReload(path)) { diff --git a/tests/paths.spec.ts b/tests/paths.spec.ts new file mode 100644 index 0000000..52474d3 --- /dev/null +++ b/tests/paths.spec.ts @@ -0,0 +1,18 @@ +import { describe, expect, it } from 'vitest' +import { normalizePaths } from '../src' + +const root = '/root' +const expectNormalized = (path: any) => expect(normalizePaths(root, path)) + +describe('normalizePaths', () => { + it('it handles strings and arrays', () => { + expectNormalized('/absolute/**/*.js') + .toEqual(['/absolute/**/*.js']) + + expectNormalized('relative/**/*.vue') + .toEqual(['/root/relative/**/*.vue']) + + expectNormalized(['/absolute/**/*.js', 'relative/**/*.vue']) + .toEqual(['/absolute/**/*.js', '/root/relative/**/*.vue']) + }) +})