@platecms/delta-cast 0.7.0 → 0.9.0
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/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platecms/delta-cast",
|
|
3
3
|
"description": "Package containing the definition of CAST",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.9.0",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
@@ -22,6 +22,6 @@
|
|
|
22
22
|
"tslib": "2.8.1"
|
|
23
23
|
},
|
|
24
24
|
"peerDependencies": {
|
|
25
|
-
"@platecms/delta-plate-resource-notation": "0.
|
|
25
|
+
"@platecms/delta-plate-resource-notation": "0.9.0"
|
|
26
26
|
}
|
|
27
27
|
}
|
|
@@ -52,6 +52,47 @@
|
|
|
52
52
|
},
|
|
53
53
|
"type": "object"
|
|
54
54
|
},
|
|
55
|
+
"CasSuggestion": {
|
|
56
|
+
"description": "A CAS suggestion node.",
|
|
57
|
+
"properties": {
|
|
58
|
+
"data": {
|
|
59
|
+
"$ref": "#/definitions/Data",
|
|
60
|
+
"description": "Info from the ecosystem."
|
|
61
|
+
},
|
|
62
|
+
"message": {
|
|
63
|
+
"description": "A message explaining the suggestion.",
|
|
64
|
+
"type": "string"
|
|
65
|
+
},
|
|
66
|
+
"method": {
|
|
67
|
+
"description": "The method or algorithm that created the suggestion (e.g. \"database; reusable\")",
|
|
68
|
+
"type": "string"
|
|
69
|
+
},
|
|
70
|
+
"original": {
|
|
71
|
+
"description": "The original content that is suggested to be replaced.",
|
|
72
|
+
"items": {
|
|
73
|
+
"$ref": "#/definitions/Content"
|
|
74
|
+
},
|
|
75
|
+
"type": "array"
|
|
76
|
+
},
|
|
77
|
+
"position": {
|
|
78
|
+
"$ref": "#/definitions/Position",
|
|
79
|
+
"description": "Position of a node in a source document.\n\nNodes that are generated (not in the original source document) must not\nhave a position."
|
|
80
|
+
},
|
|
81
|
+
"suggested": {
|
|
82
|
+
"description": "The suggested replacement content.",
|
|
83
|
+
"items": {
|
|
84
|
+
"$ref": "#/definitions/Content"
|
|
85
|
+
},
|
|
86
|
+
"type": "array"
|
|
87
|
+
},
|
|
88
|
+
"type": {
|
|
89
|
+
"const": "casSuggestion",
|
|
90
|
+
"description": "Node type.",
|
|
91
|
+
"type": "string"
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
"type": "object"
|
|
95
|
+
},
|
|
55
96
|
"Code": {
|
|
56
97
|
"properties": {
|
|
57
98
|
"children": {
|
|
@@ -101,6 +142,9 @@
|
|
|
101
142
|
{
|
|
102
143
|
"$ref": "#/definitions/ListItem"
|
|
103
144
|
},
|
|
145
|
+
{
|
|
146
|
+
"$ref": "#/definitions/CasSuggestion"
|
|
147
|
+
},
|
|
104
148
|
{
|
|
105
149
|
"$ref": "#/definitions/Bold"
|
|
106
150
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Node, Literal as UnistLiteral, Parent as UnistParent } from "unist";
|
|
2
2
|
|
|
3
|
-
export type Content = BlockContent | InlineContent;
|
|
3
|
+
export type Content = BlockContent | CasSuggestion | InlineContent;
|
|
4
4
|
|
|
5
5
|
export type BlockContent = BlockContentMap[keyof BlockContentMap];
|
|
6
6
|
export type InlineContent = InlineContentMap[keyof InlineContentMap];
|
|
@@ -232,3 +232,30 @@ export interface InternalLink extends Parent {
|
|
|
232
232
|
|
|
233
233
|
target?: "_parent" | "_top" | "blank" | "self";
|
|
234
234
|
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* A CAS suggestion node.
|
|
238
|
+
*/
|
|
239
|
+
export interface CasSuggestion extends Node {
|
|
240
|
+
type: "casSuggestion";
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* The original content that is suggested to be replaced.
|
|
244
|
+
*/
|
|
245
|
+
original: Content[];
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* The suggested replacement content.
|
|
249
|
+
*/
|
|
250
|
+
suggested: Content[];
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* A message explaining the suggestion.
|
|
254
|
+
*/
|
|
255
|
+
message: string;
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* The method or algorithm that created the suggestion (e.g. "database; reusable")
|
|
259
|
+
*/
|
|
260
|
+
method: string;
|
|
261
|
+
}
|
|
@@ -2,6 +2,7 @@ import { validateCast } from "./validate-cast";
|
|
|
2
2
|
import {
|
|
3
3
|
Blockquote,
|
|
4
4
|
Bold,
|
|
5
|
+
CasSuggestion,
|
|
5
6
|
Code,
|
|
6
7
|
Content,
|
|
7
8
|
ExternalLink,
|
|
@@ -99,6 +100,16 @@ describe("validateCast", () => {
|
|
|
99
100
|
"valid blockquote",
|
|
100
101
|
{ type: "blockquote", children: [{ type: "text", value: "Blockquote text" }] } satisfies Blockquote,
|
|
101
102
|
],
|
|
103
|
+
[
|
|
104
|
+
"valid cas suggestion",
|
|
105
|
+
{
|
|
106
|
+
type: "casSuggestion",
|
|
107
|
+
original: [{ type: "text", value: "Original text" }],
|
|
108
|
+
suggested: [{ type: "text", value: "Suggested text" }],
|
|
109
|
+
message: "This is a suggestion",
|
|
110
|
+
method: "database; reusable",
|
|
111
|
+
} satisfies CasSuggestion,
|
|
112
|
+
],
|
|
102
113
|
])("validates a %s", (_, input) => {
|
|
103
114
|
const root: Root = { type: "root", children: [input as Content] };
|
|
104
115
|
expect(() => validateCast(root)).not.toThrow();
|
|
@@ -317,6 +328,66 @@ describe("validateCast", () => {
|
|
|
317
328
|
children: [{ type: "listItem", children: "notAnArray" as unknown as InlineContent[] }],
|
|
318
329
|
} satisfies Root,
|
|
319
330
|
],
|
|
331
|
+
[
|
|
332
|
+
"invalid cas suggestion - original not an array",
|
|
333
|
+
{
|
|
334
|
+
type: "root",
|
|
335
|
+
children: [
|
|
336
|
+
{
|
|
337
|
+
type: "casSuggestion",
|
|
338
|
+
original: "notAnArray" as unknown as InlineContent[],
|
|
339
|
+
suggested: [{ type: "text", value: "Suggested text" }],
|
|
340
|
+
message: "This is a suggestion",
|
|
341
|
+
method: "database; reusable",
|
|
342
|
+
},
|
|
343
|
+
],
|
|
344
|
+
} satisfies Root,
|
|
345
|
+
],
|
|
346
|
+
[
|
|
347
|
+
"invalid cas suggestion - suggested not an array",
|
|
348
|
+
{
|
|
349
|
+
type: "root",
|
|
350
|
+
children: [
|
|
351
|
+
{
|
|
352
|
+
type: "casSuggestion",
|
|
353
|
+
original: [{ type: "text", value: "Original text" }],
|
|
354
|
+
suggested: "notAnArray" as unknown as InlineContent[],
|
|
355
|
+
message: "This is a suggestion",
|
|
356
|
+
method: "database; reusable",
|
|
357
|
+
},
|
|
358
|
+
],
|
|
359
|
+
} satisfies Root,
|
|
360
|
+
],
|
|
361
|
+
[
|
|
362
|
+
"invalid cas suggestion - message not a string",
|
|
363
|
+
{
|
|
364
|
+
type: "root",
|
|
365
|
+
children: [
|
|
366
|
+
{
|
|
367
|
+
type: "casSuggestion",
|
|
368
|
+
original: [{ type: "text", value: "Original text" }],
|
|
369
|
+
suggested: [{ type: "text", value: "Suggested text" }],
|
|
370
|
+
message: null as unknown as string,
|
|
371
|
+
method: "database; reusable",
|
|
372
|
+
},
|
|
373
|
+
],
|
|
374
|
+
} satisfies Root,
|
|
375
|
+
],
|
|
376
|
+
[
|
|
377
|
+
"invalid cas suggestion - method not a string",
|
|
378
|
+
{
|
|
379
|
+
type: "root",
|
|
380
|
+
children: [
|
|
381
|
+
{
|
|
382
|
+
type: "casSuggestion",
|
|
383
|
+
original: [{ type: "text", value: "Original text" }],
|
|
384
|
+
suggested: [{ type: "text", value: "Suggested text" }],
|
|
385
|
+
message: "This is a suggestion",
|
|
386
|
+
method: 123 as unknown as string,
|
|
387
|
+
},
|
|
388
|
+
],
|
|
389
|
+
} satisfies Root,
|
|
390
|
+
],
|
|
320
391
|
])("throws an error for %s", (_, input) => {
|
|
321
392
|
expect(() => validateCast(input)).toThrow(InvalidCastError);
|
|
322
393
|
});
|
package/src/lib/validate-cast.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
CasSuggestion,
|
|
2
3
|
Code,
|
|
3
4
|
Content,
|
|
4
5
|
ExternalLink,
|
|
@@ -137,6 +138,35 @@ function assertValidInternalLink(value: unknown): asserts value is InternalLink
|
|
|
137
138
|
link.children.forEach(assertTextNode);
|
|
138
139
|
}
|
|
139
140
|
|
|
141
|
+
function assertValidCasSuggestion(value: unknown): asserts value is CasSuggestion {
|
|
142
|
+
assertNonNullObject(value);
|
|
143
|
+
|
|
144
|
+
const suggestion = value as CasSuggestion;
|
|
145
|
+
|
|
146
|
+
// Validate required fields
|
|
147
|
+
if (!Array.isArray(suggestion.original)) {
|
|
148
|
+
throw new InvalidCastError("Invalid casSuggestion: original must be an array");
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (!Array.isArray(suggestion.suggested)) {
|
|
152
|
+
throw new InvalidCastError("Invalid casSuggestion: suggested must be an array");
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (typeof suggestion.message !== "string") {
|
|
156
|
+
throw new InvalidCastError("Invalid casSuggestion: message must be a string");
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (typeof suggestion.method !== "string") {
|
|
160
|
+
throw new InvalidCastError("Invalid casSuggestion: method must be a string");
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
164
|
+
suggestion.original.forEach(assertValidContent);
|
|
165
|
+
|
|
166
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
167
|
+
suggestion.suggested.forEach(assertValidContent);
|
|
168
|
+
}
|
|
169
|
+
|
|
140
170
|
function assertValidContent(value: unknown): asserts value is Content {
|
|
141
171
|
assertNonNullObject(value);
|
|
142
172
|
const content = value as Content;
|
|
@@ -157,6 +187,9 @@ function assertValidContent(value: unknown): asserts value is Content {
|
|
|
157
187
|
case "internalLink":
|
|
158
188
|
assertValidInternalLink(content);
|
|
159
189
|
break;
|
|
190
|
+
case "casSuggestion":
|
|
191
|
+
assertValidCasSuggestion(content);
|
|
192
|
+
break;
|
|
160
193
|
case "heading":
|
|
161
194
|
assertValidHeading(content);
|
|
162
195
|
break;
|