Skip to content

Commit 9d34b2c

Browse files
committed
⚡️refactor everything
1 parent 9cdfc09 commit 9d34b2c

File tree

6 files changed

+303
-75
lines changed

6 files changed

+303
-75
lines changed

deps.ts

+43-5
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,58 @@
11
export {
22
graphql,
33
GraphQLBoolean,
4-
type GraphQLFieldConfigMap,
4+
GraphQLDeprecatedDirective,
5+
GraphQLEnumType,
6+
GraphQLError,
7+
GraphQLInputObjectType,
58
GraphQLInt,
69
GraphQLInterfaceType,
7-
type GraphQLInterfaceTypeConfig,
810
GraphQLList,
911
GraphQLNonNull,
1012
GraphQLObjectType,
11-
type GraphQLObjectTypeConfig,
13+
GraphQLScalarType,
1214
GraphQLSchema,
1315
GraphQLString,
16+
graphqlSync,
17+
GraphQLUnionType,
1418
} from "https://deno.land/x/[email protected]/mod.ts";
19+
20+
export type {
21+
GraphQLAbstractType,
22+
GraphQLCompositeType,
23+
GraphQLEnumTypeConfig,
24+
GraphQLEnumValue,
25+
GraphQLEnumValueConfig,
26+
GraphQLEnumValueConfigMap,
27+
GraphQLField,
28+
GraphQLFieldConfig,
29+
GraphQLFieldConfigMap,
30+
GraphQLFieldMap,
31+
GraphQLFormattedError,
32+
GraphQLInputObjectTypeConfig,
33+
GraphQLInterfaceTypeConfig,
34+
GraphQLNamedType,
35+
GraphQLNullableType,
36+
GraphQLObjectTypeConfig,
37+
GraphQLSchemaConfig,
38+
GraphQLType,
39+
GraphQLTypeResolver,
40+
GraphQLUnionTypeConfig,
41+
Thunk,
42+
} from "https://deno.land/x/[email protected]/mod.ts";
43+
1544
export { default as PQueue } from "https://deno.land/x/[email protected]/mod.ts";
45+
1646
export {
47+
denoDomDisableQuerySelectorCodeGeneration as disableCodeGen,
1748
DOMParser,
18-
Element,
1949
} from "https://deno.land/x/[email protected]/deno-dom-wasm.ts";
20-
export { serve } from "https://deno.land/[email protected]/http/server.ts";
50+
51+
export type { Element } from "https://deno.land/x/[email protected]/deno-dom-wasm.ts";
52+
53+
export {
54+
serve,
55+
type ServeInit,
56+
Server,
57+
type ServerInit,
58+
} from "https://deno.land/[email protected]/http/server.ts";

lib/document.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ export const TDocument = new GraphQLObjectType({
3838
if (!meta) {
3939
meta = element?.querySelector(`meta[property='${name}']`);
4040
}
41-
return getAttributeOfElement(meta!, "content") ?? null;
41+
try {
42+
return getAttributeOfElement(meta!, "content");
43+
} catch {
44+
return null;
45+
}
4246
},
4347
},
4448
}),

lib/helpers.ts

+24-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,34 @@
11
import { Element } from "../deps.ts";
22

