Skip to content

Commit d3dc877

Browse files
wheels-bot[bot]github-actions[bot]bpamiri
authored
fix(view): surface paginationLinks() deprecation at runtime and in upgrade check (#2727)
* fix(view): surface paginationLinks() deprecation at runtime and in upgrade check paginationLinks() has been documented as deprecated in favor of paginationNav() since #1930 but the deprecation was a roadmap statement only — no runtime signal, no upgrade-check coverage. 3.x → 4.0 upgraders could finish the migration without ever learning the helper is on its way out. Two surfaces: 1. vendor/wheels/view/links.cfc — paginationLinks() now writes a one-time per-request WriteLog(type="warning", ...) pointing at paginationNav() and the individual composables. Guarded by request.wheels.$paginationLinksDeprecationLogged so a paginated view rendering the helper many times still only logs once. Pattern mirrors $checkPluginsDeprecation() in Plugins.cfc. 2. cli/lucli/Module.cfc — adds a 3.x → 4.x grep check for paginationLinks( in app/views, with a remediation pointer to paginationNav() and the composable helpers. Now visible via `wheels upgrade check --to=4.0.0`. Spec at vendor/wheels/tests/specs/view/paginationLinksDeprecationSpec.cfc asserts both surfaces — the runtime guard flag is set on first call and preserved on subsequent calls, and the upgrade-scanner block in Module.cfc contains the paginationLinks grep target. Fixes #2714 Signed-off-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> * docs(web/guides): note paginationLinks() runtime warning and upgrade-check coverage Signed-off-by: wheels-bot[bot] <wheels-bot[bot]@users.noreply.github.com> Signed-off-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> * chore(web): refresh visual baseline(s) (blog) Manually triggered baseline refresh via the refresh-visual-baselines.yml workflow on the PR's branch. Run when an intentional content/layout change makes the visual-regression check fail. The new PNG(s) under web/tests/visual-baselines/ are now the expected rendering; re-run the failing visual-regression job to flip the check green. * fix(cli): address PR #2727 review — remove dead CLAUDE.md ref, dedup test Reviewer A's required-before-merge items on #2727: 1. `cli/lucli/Module.cfc` — the `fix` string in the new `paginationLinks` upgrade check referenced `CLAUDE.md ## Pagination View Helpers`. End users running `wheels upgrade check --to=4.0.0` against their own app have no `CLAUDE.md` from this repo. Replace with the public GitHub issue URL. Remove the adjacent NOTE about doubling `##` — it was only relevant while the `fix` string contained `##1930`, and the URL form no longer needs the doubling. 2. `vendor/wheels/tests/specs/view/paginationLinksDeprecationSpec.cfc` — the upgrade-check coverage `it()` duplicated the block-extraction boilerplate (`expandPath`, `find("currentMajor <= 3...")`, etc.) that already lives in `UpgradeCheckCoverageSpec.cfc`. Move the assertion into that spec as one more `it()` alongside the other 3.x → 4.x coverage checks, and trim the deprecation spec down to the runtime warning tests only. Reviewer B's adjacent point (multi-line comment blocks per CLAUDE.md's "one short line max" rule): collapse the 5-line block in `vendor/wheels/view/links.cfc`, the 7-line preamble in `Module.cfc`, and the 18-line header in `paginationLinksDeprecationSpec.cfc`. Refs #2714, #2727. Signed-off-by: Peter Amiri <peter@alurium.com> --------- Signed-off-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Signed-off-by: wheels-bot[bot] <wheels-bot[bot]@users.noreply.github.com> Signed-off-by: Peter Amiri <peter@alurium.com> Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Peter Amiri <peter@alurium.com>
1 parent ce47c80 commit d3dc877

7 files changed

Lines changed: 68 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ All historical references to "CFWheels" in this changelog have been preserved fo
3434

3535
### Fixed
3636

37+
- `paginationLinks()` now emits a one-time per-request `WriteLog(type="warning", ...)` deprecation notice pointing 3.x → 4.x upgraders at `paginationNav()` (the all-in-one helper) and the individual `firstPageLink`/`previousPageLink`/`pageNumberLinks`/`nextPageLink`/`lastPageLink` composables. `wheels upgrade check --to=4.0.0` now also greps `app/views/` for `paginationLinks(` and flags every hit with a remediation pointer, closing the silent-rot gap surfaced by titan Phase 2.4 (#2714)
3738
- `paginationNav()` now throws `Wheels.PaginationNav.InvalidArgument` when passed an argument that none of its sub-helpers (`paginationInfo`, `firstPageLink`, `previousPageLink`, `pageNumberLinks`, `nextPageLink`, `lastPageLink`) accept. Previously, typos such as `prependToList="<ul>"` were silently dropped by CFML's `argumentCollection` dispatch, leaving users to wonder why a styling argument had no effect. The check is gated on `application.wheels.showErrorInformation` so production is unaffected; development environments fail fast and the error names both the rejected arguments and the full allowlist of accepted pass-through keys (#2717)
3839
- `wheels --help` no longer summarises the `packages` command as `Install, update, search Wheels packages` — that phrasing nudged users to type `wheels packages install <name>`, which LuCLI's built-in extension installer intercepts before module dispatch and silently no-ops (`[INFO] No git or extension dependencies to install`, exit 0, nothing under `vendor/`). The summary now leads with the canonical verb (`Add, update, search ...`) and parenthesises the gotcha so the doc surface stops contradicting the runtime. Same trap that earlier renamed `wheels browser install` to `wheels browser setup` (#2706)
3940
- `wheels.middleware.Cors` now emits `Vary: Origin` alongside the reflected `Access-Control-Allow-Origin` header so CDN, reverse-proxy, and browser disk caches key the response on the request Origin instead of serving a cached response with the wrong ACAO to a different origin. Matches the behavior of the legacy 3.x `Global.cfc::$setCORSHeaders` path (vendor/wheels/Global.cfc:3565). The header is only emitted when an origin is actually being reflected — wildcard (`allowOrigins="*"`) responses and disallowed-origin responses are unchanged (#2707)

cli/lucli/Module.cfc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3733,6 +3733,15 @@ component extends="modules.BaseModule" {
37333733
extensions: "cfm,cfc",
37343734
fix: "Missing manifest entries throw Wheels.ViteAssetNotFound in production. Rebuild assets during deploy (npm run build) or set(viteStrictManifest=false) to restore 3.x silent fallback."
37353735
});
3736+
// paginationLinks() deprecation grep (#2714, replacement: paginationNav() per #1930).
3737+
arrayAppend(checks, {
3738+
description: "Deprecated paginationLinks() helper (renamed to paginationNav() in 4.0)",
3739+
pattern: "paginationLinks\s*\(",
3740+
checkType: "grep",
3741+
scanDir: "app/views",
3742+
extensions: "cfm,cfc",
3743+
fix: "Replace paginationLinks() with paginationNav() (the all-in-one nav helper) or compose firstPageLink/previousPageLink/pageNumberLinks/nextPageLink/lastPageLink directly. See https://github.com/wheels-dev/wheels/issues/1930."
3744+
});
37363745
}
37373746

37383747
// Run checks

vendor/wheels/tests/specs/cli/UpgradeCheckCoverageSpec.cfc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ component extends="wheels.WheelsTest" {
8888
);
8989
});
9090

