90 lines
2.5 KiB
TypeScript
90 lines
2.5 KiB
TypeScript
/**
|
|
* JSON Parsing Utilities
|
|
*
|
|
* Shared utilities for safely parsing JSON values that may be strings or already parsed.
|
|
*/
|
|
|
|
/**
|
|
* Parses a value that might be a JSON string or already an object.
|
|
* Returns a typed object with fallback support.
|
|
*
|
|
* @param value - The value to parse (string, object, or undefined)
|
|
* @param fallback - Fallback value if parsing fails (defaults to empty object)
|
|
* @returns The parsed object or fallback
|
|
*
|
|
* @example
|
|
* const schema = parseJsonObject<ConstructorSchema>(page.ui_schema_json, {});
|
|
* const settings = parseJsonObject<Settings>(settingsValue, { enabled: false });
|
|
*/
|
|
export const parseJsonObject = <T>(value?: unknown, fallback?: T): T => {
|
|
if (!value) return (fallback || ({} as T)) as T;
|
|
|
|
try {
|
|
if (typeof value === 'string') {
|
|
const parsed = JSON.parse(value);
|
|
return (parsed || fallback || {}) as T;
|
|
}
|
|
|
|
if (typeof value === 'object') {
|
|
return value as T;
|
|
}
|
|
|
|
return (fallback || ({} as T)) as T;
|
|
} catch {
|
|
return (fallback || ({} as T)) as T;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Parses a JSON field that might be a string, object, or null.
|
|
* More lenient than parseJsonObject - returns the original value on parse error.
|
|
*
|
|
* @param value - The value to parse
|
|
* @returns The parsed value, original value, or null
|
|
*
|
|
* @example
|
|
* const content = parseJsonField(element.content_json);
|
|
* const style = parseJsonField(element.style_json);
|
|
*/
|
|
export const parseJsonField = (value: unknown): unknown => {
|
|
if (value === null || value === undefined) return null;
|
|
if (typeof value !== 'string') return value;
|
|
if (!value.trim()) return null;
|
|
|
|
try {
|
|
return JSON.parse(value);
|
|
} catch {
|
|
return value;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Extracts preview text from parsed content by checking common text field names.
|
|
*
|
|
* @param content - Parsed content object
|
|
* @returns The first text value found, or null
|
|
*
|
|
* @example
|
|
* const previewText = getElementPreviewText(parseJsonField(element.content_json));
|
|
*/
|
|
export const getElementPreviewText = (content: unknown): string | null => {
|
|
if (typeof content === 'string') return content;
|
|
if (!content || typeof content !== 'object') return null;
|
|
|
|
const candidateKeys = [
|
|
'title',
|
|
'text',
|
|
'subtitle',
|
|
'description',
|
|
'body',
|
|
'label',
|
|
'value',
|
|
];
|
|
const contentRecord = content as Record<string, unknown>;
|
|
const firstTextKey = candidateKeys.find(
|
|
(key) => typeof contentRecord[key] === 'string',
|
|
);
|
|
|
|
return firstTextKey ? String(contentRecord[firstTextKey]) : null;
|
|
};
|