@amritk/lint 0.3.1 → 0.3.3
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/LICENSE +21 -0
- package/dist/core/document.js +12 -10
- package/dist/core/formats.js +10 -13
- package/dist/core/glob.js +96 -118
- package/dist/core/index.js +31 -11
- package/dist/core/jsonpath.js +487 -561
- package/dist/core/lint.js +78 -85
- package/dist/core/plugin.js +21 -29
- package/dist/core/pointers.js +107 -151
- package/dist/core/ruleset.js +0 -0
- package/dist/core/runner.js +214 -272
- package/dist/core/types.js +4 -1
- package/dist/core/validate-ruleset.js +98 -112
- package/dist/fix/apply.js +58 -96
- package/dist/fix/index.js +7 -2
- package/dist/fix/plugin.js +15 -20
- package/dist/functions/alphabetical.js +39 -50
- package/dist/functions/casing.js +39 -45
- package/dist/functions/defined.js +7 -5
- package/dist/functions/enumeration.js +15 -25
- package/dist/functions/falsy.js +7 -5
- package/dist/functions/index.js +60 -44
- package/dist/functions/length.js +22 -32
- package/dist/functions/or.js +18 -24
- package/dist/functions/pattern.js +39 -49
- package/dist/functions/schema.js +93 -119
- package/dist/functions/truthy.js +7 -5
- package/dist/functions/typed-enum.js +33 -36
- package/dist/functions/undefined.js +7 -8
- package/dist/functions/unreferenced-reusable-object.js +35 -47
- package/dist/functions/xor.js +13 -16
- package/dist/index.js +114 -164
- package/dist/parsers/edit-model.js +316 -444
- package/dist/parsers/index.js +22 -19
- package/dist/parsers/json.js +39 -37
- package/dist/parsers/lines.js +23 -26
- package/dist/parsers/types.js +9 -7
- package/dist/parsers/yaml.js +137 -204
- package/dist/rules/openapi/fixers.js +166 -221
- package/dist/rules/openapi/formats.js +26 -27
- package/dist/rules/openapi/functions/example-validation.js +98 -138
- package/dist/rules/openapi/functions/helpers.js +8 -10
- package/dist/rules/openapi/functions/index.js +98 -72
- package/dist/rules/openapi/functions/oas-additional-operations.js +16 -22
- package/dist/rules/openapi/functions/oas-discriminator.js +24 -22
- package/dist/rules/openapi/functions/oas-example-external-value.js +13 -21
- package/dist/rules/openapi/functions/oas-example-value.js +24 -27
- package/dist/rules/openapi/functions/oas-mutually-exclusive.js +15 -19
- package/dist/rules/openapi/functions/oas-no-nullable.js +13 -21
- package/dist/rules/openapi/functions/oas-op-form-data-consume-check.js +21 -19
- package/dist/rules/openapi/functions/oas-op-id-unique.js +27 -27
- package/dist/rules/openapi/functions/oas-op-params.js +36 -42
- package/dist/rules/openapi/functions/oas-op-security-defined.js +40 -39
- package/dist/rules/openapi/functions/oas-op-success-response.js +11 -13
- package/dist/rules/openapi/functions/oas-path-param.js +75 -96
- package/dist/rules/openapi/functions/oas-schema-example-deprecated.js +33 -40
- package/dist/rules/openapi/functions/oas-schema.js +9 -14
- package/dist/rules/openapi/functions/oas-server-name-unique.js +21 -19
- package/dist/rules/openapi/functions/oas-server-variables.js +45 -49
- package/dist/rules/openapi/functions/oas-tag-defined.js +20 -20
- package/dist/rules/openapi/functions/oas-tag-kind.js +16 -16
- package/dist/rules/openapi/functions/oas-tag-parent-defined.js +40 -43
- package/dist/rules/openapi/functions/oas-tags-unique.js +18 -16
- package/dist/rules/openapi/functions/oas-unused-component.js +48 -58
- package/dist/rules/openapi/functions/ref-siblings.js +13 -11
- package/dist/rules/openapi/index.js +99 -117
- package/dist/rules/openapi/oas.js +524 -536
- package/dist/rules/openapi/schemas/index.js +17 -33
- package/dist/rules/openapi/schemas/oas20.json +1 -1592
- package/dist/rules/openapi/schemas/oas30.json +1 -1651
- package/dist/rules/openapi/schemas/oas31.json +1 -1412
- package/dist/rules/openapi/schemas/oas32.json +1 -1684
- package/package.json +5 -5
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
const defined = (input) => {
|
|
2
|
+
if (input === void 0)
|
|
3
|
+
return [{ message: "The value must be defined" }];
|
|
4
|
+
return [];
|
|
5
|
+
};
|
|
6
|
+
export {
|
|
7
|
+
defined
|
|
6
8
|
};
|
|
@@ -1,27 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* flagged against a list they could never be `===` to.
|
|
6
|
-
*/
|
|
7
|
-
const isPrimitive = (value) => value === null || (typeof value !== 'object' && typeof value !== 'function');
|
|
8
|
-
/** Flags a value that is not one of the allowed `values`. */
|
|
9
|
-
export const enumeration = (input, options) => {
|
|
10
|
-
const values = options?.values;
|
|
11
|
-
// Without a valid list of allowed values there is nothing to compare against.
|
|
12
|
-
// Spectral requires `values` in its option schema and no-ops when it is
|
|
13
|
-
// missing, so skip rather than flag everything against an empty allow-list.
|
|
14
|
-
if (!Array.isArray(values))
|
|
15
|
-
return [];
|
|
16
|
-
// Spectral's input schema only lets primitives reach this function. `includes`
|
|
17
|
-
// uses reference equality, so a non-primitive would always be reported as
|
|
18
|
-
// "not allowed"; match Spectral by skipping objects and arrays entirely.
|
|
19
|
-
if (!isPrimitive(input))
|
|
20
|
-
return [];
|
|
21
|
-
if (!values.includes(input)) {
|
|
22
|
-
return [
|
|
23
|
-
{ message: `The value must be one of the allowed values: ${values.map((v) => JSON.stringify(v)).join(', ')}` },
|
|
24
|
-
];
|
|
25
|
-
}
|
|
1
|
+
const isPrimitive = (value) => value === null || typeof value !== "object" && typeof value !== "function";
|
|
2
|
+
const enumeration = (input, options) => {
|
|
3
|
+
const values = options?.values;
|
|
4
|
+
if (!Array.isArray(values))
|
|
26
5
|
return [];
|
|
6
|
+
if (!isPrimitive(input))
|
|
7
|
+
return [];
|
|
8
|
+
if (!values.includes(input)) {
|
|
9
|
+
return [
|
|
10
|
+
{ message: `The value must be one of the allowed values: ${values.map((v) => JSON.stringify(v)).join(", ")}` }
|
|
11
|
+
];
|
|
12
|
+
}
|
|
13
|
+
return [];
|
|
14
|
+
};
|
|
15
|
+
export {
|
|
16
|
+
enumeration
|
|
27
17
|
};
|
package/dist/functions/falsy.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
const falsy = (input) => {
|
|
2
|
+
if (input)
|
|
3
|
+
return [{ message: "The value must be falsy" }];
|
|
4
|
+
return [];
|
|
5
|
+
};
|
|
6
|
+
export {
|
|
7
|
+
falsy
|
|
6
8
|
};
|
package/dist/functions/index.js
CHANGED
|
@@ -1,45 +1,61 @@
|
|
|
1
|
-
import { alphabetical } from
|
|
2
|
-
import { casing } from
|
|
3
|
-
import { defined } from
|
|
4
|
-
import { enumeration } from
|
|
5
|
-
import { falsy } from
|
|
6
|
-
import { length } from
|
|
7
|
-
import { or } from
|
|
8
|
-
import { pattern } from
|
|
9
|
-
import { schema } from
|
|
10
|
-
import { truthy } from
|
|
11
|
-
import { typedEnum } from
|
|
12
|
-
import { undefinedFn } from
|
|
13
|
-
import { unreferencedReusableObject } from
|
|
14
|
-
import { xor } from
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
1
|
+
import { alphabetical } from "./alphabetical.js";
|
|
2
|
+
import { casing } from "./casing.js";
|
|
3
|
+
import { defined } from "./defined.js";
|
|
4
|
+
import { enumeration } from "./enumeration.js";
|
|
5
|
+
import { falsy } from "./falsy.js";
|
|
6
|
+
import { length } from "./length.js";
|
|
7
|
+
import { or } from "./or.js";
|
|
8
|
+
import { pattern } from "./pattern.js";
|
|
9
|
+
import { schema } from "./schema.js";
|
|
10
|
+
import { truthy } from "./truthy.js";
|
|
11
|
+
import { typedEnum } from "./typed-enum.js";
|
|
12
|
+
import { undefinedFn } from "./undefined.js";
|
|
13
|
+
import { unreferencedReusableObject } from "./unreferenced-reusable-object.js";
|
|
14
|
+
import { xor } from "./xor.js";
|
|
15
|
+
import { alphabetical as alphabetical2 } from "./alphabetical.js";
|
|
16
|
+
import { casing as casing2 } from "./casing.js";
|
|
17
|
+
import { defined as defined2 } from "./defined.js";
|
|
18
|
+
import { enumeration as enumeration2 } from "./enumeration.js";
|
|
19
|
+
import { falsy as falsy2 } from "./falsy.js";
|
|
20
|
+
import { length as length2 } from "./length.js";
|
|
21
|
+
import { or as or2 } from "./or.js";
|
|
22
|
+
import { pattern as pattern2 } from "./pattern.js";
|
|
23
|
+
import { schema as schema2 } from "./schema.js";
|
|
24
|
+
import { truthy as truthy2 } from "./truthy.js";
|
|
25
|
+
import { typedEnum as typedEnum2 } from "./typed-enum.js";
|
|
26
|
+
import { undefinedFn as undefinedFn2 } from "./undefined.js";
|
|
27
|
+
import { unreferencedReusableObject as unreferencedReusableObject2 } from "./unreferenced-reusable-object.js";
|
|
28
|
+
import { xor as xor2 } from "./xor.js";
|
|
29
|
+
const builtinFunctions = {
|
|
30
|
+
alphabetical,
|
|
31
|
+
casing,
|
|
32
|
+
defined,
|
|
33
|
+
enumeration,
|
|
34
|
+
falsy,
|
|
35
|
+
length,
|
|
36
|
+
or,
|
|
37
|
+
pattern,
|
|
38
|
+
schema,
|
|
39
|
+
truthy,
|
|
40
|
+
undefined: undefinedFn,
|
|
41
|
+
unreferencedReusableObject,
|
|
42
|
+
xor,
|
|
43
|
+
typedEnum
|
|
44
|
+
};
|
|
45
|
+
export {
|
|
46
|
+
alphabetical2 as alphabetical,
|
|
47
|
+
builtinFunctions,
|
|
48
|
+
casing2 as casing,
|
|
49
|
+
defined2 as defined,
|
|
50
|
+
enumeration2 as enumeration,
|
|
51
|
+
falsy2 as falsy,
|
|
52
|
+
length2 as length,
|
|
53
|
+
or2 as or,
|
|
54
|
+
pattern2 as pattern,
|
|
55
|
+
schema2 as schema,
|
|
56
|
+
truthy2 as truthy,
|
|
57
|
+
typedEnum2 as typedEnum,
|
|
58
|
+
undefinedFn2 as undefinedFn,
|
|
59
|
+
unreferencedReusableObject2 as unreferencedReusableObject,
|
|
60
|
+
xor2 as xor
|
|
45
61
|
};
|
package/dist/functions/length.js
CHANGED
|
@@ -1,35 +1,25 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Returns the comparable size of a value: string/array length, object key count,
|
|
3
|
-
* or the number itself. `undefined` for anything else (so the rule is skipped).
|
|
4
|
-
*/
|
|
5
1
|
const measure = (input) => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
2
|
+
if (typeof input === "string" || Array.isArray(input))
|
|
3
|
+
return input.length;
|
|
4
|
+
if (typeof input === "object" && input !== null)
|
|
5
|
+
return Object.keys(input).length;
|
|
6
|
+
if (typeof input === "number")
|
|
7
|
+
return input;
|
|
8
|
+
return void 0;
|
|
13
9
|
};
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
results.push({ message: `The value must not be shorter than ${options.min}` });
|
|
30
|
-
}
|
|
31
|
-
if (typeof options?.max === 'number' && size > options.max) {
|
|
32
|
-
results.push({ message: `The value must not be longer than ${options.max}` });
|
|
33
|
-
}
|
|
34
|
-
return results;
|
|
10
|
+
const length = (input, options) => {
|
|
11
|
+
const size = measure(input);
|
|
12
|
+
if (size === void 0)
|
|
13
|
+
return [];
|
|
14
|
+
const results = [];
|
|
15
|
+
if (typeof options?.min === "number" && size < options.min) {
|
|
16
|
+
results.push({ message: `The value must not be shorter than ${options.min}` });
|
|
17
|
+
}
|
|
18
|
+
if (typeof options?.max === "number" && size > options.max) {
|
|
19
|
+
results.push({ message: `The value must not be longer than ${options.max}` });
|
|
20
|
+
}
|
|
21
|
+
return results;
|
|
22
|
+
};
|
|
23
|
+
export {
|
|
24
|
+
length
|
|
35
25
|
};
|
package/dist/functions/or.js
CHANGED
|
@@ -1,25 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
if (properties.length > 4) {
|
|
20
|
-
const shortProps = properties.slice(0, 3);
|
|
21
|
-
const count = `${properties.length - 3} other properties must be defined`;
|
|
22
|
-
return [{ message: `At least one of "${shortProps.join('" or "')}" or ${count}` }];
|
|
23
|
-
}
|
|
24
|
-
return [{ message: `At least one of "${properties.join('" or "')}" must be defined` }];
|
|
1
|
+
const or = (input, options) => {
|
|
2
|
+
if (typeof input !== "object" || input === null)
|
|
3
|
+
return [];
|
|
4
|
+
const properties = options?.properties;
|
|
5
|
+
if (!Array.isArray(properties) || properties.length < 2)
|
|
6
|
+
return [];
|
|
7
|
+
const present = properties.filter((property) => property in input);
|
|
8
|
+
if (present.length > 0)
|
|
9
|
+
return [];
|
|
10
|
+
if (properties.length > 4) {
|
|
11
|
+
const shortProps = properties.slice(0, 3);
|
|
12
|
+
const count = `${properties.length - 3} other properties must be defined`;
|
|
13
|
+
return [{ message: `At least one of "${shortProps.join('" or "')}" or ${count}` }];
|
|
14
|
+
}
|
|
15
|
+
return [{ message: `At least one of "${properties.join('" or "')}" must be defined` }];
|
|
16
|
+
};
|
|
17
|
+
export {
|
|
18
|
+
or
|
|
25
19
|
};
|
|
@@ -1,53 +1,43 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
let compiled;
|
|
19
|
-
try {
|
|
20
|
-
const match = /^\/(.+)\/([a-z]*)$/s.exec(pattern);
|
|
21
|
-
compiled = match ? new RegExp(match[1], match[2]) : new RegExp(pattern);
|
|
22
|
-
}
|
|
23
|
-
catch (error) {
|
|
24
|
-
compiled = error instanceof Error ? error : new Error(String(error));
|
|
25
|
-
}
|
|
26
|
-
cache.set(pattern, compiled);
|
|
27
|
-
return compiled;
|
|
1
|
+
const cache = /* @__PURE__ */ new Map();
|
|
2
|
+
const toRegExp = (pattern2) => {
|
|
3
|
+
const cached = cache.get(pattern2);
|
|
4
|
+
if (cached !== void 0) {
|
|
5
|
+
if (cached instanceof RegExp)
|
|
6
|
+
cached.lastIndex = 0;
|
|
7
|
+
return cached;
|
|
8
|
+
}
|
|
9
|
+
let compiled;
|
|
10
|
+
try {
|
|
11
|
+
const match = /^\/(.+)\/([a-z]*)$/s.exec(pattern2);
|
|
12
|
+
compiled = match ? new RegExp(match[1], match[2]) : new RegExp(pattern2);
|
|
13
|
+
} catch (error) {
|
|
14
|
+
compiled = error instanceof Error ? error : new Error(String(error));
|
|
15
|
+
}
|
|
16
|
+
cache.set(pattern2, compiled);
|
|
17
|
+
return compiled;
|
|
28
18
|
};
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
else if (!re.test(input)) {
|
|
40
|
-
results.push({ message: `The value must match the pattern "${options.match}"` });
|
|
41
|
-
}
|
|
19
|
+
const pattern = (input, options) => {
|
|
20
|
+
if (typeof input !== "string")
|
|
21
|
+
return [];
|
|
22
|
+
const results = [];
|
|
23
|
+
if (options?.match !== void 0) {
|
|
24
|
+
const re = toRegExp(options.match);
|
|
25
|
+
if (re instanceof Error) {
|
|
26
|
+
results.push({ message: `The "match" option is not a valid regular expression: ${re.message}` });
|
|
27
|
+
} else if (!re.test(input)) {
|
|
28
|
+
results.push({ message: `The value must match the pattern "${options.match}"` });
|
|
42
29
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
30
|
+
}
|
|
31
|
+
if (options?.notMatch !== void 0) {
|
|
32
|
+
const re = toRegExp(options.notMatch);
|
|
33
|
+
if (re instanceof Error) {
|
|
34
|
+
results.push({ message: `The "notMatch" option is not a valid regular expression: ${re.message}` });
|
|
35
|
+
} else if (re.test(input)) {
|
|
36
|
+
results.push({ message: `The value must not match the pattern "${options.notMatch}"` });
|
|
51
37
|
}
|
|
52
|
-
|
|
38
|
+
}
|
|
39
|
+
return results;
|
|
40
|
+
};
|
|
41
|
+
export {
|
|
42
|
+
pattern
|
|
53
43
|
};
|
package/dist/functions/schema.js
CHANGED
|
@@ -1,129 +1,103 @@
|
|
|
1
|
-
import { validate as buildValidator } from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
// `validateFormats: true`); keep that by opting into all formats here.
|
|
11
|
-
validator = buildValidator(schema, { formats: 'all' });
|
|
12
|
-
validators.set(schema, validator);
|
|
13
|
-
}
|
|
14
|
-
return validator;
|
|
1
|
+
import { validate as buildValidator } from "@amritk/runtime-validators";
|
|
2
|
+
const validators = /* @__PURE__ */ new WeakMap();
|
|
3
|
+
const getValidator = (schema2) => {
|
|
4
|
+
let validator = validators.get(schema2);
|
|
5
|
+
if (!validator) {
|
|
6
|
+
validator = buildValidator(schema2, { formats: "all" });
|
|
7
|
+
validators.set(schema2, validator);
|
|
8
|
+
}
|
|
9
|
+
return validator;
|
|
15
10
|
};
|
|
16
|
-
const KNOWN_TYPES = new Set([
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const SCHEMA_LIST_KEYS = ['allOf', 'anyOf', 'oneOf'];
|
|
22
|
-
const SCHEMA_MAP_KEYS = ['properties', 'patternProperties', 'definitions', '$defs', 'dependencies'];
|
|
23
|
-
/**
|
|
24
|
-
* Walks a schema looking for a `type` keyword whose value is not a JSON Schema
|
|
25
|
-
* type. `@amritk/runtime-validators` treats an unknown `type` as "always
|
|
26
|
-
* matches" (so it never rejects data it does not model), which means a typo like
|
|
27
|
-
* `type: "Pascal"` would silently disable the rule. Finding it up front lets us
|
|
28
|
-
* report it instead. Returns the offending type, or `undefined` when the schema
|
|
29
|
-
* only uses known types.
|
|
30
|
-
*/
|
|
11
|
+
const KNOWN_TYPES = /* @__PURE__ */ new Set(["string", "number", "integer", "boolean", "null", "object", "array"]);
|
|
12
|
+
const SCHEMA_VALUE_KEYS = ["additionalProperties", "not", "if", "then", "else", "propertyNames", "contains"];
|
|
13
|
+
const SCHEMA_ITEMS_KEYS = ["items", "additionalItems"];
|
|
14
|
+
const SCHEMA_LIST_KEYS = ["allOf", "anyOf", "oneOf"];
|
|
15
|
+
const SCHEMA_MAP_KEYS = ["properties", "patternProperties", "definitions", "$defs", "dependencies"];
|
|
31
16
|
const findInvalidType = (node) => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
for (const key of SCHEMA_VALUE_KEYS) {
|
|
45
|
-
const found = findInvalidType(schema[key]);
|
|
46
|
-
if (found !== undefined)
|
|
47
|
-
return found;
|
|
17
|
+
if (Array.isArray(node) || typeof node !== "object" || node === null)
|
|
18
|
+
return void 0;
|
|
19
|
+
const schema2 = node;
|
|
20
|
+
const declared = schema2["type"];
|
|
21
|
+
if (declared !== void 0) {
|
|
22
|
+
const types = Array.isArray(declared) ? declared : [declared];
|
|
23
|
+
for (const type of types) {
|
|
24
|
+
if (typeof type !== "string" || !KNOWN_TYPES.has(type)) {
|
|
25
|
+
return typeof type === "string" ? type : String(type);
|
|
26
|
+
}
|
|
48
27
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
28
|
+
}
|
|
29
|
+
for (const key of SCHEMA_VALUE_KEYS) {
|
|
30
|
+
const found = findInvalidType(schema2[key]);
|
|
31
|
+
if (found !== void 0)
|
|
32
|
+
return found;
|
|
33
|
+
}
|
|
34
|
+
for (const key of SCHEMA_ITEMS_KEYS) {
|
|
35
|
+
const value = schema2[key];
|
|
36
|
+
const list = Array.isArray(value) ? value : [value];
|
|
37
|
+
for (const item of list) {
|
|
38
|
+
const found = findInvalidType(item);
|
|
39
|
+
if (found !== void 0)
|
|
40
|
+
return found;
|
|
57
41
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
42
|
+
}
|
|
43
|
+
for (const key of SCHEMA_LIST_KEYS) {
|
|
44
|
+
const value = schema2[key];
|
|
45
|
+
if (Array.isArray(value)) {
|
|
46
|
+
for (const item of value) {
|
|
47
|
+
const found = findInvalidType(item);
|
|
48
|
+
if (found !== void 0)
|
|
49
|
+
return found;
|
|
50
|
+
}
|
|
67
51
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
52
|
+
}
|
|
53
|
+
for (const key of SCHEMA_MAP_KEYS) {
|
|
54
|
+
const value = schema2[key];
|
|
55
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
56
|
+
for (const item of Object.values(value)) {
|
|
57
|
+
const found = findInvalidType(item);
|
|
58
|
+
if (found !== void 0)
|
|
59
|
+
return found;
|
|
60
|
+
}
|
|
77
61
|
}
|
|
78
|
-
|
|
62
|
+
}
|
|
63
|
+
return void 0;
|
|
79
64
|
};
|
|
80
|
-
const pointerToPath = (pointer) => pointer
|
|
81
|
-
.split('/')
|
|
82
|
-
.slice(1)
|
|
83
|
-
.map((segment) => segment.replace(/~1/g, '/').replace(/~0/g, '~'))
|
|
84
|
-
.map((segment) => (/^\d+$/.test(segment) ? Number(segment) : segment));
|
|
65
|
+
const pointerToPath = (pointer) => pointer.split("/").slice(1).map((segment) => segment.replace(/~1/g, "/").replace(/~0/g, "~")).map((segment) => /^\d+$/.test(segment) ? Number(segment) : segment);
|
|
85
66
|
const formatError = (error) => {
|
|
86
|
-
|
|
87
|
-
|
|
67
|
+
const location = error.path || "value";
|
|
68
|
+
return `${location} ${error.message}`.trim();
|
|
88
69
|
};
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
// failure. Honor the same default and only expand to the full list when the
|
|
123
|
-
// caller opts in.
|
|
124
|
-
const errors = options.allErrors ? result.errors : result.errors.slice(0, 1);
|
|
125
|
-
return errors.map((error) => ({
|
|
126
|
-
message: formatError(error),
|
|
127
|
-
path: [...context.path, ...pointerToPath(error.path)],
|
|
128
|
-
}));
|
|
70
|
+
const schema = (input, options, context) => {
|
|
71
|
+
if (!options?.schema)
|
|
72
|
+
return [];
|
|
73
|
+
const invalidType = findInvalidType(options.schema);
|
|
74
|
+
if (invalidType !== void 0) {
|
|
75
|
+
return [
|
|
76
|
+
{
|
|
77
|
+
message: `Invalid schema: unknown type "${invalidType}". Valid types are: ${[...KNOWN_TYPES].join(", ")}`,
|
|
78
|
+
path: [...context.path]
|
|
79
|
+
}
|
|
80
|
+
];
|
|
81
|
+
}
|
|
82
|
+
let result;
|
|
83
|
+
try {
|
|
84
|
+
result = getValidator(options.schema)(input);
|
|
85
|
+
} catch (error) {
|
|
86
|
+
return [
|
|
87
|
+
{
|
|
88
|
+
message: `Invalid schema: ${error instanceof Error ? error.message : String(error)}`,
|
|
89
|
+
path: [...context.path]
|
|
90
|
+
}
|
|
91
|
+
];
|
|
92
|
+
}
|
|
93
|
+
if (result === true)
|
|
94
|
+
return [];
|
|
95
|
+
const errors = options.allErrors ? result.errors : result.errors.slice(0, 1);
|
|
96
|
+
return errors.map((error) => ({
|
|
97
|
+
message: formatError(error),
|
|
98
|
+
path: [...context.path, ...pointerToPath(error.path)]
|
|
99
|
+
}));
|
|
100
|
+
};
|
|
101
|
+
export {
|
|
102
|
+
schema
|
|
129
103
|
};
|
package/dist/functions/truthy.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
const truthy = (input) => {
|
|
2
|
+
if (!input)
|
|
3
|
+
return [{ message: "The value must be truthy" }];
|
|
4
|
+
return [];
|
|
5
|
+
};
|
|
6
|
+
export {
|
|
7
|
+
truthy
|
|
6
8
|
};
|