data-to-jsonschema-to-ts
Version:
Convert plain javascript objects to JSON Schema and TypeScript typings
88 lines • 2.79 kB
JavaScript
/**
* Walk an object or array, invoking the callback for each **primitive leaf**
* (`string`, `number`, `boolean`, `null`, `undefined`).
*
* The callback receives:
* - `value` — the primitive
* - `jsonPath` — dot/bracket notation path (e.g. `"profile.name"`, `"tags[0]"`)
* - `meta` — `{ key, parent? }` where `parent` describes the containing object/array
*
* Useful for redaction, indexing, or path-based diffing of plain JSON-like objects.
*
* @param obj - The object or array to traverse.
* @param handlePrimitive - Called once per primitive leaf.
* @param currentPath - Used internally for recursion. Don't pass.
*/
export function traverseObject(obj, handlePrimitive, currentPath = "") {
// Handle null separately since typeof null === 'object'
if (obj === null) {
handlePrimitive(obj, currentPath, {
key: "",
parent: {
path: currentPath,
type: "object",
},
});
return;
}
// Handle arrays
if (Array.isArray(obj)) {
obj.forEach((item, index) => {
const newPath = currentPath ? `${currentPath}[${index}]` : `[${index}]`;
if (isPrimitive(item)) {
handlePrimitive(item, newPath, {
key: index,
parent: {
path: currentPath,
type: "array",
},
});
}
else {
traverseObject(item, handlePrimitive, newPath);
}
});
return;
}
// Handle objects
if (typeof obj === "object") {
Object.entries(obj).forEach(([key, value]) => {
const newPath = currentPath ? `${currentPath}.${key}` : key;
if (isPrimitive(value)) {
handlePrimitive(value, newPath, {
key,
parent: {
path: currentPath,
type: "object",
},
});
}
else {
traverseObject(value, handlePrimitive, newPath);
}
});
return;
}
// Handle primitive values at root level
if (currentPath) {
handlePrimitive(obj, currentPath, {
key: "",
parent: {
path: currentPath,
type: Array.isArray(obj) ? "array" : "object",
},
});
}
return;
}
/**
* Type guard to check if a value is a primitive
*/
function isPrimitive(value) {
return (value === null ||
value === undefined ||
typeof value === "string" ||
typeof value === "number" ||
typeof value === "boolean");
}
//# sourceMappingURL=index.js.map