Website Structure

This commit is contained in:
supalerk-ar66 2026-01-13 10:46:40 +07:00
parent 62812f2090
commit 71f0676a62
22365 changed files with 4265753 additions and 791 deletions

View file

@ -0,0 +1,62 @@
import type { StructuredPatch } from '../types.js';
export interface ApplyPatchOptions {
/**
* Maximum Levenshtein distance (in lines deleted, added, or subtituted) between the context shown in a patch hunk and the lines found in the file.
* @default 0
*/
fuzzFactor?: number;
/**
* If `true`, and if the file to be patched consistently uses different line endings to the patch (i.e. either the file always uses Unix line endings while the patch uses Windows ones, or vice versa), then `applyPatch` will behave as if the line endings in the patch were the same as those in the source file.
* (If `false`, the patch will usually fail to apply in such circumstances since lines deleted in the patch won't be considered to match those in the source file.)
* @default true
*/
autoConvertLineEndings?: boolean;
/**
* Callback used to compare to given lines to determine if they should be considered equal when patching.
* Defaults to strict equality but may be overridden to provide fuzzier comparison.
* Should return false if the lines should be rejected.
*/
compareLine?: (lineNumber: number, line: string, operation: string, patchContent: string) => boolean;
}
/**
* attempts to apply a unified diff patch.
*
* Hunks are applied first to last.
* `applyPatch` first tries to apply the first hunk at the line number specified in the hunk header, and with all context lines matching exactly.
* If that fails, it tries scanning backwards and forwards, one line at a time, to find a place to apply the hunk where the context lines match exactly.
* If that still fails, and `fuzzFactor` is greater than zero, it increments the maximum number of mismatches (missing, extra, or changed context lines) that there can be between the hunk context and a region where we are trying to apply the patch such that the hunk will still be considered to match.
* Regardless of `fuzzFactor`, lines to be deleted in the hunk *must* be present for a hunk to match, and the context lines *immediately* before and after an insertion must match exactly.
*
* Once a hunk is successfully fitted, the process begins again with the next hunk.
* Regardless of `fuzzFactor`, later hunks must be applied later in the file than earlier hunks.
*
* If a hunk cannot be successfully fitted *anywhere* with fewer than `fuzzFactor` mismatches, `applyPatch` fails and returns `false`.
*
* If a hunk is successfully fitted but not at the line number specified by the hunk header, all subsequent hunks have their target line number adjusted accordingly.
* (e.g. if the first hunk is applied 10 lines below where the hunk header said it should fit, `applyPatch` will *start* looking for somewhere to apply the second hunk 10 lines below where its hunk header says it goes.)
*
* If the patch was applied successfully, returns a string containing the patched text.
* If the patch could not be applied (because some hunks in the patch couldn't be fitted to the text in `source`), `applyPatch` returns false.
*
* @param patch a string diff or the output from the `parsePatch` or `structuredPatch` methods.
*/
export declare function applyPatch(source: string, patch: string | StructuredPatch | [StructuredPatch], options?: ApplyPatchOptions): string | false;
export interface ApplyPatchesOptions extends ApplyPatchOptions {
loadFile: (index: StructuredPatch, callback: (err: any, data: string) => void) => void;
patched: (index: StructuredPatch, content: string | false, callback: (err: any) => void) => void;
complete: (err?: any) => void;
}
/**
* applies one or more patches.
*
* `patch` may be either an array of structured patch objects, or a string representing a patch in unified diff format (which may patch one or more files).
*
* This method will iterate over the contents of the patch and apply to data provided through callbacks. The general flow for each patch index is:
*
* - `options.loadFile(index, callback)` is called. The caller should then load the contents of the file and then pass that to the `callback(err, data)` callback. Passing an `err` will terminate further patch execution.
* - `options.patched(index, content, callback)` is called once the patch has been applied. `content` will be the return value from `applyPatch`. When it's ready, the caller should call `callback(err)` callback. Passing an `err` will terminate further patch execution.
*
* Once all patches have been applied or an error occurs, the `options.complete(err)` callback is made.
*/
export declare function applyPatches(uniDiff: string | StructuredPatch[], options: ApplyPatchesOptions): void;
//# sourceMappingURL=apply.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/patch/apply.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC;CACtG;AAOD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GAAG,eAAe,GAAG,CAAC,eAAe,CAAC,EACnD,OAAO,GAAE,iBAAsB,GAC9B,MAAM,GAAG,KAAK,CAehB;AAyPD,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB;IAC5D,QAAQ,EAAE,CAAC,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC;IACvF,OAAO,EAAE,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,KAAK,IAAI,CAAC;IACjG,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;CAC/B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,EAAE,EAAE,OAAO,EAAE,mBAAmB,GAAG,IAAI,CA0BpG"}

View file

