markdown-patch 0.1.3 → 0.2.1
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 +6 -107
- package/dist/cli.js +21 -0
- package/dist/constants.d.ts +0 -4
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +0 -5
- package/dist/debug.d.ts.map +1 -1
- package/dist/debug.js +12 -3
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/map.d.ts.map +1 -1
- package/dist/map.js +47 -29
- package/dist/patch.d.ts +12 -1
- package/dist/patch.d.ts.map +1 -1
- package/dist/patch.js +192 -38
- package/dist/tests/map.test.js +23 -0
- package/dist/tests/patch.test.js +271 -43
- package/dist/typeGuards.d.ts +7 -0
- package/dist/typeGuards.d.ts.map +1 -0
- package/dist/typeGuards.js +20 -0
- package/dist/types.d.ts +118 -14
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +11 -1
- package/package.json +21 -9
package/dist/tests/patch.test.js
CHANGED
|
@@ -1,65 +1,60 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import path from "path";
|
|
3
3
|
import { applyPatch, PatchFailed } from "../patch";
|
|
4
|
-
import { ContentType } from "../
|
|
4
|
+
import { ContentType } from "../types";
|
|
5
5
|
describe("patch", () => {
|
|
6
6
|
const sample = fs.readFileSync(path.join(__dirname, "sample.md"), "utf-8");
|
|
7
|
+
const assertPatchResultsMatch = (inputDocumentPath, outputDocumentPath, instruction) => {
|
|
8
|
+
const inputDocument = fs.readFileSync(path.join(__dirname, inputDocumentPath), "utf-8");
|
|
9
|
+
const outputDocument = fs.readFileSync(path.join(__dirname, outputDocumentPath), "utf-8");
|
|
10
|
+
expect(applyPatch(inputDocument, instruction)).toEqual(outputDocument);
|
|
11
|
+
};
|
|
7
12
|
describe("heading", () => {
|
|
8
13
|
test("prepend", () => {
|
|
9
|
-
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.heading.prepend.md"), "utf-8");
|
|
10
14
|
const instruction = {
|
|
11
15
|
targetType: "heading",
|
|
12
16
|
target: ["Overview"],
|
|
13
17
|
operation: "prepend",
|
|
14
18
|
content: "Beep Boop\n",
|
|
15
19
|
};
|
|
16
|
-
|
|
17
|
-
expect(actualResult).toEqual(expected);
|
|
20
|
+
assertPatchResultsMatch("sample.md", "sample.patch.heading.prepend.md", instruction);
|
|
18
21
|
});
|
|
19
22
|
test("append", () => {
|
|
20
|
-
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.heading.append.md"), "utf-8");
|
|
21
23
|
const instruction = {
|
|
22
24
|
targetType: "heading",
|
|
23
25
|
target: ["Overview"],
|
|
24
26
|
operation: "append",
|
|
25
27
|
content: "Beep Boop\n",
|
|
26
28
|
};
|
|
27
|
-
|
|
28
|
-
expect(actualResult).toEqual(expected);
|
|
29
|
+
assertPatchResultsMatch("sample.md", "sample.patch.heading.append.md", instruction);
|
|
29
30
|
});
|
|
30
31
|
test("replace", () => {
|
|
31
|
-
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.heading.replace.md"), "utf-8");
|
|
32
32
|
const instruction = {
|
|
33
33
|
targetType: "heading",
|
|
34
34
|
target: ["Overview"],
|
|
35
35
|
operation: "replace",
|
|
36
36
|
content: "Beep Boop\n",
|
|
37
37
|
};
|
|
38
|
-
|
|
39
|
-
expect(actualResult).toEqual(expected);
|
|
38
|
+
assertPatchResultsMatch("sample.md", "sample.patch.heading.replace.md", instruction);
|
|
40
39
|
});
|
|
41
40
|
describe("document", () => {
|
|
42
41
|
test("prepend", () => {
|
|
43
|
-
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.heading.document.prepend.md"), "utf-8");
|
|
44
42
|
const instruction = {
|
|
45
43
|
targetType: "heading",
|
|
46
44
|
target: null,
|
|
47
45
|
operation: "prepend",
|
|
48
46
|
content: "Beep Boop\n",
|
|
49
47
|
};
|
|
50
|
-
|
|
51
|
-
expect(actualResult).toEqual(expected);
|
|
48
|
+
assertPatchResultsMatch("sample.md", "sample.patch.heading.document.prepend.md", instruction);
|
|
52
49
|
});
|
|
53
50
|
test("append", () => {
|
|
54
|
-
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.heading.document.append.md"), "utf-8");
|
|
55
51
|
const instruction = {
|
|
56
52
|
targetType: "heading",
|
|
57
53
|
target: null,
|
|
58
54
|
operation: "append",
|
|
59
55
|
content: "Beep Boop\n",
|
|
60
56
|
};
|
|
61
|
-
|
|
62
|
-
expect(actualResult).toEqual(expected);
|
|
57
|
+
assertPatchResultsMatch("sample.md", "sample.patch.heading.document.append.md", instruction);
|
|
63
58
|
});
|
|
64
59
|
});
|
|
65
60
|
});
|
|
@@ -67,7 +62,6 @@ describe("patch", () => {
|
|
|
67
62
|
describe("trimTargetWhitespace", () => {
|
|
68
63
|
describe("heading", () => {
|
|
69
64
|
test("prepend", () => {
|
|
70
|
-
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.heading.trimTargetWhitespace.prepend.md"), "utf-8");
|
|
71
65
|
const instruction = {
|
|
72
66
|
targetType: "heading",
|
|
73
67
|
target: ["Page Targets", "Document Properties (Exploratory)"],
|
|
@@ -75,11 +69,9 @@ describe("patch", () => {
|
|
|
75
69
|
content: "Beep Boop",
|
|
76
70
|
trimTargetWhitespace: true,
|
|
77
71
|
};
|
|
78
|
-
|
|
79
|
-
expect(actualResult).toEqual(expected);
|
|
72
|
+
assertPatchResultsMatch("sample.md", "sample.patch.heading.trimTargetWhitespace.prepend.md", instruction);
|
|
80
73
|
});
|
|
81
74
|
test("append", () => {
|
|
82
|
-
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.heading.trimTargetWhitespace.append.md"), "utf-8");
|
|
83
75
|
const instruction = {
|
|
84
76
|
targetType: "heading",
|
|
85
77
|
target: ["Problems"],
|
|
@@ -87,11 +79,32 @@ describe("patch", () => {
|
|
|
87
79
|
content: "Beep Boop\n",
|
|
88
80
|
trimTargetWhitespace: true,
|
|
89
81
|
};
|
|
90
|
-
|
|
91
|
-
expect(actualResult).toEqual(expected);
|
|
82
|
+
assertPatchResultsMatch("sample.md", "sample.patch.heading.trimTargetWhitespace.append.md", instruction);
|
|
92
83
|
});
|
|
93
84
|
});
|
|
94
85
|
});
|
|
86
|
+
describe("createTargetIfMissing", () => {
|
|
87
|
+
test("nested", () => {
|
|
88
|
+
const instruction = {
|
|
89
|
+
targetType: "heading",
|
|
90
|
+
target: ["Page Targets", "Block", "Test"],
|
|
91
|
+
operation: "replace",
|
|
92
|
+
content: "Beep Boop\n",
|
|
93
|
+
createTargetIfMissing: true,
|
|
94
|
+
};
|
|
95
|
+
assertPatchResultsMatch("sample.md", "sample.patch.heading.createIfMissing.nested.md", instruction);
|
|
96
|
+
});
|
|
97
|
+
test("root", () => {
|
|
98
|
+
const instruction = {
|
|
99
|
+
targetType: "heading",
|
|
100
|
+
target: ["Alpha", "Beta", "Test"],
|
|
101
|
+
operation: "replace",
|
|
102
|
+
content: "Beep Boop\n",
|
|
103
|
+
createTargetIfMissing: true,
|
|
104
|
+
};
|
|
105
|
+
assertPatchResultsMatch("sample.md", "sample.patch.heading.createIfMissing.root.md", instruction);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
95
108
|
describe("applyIfContentPreexists", () => {
|
|
96
109
|
describe("disabled (default)", () => {
|
|
97
110
|
describe("heading", () => {
|
|
@@ -141,81 +154,296 @@ describe("patch", () => {
|
|
|
141
154
|
});
|
|
142
155
|
describe("block", () => {
|
|
143
156
|
test("prepend", () => {
|
|
144
|
-
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.block.prepend.md"), "utf-8");
|
|
145
157
|
const instruction = {
|
|
146
158
|
targetType: "block",
|
|
147
159
|
target: "e6068e",
|
|
148
160
|
operation: "prepend",
|
|
149
161
|
content: "- OK\n",
|
|
150
162
|
};
|
|
151
|
-
|
|
152
|
-
expect(actualResult).toEqual(expected);
|
|
163
|
+
assertPatchResultsMatch("sample.md", "sample.patch.block.prepend.md", instruction);
|
|
153
164
|
});
|
|
154
165
|
test("append", () => {
|
|
155
|
-
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.block.append.md"), "utf-8");
|
|
156
166
|
const instruction = {
|
|
157
167
|
targetType: "block",
|
|
158
168
|
target: "e6068e",
|
|
159
169
|
operation: "append",
|
|
160
170
|
content: "\n- OK",
|
|
161
171
|
};
|
|
162
|
-
|
|
163
|
-
expect(actualResult).toEqual(expected);
|
|
172
|
+
assertPatchResultsMatch("sample.md", "sample.patch.block.append.md", instruction);
|
|
164
173
|
});
|
|
165
174
|
test("replace", () => {
|
|
166
|
-
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.block.replace.md"), "utf-8");
|
|
167
175
|
const instruction = {
|
|
168
176
|
targetType: "block",
|
|
169
177
|
target: "259a73",
|
|
170
178
|
operation: "replace",
|
|
171
179
|
content: "- OK",
|
|
172
180
|
};
|
|
173
|
-
|
|
174
|
-
expect(actualResult).toEqual(expected);
|
|
181
|
+
assertPatchResultsMatch("sample.md", "sample.patch.block.replace.md", instruction);
|
|
175
182
|
});
|
|
176
183
|
describe("tagetBlockTypeBehavior", () => {
|
|
177
184
|
describe("table", () => {
|
|
178
185
|
test("prepend", () => {
|
|
179
|
-
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.block.targetBlockTypeBehavior.table.prepend.md"), "utf-8");
|
|
180
186
|
const instruction = {
|
|
181
187
|
targetType: "block",
|
|
182
188
|
target: "2c67a6",
|
|
183
189
|
operation: "prepend",
|
|
184
|
-
contentType: ContentType.
|
|
190
|
+
contentType: ContentType.json,
|
|
185
191
|
content: [
|
|
186
192
|
["`something else`", "Some other application", "✅", "✅", "✅"],
|
|
187
193
|
],
|
|
188
194
|
};
|
|
189
|
-
|
|
190
|
-
expect(actualResult).toEqual(expected);
|
|
195
|
+
assertPatchResultsMatch("sample.md", "sample.patch.block.targetBlockTypeBehavior.table.prepend.md", instruction);
|
|
191
196
|
});
|
|
192
197
|
test("append", () => {
|
|
193
|
-
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.block.targetBlockTypeBehavior.table.append.md"), "utf-8");
|
|
194
198
|
const instruction = {
|
|
195
199
|
targetType: "block",
|
|
196
200
|
target: "2c67a6",
|
|
197
201
|
operation: "append",
|
|
198
|
-
contentType: ContentType.
|
|
202
|
+
contentType: ContentType.json,
|
|
199
203
|
content: [
|
|
200
204
|
["`something else`", "Some other application", "✅", "✅", "✅"],
|
|
201
205
|
],
|
|
202
206
|
};
|
|
203
|
-
|
|
204
|
-
expect(actualResult).toEqual(expected);
|
|
207
|
+
assertPatchResultsMatch("sample.md", "sample.patch.block.targetBlockTypeBehavior.table.append.md", instruction);
|
|
205
208
|
});
|
|
206
209
|
test("replace", () => {
|
|
207
|
-
const expected = fs.readFileSync(path.join(__dirname, "sample.patch.block.targetBlockTypeBehavior.table.replace.md"), "utf-8");
|
|
208
210
|
const instruction = {
|
|
209
211
|
targetType: "block",
|
|
210
212
|
target: "2c67a6",
|
|
211
213
|
operation: "replace",
|
|
212
|
-
contentType: ContentType.
|
|
214
|
+
contentType: ContentType.json,
|
|
213
215
|
content: [
|
|
214
216
|
["`something else`", "Some other application", "✅", "✅", "✅"],
|
|
215
217
|
],
|
|
216
218
|
};
|
|
217
|
-
|
|
218
|
-
|
|
219
|
+
assertPatchResultsMatch("sample.md", "sample.patch.block.targetBlockTypeBehavior.table.replace.md", instruction);
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
describe("frontmatter", () => {
|
|
225
|
+
describe("append", () => {
|
|
226
|
+
test("mismatched types", () => {
|
|
227
|
+
const instruction = {
|
|
228
|
+
targetType: "frontmatter",
|
|
229
|
+
target: "array-value",
|
|
230
|
+
operation: "append",
|
|
231
|
+
contentType: ContentType.json,
|
|
232
|
+
content: "OK",
|
|
233
|
+
};
|
|
234
|
+
expect(() => {
|
|
235
|
+
applyPatch(sample, instruction);
|
|
236
|
+
}).toThrow(PatchFailed);
|
|
237
|
+
});
|
|
238
|
+
test("invalid type", () => {
|
|
239
|
+
const instruction = {
|
|
240
|
+
targetType: "frontmatter",
|
|
241
|
+
target: "array-value",
|
|
242
|
+
operation: "append",
|
|
243
|
+
contentType: ContentType.json,
|
|
244
|
+
content: 10,
|
|
245
|
+
};
|
|
246
|
+
expect(() => {
|
|
247
|
+
applyPatch(sample, instruction);
|
|
248
|
+
}).toThrow(PatchFailed);
|
|
249
|
+
});
|
|
250
|
+
test("list", () => {
|
|
251
|
+
const instruction = {
|
|
252
|
+
targetType: "frontmatter",
|
|
253
|
+
target: "array-value",
|
|
254
|
+
operation: "append",
|
|
255
|
+
contentType: ContentType.json,
|
|
256
|
+
content: ["Beep"],
|
|
257
|
+
};
|
|
258
|
+
assertPatchResultsMatch("sample.frontmatter.md", "sample.patch.frontmatter.append.list.md", instruction);
|
|
259
|
+
});
|
|
260
|
+
test("dictionary", () => {
|
|
261
|
+
const instruction = {
|
|
262
|
+
targetType: "frontmatter",
|
|
263
|
+
target: "object-value",
|
|
264
|
+
operation: "append",
|
|
265
|
+
contentType: ContentType.json,
|
|
266
|
+
content: { three: "Beep" },
|
|
267
|
+
};
|
|
268
|
+
assertPatchResultsMatch("sample.frontmatter.md", "sample.patch.frontmatter.append.dictionary.md", instruction);
|
|
269
|
+
});
|
|
270
|
+
test("string", () => {
|
|
271
|
+
const instruction = {
|
|
272
|
+
targetType: "frontmatter",
|
|
273
|
+
target: "string-value",
|
|
274
|
+
operation: "append",
|
|
275
|
+
contentType: ContentType.json,
|
|
276
|
+
content: "Beep",
|
|
277
|
+
};
|
|
278
|
+
assertPatchResultsMatch("sample.frontmatter.md", "sample.patch.frontmatter.append.string.md", instruction);
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
describe("prepend", () => {
|
|
282
|
+
test("mismatched types", () => {
|
|
283
|
+
const instruction = {
|
|
284
|
+
targetType: "frontmatter",
|
|
285
|
+
target: "array-value",
|
|
286
|
+
operation: "prepend",
|
|
287
|
+
contentType: ContentType.json,
|
|
288
|
+
content: "OK",
|
|
289
|
+
};
|
|
290
|
+
expect(() => {
|
|
291
|
+
applyPatch(sample, instruction);
|
|
292
|
+
}).toThrow(PatchFailed);
|
|
293
|
+
});
|
|
294
|
+
test("invalid type", () => {
|
|
295
|
+
const instruction = {
|
|
296
|
+
targetType: "frontmatter",
|
|
297
|
+
target: "array-value",
|
|
298
|
+
operation: "prepend",
|
|
299
|
+
contentType: ContentType.json,
|
|
300
|
+
content: 10,
|
|
301
|
+
};
|
|
302
|
+
expect(() => {
|
|
303
|
+
applyPatch(sample, instruction);
|
|
304
|
+
}).toThrow(PatchFailed);
|
|
305
|
+
});
|
|
306
|
+
test("list", () => {
|
|
307
|
+
const instruction = {
|
|
308
|
+
targetType: "frontmatter",
|
|
309
|
+
target: "array-value",
|
|
310
|
+
operation: "prepend",
|
|
311
|
+
contentType: ContentType.json,
|
|
312
|
+
content: ["Beep"],
|
|
313
|
+
};
|
|
314
|
+
assertPatchResultsMatch("sample.frontmatter.md", "sample.patch.frontmatter.prepend.list.md", instruction);
|
|
315
|
+
});
|
|
316
|
+
test("dictionary", () => {
|
|
317
|
+
const instruction = {
|
|
318
|
+
targetType: "frontmatter",
|
|
319
|
+
target: "object-value",
|
|
320
|
+
operation: "prepend",
|
|
321
|
+
contentType: ContentType.json,
|
|
322
|
+
content: { three: "Beep" },
|
|
323
|
+
};
|
|
324
|
+
assertPatchResultsMatch("sample.frontmatter.md", "sample.patch.frontmatter.prepend.dictionary.md", instruction);
|
|
325
|
+
});
|
|
326
|
+
test("string", () => {
|
|
327
|
+
const instruction = {
|
|
328
|
+
targetType: "frontmatter",
|
|
329
|
+
target: "string-value",
|
|
330
|
+
operation: "prepend",
|
|
331
|
+
contentType: ContentType.json,
|
|
332
|
+
content: "Beep",
|
|
333
|
+
};
|
|
334
|
+
assertPatchResultsMatch("sample.frontmatter.md", "sample.patch.frontmatter.prepend.string.md", instruction);
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
describe("replace", () => {
|
|
338
|
+
test("list", () => {
|
|
339
|
+
const instruction = {
|
|
340
|
+
targetType: "frontmatter",
|
|
341
|
+
target: "array-value",
|
|
342
|
+
operation: "replace",
|
|
343
|
+
contentType: ContentType.json,
|
|
344
|
+
content: ["Replaced"],
|
|
345
|
+
};
|
|
346
|
+
assertPatchResultsMatch("sample.frontmatter.md", "sample.patch.frontmatter.replace.list.md", instruction);
|
|
347
|
+
});
|
|
348
|
+
test("dictionary", () => {
|
|
349
|
+
const instruction = {
|
|
350
|
+
targetType: "frontmatter",
|
|
351
|
+
target: "object-value",
|
|
352
|
+
operation: "replace",
|
|
353
|
+
contentType: ContentType.json,
|
|
354
|
+
content: {
|
|
355
|
+
replaced: true,
|
|
356
|
+
},
|
|
357
|
+
};
|
|
358
|
+
assertPatchResultsMatch("sample.frontmatter.md", "sample.patch.frontmatter.replace.dictionary.md", instruction);
|
|
359
|
+
});
|
|
360
|
+
test("string", () => {
|
|
361
|
+
const instruction = {
|
|
362
|
+
targetType: "frontmatter",
|
|
363
|
+
target: "string-value",
|
|
364
|
+
operation: "replace",
|
|
365
|
+
contentType: ContentType.json,
|
|
366
|
+
content: "Replaced",
|
|
367
|
+
};
|
|
368
|
+
assertPatchResultsMatch("sample.frontmatter.md", "sample.patch.frontmatter.replace.string.md", instruction);
|
|
369
|
+
});
|
|
370
|
+
test("number", () => {
|
|
371
|
+
const instruction = {
|
|
372
|
+
targetType: "frontmatter",
|
|
373
|
+
target: "number-value",
|
|
374
|
+
operation: "replace",
|
|
375
|
+
contentType: ContentType.json,
|
|
376
|
+
content: 10,
|
|
377
|
+
};
|
|
378
|
+
assertPatchResultsMatch("sample.frontmatter.md", "sample.patch.frontmatter.replace.number.md", instruction);
|
|
379
|
+
});
|
|
380
|
+
test("boolean", () => {
|
|
381
|
+
const instruction = {
|
|
382
|
+
targetType: "frontmatter",
|
|
383
|
+
target: "boolean-value",
|
|
384
|
+
operation: "replace",
|
|
385
|
+
contentType: ContentType.json,
|
|
386
|
+
content: true,
|
|
387
|
+
};
|
|
388
|
+
assertPatchResultsMatch("sample.frontmatter.md", "sample.patch.frontmatter.replace.boolean.md", instruction);
|
|
389
|
+
});
|
|
390
|
+
describe("createTargetIfMissing", () => {
|
|
391
|
+
test("list", () => {
|
|
392
|
+
const instruction = {
|
|
393
|
+
targetType: "frontmatter",
|
|
394
|
+
target: "new-field",
|
|
395
|
+
operation: "replace",
|
|
396
|
+
contentType: ContentType.json,
|
|
397
|
+
content: ["New Value"],
|
|
398
|
+
createTargetIfMissing: true,
|
|
399
|
+
};
|
|
400
|
+
assertPatchResultsMatch("sample.frontmatter.md", "sample.patch.frontmatter.createTargetIfMissing.list.md", instruction);
|
|
401
|
+
});
|
|
402
|
+
test("dictionary", () => {
|
|
403
|
+
const instruction = {
|
|
404
|
+
targetType: "frontmatter",
|
|
405
|
+
target: "new-field",
|
|
406
|
+
operation: "replace",
|
|
407
|
+
contentType: ContentType.json,
|
|
408
|
+
content: {
|
|
409
|
+
newValue: true,
|
|
410
|
+
},
|
|
411
|
+
createTargetIfMissing: true,
|
|
412
|
+
};
|
|
413
|
+
assertPatchResultsMatch("sample.frontmatter.md", "sample.patch.frontmatter.createTargetIfMissing.dictionary.md", instruction);
|
|
414
|
+
});
|
|
415
|
+
test("string", () => {
|
|
416
|
+
const instruction = {
|
|
417
|
+
targetType: "frontmatter",
|
|
418
|
+
target: "new-field",
|
|
419
|
+
operation: "replace",
|
|
420
|
+
contentType: ContentType.json,
|
|
421
|
+
content: "New Value",
|
|
422
|
+
createTargetIfMissing: true,
|
|
423
|
+
};
|
|
424
|
+
assertPatchResultsMatch("sample.frontmatter.md", "sample.patch.frontmatter.createTargetIfMissing.string.md", instruction);
|
|
425
|
+
});
|
|
426
|
+
test("number", () => {
|
|
427
|
+
const instruction = {
|
|
428
|
+
targetType: "frontmatter",
|
|
429
|
+
target: "new-field",
|
|
430
|
+
operation: "replace",
|
|
431
|
+
contentType: ContentType.json,
|
|
432
|
+
content: 588600,
|
|
433
|
+
createTargetIfMissing: true,
|
|
434
|
+
};
|
|
435
|
+
assertPatchResultsMatch("sample.frontmatter.md", "sample.patch.frontmatter.createTargetIfMissing.number.md", instruction);
|
|
436
|
+
});
|
|
437
|
+
test("boolean", () => {
|
|
438
|
+
const instruction = {
|
|
439
|
+
targetType: "frontmatter",
|
|
440
|
+
target: "new-field",
|
|
441
|
+
operation: "replace",
|
|
442
|
+
contentType: ContentType.json,
|
|
443
|
+
content: true,
|
|
444
|
+
createTargetIfMissing: true,
|
|
445
|
+
};
|
|
446
|
+
assertPatchResultsMatch("sample.frontmatter.md", "sample.patch.frontmatter.createTargetIfMissing.boolean.md", instruction);
|
|
219
447
|
});
|
|
220
448
|
});
|
|
221
449
|
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AppendableFrontmatterType } from "./types";
|
|
2
|
+
export declare function isStringArrayArray(obj: unknown): obj is string[][];
|
|
3
|
+
export declare function isAppendableFrontmatterType(obj: unknown): obj is AppendableFrontmatterType;
|
|
4
|
+
export declare function isString(obj: unknown): obj is string;
|
|
5
|
+
export declare function isDictionary(obj: unknown): obj is Record<string, unknown>;
|
|
6
|
+
export declare function isList(obj: unknown): obj is Array<unknown>;
|
|
7
|
+
//# sourceMappingURL=typeGuards.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typeGuards.d.ts","sourceRoot":"","sources":["../src/typeGuards.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAC;AAEpD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,MAAM,EAAE,EAAE,CAUlE;AACD,wBAAgB,2BAA2B,CACzC,GAAG,EAAE,OAAO,GACX,GAAG,IAAI,yBAAyB,CAElC;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,MAAM,CAEpD;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,CAE1D"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function isStringArrayArray(obj) {
|
|
2
|
+
// Check if the object is an array
|
|
3
|
+
if (!Array.isArray(obj))
|
|
4
|
+
return false;
|
|
5
|
+
// Check if every element is an array of strings
|
|
6
|
+
return obj.every((item) => Array.isArray(item) &&
|
|
7
|
+
item.every((subItem) => typeof subItem === "string"));
|
|
8
|
+
}
|
|
9
|
+
export function isAppendableFrontmatterType(obj) {
|
|
10
|
+
return isString(obj) || isDictionary(obj) || isList(obj);
|
|
11
|
+
}
|
|
12
|
+
export function isString(obj) {
|
|
13
|
+
return typeof obj === "string";
|
|
14
|
+
}
|
|
15
|
+
export function isDictionary(obj) {
|
|
16
|
+
return typeof obj === "object" && obj !== null && !Array.isArray(obj);
|
|
17
|
+
}
|
|
18
|
+
export function isList(obj) {
|
|
19
|
+
return Array.isArray(obj);
|
|
20
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { ContentType } from "./constants";
|
|
2
1
|
export interface DocumentRange {
|
|
3
2
|
start: number;
|
|
4
3
|
end: number;
|
|
@@ -13,12 +12,16 @@ export interface HeadingMarkerContentPair extends DocumentMapMarkerContentPair {
|
|
|
13
12
|
export interface DocumentMap {
|
|
14
13
|
heading: Record<string, HeadingMarkerContentPair>;
|
|
15
14
|
block: Record<string, DocumentMapMarkerContentPair>;
|
|
15
|
+
frontmatter: Record<string, any>;
|
|
16
|
+
contentOffset: number;
|
|
17
|
+
lineEnding: string;
|
|
16
18
|
}
|
|
17
|
-
export type PatchTargetType = "heading" | "block";
|
|
19
|
+
export type PatchTargetType = "heading" | "block" | "frontmatter";
|
|
18
20
|
export type PatchOperation = "replace" | "prepend" | "append";
|
|
19
21
|
export interface BasePatchInstructionTarget {
|
|
20
22
|
targetType: PatchTargetType;
|
|
21
23
|
target: any;
|
|
24
|
+
createTargetIfMissing?: boolean;
|
|
22
25
|
}
|
|
23
26
|
export interface BasePatchInstructionOperation {
|
|
24
27
|
operation: string;
|
|
@@ -27,13 +30,17 @@ export interface BaseHeadingPatchInstruction extends BasePatchInstructionTarget
|
|
|
27
30
|
targetType: "heading";
|
|
28
31
|
target: string[] | null;
|
|
29
32
|
}
|
|
33
|
+
export interface BaseFrontmatterPatchInstruction extends BasePatchInstructionTarget {
|
|
34
|
+
targetType: "frontmatter";
|
|
35
|
+
target: string;
|
|
36
|
+
}
|
|
30
37
|
export interface BaseBlockPatchInstruction extends BasePatchInstructionTarget {
|
|
31
38
|
targetType: "block";
|
|
32
39
|
target: string;
|
|
33
40
|
}
|
|
34
41
|
export interface NonExtendingPatchInstruction extends BasePatchInstructionOperation {
|
|
35
42
|
}
|
|
36
|
-
export interface
|
|
43
|
+
export interface TextExtendingPatchInstruction extends BasePatchInstructionOperation {
|
|
37
44
|
/** Trim whitepsace from target before joining with content
|
|
38
45
|
*
|
|
39
46
|
* - For `prepend`: Trims content from the beginning of
|
|
@@ -58,38 +65,135 @@ export interface StringContent {
|
|
|
58
65
|
contentType?: ContentType.text;
|
|
59
66
|
content: string;
|
|
60
67
|
}
|
|
61
|
-
export interface
|
|
62
|
-
contentType: ContentType.
|
|
63
|
-
content:
|
|
68
|
+
export interface JsonContent {
|
|
69
|
+
contentType: ContentType.json;
|
|
70
|
+
content: unknown;
|
|
64
71
|
}
|
|
65
|
-
|
|
72
|
+
/**
|
|
73
|
+
* Prepend content to content existing under a heading
|
|
74
|
+
*
|
|
75
|
+
* @category Patch Instructions
|
|
76
|
+
*/
|
|
77
|
+
export interface PrependHeadingPatchInstruction extends TextExtendingPatchInstruction, BaseHeadingPatchInstruction, StringContent {
|
|
66
78
|
operation: "prepend";
|
|
67
79
|
}
|
|
68
|
-
|
|
80
|
+
/**
|
|
81
|
+
* Append content to content existing under a heading
|
|
82
|
+
*
|
|
83
|
+
* @category Patch Instructions
|
|
84
|
+
*/
|
|
85
|
+
export interface AppendHeadingPatchInstruction extends TextExtendingPatchInstruction, BaseHeadingPatchInstruction, StringContent {
|
|
69
86
|
operation: "append";
|
|
70
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Replace content under a heading
|
|
90
|
+
*
|
|
91
|
+
* @category Patch Instructions
|
|
92
|
+
*/
|
|
71
93
|
export interface ReplaceHeadingPatchInstruction extends NonExtendingPatchInstruction, BaseHeadingPatchInstruction, StringContent {
|
|
72
94
|
operation: "replace";
|
|
73
95
|
}
|
|
74
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Prepend content to a block referenced by a block reference
|
|
98
|
+
*
|
|
99
|
+
* @category Patch Instructions
|
|
100
|
+
*/
|
|
101
|
+
export interface PrependBlockPatchInstruction extends TextExtendingPatchInstruction, BaseBlockPatchInstruction, StringContent {
|
|
75
102
|
operation: "prepend";
|
|
76
103
|
}
|
|
77
|
-
|
|
104
|
+
/**
|
|
105
|
+
* Append content to a block referenced by a block reference
|
|
106
|
+
*
|
|
107
|
+
* @category Patch Instructions
|
|
108
|
+
*/
|
|
109
|
+
export interface AppendBlockPatchInstruction extends TextExtendingPatchInstruction, BaseBlockPatchInstruction, StringContent {
|
|
78
110
|
operation: "append";
|
|
79
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* Replace content of block referenced by a block reference.
|
|
114
|
+
*
|
|
115
|
+
* @category Patch Instructions
|
|
116
|
+
*/
|
|
80
117
|
export interface ReplaceBlockPatchInstruction extends NonExtendingPatchInstruction, BaseBlockPatchInstruction, StringContent {
|
|
81
118
|
operation: "replace";
|
|
82
119
|
}
|
|
83
|
-
|
|
120
|
+
/**
|
|
121
|
+
* Prepend rows to a table referenced by a block reference.
|
|
122
|
+
*
|
|
123
|
+
* @category Patch Instructions
|
|
124
|
+
*/
|
|
125
|
+
export interface PrependTableRowsBlockPatchInstruction extends TextExtendingPatchInstruction, BaseBlockPatchInstruction, JsonContent {
|
|
84
126
|
operation: "prepend";
|
|
85
127
|
}
|
|
86
|
-
|
|
128
|
+
/**
|
|
129
|
+
* Patch Instruction for appending rows to a table
|
|
130
|
+
* referenced by a block reference.
|
|
131
|
+
*
|
|
132
|
+
* @category Patch Instructions
|
|
133
|
+
*/
|
|
134
|
+
export interface AppendTableRowsBlockPatchInstruction extends TextExtendingPatchInstruction, BaseBlockPatchInstruction, JsonContent {
|
|
87
135
|
operation: "append";
|
|
88
136
|
}
|
|
89
|
-
|
|
137
|
+
/**
|
|
138
|
+
* Patch Instruction for replacing all rows of a table
|
|
139
|
+
* referenced by a block reference.
|
|
140
|
+
*
|
|
141
|
+
* @category Patch Instructions
|
|
142
|
+
*/
|
|
143
|
+
export interface ReplaceTableRowsBlockPatchInstruction extends NonExtendingPatchInstruction, BaseBlockPatchInstruction, JsonContent {
|
|
90
144
|
operation: "replace";
|
|
91
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* Prepend content to a frontmatter field
|
|
148
|
+
*
|
|
149
|
+
* @category Patch Instructions
|
|
150
|
+
*/
|
|
151
|
+
export interface PrependFrontmatterPatchInstruction extends NonExtendingPatchInstruction, BaseFrontmatterPatchInstruction, JsonContent {
|
|
152
|
+
operation: "prepend";
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Append content to a frontmatter field
|
|
156
|
+
*
|
|
157
|
+
* @category Patch Instructions
|
|
158
|
+
*/
|
|
159
|
+
export interface AppendFrontmatterPatchInstruction extends NonExtendingPatchInstruction, BaseFrontmatterPatchInstruction, JsonContent {
|
|
160
|
+
operation: "append";
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Replace content of frontmatter field
|
|
164
|
+
*
|
|
165
|
+
* @category Patch Instructions
|
|
166
|
+
*/
|
|
167
|
+
export interface ReplaceFrontmatterPatchInstruction extends NonExtendingPatchInstruction, BaseFrontmatterPatchInstruction, JsonContent {
|
|
168
|
+
operation: "replace";
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Patch Instruction for Headings
|
|
172
|
+
*/
|
|
92
173
|
export type HeadingPatchInstruction = PrependHeadingPatchInstruction | AppendHeadingPatchInstruction | ReplaceHeadingPatchInstruction;
|
|
174
|
+
/**
|
|
175
|
+
* Patch Instruction for Block References
|
|
176
|
+
*/
|
|
93
177
|
export type BlockPatchInstruction = PrependBlockPatchInstruction | AppendBlockPatchInstruction | ReplaceBlockPatchInstruction | PrependTableRowsBlockPatchInstruction | AppendTableRowsBlockPatchInstruction | ReplaceTableRowsBlockPatchInstruction;
|
|
94
|
-
export type
|
|
178
|
+
export type FrontmatterPatchInstruction = PrependFrontmatterPatchInstruction | AppendFrontmatterPatchInstruction | ReplaceFrontmatterPatchInstruction;
|
|
179
|
+
/**
|
|
180
|
+
* Patch Instruction
|
|
181
|
+
*/
|
|
182
|
+
export type PatchInstruction = HeadingPatchInstruction | BlockPatchInstruction | FrontmatterPatchInstruction;
|
|
183
|
+
export declare enum ContentType {
|
|
184
|
+
/**
|
|
185
|
+
* Content is simple markdown text.
|
|
186
|
+
*/
|
|
187
|
+
text = "text/markdown",
|
|
188
|
+
/**
|
|
189
|
+
* Content is a JSON document
|
|
190
|
+
*/
|
|
191
|
+
json = "application/json"
|
|
192
|
+
}
|
|
193
|
+
export interface PreprocessedDocument {
|
|
194
|
+
frontmatter: Record<string, any>;
|
|
195
|
+
contentOffset: number;
|
|
196
|
+
content: string;
|
|
197
|
+
}
|
|
198
|
+
export type AppendableFrontmatterType = string | Array<unknown> | Record<string, unknown>;
|
|
95
199
|
//# sourceMappingURL=types.d.ts.map
|