@percy/config 1.0.0-beta.9 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -11
- package/package.json +29 -20
- package/dist/defaults.js +0 -48
- package/dist/index.js +0 -33
- package/dist/load.js +0 -92
- package/dist/normalize.js +0 -37
- package/dist/stringify.js +0 -42
- package/dist/validate.js +0 -121
- package/types/index.d.ts +0 -33
package/README.md
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
# @percy/config
|
|
2
2
|
|
|
3
3
|
Handles loading and adding options to Percy configuration files. Uses
|
|
4
4
|
[cosmiconfig](https://github.com/davidtheclark/cosmiconfig) to load configuration files and [JSON
|
|
5
5
|
schema](https://json-schema.org/) with [AJV](https://github.com/epoberezkin/ajv) to validate those
|
|
6
6
|
configuration files.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
- [Loading config files](#loading-config-files)
|
|
9
|
+
- [Extending config options](#extending-config-options)
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
## Loading config files
|
|
11
12
|
|
|
12
13
|
The `.load()` method will load and validate a configuation file, optionally merging it with any
|
|
13
14
|
provided `overrides`. If no `path` is provided, will search for the first supported config found
|
|
@@ -18,14 +19,17 @@ from the current directory up to the home directoy. Configuration files are cach
|
|
|
18
19
|
import PercyConfig from '@percy/config'
|
|
19
20
|
|
|
20
21
|
// loading is done synchronously
|
|
21
|
-
const config = PercyConfig.load(
|
|
22
|
-
path, // config file path or directory path containing a config file
|
|
23
|
-
overrides = {}, // configuration option overrides
|
|
24
|
-
reload = false, // reload file and update cache
|
|
25
|
-
bail = false // return undefined on validation warnings
|
|
26
|
-
})
|
|
22
|
+
const config = PercyConfig.load(options)
|
|
27
23
|
```
|
|
28
24
|
|
|
25
|
+
#### Options
|
|
26
|
+
|
|
27
|
+
- `path` — Config file path or directory containing a config file
|
|
28
|
+
- `overrides` — Config option overrides
|
|
29
|
+
- `reload` — Do not use cached config (**default** `false`)
|
|
30
|
+
- `bail` — Return undefined when failing validation (**default** `false`)
|
|
31
|
+
- `print` — Print info and error logs (**default** `false`)
|
|
32
|
+
|
|
29
33
|
#### Supported files
|
|
30
34
|
|
|
31
35
|
- `"percy"` entry in `package.json`
|
|
@@ -34,7 +38,7 @@ const config = PercyConfig.load({
|
|
|
34
38
|
- `.percy.yaml` or `.percy.yml` YAML file
|
|
35
39
|
- `.percy.js` or `percy.config.js` file that exports an object
|
|
36
40
|
|
|
37
|
-
|
|
41
|
+
## Extending config options
|
|
38
42
|
|
|
39
43
|
The `.addSchema()` function will add a sub-schema to the Percy configuration file which will be
|
|
40
44
|
parsed and validated when `PercyConfig.load()` is called. See [JSON
|
|
@@ -43,5 +47,7 @@ schema](https://json-schema.org/) for possible schema options.
|
|
|
43
47
|
```js
|
|
44
48
|
import PercyConfig from '@percy/config'
|
|
45
49
|
|
|
46
|
-
PercyConfig.addSchema({
|
|
50
|
+
PercyConfig.addSchema({
|
|
51
|
+
propertyName: JSONSchema
|
|
52
|
+
})
|
|
47
53
|
```
|
package/package.json
CHANGED
|
@@ -1,36 +1,45 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@percy/config",
|
|
3
|
-
"version": "1.0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"
|
|
6
|
-
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/percy/cli",
|
|
8
|
+
"directory": "packages/config"
|
|
9
|
+
},
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public"
|
|
12
|
+
},
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=14"
|
|
15
|
+
},
|
|
7
16
|
"files": [
|
|
8
|
-
"dist",
|
|
9
|
-
"types/index.d.ts"
|
|
17
|
+
"./dist",
|
|
18
|
+
"./types/index.d.ts"
|
|
10
19
|
],
|
|
20
|
+
"main": "./dist/index.js",
|
|
21
|
+
"types": "./types/index.d.ts",
|
|
22
|
+
"type": "module",
|
|
23
|
+
"exports": {
|
|
24
|
+
".": "./dist/index.js",
|
|
25
|
+
"./utils": "./dist/utils/index.js",
|
|
26
|
+
"./test/helpers": "./test/helpers.js"
|
|
27
|
+
},
|
|
11
28
|
"scripts": {
|
|
12
|
-
"build": "
|
|
29
|
+
"build": "node ../../scripts/build",
|
|
13
30
|
"lint": "eslint --ignore-path ../../.gitignore .",
|
|
14
|
-
"test": "
|
|
15
|
-
"test:coverage": "
|
|
31
|
+
"test": "node ../../scripts/test",
|
|
32
|
+
"test:coverage": "yarn test --coverage",
|
|
16
33
|
"test:types": "tsd"
|
|
17
34
|
},
|
|
18
|
-
"publishConfig": {
|
|
19
|
-
"access": "public"
|
|
20
|
-
},
|
|
21
|
-
"mocha": {
|
|
22
|
-
"require": "../../scripts/babel-register"
|
|
23
|
-
},
|
|
24
35
|
"dependencies": {
|
|
25
|
-
"@percy/logger": "
|
|
26
|
-
"ajv": "^6.
|
|
36
|
+
"@percy/logger": "1.0.0",
|
|
37
|
+
"ajv": "^8.6.2",
|
|
27
38
|
"cosmiconfig": "^7.0.0",
|
|
28
|
-
"
|
|
29
|
-
"path-type": "^4.0.0",
|
|
30
|
-
"yaml": "^1.8.0"
|
|
39
|
+
"yaml": "^1.10.0"
|
|
31
40
|
},
|
|
32
41
|
"devDependencies": {
|
|
33
42
|
"json-schema-typed": "^7.0.3"
|
|
34
43
|
},
|
|
35
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "6df509421a60144e4f9f5d59dc57a5675372a0b2"
|
|
36
45
|
}
|
package/dist/defaults.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = getDefaults;
|
|
7
|
-
|
|
8
|
-
var _deepmerge = _interopRequireDefault(require("deepmerge"));
|
|
9
|
-
|
|
10
|
-
var _validate = require("./validate");
|
|
11
|
-
|
|
12
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
-
|
|
14
|
-
const {
|
|
15
|
-
assign,
|
|
16
|
-
entries,
|
|
17
|
-
freeze
|
|
18
|
-
} = Object; // Recursively walks a schema and collects defaults. When no schema is provided,
|
|
19
|
-
// the default config schema is used. Returned defaults are frozen.
|
|
20
|
-
|
|
21
|
-
function getDefaultFromSchema(schema) {
|
|
22
|
-
if (!schema || typeof schema.$ref === 'string') {
|
|
23
|
-
var _schema$$ref;
|
|
24
|
-
|
|
25
|
-
// get the schema from ajv
|
|
26
|
-
return getDefaultFromSchema((0, _validate.getSchema)((_schema$$ref = schema === null || schema === void 0 ? void 0 : schema.$ref) !== null && _schema$$ref !== void 0 ? _schema$$ref : 'config'));
|
|
27
|
-
} else if (schema.default != null) {
|
|
28
|
-
// return the frozen default for this schema
|
|
29
|
-
return freeze(schema.default);
|
|
30
|
-
} else if (schema.type === 'object' && schema.properties) {
|
|
31
|
-
// return a frozen object of default properties
|
|
32
|
-
return freeze(entries(schema.properties).reduce((acc, [prop, schema]) => {
|
|
33
|
-
let def = getDefaultFromSchema(schema);
|
|
34
|
-
return def != null ? assign(acc || {}, {
|
|
35
|
-
[prop]: def
|
|
36
|
-
}) : acc;
|
|
37
|
-
}, undefined));
|
|
38
|
-
} else {
|
|
39
|
-
return undefined;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function getDefaults(overrides = {}) {
|
|
44
|
-
return _deepmerge.default.all([getDefaultFromSchema(), overrides], {
|
|
45
|
-
// overwrite default arrays, do not merge
|
|
46
|
-
arrayMerge: (_, arr) => arr
|
|
47
|
-
});
|
|
48
|
-
}
|
package/dist/index.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = void 0;
|
|
7
|
-
|
|
8
|
-
var _load = _interopRequireWildcard(require("./load"));
|
|
9
|
-
|
|
10
|
-
var _validate = _interopRequireWildcard(require("./validate"));
|
|
11
|
-
|
|
12
|
-
var _defaults = _interopRequireDefault(require("./defaults"));
|
|
13
|
-
|
|
14
|
-
var _stringify = _interopRequireDefault(require("./stringify"));
|
|
15
|
-
|
|
16
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
|
-
|
|
18
|
-
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
|
19
|
-
|
|
20
|
-
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
21
|
-
|
|
22
|
-
// Export a single object that can be imported as PercyConfig
|
|
23
|
-
var _default = {
|
|
24
|
-
load: _load.default,
|
|
25
|
-
cache: _load.cache,
|
|
26
|
-
explorer: _load.explorer,
|
|
27
|
-
validate: _validate.default,
|
|
28
|
-
addSchema: _validate.addSchema,
|
|
29
|
-
resetSchema: _validate.resetSchema,
|
|
30
|
-
getDefaults: _defaults.default,
|
|
31
|
-
stringify: _stringify.default
|
|
32
|
-
};
|
|
33
|
-
exports.default = _default;
|
package/dist/load.js
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = load;
|
|
7
|
-
exports.explorer = exports.cache = void 0;
|
|
8
|
-
|
|
9
|
-
var _path = require("path");
|
|
10
|
-
|
|
11
|
-
var _cosmiconfig = require("cosmiconfig");
|
|
12
|
-
|
|
13
|
-
var _pathType = require("path-type");
|
|
14
|
-
|
|
15
|
-
var _deepmerge = _interopRequireDefault(require("deepmerge"));
|
|
16
|
-
|
|
17
|
-
var _logger = _interopRequireDefault(require("@percy/logger"));
|
|
18
|
-
|
|
19
|
-
var _defaults = _interopRequireDefault(require("./defaults"));
|
|
20
|
-
|
|
21
|
-
var _normalize = _interopRequireDefault(require("./normalize"));
|
|
22
|
-
|
|
23
|
-
var _validate = _interopRequireDefault(require("./validate"));
|
|
24
|
-
|
|
25
|
-
var _stringify = require("./stringify");
|
|
26
|
-
|
|
27
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
28
|
-
|
|
29
|
-
// Loaded configuration file cache
|
|
30
|
-
const cache = new Map(); // The cosmiconfig explorer used to load config files
|
|
31
|
-
|
|
32
|
-
exports.cache = cache;
|
|
33
|
-
const explorer = (0, _cosmiconfig.cosmiconfigSync)('percy', {
|
|
34
|
-
cache: false,
|
|
35
|
-
searchPlaces: ['package.json', '.percyrc', '.percy.json', '.percy.yaml', '.percy.yml', '.percy.js', 'percy.config.js']
|
|
36
|
-
}); // Finds and loads a config file using cosmiconfig, merges it with optional
|
|
37
|
-
// inputs, validates the combined config according to the schema, and returns
|
|
38
|
-
// the combined config. Loaded config files are cached and reused on next load,
|
|
39
|
-
// unless `reload` is true in which the file will be reloaded and the cache
|
|
40
|
-
// updated. Validation errors are logged as warnings and the config is returned
|
|
41
|
-
// unless `bail` is true. Supports kebab-case and camelCase config options and
|
|
42
|
-
// always returns camelCase options. Currently only supports version 2 config
|
|
43
|
-
// files; missing versions or other versions are discarded.
|
|
44
|
-
|
|
45
|
-
exports.explorer = explorer;
|
|
46
|
-
|
|
47
|
-
function load({
|
|
48
|
-
path,
|
|
49
|
-
overrides = {},
|
|
50
|
-
reload = false,
|
|
51
|
-
bail = false
|
|
52
|
-
} = {}) {
|
|
53
|
-
var _Array$from;
|
|
54
|
-
|
|
55
|
-
// load cached config; when no path is specified, get the last config cached
|
|
56
|
-
let config = path ? cache.get(path) : (_Array$from = Array.from(cache)[cache.size - 1]) === null || _Array$from === void 0 ? void 0 : _Array$from[1]; // load config or reload cached config
|
|
57
|
-
|
|
58
|
-
if (path !== false && (!config || reload)) {
|
|
59
|
-
try {
|
|
60
|
-
let result = !path || (0, _pathType.isDirectorySync)(path) ? explorer.search(path) : explorer.load(path);
|
|
61
|
-
|
|
62
|
-
if (result && result.config) {
|
|
63
|
-
_logger.default.debug(`Found config file: ${(0, _path.relative)('', result.filepath)}`);
|
|
64
|
-
|
|
65
|
-
if (result.config.version !== 2) {
|
|
66
|
-
_logger.default.warn('Ignoring config file - ' + (!result.config.version ? 'missing version' : 'unsupported version'));
|
|
67
|
-
} else {
|
|
68
|
-
// normalize to remove empty values and convert snake-case to camelCase
|
|
69
|
-
config = (0, _normalize.default)(result.config);
|
|
70
|
-
cache.set(path, config);
|
|
71
|
-
}
|
|
72
|
-
} else {
|
|
73
|
-
_logger.default.debug('Config file not found');
|
|
74
|
-
}
|
|
75
|
-
} catch (error) {
|
|
76
|
-
_logger.default.debug('Failed to load or parse config file');
|
|
77
|
-
|
|
78
|
-
_logger.default.debug(error);
|
|
79
|
-
}
|
|
80
|
-
} // merge found config with overrides and validate
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
config = (0, _deepmerge.default)(config || {}, overrides);
|
|
84
|
-
if (!(0, _validate.default)(config, {
|
|
85
|
-
scrub: true
|
|
86
|
-
}) && bail) return; // normalize again to remove empty values from overrides and validation scrubbing
|
|
87
|
-
|
|
88
|
-
config = (0, _normalize.default)(config);
|
|
89
|
-
if (config) _logger.default.debug(`Using config:\n${(0, _stringify.inspect)(config)}`); // merge with defaults
|
|
90
|
-
|
|
91
|
-
return (0, _defaults.default)(config);
|
|
92
|
-
}
|
package/dist/normalize.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = normalize;
|
|
7
|
-
|
|
8
|
-
// recursively reduces config objects and arrays to remove undefined and empty
|
|
9
|
-
// values and rename kebab-case properties to camelCase.
|
|
10
|
-
function normalize(subject) {
|
|
11
|
-
if (typeof subject === 'object') {
|
|
12
|
-
let isArray = Array.isArray(subject);
|
|
13
|
-
return Object.entries(subject).reduce((result, [key, value]) => {
|
|
14
|
-
value = normalize(value);
|
|
15
|
-
|
|
16
|
-
if (typeof value !== 'undefined') {
|
|
17
|
-
return isArray ? (result || []).concat(value) : Object.assign(result || {}, {
|
|
18
|
-
[camelize(key)]: value
|
|
19
|
-
});
|
|
20
|
-
} else {
|
|
21
|
-
return result;
|
|
22
|
-
}
|
|
23
|
-
}, undefined);
|
|
24
|
-
} else {
|
|
25
|
-
return subject;
|
|
26
|
-
}
|
|
27
|
-
} // Edge case camelizations
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const CAMELIZE_MAP = {
|
|
31
|
-
css: 'CSS',
|
|
32
|
-
javascript: 'JavaScript'
|
|
33
|
-
}; // Converts a kebab-cased string to camelCase.
|
|
34
|
-
|
|
35
|
-
function camelize(s) {
|
|
36
|
-
return s.replace(/-([^-]+)/g, (_, w) => CAMELIZE_MAP[w] || w[0].toUpperCase() + w.slice(1));
|
|
37
|
-
}
|
package/dist/stringify.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.inspect = inspect;
|
|
7
|
-
exports.default = stringify;
|
|
8
|
-
|
|
9
|
-
var _util = _interopRequireDefault(require("util"));
|
|
10
|
-
|
|
11
|
-
var _yaml = _interopRequireDefault(require("yaml"));
|
|
12
|
-
|
|
13
|
-
var _defaults = _interopRequireDefault(require("./defaults"));
|
|
14
|
-
|
|
15
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
16
|
-
|
|
17
|
-
// Provides native util.inspect with common options for printing configs.
|
|
18
|
-
function inspect(config) {
|
|
19
|
-
return _util.default.inspect(config, {
|
|
20
|
-
depth: null,
|
|
21
|
-
compact: false
|
|
22
|
-
});
|
|
23
|
-
} // Converts a config to a yaml, json, or js string. When no config is provided,
|
|
24
|
-
// falls back to schema defaults.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
function stringify(format, config = (0, _defaults.default)()) {
|
|
28
|
-
switch (format) {
|
|
29
|
-
case 'yml':
|
|
30
|
-
case 'yaml':
|
|
31
|
-
return _yaml.default.stringify(config);
|
|
32
|
-
|
|
33
|
-
case 'json':
|
|
34
|
-
return JSON.stringify(config, null, 2);
|
|
35
|
-
|
|
36
|
-
case 'js':
|
|
37
|
-
return `module.exports = ${inspect(config)}`;
|
|
38
|
-
|
|
39
|
-
default:
|
|
40
|
-
throw new Error(`Unsupported format: ${format}`);
|
|
41
|
-
}
|
|
42
|
-
}
|
package/dist/validate.js
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.getSchema = getSchema;
|
|
7
|
-
exports.addSchema = addSchema;
|
|
8
|
-
exports.resetSchema = resetSchema;
|
|
9
|
-
exports.default = validate;
|
|
10
|
-
|
|
11
|
-
var _ajv = _interopRequireDefault(require("ajv"));
|
|
12
|
-
|
|
13
|
-
var _logger = _interopRequireDefault(require("@percy/logger"));
|
|
14
|
-
|
|
15
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
16
|
-
|
|
17
|
-
const {
|
|
18
|
-
assign,
|
|
19
|
-
entries
|
|
20
|
-
} = Object; // Ajv manages and validates schemas.
|
|
21
|
-
|
|
22
|
-
const ajv = new _ajv.default({
|
|
23
|
-
verbose: true,
|
|
24
|
-
allErrors: true,
|
|
25
|
-
schemas: {
|
|
26
|
-
config: getDefaultSchema()
|
|
27
|
-
}
|
|
28
|
-
}); // Returns a new default schema.
|
|
29
|
-
|
|
30
|
-
function getDefaultSchema() {
|
|
31
|
-
return {
|
|
32
|
-
type: 'object',
|
|
33
|
-
additionalProperties: false,
|
|
34
|
-
properties: {
|
|
35
|
-
version: {
|
|
36
|
-
type: 'integer',
|
|
37
|
-
default: 2
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
} // Gets the schema object from the AJV schema.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
function getSchema(name) {
|
|
45
|
-
return ajv.getSchema(name).schema;
|
|
46
|
-
} // Adds schemas to the config schema's properties. The config schema is removed,
|
|
47
|
-
// modified, and replaced after the new schemas are added to clear any compiled
|
|
48
|
-
// caches. Existing schemas are removed and replaced as well.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
function addSchema(schemas) {
|
|
52
|
-
let config = getSchema('config');
|
|
53
|
-
ajv.removeSchema('config');
|
|
54
|
-
|
|
55
|
-
for (let [$id, schema] of entries(schemas)) {
|
|
56
|
-
if (ajv.getSchema($id)) ajv.removeSchema($id);
|
|
57
|
-
assign(config.properties, {
|
|
58
|
-
[$id]: {
|
|
59
|
-
$ref: $id
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
ajv.addSchema(schema, $id);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
ajv.addSchema(config, 'config');
|
|
66
|
-
} // Resets the schema by removing all schemas and inserting a new default schema.
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
function resetSchema() {
|
|
70
|
-
ajv.removeSchema();
|
|
71
|
-
ajv.addSchema(getDefaultSchema(), 'config');
|
|
72
|
-
} // Validates config data according to the config schema and logs warnings to the
|
|
73
|
-
// console. Optionallly scrubs invalid values from the provided config. Returns
|
|
74
|
-
// true when the validation success, false otherwise.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
function validate(config, {
|
|
78
|
-
scrub
|
|
79
|
-
} = {}) {
|
|
80
|
-
let result = ajv.validate('config', config);
|
|
81
|
-
|
|
82
|
-
if (!result) {
|
|
83
|
-
_logger.default.warn('Invalid config:');
|
|
84
|
-
|
|
85
|
-
for (let error of ajv.errors) {
|
|
86
|
-
let {
|
|
87
|
-
dataPath,
|
|
88
|
-
keyword,
|
|
89
|
-
params,
|
|
90
|
-
message,
|
|
91
|
-
data
|
|
92
|
-
} = error;
|
|
93
|
-
let pre = dataPath ? `'${dataPath.substr(1)}' ` : '';
|
|
94
|
-
|
|
95
|
-
if (keyword === 'required') {
|
|
96
|
-
message = `is missing required property '${params.missingProperty}'`;
|
|
97
|
-
} else if (keyword === 'additionalProperties') {
|
|
98
|
-
pre = pre ? `${pre}has ` : '';
|
|
99
|
-
message = `unknown property '${params.additionalProperty}'`;
|
|
100
|
-
if (scrub) delete data[params.additionalProperty];
|
|
101
|
-
} else if (keyword === 'type') {
|
|
102
|
-
let dataType = Array.isArray(data) ? 'array' : typeof data;
|
|
103
|
-
message = `should be ${a(params.type)}, received ${a(dataType)}`;
|
|
104
|
-
|
|
105
|
-
if (scrub) {
|
|
106
|
-
let [key, ...path] = dataPath.substr(1).split('.').reverse();
|
|
107
|
-
delete path.reduceRight((d, k) => d[k], config)[key];
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
_logger.default.warn(`- ${pre}${message}`);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
return result;
|
|
116
|
-
} // Adds "a" or "an" to a word for readability.
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
function a(word) {
|
|
120
|
-
return `${'aeiou'.includes(word[0]) ? 'an' : 'a'} ${word}`;
|
|
121
|
-
}
|
package/types/index.d.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { JSONSchema } from 'json-schema-typed';
|
|
2
|
-
|
|
3
|
-
interface Pojo { [x: string]: any; }
|
|
4
|
-
export interface PercyConfigObject extends Pojo { version: number; }
|
|
5
|
-
|
|
6
|
-
declare namespace PercyConfig {
|
|
7
|
-
function load(options?: {
|
|
8
|
-
path?: undefined | string | false,
|
|
9
|
-
overrides?: Pojo,
|
|
10
|
-
reload?: boolean,
|
|
11
|
-
bail?: boolean
|
|
12
|
-
}): PercyConfigObject;
|
|
13
|
-
|
|
14
|
-
function validate(
|
|
15
|
-
config: PercyConfigObject,
|
|
16
|
-
options?: { scrub?: boolean }
|
|
17
|
-
): boolean;
|
|
18
|
-
|
|
19
|
-
function addSchema(schemas: {
|
|
20
|
-
[x: string]: JSONSchema
|
|
21
|
-
}): void;
|
|
22
|
-
|
|
23
|
-
function getDefaults(
|
|
24
|
-
overrides?: Pojo
|
|
25
|
-
): PercyConfigObject;
|
|
26
|
-
|
|
27
|
-
function stringify(
|
|
28
|
-
format: 'yaml' | 'json' | 'js',
|
|
29
|
-
config?: PercyConfigObject
|
|
30
|
-
): string;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export default PercyConfig
|