@dollhousemcp/mcp-server
Version:
DollhouseMCP - A Model Context Protocol (MCP) server that enables dynamic AI persona management from markdown files, allowing Claude and other compatible AI assistants to activate and switch between different behavioral personas.
144 lines • 14.3 kB
JavaScript
/**
* Utility functions for element ID parsing and formatting
*
* FIXES IMPLEMENTED (Issue #1099):
* - Centralized element ID parsing logic
* - Consistent separator usage (':')
* - Validation and error handling
* - Type-safe interfaces
*/
export const ELEMENT_ID_SEPARATOR = ':';
/**
* Parse an element ID into its type and name components
*
* @param id Element ID in format "type:name"
* @returns Parsed element ID or null if invalid
*/
export function parseElementId(id) {
if (!id || typeof id !== 'string') {
return null;
}
const parts = id.split(ELEMENT_ID_SEPARATOR);
if (parts.length !== 2 || !parts[0] || !parts[1]) {
return null;
}
return {
type: parts[0],
name: parts[1]
};
}
/**
* Parse an element ID, throwing an error if invalid
*
* @param id Element ID in format "type:name"
* @returns Parsed element ID
* @throws Error if ID is invalid
*/
export function parseElementIdStrict(id) {
const parsed = parseElementId(id);
if (!parsed) {
throw new Error(`Invalid element ID format: "${id}". Expected "type:name"`);
}
return parsed;
}
/**
* Parse an element ID with fallback values for invalid IDs
*
* @param id Element ID to parse
* @param defaultType Default type if parsing fails
* @param defaultName Default name if parsing fails (defaults to the original ID)
* @returns Parsed element ID with fallbacks
*/
export function parseElementIdWithFallback(id, defaultType = 'unknown', defaultName) {
const parsed = parseElementId(id);
if (parsed) {
return parsed;
}
return {
type: defaultType,
name: defaultName ?? id
};
}
/**
* Format an element ID from type and name components
*
* @param type Element type
* @param name Element name
* @returns Formatted element ID
*/
export function formatElementId(type, name) {
if (!type || !name) {
throw new Error('Both type and name are required to format element ID');
}
// Check for separator in type or name
if (type.includes(ELEMENT_ID_SEPARATOR)) {
throw new Error(`Element type cannot contain separator "${ELEMENT_ID_SEPARATOR}": ${type}`);
}
if (name.includes(ELEMENT_ID_SEPARATOR)) {
throw new Error(`Element name cannot contain separator "${ELEMENT_ID_SEPARATOR}": ${name}`);
}
return `${type}${ELEMENT_ID_SEPARATOR}${name}`;
}
/**
* Validate an element ID format
*
* @param id Element ID to validate
* @returns true if valid, false otherwise
*/
export function isValidElementId(id) {
return parseElementId(id) !== null;
}
/**
* Extract element IDs from an array of strings, filtering out invalid ones
*
* @param ids Array of potential element IDs
* @returns Array of valid parsed element IDs
*/
export function parseElementIds(ids) {
return ids
.map(id => parseElementId(id))
.filter((parsed) => parsed !== null);
}
/**
* Batch parse element IDs with detailed error reporting
*
* @param ids Array of element IDs to parse
* @returns Object with valid parsed IDs and errors for invalid ones
*/
export function batchParseElementIds(ids) {
const valid = [];
const invalid = [];
for (const id of ids) {
const parsed = parseElementId(id);
if (parsed) {
valid.push({ ...parsed, originalId: id });
}
else {
let reason = 'Invalid format';
if (!id) {
reason = 'Empty ID';
}
else if (typeof id !== 'string') {
reason = 'Not a string';
}
else if (!id.includes(ELEMENT_ID_SEPARATOR)) {
reason = `Missing separator "${ELEMENT_ID_SEPARATOR}"`;
}
else {
const parts = id.split(ELEMENT_ID_SEPARATOR);
if (parts.length > 2) {
reason = 'Multiple separators found';
}
else if (!parts[0]) {
reason = 'Missing type';
}
else if (!parts[1]) {
reason = 'Missing name';
}
}
invalid.push({ id, reason });
}
}
return { valid, invalid };
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxlbWVudElkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL2VsZW1lbnRJZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7R0FRRztBQUVILE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHLEdBQUcsQ0FBQztBQU94Qzs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxjQUFjLENBQUMsRUFBVTtJQUN2QyxJQUFJLENBQUMsRUFBRSxJQUFJLE9BQU8sRUFBRSxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQ2xDLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUM3QyxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDakQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsT0FBTztRQUNMLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ2QsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7S0FDZixDQUFDO0FBQ0osQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxvQkFBb0IsQ0FBQyxFQUFVO0lBQzdDLE1BQU0sTUFBTSxHQUFHLGNBQWMsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNsQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDWixNQUFNLElBQUksS0FBSyxDQUFDLCtCQUErQixFQUFFLHlCQUF5QixDQUFDLENBQUM7SUFDOUUsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxVQUFVLDBCQUEwQixDQUN4QyxFQUFVLEVBQ1YsY0FBc0IsU0FBUyxFQUMvQixXQUFvQjtJ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Y0FBYyxDQUFDO2dCQUMxQixDQUFDO3FCQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztvQkFDckIsTUFBTSxHQUFHLGNBQWMsQ0FBQztnQkFDMUIsQ0FBQztZQUNILENBQUM7WUFDRCxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDL0IsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxDQUFDO0FBQzVCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFV0aWxpdHkgZnVuY3Rpb25zIGZvciBlbGVtZW50IElEIHBhcnNpbmcgYW5kIGZvcm1hdHRpbmdcbiAqXG4gKiBGSVhFUyBJTVBMRU1FTlRFRCAoSXNzdWUgIzEwOTkpOlxuICogLSBDZW50cmFsaXplZCBlbGVtZW50IElEIHBhcnNpbmcgbG9naWNcbiAqIC0gQ29uc2lzdGVudCBzZXBhcmF0b3IgdXNhZ2UgKCc6JylcbiAqIC0gVmFsaWRhdGlvbiBhbmQgZXJyb3IgaGFuZGxpbmdcbiAqIC0gVHlwZS1zYWZlIGludGVyZmFjZXNcbiAqL1xuXG5leHBvcnQgY29uc3QgRUxFTUVOVF9JRF9TRVBBUkFUT1IgPSAnOic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGFyc2VkRWxlbWVudElkIHtcbiAgdHlwZTogc3RyaW5nO1xuICBuYW1lOiBzdHJpbmc7XG59XG5cbi8qKlxuICogUGFyc2UgYW4gZWxlbWVudCBJRCBpbnRvIGl0cyB0eXBlIGFuZCBuYW1lIGNvbXBvbmVudHNcbiAqXG4gKiBAcGFyYW0gaWQgRWxlbWVudCBJRCBpbiBmb3JtYXQgXCJ0eXBlOm5hbWVcIlxuICogQHJldHVybnMgUGFyc2VkIGVsZW1lbnQgSUQgb3IgbnVsbCBpZiBpbnZhbGlkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUVsZW1lbnRJZChpZDogc3RyaW5nKTogUGFyc2VkRWxlbWVudElkIHwgbnVsbCB7XG4gIGlmICghaWQgfHwgdHlwZW9mIGlkICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgcGFydHMgPSBpZC5zcGxpdChFTEVNRU5UX0lEX1NFUEFSQVRPUik7XG4gIGlmIChwYXJ0cy5sZW5ndGggIT09IDIgfHwgIXBhcnRzWzBdIHx8ICFwYXJ0c1sxXSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBwYXJ0c1swXSxcbiAgICBuYW1lOiBwYXJ0c1sxXVxuICB9O1xufVxuXG4vKipcbiAqIFBhcnNlIGFuIGVsZW1lbnQgSUQsIHRocm93aW5nIGFuIGVycm9yIGlmIGludmFsaWRcbiAqXG4gKiBAcGFyYW0gaWQgRWxlbWVudCBJRCBpbiBmb3JtYXQgXCJ0eXBlOm5hbWVcIlxuICogQHJldHVybnMgUGFyc2VkIGVsZW1lbnQgSURcbiAqIEB0aHJvd3MgRXJyb3IgaWYgSUQgaXMgaW52YWxpZFxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VFbGVtZW50SWRTdHJpY3QoaWQ6IHN0cmluZyk6IFBhcnNlZEVsZW1lbnRJZCB7XG4gIGNvbnN0IHBhcnNlZCA9IHBhcnNlRWxlbWVudElkKGlkKTtcbiAgaWYgKCFwYXJzZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgZWxlbWVudCBJRCBmb3JtYXQ6IFwiJHtpZH1cIi4gRXhwZWN0ZWQgXCJ0eXBlOm5hbWVcImApO1xuICB9XG4gIHJldHVybiBwYXJzZWQ7XG59XG5cbi8qKlxuICogUGFyc2UgYW4gZWxlbWVudCBJRCB3aXRoIGZhbGxiYWNrIHZhbHVlcyBmb3IgaW52YWxpZCBJRHNcbiAqXG4gKiBAcGFyYW0gaWQgRWxlbWVudCBJRCB0byBwYXJzZVxuICogQHBhcmFtIGRlZmF1bHRUeXBlIERlZmF1bHQgdHlwZSBpZiBwYXJzaW5nIGZhaWxzXG4gKiBAcGFyYW0gZGVmYXVsdE5hbWUgRGVmYXVsdCBuYW1lIGlmIHBhcnNpbmcgZmFpbHMgKGRlZmF1bHRzIHRvIHRoZSBvcmlnaW5hbCBJRClcbiAqIEByZXR1cm5zIFBhcnNlZCBlbGVtZW50IElEIHdpdGggZmFsbGJhY2tzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUVsZW1lbnRJZFdpdGhGYWxsYmFjayhcbiAgaWQ6IHN0cmluZyxcbiAgZGVmYXVsdFR5cGU6IHN0cmluZyA9ICd1bmtub3duJyxcbiAgZGVmYXVsdE5hbWU/OiBzdHJpbmdcbik6IFBhcnNlZEVsZW1lbnRJZCB7XG4gIGNvbnN0IHBhcnNlZCA9IHBhcnNlRWxlbWVudElkKGlkKTtcbiAgaWYgKHBhcnNlZCkge1xuICAgIHJldHVybiBwYXJzZWQ7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHR5cGU6IGRlZmF1bHRUeXBlLFxuICAgIG5hbWU6IGRlZmF1bHROYW1lID8/IGlkXG4gIH07XG59XG5cbi8qKlxuICogRm9ybWF0IGFuIGVsZW1lbnQgSUQgZnJvbSB0eXBlIGFuZCBuYW1lIGNvbXBvbmVudHNcbiAqXG4gKiBAcGFyYW0gdHlwZSBFbGVtZW50IHR5cGVcbiAqIEBwYXJhbSBuYW1lIEVsZW1lbnQgbmFtZVxuICogQHJldHVybnMgRm9ybWF0dGVkIGVsZW1lbnQgSURcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdEVsZW1lbnRJZCh0eXBlOiBzdHJpbmcsIG5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIGlmICghdHlwZSB8fCAhbmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQm90aCB0eXBlIGFuZCBuYW1lIGFyZSByZXF1aXJlZCB0byBmb3JtYXQgZWxlbWVudCBJRCcpO1xuICB9XG5cbiAgLy8gQ2hlY2sgZm9yIHNlcGFyYXRvciBpbiB0eXBlIG9yIG5hbWVcbiAgaWYgKHR5cGUuaW5jbHVkZXMoRUxFTUVOVF9JRF9TRVBBUkFUT1IpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBFbGVtZW50IHR5cGUgY2Fubm90IGNvbnRhaW4gc2VwYXJhdG9yIFwiJHtFTEVNRU5UX0lEX1NFUEFSQVRPUn1cIjogJHt0eXBlfWApO1xuICB9XG4gIGlmIChuYW1lLmluY2x1ZGVzKEVMRU1FTlRfSURfU0VQQVJBVE9SKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgRWxlbWVudCBuYW1lIGNhbm5vdCBjb250YWluIHNlcGFyYXRvciBcIiR7RUxFTUVOVF9JRF9TRVBBUkFUT1J9XCI6ICR7bmFtZX1gKTtcbiAgfVxuXG4gIHJldHVybiBgJHt0eXBlfSR7RUxFTUVOVF9JRF9TRVBBUkFUT1J9JHtuYW1lfWA7XG59XG5cbi8qKlxuICogVmFsaWRhdGUgYW4gZWxlbWVudCBJRCBmb3JtYXRcbiAqXG4gKiBAcGFyYW0gaWQgRWxlbWVudCBJRCB0byB2YWxpZGF0ZVxuICogQHJldHVybnMgdHJ1ZSBpZiB2YWxpZCwgZmFsc2Ugb3RoZXJ3aXNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkRWxlbWVudElkKGlkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIHBhcnNlRWxlbWVudElkKGlkKSAhPT0gbnVsbDtcbn1cblxuLyoqXG4gKiBFeHRyYWN0IGVsZW1lbnQgSURzIGZyb20gYW4gYXJyYXkgb2Ygc3RyaW5ncywgZmlsdGVyaW5nIG91dCBpbnZhbGlkIG9uZXNcbiAqXG4gKiBAcGFyYW0gaWRzIEFycmF5IG9mIHBvdGVudGlhbCBlbGVtZW50IElEc1xuICogQHJldHVybnMgQXJyYXkgb2YgdmFsaWQgcGFyc2VkIGVsZW1lbnQgSURzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUVsZW1lbnRJZHMoaWRzOiBzdHJpbmdbXSk6IFBhcnNlZEVsZW1lbnRJZFtdIHtcbiAgcmV0dXJuIGlkc1xuICAgIC5tYXAoaWQgPT4gcGFyc2VFbGVtZW50SWQoaWQpKVxuICAgIC5maWx0ZXIoKHBhcnNlZCk6IHBhcnNlZCBpcyBQYXJzZWRFbGVtZW50SWQgPT4gcGFyc2VkICE9PSBudWxsKTtcbn1cblxuLyoqXG4gKiBCYXRjaCBwYXJzZSBlbGVtZW50IElEcyB3aXRoIGRldGFpbGVkIGVycm9yIHJlcG9ydGluZ1xuICpcbiAqIEBwYXJhbSBpZHMgQXJyYXkgb2YgZWxlbWVudCBJRHMgdG8gcGFyc2VcbiAqIEByZXR1cm5zIE9iamVjdCB3aXRoIHZhbGlkIHBhcnNlZCBJRHMgYW5kIGVycm9ycyBmb3IgaW52YWxpZCBvbmVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiYXRjaFBhcnNlRWxlbWVudElkcyhpZHM6IHN0cmluZ1tdKToge1xuICB2YWxpZDogQXJyYXk8UGFyc2VkRWxlbWVudElkICYgeyBvcmlnaW5hbElkOiBzdHJpbmcgfT47XG4gIGludmFsaWQ6IEFycmF5PHsgaWQ6IHN0cmluZzsgcmVhc29uOiBzdHJpbmcgfT47XG59IHtcbiAgY29uc3QgdmFsaWQ6IEFycmF5PFBhcnNlZEVsZW1lbnRJZCAmIHsgb3JpZ2luYWxJZDogc3RyaW5nIH0+ID0gW107XG4gIGNvbnN0IGludmFsaWQ6IEFycmF5PHsgaWQ6IHN0cmluZzsgcmVhc29uOiBzdHJpbmcgfT4gPSBbXTtcblxuICBmb3IgKGNvbnN0IGlkIG9mIGlkcykge1xuICAgIGNvbnN0IHBhcnNlZCA9IHBhcnNlRWxlbWVudElkKGlkKTtcbiAgICBpZiAocGFyc2VkKSB7XG4gICAgICB2YWxpZC5wdXNoKHsgLi4ucGFyc2VkLCBvcmlnaW5hbElkOiBpZCB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IHJlYXNvbiA9ICdJbnZhbGlkIGZvcm1hdCc7XG4gICAgICBpZiAoIWlkKSB7XG4gICAgICAgIHJlYXNvbiA9ICdFbXB0eSBJRCc7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBpZCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmVhc29uID0gJ05vdCBhIHN0cmluZyc7XG4gICAgICB9IGVsc2UgaWYgKCFpZC5pbmNsdWRlcyhFTEVNRU5UX0lEX1NFUEFSQVRPUikpIHtcbiAgICAgICAgcmVhc29uID0gYE1pc3Npbmcgc2VwYXJhdG9yIFwiJHtFTEVNRU5UX0lEX1NFUEFSQVRPUn1cImA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBwYXJ0cyA9IGlkLnNwbGl0KEVMRU1FTlRfSURfU0VQQVJBVE9SKTtcbiAgICAgICAgaWYgKHBhcnRzLmxlbmd0aCA+IDIpIHtcbiAgICAgICAgICByZWFzb24gPSAnTXVsdGlwbGUgc2VwYXJhdG9ycyBmb3VuZCc7XG4gICAgICAgIH0gZWxzZSBpZiAoIXBhcnRzWzBdKSB7XG4gICAgICAgICAgcmVhc29uID0gJ01pc3NpbmcgdHlwZSc7XG4gICAgICAgIH0gZWxzZSBpZiAoIXBhcnRzWzFdKSB7XG4gICAgICAgICAgcmVhc29uID0gJ01pc3NpbmcgbmFtZSc7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGludmFsaWQucHVzaCh7IGlkLCByZWFzb24gfSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgdmFsaWQsIGludmFsaWQgfTtcbn0iXX0=