-
Notifications
You must be signed in to change notification settings - Fork 7
/
guards.ts
160 lines (135 loc) · 3.55 KB
/
guards.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import {
Root,
List,
Blockquote,
Block,
Link,
ItemLink,
InlineItem,
Code,
ListItem,
Paragraph,
Heading,
Node,
Span,
WithChildrenNode,
InlineNode,
NodeType,
Record as DatoCmsRecord,
StructuredText,
ThematicBreak,
Document,
} from './types';
import {
allowedNodeTypes,
headingNodeType,
spanNodeType,
rootNodeType,
paragraphNodeType,
listNodeType,
listItemNodeType,
blockquoteNodeType,
blockNodeType,
codeNodeType,
linkNodeType,
itemLinkNodeType,
inlineItemNodeType,
inlineNodeTypes,
thematicBreakNodeType,
} from './definitions';
export function hasChildren(node: Node): node is WithChildrenNode {
return 'children' in node;
}
export function isInlineNode(node: Node): node is InlineNode {
return (inlineNodeTypes as NodeType[]).includes(node.type);
}
export function isHeading(node: Node): node is Heading {
return node.type === headingNodeType;
}
export function isSpan(node: Node): node is Span {
return node.type === spanNodeType;
}
export function isRoot(node: Node): node is Root {
return node.type === rootNodeType;
}
export function isParagraph(node: Node): node is Paragraph {
return node.type === paragraphNodeType;
}
export function isList(node: Node): node is List {
return node.type === listNodeType;
}
export function isListItem(node: Node): node is ListItem {
return node.type === listItemNodeType;
}
export function isBlockquote(node: Node): node is Blockquote {
return node.type === blockquoteNodeType;
}
export function isBlock(node: Node): node is Block {
return node.type === blockNodeType;
}
export function isCode(node: Node): node is Code {
return node.type === codeNodeType;
}
export function isLink(node: Node): node is Link {
return node.type === linkNodeType;
}
export function isItemLink(node: Node): node is ItemLink {
return node.type === itemLinkNodeType;
}
export function isInlineItem(node: Node): node is InlineItem {
return node.type === inlineItemNodeType;
}
export function isThematicBreak(node: Node): node is ThematicBreak {
return node.type === thematicBreakNodeType;
}
function isObject(obj: unknown): obj is Record<string, unknown> {
return Boolean(typeof obj === 'object' && obj);
}
export function isNodeType(value: string): value is NodeType {
return allowedNodeTypes.includes(value as NodeType);
}
export function isNode(obj: unknown): obj is Node {
return Boolean(
isObject(obj) &&
'type' in obj &&
typeof obj.type === 'string' &&
isNodeType(obj.type),
);
}
export function isStructuredText<
R1 extends DatoCmsRecord,
R2 extends DatoCmsRecord = R1
>(obj: unknown): obj is StructuredText<R1, R2> {
return Boolean(isObject(obj) && 'value' in obj && isDocument(obj.value));
}
export function isDocument(obj: unknown): obj is Document {
return Boolean(
isObject(obj) &&
'schema' in obj &&
'document' in obj &&
obj.schema === 'dast',
);
}
export function isEmptyDocument(obj: unknown): boolean {
if (!obj) {
return true;
}
const document =
isStructuredText(obj) && isDocument(obj.value)
? obj.value
: isDocument(obj)
? obj
: null;
if (!document) {
throw new Error(
'Passed object is neither null, a Structured Text value or a DAST document',
);
}
return (
document.document.children.length === 1 &&
document.document.children[0].type === 'paragraph' &&
document.document.children[0].children.length === 1 &&
document.document.children[0].children[0].type === 'span' &&
document.document.children[0].children[0].value === ''
);
}