Skip to content

Commit eca2a8e

Browse files
authored
Remove axios dependency, using fetch instead (#4737)
1 parent 8d0f094 commit eca2a8e

File tree

6 files changed

+46
-327
lines changed

6 files changed

+46
-327
lines changed

11ty/biblio.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
import axios from "axios";
21
import { readFile } from "fs/promises";
32
import { glob } from "glob";
43
import invert from "lodash-es/invert";
54
import uniq from "lodash-es/uniq";
65
import { join } from "path";
76

87
import { loadFromFile } from "./cheerio";
9-
import { wrapAxiosRequest } from "./common";
8+
import { fetchOptionalText } from "./common";
109

1110
export const biblioPattern = /\[\[\??([\w-]+)\]\]/g;
1211

@@ -33,16 +32,16 @@ export async function getBiblio() {
3332
ref in aliases ? aliases[ref as keyof typeof aliases] : ref
3433
);
3534

36-
const response = await wrapAxiosRequest(
37-
axios.get(`https://api.specref.org/bibrefs?refs=${uniqueRefs.join(",")}`)
35+
const responseText = await fetchOptionalText(
36+
`https://api.specref.org/bibrefs?refs=${uniqueRefs.join(",")}`
3837
);
39-
if (response.data) {
40-
for (const [from, to] of Object.entries(invert(aliases)))
41-
response.data[to] = response.data[from];
38+
const data = responseText ? JSON.parse(responseText) : null;
39+
if (data) {
40+
for (const [from, to] of Object.entries(invert(aliases))) data[to] = data[from];
4241
}
4342

4443
return {
45-
...response.data,
44+
...data,
4645
...localBiblio,
4746
};
4847
}

11ty/common.ts

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
/** @fileoverview Common functions used by multiple parts of the build process */
22

3-
import { AxiosError, type AxiosResponse } from "axios";
4-
53
import type { WcagItem } from "./guidelines";
64

75
/** Generates an ID for heading permalinks. Equivalent to wcag:generate-id in base.xslt. */
@@ -17,10 +15,7 @@ export function generateId(title: string) {
1715
export const resolveDecimalVersion = (version: `${number}`) => version.split("").join(".");
1816

1917
/** Sort function for ordering WCAG principle/guideline/SC numbers ascending */
20-
export function wcagSort(
21-
a: WcagItem,
22-
b: WcagItem
23-
) {
18+
export function wcagSort(a: WcagItem, b: WcagItem) {
2419
const aParts = a.num.split(".").map((n) => +n);
2520
const bParts = b.num.split(".").map((n) => +n);
2621

@@ -31,22 +26,32 @@ export function wcagSort(
3126
return 0;
3227
}
3328

29+
type FetchText = (...args: Parameters<typeof fetch>) => Promise<string>;
30+
31+
/** Performs a fetch, returning body text or throwing an error if a 4xx/5xx response occurs. */
32+
export const fetchText: FetchText = (input, init) =>
33+
fetch(input, init).then(
34+
(response) => {
35+
if (response.status >= 400)
36+
throw new Error(`fetching ${input} yielded ${response.status} response`);
37+
return response.text();
38+
},
39+
(error) => {
40+
throw new Error(`fetching ${input} yielded error: ${error.message}`);
41+
}
42+
);
43+
3444
/**
35-
* Handles HTTP error responses from Axios requests in local dev;
36-
* re-throws error during builds to fail loudly.
37-
* This should only be used for non-critical requests that can tolerate null data
45+
* Performs a fetch that ignores errors in local dev;
46+
* throws during builds to fail loudly.
47+
* This should only be used for non-critical requests that can tolerate no data
3848
* without major side effects.
3949
*/
40-
export const wrapAxiosRequest = <T, D>(promise: Promise<AxiosResponse<T, D>>) =>
41-
promise.catch((error) => {
42-
if (!(error instanceof AxiosError) || !error.response || !error.request) throw error;
43-
const { response, request } = error;
44-
console.warn(
45-
`AxiosError: status ${response.status} received from ${
46-
request.protocol + "//" + request.host
47-
}${request.path || ""}`
48-
);
49-
50-
if (process.env.ELEVENTY_RUN_MODE === "build") throw error;
51-
else return { data: null };
52-
});
50+
export const fetchOptionalText: FetchText =
51+
process.env.ELEVENTY_RUN_MODE === "build"
52+
? fetchText
53+
: (input, init) =>
54+
fetchText(input, init).catch((error) => {
55+
console.warn("Bypassing fetch error:", error.message);
56+
return "";
57+
});

11ty/guidelines.ts

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
1-
import axios from "axios";
21
import type { CheerioAPI } from "cheerio";
32
import { glob } from "glob";
4-
import pick from "lodash-es/pick";
53

64
import { readFile } from "fs/promises";
75
import { basename, join, sep } from "path";
86

97
import { flattenDomFromFile, load, loadFromFile, type CheerioAnyNode } from "./cheerio";
10-
import { generateId } from "./common";
8+
import { fetchText, generateId } from "./common";
119

1210
export type WcagVersion = "20" | "21" | "22";
1311
export function assertIsWcagVersion(v: string): asserts v is WcagVersion {
@@ -256,9 +254,7 @@ const guidelinesCache: Partial<Record<WcagVersion, string>> = {};
256254
const loadRemoteGuidelines = async (version: WcagVersion, stripRespec = true) => {
257255
const html =
258256
guidelinesCache[version] ||
259-
(guidelinesCache[version] = (
260-
await axios.get(`https://www.w3.org/TR/WCAG${version}/`, { responseType: "text" })
261-
).data);
257+
(guidelinesCache[version] = await fetchText(`https://www.w3.org/TR/WCAG${version}/`));
262258

263259
const $ = load(html);
264260

@@ -360,13 +356,13 @@ export const getErrataForVersion = async (version: WcagVersion) => {
360356
.each((_, el) => {
361357
const $el = $(el);
362358
const erratumHtml = $el
363-
.html()!
364-
// Remove everything before and including the final TR link
365-
.replace(/^[\s\S]*href="\{\{\s*\w+\s*\}\}#[\s\S]*?<\/a>,?\s*/, "")
366-
// Remove parenthetical github references (still in Liquid syntax)
367-
.replace(/\(\{%.*%\}\)\s*$/, "")
368-
.replace(/^(\w)/, (_, p1) => p1.toUpperCase());
369-
359+
.html()!
360+
// Remove everything before and including the final TR link
361+
.replace(/^[\s\S]*href="\{\{\s*\w+\s*\}\}#[\s\S]*?<\/a>,?\s*/, "")
362+
// Remove parenthetical github references (still in Liquid syntax)
363+
.replace(/\(\{%.*%\}\)\s*$/, "")
364+
.replace(/^(\w)/, (_, p1) => p1.toUpperCase());
365+
370366
$el.find(aSelector).each((_, aEl) => {
371367
const $aEl = $(aEl);
372368
let hash: string | undefined = $aEl.attr("href")!.replace(/^.*#/, "");

eleventy.config.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import axios from "axios";
21
import compact from "lodash-es/compact";
32
import { mkdirp } from "mkdirp";
43
import { rimraf } from "rimraf";
@@ -7,7 +6,7 @@ import { copyFile, writeFile } from "fs/promises";
76
import { join } from "path";
87

98
import { CustomLiquid } from "11ty/CustomLiquid";
10-
import { resolveDecimalVersion } from "11ty/common";
9+
import { fetchText, resolveDecimalVersion } from "11ty/common";
1110
import { loadDataDependencies } from "11ty/data-dependencies";
1211
import {
1312
actRules,
@@ -239,9 +238,8 @@ export default async function (eleventyConfig: any) {
239238
);
240239

241240
const url = `https://raw.githack.com/${GH_ORG}/${GH_REPO}/${sha}/guidelines/index.html?isPreview=true`;
242-
const { data: processedGuidelines } = await axios.get(
243-
`https://labs.w3.org/spec-generator/?type=respec&url=${encodeURIComponent(url)}`,
244-
{ responseType: "text" }
241+
const processedGuidelines = await fetchText(
242+
`https://labs.w3.org/spec-generator/?type=respec&url=${encodeURIComponent(url)}`
245243
);
246244
await writeFile(`${dir.output}/guidelines/index.html`, processedGuidelines);
247245
}

0 commit comments

Comments
 (0)