@ -0,0 +1,267 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.applyPatch = applyPatch;
exports.applyPatches = applyPatches;
var string_js_1 = require("../util/string.js");
var line_endings_js_1 = require("./line-endings.js");
var parse_js_1 = require("./parse.js");
var distance_iterator_js_1 = require("../util/distance-iterator.js");
/**
* attempts to apply a unified diff patch.
*
* Hunks are applied first to last.
* `applyPatch` first tries to apply the first hunk at the line number specified in the hunk header, and with all context lines matching exactly.
* If that fails, it tries scanning backwards and forwards, one line at a time, to find a place to apply the hunk where the context lines match exactly.
* If that still fails, and `fuzzFactor` is greater than zero, it increments the maximum number of mismatches (missing, extra, or changed context lines) that there can be between the hunk context and a region where we are trying to apply the patch such that the hunk will still be considered to match.
* Regardless of `fuzzFactor`, lines to be deleted in the hunk *must* be present for a hunk to match, and the context lines *immediately* before and after an insertion must match exactly.
*
* Once a hunk is successfully fitted, the process begins again with the next hunk.
* Regardless of `fuzzFactor`, later hunks must be applied later in the file than earlier hunks.
*
* If a hunk cannot be successfully fitted *anywhere* with fewer than `fuzzFactor` mismatches, `applyPatch` fails and returns `false`.
*
* If a hunk is successfully fitted but not at the line number specified by the hunk header, all subsequent hunks have their target line number adjusted accordingly.
* (e.g. if the first hunk is applied 10 lines below where the hunk header said it should fit, `applyPatch` will *start* looking for somewhere to apply the second hunk 10 lines below where its hunk header says it goes.)
*
* If the patch was applied successfully, returns a string containing the patched text.
* If the patch could not be applied (because some hunks in the patch couldn't be fitted to the text in `source`), `applyPatch` returns false.
*
* @param patch a string diff or the output from the `parsePatch` or `structuredPatch` methods.
*/
function applyPatch(source, patch, options) {
if (options === void 0) { options = {}; }
var patches;
if (typeof patch === 'string') {
patches = (0, parse_js_1.parsePatch)(patch);
}
else if (Array.isArray(patch)) {
patches = patch;
}
else {
patches = [patch];
}
if (patches.length > 1) {
throw new Error('applyPatch only works with a single input.');
}
return applyStructuredPatch(source, patches[0], options);
}
function applyStructuredPatch(source, patch, options) {
if (options === void 0) { options = {}; }
if (options.autoConvertLineEndings || options.autoConvertLineEndings == null) {
if ((0, string_js_1.hasOnlyWinLineEndings)(source) && (0, line_endings_js_1.isUnix)(patch)) {
patch = (0, line_endings_js_1.unixToWin)(patch);
}
else if ((0, string_js_1.hasOnlyUnixLineEndings)(source) && (0, line_endings_js_1.isWin)(patch)) {
patch = (0, line_endings_js_1.winToUnix)(patch);
}
}
// Apply the diff to the input
var lines = source.split('\n'), hunks = patch.hunks, compareLine = options.compareLine || (function (lineNumber, line, operation, patchContent) { return line === patchContent; }), fuzzFactor = options.fuzzFactor || 0;
var minLine = 0;
if (fuzzFactor < 0 || !Number.isInteger(fuzzFactor)) {
throw new Error('fuzzFactor must be a non-negative integer');
}
// Special case for empty patch.
if (!hunks.length) {
return source;
}
// Before anything else, handle EOFNL insertion/removal. If the patch tells us to make a change
// to the EOFNL that is redundant/impossible - i.e. to remove a newline that's not there, or add a
// newline that already exists - then we either return false and fail to apply the patch (if
// fuzzFactor is 0) or simply ignore the problem and do nothing (if fuzzFactor is >0).
// If we do need to remove/add a newline at EOF, this will always be in the final hunk:
var prevLine = '', removeEOFNL = false, addEOFNL = false;
for (var i = 0; i < hunks[hunks.length - 1].lines.length; i++) {
var line = hunks[hunks.length - 1].lines[i];
if (line[0] == '\\') {
if (prevLine[0] == '+') {
removeEOFNL = true;
}
else if (prevLine[0] == '-') {
addEOFNL = true;
}
}
prevLine = line;
}
if (removeEOFNL) {
if (addEOFNL) {
// This means the final line gets changed but doesn't have a trailing newline in either the
// original or patched version. In that case, we do nothing if fuzzFactor > 0, and if
// fuzzFactor is 0, we simply validate that the source file has no trailing newline.
if (!fuzzFactor && lines[lines.length - 1] == '') {
return false;
}
}
else if (lines[lines.length - 1] == '') {
lines.pop();
}
else if (!fuzzFactor) {
return false;
}
}
else if (addEOFNL) {
if (lines[lines.length - 1] != '') {
lines.push('');
}
else if (!fuzzFactor) {
return false;
}
}
/**
* Checks if the hunk can be made to fit at the provided location with at most `maxErrors`
* insertions, substitutions, or deletions, while ensuring also that:
* - lines deleted in the hunk match exactly, and
* - wherever an insertion operation or block of insertion operations appears in the hunk, the
* immediately preceding and following lines of context match exactly
*
* `toPos` should be set such that lines[toPos] is meant to match hunkLines[0].
*
* If the hunk can be applied, returns an object with properties `oldLineLastI` and
* `replacementLines`. Otherwise, returns null.
*/
function applyHunk(hunkLines, toPos, maxErrors, hunkLinesI, lastContextLineMatched, patchedLines, patchedLinesLength) {
if (hunkLinesI === void 0) { hunkLinesI = 0; }
if (lastContextLineMatched === void 0) { lastContextLineMatched = true; }
if (patchedLines === void 0) { patchedLines = []; }
if (patchedLinesLength === void 0) { patchedLinesLength = 0; }
var nConsecutiveOldContextLines = 0;
var nextContextLineMustMatch = false;
for (; hunkLinesI < hunkLines.length; hunkLinesI++) {
var hunkLine = hunkLines[hunkLinesI], operation = (hunkLine.length > 0 ? hunkLine[0] : ' '), content = (hunkLine.length > 0 ? hunkLine.substr(1) : hunkLine);
if (operation === '-') {
if (compareLine(toPos + 1, lines[toPos], operation, content)) {
toPos++;
nConsecutiveOldContextLines = 0;
}
else {
if (!maxErrors || lines[toPos] == null) {
return null;
}
patchedLines[patchedLinesLength] = lines[toPos];
return applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI, false, patchedLines, patchedLinesLength + 1);
}
}
if (operation === '+') {
if (!lastContextLineMatched) {
return null;
}
patchedLines[patchedLinesLength] = content;
patchedLinesLength++;
nConsecutiveOldContextLines = 0;
nextContextLineMustMatch = true;
}
if (operation === ' ') {
nConsecutiveOldContextLines++;
patchedLines[patchedLinesLength] = lines[toPos];
if (compareLine(toPos + 1, lines[toPos], operation, content)) {
patchedLinesLength++;
lastContextLineMatched = true;
nextContextLineMustMatch = false;
toPos++;
}
else {
if (nextContextLineMustMatch || !maxErrors) {
return null;
}
// Consider 3 possibilities in sequence:
// 1. lines contains a *substitution* not included in the patch context, or
// 2. lines contains an *insertion* not included in the patch context, or
// 3. lines contains a *deletion* not included in the patch context
// The first two options are of course only possible if the line from lines is non-null -
// i.e. only option 3 is possible if we've overrun the end of the old file.
return (lines[toPos] && (applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI + 1, false, patchedLines, patchedLinesLength + 1) || applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI, false, patchedLines, patchedLinesLength + 1)) || applyHunk(hunkLines, toPos, maxErrors - 1, hunkLinesI + 1, false, patchedLines, patchedLinesLength));
}
}
}
// Before returning, trim any unmodified context lines off the end of patchedLines and reduce
// toPos (and thus oldLineLastI) accordingly. This allows later hunks to be applied to a region
// that starts in this hunk's trailing context.
patchedLinesLength -= nConsecutiveOldContextLines;
toPos -= nConsecutiveOldContextLines;
patchedLines.length = patchedLinesLength;
return {
patchedLines: patchedLines,
oldLineLastI: toPos - 1
};
}
var resultLines = [];
// Search best fit offsets for each hunk based on the previous ones
var prevHunkOffset = 0;
for (var i = 0; i < hunks.length; i++) {
var hunk = hunks[i];
var hunkResult = void 0;
var maxLine = lines.length - hunk.oldLines + fuzzFactor;
var toPos = void 0;
for (var maxErrors = 0; maxErrors <= fuzzFactor; maxErrors++) {
toPos = hunk.oldStart + prevHunkOffset - 1;
var iterator = (0, distance_iterator_js_1.default)(toPos, minLine, maxLine);
for (; toPos !== undefined; toPos = iterator()) {
hunkResult = applyHunk(hunk.lines, toPos, maxErrors);
if (hunkResult) {
break;
}
}
if (hunkResult) {
break;
}
}
if (!hunkResult) {
return false;
}
// Copy everything from the end of where we applied the last hunk to the start of this hunk
for (var i_1 = minLine; i_1 < toPos; i_1++) {
resultLines.push(lines[i_1]);
}
// Add the lines produced by applying the hunk:
for (var i_2 = 0; i_2 < hunkResult.patchedLines.length; i_2++) {
var line = hunkResult.patchedLines[i_2];
resultLines.push(line);
}
// Set lower text limit to end of the current hunk, so next ones don't try
// to fit over already patched text
minLine = hunkResult.oldLineLastI + 1;
// Note the offset between where the patch said the hunk should've applied and where we
// applied it, so we can adjust future hunks accordingly:
prevHunkOffset = toPos + 1 - hunk.oldStart;
}
// Copy over the rest of the lines from the old text
for (var i = minLine; i < lines.length; i++) {
resultLines.push(lines[i]);
}
return resultLines.join('\n');
}
/**
* applies one or more patches.
*
* `patch` may be either an array of structured patch objects, or a string representing a patch in unified diff format (which may patch one or more files).
*
* This method will iterate over the contents of the patch and apply to data provided through callbacks. The general flow for each patch index is:
*
* - `options.loadFile(index, callback)` is called. The caller should then load the contents of the file and then pass that to the `callback(err, data)` callback. Passing an `err` will terminate further patch execution.
* - `options.patched(index, content, callback)` is called once the patch has been applied. `content` will be the return value from `applyPatch`. When it's ready, the caller should call `callback(err)` callback. Passing an `err` will terminate further patch execution.
*
* Once all patches have been applied or an error occurs, the `options.complete(err)` callback is made.
*/
function applyPatches(uniDiff, options) {
var spDiff = typeof uniDiff === 'string' ? (0, parse_js_1.parsePatch)(uniDiff) : uniDiff;
var currentIndex = 0;
function processIndex() {
var index = spDiff[currentIndex++];
if (!index) {
return options.complete();
}
options.loadFile(index, function (err, data) {
if (err) {
return options.complete(err);
}
var updatedContent = applyPatch(data, index, options);
options.patched(index, updatedContent, function (err) {
if (err) {
return options.complete(err);
}
processIndex();
});
});
}
processIndex();
}

