diff --git a/flow-typed/defs.js b/flow-typed/defs.js index bd963391..82dad27f 100644 --- a/flow-typed/defs.js +++ b/flow-typed/defs.js @@ -14,13 +14,14 @@ type ExplorerOptions = { stopDir: string, cache: boolean, transform: CosmiconfigResult => CosmiconfigResult, + packageFilenames: Array, packageProp: string, loaders: Loaders, searchPlaces: Array, ignoreEmptySearchPlaces: boolean, }; -type ExplorerContext = ExplorerOptions & { +type ExplorerContext = & { loadCache: ?Map>, loadSyncCache: ?Map, searchCache: ?Map>, diff --git a/src/createExplorer.js b/src/createExplorer.js index 112e1f85..466fb526 100644 --- a/src/createExplorer.js +++ b/src/createExplorer.js @@ -179,7 +179,7 @@ class Explorer { } getLoaderEntryForFile(filepath: string): LoaderEntry { - if (path.basename(filepath) === 'package.json') { + if (this.config.packageFilenames.includes(path.basename(filepath))) { const loader = this.loadPackageProp.bind(this); return { sync: loader, async: loader }; } diff --git a/src/index.js b/src/index.js index 19eb0b82..84e33f45 100644 --- a/src/index.js +++ b/src/index.js @@ -10,6 +10,7 @@ module.exports = cosmiconfig; function cosmiconfig( moduleName: string, options: { + packageFilenames?: Array, packageProp?: string, loaders?: Object, searchPlaces?: Array, @@ -21,6 +22,7 @@ function cosmiconfig( ) { options = options || {}; const defaults = { + packageFilenames: ['package.json'], packageProp: moduleName, searchPlaces: [ 'package.json', diff --git a/test/index.test.js b/test/index.test.js index 0b0b026d..91f7fbb4 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -35,6 +35,7 @@ describe('cosmiconfig', () => { expect(createExplorerMock).toHaveBeenCalledTimes(1); const explorerOptions = createExplorerMock.mock.calls[0][0]; expect(explorerOptions).toMatchObject({ + packageFilenames: ['package.json'], packageProp: moduleName, searchPlaces: [ 'package.json', @@ -79,6 +80,7 @@ describe('cosmiconfig', () => { stopDir: __dirname, cache: false, searchPlaces: ['.foorc.json', 'wildandfree.js'], + packageFilenames: ['manifest.json'], packageProp: 'wildandfree', ignoreEmptySearchPlaces: false, loaders: { @@ -91,6 +93,7 @@ describe('cosmiconfig', () => { const explorerOptions = createExplorerMock.mock.calls[0][0]; expect(explorerOptions).toMatchObject({ + packageFilenames: ['manifest.json'], packageProp: 'wildandfree', searchPlaces: ['.foorc.json', 'wildandfree.js'], ignoreEmptySearchPlaces: false, diff --git a/test/successful-files.test.js b/test/successful-files.test.js index d83a22d7..f62455ea 100644 --- a/test/successful-files.test.js +++ b/test/successful-files.test.js @@ -147,12 +147,26 @@ describe('loads package prop when configPath is package.json', () => { } }` ); + temp.createFile( + 'manifest.json', + `{ + "foo": { + "bar": "baz" + }, + "isManifest": {"very": "yes"}, + "otherPackage": { + "please": "no" + } + }` + ); }); const configPath = temp.absolutePath('package.json'); - const checkResult = (result, expectedConfig) => { + const manifestPath = temp.absolutePath('manifest.json'); + const checkResult = (result, expectedConfig, filepath) => { + if(filepath === undefined) filepath = configPath; expect(result.config).toEqual(expectedConfig); - expect(result.filepath).toBe(configPath); + expect(result.filepath).toBe(filepath); }; describe('default package prop', () => { @@ -232,6 +246,45 @@ describe('loads package prop when configPath is package.json', () => { expect(result).toBeNull(); }); }); + + describe('load packageProp from alternative packageNames', () => { + const explorer = cosmiconfig('foo', { packageFilenames: ['manifest.json'], packageProp: 'isManifest' }); + const expectedConfig = { very: 'yes' }; + + test('async', () => { + return explorer + .load(manifestPath) + .then(result => checkResult(result, expectedConfig, manifestPath)); + }); + + test('sync', () => { + const result = explorer.loadSync(manifestPath); + checkResult(result, expectedConfig, manifestPath); + }); + }); + + describe('do not load packageProp when package.json is not in packageNames', () => { + const explorer = cosmiconfig('foo', { packageFilenames: ['manifest.json'], packageProp: 'foo' }); + const expectedConfig = { + foo: { + bar: "baz" + }, + otherPackage: { + please: "no" + } + }; + + test('async', () => { + return explorer + .load(configPath) + .then(result => checkResult(result, expectedConfig)); + }); + + test('sync', () => { + const result = explorer.loadSync(configPath); + checkResult(result, expectedConfig); + }); + }); }); describe('runs transform', () => {