91+
it("scans for deprecated paginationLinks() helper", () => {
92+
expect(findNoCase("paginationLinks", block) > 0).toBeTrue(
93+
"3.x -> 4.x checks should grep views for paginationLinks( (renamed to paginationNav(), CHANGELOG ##2714)."
94+
);
95+
});
96+
9197
});
9298

9399
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
component extends="wheels.WheelsTest" {
2+
3+
function run() {
4+
5+
g = application.wo
6+
7+
describe("paginationLinks deprecation warning (##2714)", () => {
8+
9+
beforeEach(() => {
10+
_params = {controller = "dummy", action = "dummy"}
11+
_controller = g.controller("dummy", _params)
12+
g.set(functionName = "paginationLinks", encode = false)
13+
structDelete(request.wheels, "$paginationLinksDeprecationLogged")
14+
})
15+
16+
afterEach(() => {
17+
g.set(functionName = "paginationLinks", encode = true)
18+
structDelete(request.wheels, "$paginationLinksDeprecationLogged")
19+
})
20+
21+
it("sets a request-scoped guard flag on first call", () => {
22+
g.model("author").findAll(page = 2, perPage = 3, order = "lastName")
23+
expect(structKeyExists(request.wheels, "$paginationLinksDeprecationLogged")).toBeFalse()
24+
_controller.paginationLinks()
25+
expect(structKeyExists(request.wheels, "$paginationLinksDeprecationLogged")).toBeTrue()
26+
expect(request.wheels.$paginationLinksDeprecationLogged).toBeTrue()
27+
})
28+
29+
it("does not re-log when called multiple times in the same request", () => {
30+
g.model("author").findAll(page = 2, perPage = 3, order = "lastName")
31+
_controller.paginationLinks()
32+
request.wheels.$paginationLinksDeprecationLogged = "first"
33+
_controller.paginationLinks()
34+
expect(request.wheels.$paginationLinksDeprecationLogged).toBe("first")
35+
})
36+
37+
})
38+
39+
}
40+
41+
}

