markdown-patch 0.1.1 → 0.1.2
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.
- package/README.md +111 -0
- package/dist/cli.js +108 -0
- package/{src/constants.ts → dist/constants.js} +7 -8
- package/dist/debug.js +50 -0
- package/dist/index.js +1 -0
- package/dist/map.js +144 -0
- package/dist/patch.js +191 -0
- package/dist/tests/map.test.js +202 -0
- package/dist/tests/patch.test.js +222 -0
- package/dist/types.js +1 -0
- package/package.json +7 -2
- package/.tool-versions +0 -1
- package/.vscode/launch.json +0 -21
- package/document.md +0 -11
- package/document.mdpatch.json +0 -8
- package/jest.config.ts +0 -9
- package/src/cli.ts +0 -88
- package/src/debug.ts +0 -75
- package/src/index.ts +0 -9
- package/src/map.ts +0 -200
- package/src/patch.ts +0 -326
- package/src/tests/map.test.ts +0 -212
- package/src/tests/patch.test.ts +0 -297
- package/src/tests/sample.md +0 -81
- package/src/tests/sample.patch.block.append.md +0 -82
- package/src/tests/sample.patch.block.prepend.md +0 -82
- package/src/tests/sample.patch.block.replace.md +0 -81
- package/src/tests/sample.patch.block.targetBlockTypeBehavior.table.append.md +0 -82
- package/src/tests/sample.patch.block.targetBlockTypeBehavior.table.prepend.md +0 -82
- package/src/tests/sample.patch.block.targetBlockTypeBehavior.table.replace.md +0 -77
- package/src/tests/sample.patch.heading.append.md +0 -82
- package/src/tests/sample.patch.heading.document.append.md +0 -82
- package/src/tests/sample.patch.heading.document.prepend.md +0 -82
- package/src/tests/sample.patch.heading.prepend.md +0 -82
- package/src/tests/sample.patch.heading.replace.md +0 -81
- package/src/tests/sample.patch.heading.trimTargetWhitespace.append.md +0 -80
- package/src/tests/sample.patch.heading.trimTargetWhitespace.prepend.md +0 -80
- package/src/types.ts +0 -155
- package/tsconfig.json +0 -18
|
@@ -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,222 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { applyPatch, PatchFailed } from "../patch";
|
|
4
|
+
describe("patch", () => {
|
|
5
|
+
const sample = fs.readFileSync(path.join(__dirname, "sample.md"), "utf-8");
|
|
6
|
+
describe("heading", () => {
|
|
7
|
+
test("prepend", () => {
|
|
8
|
+
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.heading.prepend.md"), "utf-8");
|
|
9
|
+
const instruction = {
|
|
10
|
+
targetType: "heading",
|
|
11
|
+
target: ["Overview"],
|
|
12
|
+
operation: "prepend",
|
|
13
|
+
content: "Beep Boop\n",
|
|
14
|
+
};
|
|
15
|
+
const actualResult = applyPatch(sample, instruction);
|
|
16
|
+
expect(actualResult).toEqual(expected);
|
|
17
|
+
});
|
|
18
|
+
test("append", () => {
|
|
19
|
+
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.heading.append.md"), "utf-8");
|
|
20
|
+
const instruction = {
|
|
21
|
+
targetType: "heading",
|
|
22
|
+
target: ["Overview"],
|
|
23
|
+
operation: "append",
|
|
24
|
+
content: "Beep Boop\n",
|
|
25
|
+
};
|
|
26
|
+
const actualResult = applyPatch(sample, instruction);
|
|
27
|
+
expect(actualResult).toEqual(expected);
|
|
28
|
+
});
|
|
29
|
+
test("replace", () => {
|
|
30
|
+
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.heading.replace.md"), "utf-8");
|
|
31
|
+
const instruction = {
|
|
32
|
+
targetType: "heading",
|
|
33
|
+
target: ["Overview"],
|
|
34
|
+
operation: "replace",
|
|
35
|
+
content: "Beep Boop\n",
|
|
36
|
+
};
|
|
37
|
+
const actualResult = applyPatch(sample, instruction);
|
|
38
|
+
expect(actualResult).toEqual(expected);
|
|
39
|
+
});
|
|
40
|
+
describe("document", () => {
|
|
41
|
+
test("prepend", () => {
|
|
42
|
+
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.heading.document.prepend.md"), "utf-8");
|
|
43
|
+
const instruction = {
|
|
44
|
+
targetType: "heading",
|
|
45
|
+
target: null,
|
|
46
|
+
operation: "prepend",
|
|
47
|
+
content: "Beep Boop\n",
|
|
48
|
+
};
|
|
49
|
+
const actualResult = applyPatch(sample, instruction);
|
|
50
|
+
expect(actualResult).toEqual(expected);
|
|
51
|
+
});
|
|
52
|
+
test("append", () => {
|
|
53
|
+
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.heading.document.append.md"), "utf-8");
|
|
54
|
+
const instruction = {
|
|
55
|
+
targetType: "heading",
|
|
56
|
+
target: null,
|
|
57
|
+
operation: "append",
|
|
58
|
+
content: "Beep Boop\n",
|
|
59
|
+
};
|
|
60
|
+
const actualResult = applyPatch(sample, instruction);
|
|
61
|
+
expect(actualResult).toEqual(expected);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
describe("parameter", () => {
|
|
66
|
+
describe("trimTargetWhitespace", () => {
|
|
67
|
+
describe("heading", () => {
|
|
68
|
+
test("prepend", () => {
|
|
69
|
+
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.heading.trimTargetWhitespace.prepend.md"), "utf-8");
|
|
70
|
+
const instruction = {
|
|
71
|
+
targetType: "heading",
|
|
72
|
+
target: ["Page Targets", "Document Properties (Exploratory)"],
|
|
73
|
+
operation: "prepend",
|
|
74
|
+
content: "Beep Boop",
|
|
75
|
+
trimTargetWhitespace: true,
|
|
76
|
+
};
|
|
77
|
+
const actualResult = applyPatch(sample, instruction);
|
|
78
|
+
expect(actualResult).toEqual(expected);
|
|
79
|
+
});
|
|
80
|
+
test("append", () => {
|
|
81
|
+
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.heading.trimTargetWhitespace.append.md"), "utf-8");
|
|
82
|
+
const instruction = {
|
|
83
|
+
targetType: "heading",
|
|
84
|
+
target: ["Problems"],
|
|
85
|
+
operation: "append",
|
|
86
|
+
content: "Beep Boop\n",
|
|
87
|
+
trimTargetWhitespace: true,
|
|
88
|
+
};
|
|
89
|
+
const actualResult = applyPatch(sample, instruction);
|
|
90
|
+
expect(actualResult).toEqual(expected);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
describe("applyIfContentPreexists", () => {
|
|
95
|
+
describe("disabled (default)", () => {
|
|
96
|
+
describe("heading", () => {
|
|
97
|
+
test("preexists at target", () => {
|
|
98
|
+
const instruction = {
|
|
99
|
+
targetType: "heading",
|
|
100
|
+
target: ["Page Targets"],
|
|
101
|
+
operation: "append",
|
|
102
|
+
content: "## Frontmatter Field",
|
|
103
|
+
// applyIfContentPreexists: false, # default
|
|
104
|
+
};
|
|
105
|
+
expect(() => {
|
|
106
|
+
applyPatch(sample, instruction);
|
|
107
|
+
}).toThrow(PatchFailed);
|
|
108
|
+
});
|
|
109
|
+
test("does not preexist at target", () => {
|
|
110
|
+
const instruction = {
|
|
111
|
+
targetType: "heading",
|
|
112
|
+
target: ["Headers"],
|
|
113
|
+
operation: "append",
|
|
114
|
+
content: "## Frontmatter Field",
|
|
115
|
+
// applyIfContentPreexists: false, # default
|
|
116
|
+
};
|
|
117
|
+
expect(() => {
|
|
118
|
+
applyPatch(sample, instruction);
|
|
119
|
+
}).not.toThrow(PatchFailed);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
describe("enabled", () => {
|
|
124
|
+
describe("heading", () => {
|
|
125
|
+
test("preexists at target", () => {
|
|
126
|
+
const instruction = {
|
|
127
|
+
targetType: "heading",
|
|
128
|
+
target: ["Page Targets"],
|
|
129
|
+
operation: "append",
|
|
130
|
+
content: "## Frontmatter Field",
|
|
131
|
+
applyIfContentPreexists: true,
|
|
132
|
+
};
|
|
133
|
+
expect(() => {
|
|
134
|
+
applyPatch(sample, instruction);
|
|
135
|
+
}).not.toThrow(PatchFailed);
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
describe("block", () => {
|
|
142
|
+
test("prepend", () => {
|
|
143
|
+
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.block.prepend.md"), "utf-8");
|
|
144
|
+
const instruction = {
|
|
145
|
+
targetType: "block",
|
|
146
|
+
target: "e6068e",
|
|
147
|
+
operation: "prepend",
|
|
148
|
+
content: "- OK\n",
|
|
149
|
+
};
|
|
150
|
+
const actualResult = applyPatch(sample, instruction);
|
|
151
|
+
expect(actualResult).toEqual(expected);
|
|
152
|
+
});
|
|
153
|
+
test("append", () => {
|
|
154
|
+
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.block.append.md"), "utf-8");
|
|
155
|
+
const instruction = {
|
|
156
|
+
targetType: "block",
|
|
157
|
+
target: "e6068e",
|
|
158
|
+
operation: "append",
|
|
159
|
+
content: "\n- OK",
|
|
160
|
+
};
|
|
161
|
+
const actualResult = applyPatch(sample, instruction);
|
|
162
|
+
expect(actualResult).toEqual(expected);
|
|
163
|
+
});
|
|
164
|
+
test("replace", () => {
|
|
165
|
+
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.block.replace.md"), "utf-8");
|
|
166
|
+
const instruction = {
|
|
167
|
+
targetType: "block",
|
|
168
|
+
target: "259a73",
|
|
169
|
+
operation: "replace",
|
|
170
|
+
content: "- OK",
|
|
171
|
+
};
|
|
172
|
+
const actualResult = applyPatch(sample, instruction);
|
|
173
|
+
expect(actualResult).toEqual(expected);
|
|
174
|
+
});
|
|
175
|
+
describe("tagetBlockTypeBehavior", () => {
|
|
176
|
+
describe("table", () => {
|
|
177
|
+
test("prepend", () => {
|
|
178
|
+
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.block.targetBlockTypeBehavior.table.prepend.md"), "utf-8");
|
|
179
|
+
const instruction = {
|
|
180
|
+
targetType: "block",
|
|
181
|
+
targetBlockTypeBehavior: "table",
|
|
182
|
+
target: "2c67a6",
|
|
183
|
+
operation: "prepend",
|
|
184
|
+
content: [
|
|
185
|
+
["`something else`", "Some other application", "✅", "✅", "✅"],
|
|
186
|
+
],
|
|
187
|
+
};
|
|
188
|
+
const actualResult = applyPatch(sample, instruction);
|
|
189
|
+
expect(actualResult).toEqual(expected);
|
|
190
|
+
});
|
|
191
|
+
test("append", () => {
|
|
192
|
+
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.block.targetBlockTypeBehavior.table.append.md"), "utf-8");
|
|
193
|
+
const instruction = {
|
|
194
|
+
targetType: "block",
|
|
195
|
+
targetBlockTypeBehavior: "table",
|
|
196
|
+
target: "2c67a6",
|
|
197
|
+
operation: "append",
|
|
198
|
+
content: [
|
|
199
|
+
["`something else`", "Some other application", "✅", "✅", "✅"],
|
|
200
|
+
],
|
|
201
|
+
};
|
|
202
|
+
const actualResult = applyPatch(sample, instruction);
|
|
203
|
+
expect(actualResult).toEqual(expected);
|
|
204
|
+
});
|
|
205
|
+
test("replace", () => {
|
|
206
|
+
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.block.targetBlockTypeBehavior.table.replace.md"), "utf-8");
|
|
207
|
+
const instruction = {
|
|
208
|
+
targetType: "block",
|
|
209
|
+
targetBlockTypeBehavior: "table",
|
|
210
|
+
target: "2c67a6",
|
|
211
|
+
operation: "replace",
|
|
212
|
+
content: [
|
|
213
|
+
["`something else`", "Some other application", "✅", "✅", "✅"],
|
|
214
|
+
],
|
|
215
|
+
};
|
|
216
|
+
const actualResult = applyPatch(sample, instruction);
|
|
217
|
+
expect(actualResult).toEqual(expected);
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
});
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -15,9 +15,10 @@
|
|
|
15
15
|
"typescript": "^5.5.4"
|
|
16
16
|
},
|
|
17
17
|
"name": "markdown-patch",
|
|
18
|
-
"version": "0.1.
|
|
18
|
+
"version": "0.1.2",
|
|
19
19
|
"main": "./dist/index.js",
|
|
20
20
|
"scripts": {
|
|
21
|
+
"build": "npx tsc",
|
|
21
22
|
"test": "node node_modules/.bin/jest"
|
|
22
23
|
},
|
|
23
24
|
"bin": {
|
|
@@ -27,5 +28,9 @@
|
|
|
27
28
|
"author": "",
|
|
28
29
|
"license": "ISC",
|
|
29
30
|
"description": "Change markdown documents by inserting or changing content relative to headings or other parts of a document's structure.",
|
|
30
|
-
"type": "module"
|
|
31
|
+
"type": "module",
|
|
32
|
+
"files": [
|
|
33
|
+
"dist/",
|
|
34
|
+
"README.md"
|
|
35
|
+
]
|
|
31
36
|
}
|
package/.tool-versions
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
nodejs 20.8.0
|
package/.vscode/launch.json
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
// Use IntelliSense to learn about possible attributes.
|
|
3
|
-
// Hover to view descriptions of existing attributes.
|
|
4
|
-
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
-
"version": "0.2.0",
|
|
6
|
-
"configurations": [
|
|
7
|
-
{
|
|
8
|
-
"type": "node",
|
|
9
|
-
"request": "launch",
|
|
10
|
-
"name": "Jest All",
|
|
11
|
-
//"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/jest",
|
|
12
|
-
"args": [
|
|
13
|
-
"--runInBand"
|
|
14
|
-
],
|
|
15
|
-
"console": "integratedTerminal",
|
|
16
|
-
"internalConsoleOptions": "neverOpen",
|
|
17
|
-
"program": "${workspaceFolder}/node_modules/.bin/jest",
|
|
18
|
-
"cwd": "${workspaceFolder}"
|
|
19
|
-
}
|
|
20
|
-
]
|
|
21
|
-
}
|
package/document.md
DELETED
package/document.mdpatch.json
DELETED
package/jest.config.ts
DELETED
package/src/cli.ts
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { Command } from "commander";
|
|
3
|
-
import fs from "fs/promises";
|
|
4
|
-
import { getDocumentMap } from "./map.js";
|
|
5
|
-
import { printMap } from "./debug.js";
|
|
6
|
-
import { PatchInstruction } from "./types.js";
|
|
7
|
-
import { applyPatch } from "./patch.js";
|
|
8
|
-
import packageJson from "../package.json" assert { type: "json" };
|
|
9
|
-
|
|
10
|
-
async function readStdin(): Promise<string> {
|
|
11
|
-
return new Promise((resolve, reject) => {
|
|
12
|
-
let data = "";
|
|
13
|
-
process.stdin.on("data", (chunk) => (data += chunk));
|
|
14
|
-
process.stdin.on("end", () => resolve(data));
|
|
15
|
-
process.stdin.on("error", reject);
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const program = new Command();
|
|
20
|
-
|
|
21
|
-
// Configure the CLI
|
|
22
|
-
program
|
|
23
|
-
.name(Object.keys(packageJson.bin)[0])
|
|
24
|
-
.description(packageJson.description)
|
|
25
|
-
.version(packageJson.version);
|
|
26
|
-
|
|
27
|
-
program
|
|
28
|
-
.command("print-map")
|
|
29
|
-
.argument("<path>", "filepath to show identified patchable paths for")
|
|
30
|
-
.argument(
|
|
31
|
-
"[regex]",
|
|
32
|
-
"limit displayed matches to those matching the supplied regular expression"
|
|
33
|
-
)
|
|
34
|
-
.action(async (path: string, regex: string | undefined) => {
|
|
35
|
-
const document = await fs.readFile(path, "utf-8");
|
|
36
|
-
const documentMap = getDocumentMap(document);
|
|
37
|
-
|
|
38
|
-
printMap(document, documentMap, regex ? new RegExp(regex) : undefined);
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
program
|
|
42
|
-
.command("apply")
|
|
43
|
-
.argument("<path>", "file to patch")
|
|
44
|
-
.argument("<patch>", "patch file to apply")
|
|
45
|
-
.option(
|
|
46
|
-
"-o, --output <output>",
|
|
47
|
-
"write output to the specified path instead of applying in-place; use '-' for stdout"
|
|
48
|
-
)
|
|
49
|
-
.action(async (path: string, patch: string, options) => {
|
|
50
|
-
let patchParsed: PatchInstruction[];
|
|
51
|
-
let patchData: string;
|
|
52
|
-
try {
|
|
53
|
-
if (patch === "-") {
|
|
54
|
-
patchData = await readStdin();
|
|
55
|
-
} else {
|
|
56
|
-
patchData = await fs.readFile(patch, "utf-8");
|
|
57
|
-
}
|
|
58
|
-
} catch (e) {
|
|
59
|
-
console.error("Failed to read patch: ", e);
|
|
60
|
-
process.exit(1);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
try {
|
|
64
|
-
const parsedData = JSON.parse(patchData);
|
|
65
|
-
if (!Array.isArray(parsedData)) {
|
|
66
|
-
patchParsed = [parsedData];
|
|
67
|
-
} else {
|
|
68
|
-
patchParsed = parsedData;
|
|
69
|
-
}
|
|
70
|
-
} catch (e) {
|
|
71
|
-
console.error("Could not parse patch file as JSON");
|
|
72
|
-
process.exit(1);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
let document = await fs.readFile(path, "utf-8");
|
|
76
|
-
console.log("Document", document);
|
|
77
|
-
for (const instruction of patchParsed) {
|
|
78
|
-
document = applyPatch(document, instruction);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (options.output === "-") {
|
|
82
|
-
process.stdout.write(document);
|
|
83
|
-
} else {
|
|
84
|
-
await fs.writeFile(options.output ? options.output : path, document);
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
program.parse(process.argv);
|
package/src/debug.ts
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import chalk from "chalk";
|
|
2
|
-
import { DocumentMap } from "./types.js";
|
|
3
|
-
|
|
4
|
-
export const printMap = (
|
|
5
|
-
content: string,
|
|
6
|
-
documentMap: DocumentMap,
|
|
7
|
-
regex: RegExp | undefined
|
|
8
|
-
): void => {
|
|
9
|
-
for (const type in documentMap) {
|
|
10
|
-
for (const positionName in documentMap[type as keyof typeof documentMap]) {
|
|
11
|
-
const position =
|
|
12
|
-
documentMap[type as keyof typeof documentMap][positionName];
|
|
13
|
-
|
|
14
|
-
const blockName = `${type} :: ${positionName.replaceAll(
|
|
15
|
-
"\u001f",
|
|
16
|
-
" :: "
|
|
17
|
-
)}`;
|
|
18
|
-
if (regex && !blockName.match(regex)) {
|
|
19
|
-
continue;
|
|
20
|
-
}
|
|
21
|
-
console.log("\n" + chalk.blue(blockName));
|
|
22
|
-
if (position.content.start < position.marker.start) {
|
|
23
|
-
console.log(
|
|
24
|
-
content
|
|
25
|
-
.slice(position.content.start - 100, position.content.start)
|
|
26
|
-
.replaceAll("\n", "\\n\n") +
|
|
27
|
-
chalk.black.bgGreen(
|
|
28
|
-
content
|
|
29
|
-
.slice(position.content.start, position.content.end)
|
|
30
|
-
.replaceAll("\n", "\\n\n")
|
|
31
|
-
) +
|
|
32
|
-
content
|
|
33
|
-
.slice(
|
|
34
|
-
position.content.end,
|
|
35
|
-
Math.min(position.content.end + 100, position.marker.start)
|
|
36
|
-
)
|
|
37
|
-
.replaceAll("\n", "\\n\n") +
|
|
38
|
-
chalk.black.bgRed(
|
|
39
|
-
content
|
|
40
|
-
.slice(position.marker.start, position.marker.end)
|
|
41
|
-
.replaceAll("\n", "\\n\n")
|
|
42
|
-
) +
|
|
43
|
-
content
|
|
44
|
-
.slice(position.marker.end, position.marker.end + 100)
|
|
45
|
-
.replaceAll("\n", "\\n\n")
|
|
46
|
-
);
|
|
47
|
-
} else {
|
|
48
|
-
console.log(
|
|
49
|
-
content
|
|
50
|
-
.slice(position.marker.start - 100, position.marker.start)
|
|
51
|
-
.replaceAll("\n", "\\n\n") +
|
|
52
|
-
chalk.black.bgRed(
|
|
53
|
-
content
|
|
54
|
-
.slice(position.marker.start, position.marker.end)
|
|
55
|
-
.replaceAll("\n", "\\n\n")
|
|
56
|
-
) +
|
|
57
|
-
content
|
|
58
|
-
.slice(
|
|
59
|
-
position.marker.end,
|
|
60
|
-
Math.min(position.marker.end + 100, position.content.start)
|
|
61
|
-
)
|
|
62
|
-
.replaceAll("\n", "\\n\n") +
|
|
63
|
-
chalk.black.bgGreen(
|
|
64
|
-
content
|
|
65
|
-
.slice(position.content.start, position.content.end)
|
|
66
|
-
.replaceAll("\n", "\\n\n")
|
|
67
|
-
) +
|
|
68
|
-
content
|
|
69
|
-
.slice(position.content.end, position.content.end + 100)
|
|
70
|
-
.replaceAll("\n", "\\n\n")
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
};
|