View file

@ -0,0 +1,100 @@
import type { StructuredPatch, DiffLinesOptionsAbortable, DiffLinesOptionsNonabortable, AbortableDiffOptions } from '../types.js';
type StructuredPatchCallbackAbortable = (patch: StructuredPatch | undefined) => void;
type StructuredPatchCallbackNonabortable = (patch: StructuredPatch) => void;
interface _StructuredPatchOptionsAbortable extends Pick<DiffLinesOptionsAbortable, 'ignoreWhitespace' | 'stripTrailingCr'> {
/**
* describes how many lines of context should be included.
* You can set this to `Number.MAX_SAFE_INTEGER` or `Infinity` to include the entire file content in one hunk.
* @default 4
*/
context?: number;
callback?: StructuredPatchCallbackAbortable;
}
export type StructuredPatchOptionsAbortable = _StructuredPatchOptionsAbortable & AbortableDiffOptions;
export interface StructuredPatchOptionsNonabortable extends Pick<DiffLinesOptionsNonabortable, 'ignoreWhitespace' | 'stripTrailingCr'> {
context?: number;
callback?: StructuredPatchCallbackNonabortable;
}
interface StructuredPatchCallbackOptionAbortable {
/**
* If provided, the diff will be computed in async mode to avoid blocking the event loop while the diff is calculated.
* The value of the `callback` option should be a function and will be passed the computed diff or patch as its first argument.
*/
callback: StructuredPatchCallbackAbortable;
}
interface StructuredPatchCallbackOptionNonabortable {
/**
* If provided, the diff will be computed in async mode to avoid blocking the event loop while the diff is calculated.
* The value of the `callback` option should be a function and will be passed the computed diff or patch as its first argument.
*/
callback: StructuredPatchCallbackNonabortable;
}
/**
* returns an object with an array of hunk objects.
*
* This method is similar to createTwoFilesPatch, but returns a data structure suitable for further processing.
* @param oldFileName String to be output in the filename section of the patch for the removals
* @param newFileName String to be output in the filename section of the patch for the additions
* @param oldStr Original string value
* @param newStr New string value
* @param oldHeader Optional additional information to include in the old file header.
* @param newHeader Optional additional information to include in the new file header.
*/
export declare function structuredPatch(oldFileName: string, newFileName: string, oldStr: string, newStr: string, oldHeader: string | undefined, newHeader: string | undefined, options: StructuredPatchCallbackNonabortable): undefined;
export declare function structuredPatch(oldFileName: string, newFileName: string, oldStr: string, newStr: string, oldHeader: string | undefined, newHeader: string | undefined, options: StructuredPatchOptionsAbortable & StructuredPatchCallbackOptionAbortable): undefined;
export declare function structuredPatch(oldFileName: string, newFileName: string, oldStr: string, newStr: string, oldHeader: string | undefined, newHeader: string | undefined, options: StructuredPatchOptionsNonabortable & StructuredPatchCallbackOptionNonabortable): undefined;
export declare function structuredPatch(oldFileName: string, newFileName: string, oldStr: string, newStr: string, oldHeader: string | undefined, newHeader: string | undefined, options: StructuredPatchOptionsAbortable): StructuredPatch | undefined;
export declare function structuredPatch(oldFileName: string, newFileName: string, oldStr: string, newStr: string, oldHeader?: string, newHeader?: string, options?: StructuredPatchOptionsNonabortable): StructuredPatch;
/**
* creates a unified diff patch.
* @param patch either a single structured patch object (as returned by `structuredPatch`) or an array of them (as returned by `parsePatch`)
*/
export declare function formatPatch(patch: StructuredPatch | StructuredPatch[]): string;
type CreatePatchCallbackAbortable = (patch: string | undefined) => void;
type CreatePatchCallbackNonabortable = (patch: string) => void;
interface _CreatePatchOptionsAbortable extends Pick<DiffLinesOptionsAbortable, 'ignoreWhitespace' | 'stripTrailingCr'> {
context?: number;
callback?: CreatePatchCallbackAbortable;
}
export type CreatePatchOptionsAbortable = _CreatePatchOptionsAbortable & AbortableDiffOptions;
export interface CreatePatchOptionsNonabortable extends Pick<DiffLinesOptionsNonabortable, 'ignoreWhitespace' | 'stripTrailingCr'> {
context?: number;
callback?: CreatePatchCallbackNonabortable;
}
interface CreatePatchCallbackOptionAbortable {
callback: CreatePatchCallbackAbortable;
}
interface CreatePatchCallbackOptionNonabortable {
callback: CreatePatchCallbackNonabortable;
}
/**
* creates a unified diff patch by first computing a diff with `diffLines` and then serializing it to unified diff format.
* @param oldFileName String to be output in the filename section of the patch for the removals
* @param newFileName String to be output in the filename section of the patch for the additions
* @param oldStr Original string value
* @param newStr New string value
* @param oldHeader Optional additional information to include in the old file header.
* @param newHeader Optional additional information to include in the new file header.
*/
export declare function createTwoFilesPatch(oldFileName: string, newFileName: string, oldStr: string, newStr: string, oldHeader: string | undefined, newHeader: string | undefined, options: CreatePatchCallbackNonabortable): undefined;
export declare function createTwoFilesPatch(oldFileName: string, newFileName: string, oldStr: string, newStr: string, oldHeader: string | undefined, newHeader: string | undefined, options: CreatePatchOptionsAbortable & CreatePatchCallbackOptionAbortable): undefined;
export declare function createTwoFilesPatch(oldFileName: string, newFileName: string, oldStr: string, newStr: string, oldHeader: string | undefined, newHeader: string | undefined, options: CreatePatchOptionsNonabortable & CreatePatchCallbackOptionNonabortable): undefined;
export declare function createTwoFilesPatch(oldFileName: string, newFileName: string, oldStr: string, newStr: string, oldHeader: string | undefined, newHeader: string | undefined, options: CreatePatchOptionsAbortable): string | undefined;
export declare function createTwoFilesPatch(oldFileName: string, newFileName: string, oldStr: string, newStr: string, oldHeader?: string, newHeader?: string, options?: CreatePatchOptionsNonabortable): string;
/**
* creates a unified diff patch.
*
* Just like createTwoFilesPatch, but with oldFileName being equal to newFileName.
* @param fileName String to be output in the filename section of the patch
* @param oldStr Original string value
* @param newStr New string value
* @param oldHeader Optional additional information to include in the old file header.
* @param newHeader Optional additional information to include in the new file header.
*/
export declare function createPatch(fileName: string, oldStr: string, newStr: string, oldHeader: string | undefined, newHeader: string | undefined, options: CreatePatchCallbackNonabortable): undefined;
export declare function createPatch(fileName: string, oldStr: string, newStr: string, oldHeader: string | undefined, newHeader: string | undefined, options: CreatePatchOptionsAbortable & CreatePatchCallbackOptionAbortable): undefined;
export declare function createPatch(fileName: string, oldStr: string, newStr: string, oldHeader: string | undefined, newHeader: string | undefined, options: CreatePatchOptionsNonabortable & CreatePatchCallbackOptionNonabortable): undefined;
export declare function createPatch(fileName: string, oldStr: string, newStr: string, oldHeader: string | undefined, newHeader: string | undefined, options: CreatePatchOptionsAbortable): string | undefined;
export declare function createPatch(fileName: string, oldStr: string, newStr: string, oldHeader?: string, newHeader?: string, options?: CreatePatchOptionsNonabortable): string;
export {};
//# sourceMappingURL=create.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/patch/create.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,yBAAyB,EAAE,4BAA4B,EAAE,oBAAoB,EAAgB,MAAM,aAAa,CAAC;AAEhJ,KAAK,gCAAgC,GAAG,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,KAAK,IAAI,CAAC;AACrF,KAAK,mCAAmC,GAAG,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;AAE5E,UAAU,gCAAiC,SAAQ,IAAI,CAAC,yBAAyB,EAAE,kBAAkB,GAAG,iBAAiB,CAAC;IACxH;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,gCAAgC,CAAC;CAC7C;AACD,MAAM,MAAM,+BAA+B,GAAG,gCAAgC,GAAG,oBAAoB,CAAC;AACtG,MAAM,WAAW,kCAAmC,SAAQ,IAAI,CAAC,4BAA4B,EAAE,kBAAkB,GAAG,iBAAiB,CAAC;IACpI,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,mCAAmC,CAAC;CAChD;AACD,UAAU,sCAAsC;IAC9C;;;OAGG;IACH,QAAQ,EAAE,gCAAgC,CAAC;CAC5C;AACD,UAAU,yCAAyC;IACjD;;;OAGG;IACH,QAAQ,EAAE,mCAAmC,CAAC;CAC/C;AASD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,OAAO,EAAE,mCAAmC,GAC3C,SAAS,CAAC;AACb,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,OAAO,EAAE,+BAA+B,GAAG,sCAAsC,GAChF,SAAS,CAAA;AACZ,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,OAAO,EAAE,kCAAkC,GAAG,yCAAyC,GACtF,SAAS,CAAA;AACZ,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,OAAO,EAAE,+BAA+B,GACvC,eAAe,GAAG,SAAS,CAAA;AAC9B,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,kCAAkC,GAC3C,eAAe,CAAA;AA2JlB;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,eAAe,GAAG,eAAe,EAAE,GAAG,MAAM,CAmC9E;AAED,KAAK,4BAA4B,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;AACxE,KAAK,+BAA+B,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;AAE/D,UAAU,4BAA6B,SAAQ,IAAI,CAAC,yBAAyB,EAAE,kBAAkB,GAAG,iBAAiB,CAAC;IACpH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,4BAA4B,CAAC;CACzC;AACD,MAAM,MAAM,2BAA2B,GAAG,4BAA4B,GAAG,oBAAoB,CAAC;AAC9F,MAAM,WAAW,8BAA+B,SAAQ,IAAI,CAAC,4BAA4B,EAAE,kBAAkB,GAAG,iBAAiB,CAAC;IAChI,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,+BAA+B,CAAC;CAC5C;AACD,UAAU,kCAAkC;IAC1C,QAAQ,EAAE,4BAA4B,CAAC;CACxC;AACD,UAAU,qCAAqC;IAC7C,QAAQ,EAAE,+BAA+B,CAAC;CAC3C;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,OAAO,EAAE,+BAA+B,GACvC,SAAS,CAAC;AACb,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,OAAO,EAAE,2BAA2B,GAAG,kCAAkC,GACxE,SAAS,CAAA;AACZ,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,OAAO,EAAE,8BAA8B,GAAG,qCAAqC,GAC9E,SAAS,CAAA;AACZ,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,OAAO,EAAE,2BAA2B,GACnC,MAAM,GAAG,SAAS,CAAA;AACrB,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,8BAA8B,GACvC,MAAM,CAAA;AA2CT;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,OAAO,EAAE,+BAA+B,GACvC,SAAS,CAAC;AACb,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,OAAO,EAAE,2BAA2B,GAAG,kCAAkC,GACxE,SAAS,CAAA;AACZ,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,OAAO,EAAE,8BAA8B,GAAG,qCAAqC,GAC9E,SAAS,CAAA;AACZ,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,OAAO,EAAE,2BAA2B,GACnC,MAAM,GAAG,SAAS,CAAA;AACrB,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,8BAA8B,GACvC,MAAM,CAAA"}

