@archer-edu/dxp-directus-cli
Version:
138 lines • 6.96 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.runLighthouse = void 0;
const node_fetch_1 = __importDefault(require("node-fetch"));
const api_1 = require("./support/api");
const DEFAULT_API_URL = "https://dashboard-xi-olive.vercel.app/api/lighthouse-trigger";
const DEFAULT_RESULT_URL_BASE = "https://dashboard-xi-olive.vercel.app/api/lighthouse-results";
const register = (program) => {
program
.command("lighthouse-run")
.alias("lhr")
.description("Runs a Lighthouse analysis against the configured site.")
.option("--auth-token <authToken>", "Auth token (or set LIGHTHOUSE_SERVERLESS_AUTH_TOKEN env var)")
.option("--sitemap-url <sitemapUrl>", "Sitemap URL (or set SITEMAP_URL env var)")
.option("--api-url <apiUrl>", "API URL for trigger")
.option("--result-url-base <resultUrlBase>", "Base URL for result polling")
.option("--max-urls <maxUrls>", "Maximum number of URLs to test")
.option("--poll-interval <pollInterval>", "Polling interval in seconds")
.option("--max-attempts <maxAttempts>", "Maximum number of polling attempts")
.action((options) => __awaiter(void 0, void 0, void 0, function* () {
try {
yield runLighthouse(options);
}
catch (error) {
console.error(error.message);
process.exitCode = 1;
}
}));
};
exports.default = register;
function runLighthouse(options, logger = console.log) {
return __awaiter(this, void 0, void 0, function* () {
const resolved = resolveOptions(options);
logger("Triggering Lighthouse test...");
const response = yield (0, node_fetch_1.default)(resolved.apiUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${resolved.authToken}`,
},
body: JSON.stringify({
sitemap_url: resolved.sitemapUrl,
// GitHub workflow_dispatch inputs must be strings.
max_urls: resolved.maxUrls,
}),
});
const json = yield readJson(response, "trigger");
console.log(JSON.stringify(json, null, 2));
const runId = json.run_id || json.runId;
if (!runId) {
console.error("Failed to retrieve run_id from response");
process.exitCode = 1;
return;
}
logger(`Lighthouse test started. Run ID: ${runId}`);
logger(`Polling for results (every ${resolved.pollInterval}s, up to ${formatMinutes(resolved.pollInterval, resolved.maxAttempts)} mins)...`);
for (let attempt = 0; attempt < resolved.maxAttempts; attempt++) {
yield sleep(resolved.pollInterval * 1000);
logger(`Attempt ${attempt + 1}...`);
const resultUrl = getResultUrl(resolved.resultUrlBase, runId);
const resultResponse = yield (0, node_fetch_1.default)(resultUrl);
const outerResult = yield readJson(resultResponse, "result");
const result = outerResult.result || {};
const { status, results } = result;
const hasResults = results != null;
if (status === "completed" && hasResults) {
logger("Lighthouse test completed.");
console.dir(results, { depth: null });
return;
}
logger(`Status: ${status || "unknown"} | Results ready: ${hasResults}`);
}
logger(`Timeout waiting for Lighthouse results after ${formatMinutes(resolved.pollInterval, resolved.maxAttempts)} minutes`);
});
}
exports.runLighthouse = runLighthouse;
function resolveOptions(options) {
const authToken = options.authToken || process.env.LIGHTHOUSE_SERVERLESS_AUTH_TOKEN;
const sitemapUrl = options.sitemapUrl || process.env.SITEMAP_URL;
if (!authToken)
throw new Error("A value for auth-token is required. Pass --auth-token or set LIGHTHOUSE_SERVERLESS_AUTH_TOKEN.");
if (!sitemapUrl)
throw new Error("A value for sitemap-url is required. Pass --sitemap-url or set SITEMAP_URL.");
return {
authToken,
sitemapUrl,
apiUrl: options.apiUrl || process.env.LIGHTHOUSE_SERVERLESS_API_URL || DEFAULT_API_URL,
resultUrlBase: options.resultUrlBase || process.env.LIGHTHOUSE_SERVERLESS_RESULT_URL_BASE || DEFAULT_RESULT_URL_BASE,
maxUrls: parsePositiveIntegerString(options.maxUrls || process.env.LIGHTHOUSE_SERVERLESS_MAX_URLS, 1, "max-urls"),
pollInterval: parsePositiveInteger(options.pollInterval || process.env.LIGHTHOUSE_SERVERLESS_POLL_INTERVAL, 60, "poll-interval"),
maxAttempts: parsePositiveInteger(options.maxAttempts || process.env.LIGHTHOUSE_SERVERLESS_MAX_ATTEMPTS, 10, "max-attempts")
};
}
function parsePositiveIntegerString(value, defaultValue, name) {
return parsePositiveInteger(value, defaultValue, name).toString();
}
function parsePositiveInteger(value, defaultValue, name) {
if (value == null)
return defaultValue;
const parsedValue = typeof value === "number" ? value : parseInt(value, 10);
if (!Number.isInteger(parsedValue) || parsedValue < 1) {
throw new Error(`A positive integer is required for ${name}.`);
}
return parsedValue;
}
function readJson(response, label) {
return __awaiter(this, void 0, void 0, function* () {
const body = yield (0, api_1.safeJsonParse)(response);
if (!response.ok) {
throw new Error(`Lighthouse ${label} request failed (${response.status} ${response.statusText}): ${JSON.stringify(body)}`);
}
return body;
});
}
function getResultUrl(resultUrlBase, runId) {
const resultUrl = new URL(resultUrlBase);
resultUrl.searchParams.set("run_id", runId);
return resultUrl.toString();
}
function formatMinutes(pollInterval, maxAttempts) {
return ((pollInterval * maxAttempts) / 60).toFixed(1);
}
function sleep(milliseconds) {
return new Promise(resolve => setTimeout(resolve, milliseconds));
}
//# sourceMappingURL=lighthouse-run.js.map