mirror of
https://github.com/renovatebot/renovate.git
synced 2025-05-15 00:42:26 +00:00
![renovate[bot]](/assets/img/avatar_default.png)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
72 lines
1.7 KiB
TypeScript
72 lines
1.7 KiB
TypeScript
import is from '@sindresorhus/is';
|
|
import { parse } from './parser';
|
|
import type { Fragment, FragmentPath, FragmentUpdater } from './types';
|
|
|
|
export function findCodeFragment(
|
|
input: string,
|
|
path: FragmentPath,
|
|
): Fragment | null {
|
|
const parsed = parse(input);
|
|
if (!parsed) {
|
|
return null;
|
|
}
|
|
|
|
const [ruleIndex, ...restPath] = path;
|
|
let fragment: Fragment | undefined = parsed[ruleIndex];
|
|
for (const key of restPath) {
|
|
if (!fragment) {
|
|
break;
|
|
}
|
|
|
|
if (fragment.type === 'array' && is.number(key)) {
|
|
fragment = fragment.children[key];
|
|
}
|
|
|
|
if (fragment.type === 'record' && is.string(key)) {
|
|
fragment = fragment.children[key];
|
|
}
|
|
}
|
|
|
|
return fragment ?? null;
|
|
}
|
|
|
|
export function patchCodeAtFragment(
|
|
input: string,
|
|
fragment: Fragment,
|
|
updater: FragmentUpdater,
|
|
): string {
|
|
const { value, offset } = fragment;
|
|
const left = input.slice(0, offset);
|
|
const right = input.slice(offset + value.length);
|
|
return is.string(updater)
|
|
? `${left}${updater}${right}`
|
|
: `${left}${updater(value)}${right}`;
|
|
}
|
|
|
|
export function patchCodeAtFragments(
|
|
input: string,
|
|
fragments: Fragment[],
|
|
updater: FragmentUpdater,
|
|
): string {
|
|
const sortedFragments = fragments.sort(
|
|
({ offset: a }, { offset: b }) => b - a,
|
|
);
|
|
let result = input;
|
|
for (const fragment of sortedFragments) {
|
|
result = patchCodeAtFragment(result, fragment, updater);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
export function updateCode(
|
|
input: string,
|
|
path: FragmentPath,
|
|
updater: FragmentUpdater,
|
|
): string {
|
|
const fragment = findCodeFragment(input, path);
|
|
if (!fragment) {
|
|
return input;
|
|
}
|
|
|
|
return patchCodeAtFragment(input, fragment, updater);
|
|
}
|