View file

@ -0,0 +1,223 @@
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.structuredPatch = structuredPatch;
exports.formatPatch = formatPatch;
exports.createTwoFilesPatch = createTwoFilesPatch;
exports.createPatch = createPatch;
var line_js_1 = require("../diff/line.js");
function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
var optionsObj;
if (!options) {
optionsObj = {};
}
else if (typeof options === 'function') {
optionsObj = { callback: options };
}
else {
optionsObj = options;
}
if (typeof optionsObj.context === 'undefined') {
optionsObj.context = 4;
}
// We copy this into its own variable to placate TypeScript, which thinks
// optionsObj.context might be undefined in the callbacks below.
var context = optionsObj.context;
// @ts-expect-error (runtime check for something that is correctly a static type error)
if (optionsObj.newlineIsToken) {
throw new Error('newlineIsToken may not be used with patch-generation functions, only with diffing functions');
}
if (!optionsObj.callback) {
return diffLinesResultToPatch((0, line_js_1.diffLines)(oldStr, newStr, optionsObj));
}
else {
var callback_1 = optionsObj.callback;
(0, line_js_1.diffLines)(oldStr, newStr, __assign(__assign({}, optionsObj), { callback: function (diff) {
var patch = diffLinesResultToPatch(diff);
// TypeScript is unhappy without the cast because it does not understand that `patch` may
// be undefined here only if `callback` is StructuredPatchCallbackAbortable:
callback_1(patch);
} }));
}
function diffLinesResultToPatch(diff) {
// STEP 1: Build up the patch with no "\ No newline at end of file" lines and with the arrays
// of lines containing trailing newline characters. We'll tidy up later...
if (!diff) {
return;
}
diff.push({ value: '', lines: [] }); // Append an empty value to make cleanup easier
function contextLines(lines) {
return lines.map(function (entry) { return ' ' + entry; });
}
var hunks = [];
var oldRangeStart = 0, newRangeStart = 0, curRange = [], oldLine = 1, newLine = 1;
for (var i = 0; i < diff.length; i++) {
var current = diff[i], lines = current.lines || splitLines(current.value);
current.lines = lines;
if (current.added || current.removed) {
// If we have previous context, start with that
if (!oldRangeStart) {
var prev = diff[i - 1];
oldRangeStart = oldLine;
newRangeStart = newLine;
if (prev) {
curRange = context > 0 ? contextLines(prev.lines.slice(-context)) : [];
oldRangeStart -= curRange.length;
newRangeStart -= curRange.length;
}
}
// Output our changes
for (var _i = 0, lines_1 = lines; _i < lines_1.length; _i++) {
var line = lines_1[_i];
curRange.push((current.added ? '+' : '-') + line);
}
// Track the updated file position
if (current.added) {
newLine += lines.length;
}
else {
oldLine += lines.length;
}
}
else {
// Identical context lines. Track line changes
if (oldRangeStart) {
// Close out any changes that have been output (or join overlapping)
if (lines.length <= context * 2 && i < diff.length - 2) {
// Overlapping
for (var _a = 0, _b = contextLines(lines); _a < _b.length; _a++) {
var line = _b[_a];
curRange.push(line);
}
}
else {
// end the range and output
var contextSize = Math.min(lines.length, context);
for (var _c = 0, _d = contextLines(lines.slice(0, contextSize)); _c < _d.length; _c++) {
var line = _d[_c];
curRange.push(line);
}
var hunk = {
oldStart: oldRangeStart,
oldLines: (oldLine - oldRangeStart + contextSize),
newStart: newRangeStart,
newLines: (newLine - newRangeStart + contextSize),
lines: curRange
};
hunks.push(hunk);
oldRangeStart = 0;
newRangeStart = 0;
curRange = [];
}
}
oldLine += lines.length;
newLine += lines.length;
}
}
// Step 2: eliminate the trailing `\n` from each line of each hunk, and, where needed, add
// "\ No newline at end of file".
for (var _e = 0, hunks_1 = hunks; _e < hunks_1.length; _e++) {
var hunk = hunks_1[_e];
for (var i = 0; i < hunk.lines.length; i++) {
if (hunk.lines[i].endsWith('\n')) {
hunk.lines[i] = hunk.lines[i].slice(0, -1);
}
else {
hunk.lines.splice(i + 1, 0, '\\ No newline at end of file');
i++; // Skip the line we just added, then continue iterating
}
}
}
return {
oldFileName: oldFileName, newFileName: newFileName,
oldHeader: oldHeader, newHeader: newHeader,
hunks: hunks
};
}
}
/**
* creates a unified diff patch.
* @param patch either a single structured patch object (as returned by `structuredPatch`) or an array of them (as returned by `parsePatch`)
*/
function formatPatch(patch) {
if (Array.isArray(patch)) {
return patch.map(formatPatch).join('\n');
}
var ret = [];
if (patch.oldFileName == patch.newFileName) {
ret.push('Index: ' + patch.oldFileName);
}
ret.push('===================================================================');
ret.push('--- ' + patch.oldFileName + (typeof patch.oldHeader === 'undefined' ? '' : '\t' + patch.oldHeader));
ret.push('+++ ' + patch.newFileName + (typeof patch.newHeader === 'undefined' ? '' : '\t' + patch.newHeader));
for (var i = 0; i < patch.hunks.length; i++) {
var hunk = patch.hunks[i];
// Unified Diff Format quirk: If the chunk size is 0,
// the first number is one lower than one would expect.
// https://www.artima.com/weblogs/viewpost.jsp?thread=164293
if (hunk.oldLines === 0) {
hunk.oldStart -= 1;
}
if (hunk.newLines === 0) {
hunk.newStart -= 1;
}
ret.push('@@ -' + hunk.oldStart + ',' + hunk.oldLines
+ ' +' + hunk.newStart + ',' + hunk.newLines
+ ' @@');
for (var _i = 0, _a = hunk.lines; _i < _a.length; _i++) {
var line = _a[_i];
ret.push(line);
}
}
return ret.join('\n') + '\n';
}
function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
if (typeof options === 'function') {
options = { callback: options };
}
if (!(options === null || options === void 0 ? void 0 : options.callback)) {
var patchObj = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options);
if (!patchObj) {
return;
}
return formatPatch(patchObj);
}
else {
var callback_2 = options.callback;
structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, __assign(__assign({}, options), { callback: function (patchObj) {
if (!patchObj) {
callback_2(undefined);
}
else {
callback_2(formatPatch(patchObj));
}
} }));
}
}
function createPatch(fileName, oldStr, newStr, oldHeader, newHeader, options) {
return createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader, options);
}
/**
* Split `text` into an array of lines, including the trailing newline character (where present)
*/
function splitLines(text) {
var hasTrailingNl = text.endsWith('\n');
var result = text.split('\n').map(function (line) { return line + '\n'; });
if (hasTrailingNl) {
result.pop();
}
else {
result.push(result.pop().slice(0, -1));
}
return result;
}

