Atom eve seo
This commit is contained in:
257
.output/server/node_modules/diff/libesm/patch/apply.js
generated
vendored
Normal file
257
.output/server/node_modules/diff/libesm/patch/apply.js
generated
vendored
Normal file
@@ -0,0 +1,257 @@
|
||||
import { hasOnlyWinLineEndings, hasOnlyUnixLineEndings } from '../util/string.js';
|
||||
import { isWin, isUnix, unixToWin, winToUnix } from './line-endings.js';
|
||||
import { parsePatch } from './parse.js';
|
||||
import distanceIterator from '../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.
|
||||
*/
|
||||
export function applyPatch(source, patch, options = {}) {
|
||||
let patches;
|
||||
if (typeof patch === 'string') {
|
||||
patches = 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.autoConvertLineEndings || options.autoConvertLineEndings == null) {
|
||||
if (hasOnlyWinLineEndings(source) && isUnix(patch)) {
|
||||
patch = unixToWin(patch);
|
||||
}
|
||||
else if (hasOnlyUnixLineEndings(source) && isWin(patch)) {
|
||||
patch = winToUnix(patch);
|
||||
}
|
||||
}
|
||||
// Apply the diff to the input
|
||||
const lines = source.split('\n'), hunks = patch.hunks, compareLine = options.compareLine || ((lineNumber, line, operation, patchContent) => line === patchContent), fuzzFactor = options.fuzzFactor || 0;
|
||||
let 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:
|
||||
let prevLine = '', removeEOFNL = false, addEOFNL = false;
|
||||
for (let i = 0; i < hunks[hunks.length - 1].lines.length; i++) {
|
||||
const 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 = 0, lastContextLineMatched = true, patchedLines = [], patchedLinesLength = 0) {
|
||||
let nConsecutiveOldContextLines = 0;
|
||||
let nextContextLineMustMatch = false;
|
||||
for (; hunkLinesI < hunkLines.length; hunkLinesI++) {
|
||||
const 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,
|
||||
oldLineLastI: toPos - 1
|
||||
};
|
||||
}
|
||||
const resultLines = [];
|
||||
// Search best fit offsets for each hunk based on the previous ones
|
||||
let prevHunkOffset = 0;
|
||||
for (let i = 0; i < hunks.length; i++) {
|
||||
const hunk = hunks[i];
|
||||
let hunkResult;
|
||||
const maxLine = lines.length - hunk.oldLines + fuzzFactor;
|
||||
let toPos;
|
||||
for (let maxErrors = 0; maxErrors <= fuzzFactor; maxErrors++) {
|
||||
toPos = hunk.oldStart + prevHunkOffset - 1;
|
||||
const iterator = distanceIterator(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 (let i = minLine; i < toPos; i++) {
|
||||
resultLines.push(lines[i]);
|
||||
}
|
||||
// Add the lines produced by applying the hunk:
|
||||
for (let i = 0; i < hunkResult.patchedLines.length; i++) {
|
||||
const line = hunkResult.patchedLines[i];
|
||||
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 (let 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.
|
||||
*/
|
||||
export function applyPatches(uniDiff, options) {
|
||||
const spDiff = typeof uniDiff === 'string' ? parsePatch(uniDiff) : uniDiff;
|
||||
let currentIndex = 0;
|
||||
function processIndex() {
|
||||
const index = spDiff[currentIndex++];
|
||||
if (!index) {
|
||||
return options.complete();
|
||||
}
|
||||
options.loadFile(index, function (err, data) {
|
||||
if (err) {
|
||||
return options.complete(err);
|
||||
}
|
||||
const updatedContent = applyPatch(data, index, options);
|
||||
options.patched(index, updatedContent, function (err) {
|
||||
if (err) {
|
||||
return options.complete(err);
|
||||
}
|
||||
processIndex();
|
||||
});
|
||||
});
|
||||
}
|
||||
processIndex();
|
||||
}
|
||||
228
.output/server/node_modules/diff/libesm/patch/create.js
generated
vendored
Normal file
228
.output/server/node_modules/diff/libesm/patch/create.js
generated
vendored
Normal file
@@ -0,0 +1,228 @@
|
||||
import { diffLines } from '../diff/line.js';
|
||||
export const INCLUDE_HEADERS = {
|
||||
includeIndex: true,
|
||||
includeUnderline: true,
|
||||
includeFileHeaders: true
|
||||
};
|
||||
export const FILE_HEADERS_ONLY = {
|
||||
includeIndex: false,
|
||||
includeUnderline: false,
|
||||
includeFileHeaders: true
|
||||
};
|
||||
export const OMIT_HEADERS = {
|
||||
includeIndex: false,
|
||||
includeUnderline: false,
|
||||
includeFileHeaders: false
|
||||
};
|
||||
export function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
|
||||
let 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.
|
||||
const 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(diffLines(oldStr, newStr, optionsObj));
|
||||
}
|
||||
else {
|
||||
const { callback } = optionsObj;
|
||||
diffLines(oldStr, newStr, Object.assign(Object.assign({}, optionsObj), { callback: (diff) => {
|
||||
const 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(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; });
|
||||
}
|
||||
const hunks = [];
|
||||
let oldRangeStart = 0, newRangeStart = 0, curRange = [], oldLine = 1, newLine = 1;
|
||||
for (let i = 0; i < diff.length; i++) {
|
||||
const 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) {
|
||||
const 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 (const line of lines) {
|
||||
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 (const line of contextLines(lines)) {
|
||||
curRange.push(line);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// end the range and output
|
||||
const contextSize = Math.min(lines.length, context);
|
||||
for (const line of contextLines(lines.slice(0, contextSize))) {
|
||||
curRange.push(line);
|
||||
}
|
||||
const 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 (const hunk of hunks) {
|
||||
for (let 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`)
|
||||
*/
|
||||
export function formatPatch(patch, headerOptions) {
|
||||
if (!headerOptions) {
|
||||
headerOptions = INCLUDE_HEADERS;
|
||||
}
|
||||
if (Array.isArray(patch)) {
|
||||
if (patch.length > 1 && !headerOptions.includeFileHeaders) {
|
||||
throw new Error('Cannot omit file headers on a multi-file patch. '
|
||||
+ '(The result would be unparseable; how would a tool trying to apply '
|
||||
+ 'the patch know which changes are to which file?)');
|
||||
}
|
||||
return patch.map(p => formatPatch(p, headerOptions)).join('\n');
|
||||
}
|
||||
const ret = [];
|
||||
if (headerOptions.includeIndex && patch.oldFileName == patch.newFileName) {
|
||||
ret.push('Index: ' + patch.oldFileName);
|
||||
}
|
||||
if (headerOptions.includeUnderline) {
|
||||
ret.push('===================================================================');
|
||||
}
|
||||
if (headerOptions.includeFileHeaders) {
|
||||
ret.push('--- ' + patch.oldFileName + (typeof patch.oldHeader === 'undefined' ? '' : '\t' + patch.oldHeader));
|
||||
ret.push('+++ ' + patch.newFileName + (typeof patch.newHeader === 'undefined' ? '' : '\t' + patch.newHeader));
|
||||
}
|
||||
for (let i = 0; i < patch.hunks.length; i++) {
|
||||
const 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 (const line of hunk.lines) {
|
||||
ret.push(line);
|
||||
}
|
||||
}
|
||||
return ret.join('\n') + '\n';
|
||||
}
|
||||
export 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)) {
|
||||
const patchObj = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options);
|
||||
if (!patchObj) {
|
||||
return;
|
||||
}
|
||||
return formatPatch(patchObj, options === null || options === void 0 ? void 0 : options.headerOptions);
|
||||
}
|
||||
else {
|
||||
const { callback } = options;
|
||||
structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, Object.assign(Object.assign({}, options), { callback: patchObj => {
|
||||
if (!patchObj) {
|
||||
callback(undefined);
|
||||
}
|
||||
else {
|
||||
callback(formatPatch(patchObj, options.headerOptions));
|
||||
}
|
||||
} }));
|
||||
}
|
||||
}
|
||||
export 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) {
|
||||
const hasTrailingNl = text.endsWith('\n');
|
||||
const result = text.split('\n').map(line => line + '\n');
|
||||
if (hasTrailingNl) {
|
||||
result.pop();
|
||||
}
|
||||
else {
|
||||
result.push(result.pop().slice(0, -1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
44
.output/server/node_modules/diff/libesm/patch/line-endings.js
generated
vendored
Normal file
44
.output/server/node_modules/diff/libesm/patch/line-endings.js
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
export 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(p => unixToWin(p));
|
||||
}
|
||||
return Object.assign(Object.assign({}, patch), { hunks: patch.hunks.map(hunk => (Object.assign(Object.assign({}, hunk), { lines: hunk.lines.map((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';
|
||||
}) }))) });
|
||||
}
|
||||
export function winToUnix(patch) {
|
||||
if (Array.isArray(patch)) {
|
||||
// (See comment above equivalent line in unixToWin)
|
||||
return patch.map(p => winToUnix(p));
|
||||
}
|
||||
return Object.assign(Object.assign({}, patch), { hunks: patch.hunks.map(hunk => (Object.assign(Object.assign({}, hunk), { lines: hunk.lines.map(line => 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).
|
||||
*/
|
||||
export function isUnix(patch) {
|
||||
if (!Array.isArray(patch)) {
|
||||
patch = [patch];
|
||||
}
|
||||
return !patch.some(index => index.hunks.some(hunk => hunk.lines.some(line => !line.startsWith('\\') && line.endsWith('\r'))));
|
||||
}
|
||||
/**
|
||||
* Returns true if the patch uses Windows line endings and only Windows line endings.
|
||||
*/
|
||||
export function isWin(patch) {
|
||||
if (!Array.isArray(patch)) {
|
||||
patch = [patch];
|
||||
}
|
||||
return patch.some(index => index.hunks.some(hunk => hunk.lines.some(line => line.endsWith('\r'))))
|
||||
&& patch.every(index => index.hunks.every(hunk => hunk.lines.every((line, i) => { var _a; return line.startsWith('\\') || line.endsWith('\r') || ((_a = hunk.lines[i + 1]) === null || _a === void 0 ? void 0 : _a.startsWith('\\')); })));
|
||||
}
|
||||
147
.output/server/node_modules/diff/libesm/patch/parse.js
generated
vendored
Normal file
147
.output/server/node_modules/diff/libesm/patch/parse.js
generated
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
/**
|
||||
* 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 function parsePatch(uniDiff) {
|
||||
const diffstr = uniDiff.split(/\n/), list = [];
|
||||
let i = 0;
|
||||
function parseIndex() {
|
||||
const index = {};
|
||||
list.push(index);
|
||||
// Parse diff metadata
|
||||
while (i < diffstr.length) {
|
||||
const line = diffstr[i];
|
||||
// File header found, end parsing diff metadata
|
||||
if ((/^(---|\+\+\+|@@)\s/).test(line)) {
|
||||
break;
|
||||
}
|
||||
// Try to parse the line as a diff header, like
|
||||
// Index: README.md
|
||||
// or
|
||||
// diff -r 9117c6561b0b -r 273ce12ad8f1 .hgignore
|
||||
// or
|
||||
// Index: something with multiple words
|
||||
// and extract the filename (or whatever else is used as an index name)
|
||||
// from the end (i.e. 'README.md', '.hgignore', or
|
||||
// 'something with multiple words' in the examples above).
|
||||
//
|
||||
// TODO: It seems awkward that we indiscriminately trim off trailing
|
||||
// whitespace here. Theoretically, couldn't that be meaningful -
|
||||
// e.g. if the patch represents a diff of a file whose name ends
|
||||
// with a space? Seems wrong to nuke it.
|
||||
// But this behaviour has been around since v2.2.1 in 2015, so if
|
||||
// it's going to change, it should be done cautiously and in a new
|
||||
// major release, for backwards-compat reasons.
|
||||
// -- ExplodingCabbage
|
||||
const headerMatch = (/^(?:Index:|diff(?: -r \w+)+)\s+/).exec(line);
|
||||
if (headerMatch) {
|
||||
index.index = line.substring(headerMatch[0].length).trim();
|
||||
}
|
||||
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) {
|
||||
const 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) {
|
||||
const fileHeaderMatch = (/^(---|\+\+\+)\s+/).exec(diffstr[i]);
|
||||
if (fileHeaderMatch) {
|
||||
const prefix = fileHeaderMatch[1], data = diffstr[i].substring(3).trim().split('\t', 2), header = (data[1] || '').trim();
|
||||
let fileName = data[0].replace(/\\\\/g, '\\');
|
||||
if (fileName.startsWith('"') && fileName.endsWith('"')) {
|
||||
fileName = fileName.substr(1, fileName.length - 2);
|
||||
}
|
||||
if (prefix === '---') {
|
||||
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;
|
||||
const chunkHeaderIndex = i, chunkHeaderLine = diffstr[i++], chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/);
|
||||
const 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;
|
||||
}
|
||||
let 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++) {
|
||||
const 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 ${chunkHeaderIndex + 1} contained invalid line ${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;
|
||||
}
|
||||
23
.output/server/node_modules/diff/libesm/patch/reverse.js
generated
vendored
Normal file
23
.output/server/node_modules/diff/libesm/patch/reverse.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
export function reversePatch(structuredPatch) {
|
||||
if (Array.isArray(structuredPatch)) {
|
||||
// (See comment in unixToWin for why we need the pointless-looking anonymous function here)
|
||||
return structuredPatch.map(patch => reversePatch(patch)).reverse();
|
||||
}
|
||||
return Object.assign(Object.assign({}, structuredPatch), { oldFileName: structuredPatch.newFileName, oldHeader: structuredPatch.newHeader, newFileName: structuredPatch.oldFileName, newHeader: structuredPatch.oldHeader, hunks: structuredPatch.hunks.map(hunk => {
|
||||
return {
|
||||
oldLines: hunk.newLines,
|
||||
oldStart: hunk.newStart,
|
||||
newLines: hunk.oldLines,
|
||||
newStart: hunk.oldStart,
|
||||
lines: hunk.lines.map(l => {
|
||||
if (l.startsWith('-')) {
|
||||
return `+${l.slice(1)}`;
|
||||
}
|
||||
if (l.startsWith('+')) {
|
||||
return `-${l.slice(1)}`;
|
||||
}
|
||||
return l;
|
||||
})
|
||||
};
|
||||
}) });
|
||||
}
|
||||
Reference in New Issue
Block a user