@blamejs/blamejs-shop 0.0.108 → 0.0.109
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 +2 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,8 @@ upgrading across more than a few patches at a time.
|
|
|
8
8
|
|
|
9
9
|
## v0.0.x
|
|
10
10
|
|
|
11
|
+
- v0.0.109 (2026-05-23) — **Blog-table-resilient D1 queries + tighter `edge-handler-catch-returns-null` regex.** Live probing surfaced that `/feed.xml` (503), `/sitemap.xml` (503), and `/blog` (500) all fail when the live D1 doesn't have the `blog_articles` table — migration `0189` ships with the blogArticles primitive (v0.0.75) but hadn't been applied to the live deployment yet. The four blog-touching queries in `worker/data/catalog.js` now treat `"no such table"` errors as "no published articles" and return empty rows, so the dependent edge routes degrade gracefully (feed renders no items, sitemap renders only the product + static URLs, /blog shows the empty-state). The `edge-handler-catch-returns-null` detector also tightens — the previous regex spanned 400 chars after the catch's opening `{`, which reached across function boundaries into the next function's guard-clause `return null;` and tripped a false positive. The new regex uses `[^}]` to stay inside the catch body. **Fixed:** *Blog-table-resilient queries in `worker/data/catalog.js`* — `listPublishedBlogSlugs`, `listBlogArticles`, `getBlogArticleBySlug`, and `recentBlogArticles` now catch `"no such table"` errors from D1 and return empty rows / null. Operators who haven't applied migration `0189_blog_articles.sql` (or who deploy the worker before the migrations land) get a clean degradation instead of `/feed.xml` 503 / `/sitemap.xml` 503 / `/blog` 500. Non-table-missing errors still propagate to the caller's `_edgeError` for the canonical 5xx render. · *`edge-handler-catch-returns-null` regex tightened — no more cross-function false positives* — Previous regex: `catch\s*\(\s*[\w$]+\s*\)\s*\{[\s\S]{0,400}?return\s+null\s*;` — the `[\s\S]` matches anything including the catch's closing `}`, so a small catch body followed shortly by a function-guard `return null;` was matching as if the null were inside the catch. New regex: `catch\s*\(\s*[\w$]+\s*\)\s*\{[^}]{0,400}return\s+null\s*;` — `[^}]` keeps the match inside the catch body. Catches still flagged for injection-tested anti-pattern (`catch (e) { return null; }`); the blog-query data layer's guard-clause `return null` outside any catch is no longer flagged. · *Blog-query refactor — null-return moves outside the catch body* — `getBlogArticleBySlug` now uses a `var row = null` outer binding and assigns inside the try; the catch swallows the missing-table case without an inner `return null`. The function's contract ("returns the row or null when not found") is preserved; the tightened detector regex doesn't flag the new shape.
|
|
12
|
+
|
|
11
13
|
- v0.0.108 (2026-05-23) — **ETag + `If-None-Match` 304 handling on `/privacy` + `/terms` — saves the body bytes on every browser revalidate.** `/privacy` and `/terms` carry `max-age=3600` so a returning visitor's browser revalidates the resource every hour. Previously the revalidate downloaded the full body each time (~5KB); now the response carries an `ETag` derived from a FNV-1a hash of the minified body, and the handler compares incoming `If-None-Match` against the same etag — on a match it returns `304 Not Modified` with no body. The Edge cache (24h s-maxage) holds the 200 response; revalidates hit the Worker, run the cheap hash, and 99% of the time return a few hundred bytes instead of the full page. FNV-1a is chosen for speed + zero allocation — collision irrelevant because operators (not visitors) control the policy text, so the attacker-controlled input space at this surface is empty. **Added:** *ETag + `If-None-Match` 304 handling in `_staticHtml`* — `_staticHtml(body, method, env, request)` minifies the body, computes a 32-bit FNV-1a hash of the minified bytes, formats as a quoted hex ETag (`"<hash>"`), and returns 304 (with the ETag header repeated per RFC 7232 §4.1) when the incoming `If-None-Match` matches. The hash is content-stable — a re-render of the same operator-set policy text produces the same ETag across edge instances. Carries through to `/privacy` and `/terms`; the dynamic edge-rendered routes (`/`, `/search`, `/products/:slug`, `/blog`, `/blog/:slug`) keep their `no-store` posture since their D1-sourced content changes per-request.
|
|
12
14
|
|
|
13
15
|
- v0.0.107 (2026-05-23) — **`X-Robots-Tag: noindex, nofollow` on `/cart` — crawlers stop indexing the session-bound empty-state.** The guest `/cart` route ships an empty-cart render at the edge for visitors without a session cookie. Crawlers reaching the page were indexing it as if it were content; the empty-state snippet ("Your cart is empty") was appearing in SERPs as a stale search result for unrelated queries. The handler now sets `X-Robots-Tag: noindex, nofollow` on the response so well-behaved crawlers skip indexing. `robots.txt` already `Disallow`s the route — the response header is belt-and-suspenders. **Changed:** *`_edgeCartEmpty` sets `X-Robots-Tag: noindex, nofollow`* — The handler now builds its own Response (instead of routing through `_html`) so the response carries the X-Robots-Tag header alongside the full security-header set + Link preload + minification. Per-route headers compose cleanly without changing `_html`'s signature for one outlier.
|
package/package.json
CHANGED