View file

@ -0,0 +1,17 @@
import type { StructuredPatch } from '../types.js';
export declare function unixToWin(patch: StructuredPatch): StructuredPatch;
export declare function unixToWin(patches: StructuredPatch[]): StructuredPatch[];
export declare function unixToWin(patch: StructuredPatch | StructuredPatch[]): StructuredPatch | StructuredPatch[];
export declare function winToUnix(patch: StructuredPatch): StructuredPatch;
export declare function winToUnix(patches: StructuredPatch[]): StructuredPatch[];
export declare function winToUnix(patch: StructuredPatch | StructuredPatch[]): StructuredPatch | StructuredPatch[];
/**
* Returns true if the patch consistently uses Unix line endings (or only involves one line and has
* no line endings).
*/
export declare function isUnix(patch: StructuredPatch | StructuredPatch[]): boolean;
/**
* Returns true if the patch uses Windows line endings and only Windows line endings.
*/
export declare function isWin(patch: StructuredPatch | StructuredPatch[]): boolean;
//# sourceMappingURL=line-endings.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"line-endings.d.ts","sourceRoot":"","sources":["../../src/patch/line-endings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,wBAAgB,SAAS,CAAC,KAAK,EAAE,eAAe,GAAG,eAAe,CAAC;AACnE,wBAAgB,SAAS,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,eAAe,EAAE,CAAC;AACzE,wBAAgB,SAAS,CAAC,KAAK,EAAE,eAAe,GAAG,eAAe,EAAE,GAAG,eAAe,GAAG,eAAe,EAAE,CAAC;AA0B3G,wBAAgB,SAAS,CAAC,KAAK,EAAE,eAAe,GAAG,eAAe,CAAC;AACnE,wBAAgB,SAAS,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,eAAe,EAAE,CAAC;AACzE,wBAAgB,SAAS,CAAC,KAAK,EAAE,eAAe,GAAG,eAAe,EAAE,GAAG,eAAe,GAAG,eAAe,EAAE,CAAC;AAgB3G;;;GAGG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,eAAe,EAAE,GAAG,OAAO,CAS1E;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,eAAe,GAAG,eAAe,EAAE,GAAG,OAAO,CAUzE"}

