From 6d0ce6cb2a863492377140c7034e25c606e6b019 Mon Sep 17 00:00:00 2001 From: Dimitri B Date: Thu, 3 Jun 2021 12:10:35 +0200 Subject: [PATCH] Process gitignore-style patterns in `files` property of `package.json` (#116) Fixes #79 --- source/lib/rules/files-property.ts | 28 +++++++++++++++++-- .../negative-pattern-negated/index.js | 3 ++ .../negative-pattern-negated/package.json | 7 +++++ .../negative-pattern-negated/types/index.d.ts | 6 ++++ .../types/index.test-d.ts | 5 ++++ .../negative-pattern/index.d.ts | 6 ++++ .../negative-pattern/index.js | 3 ++ .../negative-pattern/index.test-d.ts | 5 ++++ .../negative-pattern/package.json | 6 ++++ .../root-marker-pattern/index.js | 3 ++ .../root-marker-pattern/package.json | 7 +++++ .../root-marker-pattern/types/index.d.ts | 6 ++++ .../root-marker-pattern/types/index.test-d.ts | 5 ++++ source/test/test.ts | 20 +++++++++++++ 14 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 source/test/fixtures/files-gitignore-patterns/negative-pattern-negated/index.js create mode 100644 source/test/fixtures/files-gitignore-patterns/negative-pattern-negated/package.json create mode 100644 source/test/fixtures/files-gitignore-patterns/negative-pattern-negated/types/index.d.ts create mode 100644 source/test/fixtures/files-gitignore-patterns/negative-pattern-negated/types/index.test-d.ts create mode 100644 source/test/fixtures/files-gitignore-patterns/negative-pattern/index.d.ts create mode 100644 source/test/fixtures/files-gitignore-patterns/negative-pattern/index.js create mode 100644 source/test/fixtures/files-gitignore-patterns/negative-pattern/index.test-d.ts create mode 100644 source/test/fixtures/files-gitignore-patterns/negative-pattern/package.json create mode 100644 source/test/fixtures/files-gitignore-patterns/root-marker-pattern/index.js create mode 100644 source/test/fixtures/files-gitignore-patterns/root-marker-pattern/package.json create mode 100644 source/test/fixtures/files-gitignore-patterns/root-marker-pattern/types/index.d.ts create mode 100644 source/test/fixtures/files-gitignore-patterns/root-marker-pattern/types/index.test-d.ts diff --git a/source/lib/rules/files-property.ts b/source/lib/rules/files-property.ts index 693011f6..61a2094e 100644 --- a/source/lib/rules/files-property.ts +++ b/source/lib/rules/files-property.ts @@ -13,12 +13,15 @@ import {getJSONPropertyPosition} from '../utils'; export default (context: Context): Diagnostic[] => { const {pkg, typingsFile} = context; - if (!Array.isArray(pkg.files)) { + const packageFiles = pkg.files; + if (!Array.isArray(packageFiles)) { return []; } const normalizedTypingsFile = path.normalize(typingsFile); - const normalizedFiles = globby.sync(pkg.files as string[], {cwd: context.cwd}).map(path.normalize); + + const patternProcessedPackageFiles = processGitIgnoreStylePatterns(packageFiles); + const normalizedFiles = globby.sync(patternProcessedPackageFiles, {cwd: context.cwd}).map(path.normalize); if (normalizedFiles.includes(normalizedTypingsFile)) { return []; @@ -36,3 +39,24 @@ export default (context: Context): Diagnostic[] => { } ]; }; + +function processGitIgnoreStylePatterns(patterns: readonly string[]): string[] { + const processedPatterns = patterns + .map(pattern => { + const [negatePatternMatch] = pattern.match(/^!+/) || []; + const negationMarkersCount = negatePatternMatch ? negatePatternMatch.length : 0; + + return [ + pattern + .slice(negationMarkersCount) + // Strip off `/` from the start of the pattern + .replace(/^\/+/, ''), + negationMarkersCount % 2 === 0 + ] as const; + }) + // Only include pattern if it has an even count of negation markers + .filter(([, hasEvenCountOfNegationMarkers]) => hasEvenCountOfNegationMarkers) + .map(([processedPattern]) => processedPattern); + + return [...new Set(processedPatterns)]; +} diff --git a/source/test/fixtures/files-gitignore-patterns/negative-pattern-negated/index.js b/source/test/fixtures/files-gitignore-patterns/negative-pattern-negated/index.js new file mode 100644 index 00000000..f17717f5 --- /dev/null +++ b/source/test/fixtures/files-gitignore-patterns/negative-pattern-negated/index.js @@ -0,0 +1,3 @@ +module.exports.default = (foo, bar) => { + return foo + bar; +}; diff --git a/source/test/fixtures/files-gitignore-patterns/negative-pattern-negated/package.json b/source/test/fixtures/files-gitignore-patterns/negative-pattern-negated/package.json new file mode 100644 index 00000000..05642a5b --- /dev/null +++ b/source/test/fixtures/files-gitignore-patterns/negative-pattern-negated/package.json @@ -0,0 +1,7 @@ +{ + "name": "foo", + "files": [ + "!!types/index.d.ts" + ], + "types": "types/index.d.ts" +} diff --git a/source/test/fixtures/files-gitignore-patterns/negative-pattern-negated/types/index.d.ts b/source/test/fixtures/files-gitignore-patterns/negative-pattern-negated/types/index.d.ts new file mode 100644 index 00000000..266914ab --- /dev/null +++ b/source/test/fixtures/files-gitignore-patterns/negative-pattern-negated/types/index.d.ts @@ -0,0 +1,6 @@ +declare const concat: { + (foo: string, bar: string): string; + (foo: number, bar: number): number; +}; + +export default concat; diff --git a/source/test/fixtures/files-gitignore-patterns/negative-pattern-negated/types/index.test-d.ts b/source/test/fixtures/files-gitignore-patterns/negative-pattern-negated/types/index.test-d.ts new file mode 100644 index 00000000..338a3227 --- /dev/null +++ b/source/test/fixtures/files-gitignore-patterns/negative-pattern-negated/types/index.test-d.ts @@ -0,0 +1,5 @@ +import {expectType} from '../../../../..'; +import concat from '..'; + +expectType(concat('foo', 'bar')); +expectType(concat(1, 2)); diff --git a/source/test/fixtures/files-gitignore-patterns/negative-pattern/index.d.ts b/source/test/fixtures/files-gitignore-patterns/negative-pattern/index.d.ts new file mode 100644 index 00000000..266914ab --- /dev/null +++ b/source/test/fixtures/files-gitignore-patterns/negative-pattern/index.d.ts @@ -0,0 +1,6 @@ +declare const concat: { + (foo: string, bar: string): string; + (foo: number, bar: number): number; +}; + +export default concat; diff --git a/source/test/fixtures/files-gitignore-patterns/negative-pattern/index.js b/source/test/fixtures/files-gitignore-patterns/negative-pattern/index.js new file mode 100644 index 00000000..f17717f5 --- /dev/null +++ b/source/test/fixtures/files-gitignore-patterns/negative-pattern/index.js @@ -0,0 +1,3 @@ +module.exports.default = (foo, bar) => { + return foo + bar; +}; diff --git a/source/test/fixtures/files-gitignore-patterns/negative-pattern/index.test-d.ts b/source/test/fixtures/files-gitignore-patterns/negative-pattern/index.test-d.ts new file mode 100644 index 00000000..66ad1b38 --- /dev/null +++ b/source/test/fixtures/files-gitignore-patterns/negative-pattern/index.test-d.ts @@ -0,0 +1,5 @@ +import {expectType} from '../../../..'; +import concat from '.'; + +expectType(concat('foo', 'bar')); +expectType(concat(1, 2)); diff --git a/source/test/fixtures/files-gitignore-patterns/negative-pattern/package.json b/source/test/fixtures/files-gitignore-patterns/negative-pattern/package.json new file mode 100644 index 00000000..2895c927 --- /dev/null +++ b/source/test/fixtures/files-gitignore-patterns/negative-pattern/package.json @@ -0,0 +1,6 @@ +{ + "name": "foo", + "files": [ + "!index.d.ts" + ] +} diff --git a/source/test/fixtures/files-gitignore-patterns/root-marker-pattern/index.js b/source/test/fixtures/files-gitignore-patterns/root-marker-pattern/index.js new file mode 100644 index 00000000..f17717f5 --- /dev/null +++ b/source/test/fixtures/files-gitignore-patterns/root-marker-pattern/index.js @@ -0,0 +1,3 @@ +module.exports.default = (foo, bar) => { + return foo + bar; +}; diff --git a/source/test/fixtures/files-gitignore-patterns/root-marker-pattern/package.json b/source/test/fixtures/files-gitignore-patterns/root-marker-pattern/package.json new file mode 100644 index 00000000..a17c09ab --- /dev/null +++ b/source/test/fixtures/files-gitignore-patterns/root-marker-pattern/package.json @@ -0,0 +1,7 @@ +{ + "name": "foo", + "files": [ + "/types/index.d.ts" + ], + "types": "types/index.d.ts" +} diff --git a/source/test/fixtures/files-gitignore-patterns/root-marker-pattern/types/index.d.ts b/source/test/fixtures/files-gitignore-patterns/root-marker-pattern/types/index.d.ts new file mode 100644 index 00000000..266914ab --- /dev/null +++ b/source/test/fixtures/files-gitignore-patterns/root-marker-pattern/types/index.d.ts @@ -0,0 +1,6 @@ +declare const concat: { + (foo: string, bar: string): string; + (foo: number, bar: number): number; +}; + +export default concat; diff --git a/source/test/fixtures/files-gitignore-patterns/root-marker-pattern/types/index.test-d.ts b/source/test/fixtures/files-gitignore-patterns/root-marker-pattern/types/index.test-d.ts new file mode 100644 index 00000000..338a3227 --- /dev/null +++ b/source/test/fixtures/files-gitignore-patterns/root-marker-pattern/types/index.test-d.ts @@ -0,0 +1,5 @@ +import {expectType} from '../../../../..'; +import concat from '..'; + +expectType(concat('foo', 'bar')); +expectType(concat(1, 2)); diff --git a/source/test/test.ts b/source/test/test.ts index b6f967bd..c7104e77 100644 --- a/source/test/test.ts +++ b/source/test/test.ts @@ -45,6 +45,26 @@ test('allow specifying folders containing typings file in `files` list', async t verify(t, diagnostics, []); }); +test('allow specifying negative gitignore-style patterns in `files` list', async t => { + const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/files-gitignore-patterns/negative-pattern')}); + + verify(t, diagnostics, [ + [3, 1, 'error', 'TypeScript type definition `index.d.ts` is not part of the `files` list.'], + ]); +}); + +test('allow specifying negated negative (positive) gitignore-style patterns in `files` list', async t => { + const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/files-gitignore-patterns/negative-pattern-negated')}); + + verify(t, diagnostics, []); +}); + +test('allow specifying root marker (/) gitignore-style patterns in `files` list', async t => { + const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/files-gitignore-patterns/root-marker-pattern')}); + + verify(t, diagnostics, []); +}); + test('allow specifying glob patterns containing typings file in `files` list', async t => { const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/files-glob')});