@nu-appdev/northwestern-starlight-theme 1.6.1 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.6.2] - 2026-08-20
11
+
12
+ ### Fixed
13
+
14
+ - OG image text no longer unescapes twice. Entities were decoded in sequence with `&amp;` first, so a title containing the escaped text `&amp;lt;` came out as `<`. Decoding is now a single pass, and escaped text stays escaped.
15
+ - The meta-refresh patterns used to rewrite legacy `.html` redirect pages are bounded. The previous patterns scanned the rest of the page from every start position, so time grew with the square of the page size: a 200 KB page of near-matches took over half a second. A tag longer than the bound is left alone, which skips hash forwarding for that page but keeps the redirect.
16
+
10
17
  ## [1.6.1] - 2026-08-20
11
18
 
12
19
  ### Fixed
@@ -203,7 +210,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
203
210
  - OpenAPI plugin compatibility with method badge preservation
204
211
  - Reduced motion support for transitions
205
212
 
206
- [Unreleased]: https://github.com/NIT-Administrative-Systems/northwestern-starlight-theme/compare/v1.6.1...HEAD
213
+ [Unreleased]: https://github.com/NIT-Administrative-Systems/northwestern-starlight-theme/compare/v1.6.2...HEAD
214
+ [1.6.2]: https://github.com/NIT-Administrative-Systems/northwestern-starlight-theme/compare/v1.6.1...v1.6.2
207
215
  [1.6.1]: https://github.com/NIT-Administrative-Systems/northwestern-starlight-theme/compare/v1.6.0...v1.6.1
208
216
  [1.6.0]: https://github.com/NIT-Administrative-Systems/northwestern-starlight-theme/compare/v1.5.1...v1.6.0
209
217
  [1.5.1]: https://github.com/NIT-Administrative-Systems/northwestern-starlight-theme/compare/v1.5.0...v1.5.1
@@ -1 +1 @@
1
- {"version":3,"file":"legacy-html-redirects.d.ts","sourceRoot":"","sources":["../legacy-html-redirects.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAG9C;;;GAGG;AACH,MAAM,WAAW,0BAA0B;IACvC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAUD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,GAAE,0BAA+B,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAqB5G;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,8BAA8B,IAAI,gBAAgB,CASjE;AAED,0CAA0C;AAC1C,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE7D;AAuCD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAWxD"}
1
+ {"version":3,"file":"legacy-html-redirects.d.ts","sourceRoot":"","sources":["../legacy-html-redirects.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAG9C;;;GAGG;AACH,MAAM,WAAW,0BAA0B;IACvC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAUD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,GAAE,0BAA+B,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAqB5G;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,8BAA8B,IAAI,gBAAgB,CASjE;AAED,0CAA0C;AAC1C,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE7D;AA4CD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAWxD"}
@@ -142,8 +142,13 @@ function flattenOne(root: string, rel: string): void {
142
142
  renameSync(tmpPath, dirPath);
143
143
  }
144
144
 
145
- const META_REFRESH_TAG = /<meta\s+http-equiv="refresh"[^>]*>/i;
146
- const META_REFRESH_URL = /url=([^"]+)"/i;
145
+ // Every quantifier below is bounded. An unbounded one makes matching quadratic
146
+ // on a page full of near-matches, because each failed start position rescans the
147
+ // rest of the document (CodeQL `js/polynomial-redos`). The bounds are far above
148
+ // any tag Astro emits; a page that exceeds them is left alone, which only costs
149
+ // hash forwarding, not the redirect itself.
150
+ const META_REFRESH_TAG = /<meta\s{1,32}http-equiv="refresh"[^>]{0,1024}>/i;
151
+ const META_REFRESH_URL = /url=([^"]{1,2048})"/i;
147
152
  const HASH_FORWARD_SCRIPT = /<script>location\.replace\(/;
148
153
 
149
154
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nu-appdev/northwestern-starlight-theme",
3
- "version": "1.6.1",
3
+ "version": "1.6.2",
4
4
  "description": "A Northwestern-branded theme for Astro Starlight",
5
5
  "license": "MIT",
6
6
  "author": "Danny Foster <danny@northwestern.edu>",
@@ -90,7 +90,11 @@
90
90
  }
91
91
  },
92
92
  "devDependencies": {
93
+ "@astrojs/starlight": "^0.41.7",
93
94
  "@types/hast": "^3.0.5",
95
+ "astro": "^7.2.4",
96
+ "astro-mermaid": "^2.1.0",
97
+ "mermaid": "^11.17.0",
94
98
  "typescript": "^7.0.2"
95
99
  },
96
100
  "scripts": {
package/src/og/render.ts CHANGED
@@ -53,13 +53,24 @@ function toFontWeight(weight: string): number {
53
53
  return fontWeightMap[weight] ?? 400;
54
54
  }
55
55
 
56
- function decodeText(text: string) {
57
- return text
58
- .replaceAll("&amp;", "&")
59
- .replaceAll("&lt;", "<")
60
- .replaceAll("&gt;", ">")
61
- .replaceAll("&quot;", '"')
62
- .replaceAll("&#39;", "'");
56
+ const HTML_ENTITIES: Record<string, string> = {
57
+ "&amp;": "&",
58
+ "&lt;": "<",
59
+ "&gt;": ">",
60
+ "&quot;": '"',
61
+ "&#39;": "'",
62
+ };
63
+
64
+ /**
65
+ * Decode the HTML entities Starlight escapes into page titles and descriptions.
66
+ *
67
+ * One pass, because decoding `&amp;` before the others would unescape twice:
68
+ * `&amp;lt;` is the text `&lt;`, not `<`.
69
+ *
70
+ * @internal — exposed for unit tests.
71
+ */
72
+ export function decodeText(text: string) {
73
+ return text.replace(/&(?:amp|lt|gt|quot|#39);/g, (entity) => HTML_ENTITIES[entity] ?? entity);
63
74
  }
64
75
 
65
76
  function rgbToCSS(rgb: RGBColor): string {