markdown-patch 0.1.1 → 0.1.3

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 (58) hide show
  1. package/README.md +111 -0
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +108 -0
  5. package/dist/constants.d.ts +7 -0
  6. package/dist/constants.d.ts.map +1 -0
  7. package/dist/constants.js +15 -0
  8. package/dist/debug.d.ts +3 -0
  9. package/dist/debug.d.ts.map +1 -0
  10. package/dist/debug.js +50 -0
  11. package/dist/index.d.ts +3 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +2 -0
  14. package/dist/map.d.ts +3 -0
  15. package/dist/map.d.ts.map +1 -0
  16. package/dist/map.js +144 -0
  17. package/dist/patch.d.ts +19 -0
  18. package/dist/patch.d.ts.map +1 -0
  19. package/dist/patch.js +189 -0
  20. package/dist/tests/map.test.d.ts +2 -0
  21. package/dist/tests/map.test.d.ts.map +1 -0
  22. package/dist/tests/map.test.js +202 -0
  23. package/dist/tests/patch.test.d.ts +2 -0
  24. package/dist/tests/patch.test.d.ts.map +1 -0
  25. package/dist/tests/patch.test.js +223 -0
  26. package/dist/types.d.ts +95 -0
  27. package/dist/types.d.ts.map +1 -0
  28. package/dist/types.js +1 -0
  29. package/package.json +23 -3
  30. package/.tool-versions +0 -1
  31. package/.vscode/launch.json +0 -21
  32. package/document.md +0 -11
  33. package/document.mdpatch.json +0 -8
  34. package/jest.config.ts +0 -9
  35. package/src/cli.ts +0 -88
  36. package/src/constants.ts +0 -11
  37. package/src/debug.ts +0 -75
  38. package/src/index.ts +0 -9
  39. package/src/map.ts +0 -200
  40. package/src/patch.ts +0 -326
  41. package/src/tests/map.test.ts +0 -212
  42. package/src/tests/patch.test.ts +0 -297
  43. package/src/tests/sample.md +0 -81
  44. package/src/tests/sample.patch.block.append.md +0 -82
  45. package/src/tests/sample.patch.block.prepend.md +0 -82
  46. package/src/tests/sample.patch.block.replace.md +0 -81
  47. package/src/tests/sample.patch.block.targetBlockTypeBehavior.table.append.md +0 -82
  48. package/src/tests/sample.patch.block.targetBlockTypeBehavior.table.prepend.md +0 -82
  49. package/src/tests/sample.patch.block.targetBlockTypeBehavior.table.replace.md +0 -77
  50. package/src/tests/sample.patch.heading.append.md +0 -82
  51. package/src/tests/sample.patch.heading.document.append.md +0 -82
  52. package/src/tests/sample.patch.heading.document.prepend.md +0 -82
  53. package/src/tests/sample.patch.heading.prepend.md +0 -82
  54. package/src/tests/sample.patch.heading.replace.md +0 -81
  55. package/src/tests/sample.patch.heading.trimTargetWhitespace.append.md +0 -80
  56. package/src/tests/sample.patch.heading.trimTargetWhitespace.prepend.md +0 -80
  57. package/src/types.ts +0 -155
  58. package/tsconfig.json +0 -18
