improve validation errors
This commit is contained in:
parent
0963d744e9
commit
a4406ff187
|
@ -22,6 +22,8 @@ export type EntryDynamic = () => EntryStatic | Promise<EntryStatic>;
|
||||||
*/
|
*/
|
||||||
export type EntryStatic = EntryObject | EntryItem;
|
export type EntryStatic = EntryObject | EntryItem;
|
||||||
/**
|
/**
|
||||||
|
* A non-empty array of non-empty strings
|
||||||
|
*
|
||||||
* This interface was referenced by `WebpackOptions`'s JSON-Schema
|
* This interface was referenced by `WebpackOptions`'s JSON-Schema
|
||||||
* via the `definition` "NonEmptyArrayOfUniqueStringValues".
|
* via the `definition` "NonEmptyArrayOfUniqueStringValues".
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -50,13 +50,34 @@ const getSchemaPartDescription = schemaPart => {
|
||||||
return "";
|
return "";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const SPECIFICITY = {
|
||||||
|
type: 1,
|
||||||
|
oneOf: 1,
|
||||||
|
anyOf: 1,
|
||||||
|
allOf: 1,
|
||||||
|
additionalProperties: 2,
|
||||||
|
enum: 1,
|
||||||
|
instanceof: 1,
|
||||||
|
required: 2,
|
||||||
|
minimum: 2,
|
||||||
|
uniqueItems: 2,
|
||||||
|
minLength: 2,
|
||||||
|
minItems: 2,
|
||||||
|
minProperties: 2,
|
||||||
|
absolutePath: 2
|
||||||
|
};
|
||||||
|
|
||||||
|
const filterMax = (array, fn) => {
|
||||||
|
const max = array.reduce((max, item) => Math.max(max, fn(item)), 0);
|
||||||
|
return array.filter(item => fn(item) === max);
|
||||||
|
};
|
||||||
|
|
||||||
const filterChildren = children => {
|
const filterChildren = children => {
|
||||||
return children.filter(
|
children = filterMax(children, err =>
|
||||||
err =>
|
err.dataPath ? err.dataPath.length : 0
|
||||||
err.keyword !== "anyOf" &&
|
|
||||||
err.keyword !== "allOf" &&
|
|
||||||
err.keyword !== "oneOf"
|
|
||||||
);
|
);
|
||||||
|
children = filterMax(children, err => SPECIFICITY[err.keyword] || 2);
|
||||||
|
return children;
|
||||||
};
|
};
|
||||||
|
|
||||||
const indent = (str, prefix, firstLine) => {
|
const indent = (str, prefix, firstLine) => {
|
||||||
|
@ -230,11 +251,17 @@ class WebpackOptionsValidationError extends WebpackError {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
const children = filterChildren(err.children);
|
||||||
|
if (children.length === 1) {
|
||||||
|
return WebpackOptionsValidationError.formatValidationError(
|
||||||
|
children[0]
|
||||||
|
);
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
`${dataPath} should be one of these:\n${getSchemaPartText(
|
`${dataPath} should be one of these:\n${getSchemaPartText(
|
||||||
err.parentSchema
|
err.parentSchema
|
||||||
)}\n` +
|
)}\n` +
|
||||||
`Details:\n${filterChildren(err.children)
|
`Details:\n${children
|
||||||
.map(
|
.map(
|
||||||
err =>
|
err =>
|
||||||
" * " +
|
" * " +
|
||||||
|
@ -251,7 +278,6 @@ class WebpackOptionsValidationError extends WebpackError {
|
||||||
err.parentSchema
|
err.parentSchema
|
||||||
)}`;
|
)}`;
|
||||||
} else if (err.keyword === "enum") {
|
} else if (err.keyword === "enum") {
|
||||||
console.log(err.parentSchema);
|
|
||||||
if (
|
if (
|
||||||
err.parentSchema &&
|
err.parentSchema &&
|
||||||
err.parentSchema.enum &&
|
err.parentSchema.enum &&
|
||||||
|
@ -314,7 +340,21 @@ class WebpackOptionsValidationError extends WebpackError {
|
||||||
err.keyword === "minProperties"
|
err.keyword === "minProperties"
|
||||||
) {
|
) {
|
||||||
if (err.params.limit === 1) {
|
if (err.params.limit === 1) {
|
||||||
return `${dataPath} should not be empty.${getSchemaPartDescription(
|
switch (err.keyword) {
|
||||||
|
case "minLength":
|
||||||
|
return `${dataPath} should be an non-empty string.${getSchemaPartDescription(
|
||||||
|
err.parentSchema
|
||||||
|
)}`;
|
||||||
|
case "minItems":
|
||||||
|
return `${dataPath} should be an non-empty array.${getSchemaPartDescription(
|
||||||
|
err.parentSchema
|
||||||
|
)}`;
|
||||||
|
case "minProperties":
|
||||||
|
return `${dataPath} should be an non-empty object.${getSchemaPartDescription(
|
||||||
|
err.parentSchema
|
||||||
|
)}`;
|
||||||
|
}
|
||||||
|
return `${dataPath} should be not empty.${getSchemaPartDescription(
|
||||||
err.parentSchema
|
err.parentSchema
|
||||||
)}`;
|
)}`;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -385,6 +385,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"NonEmptyArrayOfUniqueStringValues": {
|
"NonEmptyArrayOfUniqueStringValues": {
|
||||||
|
"description": "A non-empty array of non-empty strings",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"description": "A non-empty string",
|
"description": "A non-empty string",
|
||||||
|
|
|
@ -43,18 +43,8 @@ describe("Validation", () => {
|
||||||
msg =>
|
msg =>
|
||||||
expect(msg).toMatchInlineSnapshot(`
|
expect(msg).toMatchInlineSnapshot(`
|
||||||
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
|
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
|
||||||
- configuration.entry should be one of these:
|
- configuration.entry should be an non-empty string.
|
||||||
function | object { <key>: non-empty string | [non-empty string] } | non-empty string | [non-empty string]
|
-> An entry point without name. The string is resolved to a module which is loaded upon startup."
|
||||||
-> The entry point(s) of the compilation.
|
|
||||||
Details:
|
|
||||||
* configuration.entry should be an instance of function
|
|
||||||
-> A Function returning an entry object, an entry string, an entry array or a promise to these things.
|
|
||||||
* configuration.entry should be an object.
|
|
||||||
-> Multiple entry bundles are created. The key is the chunk name. The value can be a string or an array.
|
|
||||||
* configuration.entry should not be empty.
|
|
||||||
-> An entry point without name. The string is resolved to a module which is loaded upon startup.
|
|
||||||
* configuration.entry should be an array:
|
|
||||||
[non-empty string]"
|
|
||||||
`)
|
`)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -68,19 +58,8 @@ describe("Validation", () => {
|
||||||
msg =>
|
msg =>
|
||||||
expect(msg).toMatchInlineSnapshot(`
|
expect(msg).toMatchInlineSnapshot(`
|
||||||
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
|
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
|
||||||
- configuration.entry should be one of these:
|
- configuration.entry['bundle'] should be an non-empty array.
|
||||||
function | object { <key>: non-empty string | [non-empty string] } | non-empty string | [non-empty string]
|
-> A non-empty array of non-empty strings"
|
||||||
-> The entry point(s) of the compilation.
|
|
||||||
Details:
|
|
||||||
* configuration.entry should be an instance of function
|
|
||||||
-> A Function returning an entry object, an entry string, an entry array or a promise to these things.
|
|
||||||
* configuration.entry['bundle'] should be a string.
|
|
||||||
-> The string is resolved to a module which is loaded upon startup.
|
|
||||||
* configuration.entry['bundle'] should not be empty.
|
|
||||||
* configuration.entry should be a string.
|
|
||||||
-> An entry point without name. The string is resolved to a module which is loaded upon startup.
|
|
||||||
* configuration.entry should be an array:
|
|
||||||
[non-empty string]"
|
|
||||||
`)
|
`)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -122,17 +101,8 @@ describe("Validation", () => {
|
||||||
msg =>
|
msg =>
|
||||||
expect(msg).toMatchInlineSnapshot(`
|
expect(msg).toMatchInlineSnapshot(`
|
||||||
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
|
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
|
||||||
- configuration.entry should be one of these:
|
- configuration.entry should not contain the item 'abc' twice.
|
||||||
function | object { <key>: non-empty string | [non-empty string] } | non-empty string | [non-empty string]
|
-> A non-empty array of non-empty strings"
|
||||||
-> The entry point(s) of the compilation.
|
|
||||||
Details:
|
|
||||||
* configuration.entry should be an instance of function
|
|
||||||
-> A Function returning an entry object, an entry string, an entry array or a promise to these things.
|
|
||||||
* configuration.entry should be an object.
|
|
||||||
-> Multiple entry bundles are created. The key is the chunk name. The value can be a string or an array.
|
|
||||||
* configuration.entry should be a string.
|
|
||||||
-> An entry point without name. The string is resolved to a module which is loaded upon startup.
|
|
||||||
* configuration.entry should not contain the item 'abc' twice."
|
|
||||||
`)
|
`)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -147,18 +117,8 @@ describe("Validation", () => {
|
||||||
msg =>
|
msg =>
|
||||||
expect(msg).toMatchInlineSnapshot(`
|
expect(msg).toMatchInlineSnapshot(`
|
||||||
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
|
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
|
||||||
- configuration.entry should be one of these:
|
- configuration.entry[0] should be a string.
|
||||||
function | object { <key>: non-empty string | [non-empty string] } | non-empty string | [non-empty string]
|
-> A non-empty string
|
||||||
-> The entry point(s) of the compilation.
|
|
||||||
Details:
|
|
||||||
* configuration.entry should be an instance of function
|
|
||||||
-> A Function returning an entry object, an entry string, an entry array or a promise to these things.
|
|
||||||
* configuration.entry should be an object.
|
|
||||||
-> Multiple entry bundles are created. The key is the chunk name. The value can be a string or an array.
|
|
||||||
* configuration.entry should be a string.
|
|
||||||
-> An entry point without name. The string is resolved to a module which is loaded upon startup.
|
|
||||||
* configuration.entry[0] should be a string.
|
|
||||||
-> A non-empty string
|
|
||||||
- configuration.output.filename should be one of these:
|
- configuration.output.filename should be one of these:
|
||||||
string | function
|
string | function
|
||||||
-> Specifies the name of each output file on disk. You must **not** specify an absolute path here! The \`output.path\` option determines the location on disk the files are written to, filename is used solely for naming the individual files.
|
-> Specifies the name of each output file on disk. You must **not** specify an absolute path here! The \`output.path\` option determines the location on disk the files are written to, filename is used solely for naming the individual files.
|
||||||
|
@ -184,18 +144,8 @@ describe("Validation", () => {
|
||||||
msg =>
|
msg =>
|
||||||
expect(msg).toMatchInlineSnapshot(`
|
expect(msg).toMatchInlineSnapshot(`
|
||||||
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
|
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
|
||||||
- configuration[0].entry should be one of these:
|
- configuration[0].entry[0] should be a string.
|
||||||
function | object { <key>: non-empty string | [non-empty string] } | non-empty string | [non-empty string]
|
-> A non-empty string
|
||||||
-> The entry point(s) of the compilation.
|
|
||||||
Details:
|
|
||||||
* configuration[0].entry should be an instance of function
|
|
||||||
-> A Function returning an entry object, an entry string, an entry array or a promise to these things.
|
|
||||||
* configuration[0].entry should be an object.
|
|
||||||
-> Multiple entry bundles are created. The key is the chunk name. The value can be a string or an array.
|
|
||||||
* configuration[0].entry should be a string.
|
|
||||||
-> An entry point without name. The string is resolved to a module which is loaded upon startup.
|
|
||||||
* configuration[0].entry[0] should be a string.
|
|
||||||
-> A non-empty string
|
|
||||||
- configuration[1].output.filename should be one of these:
|
- configuration[1].output.filename should be one of these:
|
||||||
string | function
|
string | function
|
||||||
-> Specifies the name of each output file on disk. You must **not** specify an absolute path here! The \`output.path\` option determines the location on disk the files are written to, filename is used solely for naming the individual files.
|
-> Specifies the name of each output file on disk. You must **not** specify an absolute path here! The \`output.path\` option determines the location on disk the files are written to, filename is used solely for naming the individual files.
|
||||||
|
@ -305,13 +255,8 @@ describe("Validation", () => {
|
||||||
msg =>
|
msg =>
|
||||||
expect(msg).toMatchInlineSnapshot(`
|
expect(msg).toMatchInlineSnapshot(`
|
||||||
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
|
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
|
||||||
- configuration.output.filename should be one of these:
|
- configuration.output.filename: A relative path is expected. However, the provided value \\"/bar\\" is an absolute path!
|
||||||
string | function
|
Please use output.path to specify absolute path and output.filename for the file name."
|
||||||
-> Specifies the name of each output file on disk. You must **not** specify an absolute path here! The \`output.path\` option determines the location on disk the files are written to, filename is used solely for naming the individual files.
|
|
||||||
Details:
|
|
||||||
* configuration.output.filename: A relative path is expected. However, the provided value \\"/bar\\" is an absolute path!
|
|
||||||
Please use output.path to specify absolute path and output.filename for the file name.
|
|
||||||
* configuration.output.filename should be an instance of function"
|
|
||||||
`)
|
`)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -347,15 +292,8 @@ describe("Validation", () => {
|
||||||
.replace(/"none" \| .+/g, '"none" | ...')
|
.replace(/"none" \| .+/g, '"none" | ...')
|
||||||
).toMatchInlineSnapshot(`
|
).toMatchInlineSnapshot(`
|
||||||
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
|
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
|
||||||
- configuration.stats should be one of these:
|
- configuration.stats has an unknown property 'foobar'. These properties are valid:
|
||||||
object {...} | boolean | \\"none\\" | ...
|
object {...}"
|
||||||
-> Used by the webpack CLI program to pass stats options.
|
|
||||||
Details:
|
|
||||||
* configuration.stats has an unknown property 'foobar'. These properties are valid:
|
|
||||||
object {...}
|
|
||||||
* configuration.stats should be a boolean.
|
|
||||||
* configuration.stats should be one of these:
|
|
||||||
\\"none\\" | ..."
|
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -449,15 +387,9 @@ describe("Validation", () => {
|
||||||
msg =>
|
msg =>
|
||||||
expect(msg).toMatchInlineSnapshot(`
|
expect(msg).toMatchInlineSnapshot(`
|
||||||
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
|
"Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
|
||||||
- configuration.plugins[0] should be one of these:
|
- configuration.plugins[0] misses the property 'apply'.
|
||||||
object { apply, … } | function
|
function
|
||||||
-> Plugin of type object or instanceof Function
|
-> The run point of the plugin, required method."
|
||||||
Details:
|
|
||||||
* configuration.plugins[0] misses the property 'apply'.
|
|
||||||
function
|
|
||||||
-> The run point of the plugin, required method.
|
|
||||||
* configuration.plugins[0] should be an instance of function
|
|
||||||
-> Function acting as plugin"
|
|
||||||
`)
|
`)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue