1 | import path from 'path';
|
2 |
|
3 | import 'resolve-global';
|
4 | import requireUncached from 'require-uncached';
|
5 | import resolveFrom from 'resolve-from';
|
6 | import merge from 'lodash.merge';
|
7 | import omit from 'lodash.omit';
|
8 |
|
9 |
|
10 | export default function resolveExtends(config = {}, context = {}) {
|
11 | const {extends: e} = config;
|
12 | const extended = loadExtends(config, context).reduceRight(
|
13 | (r, c) => merge(r, omit(c, 'extends')),
|
14 | e ? {extends: e} : {}
|
15 | );
|
16 |
|
17 |
|
18 | if (typeof config === 'object' && 'wildcards' in config) {
|
19 | console.warn(
|
20 | `'wildcards' found in top-level configuration ignored. Remove them from your config to silence this warning.`
|
21 | );
|
22 | }
|
23 |
|
24 | return merge({}, extended, config);
|
25 | }
|
26 |
|
27 |
|
28 | function loadExtends(config = {}, context = {}) {
|
29 | return (config.extends || []).reduce((configs, raw) => {
|
30 | const load = context.require || require;
|
31 | const resolved = resolveConfig(raw, context);
|
32 | const c = load(resolved);
|
33 | const cwd = path.dirname(resolved);
|
34 |
|
35 |
|
36 | if (typeof c === 'object' && 'wildcards' in c) {
|
37 | console.warn(
|
38 | `'wildcards' found in '${raw}' ignored. To silence this warning raise an issue at 'npm repo ${raw}' to remove the wildcards.`
|
39 | );
|
40 | }
|
41 |
|
42 | const ctx = merge({}, context, {cwd});
|
43 |
|
44 |
|
45 | if (
|
46 | !context.parserPreset &&
|
47 | typeof c === 'object' &&
|
48 | typeof c.parserPreset === 'string'
|
49 | ) {
|
50 | const resolvedParserPreset = resolveFrom(cwd, c.parserPreset);
|
51 | const parserPreset = {
|
52 | name: c.parserPreset,
|
53 | path: `./${path.relative(process.cwd(), resolvedParserPreset)}`
|
54 | .split(path.sep)
|
55 | .join('/'),
|
56 | parserOpts: require(resolvedParserPreset)
|
57 | };
|
58 |
|
59 | ctx.parserPreset = parserPreset;
|
60 | config.parserPreset = parserPreset;
|
61 | }
|
62 |
|
63 | return [...configs, c, ...loadExtends(c, ctx)];
|
64 | }, []);
|
65 | }
|
66 |
|
67 | function getId(raw = '', prefix = '') {
|
68 | const first = raw.charAt(0);
|
69 | const scoped = first === '@';
|
70 | const relative = first === '.';
|
71 | return scoped || relative ? raw : [prefix, raw].filter(String).join('-');
|
72 | }
|
73 |
|
74 | function resolveConfig(raw, context = {}) {
|
75 | const resolve = context.resolve || resolveId;
|
76 | const id = getId(raw, context.prefix);
|
77 |
|
78 | try {
|
79 | return resolve(id, context);
|
80 | } catch (err) {
|
81 | const legacy = getId(raw, 'conventional-changelog-lint-config');
|
82 | const resolved = resolve(legacy, context);
|
83 | console.warn(
|
84 | `Resolving ${raw} to legacy config ${legacy}. To silence this warning raise an issue at 'npm repo ${legacy}' to rename to ${id}.`
|
85 | );
|
86 | return resolved;
|
87 | }
|
88 | }
|
89 |
|
90 | function resolveId(id, context = {}) {
|
91 | const cwd = context.cwd || process.cwd();
|
92 | const localPath = resolveFrom.silent(cwd, id);
|
93 |
|
94 | if (typeof localPath === 'string') {
|
95 | return localPath;
|
96 | }
|
97 |
|
98 | const resolveGlobal = requireUncached('resolve-global');
|
99 | const globalPath = resolveGlobal.silent(id);
|
100 |
|
101 | if (typeof globalPath === 'string') {
|
102 | return globalPath;
|
103 | }
|
104 |
|
105 | const err = new Error(`Cannot find module "${id}" from "${cwd}"`);
|
106 | err.code = 'MODULE_NOT_FOUND';
|
107 | throw err;
|
108 | }
|