package/dist/patch.js ADDED
@@ -0,0 +1,189 @@
1
+ import { getDocumentMap } from "./map.js";
2
+ import * as marked from "marked";
3
+ import { ContentType } from "./constants.js";
4
+ export var PatchFailureReason;
5
+ (function (PatchFailureReason) {
6
+ PatchFailureReason["InvalidTarget"] = "invalid-target";
7
+ PatchFailureReason["ContentAlreadyPreexistsInTarget"] = "content-already-preexists-in-target";
8
+ PatchFailureReason["TableContentIncorrectColumnCount"] = "table-content-incorrect-column-count";
9
+ PatchFailureReason["RequestedBlockTypeBehaviorUnavailable"] = "requested-block-type-behavior-unavailable";
10
+ })(PatchFailureReason || (PatchFailureReason = {}));
11
+ export class PatchFailed extends Error {
12
+ constructor(reason, instruction, targetMap) {
13
+ super();
14
+ this.reason = reason;
15
+ this.instruction = instruction;
16
+ this.targetMap = targetMap;
17
+ this.name = "PatchFailed";
18
+ Object.setPrototypeOf(this, new.target.prototype);
19
+ }
20
+ }
21
+ export class PatchError extends Error {
22
+ }
23
+ const replaceText = (document, instruction, target) => {
24
+ return [
25
+ document.slice(0, target.content.start),
26
+ instruction.content,
27
+ document.slice(target.content.end),
28
+ ].join("");
29
+ };
30
+ const prependText = (document, instruction, target) => {
31
+ return [
32
+ document.slice(0, target.content.start),
33
+ instruction.content,
34
+ instruction.trimTargetWhitespace
35
+ ? document.slice(target.content.start).trimStart()
36
+ : document.slice(target.content.start),
37
+ ].join("");
38
+ };
39
+ const appendText = (document, instruction, target) => {
40
+ return [
41
+ instruction.trimTargetWhitespace
42
+ ? document.slice(0, target.content.end).trimEnd()
43
+ : document.slice(0, target.content.end),
44
+ instruction.content,
45
+ document.slice(target.content.end),
46
+ ].join("");
47
+ };
48
+ export class TablePartsNotFound extends Error {
49
+ }
50
+ const _getTableData = (document, target) => {
51
+ const targetTable = document.slice(target.content.start, target.content.end);
52
+ const tableToken = marked.lexer(targetTable)[0];
53
+ const match = /^(.*?)(?:\r?\n)(.*?)(\r?\n)/.exec(targetTable);
54
+ if (!(tableToken.type === "table") || !match) {
55
+ throw new TablePartsNotFound();
56
+ }
57
+ const lineEnding = match[3];
58
+ return {
59
+ token: tableToken,
60
+ lineEnding: match[3],
61
+ headerParts: match[1] + lineEnding + match[2] + lineEnding,
62
+ contentParts: targetTable.slice(match[0].length),
63
+ };
64
+ };
65
+ const replaceTable = (document, instruction, target) => {
66
+ try {
67
+ const table = _getTableData(document, target);
68
+ const tableRows = [table.headerParts];
69
+ for (const row of instruction.content) {
70
+ if (row.length !== table.token.header.length || typeof row === "string") {
71
+ throw new PatchFailed(PatchFailureReason.TableContentIncorrectColumnCount, instruction, target);
72
+ }
73
+ tableRows.push("| " + row.join(" | ") + " |" + table.lineEnding);
74
+ }
75
+ return [
76
+ document.slice(0, target.content.start),
77
+ tableRows.join(""),
78
+ document.slice(target.content.end),
79
+ ].join("");
80
+ }
81
+ catch (TablePartsNotFound) {
82
+ throw new PatchFailed(PatchFailureReason.RequestedBlockTypeBehaviorUnavailable, instruction, target);
83
+ }
84
+ };
85
+ const prependTable = (document, instruction, target) => {
86
+ try {
87
+ const table = _getTableData(document, target);
88
+ const tableRows = [table.headerParts];
89
+ for (const row of instruction.content) {
90
+ if (row.length !== table.token.header.length || typeof row === "string") {
91
+ throw new PatchFailed(PatchFailureReason.TableContentIncorrectColumnCount, instruction, target);
92
+ }
93
+ tableRows.push("| " + row.join(" | ") + " |" + table.lineEnding);
94
+ }
95
+ tableRows.push(table.contentParts);
96
+ return [
97
+ document.slice(0, target.content.start),
98
+ tableRows.join(""),
99
+ document.slice(target.content.end),
100
+ ].join("");
101
+ }
102
+ catch (TablePartsNotFound) {
103
+ throw new PatchFailed(PatchFailureReason.RequestedBlockTypeBehaviorUnavailable, instruction, target);
104
+ }
105
+ };
106
+ const appendTable = (document, instruction, target) => {
107
+ try {
108
+ const table = _getTableData(document, target);
109
+ const tableRows = [table.headerParts, table.contentParts];
110
+ for (const row of instruction.content) {
111
+ if (row.length !== table.token.header.length || typeof row === "string") {
112
+ throw new PatchFailed(PatchFailureReason.TableContentIncorrectColumnCount, instruction, target);
113
+ }
114
+ tableRows.push("| " + row.join(" | ") + " |" + table.lineEnding);
115
+ }
116
+ return [
117
+ document.slice(0, target.content.start),
118
+ tableRows.join(""),
119
+ document.slice(target.content.end),
120
+ ].join("");
121
+ }
122
+ catch (TablePartsNotFound) {
123
+ throw new PatchFailed(PatchFailureReason.RequestedBlockTypeBehaviorUnavailable, instruction, target);
124
+ }
125
+ };
126
+ const replace = (document, instruction, target) => {
127
+ const contentType = "contentType" in instruction && instruction.contentType
128
+ ? instruction.contentType
129
+ : ContentType.text;
130
+ switch (contentType) {
131
+ case ContentType.text:
132
+ return replaceText(document, instruction, target);
133
+ case ContentType.tableRows:
134
+ return replaceTable(document, instruction, target);
135
+ }
136
+ };
137
+ const prepend = (document, instruction, target) => {
138
+ const contentType = "contentType" in instruction && instruction.contentType
139
+ ? instruction.contentType
140
+ : ContentType.text;
141
+ switch (contentType) {
142
+ case ContentType.text:
143
+ return prependText(document, instruction, target);
144
+ case ContentType.tableRows:
145
+ return prependTable(document, instruction, target);
146
+ }
147
+ };
148
+ const append = (document, instruction, target) => {
149
+ const contentType = "contentType" in instruction && instruction.contentType
150
+ ? instruction.contentType
151
+ : ContentType.text;
152
+ switch (contentType) {
153
+ case ContentType.text:
154
+ return appendText(document, instruction, target);
155
+ case ContentType.tableRows:
156
+ return appendTable(document, instruction, target);
157
+ }
158
+ };
159
+ const getTarget = (map, instruction) => {
160
+ switch (instruction.targetType) {
161
+ case "heading":
162
+ return map.heading[instruction.target ? instruction.target.join("\u001f") : ""];
163
+ case "block":
164
+ return map.block[instruction.target];
165
+ }
166
+ };
167
+ export const applyPatch = (document, instruction) => {
168
+ const map = getDocumentMap(document);
169
+ const target = getTarget(map, instruction);
170
+ if (!target) {
171
+ throw new PatchFailed(PatchFailureReason.InvalidTarget, instruction, null);
172
+ }
173
+ if ((!("applyIfContentPreexists" in instruction) ||
174
+ !instruction.applyIfContentPreexists) &&
175
+ typeof instruction.content === "string" &&
176
+ document
177
+ .slice(target.content.start, target.content.end)
178
+ .includes(instruction.content.trim())) {
179
+ throw new PatchFailed(PatchFailureReason.ContentAlreadyPreexistsInTarget, instruction, target);
180
+ }
181
+ switch (instruction.operation) {
182
+ case "append":
183
+ return append(document, instruction, target);
184
+ case "prepend":
185
+ return prepend(document, instruction, target);
186
+ case "replace":
187
+ return replace(document, instruction, target);
188
+ }
189
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=map.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map.test.d.ts","sourceRoot":"","sources":["../../src/tests/map.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,202 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { getDocumentMap } from "../map";
4
+ describe("map", () => {
5
+ const sample = fs.readFileSync(path.join(__dirname, "sample.md"), "utf-8");
6
+ test("heading", () => {
7
+ const actualHeadings = getDocumentMap(sample).heading;
8
+ const expectedHeadings = {
9
+ "": {
10
+ content: {
11
+ start: 130,
12
+ end: 6988,
13
+ },
14
+ marker: {
15
+ start: 0,
16
+ end: 0,
17
+ },
18
+ level: 0,
19
+ },
20
+ Overview: {
21
+ content: {
22
+ start: 142,
23
+ end: 430,
24
+ },
25
+ marker: {
26
+ start: 131,
27
+ end: 142,
28
+ },
29
+ level: 1,
30
+ },
31
+ Problems: {
32
+ content: {
33
+ start: 441,
34
+ end: 1468,
35
+ },
36
+ marker: {
37
+ start: 430,
38
+ end: 441,
39
+ },
40
+ level: 1,
41
+ },
42
+ Actions: {
43
+ content: {
44
+ start: 1478,
45
+ end: 3182,
46
+ },
47
+ marker: {
48
+ start: 1468,
49
+ end: 1478,
50
+ },
51
+ level: 1,
52
+ },
53
+ Headers: {
54
+ content: {
55
+ start: 3192,
56
+ end: 4282,
57
+ },
58
+ marker: {
59
+ start: 3182,
60
+ end: 3192,
61
+ },
62
+ level: 1,
63
+ },
64
+ "Page Targets": {
65
+ content: {
66
+ start: 4297,
67
+ end: 6988,
68
+ },
69
+ marker: {
70
+ start: 4282,
71
+ end: 4297,
72
+ },
73
+ level: 1,
74
+ },
75
+ "Page Targets\u001fHeading": {
76
+ content: {
77
+ start: 4309,
78
+ end: 5251,
79
+ },
80
+ marker: {
81
+ start: 4298,
82
+ end: 4309,
83
+ },
84
+ level: 2,
85
+ },
86
+ "Page Targets\u001fBlock": {
87
+ content: {
88
+ start: 5260,
89
+ end: 6122,
90
+ },
91
+ marker: {
92
+ start: 5251,
93
+ end: 5260,
94
+ },
95
+ level: 2,
96
+ },
97
+ "Page Targets\u001fBlock\u001fUse Cases": {
98
+ content: {
99
+ start: 5778,
100
+ end: 6122,
101
+ },
102
+ marker: {
103
+ start: 5764,
104
+ end: 5778,
105
+ },
106
+ level: 3,
107
+ },
108
+ "Page Targets\u001fFrontmatter Field": {
109
+ content: {
110
+ start: 6143,
111
+ end: 6690,
112
+ },
113
+ marker: {
114
+ start: 6122,
115
+ end: 6143,
116
+ },
117
+ level: 2,
118
+ },
119
+ "Page Targets\u001fFrontmatter Field\u001fUse Cases": {
120
+ content: {
121
+ start: 6510,
122
+ end: 6690,
123
+ },
124
+ marker: {
125
+ start: 6496,
126
+ end: 6510,
127
+ },
128
+ level: 3,
129
+ },
130
+ "Page Targets\u001fDocument Properties (Exploratory)": {
131
+ content: {
132
+ start: 6727,
133
+ end: 6988,
134
+ },
135
+ marker: {
136
+ start: 6690,
137
+ end: 6727,
138
+ },
139
+ level: 2,
140
+ },
141
+ };
142
+ //console.log(JSON.stringify(actualHeadings, undefined, 4));
143
+ expect(actualHeadings).toEqual(expectedHeadings);
144
+ });
145
+ test("block", () => {
146
+ const actualBlocks = getDocumentMap(sample).block;
147
+ const expectedBlocks = {
148
+ "2c67a6": {
149
+ content: {
150
+ start: 1478,
151
+ end: 3172,
152
+ },
153
+ marker: {
154
+ start: 3173,
155
+ end: 3181,
156
+ },
157
+ },
158
+ "1d6271": {
159
+ content: {
160
+ start: 3192,
161
+ end: 4272,
162
+ },
163
+ marker: {
164
+ start: 4273,
165
+ end: 4281,
166
+ },
167
+ },
168
+ bfec1f: {
169
+ content: {
170
+ start: 4310,
171
+ end: 4606,
172
+ },
173
+ marker: {
174
+ start: 4607,
175
+ end: 4615,
176
+ },
177
+ },
178
+ "259a73": {
179
+ content: {
180
+ start: 6570,
181
+ end: 6633,
182
+ },
183
+ marker: {
184
+ start: 6633,
185
+ end: 6642,
186
+ },
187
+ },
188
+ e6068e: {
189
+ content: {
190
+ start: 6642,
191
+ end: 6681,
192
+ },
193
+ marker: {
194
+ start: 6681,
195
+ end: 6690,
196
+ },
197
+ },
198
+ };
199
+ //console.log(JSON.stringify(actualBlocks, undefined, 4));
200
+ expect(actualBlocks).toEqual(expectedBlocks);
201
+ });
202
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=patch.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patch.test.d.ts","sourceRoot":"","sources":["../../src/tests/patch.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,223 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { applyPatch, PatchFailed } from "../patch";
4
+ import { ContentType } from "../constants";
5
+ describe("patch", () => {
6
+ const sample = fs.readFileSync(path.join(__dirname, "sample.md"), "utf-8");
7
+ describe("heading", () => {
8
+ test("prepend", () => {
9
+ const expected = fs.readFileSync(path.join(__dirname, "sample.patch.heading.prepend.md"), "utf-8");
10
+ const instruction = {
11
+ targetType: "heading",
12
+ target: ["Overview"],
13
+ operation: "prepend",
14
+ content: "Beep Boop\n",
15
+ };
16
+ const actualResult = applyPatch(sample, instruction);
17
+ expect(actualResult).toEqual(expected);
18
+ });
19
+ test("append", () => {
20
+ const expected = fs.readFileSync(path.join(__dirname, "sample.patch.heading.append.md"), "utf-8");
21
+ const instruction = {
22
+ targetType: "heading",
23
+ target: ["Overview"],
24
+ operation: "append",
25
+ content: "Beep Boop\n",
26
+ };
27
+ const actualResult = applyPatch(sample, instruction);
28
+ expect(actualResult).toEqual(expected);
29
+ });
30
+ test("replace", () => {
31
+ const expected = fs.readFileSync(path.join(__dirname, "sample.patch.heading.replace.md"), "utf-8");
32
+ const instruction = {
33
+ targetType: "heading",
34
+ target: ["Overview"],
35
+ operation: "replace",
36
+ content: "Beep Boop\n",
37
+ };
38
+ const actualResult = applyPatch(sample, instruction);
39
+ expect(actualResult).toEqual(expected);
40
+ });
41
+ describe("document", () => {
42
+ test("prepend", () => {
43
+ const expected = fs.readFileSync(path.join(__dirname, "sample.patch.heading.document.prepend.md"), "utf-8");
44
+ const instruction = {
45
+ targetType: "heading",
46
+ target: null,
47
+ operation: "prepend",
48
+ content: "Beep Boop\n",
49
+ };
50
+ const actualResult = applyPatch(sample, instruction);
51
+ expect(actualResult).toEqual(expected);
52
+ });
53
+ test("append", () => {
54
+ const expected = fs.readFileSync(path.join(__dirname, "sample.patch.heading.document.append.md"), "utf-8");
55
+ const instruction = {
56
+ targetType: "heading",
57
+ target: null,
58
+ operation: "append",
59
+ content: "Beep Boop\n",
60
+ };
61
+ const actualResult = applyPatch(sample, instruction);
62
+ expect(actualResult).toEqual(expected);
63
+ });
64
+ });
65
+ });
66
+ describe("parameter", () => {
67
+ describe("trimTargetWhitespace", () => {
68
+ describe("heading", () => {
69
+ test("prepend", () => {
70
+ const expected = fs.readFileSync(path.join(__dirname, "sample.patch.heading.trimTargetWhitespace.prepend.md"), "utf-8");
71
+ const instruction = {
72
+ targetType: "heading",
73
+ target: ["Page Targets", "Document Properties (Exploratory)"],
74
+ operation: "prepend",
75
+ content: "Beep Boop",
76
+ trimTargetWhitespace: true,
77
+ };
78
+ const actualResult = applyPatch(sample, instruction);
79
+ expect(actualResult).toEqual(expected);
80
+ });
81
+ test("append", () => {
82
+ const expected = fs.readFileSync(path.join(__dirname, "sample.patch.heading.trimTargetWhitespace.append.md"), "utf-8");
83
+ const instruction = {
84
+ targetType: "heading",
85
+ target: ["Problems"],
86
+ operation: "append",
87
+ content: "Beep Boop\n",
88
+ trimTargetWhitespace: true,
89
+ };
90
+ const actualResult = applyPatch(sample, instruction);
91
+ expect(actualResult).toEqual(expected);
92
+ });
93
+ });
94
+ });
95
+ describe("applyIfContentPreexists", () => {
96
+ describe("disabled (default)", () => {
97
+ describe("heading", () => {
98
+ test("preexists at target", () => {
99
+ const instruction = {
100
+ targetType: "heading",
101
+ target: ["Page Targets"],
102
+ operation: "append",
103
+ content: "## Frontmatter Field",
104
+ // applyIfContentPreexists: false, # default
105
+ };
106
+ expect(() => {
107
+ applyPatch(sample, instruction);
108
+ }).toThrow(PatchFailed);
109
+ });
110
+ test("does not preexist at target", () => {
111
+ const instruction = {
112
+ targetType: "heading",
113
+ target: ["Headers"],
114
+ operation: "append",
115
+ content: "## Frontmatter Field",
116
+ // applyIfContentPreexists: false, # default
117
+ };
118
+ expect(() => {
119
+ applyPatch(sample, instruction);
120
+ }).not.toThrow(PatchFailed);
121
+ });
122
+ });
123
+ });
124
+ describe("enabled", () => {
125
+ describe("heading", () => {
126
+ test("preexists at target", () => {
127
+ const instruction = {
128
+ targetType: "heading",
129
+ target: ["Page Targets"],
130
+ operation: "append",
131
+ content: "## Frontmatter Field",
132
+ applyIfContentPreexists: true,
133
+ };
134
+ expect(() => {
135
+ applyPatch(sample, instruction);
136
+ }).not.toThrow(PatchFailed);
137
+ });
138
+ });
139
+ });
140
+ });
141
+ });
142
+ describe("block", () => {
143
+ test("prepend", () => {
144
+ const expected = fs.readFileSync(path.join(__dirname, "sample.patch.block.prepend.md"), "utf-8");
145
+ const instruction = {
146
+ targetType: "block",
147
+ target: "e6068e",
148
+ operation: "prepend",
149
+ content: "- OK\n",
150
+ };
151
+ const actualResult = applyPatch(sample, instruction);
152
+ expect(actualResult).toEqual(expected);
153
+ });
154
+ test("append", () => {
155
+ const expected = fs.readFileSync(path.join(__dirname, "sample.patch.block.append.md"), "utf-8");
156
+ const instruction = {
157
+ targetType: "block",
158
+ target: "e6068e",
159
+ operation: "append",
160
+ content: "\n- OK",
161
+ };
162
+ const actualResult = applyPatch(sample, instruction);
163
+ expect(actualResult).toEqual(expected);
164
+ });
165
+ test("replace", () => {
166
+ const expected = fs.readFileSync(path.join(__dirname, "sample.patch.block.replace.md"), "utf-8");
167
+ const instruction = {
168
+ targetType: "block",
169
+ target: "259a73",
170
+ operation: "replace",
171
+ content: "- OK",
172
+ };
173
+ const actualResult = applyPatch(sample, instruction);
174
+ expect(actualResult).toEqual(expected);
175
+ });
176
+ describe("tagetBlockTypeBehavior", () => {
177
+ describe("table", () => {
178
+ test("prepend", () => {
179
+ const expected = fs.readFileSync(path.join(__dirname, "sample.patch.block.targetBlockTypeBehavior.table.prepend.md"), "utf-8");
180
+ const instruction = {
181
+ targetType: "block",
182
+ target: "2c67a6",
183
+ operation: "prepend",
184
+ contentType: ContentType.tableRows,
185
+ content: [
186
+ ["`something else`", "Some other application", "✅", "✅", "✅"],
187
+ ],
188
+ };
189
+ const actualResult = applyPatch(sample, instruction);
190
+ expect(actualResult).toEqual(expected);
191
+ });
192
+ test("append", () => {
193
+ const expected = fs.readFileSync(path.join(__dirname, "sample.patch.block.targetBlockTypeBehavior.table.append.md"), "utf-8");
194
+ const instruction = {
195
+ targetType: "block",
196
+ target: "2c67a6",
197
+ operation: "append",
198
+ contentType: ContentType.tableRows,
199
+ content: [
200
+ ["`something else`", "Some other application", "✅", "✅", "✅"],
201
+ ],
202
+ };
203
+ const actualResult = applyPatch(sample, instruction);
204
+ expect(actualResult).toEqual(expected);
205
+ });
206
+ test("replace", () => {
207
+ const expected = fs.readFileSync(path.join(__dirname, "sample.patch.block.targetBlockTypeBehavior.table.replace.md"), "utf-8");
208
+ const instruction = {
209
+ targetType: "block",
210
+ target: "2c67a6",
211
+ operation: "replace",
212
+ contentType: ContentType.tableRows,
213
+ content: [
214
+ ["`something else`", "Some other application", "✅", "✅", "✅"],
215
+ ],
216
+ };
217
+ const actualResult = applyPatch(sample, instruction);
218
+ expect(actualResult).toEqual(expected);
219
+ });
220
+ });
221
+ });
222
+ });
223
+ });