vendor/wheels/view/links.cfc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,15 @@ component {
233233
boolean pageNumberAsParam,
234234
any encode
235235
) {
236+
// One-time per-request deprecation warning (#2714) — mirrors $checkPluginsDeprecation() in Plugins.cfc.
237+
if (!StructKeyExists(request.wheels, "$paginationLinksDeprecationLogged")) {
238+
request.wheels.$paginationLinksDeprecationLogged = true;
239+
WriteLog(
240+
type = "warning",
241+
text = "[Wheels] paginationLinks() is deprecated and will be removed in a future release. Use paginationNav() instead (or compose the individual helpers: firstPageLink/previousPageLink/pageNumberLinks/nextPageLink/lastPageLink). See https://github.com/wheels-dev/wheels/issues/1930"
242+
);
243+
}
244+
236245
/* To fix the bug below:
237246
https://github.com/wheels-dev/wheels/issues/942
238247

web/sites/guides/src/content/docs/v4-0-0/upgrading/3x-to-4x.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ See [Packages](/v4-0-0/digging-deeper/packages/) for manifest fields, per-method
366366

367367
### Monolithic `paginationLinks()`
368368

369-
**CHANGELOG:** composable pagination helpers added (#1930). The 3.x `paginationLinks()` is retained. New code should use `paginationNav()` or compose the individual helpers (`paginationInfo`, `firstPageLink`, `previousPageLink`, `pageNumberLinks`, `nextPageLink`, `lastPageLink`).
369+
**CHANGELOG:** composable pagination helpers added (#1930). The 3.x `paginationLinks()` is retained but deprecated. As of #2727, calling `paginationLinks()` emits a one-time per-request `WriteLog(type="warning")` pointing at the replacement so apps see the signal without flooding the log. `wheels upgrade check --to=4.0.0` also greps `app/views/` for `paginationLinks(` and flags every hit with a remediation pointer. New code should use `paginationNav()` or compose the individual helpers (`paginationInfo`, `firstPageLink`, `previousPageLink`, `pageNumberLinks`, `nextPageLink`, `lastPageLink`).
370370

371371
### RocketUnit test style
372372

web/sites/guides/src/content/docs/v4-0-1-snapshot/upgrading/3x-to-4x.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ See [Packages](/v4-0-1-snapshot/digging-deeper/packages/) for manifest fields, p
366366

367367
### Monolithic `paginationLinks()`
368368

369-
**CHANGELOG:** composable pagination helpers added (#1930). The 3.x `paginationLinks()` is retained. New code should use `paginationNav()` or compose the individual helpers (`paginationInfo`, `firstPageLink`, `previousPageLink`, `pageNumberLinks`, `nextPageLink`, `lastPageLink`).
369+
**CHANGELOG:** composable pagination helpers added (#1930). The 3.x `paginationLinks()` is retained but deprecated. As of #2727, calling `paginationLinks()` emits a one-time per-request `WriteLog(type="warning")` pointing at the replacement so apps see the signal without flooding the log. `wheels upgrade check --to=4.0.0` also greps `app/views/` for `paginationLinks(` and flags every hit with a remediation pointer. New code should use `paginationNav()` or compose the individual helpers (`paginationInfo`, `firstPageLink`, `previousPageLink`, `pageNumberLinks`, `nextPageLink`, `lastPageLink`).
370370

371371
### RocketUnit test style
372372

0 commit comments

Comments
 (0)