@thxgg/steward 0.1.24 → 0.1.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/{Bc2V3wPK.js → B2ow85x_.js} +2 -2
  3. package/.output/public/_nuxt/{U78rMDmo.js → B6CbIr08.js} +1 -1
  4. package/.output/public/_nuxt/{BknRrWsw.js → BLQAF8wp.js} +1 -1
  5. package/.output/public/_nuxt/BXuwtOqb.js +1 -0
  6. package/.output/public/_nuxt/CAMiEhze.js +1 -0
  7. package/.output/public/_nuxt/{BRQ9Cxaw.js → CIBCqZF5.js} +1 -1
  8. package/.output/public/_nuxt/Ce0-nlm9.js +1 -0
  9. package/.output/public/_nuxt/{T11EuTtn.js → ConzneVY.js} +1 -1
  10. package/.output/public/_nuxt/D0qxz_Pn.js +1310 -0
  11. package/.output/public/_nuxt/D3PDtLSF.js +3 -0
  12. package/.output/public/_nuxt/{C73kduX-.js → DdKC0UAK.js} +1 -1
  13. package/.output/public/_nuxt/Detail.BGdvrJGh.css +1 -0
  14. package/.output/public/_nuxt/{C53_p0K1.js → Dkh9ic1y.js} +1 -1
  15. package/.output/public/_nuxt/LEjJTR7-.js +1 -0
  16. package/.output/public/_nuxt/{BTmXUZ_s.js → UqZfMfrZ.js} +1 -1
  17. package/.output/public/_nuxt/builds/latest.json +1 -1
  18. package/.output/public/_nuxt/builds/meta/25438e34-19a2-421d-aede-53fd18f1ccd4.json +1 -0
  19. package/.output/public/_nuxt/dckrK0oj.js +1 -0
  20. package/.output/public/_nuxt/entry.DT4p6_uW.css +1 -0
  21. package/.output/public/_nuxt/pIWeVmPw.js +1 -0
  22. package/.output/public/_nuxt/xrHaPo1U.js +60 -0
  23. package/.output/server/chunks/_/prd-service.mjs.map +1 -1
  24. package/.output/server/chunks/build/{Detail-DMMUwTWr.mjs → Detail-rpcemNXe.mjs} +674 -481
  25. package/.output/server/chunks/build/Detail-rpcemNXe.mjs.map +1 -0
  26. package/.output/server/chunks/build/DiffViewer-styles.B1FB5NJj.mjs +8 -0
  27. package/.output/server/chunks/build/DiffViewer-styles.B1FB5NJj.mjs.map +1 -0
  28. package/.output/server/chunks/build/{_prd_-ByugK4Yi.mjs → _prd_-CeibvZOH.mjs} +67 -233
  29. package/.output/server/chunks/build/_prd_-CeibvZOH.mjs.map +1 -0
  30. package/.output/server/chunks/build/client.precomputed.mjs +1 -1
  31. package/.output/server/chunks/build/{default-BKKgG7HJ.mjs → default-iq8SaDDN.mjs} +3 -3
  32. package/.output/server/chunks/build/default-iq8SaDDN.mjs.map +1 -0
  33. package/.output/server/chunks/build/{error-404-Bf6kdO80.mjs → error-404-DFale9A5.mjs} +2 -2
  34. package/.output/server/chunks/build/error-404-DFale9A5.mjs.map +1 -0
  35. package/.output/server/chunks/build/{index-DE1tjHAd.mjs → index-Po00RvHm.mjs} +2 -2
  36. package/.output/server/chunks/build/index-Po00RvHm.mjs.map +1 -0
  37. package/.output/server/chunks/build/{nuxt-link-SvT1nf8Z.mjs → nuxt-link-B4oWFn7n.mjs} +2 -2
  38. package/.output/server/chunks/build/nuxt-link-B4oWFn7n.mjs.map +1 -0
  39. package/.output/server/chunks/build/{repo-graph-DzT45gSB.mjs → repo-graph-BQVFpA-w.mjs} +5 -4
  40. package/.output/server/chunks/build/repo-graph-BQVFpA-w.mjs.map +1 -0
  41. package/.output/server/chunks/build/server.mjs +7 -7
  42. package/.output/server/chunks/build/styles.mjs +4 -5
  43. package/.output/server/chunks/build/{usePrd-hXZOmvAv.mjs → usePrd-Bb6jlnNZ.mjs} +2 -2
  44. package/.output/server/chunks/build/usePrd-Bb6jlnNZ.mjs.map +1 -0
  45. package/.output/server/chunks/nitro/nitro.mjs +983 -678
  46. package/.output/server/chunks/nitro/nitro.mjs.map +1 -1
  47. package/.output/server/node_modules/@pierre/diffs/dist/components/File.js +324 -0
  48. package/.output/server/node_modules/@pierre/diffs/dist/components/FileDiff.js +395 -0
  49. package/.output/server/node_modules/@pierre/diffs/dist/components/FileStream.js +161 -0
  50. package/.output/server/node_modules/@pierre/diffs/dist/components/web-components.js +25 -0
  51. package/.output/server/node_modules/@pierre/diffs/dist/constants.js +23 -0
  52. package/.output/server/node_modules/@pierre/diffs/dist/highlighter/languages/areLanguagesAttached.js +11 -0
  53. package/.output/server/node_modules/@pierre/diffs/dist/highlighter/languages/attachResolvedLanguages.js +20 -0
  54. package/.output/server/node_modules/@pierre/diffs/dist/highlighter/languages/cleanUpResolvedLanguages.js +11 -0
  55. package/.output/server/node_modules/@pierre/diffs/dist/highlighter/languages/constants.js +8 -0
  56. package/.output/server/node_modules/@pierre/diffs/dist/highlighter/languages/getResolvedLanguages.js +16 -0
  57. package/.output/server/node_modules/@pierre/diffs/dist/highlighter/languages/getResolvedOrResolveLanguage.js +11 -0
  58. package/.output/server/node_modules/@pierre/diffs/dist/highlighter/languages/hasResolvedLanguages.js +11 -0
  59. package/.output/server/node_modules/@pierre/diffs/dist/highlighter/languages/resolveLanguage.js +30 -0
  60. package/.output/server/node_modules/@pierre/diffs/dist/highlighter/languages/resolveLanguages.js +25 -0
  61. package/.output/server/node_modules/@pierre/diffs/dist/highlighter/shared_highlighter.js +71 -0
  62. package/.output/server/node_modules/@pierre/diffs/dist/highlighter/themes/areThemesAttached.js +12 -0
  63. package/.output/server/node_modules/@pierre/diffs/dist/highlighter/themes/attachResolvedThemes.js +24 -0
  64. package/.output/server/node_modules/@pierre/diffs/dist/highlighter/themes/cleanUpResolvedThemes.js +11 -0
  65. package/.output/server/node_modules/@pierre/diffs/dist/highlighter/themes/constants.js +9 -0
  66. package/.output/server/node_modules/@pierre/diffs/dist/highlighter/themes/getResolvedOrResolveTheme.js +11 -0
  67. package/.output/server/node_modules/@pierre/diffs/dist/highlighter/themes/getResolvedThemes.js +16 -0
  68. package/.output/server/node_modules/@pierre/diffs/dist/highlighter/themes/hasResolvedThemes.js +11 -0
  69. package/.output/server/node_modules/@pierre/diffs/dist/highlighter/themes/registerCustomCSSVariableTheme.js +18 -0
  70. package/.output/server/node_modules/@pierre/diffs/dist/highlighter/themes/registerCustomTheme.js +14 -0
  71. package/.output/server/node_modules/@pierre/diffs/dist/highlighter/themes/resolveTheme.js +35 -0
  72. package/.output/server/node_modules/@pierre/diffs/dist/highlighter/themes/resolveThemes.js +21 -0
  73. package/.output/server/node_modules/@pierre/diffs/dist/index.js +84 -0
  74. package/.output/server/node_modules/@pierre/diffs/dist/managers/LineSelectionManager.js +282 -0
  75. package/.output/server/node_modules/@pierre/diffs/dist/managers/MouseEventManager.js +244 -0
  76. package/.output/server/node_modules/@pierre/diffs/dist/managers/ResizeManager.js +132 -0
  77. package/.output/server/node_modules/@pierre/diffs/dist/managers/ScrollSyncManager.js +62 -0
  78. package/.output/server/node_modules/@pierre/diffs/dist/managers/UniversalRenderingManager.js +32 -0
  79. package/.output/server/node_modules/@pierre/diffs/dist/renderers/DiffHunksRenderer.js +655 -0
  80. package/.output/server/node_modules/@pierre/diffs/dist/renderers/FileRenderer.js +243 -0
  81. package/.output/server/node_modules/@pierre/diffs/dist/shiki-stream/stream.js +32 -0
  82. package/.output/server/node_modules/@pierre/diffs/dist/shiki-stream/tokenizer.js +71 -0
  83. package/.output/server/node_modules/@pierre/diffs/dist/sprite.js +55 -0
  84. package/.output/server/node_modules/@pierre/diffs/dist/style.js +6 -0
  85. package/.output/server/node_modules/@pierre/diffs/dist/themes/pierre-dark.js +1328 -0
  86. package/.output/server/node_modules/@pierre/diffs/dist/themes/pierre-light.js +1328 -0
  87. package/.output/server/node_modules/@pierre/diffs/dist/utils/areFilesEqual.js +8 -0
  88. package/.output/server/node_modules/@pierre/diffs/dist/utils/areObjectsEqual.js +18 -0
  89. package/.output/server/node_modules/@pierre/diffs/dist/utils/areOptionsEqual.js +12 -0
  90. package/.output/server/node_modules/@pierre/diffs/dist/utils/areSelectionsEqual.js +8 -0
  91. package/.output/server/node_modules/@pierre/diffs/dist/utils/areThemesEqual.js +9 -0
  92. package/.output/server/node_modules/@pierre/diffs/dist/utils/cleanLastNewline.js +8 -0
  93. package/.output/server/node_modules/@pierre/diffs/dist/utils/createAnnotationElement.js +21 -0
  94. package/.output/server/node_modules/@pierre/diffs/dist/utils/createAnnotationWrapperNode.js +12 -0
  95. package/.output/server/node_modules/@pierre/diffs/dist/utils/createCodeNode.js +12 -0
  96. package/.output/server/node_modules/@pierre/diffs/dist/utils/createEmptyRowBuffer.js +16 -0
  97. package/.output/server/node_modules/@pierre/diffs/dist/utils/createFileHeaderElement.js +84 -0
  98. package/.output/server/node_modules/@pierre/diffs/dist/utils/createHoverContentNode.js +15 -0
  99. package/.output/server/node_modules/@pierre/diffs/dist/utils/createNoNewlineElement.js +24 -0
  100. package/.output/server/node_modules/@pierre/diffs/dist/utils/createPreElement.js +28 -0
  101. package/.output/server/node_modules/@pierre/diffs/dist/utils/createRowNodes.js +20 -0
  102. package/.output/server/node_modules/@pierre/diffs/dist/utils/createSeparator.js +69 -0
  103. package/.output/server/node_modules/@pierre/diffs/dist/utils/createSpanNodeFromToken.js +13 -0
  104. package/.output/server/node_modules/@pierre/diffs/dist/utils/createStyleElement.js +19 -0
  105. package/.output/server/node_modules/@pierre/diffs/dist/utils/createTransformerWithState.js +56 -0
  106. package/.output/server/node_modules/@pierre/diffs/dist/utils/createUnsafeCSSStyleNode.js +12 -0
  107. package/.output/server/node_modules/@pierre/diffs/dist/utils/cssWrappers.js +21 -0
  108. package/.output/server/node_modules/@pierre/diffs/dist/utils/diffAcceptRejectHunk.js +82 -0
  109. package/.output/server/node_modules/@pierre/diffs/dist/utils/formatCSSVariablePrefix.js +8 -0
  110. package/.output/server/node_modules/@pierre/diffs/dist/utils/getFiletypeFromFileName.js +343 -0
  111. package/.output/server/node_modules/@pierre/diffs/dist/utils/getHighlighterOptions.js +13 -0
  112. package/.output/server/node_modules/@pierre/diffs/dist/utils/getHighlighterThemeStyles.js +40 -0
  113. package/.output/server/node_modules/@pierre/diffs/dist/utils/getHunkSeparatorSlotName.js +8 -0
  114. package/.output/server/node_modules/@pierre/diffs/dist/utils/getIconForType.js +15 -0
  115. package/.output/server/node_modules/@pierre/diffs/dist/utils/getLineAnnotationName.js +8 -0
  116. package/.output/server/node_modules/@pierre/diffs/dist/utils/getLineEndingType.js +11 -0
  117. package/.output/server/node_modules/@pierre/diffs/dist/utils/getLineNodes.js +15 -0
  118. package/.output/server/node_modules/@pierre/diffs/dist/utils/getSingularPatch.js +20 -0
  119. package/.output/server/node_modules/@pierre/diffs/dist/utils/getThemes.js +16 -0
  120. package/.output/server/node_modules/@pierre/diffs/dist/utils/getTotalLineCountFromHunks.js +10 -0
  121. package/.output/server/node_modules/@pierre/diffs/dist/utils/hast_utils.js +42 -0
  122. package/.output/server/node_modules/@pierre/diffs/dist/utils/isWorkerContext.js +8 -0
  123. package/.output/server/node_modules/@pierre/diffs/dist/utils/parseDiffDecorations.js +34 -0
  124. package/.output/server/node_modules/@pierre/diffs/dist/utils/parseDiffFromFile.js +23 -0
  125. package/.output/server/node_modules/@pierre/diffs/dist/utils/parseLineType.js +17 -0
  126. package/.output/server/node_modules/@pierre/diffs/dist/utils/parsePatchFiles.js +211 -0
  127. package/.output/server/node_modules/@pierre/diffs/dist/utils/prerenderHTMLIfNecessary.js +10 -0
  128. package/.output/server/node_modules/@pierre/diffs/dist/utils/processLine.js +42 -0
  129. package/.output/server/node_modules/@pierre/diffs/dist/utils/renderDiffWithHighlighter.js +339 -0
  130. package/.output/server/node_modules/@pierre/diffs/dist/utils/renderFileWithHighlighter.js +52 -0
  131. package/.output/server/node_modules/@pierre/diffs/dist/utils/setLanguageOverride.js +11 -0
  132. package/.output/server/node_modules/@pierre/diffs/dist/utils/setWrapperNodeProps.js +29 -0
  133. package/.output/server/node_modules/@pierre/diffs/package.json +89 -0
  134. package/.output/server/node_modules/@shikijs/transformers/dist/index.mjs +831 -0
  135. package/.output/server/node_modules/@shikijs/transformers/package.json +37 -0
  136. package/.output/server/node_modules/diff/libesm/convert/dmp.js +21 -0
  137. package/.output/server/node_modules/diff/libesm/convert/xml.js +31 -0
  138. package/.output/server/node_modules/diff/libesm/diff/array.js +16 -0
  139. package/.output/server/node_modules/diff/libesm/diff/base.js +253 -0
  140. package/.output/server/node_modules/diff/libesm/diff/character.js +7 -0
  141. package/.output/server/node_modules/diff/libesm/diff/css.js +10 -0
  142. package/.output/server/node_modules/diff/libesm/diff/json.js +78 -0
  143. package/.output/server/node_modules/diff/libesm/diff/line.js +65 -0
  144. package/.output/server/node_modules/diff/libesm/diff/sentence.js +43 -0
  145. package/.output/server/node_modules/diff/libesm/diff/word.js +296 -0
  146. package/.output/server/node_modules/diff/libesm/index.js +30 -0
  147. package/.output/server/node_modules/diff/libesm/package.json +1 -0
  148. package/.output/server/node_modules/diff/libesm/patch/apply.js +257 -0
  149. package/.output/server/node_modules/diff/libesm/patch/create.js +228 -0
  150. package/.output/server/node_modules/diff/libesm/patch/line-endings.js +44 -0
  151. package/.output/server/node_modules/diff/libesm/patch/parse.js +147 -0
  152. package/.output/server/node_modules/diff/libesm/patch/reverse.js +23 -0
  153. package/.output/server/node_modules/diff/libesm/util/distance-iterator.js +37 -0
  154. package/.output/server/node_modules/diff/libesm/util/params.js +14 -0
  155. package/.output/server/node_modules/diff/libesm/util/string.js +128 -0
  156. package/.output/server/node_modules/diff/package.json +132 -0
  157. package/.output/server/package.json +4 -1
  158. package/README.md +41 -0
  159. package/bin/prd +1 -1
  160. package/dist/host/src/index.js +10 -0
  161. package/dist/host/src/sync.js +201 -0
  162. package/dist/server/utils/db.js +64 -0
  163. package/dist/server/utils/git.js +8 -6
  164. package/dist/server/utils/prd-state.js +24 -2
  165. package/dist/server/utils/repos.js +12 -2
  166. package/dist/server/utils/state-migration.js +4 -3
  167. package/dist/server/utils/sync-apply.js +380 -0
  168. package/dist/server/utils/sync-export.js +183 -0
  169. package/dist/server/utils/sync-identity.js +231 -0
  170. package/dist/server/utils/sync-inspect.js +103 -0
  171. package/dist/server/utils/sync-merge.js +579 -0
  172. package/dist/server/utils/sync-schema.js +100 -0
  173. package/package.json +2 -1
  174. package/.output/public/_nuxt/6tINjQEd.js +0 -141
  175. package/.output/public/_nuxt/B2mIQf5X.js +0 -3
  176. package/.output/public/_nuxt/C0BBSDJ7.js +0 -1
  177. package/.output/public/_nuxt/CN46Bgts.js +0 -1
  178. package/.output/public/_nuxt/CTJgb0zb.js +0 -1
  179. package/.output/public/_nuxt/Cce168lk.js +0 -30
  180. package/.output/public/_nuxt/CyVSeLw5.js +0 -1
  181. package/.output/public/_nuxt/Detail.CYc96mGf.css +0 -1
  182. package/.output/public/_nuxt/ZNypZshD.js +0 -13
  183. package/.output/public/_nuxt/builds/meta/8c342d49-fe70-4f67-a987-821c16f86125.json +0 -1
  184. package/.output/public/_nuxt/entry.Bw0CE6Iz.css +0 -1
  185. package/.output/public/_nuxt/pYJYAY-W.js +0 -60
  186. package/.output/server/chunks/build/Detail-DMMUwTWr.mjs.map +0 -1
  187. package/.output/server/chunks/build/DiffViewer-styles-1.mjs-d2dQvARr.mjs +0 -4
  188. package/.output/server/chunks/build/DiffViewer-styles-1.mjs-d2dQvARr.mjs.map +0 -1
  189. package/.output/server/chunks/build/DiffViewer-styles-2.mjs-X6QKNjM0.mjs +0 -4
  190. package/.output/server/chunks/build/DiffViewer-styles-2.mjs-X6QKNjM0.mjs.map +0 -1
  191. package/.output/server/chunks/build/DiffViewer-styles.0AbHFl6N.mjs +0 -8
  192. package/.output/server/chunks/build/DiffViewer-styles.0AbHFl6N.mjs.map +0 -1
  193. package/.output/server/chunks/build/DiffViewer-styles.BDwAqkTk.mjs +0 -8
  194. package/.output/server/chunks/build/DiffViewer-styles.BDwAqkTk.mjs.map +0 -1
  195. package/.output/server/chunks/build/DiffViewer-styles.DRJh5Ui4.mjs +0 -10
  196. package/.output/server/chunks/build/DiffViewer-styles.DRJh5Ui4.mjs.map +0 -1
  197. package/.output/server/chunks/build/_prd_-ByugK4Yi.mjs.map +0 -1
  198. package/.output/server/chunks/build/default-BKKgG7HJ.mjs.map +0 -1
  199. package/.output/server/chunks/build/error-404-Bf6kdO80.mjs.map +0 -1
  200. package/.output/server/chunks/build/index-DE1tjHAd.mjs.map +0 -1
  201. package/.output/server/chunks/build/nuxt-link-SvT1nf8Z.mjs.map +0 -1
  202. package/.output/server/chunks/build/repo-graph-DzT45gSB.mjs.map +0 -1
  203. package/.output/server/chunks/build/usePrd-hXZOmvAv.mjs.map +0 -1