3-
export function getAttributeOfElement(element: Element, name: string) {
3+
export function getAttributeOfElement(
4+
element: Element,
5+
name?: string,
6+
trim = false,
7+
): string | null {
8+
if (element == null || name == null) {
9+
return null;
10+
}
411
const attribute = element.getAttribute(name);
5-
if (attribute == null) return null;
12+
if (attribute == null) {
13+
return null;
14+
}
15+
return trim ? attribute.trim() : attribute;
16+
}
617

7-
return attribute;
18+
export function getAttributesOfElement(element: Element, trim = false) {
19+
if (element == null) {
20+
return null;
21+
}
22+
const names = element.getAttributeNames();
23+
if (names == null || names.length === 0) {
24+
return {};
25+
}
26+
return Object.fromEntries(names.map(
27+
(attr) => [attr, getAttributeOfElement(element, attr, trim)],
28+
));
829
}
930

1031
export function resolveURL(base: string, url: string) {
1132
const uri = new URL(url, base);
12-
1333
return uri.toString();
1434
}

lib/shared.ts

+63-41
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ export const shared: GraphQLFieldConfigMap<Element, any> = {
6767
selector,
6868
trim: {
6969
type: GraphQLBoolean,
70-
description: "Trim any leading and trailing whitespace from the value (optional, default: false)",
70+
description:
71+
"Trim any leading and trailing whitespace from the value (optional, default: false)",
7172
defaultValue: false,
7273
},
7374
},
@@ -79,22 +80,30 @@ export const shared: GraphQLFieldConfigMap<Element, any> = {
7980
},
8081
table: {
8182
type: new GraphQLList(new GraphQLList(GraphQLString)),
82-
description: "Returns a two-dimensional array representing an HTML table element's contents. The first level is a list of rows (`<tr>`), and each row is an array of cell (`<td>`) contents.",
83+
description:
84+
"Returns a two-dimensional array representing an HTML table element's contents. The first level is a list of rows (`<tr>`), and each row is an array of cell (`<td>`) contents.",
8385
args: {
8486
selector,
87+
trim: {
88+
type: GraphQLBoolean,
89+
description:
90+
"Trim any leading and trailing whitespace from the values (optional, default: false)",
91+
defaultValue: false,
92+
},
8593
},
86-
resolve(element: Element, { selector }: ElementParams) {
94+
resolve(element: Element, { selector, trim }: TextParams) {
8795
element = selector ? element.querySelector(selector)! : element;
8896

8997
const result = element && Array.from(
9098
element.querySelectorAll("tr"),
91-
).map((row) =>
92-
Array.from((row as Element).querySelectorAll("td")).map((td) =>
93-
td.textContent.trim()
94-
)
99+
(row) =>
100+
Array.from(
101+
(row as Element).querySelectorAll("td"),
102+
(td) => (trim ? td.textContent.trim() : td.textContent),
103+
),
95104
);
96105

97-
return result.filter((row) => row.length > 0);
106+
return result.filter(Boolean).filter((row) => row.length > 0);
98107
},
99108
},
100109
tag: {
@@ -103,71 +112,85 @@ export const shared: GraphQLFieldConfigMap<Element, any> = {
103112
args: { selector },
104113
resolve(element: Element, { selector }: ElementParams) {
105114
element = selector ? element.querySelector(selector)! : element;
106-
107-
return element && element.tagName;
115+
return element?.tagName ?? null;
108116
},
109117
},
110118
attr: {
111119
type: GraphQLString,
112-
description: "The value of a given attribute from the selected node (`href`, `src`, etc.), if it exists.",
120+
description:
121+
"The value of a given attribute from the selected node (`href`, `src`, etc.), if it exists.",
113122
args: {
114123
selector,
115124
name: {
116125
type: new GraphQLNonNull(GraphQLString),
117126
description: "The name of the attribute",
118127
},
128+
trim: {
129+
type: GraphQLBoolean,
130+
description:
131+
"Trim any leading and trailing whitespace from the value (optional, default: false)",
132+
defaultValue: false,
133+
},
119134
},
120-
resolve(element: Element, { selector, name }: TParams) {
135+
resolve(element: Element, { selector, name, trim }: TParams) {
121136
element = selector ? element.querySelector(selector)! : element;
122-
if (element == null || name == null) {
123-
return null;
124-
}
125-
126-
const attribute = element.getAttribute(name);
127-
if (attribute == null) {
128-
return null;
129-
}
130-
131-
return attribute;
137+
return getAttributeOfElement(element, name as string, trim);
132138
},
133139
},
134140
href: {
135141
type: GraphQLString,
136-
description: "Shorthand for `attr(name: \"href\")`",
142+
description: "Shorthand for `attr(name: 'href')`",
137143
args: {
138144
selector,
145+
trim: {
146+
type: GraphQLBoolean,
147+
description:
148+
"Trim any leading and trailing whitespace from the value (optional, default: false)",
149+
defaultValue: false,
150+
},
139151
},
140-
resolve(element: Element, { selector }: ElementParams) {
152+
resolve(element: Element, { selector, trim }: TextParams) {
141153
element = selector ? element.querySelector(selector)! : element;
142-
if (element == null) return null;
143-
144-
return getAttributeOfElement(element, "href");
154+
return getAttributeOfElement(element, "href", trim);
145155
},
146156
},
147157
src: {
148158
type: GraphQLString,
149-
description: "Shorthand for `attr(name: \"src\")`",
159+
description: "Shorthand for `attr(name: 'src')`",
150160
args: {
151161
selector,
162+
trim: {
163+
type: GraphQLBoolean,
164+
description:
165+
"Trim any leading and trailing whitespace from the value (optional, default: false)",
166+
defaultValue: false,
167+
},
152168
},
153-
resolve(element: Element, { selector }: ElementParams) {
169+
resolve(element: Element, { selector, trim }: TextParams) {
154170
element = selector ? element.querySelector(selector)! : element;
155171
if (element == null) return null;
156172

157-
return getAttributeOfElement(element, "src");
173+
return getAttributeOfElement(element, "src", trim);
158174
},
159175
},
160176
class: {
161177
type: GraphQLString,
162-
description: "The class attribute of the selected node, if any exists. Formatted as a space-separated list of CSS class names.",
178+
description:
179+
"The class attribute of the selected node, if any exists. Formatted as a space-separated list of CSS class names.",
163180
args: {
164181
selector,
182+
trim: {
183+
type: GraphQLBoolean,
184+
description:
185+
"Trim any leading and trailing whitespace from the value (optional, default: false)",
186+
defaultValue: false,
187+
},
165188
},
166-
resolve(element: Element, { selector }: TParams) {
189+
resolve(element: Element, { selector, trim }: TextParams) {
167190
element = selector ? element.querySelector(selector)! : element;
168191
if (element == null) return null;
169192

170-
return getAttributeOfElement(element, "class");
193+
return getAttributeOfElement(element, "class", trim);
171194
},
172195
},
173196
classList: {
@@ -179,24 +202,22 @@ export const shared: GraphQLFieldConfigMap<Element, any> = {
179202
resolve(element: Element, { selector }: ElementParams) {
180203
element = selector ? element.querySelector(selector)! : element;
181204
if (element == null) return null;
182-
183-
const attribute = getAttributeOfElement(element, "class");
184-
if (attribute == null) return null;
185-
186-
return attribute.split(" ");
205+
return [...(element?.classList.values() ?? [])];
187206
},
188207
},
189208
has: {
190209
type: GraphQLBoolean,
191-
description: "Returns true if an element with the given selector exists, otherwise false.",
210+
description:
211+
"Returns true if an element with the given selector exists, otherwise false.",
192212
args: { selector },
193213
resolve(element: Element, { selector }: ElementParams) {
194214
return !!element.querySelector(selector!);
195215
},
196216
},
197217
count: {
198218
type: GraphQLInt,
199-
description: "Returns the number of DOM nodes that match the given selector, or 0 if no nodes match.",
219+
description:
220+
"Returns the number of DOM nodes that match the given selector, or 0 if no nodes match.",
200221
args: { selector },
201222
resolve(element: Element, { selector }: ElementParams) {
202223
if (!selector) return 0;
@@ -231,7 +252,8 @@ export const shared: GraphQLFieldConfigMap<Element, any> = {
231252
},
232253
childNodes: {
233254
type: new GraphQLList(TElement),
234-
description: "Child nodes (not elements) of a selected node, including any text nodes.",
255+
description:
256+
"Child nodes (not elements) of a selected node, including any text nodes.",
235257
resolve(element: Element) {
236258
return Array.from(element.childNodes);
237259
},

0 commit comments

Comments
 (0)