-
Notifications
You must be signed in to change notification settings - Fork 21
/
lighthouse-api.mjs
113 lines (97 loc) · 3.09 KB
/
lighthouse-api.mjs
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
/**
* Copyright 2018 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import fs from 'fs';
import url from 'url';
const URL = url.URL;
import fetch from 'node-fetch';
const LHR = JSON.parse(fs.readFileSync('./lhr.json', 'utf8'));
/**
* Wrapper for interactions with the Lighthouse API.
*/
class LighthouseAPI {
/**
* @export
*/
static get version() { return 'v5'; }
/**
* @export
*/
static get endpoints() {
// const scope = 'https://develop-pagespeedonline.sandbox.googleapis.com/pagespeedonline';
// const scope = 'https://www-googleapis-staging.sandbox.google.com/pagespeedonline';
const scope = 'https://www.googleapis.com/pagespeedonline';
return {
scope,
audit: `${scope}/${this.version}/runPagespeed`,
};
}
/**
* @constructor
* @param {string} apiKey
*/
constructor(apiKey) {
this.apiKey = apiKey;
}
/**
* Audits a site.
* @param {string} url Url to audit.
* @return {!Object} API response.
* @export
*/
async audit(url) {
const auditUrl = new URL(LighthouseAPI.endpoints.audit);
auditUrl.searchParams.set('key', this.apiKey);
auditUrl.searchParams.set('locale', 'en_US');
auditUrl.searchParams.set('strategy', 'mobile');
// Include all categories.
const cats = Object.keys(LHR.categories).filter(cat => cat !== 'pwa');
cats.forEach(cat => {
auditUrl.searchParams.append('category', cat);
});
auditUrl.searchParams.set('url', url);
console.info('Lighthouse API request:', auditUrl.toString());
try {
const resp = await fetch(auditUrl);
const json = await resp.json();
if (json.captchaResult && json.captchaResult !== 'CAPTCHA_NOT_NEEDED') {
throw Error(`Lighthouse API response: ${json.captchaResult}`);
}
if (json.error) {
throw Error(`${json.error.message}`);
}
if (!resp.ok) {
throw Error(`${resp.status} from Lighthouse API: ${resp.statusText}`);
}
let lhr = json.lighthouseResult;
if (!lhr) {
throw Error('Lighthouse API response: missing lighthouseResult.');
}
const crux = {};
// Firestore cannot save object keys with values of undefined, so make
// sure to only include each crux key when the API has populated values.
if (json.loadingExperience) {
crux.loadingExperience = json.loadingExperience;
}
if (json.originLoadingExperience) {
crux.originLoadingExperience = json.originLoadingExperience;
}
return {lhr, crux};
} catch (err) {
throw err;
}
}
}
export default LighthouseAPI;