This repository has been archived on 2026-09-03. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
open-brainy/src/utils/fieldNameTracking.ts
David Snelling f8c45f2d8d Initial commit: Brainy - Multi-Dimensional AI Database
Open source vector database with HNSW indexing, graph relationships,
and metadata facets. Features CLI with professional augmentation registry
integration for discovering extensions and capabilities.
2025-08-18 17:35:06 -07:00

114 lines
3.3 KiB
TypeScript

/**
* Utility functions for tracking and managing field names in JSON documents
*/
/**
* Extracts field names from a JSON document
* @param jsonObject The JSON object to extract field names from
* @param options Configuration options
* @returns An array of field paths (e.g., "user.name", "addresses[0].city")
*/
export function extractFieldNamesFromJson(
jsonObject: any,
options: {
maxDepth?: number
currentDepth?: number
currentPath?: string
fieldNames?: Set<string>
} = {}
): string[] {
const {
maxDepth = 5,
currentDepth = 0,
currentPath = '',
fieldNames = new Set<string>()
} = options
if (
jsonObject === null ||
jsonObject === undefined ||
typeof jsonObject !== 'object' ||
currentDepth >= maxDepth
) {
return Array.from(fieldNames)
}
if (Array.isArray(jsonObject)) {
// For arrays, we'll just check the first item to avoid explosion of paths
if (jsonObject.length > 0) {
const arrayPath = currentPath ? `${currentPath}[0]` : '[0]'
extractFieldNamesFromJson(jsonObject[0], {
maxDepth,
currentDepth: currentDepth + 1,
currentPath: arrayPath,
fieldNames
})
}
} else {
// For objects, process each property
for (const key of Object.keys(jsonObject)) {
const value = jsonObject[key]
const fieldPath = currentPath ? `${currentPath}.${key}` : key
// Add this field path
fieldNames.add(fieldPath)
// Recursively process nested objects
if (typeof value === 'object' && value !== null) {
extractFieldNamesFromJson(value, {
maxDepth,
currentDepth: currentDepth + 1,
currentPath: fieldPath,
fieldNames
})
}
}
}
return Array.from(fieldNames)
}
/**
* Maps field names to standard field names based on common patterns
* @param fieldName The field name to map
* @returns The standard field name if a match is found, or null if no match
*/
export function mapToStandardField(fieldName: string): string | null {
// Standard field mappings
const standardMappings: Record<string, string[]> = {
'title': ['title', 'name', 'headline', 'subject'],
'description': ['description', 'summary', 'content', 'text', 'body'],
'author': ['author', 'creator', 'user', 'owner', 'by'],
'date': ['date', 'created', 'createdAt', 'timestamp', 'published'],
'url': ['url', 'link', 'href', 'source'],
'image': ['image', 'thumbnail', 'photo', 'picture'],
'tags': ['tags', 'categories', 'keywords', 'topics']
}
// Check for matches
for (const [standardField, possibleMatches] of Object.entries(standardMappings)) {
// Exact match
if (possibleMatches.includes(fieldName)) {
return standardField
}
// Path match (e.g., "user.name" matches "name")
const parts = fieldName.split('.')
const lastPart = parts[parts.length - 1]
if (possibleMatches.includes(lastPart)) {
return standardField
}
// Array match (e.g., "items[0].name" matches "name")
if (fieldName.includes('[')) {
for (const part of parts) {
const cleanPart = part.split('[')[0]
if (possibleMatches.includes(cleanPart)) {
return standardField
}
}
}
}
return null
}