@@ -0,0 +1,296 @@
1
+ import Diff from './base.js';
2
+ import { longestCommonPrefix, longestCommonSuffix, replacePrefix, replaceSuffix, removePrefix, removeSuffix, maximumOverlap, leadingWs, trailingWs } from '../util/string.js';
3
+ // Based on https://en.wikipedia.org/wiki/Latin_script_in_Unicode
4
+ //
5
+ // Chars/ranges counted as "word" characters by this regex are as follows:
6
+ //
7
+ // + U+00AD Soft hyphen
8
+ // + 00C0–00FF (letters with diacritics from the Latin-1 Supplement), except:
9
+ // - U+00D7 × Multiplication sign
10
+ // - U+00F7 ÷ Division sign
11
+ // + Latin Extended-A, 0100–017F
12
+ // + Latin Extended-B, 0180–024F
13
+ // + IPA Extensions, 0250–02AF
14
+ // + Spacing Modifier Letters, 02B0–02FF, except:
15
+ // - U+02C7 ˇ ˇ Caron
16
+ // - U+02D8 ˘ ˘ Breve
17
+ // - U+02D9 ˙ ˙ Dot Above
18
+ // - U+02DA ˚ ˚ Ring Above
19
+ // - U+02DB ˛ ˛ Ogonek
20
+ // - U+02DC ˜ ˜ Small Tilde
21
+ // - U+02DD ˝ ˝ Double Acute Accent
22
+ // + Latin Extended Additional, 1E00–1EFF
23
+ const extendedWordChars = 'a-zA-Z0-9_\\u{AD}\\u{C0}-\\u{D6}\\u{D8}-\\u{F6}\\u{F8}-\\u{2C6}\\u{2C8}-\\u{2D7}\\u{2DE}-\\u{2FF}\\u{1E00}-\\u{1EFF}';
24
+ // Each token is one of the following:
25
+ // - A punctuation mark plus the surrounding whitespace
26
+ // - A word plus the surrounding whitespace
27
+ // - Pure whitespace (but only in the special case where the entire text
28
+ // is just whitespace)
29
+ //
30
+ // We have to include surrounding whitespace in the tokens because the two
31
+ // alternative approaches produce horribly broken results:
32
+ // * If we just discard the whitespace, we can't fully reproduce the original
33
+ // text from the sequence of tokens and any attempt to render the diff will
34
+ // get the whitespace wrong.
35
+ // * If we have separate tokens for whitespace, then in a typical text every
36
+ // second token will be a single space character. But this often results in
37
+ // the optimal diff between two texts being a perverse one that preserves
38
+ // the spaces between words but deletes and reinserts actual common words.
39
+ // See https://github.com/kpdecker/jsdiff/issues/160#issuecomment-1866099640
40
+ // for an example.
41
+ //
42
+ // Keeping the surrounding whitespace of course has implications for .equals
43
+ // and .join, not just .tokenize.
44
+ // This regex does NOT fully implement the tokenization rules described above.
45
+ // Instead, it gives runs of whitespace their own "token". The tokenize method
46
+ // then handles stitching whitespace tokens onto adjacent word or punctuation
47
+ // tokens.
48
+ const tokenizeIncludingWhitespace = new RegExp(`[${extendedWordChars}]+|\\s+|[^${extendedWordChars}]`, 'ug');
49
+ class WordDiff extends Diff {
50
+ equals(left, right, options) {
51
+ if (options.ignoreCase) {
52
+ left = left.toLowerCase();
53
+ right = right.toLowerCase();
54
+ }
55
+ return left.trim() === right.trim();
56
+ }
57
+ tokenize(value, options = {}) {
58
+ let parts;
59
+ if (options.intlSegmenter) {
60
+ const segmenter = options.intlSegmenter;
61
+ if (segmenter.resolvedOptions().granularity != 'word') {
62
+ throw new Error('The segmenter passed must have a granularity of "word"');
63
+ }
64
+ // We want `parts` to be an array whose elements alternate between being
65
+ // pure whitespace and being pure non-whitespace. This is ALMOST what the
66
+ // segments returned by a word-based Intl.Segmenter already look like,
67
+ // and therefore we can ALMOST get what we want by simply doing...
68
+ // parts = Array.from(segmenter.segment(value), segment => segment.segment);
69
+ // ... but not QUITE, because there's of one annoying special case: every
70
+ // newline character gets its own segment, instead of sharing a segment
71
+ // with other surrounding whitespace. We therefore need to manually merge
72
+ // consecutive segments of whitespace into a single part:
73
+ parts = [];
74
+ for (const segmentObj of Array.from(segmenter.segment(value))) {
75
+ const segment = segmentObj.segment;
76
+ if (parts.length && (/\s/).test(parts[parts.length - 1]) && (/\s/).test(segment)) {
77
+ parts[parts.length - 1] += segment;
78
+ }
79
+ else {
80
+ parts.push(segment);
81
+ }
82
+ }
83
+ }
84
+ else {
85
+ parts = value.match(tokenizeIncludingWhitespace) || [];
86
+ }
87
+ const tokens = [];
88
+ let prevPart = null;
89
+ parts.forEach(part => {
90
+ if ((/\s/).test(part)) {
91
+ if (prevPart == null) {
92
+ tokens.push(part);
93
+ }
94
+ else {
95
+ tokens.push(tokens.pop() + part);
96
+ }
97
+ }
98
+ else if (prevPart != null && (/\s/).test(prevPart)) {
99
+ if (tokens[tokens.length - 1] == prevPart) {
100
+ tokens.push(tokens.pop() + part);
101
+ }
102
+ else {
103
+ tokens.push(prevPart + part);
104
+ }
105
+ }
106
+ else {
107
+ tokens.push(part);
108
+ }
109
+ prevPart = part;
110
+ });
111
+ return tokens;
112
+ }
113
+ join(tokens) {
114
+ // Tokens being joined here will always have appeared consecutively in the
115
+ // same text, so we can simply strip off the leading whitespace from all the
116
+ // tokens except the first (and except any whitespace-only tokens - but such
117
+ // a token will always be the first and only token anyway) and then join them
118
+ // and the whitespace around words and punctuation will end up correct.
119
+ return tokens.map((token, i) => {
120
+ if (i == 0) {
121
+ return token;
122
+ }
123
+ else {
124
+ return token.replace((/^\s+/), '');
125
+ }
126
+ }).join('');
127
+ }
128
+ postProcess(changes, options) {
129
+ if (!changes || options.oneChangePerToken) {
130
+ return changes;
131
+ }
132
+ let lastKeep = null;
133
+ // Change objects representing any insertion or deletion since the last
134
+ // "keep" change object. There can be at most one of each.
135
+ let insertion = null;
136
+ let deletion = null;
137
+ changes.forEach(change => {
138
+ if (change.added) {
139
+ insertion = change;
140
+ }
141
+ else if (change.removed) {
142
+ deletion = change;
143
+ }
144
+ else {
145
+ if (insertion || deletion) { // May be false at start of text
146
+ dedupeWhitespaceInChangeObjects(lastKeep, deletion, insertion, change);
147
+ }
148
+ lastKeep = change;
149
+ insertion = null;
150
+ deletion = null;
151
+ }
152
+ });
153
+ if (insertion || deletion) {
154
+ dedupeWhitespaceInChangeObjects(lastKeep, deletion, insertion, null);
155
+ }
156
+ return changes;
157
+ }
158
+ }
159
+ export const wordDiff = new WordDiff();
160
+ export function diffWords(oldStr, newStr, options) {
161
+ // This option has never been documented and never will be (it's clearer to
162
+ // just call `diffWordsWithSpace` directly if you need that behavior), but
163
+ // has existed in jsdiff for a long time, so we retain support for it here
164
+ // for the sake of backwards compatibility.
165
+ if ((options === null || options === void 0 ? void 0 : options.ignoreWhitespace) != null && !options.ignoreWhitespace) {
166
+ return diffWordsWithSpace(oldStr, newStr, options);
167
+ }
168
+ return wordDiff.diff(oldStr, newStr, options);
169
+ }
170
+ function dedupeWhitespaceInChangeObjects(startKeep, deletion, insertion, endKeep) {
171
+ // Before returning, we tidy up the leading and trailing whitespace of the
172
+ // change objects to eliminate cases where trailing whitespace in one object
173
+ // is repeated as leading whitespace in the next.
174
+ // Below are examples of the outcomes we want here to explain the code.
175
+ // I=insert, K=keep, D=delete
176
+ // 1. diffing 'foo bar baz' vs 'foo baz'
177
+ // Prior to cleanup, we have K:'foo ' D:' bar ' K:' baz'
178
+ // After cleanup, we want: K:'foo ' D:'bar ' K:'baz'
179
+ //
180
+ // 2. Diffing 'foo bar baz' vs 'foo qux baz'
181
+ // Prior to cleanup, we have K:'foo ' D:' bar ' I:' qux ' K:' baz'
182
+ // After cleanup, we want K:'foo ' D:'bar' I:'qux' K:' baz'
183
+ //
184
+ // 3. Diffing 'foo\nbar baz' vs 'foo baz'
185
+ // Prior to cleanup, we have K:'foo ' D:'\nbar ' K:' baz'
186
+ // After cleanup, we want K'foo' D:'\nbar' K:' baz'
187
+ //
188
+ // 4. Diffing 'foo baz' vs 'foo\nbar baz'
189
+ // Prior to cleanup, we have K:'foo\n' I:'\nbar ' K:' baz'
190
+ // After cleanup, we ideally want K'foo' I:'\nbar' K:' baz'
191
+ // but don't actually manage this currently (the pre-cleanup change
192
+ // objects don't contain enough information to make it possible).
193
+ //
194
+ // 5. Diffing 'foo bar baz' vs 'foo baz'
195
+ // Prior to cleanup, we have K:'foo ' D:' bar ' K:' baz'
196
+ // After cleanup, we want K:'foo ' D:' bar ' K:'baz'
197
+ //
198
+ // Our handling is unavoidably imperfect in the case where there's a single
199
+ // indel between keeps and the whitespace has changed. For instance, consider
200
+ // diffing 'foo\tbar\nbaz' vs 'foo baz'. Unless we create an extra change
201
+ // object to represent the insertion of the space character (which isn't even
202
+ // a token), we have no way to avoid losing information about the texts'
203
+ // original whitespace in the result we return. Still, we do our best to
204
+ // output something that will look sensible if we e.g. print it with
205
+ // insertions in green and deletions in red.
206
+ // Between two "keep" change objects (or before the first or after the last
207
+ // change object), we can have either:
208
+ // * A "delete" followed by an "insert"
209
+ // * Just an "insert"
210
+ // * Just a "delete"
211
+ // We handle the three cases separately.
212
+ if (deletion && insertion) {
213
+ const oldWsPrefix = leadingWs(deletion.value);
214
+ const oldWsSuffix = trailingWs(deletion.value);
215
+ const newWsPrefix = leadingWs(insertion.value);
216
+ const newWsSuffix = trailingWs(insertion.value);
217
+ if (startKeep) {
218
+ const commonWsPrefix = longestCommonPrefix(oldWsPrefix, newWsPrefix);
219
+ startKeep.value = replaceSuffix(startKeep.value, newWsPrefix, commonWsPrefix);
220
+ deletion.value = removePrefix(deletion.value, commonWsPrefix);
221
+ insertion.value = removePrefix(insertion.value, commonWsPrefix);
222
+ }
223
+ if (endKeep) {
224
+ const commonWsSuffix = longestCommonSuffix(oldWsSuffix, newWsSuffix);
225
+ endKeep.value = replacePrefix(endKeep.value, newWsSuffix, commonWsSuffix);
226
+ deletion.value = removeSuffix(deletion.value, commonWsSuffix);
227
+ insertion.value = removeSuffix(insertion.value, commonWsSuffix);
228
+ }
229
+ }
230
+ else if (insertion) {
231
+ // The whitespaces all reflect what was in the new text rather than
232
+ // the old, so we essentially have no information about whitespace
233
+ // insertion or deletion. We just want to dedupe the whitespace.
234
+ // We do that by having each change object keep its trailing
235
+ // whitespace and deleting duplicate leading whitespace where
236
+ // present.
237
+ if (startKeep) {
238
+ const ws = leadingWs(insertion.value);
239
+ insertion.value = insertion.value.substring(ws.length);
240
+ }
241
+ if (endKeep) {
242
+ const ws = leadingWs(endKeep.value);
243
+ endKeep.value = endKeep.value.substring(ws.length);
244
+ }
245
+ // otherwise we've got a deletion and no insertion
246
+ }
247
+ else if (startKeep && endKeep) {
248
+ const newWsFull = leadingWs(endKeep.value), delWsStart = leadingWs(deletion.value), delWsEnd = trailingWs(deletion.value);
249
+ // Any whitespace that comes straight after startKeep in both the old and
250
+ // new texts, assign to startKeep and remove from the deletion.
251
+ const newWsStart = longestCommonPrefix(newWsFull, delWsStart);
252
+ deletion.value = removePrefix(deletion.value, newWsStart);
253
+ // Any whitespace that comes straight before endKeep in both the old and
254
+ // new texts, and hasn't already been assigned to startKeep, assign to
255
+ // endKeep and remove from the deletion.
256
+ const newWsEnd = longestCommonSuffix(removePrefix(newWsFull, newWsStart), delWsEnd);
257
+ deletion.value = removeSuffix(deletion.value, newWsEnd);
258
+ endKeep.value = replacePrefix(endKeep.value, newWsFull, newWsEnd);
259
+ // If there's any whitespace from the new text that HASN'T already been
260
+ // assigned, assign it to the start:
261
+ startKeep.value = replaceSuffix(startKeep.value, newWsFull, newWsFull.slice(0, newWsFull.length - newWsEnd.length));
262
+ }
263
+ else if (endKeep) {
264
+ // We are at the start of the text. Preserve all the whitespace on
265
+ // endKeep, and just remove whitespace from the end of deletion to the
266
+ // extent that it overlaps with the start of endKeep.
267
+ const endKeepWsPrefix = leadingWs(endKeep.value);
268
+ const deletionWsSuffix = trailingWs(deletion.value);
269
+ const overlap = maximumOverlap(deletionWsSuffix, endKeepWsPrefix);
270
+ deletion.value = removeSuffix(deletion.value, overlap);
271
+ }
272
+ else if (startKeep) {
273
+ // We are at the END of the text. Preserve all the whitespace on
274
+ // startKeep, and just remove whitespace from the start of deletion to
275
+ // the extent that it overlaps with the end of startKeep.
276
+ const startKeepWsSuffix = trailingWs(startKeep.value);
277
+ const deletionWsPrefix = leadingWs(deletion.value);
278
+ const overlap = maximumOverlap(startKeepWsSuffix, deletionWsPrefix);
279
+ deletion.value = removePrefix(deletion.value, overlap);
280
+ }
281
+ }
282
+ class WordsWithSpaceDiff extends Diff {
283
+ tokenize(value) {
284
+ // Slightly different to the tokenizeIncludingWhitespace regex used above in
285
+ // that this one treats each individual newline as a distinct token, rather
286
+ // than merging them into other surrounding whitespace. This was requested
287
+ // in https://github.com/kpdecker/jsdiff/issues/180 &
288
+ // https://github.com/kpdecker/jsdiff/issues/211
289
+ const regex = new RegExp(`(\\r?\\n)|[${extendedWordChars}]+|[^\\S\\n\\r]+|[^${extendedWordChars}]`, 'ug');
290
+ return value.match(regex) || [];
291
+ }
292
+ }
293
+ export const wordsWithSpaceDiff = new WordsWithSpaceDiff();
294
+ export function diffWordsWithSpace(oldStr, newStr, options) {
295
+ return wordsWithSpaceDiff.diff(oldStr, newStr, options);
296
+ }
@@ -0,0 +1,30 @@
1
+ /* See LICENSE file for terms of use */
2
+ /*
3
+ * Text diff implementation.
4
+ *
5
+ * This library supports the following APIs:
6
+ * Diff.diffChars: Character by character diff
7
+ * Diff.diffWords: Word (as defined by \b regex) diff which ignores whitespace
8
+ * Diff.diffLines: Line based diff
9
+ *
10
+ * Diff.diffCss: Diff targeted at CSS content
11
+ *
12
+ * These methods are based on the implementation proposed in
13
+ * "An O(ND) Difference Algorithm and its Variations" (Myers, 1986).
14
+ * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927
15
+ */
16
+ import Diff from './diff/base.js';
17
+ import { diffChars, characterDiff } from './diff/character.js';
18
+ import { diffWords, diffWordsWithSpace, wordDiff, wordsWithSpaceDiff } from './diff/word.js';
19
+ import { diffLines, diffTrimmedLines, lineDiff } from './diff/line.js';
20
+ import { diffSentences, sentenceDiff } from './diff/sentence.js';
21
+ import { diffCss, cssDiff } from './diff/css.js';
22
+ import { diffJson, canonicalize, jsonDiff } from './diff/json.js';
23
+ import { diffArrays, arrayDiff } from './diff/array.js';
24
+ import { applyPatch, applyPatches } from './patch/apply.js';
25
+ import { parsePatch } from './patch/parse.js';
26
+ import { reversePatch } from './patch/reverse.js';
27
+ import { structuredPatch, createTwoFilesPatch, createPatch, formatPatch, INCLUDE_HEADERS, FILE_HEADERS_ONLY, OMIT_HEADERS } from './patch/create.js';
28
+ import { convertChangesToDMP } from './convert/dmp.js';
29
+ import { convertChangesToXML } from './convert/xml.js';
30
+ export { Diff, diffChars, characterDiff, diffWords, wordDiff, diffWordsWithSpace, wordsWithSpaceDiff, diffLines, lineDiff, diffTrimmedLines, diffSentences, sentenceDiff, diffCss, cssDiff, diffJson, jsonDiff, diffArrays, arrayDiff, structuredPatch, createTwoFilesPatch, createPatch, formatPatch, INCLUDE_HEADERS, FILE_HEADERS_ONLY, OMIT_HEADERS, applyPatch, applyPatches, parsePatch, reversePatch, convertChangesToDMP, convertChangesToXML, canonicalize };
@@ -0,0 +1 @@
1
+ {"type":"module","sideEffects":false}
@@ -0,0 +1,257 @@
1
+ import { hasOnlyWinLineEndings, hasOnlyUnixLineEndings } from '../util/string.js';
2
+ import { isWin, isUnix, unixToWin, winToUnix } from './line-endings.js';
3
+ import { parsePatch } from './parse.js';
4
+ import distanceIterator from '../util/distance-iterator.js';
5
+ /**
6
+ * attempts to apply a unified diff patch.
7
+ *
8
+ * Hunks are applied first to last.
9
+ * `applyPatch` first tries to apply the first hunk at the line number specified in the hunk header, and with all context lines matching exactly.
10
+ * 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.
11
+ * 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.
12
+ * 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.
13
+ *
14
+ * Once a hunk is successfully fitted, the process begins again with the next hunk.
15
+ * Regardless of `fuzzFactor`, later hunks must be applied later in the file than earlier hunks.
16
+ *
17
+ * If a hunk cannot be successfully fitted *anywhere* with fewer than `fuzzFactor` mismatches, `applyPatch` fails and returns `false`.
18
+ *
19
+ * 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.
20
+ * (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.)
21
+ *
22
+ * If the patch was applied successfully, returns a string containing the patched text.
23
+ * 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.
24
+ *
25
+ * @param patch a string diff or the output from the `parsePatch` or `structuredPatch` methods.
26
+ */
27
+ export function applyPatch(source, patch, options = {}) {
28
+ let patches;
29
+ if (typeof patch === 'string') {
30
+ patches = parsePatch(patch);
31
+ }
32
+ else if (Array.isArray(patch)) {
33
+ patches = patch;
34
+ }
35
+ else {
36
+ patches = [patch];
37
+ }
38
+ if (patches.length > 1) {
39
+ throw new Error('applyPatch only works with a single input.');
40
+ }
41
+ return applyStructuredPatch(source, patches[0], options);
42
+ }
43
+ function applyStructuredPatch(source, patch, options = {}) {
44
+ if (options.autoConvertLineEndings || options.autoConvertLineEndings == null) {
45
+ if (hasOnlyWinLineEndings(source) && isUnix(patch)) {
46
+ patch = unixToWin(patch);
47
+ }
48
+ else if (hasOnlyUnixLineEndings(source) && isWin(patch)) {
49
+ patch = winToUnix(patch);
50
+ }
51
+ }
52
+ // Apply the diff to the input
53
+ const lines = source.split('\n'), hunks = patch.hunks, compareLine = options.compareLine || ((lineNumber, line, operation, patchContent) => line === patchContent), fuzzFactor = options.fuzzFactor || 0;
54
+ let minLine = 0;
55
+ if (fuzzFactor < 0 || !Number.isInteger(fuzzFactor)) {
56
+ throw new Error('fuzzFactor must be a non-negative integer');
57
+ }
58
+ // Special case for empty patch.
59
+ if (!hunks.length) {
60
+ return source;
61
+ }
62
+ // Before anything else, handle EOFNL insertion/removal. If the patch tells us to make a change
63
+ // to the EOFNL that is redundant/impossible - i.e. to remove a newline that's not there, or add a
64
+ // newline that already exists - then we either return false and fail to apply the patch (if
65
+ // fuzzFactor is 0) or simply ignore the problem and do nothing (if fuzzFactor is >0).
66
+ // If we do need to remove/add a newline at EOF, this will always be in the final hunk:
67
+ let prevLine = '', removeEOFNL = false, addEOFNL = false;
68
+ for (let i = 0; i < hunks[hunks.length - 1].lines.length; i++) {
69
+ const line = hunks[hunks.length - 1].lines[i];
70
+ if (line[0] == '\\') {
71
+ if (prevLine[0] == '+') {
72
+ removeEOFNL = true;
73
+ }
74
+ else if (prevLine[0] == '-') {
75
+ addEOFNL = true;
76
+ }
77
+ }
78
+ prevLine = line;
79
+ }
80
+ if (removeEOFNL) {
81
+ if (addEOFNL) {
82
+ // This means the final line gets changed but doesn't have a trailing newline in either the
83
+ // original or patched version. In that case, we do nothing if fuzzFactor > 0, and if
84
+ // fuzzFactor is 0, we simply validate that the source file has no trailing newline.
85
+ if (!fuzzFactor && lines[lines.length - 1] == '') {
86
+ return false;
87
+ }
88
+ }
89
+ else if (lines[lines.length - 1] == '') {
90
+ lines.pop();
91
+ }
92
+ else if (!fuzzFactor) {
93
+ return false;
94
+ }
95
+ }
96
+ else if (addEOFNL) {
97
+ if (lines[lines.length - 1] != '') {
98
+ lines.push('');
99
+ }
100
+ else if (!fuzzFactor) {
101
+ return false;
102
+ }
103
+ }
104
+ /**
105
+ * Checks if the hunk can be made to fit at the provided location with at most `maxErrors`
106
+ * insertions, substitutions, or deletions, while ensuring also that:
107
+ * - lines deleted in the hunk match exactly, and
108
+ * - wherever an insertion operation or block of insertion operations appears in the hunk, the
109
+ * immediately preceding and following lines of context match exactly
110
+ *
111
+ * `toPos` should be set such that lines[toPos] is meant to match hunkLines[0].
112
+ *
113
+ * If the hunk can be applied, returns an object with properties `oldLineLastI` and
114
+ * `replacementLines`. Otherwise, returns null.
115
+ */
116
+ function applyHunk(hunkLines, toPos, maxErrors, hunkLinesI = 0, lastContextLineMatched = true, patchedLines = [], patchedLinesLength = 0) {
117
+ let nConsecutiveOldContextLines = 0;
118
+ let nextContextLineMustMatch = false;
119
+ for (; hunkLinesI < hunkLines.length; hunkLinesI++) {
120
+ const hunkLine = hunkLines[hunkLinesI], operation = (hunkLine.length > 0 ? hunkLine[0] : ' '), content = (hunkLine.length > 0 ? hunkLine.substr(1) : hunkLine);
121
+ if (operation === '-') {
122
+ if (compareLine(toPos + 1, lines[toPos], operation, content)) {
123
+ toPos++;
124
+ nConsecutiveOldContextLines = 0;
125
+ }
126
+ else {
127
+ if (!maxErrors || lines[toPos] == null) {
128
+ return null;
129
+ }
130
+ patchedLines[patchedLinesLength] = lines[toPos];
131
+ return applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI, false, patchedLines, patchedLinesLength + 1);
132
+ }
133
+ }
134
+ if (operation === '+') {
135
+ if (!lastContextLineMatched) {
136
+ return null;
137
+ }
138
+ patchedLines[patchedLinesLength] = content;
139
+ patchedLinesLength++;
140
+ nConsecutiveOldContextLines = 0;
141
+ nextContextLineMustMatch = true;
142
+ }
143
+ if (operation === ' ') {
144
+ nConsecutiveOldContextLines++;
145
+ patchedLines[patchedLinesLength] = lines[toPos];
146
+ if (compareLine(toPos + 1, lines[toPos], operation, content)) {
147
+ patchedLinesLength++;
148
+ lastContextLineMatched = true;
149
+ nextContextLineMustMatch = false;
150
+ toPos++;
151
+ }
152
+ else {
153
+ if (nextContextLineMustMatch || !maxErrors) {
154
+ return null;
155
+ }
156
+ // Consider 3 possibilities in sequence:
157
+ // 1. lines contains a *substitution* not included in the patch context, or
158
+ // 2. lines contains an *insertion* not included in the patch context, or
159
+ // 3. lines contains a *deletion* not included in the patch context
160
+ // The first two options are of course only possible if the line from lines is non-null -
161
+ // i.e. only option 3 is possible if we've overrun the end of the old file.
162
+ 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));
163
+ }
164
+ }
165
+ }
166
+ // Before returning, trim any unmodified context lines off the end of patchedLines and reduce
167
+ // toPos (and thus oldLineLastI) accordingly. This allows later hunks to be applied to a region
168
+ // that starts in this hunk's trailing context.
169
+ patchedLinesLength -= nConsecutiveOldContextLines;
170
+ toPos -= nConsecutiveOldContextLines;
171
+ patchedLines.length = patchedLinesLength;
172
+ return {
173
+ patchedLines,
174
+ oldLineLastI: toPos - 1
175
+ };
176
+ }
177
+ const resultLines = [];
178
+ // Search best fit offsets for each hunk based on the previous ones
179
+ let prevHunkOffset = 0;
180
+ for (let i = 0; i < hunks.length; i++) {
181
+ const hunk = hunks[i];
182
+ let hunkResult;
183
+ const maxLine = lines.length - hunk.oldLines + fuzzFactor;
184
+ let toPos;
185
+ for (let maxErrors = 0; maxErrors <= fuzzFactor; maxErrors++) {
186
+ toPos = hunk.oldStart + prevHunkOffset - 1;
187
+ const iterator = distanceIterator(toPos, minLine, maxLine);
188
+ for (; toPos !== undefined; toPos = iterator()) {
189
+ hunkResult = applyHunk(hunk.lines, toPos, maxErrors);
190
+ if (hunkResult) {
191
+ break;
192
+ }
193
+ }
194
+ if (hunkResult) {
195
+ break;
196
+ }
197
+ }
198
+ if (!hunkResult) {
199
+ return false;
200
+ }
201
+ // Copy everything from the end of where we applied the last hunk to the start of this hunk
202
+ for (let i = minLine; i < toPos; i++) {
203
+ resultLines.push(lines[i]);
204
+ }
205
+ // Add the lines produced by applying the hunk:
206
+ for (let i = 0; i < hunkResult.patchedLines.length; i++) {
207
+ const line = hunkResult.patchedLines[i];
208
+ resultLines.push(line);
209
+ }
210
+ // Set lower text limit to end of the current hunk, so next ones don't try
211
+ // to fit over already patched text
212
+ minLine = hunkResult.oldLineLastI + 1;
213
+ // Note the offset between where the patch said the hunk should've applied and where we
214
+ // applied it, so we can adjust future hunks accordingly:
215
+ prevHunkOffset = toPos + 1 - hunk.oldStart;
216
+ }
217
+ // Copy over the rest of the lines from the old text
218
+ for (let i = minLine; i < lines.length; i++) {
219
+ resultLines.push(lines[i]);
220
+ }
221
+ return resultLines.join('\n');
222
+ }
223
+ /**
224
+ * applies one or more patches.
225
+ *
226
+ * `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).
227
+ *
228
+ * 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:
229
+ *
230
+ * - `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.
231
+ * - `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.
232
+ *
233
+ * Once all patches have been applied or an error occurs, the `options.complete(err)` callback is made.
234
+ */
235
+ export function applyPatches(uniDiff, options) {
236
+ const spDiff = typeof uniDiff === 'string' ? parsePatch(uniDiff) : uniDiff;
237
+ let currentIndex = 0;
238
+ function processIndex() {
239
+ const index = spDiff[currentIndex++];
240
+ if (!index) {
241
+ return options.complete();
242
+ }
243
+ options.loadFile(index, function (err, data) {
244
+ if (err) {
245
+ return options.complete(err);
246
+ }
247
+ const updatedContent = applyPatch(data, index, options);
248
+ options.patched(index, updatedContent, function (err) {
249
+ if (err) {
250
+ return options.complete(err);
251
+ }
252
+ processIndex();
253
+ });
254
+ });
255
+ }
256
+ processIndex();
257
+ }