View file

@ -0,0 +1,61 @@
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.unixToWin = unixToWin;
exports.winToUnix = winToUnix;
exports.isUnix = isUnix;
exports.isWin = isWin;
function unixToWin(patch) {
if (Array.isArray(patch)) {
// It would be cleaner if instead of the line below we could just write
// return patch.map(unixToWin)
// but mysteriously TypeScript (v5.7.3 at the time of writing) does not like this and it will
// refuse to compile, thinking that unixToWin could then return StructuredPatch[][] and the
// result would be incompatible with the overload signatures.
// See bug report at https://github.com/microsoft/TypeScript/issues/61398.
return patch.map(function (p) { return unixToWin(p); });
}
return __assign(__assign({}, patch), { hunks: patch.hunks.map(function (hunk) { return (__assign(__assign({}, hunk), { lines: hunk.lines.map(function (line, i) {
var _a;
return (line.startsWith('\\') || line.endsWith('\r') || ((_a = hunk.lines[i + 1]) === null || _a === void 0 ? void 0 : _a.startsWith('\\')))
? line
: line + '\r';
}) })); }) });
}
function winToUnix(patch) {
if (Array.isArray(patch)) {
// (See comment above equivalent line in unixToWin)
return patch.map(function (p) { return winToUnix(p); });
}
return __assign(__assign({}, patch), { hunks: patch.hunks.map(function (hunk) { return (__assign(__assign({}, hunk), { lines: hunk.lines.map(function (line) { return line.endsWith('\r') ? line.substring(0, line.length - 1) : line; }) })); }) });
}
/**
* Returns true if the patch consistently uses Unix line endings (or only involves one line and has
* no line endings).
*/
function isUnix(patch) {
if (!Array.isArray(patch)) {
patch = [patch];
}
return !patch.some(function (index) { return index.hunks.some(function (hunk) { return hunk.lines.some(function (line) { return !line.startsWith('\\') && line.endsWith('\r'); }); }); });
}
/**
* Returns true if the patch uses Windows line endings and only Windows line endings.
*/
function isWin(patch) {
if (!Array.isArray(patch)) {
patch = [patch];
}
return patch.some(function (index) { return index.hunks.some(function (hunk) { return hunk.lines.some(function (line) { return line.endsWith('\r'); }); }); })
&& patch.every(function (index) { return index.hunks.every(function (hunk) { return hunk.lines.every(function (line, i) { var _a; return line.startsWith('\\') || line.endsWith('\r') || ((_a = hunk.lines[i + 1]) === null || _a === void 0 ? void 0 : _a.startsWith('\\')); }); }); });
}

