1 | 'use strict';
|
2 | const path = require('path');
|
3 | const esm = require('esm');
|
4 | const isPlainObject = require('is-plain-object');
|
5 | const pkgConf = require('pkg-conf');
|
6 |
|
7 | const NO_SUCH_FILE = Symbol('no ava.config.js file');
|
8 | const MISSING_DEFAULT_EXPORT = Symbol('missing default export');
|
9 |
|
10 | function loadConfig(resolveFrom = process.cwd(), defaults = {}) {
|
11 | const packageConf = pkgConf.sync('ava', {cwd: resolveFrom});
|
12 | const filepath = pkgConf.filepath(packageConf);
|
13 | const projectDir = filepath === null ? resolveFrom : path.dirname(filepath);
|
14 |
|
15 | let fileConf;
|
16 | try {
|
17 | ({default: fileConf = MISSING_DEFAULT_EXPORT} = esm(module, {
|
18 | cjs: {
|
19 | cache: false,
|
20 | extensions: false,
|
21 | interop: false,
|
22 | mutableNamespace: false,
|
23 | namedExports: false,
|
24 | paths: false,
|
25 | vars: true
|
26 | },
|
27 | force: true,
|
28 | mode: 'all'
|
29 | })(path.join(projectDir, 'ava.config.js')));
|
30 | } catch (error) {
|
31 | if (error && error.code === 'MODULE_NOT_FOUND') {
|
32 | fileConf = NO_SUCH_FILE;
|
33 | } else {
|
34 | throw Object.assign(new Error('Error loading ava.config.js'), {parent: error});
|
35 | }
|
36 | }
|
37 |
|
38 | if (fileConf === MISSING_DEFAULT_EXPORT) {
|
39 | throw new Error('ava.config.js must have a default export, using ES module syntax');
|
40 | }
|
41 |
|
42 | if (fileConf !== NO_SUCH_FILE) {
|
43 | if (Object.keys(packageConf).length > 0) {
|
44 | throw new Error('Conflicting configuration in ava.config.js and package.json');
|
45 | }
|
46 |
|
47 | if (fileConf && typeof fileConf.then === 'function') {
|
48 | throw new TypeError('ava.config.js must not export a promise');
|
49 | }
|
50 |
|
51 | if (!isPlainObject(fileConf) && typeof fileConf !== 'function') {
|
52 | throw new TypeError('ava.config.js must export a plain object or factory function');
|
53 | }
|
54 |
|
55 | if (typeof fileConf === 'function') {
|
56 | fileConf = fileConf({projectDir});
|
57 | if (fileConf && typeof fileConf.then === 'function') {
|
58 | throw new TypeError('Factory method exported by ava.config.js must not return a promise');
|
59 | }
|
60 |
|
61 | if (!isPlainObject(fileConf)) {
|
62 | throw new TypeError('Factory method exported by ava.config.js must return a plain object');
|
63 | }
|
64 | }
|
65 |
|
66 | if ('ava' in fileConf) {
|
67 | throw new Error('Encountered \'ava\' property in ava.config.js; avoid wrapping the configuration');
|
68 | }
|
69 | }
|
70 |
|
71 | return {...defaults, ...fileConf, ...packageConf, projectDir};
|
72 | }
|
73 |
|
74 | module.exports = loadConfig;
|