From 54dabff6270c56a9d1a4e226f342aff2a6c7c344 Mon Sep 17 00:00:00 2001 From: volar Date: Mon, 17 Aug 2026 12:46:20 +0200 Subject: [PATCH] fix: redirect the pre-2.0.0 singular route paths (#85491) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2.0.0 pluralized every route path and added no redirect layer, so links to admin-dam held by other apps 404. A search through common-admin and admin-cms turned up three paths that are still linked from outside: - /asset/:id — built by DamAdminAssetLink.vue in common-admin, rendered by admin-cms (audio widget, audio/video embed dialogs), by common-admin itself (image detail dialog) and inherited by admin-ugc. - /asset/file/:id — asset-file detail, linked from an external library. - /user/:id/edit — admin-cms DAM_USER_EDIT_URL_TEMPLATE, opened by SystemUserEditButton.vue. Its value lives in .env, every developer's .env.local, the generated public/config.json and the deployment pipeline variables, so it outlives a single code change. They are added with router.addRoute() and re-added inside the handleHotUpdate callback, because a hot update replaces the generated routes and drops anything added at runtime. Redirect targets are route names rather than paths so the anzu-local/valid-route-name lint rule fails loudly if a page file is renamed, instead of the shim silently redirecting to a 404. Verified by navigating a memory-history router: all three redirect to the plural path with params, query and hash preserved, and the plural paths are unaffected. The shim is temporary; the TODO in src/router/legacyRedirects.ts lists what has to change before it can be removed. --- CHANGELOG.md | 1 + doc/changelog/2.0.1.md | 13 +++++++++++++ src/router/index.ts | 8 +++++++- src/router/legacyRedirects.ts | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 doc/changelog/2.0.1.md create mode 100644 src/router/legacyRedirects.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d01d6f4..845a89f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Changelog +- [2.0.1](doc/changelog/2.0.1.md) — 2026-08-17 - [2.0.0](doc/changelog/2.0.0.md) — 2026-08-17 - [1.29.0](doc/changelog/1.29.0.md) — 2026-06-15 - [1.28.0](doc/changelog/1.28.0.md) — 2026-03-11 diff --git a/doc/changelog/2.0.1.md b/doc/changelog/2.0.1.md new file mode 100644 index 00000000..aa99ad67 --- /dev/null +++ b/doc/changelog/2.0.1.md @@ -0,0 +1,13 @@ +2.0.1 — 2026-08-17 +=== + +### Fixed + +- **Links into DAM held by other apps no longer 404.** 2.0.0 pluralized every route path and shipped + no redirect layer, so URLs stored outside this app broke. `/asset/:id`, `/asset/file/:id` and + `/user/:id/edit` now redirect to their plural counterparts, keeping params, query and hash. + The shim in `src/router/legacyRedirects.ts` is temporary and names what has to change before it can + be dropped: `DamAdminAssetLink.vue` in common-admin (rendered by admin-cms and admin-ugc) and + admin-cms' `DAM_USER_EDIT_URL_TEMPLATE`, whose value also lives in deployment pipeline variables. + +[Compare with 2.0.0](https://github.com/anzusystems/admin-dam/compare/2.0.0...2.0.1) diff --git a/src/router/index.ts b/src/router/index.ts index 2d7f5539..80605f06 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -1,14 +1,20 @@ import { createRouter, createWebHistory } from 'vue-router' import { routes, handleHotUpdate } from 'vue-router/auto-routes' import { beforeEachRoute } from '@/router/beforeEachRoute' +import { addLegacyRedirects } from '@/router/legacyRedirects' const vueRouter = createRouter({ history: createWebHistory(), routes, }) +addLegacyRedirects(vueRouter) + if (import.meta.hot) { - handleHotUpdate(vueRouter) + // a hot update replaces the generated routes, dropping anything added at runtime + handleHotUpdate(vueRouter, () => { + addLegacyRedirects(vueRouter) + }) } vueRouter.beforeEach(async (to) => { diff --git a/src/router/legacyRedirects.ts b/src/router/legacyRedirects.ts new file mode 100644 index 00000000..81c67f5d --- /dev/null +++ b/src/router/legacyRedirects.ts @@ -0,0 +1,35 @@ +import type { RouteLocation, Router } from 'vue-router' + +/** + * TODO(#85491): temporary shim for the pre-2.0.0 singular route paths. + * + * 2.0.0 pluralized every route and shipped no redirect layer, so links held outside this app 404. + * Only the paths that are actually linked from elsewhere are covered here. Delete this file and + * both call sites in `./index.ts` once every consumer below points at the plural path: + * + * - `/asset/:id` — `DamAdminAssetLink.vue` in common-admin builds `adminDomain + '/asset/' + id` + * (rendered by admin-cms in the audio widget and the audio/video embed dialogs, by common-admin + * itself in the image detail dialog, and inherited by admin-ugc). + * - `/asset/file/:id` — asset-file detail linked from an external library. + * - `/user/:id/edit` — admin-cms `DAM_USER_EDIT_URL_TEMPLATE`, opened by `SystemUserEditButton.vue`. + * Lives in its `.env`, every developer's `.env.local` and `public/config.json`, and in the + * deployment pipeline variable — so this one outlives a single code change. + */ +// the legacy paths are not part of the generated route map, so `to.params` is typed as the +// union of every known route's params and needs narrowing +const legacyId = (to: RouteLocation) => (to.params as { id: string }).id + +export const addLegacyRedirects = (router: Router) => { + router.addRoute({ + path: '/asset/:id', + redirect: (to) => ({ name: '/(coreDam)/assets/[id]', params: { id: legacyId(to) } }), + }) + router.addRoute({ + path: '/asset/file/:id', + redirect: (to) => ({ name: '/(coreDam)/assets/file/[id]', params: { id: legacyId(to) } }), + }) + router.addRoute({ + path: '/user/:id/edit', + redirect: (to) => ({ name: '/(coreDam)/users/[id]/edit', params: { id: legacyId(to) } }), + }) +}