View file

@ -0,0 +1,8 @@
import type { StructuredPatch } from '../types.js';
/**
* Parses a patch into structured data, in the same structure returned by `structuredPatch`.
*
* @return a JSON object representation of the a patch, suitable for use with the `applyPatch` method.
*/
export declare function parsePatch(uniDiff: string): StructuredPatch[];
//# sourceMappingURL=parse.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/patch/parse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,EAAE,CAiJ7D"}

View file

@ -0,0 +1,133 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parsePatch = parsePatch;
/**
* Parses a patch into structured data, in the same structure returned by `structuredPatch`.
*
* @return a JSON object representation of the a patch, suitable for use with the `applyPatch` method.
*/
function parsePatch(uniDiff) {
var diffstr = uniDiff.split(/\n/), list = [];
var i = 0;
function parseIndex() {
var index = {};
list.push(index);
// Parse diff metadata
while (i < diffstr.length) {
var line = diffstr[i];
// File header found, end parsing diff metadata
if ((/^(---|\+\+\+|@@)\s/).test(line)) {
break;
}
// Diff index
var header = (/^(?:Index:|diff(?: -r \w+)+)\s+(.+?)\s*$/).exec(line);
if (header) {
index.index = header[1];
}
i++;
}
// Parse file headers if they are defined. Unified diff requires them, but
// there's no technical issues to have an isolated hunk without file header
parseFileHeader(index);
parseFileHeader(index);
// Parse hunks
index.hunks = [];
while (i < diffstr.length) {
var line = diffstr[i];
if ((/^(Index:\s|diff\s|---\s|\+\+\+\s|===================================================================)/).test(line)) {
break;
}
else if ((/^@@/).test(line)) {
index.hunks.push(parseHunk());
}
else if (line) {
throw new Error('Unknown line ' + (i + 1) + ' ' + JSON.stringify(line));
}
else {
i++;
}
}
}
// Parses the --- and +++ headers, if none are found, no lines
// are consumed.
function parseFileHeader(index) {
var fileHeader = (/^(---|\+\+\+)\s+(.*)\r?$/).exec(diffstr[i]);
if (fileHeader) {
var data = fileHeader[2].split('\t', 2), header = (data[1] || '').trim();
var fileName = data[0].replace(/\\\\/g, '\\');
if ((/^".*"$/).test(fileName)) {
fileName = fileName.substr(1, fileName.length - 2);
}
if (fileHeader[1] === '---') {
index.oldFileName = fileName;
index.oldHeader = header;
}
else {
index.newFileName = fileName;
index.newHeader = header;
}
i++;
}
}
// Parses a hunk
// This assumes that we are at the start of a hunk.
function parseHunk() {
var _a;
var chunkHeaderIndex = i, chunkHeaderLine = diffstr[i++], chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/);
var hunk = {
oldStart: +chunkHeader[1],
oldLines: typeof chunkHeader[2] === 'undefined' ? 1 : +chunkHeader[2],
newStart: +chunkHeader[3],
newLines: typeof chunkHeader[4] === 'undefined' ? 1 : +chunkHeader[4],
lines: []
};
// Unified Diff Format quirk: If the chunk size is 0,
// the first number is one lower than one would expect.
// https://www.artima.com/weblogs/viewpost.jsp?thread=164293
if (hunk.oldLines === 0) {
hunk.oldStart += 1;
}
if (hunk.newLines === 0) {
hunk.newStart += 1;
}
var addCount = 0, removeCount = 0;
for (; i < diffstr.length && (removeCount < hunk.oldLines || addCount < hunk.newLines || ((_a = diffstr[i]) === null || _a === void 0 ? void 0 : _a.startsWith('\\'))); i++) {
var operation = (diffstr[i].length == 0 && i != (diffstr.length - 1)) ? ' ' : diffstr[i][0];
if (operation === '+' || operation === '-' || operation === ' ' || operation === '\\') {
hunk.lines.push(diffstr[i]);
if (operation === '+') {
addCount++;
}
else if (operation === '-') {
removeCount++;
}
else if (operation === ' ') {
addCount++;
removeCount++;
}
}
else {
throw new Error("Hunk at line ".concat(chunkHeaderIndex + 1, " contained invalid line ").concat(diffstr[i]));
}
}
// Handle the empty block count case
if (!addCount && hunk.newLines === 1) {
hunk.newLines = 0;
}
if (!removeCount && hunk.oldLines === 1) {
hunk.oldLines = 0;
}
// Perform sanity checking
if (addCount !== hunk.newLines) {
throw new Error('Added line count did not match for hunk at line ' + (chunkHeaderIndex + 1));
}
if (removeCount !== hunk.oldLines) {
throw new Error('Removed line count did not match for hunk at line ' + (chunkHeaderIndex + 1));
}
return hunk;
}
while (i < diffstr.length) {
parseIndex();
}
return list;
}

