mirror of
https://github.com/github/codeql-action.git
synced 2026-08-05 04:57:19 -05:00
Validate numbers, objects, and undefinables in the json module
This commit adds a `number` validator`, an `object` validator, an `isNumber` predicate, and `undefinable()` to test optional-but-not-null properties.
This commit is contained in:
@@ -44,3 +44,26 @@ test("validateSchema - optional properties are optional", async (t) => {
|
|||||||
t.true(json.validateSchema(optionalSchema, { optionalKey: "" }));
|
t.true(json.validateSchema(optionalSchema, { optionalKey: "" }));
|
||||||
t.true(json.validateSchema(optionalSchema, { optionalKey: "foo" }));
|
t.true(json.validateSchema(optionalSchema, { optionalKey: "foo" }));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const undefinableSchema = {
|
||||||
|
optionalKey: json.undefinable(json.string),
|
||||||
|
};
|
||||||
|
|
||||||
|
test("validateSchema - undefinable properties are optional but reject null", async (t) => {
|
||||||
|
// Optional fields may be absent or explicitly undefined
|
||||||
|
t.true(json.validateSchema(undefinableSchema, {}));
|
||||||
|
t.true(json.validateSchema(undefinableSchema, { optionalKey: undefined }));
|
||||||
|
|
||||||
|
// But, unlike `optional`, `null` is rejected
|
||||||
|
t.false(json.validateSchema(undefinableSchema, { optionalKey: null }));
|
||||||
|
|
||||||
|
// And, if present, should have the expected type
|
||||||
|
t.false(json.validateSchema(undefinableSchema, { optionalKey: 0 }));
|
||||||
|
t.false(json.validateSchema(undefinableSchema, { optionalKey: 123 }));
|
||||||
|
t.false(json.validateSchema(undefinableSchema, { optionalKey: false }));
|
||||||
|
t.false(json.validateSchema(undefinableSchema, { optionalKey: true }));
|
||||||
|
t.false(json.validateSchema(undefinableSchema, { optionalKey: [] }));
|
||||||
|
t.false(json.validateSchema(undefinableSchema, { optionalKey: {} }));
|
||||||
|
t.true(json.validateSchema(undefinableSchema, { optionalKey: "" }));
|
||||||
|
t.true(json.validateSchema(undefinableSchema, { optionalKey: "foo" }));
|
||||||
|
});
|
||||||
|
|||||||
+34
-1
@@ -30,6 +30,11 @@ export function isString(value: unknown): value is string {
|
|||||||
return typeof value === "string";
|
return typeof value === "string";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Asserts that `value` is a number. */
|
||||||
|
export function isNumber(value: unknown): value is number {
|
||||||
|
return typeof value === "number";
|
||||||
|
}
|
||||||
|
|
||||||
/** Asserts that `value` is either a string or undefined. */
|
/** Asserts that `value` is either a string or undefined. */
|
||||||
export function isStringOrUndefined(
|
export function isStringOrUndefined(
|
||||||
value: unknown,
|
value: unknown,
|
||||||
@@ -55,7 +60,22 @@ export const string = {
|
|||||||
required: true,
|
required: true,
|
||||||
} as const satisfies Validator<string>;
|
} as const satisfies Validator<string>;
|
||||||
|
|
||||||
/** Transforms a validator to be optional. */
|
/** A validator for number fields in schemas. */
|
||||||
|
export const number = {
|
||||||
|
validate: isNumber,
|
||||||
|
required: true,
|
||||||
|
} as const satisfies Validator<number>;
|
||||||
|
|
||||||
|
/** A validator for object fields in schemas. */
|
||||||
|
export const object = {
|
||||||
|
validate: isObject,
|
||||||
|
required: true,
|
||||||
|
} as const satisfies Validator<UnvalidatedObject<unknown>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms a validator to be optional, accepting `undefined` or `null` for an
|
||||||
|
* absent value.
|
||||||
|
*/
|
||||||
export function optional<T>(validator: Validator<T>) {
|
export function optional<T>(validator: Validator<T>) {
|
||||||
return {
|
return {
|
||||||
validate: (val: unknown) => {
|
validate: (val: unknown) => {
|
||||||
@@ -65,6 +85,19 @@ export function optional<T>(validator: Validator<T>) {
|
|||||||
} as const satisfies Validator<T | undefined | null>;
|
} as const satisfies Validator<T | undefined | null>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms a validator to be optional, accepting `undefined` for an absent
|
||||||
|
* value but, unlike `optional`, rejecting `null`.
|
||||||
|
*/
|
||||||
|
export function undefinable<T>(validator: Validator<T>) {
|
||||||
|
return {
|
||||||
|
validate: (val: unknown): val is T | undefined => {
|
||||||
|
return val === undefined || validator.validate(val);
|
||||||
|
},
|
||||||
|
required: false,
|
||||||
|
} as const satisfies Validator<T | undefined>;
|
||||||
|
}
|
||||||
|
|
||||||
/** Represents an arbitrary object schema. */
|
/** Represents an arbitrary object schema. */
|
||||||
export type Schema = Record<string, Validator<any>>;
|
export type Schema = Record<string, Validator<any>>;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user