@pho9ubenaa/remark-mask-text-beta
Version:
A remark plugin to mask text content with block characters
117 lines • 4.88 kB
JavaScript
import { transformTreeFunctional } from "./lib/ast-manipulator.js";
import { isParentNode } from "./lib/ast-types.js";
import { ERROR_TYPES, PLUGIN_METADATA } from "./lib/constants.js";
import { isFailure } from "./lib/types/result.js";
import { validateOptions } from "./lib/utils.js";
/**
* Error handler for plugin processing failures
*
* Provides graceful error handling that logs errors but doesn't break
* the remark processing pipeline. This ensures documents are still
* processed even if masking fails.
*
* @param error - The processing error that occurred
* @param context - Additional context about where the error occurred
*/
const handleProcessingError = (error, context) => {
/** In production, we might want to log this differently */
console.warn(`${PLUGIN_METADATA.NAME} ${error.type}: ${error.message}`, {
context,
error,
});
};
/**
* Creates a safe transformer function that handles errors gracefully
*
* This wrapper ensures that processing errors don't crash the entire
* remark pipeline, while still providing useful debugging information.
*
* @param maskChar - Validated mask character
* @param delimiter - Validated delimiter string
* @returns A transformer function that safely processes AST nodes
*/
const createSafeTransformer = (maskChar, delimiter) => {
return (tree) => {
try {
/** Validate tree structure before processing */
if (!isParentNode(tree)) {
handleProcessingError({
type: ERROR_TYPES.INVALID_NODE_STRUCTURE,
message: "Root node is not a valid parent node",
nodeType: tree.type,
}, "Plugin initialization");
return;
}
/** Apply functional transformation to the tree */
const transformResult = transformTreeFunctional(tree, maskChar, delimiter);
if (isFailure(transformResult)) {
handleProcessingError(transformResult.error, "Tree transformation");
return;
}
/** Handle the case where transformation returns multiple nodes */
if (Array.isArray(transformResult.data)) {
/**
* If the root was transformed into multiple nodes, we need to restructure.
* This shouldn't happen for well-formed markdown, but we handle it gracefully
*/
if (transformResult.data.length > 1) {
handleProcessingError({
type: ERROR_TYPES.AST_TRANSFORMATION_ERROR,
message: "Root transformation resulted in multiple nodes",
context: "This indicates an unexpected document structure",
}, "Root node processing");
return;
}
/** Replace tree contents with the single transformed node */
const transformedNode = transformResult.data[0];
if (isParentNode(transformedNode)) {
Object.assign(tree, transformedNode);
}
}
else {
/** Single node transformation - replace tree contents */
if (isParentNode(transformResult.data)) {
Object.assign(tree, transformResult.data);
}
}
}
catch (error) {
/** Catch any unexpected errors to prevent pipeline failures */
handleProcessingError({
type: ERROR_TYPES.AST_TRANSFORMATION_ERROR,
message: "Unexpected error during AST transformation",
context: error instanceof Error ? error.message : "Unknown error",
}, "Error boundary");
}
};
};
/**
* Add support for masking text content.
*
* This plugin provides strict type checking when used in arrays,
* ensuring that only valid options are accepted.
*
* @this
* Unified processor.
* @param
* Configuration (optional).
* @returns
* Nothing.
*/
const remarkMaskText = (options) => {
/** Validate and normalize options upfront */
const optionsResult = validateOptions(options || {});
if (isFailure(optionsResult)) {
/** If options are invalid, return a no-op transformer with error logging */
handleProcessingError(optionsResult.error, "Plugin configuration");
return () => {
/** No-op transformer that doesn't modify the tree */
console.warn(`${PLUGIN_METADATA.NAME} Plugin disabled due to configuration errors`);
};
}
const { maskCharacter, maskDelimiter } = optionsResult.data;
/** Return the safe transformer function */
return createSafeTransformer(maskCharacter, maskDelimiter);
};
export default remarkMaskText;
//# sourceMappingURL=index.js.map