View file

@ -0,0 +1,9 @@
import type { StructuredPatch } from '../types.js';
/**
* @param patch either a single structured patch object (as returned by `structuredPatch`) or an array of them (as returned by `parsePatch`).
* @returns a new structured patch which when applied will undo the original `patch`.
*/
export declare function reversePatch(structuredPatch: StructuredPatch): StructuredPatch;
export declare function reversePatch(structuredPatch: StructuredPatch[]): StructuredPatch[];
export declare function reversePatch(structuredPatch: StructuredPatch | StructuredPatch[]): StructuredPatch | StructuredPatch[];
//# sourceMappingURL=reverse.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"reverse.d.ts","sourceRoot":"","sources":["../../src/patch/reverse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,eAAe,EAAE,eAAe,GAAG,eAAe,CAAC;AAChF,wBAAgB,YAAY,CAAC,eAAe,EAAE,eAAe,EAAE,GAAG,eAAe,EAAE,CAAC;AACpF,wBAAgB,YAAY,CAAC,eAAe,EAAE,eAAe,GAAG,eAAe,EAAE,GAAG,eAAe,GAAG,eAAe,EAAE,CAAC"}

View file

@ -0,0 +1,37 @@
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.reversePatch = reversePatch;
function reversePatch(structuredPatch) {
if (Array.isArray(structuredPatch)) {
// (See comment in unixToWin for why we need the pointless-looking anonymous function here)
return structuredPatch.map(function (patch) { return reversePatch(patch); }).reverse();
}
return __assign(__assign({}, structuredPatch), { oldFileName: structuredPatch.newFileName, oldHeader: structuredPatch.newHeader, newFileName: structuredPatch.oldFileName, newHeader: structuredPatch.oldHeader, hunks: structuredPatch.hunks.map(function (hunk) {
return {
oldLines: hunk.newLines,
oldStart: hunk.newStart,
newLines: hunk.oldLines,
newStart: hunk.oldStart,
lines: hunk.lines.map(function (l) {
if (l.startsWith('-')) {
return "+".concat(l.slice(1));
}
if (l.startsWith('+')) {
return "-".concat(l.slice(1));
}
return l;
})
};
}) });
}