Skip to content

Commit afddc10

Browse files
feat: support configuration via title (#81)
1 parent 3a4f74a commit afddc10

File tree

8 files changed

+852
-550
lines changed

8 files changed

+852
-550
lines changed

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,26 @@ validate(
9696

9797
Allow to configure validator.
9898

99+
There is an alternative method to configure the `name` and`baseDataPath` options via the `title` property in the schema.
100+
For example:
101+
102+
```json
103+
{
104+
"title": "My Loader options",
105+
"type": "object",
106+
"properties": {
107+
"name": {
108+
"description": "This is description of option.",
109+
"type": "string"
110+
}
111+
},
112+
"additionalProperties": false
113+
}
114+
```
115+
116+
The last word used for the `baseDataPath` option, other words used for the `name` option.
117+
Based on the example above the `name` option equals `My Loader`, the `baseDataPath` option equals `options`.
118+
99119
#### `name`
100120

101121
Type: `Object`

package-lock.json

Lines changed: 680 additions & 539 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,29 +43,29 @@
4343
"ajv-keywords": "^3.4.1"
4444
},
4545
"devDependencies": {
46-
"@babel/cli": "^7.7.0",
47-
"@babel/core": "^7.7.2",
48-
"@babel/preset-env": "^7.7.1",
46+
"@babel/cli": "^7.7.4",
47+
"@babel/core": "^7.7.4",
48+
"@babel/preset-env": "^7.7.4",
4949
"@commitlint/cli": "^8.2.0",
5050
"@commitlint/config-conventional": "^8.2.0",
5151
"@types/json-schema": "^7.0.3",
52-
"@webpack-contrib/defaults": "^5.1.1",
52+
"@webpack-contrib/defaults": "^6.2.0",
5353
"@webpack-contrib/eslint-config-webpack": "^3.0.0",
5454
"babel-jest": "^24.9.0",
5555
"commitlint-azure-pipelines-cli": "^1.0.2",
5656
"cross-env": "^6.0.3",
5757
"del": "^5.1.0",
5858
"del-cli": "^3.0.0",
59-
"eslint": "^6.6.0",
60-
"eslint-config-prettier": "^6.5.0",
59+
"eslint": "^6.7.1",
60+
"eslint-config-prettier": "^6.7.0",
6161
"eslint-plugin-import": "^2.18.2",
62-
"husky": "^3.0.9",
62+
"husky": "^3.1.0",
6363
"jest": "^24.9.0",
6464
"jest-junit": "^9.0.0",
65-
"lint-staged": "^9.4.2",
65+
"lint-staged": "^9.5.0",
6666
"npm-run-all": "^4.1.5",
6767
"prettier": "^1.19.1",
68-
"standard-version": "^7.0.0",
68+
"standard-version": "^7.0.1",
6969
"typescript": "^3.7.2"
7070
},
7171
"keywords": [

src/ValidationError.js

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -408,10 +408,30 @@ class ValidationError extends Error {
408408
this.errors = errors;
409409
/** @type {Schema} */
410410
this.schema = schema;
411+
412+
let headerNameFromSchema;
413+
let baseDataPathFromSchema;
414+
415+
if (schema.title && (!configuration.name || !configuration.baseDataPath)) {
416+
const splittedTitleFromSchema = schema.title.match(/^(.+) (.+)$/);
417+
418+
if (splittedTitleFromSchema) {
419+
if (!configuration.name) {
420+
[, headerNameFromSchema] = splittedTitleFromSchema;
421+
}
422+
423+
if (!configuration.name) {
424+
[, , baseDataPathFromSchema] = splittedTitleFromSchema;
425+
}
426+
}
427+
}
428+
411429
/** @type {string} */
412-
this.headerName = configuration.name || 'Object';
430+
this.headerName = configuration.name || headerNameFromSchema || 'Object';
413431
/** @type {string} */
414-
this.baseDataPath = configuration.baseDataPath || 'configuration';
432+
this.baseDataPath =
433+
configuration.baseDataPath || baseDataPathFromSchema || 'configuration';
434+
415435
/** @type {PostFormatter | null} */
416436
this.postFormatter = configuration.postFormatter || null;
417437

test/__snapshots__/api.test.js.snap

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`api should get configuration from schema 1`] = `
4+
"Invalid options object. CSS Loader has been initialised using an options object that does not match the API schema.
5+
- options has an unknown property 'foo'. These properties are valid:
6+
object { name? }"
7+
`;
8+
9+
exports[`api should prefer configuration over "title" #1 1`] = `
10+
"Invalid configuration object. NAME has been initialised using a configuration object that does not match the API schema.
11+
- configuration has an unknown property 'foo'. These properties are valid:
12+
object { name? }"
13+
`;
14+
15+
exports[`api should prefer configuration over "title" #2 1`] = `
16+
"Invalid BaseDataPath object. CSS Loader has been initialised using a BaseDataPath object that does not match the API schema.
17+
- BaseDataPath has an unknown property 'foo'. These properties are valid:
18+
object { name? }"
19+
`;
20+
21+
exports[`api should prefer configuration over "title" 1`] = `
22+
"Invalid BaseDataPath object. NAME has been initialised using a BaseDataPath object that does not match the API schema.
23+
- BaseDataPath has an unknown property 'foo'. These properties are valid:
24+
object { name? }"
25+
`;
26+
27+
exports[`api should use default values when "title" is broken 1`] = `
28+
"Invalid configuration object. Object has been initialised using a configuration object that does not match the API schema.
29+
- configuration has an unknown property 'foo'. These properties are valid:
30+
object { name? }"
31+
`;

test/api.test.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import schemaUtils from '../src/index';
22

33
import schema from './fixtures/schema.json';
4+
import schemaTitle from './fixtures/schema-title.json';
5+
import schemaTitleBrone from './fixtures/schema-title-broken.json';
46

57
describe('api', () => {
68
it('should export validate and ValidateError', () => {
@@ -32,4 +34,72 @@ describe('api', () => {
3234

3335
schemaUtils(schema, options);
3436
});
37+
38+
it('should get configuration from schema', () => {
39+
try {
40+
schemaUtils(schemaTitle, { foo: 'bar' });
41+
} catch (error) {
42+
if (error.name !== 'ValidationError') {
43+
throw error;
44+
}
45+
46+
expect(error.message).toMatchSnapshot();
47+
}
48+
});
49+
50+
it('should prefer configuration over "title"', () => {
51+
try {
52+
schemaUtils(
53+
schemaTitle,
54+
{ foo: 'bar' },
55+
{ name: 'NAME', baseDataPath: 'BaseDataPath' }
56+
);
57+
} catch (error) {
58+
if (error.name !== 'ValidationError') {
59+
throw error;
60+
}
61+
62+
expect(error.message).toMatchSnapshot();
63+
}
64+
});
65+
66+
it('should prefer configuration over "title" #1', () => {
67+
try {
68+
schemaUtils(schemaTitle, { foo: 'bar' }, { name: 'NAME' });
69+
} catch (error) {
70+
if (error.name !== 'ValidationError') {
71+
throw error;
72+
}
73+
74+
expect(error.message).toMatchSnapshot();
75+
}
76+
});
77+
78+
it('should prefer configuration over "title" #2', () => {
79+
try {
80+
schemaUtils(
81+
schemaTitle,
82+
{ foo: 'bar' },
83+
{ baseDataPath: 'BaseDataPath' }
84+
);
85+
} catch (error) {
86+
if (error.name !== 'ValidationError') {
87+
throw error;
88+
}
89+
90+
expect(error.message).toMatchSnapshot();
91+
}
92+
});
93+
94+
it('should use default values when "title" is broken', () => {
95+
try {
96+
schemaUtils(schemaTitleBrone, { foo: 'bar' });
97+
} catch (error) {
98+
if (error.name !== 'ValidationError') {
99+
throw error;
100+
}
101+
102+
expect(error.message).toMatchSnapshot();
103+
}
104+
});
35105
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"title": "CSSLoaderoptions",
3+
"additionalProperties": false,
4+
"properties": {
5+
"name": {
6+
"type": "boolean"
7+
}
8+
},
9+
"type": "object"
10+
}

test/fixtures/schema-title.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"title": "CSS Loader options",
3+
"additionalProperties": false,
4+
"properties": {
5+
"name": {
6+
"type": "boolean"
7+
}
8+
},
9+
"type": "object"
10+
}

0 commit comments

Comments
 (0)