-
Notifications
You must be signed in to change notification settings - Fork 47
/
Copy pathcrux-api-util.js
90 lines (82 loc) · 3.21 KB
/
crux-api-util.js
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
// Copyright 2020 Google LLC.
// SPDX-License-Identifier: Apache-2.0
const CrUXApiUtil = {};
// Get your CrUX API key at https://goo.gle/crux-api-key.
CrUXApiUtil.API_KEY = '[YOUR_API_KEY]';
CrUXApiUtil.API_HOST = 'https://chromeuxreport.googleapis.com';
CrUXApiUtil.HISTORY_API_ENDPOINT_PATH = `/v1/records:queryHistoryRecord?key=${CrUXApiUtil.API_KEY}`;
CrUXApiUtil.HISTORY_API_ENDPOINT = `${CrUXApiUtil.API_HOST}${CrUXApiUtil.HISTORY_API_ENDPOINT_PATH}`;
CrUXApiUtil.API_ENDPOINT_PATH = `/v1/records:queryRecord?key=${CrUXApiUtil.API_KEY}`;
CrUXApiUtil.API_ENDPOINT = `${CrUXApiUtil.API_HOST}${CrUXApiUtil.API_ENDPOINT_PATH}`;
CrUXApiUtil.API_BATCH_ENDPOINT = `${CrUXApiUtil.API_HOST}/batch/`;
CrUXApiUtil.query = function (requestBody) {
if (CrUXApiUtil.API_KEY == '[YOUR_API_KEY]') {
throw 'Replace "YOUR_API_KEY" with your private CrUX API key. Get a key at https://goo.gle/crux-api-key.';
}
return fetch(CrUXApiUtil.API_ENDPOINT, {
method: 'POST',
body: JSON.stringify(requestBody)
}).then(response => response.json()).then(response => {
if (response.error) {
return Promise.reject(response);
}
return response;
});
};
CrUXApiUtil.queryHistory = function (requestBody) {
if (CrUXApiUtil.API_KEY == '[YOUR_API_KEY]') {
throw 'Replace "YOUR_API_KEY" with your private CrUX API key. Get a key at https://goo.gle/crux-api-key.';
}
return fetch(CrUXApiUtil.HISTORY_API_ENDPOINT, {
method: 'POST',
body: JSON.stringify(requestBody)
}).then(response => response.json()).then(response => {
if (response.error) {
return Promise.reject(response);
}
return response;
});
};
CrUXApiUtil.batch = function (requests) {
if (CrUXApiUtil.API_KEY == '[YOUR_API_KEY]') {
throw 'Replace "YOUR_API_KEY" with your private CrUX API key. Get a key at https://goo.gle/crux-api-key.';
}
const BOUNDARY = 'BATCH_BOUNDARY';
return fetch(CrUXApiUtil.API_BATCH_ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': `multipart/mixed; boundary="${BOUNDARY}"`
},
body: `--${BOUNDARY}\n` + requests.map((requestBody, i) => {
return `
POST ${CrUXApiUtil.API_ENDPOINT_PATH} HTTP/1.1
Content-ID: crux-${i}
Content-Type: application/json
${JSON.stringify(requestBody)}`;
}).join(`\n\n--${BOUNDARY}\n`) + `\n\n--${BOUNDARY}--`
}).then(response => {
const contentTypeHeader = response.headers.get('Content-Type');
const boundaryPattern = /\bboundary=([\w-]+)\b/i;
if (!boundaryPattern.test(contentTypeHeader)) {
throw `Unable to parse boundary directive from Content-Type response header: "${contentTypeHeader}"`;
}
const boundary = contentTypeHeader.match(boundaryPattern)[1];
return Promise.all([
Promise.resolve(boundary),
response.text()
]);
}).then(([boundary, response]) => {
const responseParts = response.split(`--${boundary}`);
// Eject boundary bookends
responseParts.shift();
responseParts.pop();
const responseJSONPattern = /\n({[\s\S]*)/m;
return responseParts.map(part => {
if (!responseJSONPattern.test(part)) {
console.error(`Unable to parse CrUX API response from:\n${response}`);
return null;
}
return JSON.parse(part.match(responseJSONPattern)[1]);
});
});
}