Skip to content

Instantly share code, notes, and snippets.

@undefined06855
Created August 19, 2025 15:24
Show Gist options
  • Select an option

  • Save undefined06855/b45bfaa394477973f93045a69fd28f6e to your computer and use it in GitHub Desktop.

Select an option

Save undefined06855/b45bfaa394477973f93045a69fd28f6e to your computer and use it in GitHub Desktop.
An object validation library to validate client sent data etc in node/bun
/**
* Helper function to extract the type of typeof
* @param {any} x
*/
function _typeof(x) {
return typeof x;
}
/**
* @typedef {ReturnType<typeof _typeof>} TypeofResult
* recursive typing doesnt actually work here for me which is sad
* when it does start working replace the second record with FormatObject
* @typedef {Record<string, TypeofResult | Record<string, TypeofResult>>} FormatObject
*/
const Format = {
/**
* Verify the format of an object, ignoring order of keys and any extra keys.
* @param {FormatObject} syntax The format that the object should be in. Each key, value pair is the name of the key and the type it should be. Can contain nested objects.
* @param {Object<string, any>} object The object to verify the format of.
* @returns {boolean}
*/
verify: (syntax, object) => {
for (let [key, type] of Object.entries(syntax)) {
if (!key in object) {
return false;
}
if (typeof type === "object") {
if (!Format.verify(type, object[key])) {
return false;
}
}
if (typeof object[key] !== type) {
return false;
}
}
return true;
},
/**
* Verify the format of an object, including order of keys and rejecting any extra keys.
* @param {FormatObject} syntax The format that the object should be in. Each key, value pair is the name of the key and the type it should be. Can contain nested objects.
* @param {Object<string, any>} object The object to verify the format of.
* @returns
*/
verifyExact: (syntax, object) => {
let syntaxKeys = Object.keys(syntax);
let objectKeys = Object.keys(syntax);
if (syntaxKeys.length != objectKeys.length) {
return false;
}
for (let i = 0; i < syntaxKeys.length; i++) {
let syntaxKey = syntaxKeys[i];
let objectKey = objectKeys[i];
if (syntaxKey != objectKey) {
return false;
}
let syntax = syntax[syntaxKey];
let value = object[objectKey];
if (typeof syntax === "object") {
if (!Format.verifyExact(syntax, value)) {
return false;
}
}
if (typeof value !== syntax) {
return false;
}
}
return true;
}
};
export default Format;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment