json-merge-resolver
Version:
A rules-based JSON conflict resolver that parses Git conflict markers, reconstructs ours/theirs, and merges with deterministic strategies — beyond line-based merges.
66 lines (65 loc) • 2.75 kB
TypeScript
import { createLogger } from "./logger";
import { NormalizedConfig } from "./normalizer";
import { StrategyFn, StrategyResult, StrategyStatus } from "./types";
/** Conflict entry (minimal by default). */
export interface Conflict {
path: string;
reason: string;
ours?: unknown;
theirs?: unknown;
base?: unknown;
}
/** Result of merging a file. */
export interface MergeResult {
filePath: string;
merged: unknown;
conflicts: Conflict[];
}
/** Helper: stringify status for logs. */
export declare const statusToString: (s: StrategyStatus) => string;
/** Merge context (runtime state + config). */
export interface MergeContext<TContext = unknown> {
config: NormalizedConfig;
strategies: Record<string, StrategyFn<TContext>>;
context?: TContext;
_strategyCache?: Map<string, string[]>;
}
/** Internal args passed to strategies. */
interface MergeArgs<TContext> {
ours: unknown;
theirs: unknown;
base?: unknown;
path: string;
filePath?: string;
ctx: MergeContext<TContext>;
conflicts: Conflict[];
logger: Awaited<ReturnType<typeof createLogger>>;
}
/** Built-in strategies. */
export declare const BuiltInStrategies: {
readonly ours: <TContext>({ ours }: MergeArgs<TContext>) => StrategyResult;
readonly theirs: <TContext>({ theirs }: MergeArgs<TContext>) => StrategyResult;
readonly base: <TContext>({ base }: MergeArgs<TContext>) => StrategyResult;
readonly drop: <TContext>(_skipped: MergeArgs<TContext>) => StrategyResult;
readonly skip: <TContext>({ path }: MergeArgs<TContext>) => StrategyResult;
readonly "non-empty": <TContext>({ ours, theirs, base }: MergeArgs<TContext>) => StrategyResult;
readonly update: <TContext>({ ours, theirs }: MergeArgs<TContext>) => StrategyResult;
readonly merge: <TContext>(args: MergeArgs<TContext>) => Promise<StrategyResult>;
readonly concat: <TContext>({ ours, theirs, path }: MergeArgs<TContext>) => StrategyResult;
readonly unique: <TContext>({ ours, theirs, path }: MergeArgs<TContext>) => StrategyResult;
};
/**
* Recursively merges two inputs using configured strategies.
*
* Resolution order:
* 1. If values are strictly equal → return either.
* 2. Resolve strategy list from config (cached per path).
* 3. Apply built-in/custom strategies in order.
* - If a strategy succeeds → return its value immediately.
* - If a strategy fails → continue to next.
* 4. If all strategies fail → log conflict & fallback to ours.
*
* @template TContext Type of optional user context for custom strategies.
*/
export declare const mergeObject: <TContext>({ ours, theirs, base, path, filePath, ctx, conflicts, logger, }: MergeArgs<TContext>) => Promise<unknown>;
export {};