1 | 'use strict';
|
2 |
|
3 | const cosmiconfig = require('cosmiconfig').cosmiconfigSync;
|
4 | const stripJsonComments = require('strip-json-comments');
|
5 | const parseJson = require('parse-json');
|
6 | const path = require('path');
|
7 |
|
8 | const exitCodes = require('../exit-codes');
|
9 | const { consoleError, consoleDebug } = require('../helpers/console');
|
10 | const knownProps = require('./properties.json');
|
11 | const defaultConfig = require('../../.yaspellerrc.default.json');
|
12 |
|
13 | function loadJson(filepath, content) {
|
14 | try {
|
15 | return parseJson(stripJsonComments(content));
|
16 | } catch (err) {
|
17 | err.message = `JSON Error in ${filepath}:\n${err.message}`;
|
18 | throw err;
|
19 | }
|
20 | }
|
21 |
|
22 | function getType(value) {
|
23 | return Array.isArray(value) ? 'array' : typeof value;
|
24 | }
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 | function getConfig(file) {
|
33 | const explorer = cosmiconfig('yaspeller', {
|
34 | loaders: {
|
35 | '.json': loadJson,
|
36 | noExt: loadJson
|
37 | },
|
38 | searchPlaces: [
|
39 | 'package.json',
|
40 | '.yaspeller.json',
|
41 | '.yaspellerrc',
|
42 | '.yaspellerrc.js',
|
43 | '.yaspellerrc.json',
|
44 | ]
|
45 | });
|
46 |
|
47 | let data;
|
48 |
|
49 | consoleDebug('Get/check config.');
|
50 |
|
51 | try {
|
52 | if (file) {
|
53 | data = explorer.load(file).config;
|
54 | } else {
|
55 | const result = explorer.search();
|
56 | if (result) {
|
57 | file = result.filepath;
|
58 | data = result.config;
|
59 | }
|
60 | }
|
61 |
|
62 | if (file) {
|
63 | consoleDebug(`Using config: ${file}`);
|
64 | checkConfigProperties(data, file);
|
65 | }
|
66 | } catch (e) {
|
67 | consoleError(e);
|
68 | process.exit(exitCodes.ERROR_CONFIG);
|
69 | }
|
70 |
|
71 | return {
|
72 | relativePath: path.relative('./', file || '.yaspellerrc'),
|
73 | data: data || {}
|
74 | };
|
75 | }
|
76 |
|
77 |
|
78 |
|
79 |
|
80 |
|
81 |
|
82 |
|
83 | function getMergedConfig(filename) {
|
84 | const config = getConfig(filename);
|
85 |
|
86 | return Object.assign({
|
87 | configRelativePath: config.relativePath,
|
88 | }, defaultConfig, config.data);
|
89 | }
|
90 |
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 | function checkConfigProperties(obj, file) {
|
98 | obj && Object.keys(obj).forEach(prop => {
|
99 | if (knownProps[prop]) {
|
100 | let needType = knownProps[prop].type;
|
101 | let currentType = getType(obj[prop]);
|
102 | if (currentType !== needType) {
|
103 | consoleError(
|
104 | `The type for "${prop}" property should be ${knownProps[prop].type} in "${file}" config.`
|
105 | );
|
106 | }
|
107 | } else {
|
108 | consoleError(
|
109 | `Unknown "${prop}" property in "${file}" config.`
|
110 | );
|
111 | }
|
112 | });
|
113 | }
|
114 |
|
115 | module.exports = {
|
116 | defaultConfig,
|
117 | getConfig,
|
118 | getMergedConfig,
|
119 | };
|