/
graphql.ts
126 lines (120 loc) · 3.16 KB
/
graphql.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
import { AxiosRequestConfig } from "axios";
import clonedeep from "lodash.clonedeep";
import get from "lodash.get";
import {
ITriggerClassType,
ITriggerContructorParams,
IHelpers,
AnyObject,
ITriggerOptions,
} from "actionsflow-core";
class ResponseError extends Error {
data: string;
constructor(data: string) {
super("response error");
this.name = "ResponseError";
this.data = data;
}
}
export default class Graphql implements ITriggerClassType {
options: ITriggerOptions = {};
helpers: IHelpers;
getItemKey(item: AnyObject): string {
let key = "";
const deduplicationKey = this.options.deduplicationKey;
if (deduplicationKey) {
key = get(item, deduplicationKey as string) as string;
if (!key) {
throw new Error("Can not get deduplicationKey from item");
}
} else if (item.id) {
key = item.id as string;
} else if (item.key) {
key = item.key as string;
}
if (key) {
return this.options.url + "__" + key;
}
return this.helpers.createContentDigest(item);
}
constructor({ helpers, options }: ITriggerContructorParams) {
this.options = options;
this.helpers = helpers;
}
async run(): Promise<AnyObject[]> {
const {
url,
itemsPath = "data.items",
requestConfig = {},
headers,
query,
variables,
} = this.options as {
url?: string;
itemsPath?: string;
deduplicationKey?: string;
requestConfig?: AnyObject;
query?: string;
variables?: AnyObject;
headers?: AnyObject;
};
if (!url) {
throw new Error("Miss param url!");
}
if (!query) {
throw new Error("Miss param query!");
}
const items: AnyObject[] = [];
const config: AxiosRequestConfig = {
method: "POST",
...requestConfig,
headers: {
...headers,
},
data: {
query: query,
variables: variables || {},
},
url: url as string,
};
// get updates
let requestResult;
try {
requestResult = await this.helpers.axios(config);
} catch (e) {
if (e.code === "ECONNREFUSED") {
throw new Error(
`It was not possible to connect to the URL. Please make sure the URL "${url}" it is valid!`
);
}
this.helpers.log.error(`Graphql fetch ${url} error: `, e);
throw e;
}
if (
requestResult &&
requestResult.data &&
requestResult.data.errors &&
requestResult.data.errors.length > 0
) {
throw new ResponseError(JSON.stringify(requestResult.data));
}
// For now we just take the items and ignore everything else
if (requestResult && requestResult.data) {
const itemsArray: AnyObject[] = itemsPath
? get(requestResult.data, itemsPath)
: requestResult.data;
if (!Array.isArray(itemsArray)) {
throw new Error("Can not found a valid items result");
}
const deepClonedData = clonedeep(itemsArray);
itemsArray.forEach((item) => {
if (this.options.shouldIncludeRawBody) {
item.raw__body = deepClonedData;
}
items.push(item);
});
}
// if need
return items;
}
}