@actuate-media/cms-admin 0.76.3 → 0.76.5

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
@@ -1,5 +1,47 @@
1
1
  # @actuate-media/cms-admin
2
2
 
3
+ ## 0.76.5
4
+
5
+ ### Patch Changes
6
+
7
+ - cd8a061: Remove dead sidebar nav from bundled plugins and guard the whole class.
8
+
9
+ `plugin-ai`, `plugin-commerce`, and `plugin-blocks` each advertised
10
+ `adminNavItems` paths (`/ai/*`, `/commerce/*`, `/blocks`) that the admin router
11
+ has no view for — plugins cannot register views, and these plugins register no
12
+ collection backing those paths — so every one of those sidebar links landed on
13
+ the 404 page. The commerce items were also duplicates of the working collection
14
+ nav (its collections already appear under the "Commerce" group at their real
15
+ `/<slug>` routes).
16
+ - Dropped the dead `adminNavItems` from all three plugins. Commerce collections
17
+ remain reachable at `/products`, `/orders`, `/discounts`, …; plugin-ai and
18
+ plugin-blocks are backend/page-builder plugins with no standalone admin route.
19
+ - Added `cms-admin`'s `router/admin-routes` resolver (`adminPathResolves`) plus
20
+ a table-driven test asserting **every** bundled plugin's nav paths resolve to a
21
+ real view, and a drift test that keeps the known-route list in sync with
22
+ `AdminRoot`. This is the systemic guard for a bug class that has now shipped in
23
+ published packages three times.
24
+
25
+ ## 0.76.4
26
+
27
+ ### Patch Changes
28
+
29
+ - c094b8d: Fix duplicated sidebar nav (Forms/All Entries appearing twice, split CONTENT groups).
30
+
31
+ `buildNavItems` always adds the static Content destinations (Media, Forms, SEO,
32
+ Script Tags), but the custom-group loop pushed every grouped collection without
33
+ deduping — so plugin-forms' `forms` collection (`admin.group: 'Forms'`, path
34
+ `/forms`) produced a SECOND "Forms" entry, and `applyFormsNav` then attached
35
+ "All Entries" to both. Separately, plugin-contributed nav links (which carry
36
+ `group: 'Content'`) were emitted AFTER the custom collection groups, so the
37
+ renderer started a second "CONTENT" header (e.g. for the SEO Sitemap/Link Health
38
+ links).
39
+
40
+ Grouped collections are now deduped by path against everything already present,
41
+ and plugin nav links are emitted inside the Content block (before the custom
42
+ groups) so Content stays contiguous. Every sidebar path now appears exactly once
43
+ under a single header per group.
44
+
3
45
  ## 0.76.3
4
46
 
5
47
  ### Patch Changes
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=build-nav-items.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-nav-items.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/layout/build-nav-items.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,85 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { buildNavItems } from '../../layout/Sidebar.js';
3
+ /**
4
+ * Mirrors a standard scaffold that enables formsPlugin + seoPlugin +
5
+ * redirectsPlugin (like the `ntn` site): plugin-forms registers a `forms`
6
+ * collection grouped under 'Forms', and every plugin's adminNavItems arrive on
7
+ * `_pluginNavItems`. Before the fix this produced a duplicate "Forms" (static +
8
+ * grouped collection) and a second "CONTENT" header for the SEO sub-links.
9
+ */
10
+ function scaffoldLikeConfig() {
11
+ return {
12
+ collections: {
13
+ pages: { slug: 'pages', type: 'page', labels: { plural: 'Pages' } },
14
+ forms: { slug: 'forms', labels: { plural: 'Forms' }, admin: { group: 'Forms' } },
15
+ 'form-submissions': {
16
+ slug: 'form-submissions',
17
+ labels: { plural: 'Form Submissions' },
18
+ admin: { group: 'Forms' },
19
+ },
20
+ },
21
+ _pluginNavItems: [
22
+ { label: 'Forms', icon: 'FileText', path: '/forms' },
23
+ { label: 'Submissions', icon: 'Inbox', path: '/form-submissions' },
24
+ { label: 'SEO Overview', icon: 'search', path: '/seo' },
25
+ { label: 'Sitemap', icon: 'map', path: '/seo/sitemap' },
26
+ { label: 'Link Health', icon: 'link', path: '/seo/link-health' },
27
+ { label: 'Redirects', icon: 'arrow-right-left', path: '/redirects' },
28
+ ],
29
+ };
30
+ }
31
+ describe('buildNavItems — duplicate / grouping regressions', () => {
32
+ it('never emits the same path twice', () => {
33
+ const paths = buildNavItems(scaffoldLikeConfig()).map((i) => i.path);
34
+ expect(new Set(paths).size).toBe(paths.length);
35
+ });
36
+ it('shows Forms exactly once (grouped `forms` collection deduped against the static entry)', () => {
37
+ const items = buildNavItems(scaffoldLikeConfig());
38
+ expect(items.filter((i) => i.path === '/forms')).toHaveLength(1);
39
+ });
40
+ it('keeps the Content group contiguous — no second CONTENT header', () => {
41
+ const items = buildNavItems(scaffoldLikeConfig());
42
+ // Once the nav leaves the Content group it must never return to it, or the
43
+ // renderer emits a duplicate "CONTENT" section header.
44
+ let leftContent = false;
45
+ for (const item of items) {
46
+ if (item.group === 'Content') {
47
+ expect(leftContent).toBe(false);
48
+ }
49
+ else if (item.group) {
50
+ leftContent = true;
51
+ }
52
+ }
53
+ });
54
+ it('surfaces the SEO sub-links inside the Content block', () => {
55
+ const items = buildNavItems(scaffoldLikeConfig());
56
+ expect(items.find((i) => i.path === '/seo/sitemap')?.group).toBe('Content');
57
+ expect(items.find((i) => i.path === '/seo/link-health')?.group).toBe('Content');
58
+ });
59
+ it('excludes admin.hidden collections and does not resurrect removed nav paths', () => {
60
+ // Post-fix reality: plugin-forms/plugin-redirects no longer advertise
61
+ // Submissions/Redirects nav items, and their form-submissions/redirects
62
+ // collections are admin.hidden. Neither should surface a (404-ing) nav path.
63
+ const items = buildNavItems({
64
+ collections: {
65
+ pages: { slug: 'pages', type: 'page', labels: { plural: 'Pages' } },
66
+ forms: { slug: 'forms', labels: { plural: 'Forms' }, admin: { group: 'Forms' } },
67
+ 'form-submissions': {
68
+ slug: 'form-submissions',
69
+ labels: { plural: 'Form Submissions' },
70
+ admin: { hidden: true },
71
+ },
72
+ redirects: { slug: 'redirects', labels: { plural: 'Redirects' }, admin: { hidden: true } },
73
+ },
74
+ _pluginNavItems: [
75
+ { label: 'Forms', icon: 'FileText', path: '/forms' },
76
+ { label: 'SEO', icon: 'search', path: '/seo' },
77
+ ],
78
+ });
79
+ const paths = items.map((i) => i.path);
80
+ expect(paths).not.toContain('/form-submissions');
81
+ expect(paths).not.toContain('/redirects');
82
+ expect(items.filter((i) => i.path === '/forms')).toHaveLength(1);
83
+ });
84
+ });
85
+ //# sourceMappingURL=build-nav-items.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-nav-items.test.js","sourceRoot":"","sources":["../../../src/__tests__/layout/build-nav-items.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE7C,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAEvD;;;;;;GAMG;AACH,SAAS,kBAAkB;IACzB,OAAO;QACL,WAAW,EAAE;YACX,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE;YACnE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YAChF,kBAAkB,EAAE;gBAClB,IAAI,EAAE,kBAAkB;gBACxB,MAAM,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;gBACtC,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;aAC1B;SACF;QACD,eAAe,EAAE;YACf,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE;YACpD,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE;YAClE,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE;YACvD,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE;YACvD,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE;YAChE,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,YAAY,EAAE;SACrE;KACF,CAAA;AACH,CAAC;AAED,QAAQ,CAAC,kDAAkD,EAAE,GAAG,EAAE;IAChE,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,KAAK,GAAG,aAAa,CAAC,kBAAkB,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;QACpE,MAAM,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAChD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,wFAAwF,EAAE,GAAG,EAAE;QAChG,MAAM,KAAK,GAAG,aAAa,CAAC,kBAAkB,EAAE,CAAC,CAAA;QACjD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;IAClE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,KAAK,GAAG,aAAa,CAAC,kBAAkB,EAAE,CAAC,CAAA;QACjD,2EAA2E;QAC3E,uDAAuD;QACvD,IAAI,WAAW,GAAG,KAAK,CAAA;QACvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC7B,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACjC,CAAC;iBAAM,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACtB,WAAW,GAAG,IAAI,CAAA;YACpB,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,KAAK,GAAG,aAAa,CAAC,kBAAkB,EAAE,CAAC,CAAA;QACjD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,cAAc,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAC3E,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,kBAAkB,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IACjF,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4EAA4E,EAAE,GAAG,EAAE;QACpF,sEAAsE;QACtE,wEAAwE;QACxE,6EAA6E;QAC7E,MAAM,KAAK,GAAG,aAAa,CAAC;YAC1B,WAAW,EAAE;gBACX,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE;gBACnE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;gBAChF,kBAAkB,EAAE;oBAClB,IAAI,EAAE,kBAAkB;oBACxB,MAAM,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;oBACtC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;iBACxB;gBACD,SAAS,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;aAC3F;YACD,eAAe,EAAE;gBACf,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACpD,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE;aAC/C;SACF,CAAC,CAAA;QACF,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;QACtC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAA;QAChD,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,YAAY,CAAC,CAAA;QACzC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;IAClE,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=admin-routes.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin-routes.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/router/admin-routes.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,62 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { readFileSync } from 'node:fs';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { ADMIN_STATIC_ROUTE_PATTERNS, adminPathResolves, matchesRoutePattern, collectionRoutePatterns, } from '../../router/admin-routes.js';
5
+ describe('matchesRoutePattern', () => {
6
+ it('matches by equal segment count with :param wildcards', () => {
7
+ expect(matchesRoutePattern('/pages', '/pages')).toBe(true);
8
+ expect(matchesRoutePattern('/pages/abc123/edit', '/pages/:id/edit')).toBe(true);
9
+ expect(matchesRoutePattern('/', '/')).toBe(true);
10
+ });
11
+ it('rejects a mismatched segment count or literal', () => {
12
+ expect(matchesRoutePattern('/pages/abc', '/pages')).toBe(false);
13
+ expect(matchesRoutePattern('/ai/scores', '/pages/:id')).toBe(false);
14
+ expect(matchesRoutePattern('/', '/pages')).toBe(false);
15
+ });
16
+ it('ignores query string and hash', () => {
17
+ expect(matchesRoutePattern('/seo?tab=audit', '/seo')).toBe(true);
18
+ });
19
+ });
20
+ describe('adminPathResolves', () => {
21
+ it('resolves built-in routes and SEO deep paths', () => {
22
+ expect(adminPathResolves('/media')).toBe(true);
23
+ expect(adminPathResolves('/forms')).toBe(true);
24
+ expect(adminPathResolves('/seo')).toBe(true);
25
+ expect(adminPathResolves('/seo/link-health')).toBe(true);
26
+ });
27
+ it('does NOT resolve a path with no backing route (the plugin-nav bug)', () => {
28
+ expect(adminPathResolves('/ai/scores')).toBe(false);
29
+ expect(adminPathResolves('/commerce/products')).toBe(false);
30
+ expect(adminPathResolves('/blocks')).toBe(false);
31
+ });
32
+ it('resolves a non-reserved collection at /<slug> and /collections/<slug>', () => {
33
+ const config = { collections: { products: { slug: 'products' } } };
34
+ expect(adminPathResolves('/products', config)).toBe(true);
35
+ expect(adminPathResolves('/collections/products', config)).toBe(true);
36
+ // Without the collection, the top-level route does not exist.
37
+ expect(adminPathResolves('/products')).toBe(false);
38
+ });
39
+ it('does not give a reserved-slug collection a shadowing top-level route', () => {
40
+ const patterns = collectionRoutePatterns({ collections: { pages: { slug: 'pages' } } });
41
+ expect(patterns).toContain('/collections/pages');
42
+ expect(patterns).not.toContain('/pages');
43
+ });
44
+ });
45
+ /**
46
+ * Drift guard: every literal `matchRoute('…')` in AdminRoot must be represented
47
+ * in ADMIN_STATIC_ROUTE_PATTERNS, so `adminPathResolves` can't silently fall
48
+ * behind the real router (which would let a broken plugin nav path pass review).
49
+ * Dynamic `matchRoute(`/${slug}/…`)` template calls and iterated SEO paths are
50
+ * intentionally excluded — those are covered by collection/SEO patterns.
51
+ */
52
+ describe('ADMIN_STATIC_ROUTE_PATTERNS stays in sync with AdminRoot', () => {
53
+ it('covers every literal matchRoute() call in AdminRoot', () => {
54
+ const src = readFileSync(fileURLToPath(new URL('../../AdminRoot.tsx', import.meta.url)), 'utf8');
55
+ const literals = [...src.matchAll(/matchRoute\(\s*'([^']+)'\s*\)/g)].map((m) => m[1]);
56
+ expect(literals.length).toBeGreaterThan(20);
57
+ const known = new Set(ADMIN_STATIC_ROUTE_PATTERNS);
58
+ const missing = [...new Set(literals)].filter((p) => !known.has(p));
59
+ expect(missing).toEqual([]);
60
+ });
61
+ });
62
+ //# sourceMappingURL=admin-routes.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin-routes.test.js","sourceRoot":"","sources":["../../../src/__tests__/router/admin-routes.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EACL,2BAA2B,EAC3B,iBAAiB,EACjB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,8BAA8B,CAAA;AAErC,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC1D,MAAM,CAAC,mBAAmB,CAAC,oBAAoB,EAAE,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC/E,MAAM,CAAC,mBAAmB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAClD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,CAAC,mBAAmB,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC/D,MAAM,CAAC,mBAAmB,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACnE,MAAM,CAAC,mBAAmB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACxD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAClE,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC9C,MAAM,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC9C,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC5C,MAAM,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC1D,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,MAAM,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACnD,MAAM,CAAC,iBAAiB,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC3D,MAAM,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAClD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC/E,MAAM,MAAM,GAAG,EAAE,WAAW,EAAE,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,CAAA;QAClE,MAAM,CAAC,iBAAiB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACzD,MAAM,CAAC,iBAAiB,CAAC,uBAAuB,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACrE,8DAA8D;QAC9D,MAAM,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACpD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,sEAAsE,EAAE,GAAG,EAAE;QAC9E,MAAM,QAAQ,GAAG,uBAAuB,CAAC,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAA;QACvF,MAAM,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAA;QAChD,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;IAC1C,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF;;;;;;GAMG;AACH,QAAQ,CAAC,0DAA0D,EAAE,GAAG,EAAE;IACxE,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,GAAG,GAAG,YAAY,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,qBAAqB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;QAChG,MAAM,QAAQ,GAAG,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,gCAAgC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAA;QACtF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,EAAE,CAAC,CAAA;QAC3C,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,2BAA2B,CAAC,CAAA;QAClD,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;QACnE,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IAC7B,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=plugin-nav-resolves.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-nav-resolves.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/router/plugin-nav-resolves.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,46 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { aiPlugin } from '@actuate-media/plugin-ai';
3
+ import { blocksPlugin } from '@actuate-media/plugin-blocks';
4
+ import { commercePlugin } from '@actuate-media/plugin-commerce';
5
+ import { formsPlugin } from '@actuate-media/plugin-forms';
6
+ import { mediaPlugin } from '@actuate-media/plugin-media';
7
+ import { navigationPlugin } from '@actuate-media/plugin-navigation';
8
+ import { seoPlugin } from '@actuate-media/plugin-seo';
9
+ import { adminPathResolves } from '../../router/admin-routes.js';
10
+ /**
11
+ * Systemic guard for the recurring plugin-nav-404 class: a plugin advertises an
12
+ * `adminNavItems` path the admin router has no route for, so the sidebar link
13
+ * lands on the 404 page. It has shipped in published packages more than once
14
+ * (plugin-ai / plugin-commerce / plugin-blocks). Plugins cannot register views,
15
+ * so every nav path MUST resolve to a built-in route or one of the plugin's own
16
+ * collection routes — asserted here for every bundled plugin.
17
+ *
18
+ * When this fails: either point the nav item at a real route (a built-in, or a
19
+ * `/<slug>` for a collection the plugin registers) or remove it until a plugin
20
+ * view API exists. Do NOT add the path to ADMIN_STATIC_ROUTE_PATTERNS unless
21
+ * AdminRoot actually renders a view for it.
22
+ */
23
+ const BUNDLED_PLUGINS = [
24
+ { name: 'plugin-ai', plugin: aiPlugin() },
25
+ { name: 'plugin-blocks', plugin: blocksPlugin() },
26
+ { name: 'plugin-commerce', plugin: commercePlugin() },
27
+ { name: 'plugin-forms', plugin: formsPlugin() },
28
+ { name: 'plugin-media', plugin: mediaPlugin() },
29
+ { name: 'plugin-navigation', plugin: navigationPlugin() },
30
+ { name: 'plugin-seo', plugin: seoPlugin() },
31
+ ];
32
+ describe('every bundled plugin adminNavItems path resolves to a real admin view', () => {
33
+ for (const { name, plugin } of BUNDLED_PLUGINS) {
34
+ const navItems = plugin.adminNavItems ?? [];
35
+ // A config exposing exactly this plugin's collections — the only extra
36
+ // destinations a plugin can legitimately point its nav at.
37
+ const config = { collections: plugin.collections ?? {} };
38
+ it(`${name} (${navItems.length} nav item${navItems.length === 1 ? '' : 's'})`, () => {
39
+ const dead = navItems
40
+ .map((item) => item.path)
41
+ .filter((path) => !adminPathResolves(path, config));
42
+ expect(dead, `${name} advertises sidebar paths with no admin route: ${dead.join(', ')}`).toEqual([]);
43
+ });
44
+ }
45
+ });
46
+ //# sourceMappingURL=plugin-nav-resolves.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-nav-resolves.test.js","sourceRoot":"","sources":["../../../src/__tests__/router/plugin-nav-resolves.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAA;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAA;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAA;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAA;AAEhE;;;;;;;;;;;;GAYG;AACH,MAAM,eAAe,GAAG;IACtB,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE;IACzC,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE;IACjD,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,cAAc,EAAE,EAAE;IACrD,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE;IAC/C,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE;IAC/C,EAAE,IAAI,EAAE,mBAAmB,EAAE,MAAM,EAAE,gBAAgB,EAAE,EAAE;IACzD,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE;CAC5C,CAAA;AAED,QAAQ,CAAC,uEAAuE,EAAE,GAAG,EAAE;IACrF,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,eAAe,EAAE,CAAC;QAC/C,MAAM,QAAQ,GAAG,MAAM,CAAC,aAAa,IAAI,EAAE,CAAA;QAC3C,uEAAuE;QACvE,2DAA2D;QAC3D,MAAM,MAAM,GAAG,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,EAAE,EAAE,CAAA;QAExD,EAAE,CAAC,GAAG,IAAI,KAAK,QAAQ,CAAC,MAAM,YAAY,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE;YAClF,MAAM,IAAI,GAAG,QAAQ;iBAClB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;iBACxB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAA;YACrD,MAAM,CACJ,IAAI,EACJ,GAAG,IAAI,kDAAkD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC3E,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACf,CAAC,CAAC,CAAA;IACJ,CAAC;AACH,CAAC,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"Sidebar.d.ts","sourceRoot":"","sources":["../../src/layout/Sidebar.tsx"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAsM9C,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,OAAO,CAAA;IAClB,gBAAgB,EAAE,MAAM,IAAI,CAAA;IAC5B,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,MAAM,CAAC,EAAE,GAAG,CAAA;CACb;AAED,wBAAgB,OAAO,CAAC,EACtB,SAAS,EACT,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,MAAM,GACP,EAAE,YAAY,2CAqDd;AAmcD,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,UAAU,CAAA;IAChB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAA;IACpB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,EAAE,CA6HpD"}
1
+ {"version":3,"file":"Sidebar.d.ts","sourceRoot":"","sources":["../../src/layout/Sidebar.tsx"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAsM9C,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,OAAO,CAAA;IAClB,gBAAgB,EAAE,MAAM,IAAI,CAAA;IAC5B,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,MAAM,CAAC,EAAE,GAAG,CAAA;CACb;AAED,wBAAgB,OAAO,CAAC,EACtB,SAAS,EACT,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,MAAM,GACP,EAAE,YAAY,2CAqDd;AAmcD,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,UAAU,CAAA;IAChB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAA;IACpB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,EAAE,CAqIpD"}
@@ -441,26 +441,12 @@ export function buildNavItems(config) {
441
441
  // Standard Content destinations (always present — they map to CMS
442
442
  // features, not collections).
443
443
  items.push({ path: '/media', label: 'Media', icon: Image, group: 'Content' }, { path: '/forms', label: 'Forms', icon: ClipboardList, group: 'Content' }, { path: '/seo', label: 'SEO', icon: SearchIcon, group: 'Content' }, { path: '/script-tags', label: 'Script Tags', icon: Code2, group: 'Content' });
444
- // Config-supplied custom groups land after the standard Content block
445
- // and before Settings. Each renders under its own header.
446
- const groupBuckets = new Map();
447
- for (const col of grouped) {
448
- const group = col.admin.group;
449
- const bucket = groupBuckets.get(group) ?? [];
450
- bucket.push({
451
- label: col.labels?.plural ?? col.slug,
452
- path: `/${col.slug}`,
453
- icon: resolveIcon(col),
454
- group,
455
- });
456
- groupBuckets.set(group, bucket);
457
- }
458
- for (const bucket of groupBuckets.values())
459
- items.push(...bucket);
460
444
  // Plugin-contributed custom nav links (PluginDefinition.adminNavItems,
461
445
  // collected onto `_pluginNavItems` by cms-core's applyPlugins). Deduped by
462
446
  // path against everything already present so a plugin can't double a built-in
463
- // destination or one of its own collections.
447
+ // destination or one of its own collections. Emitted HERE — inside the Content
448
+ // block, before the custom collection groups below — so their `group: 'Content'`
449
+ // stays contiguous and doesn't start a second "CONTENT" header after the groups.
464
450
  const pluginNav = Array.isArray(config?._pluginNavItems)
465
451
  ? config._pluginNavItems
466
452
  : [];
@@ -474,6 +460,29 @@ export function buildNavItems(config) {
474
460
  group: 'Content',
475
461
  });
476
462
  }
463
+ // Config-supplied custom groups land after the standard Content block and
464
+ // before Settings. Each renders under its own header. Skip any collection
465
+ // whose path a built-in Content destination (or an already-added item) already
466
+ // provides — otherwise a grouped collection like plugin-forms' `forms`
467
+ // (admin.group: 'Forms', path `/forms`) duplicates the static Forms entry, and
468
+ // `applyFormsNav` then attaches "All Entries" to BOTH.
469
+ const groupBuckets = new Map();
470
+ for (const col of grouped) {
471
+ const path = `/${col.slug}`;
472
+ if (items.some((n) => n.path === path))
473
+ continue;
474
+ const group = col.admin.group;
475
+ const bucket = groupBuckets.get(group) ?? [];
476
+ bucket.push({
477
+ label: col.labels?.plural ?? col.slug,
478
+ path,
479
+ icon: resolveIcon(col),
480
+ group,
481
+ });
482
+ groupBuckets.set(group, bucket);
483
+ }
484
+ for (const bucket of groupBuckets.values())
485
+ items.push(...bucket);
477
486
  // Settings destinations — always last. Users + API Keys now live inside
478
487
  // the Settings view as tabs (see Settings.tsx), so only Settings is anchored
479
488
  // here.
@@ -1 +1 @@
1
- {"version":3,"file":"Sidebar.js","sourceRoot":"","sources":["../../src/layout/Sidebar.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Sidebar.js","sourceRoot":"","sources":["../../src/layout/Sidebar.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Every static route pattern `AdminRoot.renderView()` resolves via a literal
3
+ * `matchRoute('…')` call. Dynamic collection routes are derived per-config in
4
+ * {@link collectionRoutePatterns}; the SEO deep paths are added from the view's
5
+ * own {@link SEO_DEEP_PATHS} so the two can't drift.
6
+ */
7
+ export declare const ADMIN_STATIC_ROUTE_PATTERNS: readonly string[];
8
+ /**
9
+ * Slugs AdminRoot reserves so a consumer- or plugin-defined collection can't
10
+ * own the top-level `/<slug>` route (they stay reachable at `/collections/<slug>`).
11
+ * Mirrors `RESERVED_SLUGS` in AdminRoot.
12
+ */
13
+ export declare const RESERVED_COLLECTION_SLUGS: ReadonlySet<string>;
14
+ interface CollectionLike {
15
+ slug?: string;
16
+ type?: string;
17
+ }
18
+ interface ConfigLike {
19
+ collections?: Record<string, CollectionLike | undefined>;
20
+ }
21
+ /**
22
+ * Match a concrete path against a route pattern using AdminRoot's `matchRoute`
23
+ * rules: equal segment count, and a `:param` segment matches any single
24
+ * non-empty segment. Query string and hash are ignored.
25
+ */
26
+ export declare function matchesRoutePattern(path: string, pattern: string): boolean;
27
+ /**
28
+ * The collection routes AdminRoot derives for a config: the always-available
29
+ * generic `/collections/<slug>`, plus the top-level `/<slug>` list route for
30
+ * each non-reserved collection. Mirrors AdminRoot's `collectionMap` (keyed by
31
+ * `def.slug`, slug-less collections skipped).
32
+ */
33
+ export declare function collectionRoutePatterns(config: ConfigLike | undefined): string[];
34
+ /** Every route pattern AdminRoot can resolve under `config`. */
35
+ export declare function adminRoutePatterns(config?: ConfigLike): string[];
36
+ /**
37
+ * True when `path` resolves to a real admin view (i.e. is NOT the 404 fallback)
38
+ * under `config`. This is the contract every plugin `adminNavItems` path must
39
+ * satisfy — see the `plugin-nav-resolves` test.
40
+ */
41
+ export declare function adminPathResolves(path: string, config?: ConfigLike): boolean;
42
+ export {};
43
+ //# sourceMappingURL=admin-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin-routes.d.ts","sourceRoot":"","sources":["../../src/router/admin-routes.ts"],"names":[],"mappings":"AAgBA;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,EAAE,SAAS,MAAM,EA0CxD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,EAAE,WAAW,CAAC,MAAM,CAexD,CAAA;AAEF,UAAU,cAAc;IACtB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AACD,UAAU,UAAU;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS,CAAC,CAAA;CACzD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAW1E;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,EAAE,CAShF;AAED,gEAAgE;AAChE,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,EAAE,CAEhE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,UAAU,GAAG,OAAO,CAE5E"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * The set of admin routes `AdminRoot.renderView()` can resolve, expressed as
3
+ * data so callers other than the render tree can ask "does this path lead to a
4
+ * real view, or to the 404 fallback?".
5
+ *
6
+ * This exists to guard a recurring class of bug: a plugin advertises an
7
+ * `adminNavItems` path (e.g. `/ai/scores`) that the router has no route for, so
8
+ * the sidebar link lands on the 404 page. Plugins cannot register views — the
9
+ * only destinations that exist are the built-in routes below and the per-config
10
+ * collection routes — so a plugin path is valid only if it resolves here. The
11
+ * `plugin-nav-resolves` test asserts exactly that for every bundled plugin, and
12
+ * the `admin-routes` drift test keeps `ADMIN_STATIC_ROUTE_PATTERNS` in sync with
13
+ * the literal `matchRoute('…')` calls in AdminRoot.
14
+ */
15
+ import { SEO_DEEP_PATHS } from '../views/SEO.js';
16
+ /**
17
+ * Every static route pattern `AdminRoot.renderView()` resolves via a literal
18
+ * `matchRoute('…')` call. Dynamic collection routes are derived per-config in
19
+ * {@link collectionRoutePatterns}; the SEO deep paths are added from the view's
20
+ * own {@link SEO_DEEP_PATHS} so the two can't drift.
21
+ */
22
+ export const ADMIN_STATIC_ROUTE_PATTERNS = [
23
+ '/',
24
+ '/api-keys',
25
+ '/collections/:slug',
26
+ '/collections/:slug/:id',
27
+ '/collections/:slug/new',
28
+ '/forgot-password',
29
+ '/forms',
30
+ '/forms/:id/edit',
31
+ '/forms/:id/submissions',
32
+ '/forms/entries',
33
+ '/forms/new',
34
+ '/media',
35
+ '/page-builder/:id',
36
+ '/page-builder/new',
37
+ '/page-templates',
38
+ '/pages',
39
+ '/pages/:id',
40
+ '/pages/:id/edit',
41
+ '/pages/:id/preview',
42
+ '/pages/new',
43
+ '/pages/tags',
44
+ '/pages/tags/:id/edit',
45
+ '/pages/tags/new',
46
+ '/posts',
47
+ '/posts/:type/:id/edit',
48
+ '/posts/:type/:id/preview',
49
+ '/posts/:type/new',
50
+ '/posts/new',
51
+ '/posts/types',
52
+ '/posts/types/:slug/edit',
53
+ '/posts/types/:slug/template',
54
+ '/posts/types/new',
55
+ '/profile',
56
+ '/reset-password',
57
+ '/saved-sections',
58
+ '/script-tags',
59
+ '/script-tags/:id',
60
+ '/script-tags/new',
61
+ '/settings',
62
+ '/users',
63
+ '/widgets',
64
+ ];
65
+ /**
66
+ * Slugs AdminRoot reserves so a consumer- or plugin-defined collection can't
67
+ * own the top-level `/<slug>` route (they stay reachable at `/collections/<slug>`).
68
+ * Mirrors `RESERVED_SLUGS` in AdminRoot.
69
+ */
70
+ export const RESERVED_COLLECTION_SLUGS = new Set([
71
+ 'media',
72
+ 'forms',
73
+ 'seo',
74
+ 'script-tags',
75
+ 'saved-sections',
76
+ 'page-templates',
77
+ 'widgets',
78
+ 'users',
79
+ 'settings',
80
+ 'profile',
81
+ 'page-builder',
82
+ 'collections',
83
+ 'pages',
84
+ 'posts',
85
+ ]);
86
+ /**
87
+ * Match a concrete path against a route pattern using AdminRoot's `matchRoute`
88
+ * rules: equal segment count, and a `:param` segment matches any single
89
+ * non-empty segment. Query string and hash are ignored.
90
+ */
91
+ export function matchesRoutePattern(path, pattern) {
92
+ const pathParts = path.split('?')[0].split('#')[0].split('/').filter(Boolean);
93
+ const patternParts = pattern.split('/').filter(Boolean);
94
+ if (pattern === '/')
95
+ return pathParts.length === 0;
96
+ if (patternParts.length !== pathParts.length)
97
+ return false;
98
+ for (let i = 0; i < patternParts.length; i++) {
99
+ const pp = patternParts[i];
100
+ if (pp.startsWith(':'))
101
+ continue;
102
+ if (pp !== pathParts[i])
103
+ return false;
104
+ }
105
+ return true;
106
+ }
107
+ /**
108
+ * The collection routes AdminRoot derives for a config: the always-available
109
+ * generic `/collections/<slug>`, plus the top-level `/<slug>` list route for
110
+ * each non-reserved collection. Mirrors AdminRoot's `collectionMap` (keyed by
111
+ * `def.slug`, slug-less collections skipped).
112
+ */
113
+ export function collectionRoutePatterns(config) {
114
+ const out = [];
115
+ for (const def of Object.values(config?.collections ?? {})) {
116
+ const slug = def?.slug;
117
+ if (!slug)
118
+ continue;
119
+ out.push(`/collections/${slug}`);
120
+ if (!RESERVED_COLLECTION_SLUGS.has(slug))
121
+ out.push(`/${slug}`);
122
+ }
123
+ return out;
124
+ }
125
+ /** Every route pattern AdminRoot can resolve under `config`. */
126
+ export function adminRoutePatterns(config) {
127
+ return [...ADMIN_STATIC_ROUTE_PATTERNS, ...SEO_DEEP_PATHS, ...collectionRoutePatterns(config)];
128
+ }
129
+ /**
130
+ * True when `path` resolves to a real admin view (i.e. is NOT the 404 fallback)
131
+ * under `config`. This is the contract every plugin `adminNavItems` path must
132
+ * satisfy — see the `plugin-nav-resolves` test.
133
+ */
134
+ export function adminPathResolves(path, config) {
135
+ return adminRoutePatterns(config).some((pattern) => matchesRoutePattern(path, pattern));
136
+ }
137
+ //# sourceMappingURL=admin-routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin-routes.js","sourceRoot":"","sources":["../../src/router/admin-routes.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@actuate-media/cms-admin",
3
- "version": "0.76.3",
3
+ "version": "0.76.5",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -96,8 +96,15 @@
96
96
  "tailwindcss": "^4.0.0",
97
97
  "typescript": "^5.7.0",
98
98
  "vitest": "^4.1.0",
99
- "@actuate-media/cms-core": "0.93.1",
100
- "@actuate-media/component-blocks": "0.2.2"
99
+ "@actuate-media/cms-core": "0.93.3",
100
+ "@actuate-media/component-blocks": "0.2.2",
101
+ "@actuate-media/plugin-ai": "0.5.4",
102
+ "@actuate-media/plugin-blocks": "0.0.15",
103
+ "@actuate-media/plugin-commerce": "0.1.1",
104
+ "@actuate-media/plugin-forms": "0.0.15",
105
+ "@actuate-media/plugin-media": "0.0.14",
106
+ "@actuate-media/plugin-navigation": "0.0.14",
107
+ "@actuate-media/plugin-seo": "0.0.17"
101
108
  },
102
109
  "scripts": {
103
110
  "build": "tsc --project tsconfig.json && npx @tailwindcss/cli -i src/styles/build-input.css -o dist/actuate-admin.css --minify",
@@ -0,0 +1,90 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import { buildNavItems } from '../../layout/Sidebar.js'
4
+
5
+ /**
6
+ * Mirrors a standard scaffold that enables formsPlugin + seoPlugin +
7
+ * redirectsPlugin (like the `ntn` site): plugin-forms registers a `forms`
8
+ * collection grouped under 'Forms', and every plugin's adminNavItems arrive on
9
+ * `_pluginNavItems`. Before the fix this produced a duplicate "Forms" (static +
10
+ * grouped collection) and a second "CONTENT" header for the SEO sub-links.
11
+ */
12
+ function scaffoldLikeConfig() {
13
+ return {
14
+ collections: {
15
+ pages: { slug: 'pages', type: 'page', labels: { plural: 'Pages' } },
16
+ forms: { slug: 'forms', labels: { plural: 'Forms' }, admin: { group: 'Forms' } },
17
+ 'form-submissions': {
18
+ slug: 'form-submissions',
19
+ labels: { plural: 'Form Submissions' },
20
+ admin: { group: 'Forms' },
21
+ },
22
+ },
23
+ _pluginNavItems: [
24
+ { label: 'Forms', icon: 'FileText', path: '/forms' },
25
+ { label: 'Submissions', icon: 'Inbox', path: '/form-submissions' },
26
+ { label: 'SEO Overview', icon: 'search', path: '/seo' },
27
+ { label: 'Sitemap', icon: 'map', path: '/seo/sitemap' },
28
+ { label: 'Link Health', icon: 'link', path: '/seo/link-health' },
29
+ { label: 'Redirects', icon: 'arrow-right-left', path: '/redirects' },
30
+ ],
31
+ }
32
+ }
33
+
34
+ describe('buildNavItems — duplicate / grouping regressions', () => {
35
+ it('never emits the same path twice', () => {
36
+ const paths = buildNavItems(scaffoldLikeConfig()).map((i) => i.path)
37
+ expect(new Set(paths).size).toBe(paths.length)
38
+ })
39
+
40
+ it('shows Forms exactly once (grouped `forms` collection deduped against the static entry)', () => {
41
+ const items = buildNavItems(scaffoldLikeConfig())
42
+ expect(items.filter((i) => i.path === '/forms')).toHaveLength(1)
43
+ })
44
+
45
+ it('keeps the Content group contiguous — no second CONTENT header', () => {
46
+ const items = buildNavItems(scaffoldLikeConfig())
47
+ // Once the nav leaves the Content group it must never return to it, or the
48
+ // renderer emits a duplicate "CONTENT" section header.
49
+ let leftContent = false
50
+ for (const item of items) {
51
+ if (item.group === 'Content') {
52
+ expect(leftContent).toBe(false)
53
+ } else if (item.group) {
54
+ leftContent = true
55
+ }
56
+ }
57
+ })
58
+
59
+ it('surfaces the SEO sub-links inside the Content block', () => {
60
+ const items = buildNavItems(scaffoldLikeConfig())
61
+ expect(items.find((i) => i.path === '/seo/sitemap')?.group).toBe('Content')
62
+ expect(items.find((i) => i.path === '/seo/link-health')?.group).toBe('Content')
63
+ })
64
+
65
+ it('excludes admin.hidden collections and does not resurrect removed nav paths', () => {
66
+ // Post-fix reality: plugin-forms/plugin-redirects no longer advertise
67
+ // Submissions/Redirects nav items, and their form-submissions/redirects
68
+ // collections are admin.hidden. Neither should surface a (404-ing) nav path.
69
+ const items = buildNavItems({
70
+ collections: {
71
+ pages: { slug: 'pages', type: 'page', labels: { plural: 'Pages' } },
72
+ forms: { slug: 'forms', labels: { plural: 'Forms' }, admin: { group: 'Forms' } },
73
+ 'form-submissions': {
74
+ slug: 'form-submissions',
75
+ labels: { plural: 'Form Submissions' },
76
+ admin: { hidden: true },
77
+ },
78
+ redirects: { slug: 'redirects', labels: { plural: 'Redirects' }, admin: { hidden: true } },
79
+ },
80
+ _pluginNavItems: [
81
+ { label: 'Forms', icon: 'FileText', path: '/forms' },
82
+ { label: 'SEO', icon: 'search', path: '/seo' },
83
+ ],
84
+ })
85
+ const paths = items.map((i) => i.path)
86
+ expect(paths).not.toContain('/form-submissions')
87
+ expect(paths).not.toContain('/redirects')
88
+ expect(items.filter((i) => i.path === '/forms')).toHaveLength(1)
89
+ })
90
+ })
@@ -0,0 +1,74 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { readFileSync } from 'node:fs'
3
+ import { fileURLToPath } from 'node:url'
4
+ import {
5
+ ADMIN_STATIC_ROUTE_PATTERNS,
6
+ adminPathResolves,
7
+ matchesRoutePattern,
8
+ collectionRoutePatterns,
9
+ } from '../../router/admin-routes.js'
10
+
11
+ describe('matchesRoutePattern', () => {
12
+ it('matches by equal segment count with :param wildcards', () => {
13
+ expect(matchesRoutePattern('/pages', '/pages')).toBe(true)
14
+ expect(matchesRoutePattern('/pages/abc123/edit', '/pages/:id/edit')).toBe(true)
15
+ expect(matchesRoutePattern('/', '/')).toBe(true)
16
+ })
17
+
18
+ it('rejects a mismatched segment count or literal', () => {
19
+ expect(matchesRoutePattern('/pages/abc', '/pages')).toBe(false)
20
+ expect(matchesRoutePattern('/ai/scores', '/pages/:id')).toBe(false)
21
+ expect(matchesRoutePattern('/', '/pages')).toBe(false)
22
+ })
23
+
24
+ it('ignores query string and hash', () => {
25
+ expect(matchesRoutePattern('/seo?tab=audit', '/seo')).toBe(true)
26
+ })
27
+ })
28
+
29
+ describe('adminPathResolves', () => {
30
+ it('resolves built-in routes and SEO deep paths', () => {
31
+ expect(adminPathResolves('/media')).toBe(true)
32
+ expect(adminPathResolves('/forms')).toBe(true)
33
+ expect(adminPathResolves('/seo')).toBe(true)
34
+ expect(adminPathResolves('/seo/link-health')).toBe(true)
35
+ })
36
+
37
+ it('does NOT resolve a path with no backing route (the plugin-nav bug)', () => {
38
+ expect(adminPathResolves('/ai/scores')).toBe(false)
39
+ expect(adminPathResolves('/commerce/products')).toBe(false)
40
+ expect(adminPathResolves('/blocks')).toBe(false)
41
+ })
42
+
43
+ it('resolves a non-reserved collection at /<slug> and /collections/<slug>', () => {
44
+ const config = { collections: { products: { slug: 'products' } } }
45
+ expect(adminPathResolves('/products', config)).toBe(true)
46
+ expect(adminPathResolves('/collections/products', config)).toBe(true)
47
+ // Without the collection, the top-level route does not exist.
48
+ expect(adminPathResolves('/products')).toBe(false)
49
+ })
50
+
51
+ it('does not give a reserved-slug collection a shadowing top-level route', () => {
52
+ const patterns = collectionRoutePatterns({ collections: { pages: { slug: 'pages' } } })
53
+ expect(patterns).toContain('/collections/pages')
54
+ expect(patterns).not.toContain('/pages')
55
+ })
56
+ })
57
+
58
+ /**
59
+ * Drift guard: every literal `matchRoute('…')` in AdminRoot must be represented
60
+ * in ADMIN_STATIC_ROUTE_PATTERNS, so `adminPathResolves` can't silently fall
61
+ * behind the real router (which would let a broken plugin nav path pass review).
62
+ * Dynamic `matchRoute(`/${slug}/…`)` template calls and iterated SEO paths are
63
+ * intentionally excluded — those are covered by collection/SEO patterns.
64
+ */
65
+ describe('ADMIN_STATIC_ROUTE_PATTERNS stays in sync with AdminRoot', () => {
66
+ it('covers every literal matchRoute() call in AdminRoot', () => {
67
+ const src = readFileSync(fileURLToPath(new URL('../../AdminRoot.tsx', import.meta.url)), 'utf8')
68
+ const literals = [...src.matchAll(/matchRoute\(\s*'([^']+)'\s*\)/g)].map((m) => m[1]!)
69
+ expect(literals.length).toBeGreaterThan(20)
70
+ const known = new Set(ADMIN_STATIC_ROUTE_PATTERNS)
71
+ const missing = [...new Set(literals)].filter((p) => !known.has(p))
72
+ expect(missing).toEqual([])
73
+ })
74
+ })
@@ -0,0 +1,51 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { aiPlugin } from '@actuate-media/plugin-ai'
3
+ import { blocksPlugin } from '@actuate-media/plugin-blocks'
4
+ import { commercePlugin } from '@actuate-media/plugin-commerce'
5
+ import { formsPlugin } from '@actuate-media/plugin-forms'
6
+ import { mediaPlugin } from '@actuate-media/plugin-media'
7
+ import { navigationPlugin } from '@actuate-media/plugin-navigation'
8
+ import { seoPlugin } from '@actuate-media/plugin-seo'
9
+ import { adminPathResolves } from '../../router/admin-routes.js'
10
+
11
+ /**
12
+ * Systemic guard for the recurring plugin-nav-404 class: a plugin advertises an
13
+ * `adminNavItems` path the admin router has no route for, so the sidebar link
14
+ * lands on the 404 page. It has shipped in published packages more than once
15
+ * (plugin-ai / plugin-commerce / plugin-blocks). Plugins cannot register views,
16
+ * so every nav path MUST resolve to a built-in route or one of the plugin's own
17
+ * collection routes — asserted here for every bundled plugin.
18
+ *
19
+ * When this fails: either point the nav item at a real route (a built-in, or a
20
+ * `/<slug>` for a collection the plugin registers) or remove it until a plugin
21
+ * view API exists. Do NOT add the path to ADMIN_STATIC_ROUTE_PATTERNS unless
22
+ * AdminRoot actually renders a view for it.
23
+ */
24
+ const BUNDLED_PLUGINS = [
25
+ { name: 'plugin-ai', plugin: aiPlugin() },
26
+ { name: 'plugin-blocks', plugin: blocksPlugin() },
27
+ { name: 'plugin-commerce', plugin: commercePlugin() },
28
+ { name: 'plugin-forms', plugin: formsPlugin() },
29
+ { name: 'plugin-media', plugin: mediaPlugin() },
30
+ { name: 'plugin-navigation', plugin: navigationPlugin() },
31
+ { name: 'plugin-seo', plugin: seoPlugin() },
32
+ ]
33
+
34
+ describe('every bundled plugin adminNavItems path resolves to a real admin view', () => {
35
+ for (const { name, plugin } of BUNDLED_PLUGINS) {
36
+ const navItems = plugin.adminNavItems ?? []
37
+ // A config exposing exactly this plugin's collections — the only extra
38
+ // destinations a plugin can legitimately point its nav at.
39
+ const config = { collections: plugin.collections ?? {} }
40
+
41
+ it(`${name} (${navItems.length} nav item${navItems.length === 1 ? '' : 's'})`, () => {
42
+ const dead = navItems
43
+ .map((item) => item.path)
44
+ .filter((path) => !adminPathResolves(path, config))
45
+ expect(
46
+ dead,
47
+ `${name} advertises sidebar paths with no admin route: ${dead.join(', ')}`,
48
+ ).toEqual([])
49
+ })
50
+ }
51
+ })
@@ -860,26 +860,12 @@ export function buildNavItems(config: any): NavItem[] {
860
860
  { path: '/script-tags', label: 'Script Tags', icon: Code2, group: 'Content' },
861
861
  )
862
862
 
863
- // Config-supplied custom groups land after the standard Content block
864
- // and before Settings. Each renders under its own header.
865
- const groupBuckets = new Map<string, NavItem[]>()
866
- for (const col of grouped) {
867
- const group = col.admin.group as string
868
- const bucket = groupBuckets.get(group) ?? []
869
- bucket.push({
870
- label: col.labels?.plural ?? col.slug,
871
- path: `/${col.slug}`,
872
- icon: resolveIcon(col),
873
- group,
874
- })
875
- groupBuckets.set(group, bucket)
876
- }
877
- for (const bucket of groupBuckets.values()) items.push(...bucket)
878
-
879
863
  // Plugin-contributed custom nav links (PluginDefinition.adminNavItems,
880
864
  // collected onto `_pluginNavItems` by cms-core's applyPlugins). Deduped by
881
865
  // path against everything already present so a plugin can't double a built-in
882
- // destination or one of its own collections.
866
+ // destination or one of its own collections. Emitted HERE — inside the Content
867
+ // block, before the custom collection groups below — so their `group: 'Content'`
868
+ // stays contiguous and doesn't start a second "CONTENT" header after the groups.
883
869
  const pluginNav: Array<{ label?: string; icon?: string; path?: string }> = Array.isArray(
884
870
  config?._pluginNavItems,
885
871
  )
@@ -895,6 +881,28 @@ export function buildNavItems(config: any): NavItem[] {
895
881
  })
896
882
  }
897
883
 
884
+ // Config-supplied custom groups land after the standard Content block and
885
+ // before Settings. Each renders under its own header. Skip any collection
886
+ // whose path a built-in Content destination (or an already-added item) already
887
+ // provides — otherwise a grouped collection like plugin-forms' `forms`
888
+ // (admin.group: 'Forms', path `/forms`) duplicates the static Forms entry, and
889
+ // `applyFormsNav` then attaches "All Entries" to BOTH.
890
+ const groupBuckets = new Map<string, NavItem[]>()
891
+ for (const col of grouped) {
892
+ const path = `/${col.slug}`
893
+ if (items.some((n) => n.path === path)) continue
894
+ const group = col.admin.group as string
895
+ const bucket = groupBuckets.get(group) ?? []
896
+ bucket.push({
897
+ label: col.labels?.plural ?? col.slug,
898
+ path,
899
+ icon: resolveIcon(col),
900
+ group,
901
+ })
902
+ groupBuckets.set(group, bucket)
903
+ }
904
+ for (const bucket of groupBuckets.values()) items.push(...bucket)
905
+
898
906
  // Settings destinations — always last. Users + API Keys now live inside
899
907
  // the Settings view as tabs (see Settings.tsx), so only Settings is anchored
900
908
  // here.
@@ -0,0 +1,144 @@
1
+ /**
2
+ * The set of admin routes `AdminRoot.renderView()` can resolve, expressed as
3
+ * data so callers other than the render tree can ask "does this path lead to a
4
+ * real view, or to the 404 fallback?".
5
+ *
6
+ * This exists to guard a recurring class of bug: a plugin advertises an
7
+ * `adminNavItems` path (e.g. `/ai/scores`) that the router has no route for, so
8
+ * the sidebar link lands on the 404 page. Plugins cannot register views — the
9
+ * only destinations that exist are the built-in routes below and the per-config
10
+ * collection routes — so a plugin path is valid only if it resolves here. The
11
+ * `plugin-nav-resolves` test asserts exactly that for every bundled plugin, and
12
+ * the `admin-routes` drift test keeps `ADMIN_STATIC_ROUTE_PATTERNS` in sync with
13
+ * the literal `matchRoute('…')` calls in AdminRoot.
14
+ */
15
+ import { SEO_DEEP_PATHS } from '../views/SEO.js'
16
+
17
+ /**
18
+ * Every static route pattern `AdminRoot.renderView()` resolves via a literal
19
+ * `matchRoute('…')` call. Dynamic collection routes are derived per-config in
20
+ * {@link collectionRoutePatterns}; the SEO deep paths are added from the view's
21
+ * own {@link SEO_DEEP_PATHS} so the two can't drift.
22
+ */
23
+ export const ADMIN_STATIC_ROUTE_PATTERNS: readonly string[] = [
24
+ '/',
25
+ '/api-keys',
26
+ '/collections/:slug',
27
+ '/collections/:slug/:id',
28
+ '/collections/:slug/new',
29
+ '/forgot-password',
30
+ '/forms',
31
+ '/forms/:id/edit',
32
+ '/forms/:id/submissions',
33
+ '/forms/entries',
34
+ '/forms/new',
35
+ '/media',
36
+ '/page-builder/:id',
37
+ '/page-builder/new',
38
+ '/page-templates',
39
+ '/pages',
40
+ '/pages/:id',
41
+ '/pages/:id/edit',
42
+ '/pages/:id/preview',
43
+ '/pages/new',
44
+ '/pages/tags',
45
+ '/pages/tags/:id/edit',
46
+ '/pages/tags/new',
47
+ '/posts',
48
+ '/posts/:type/:id/edit',
49
+ '/posts/:type/:id/preview',
50
+ '/posts/:type/new',
51
+ '/posts/new',
52
+ '/posts/types',
53
+ '/posts/types/:slug/edit',
54
+ '/posts/types/:slug/template',
55
+ '/posts/types/new',
56
+ '/profile',
57
+ '/reset-password',
58
+ '/saved-sections',
59
+ '/script-tags',
60
+ '/script-tags/:id',
61
+ '/script-tags/new',
62
+ '/settings',
63
+ '/users',
64
+ '/widgets',
65
+ ]
66
+
67
+ /**
68
+ * Slugs AdminRoot reserves so a consumer- or plugin-defined collection can't
69
+ * own the top-level `/<slug>` route (they stay reachable at `/collections/<slug>`).
70
+ * Mirrors `RESERVED_SLUGS` in AdminRoot.
71
+ */
72
+ export const RESERVED_COLLECTION_SLUGS: ReadonlySet<string> = new Set([
73
+ 'media',
74
+ 'forms',
75
+ 'seo',
76
+ 'script-tags',
77
+ 'saved-sections',
78
+ 'page-templates',
79
+ 'widgets',
80
+ 'users',
81
+ 'settings',
82
+ 'profile',
83
+ 'page-builder',
84
+ 'collections',
85
+ 'pages',
86
+ 'posts',
87
+ ])
88
+
89
+ interface CollectionLike {
90
+ slug?: string
91
+ type?: string
92
+ }
93
+ interface ConfigLike {
94
+ collections?: Record<string, CollectionLike | undefined>
95
+ }
96
+
97
+ /**
98
+ * Match a concrete path against a route pattern using AdminRoot's `matchRoute`
99
+ * rules: equal segment count, and a `:param` segment matches any single
100
+ * non-empty segment. Query string and hash are ignored.
101
+ */
102
+ export function matchesRoutePattern(path: string, pattern: string): boolean {
103
+ const pathParts = path.split('?')[0]!.split('#')[0]!.split('/').filter(Boolean)
104
+ const patternParts = pattern.split('/').filter(Boolean)
105
+ if (pattern === '/') return pathParts.length === 0
106
+ if (patternParts.length !== pathParts.length) return false
107
+ for (let i = 0; i < patternParts.length; i++) {
108
+ const pp = patternParts[i]!
109
+ if (pp.startsWith(':')) continue
110
+ if (pp !== pathParts[i]) return false
111
+ }
112
+ return true
113
+ }
114
+
115
+ /**
116
+ * The collection routes AdminRoot derives for a config: the always-available
117
+ * generic `/collections/<slug>`, plus the top-level `/<slug>` list route for
118
+ * each non-reserved collection. Mirrors AdminRoot's `collectionMap` (keyed by
119
+ * `def.slug`, slug-less collections skipped).
120
+ */
121
+ export function collectionRoutePatterns(config: ConfigLike | undefined): string[] {
122
+ const out: string[] = []
123
+ for (const def of Object.values(config?.collections ?? {})) {
124
+ const slug = def?.slug
125
+ if (!slug) continue
126
+ out.push(`/collections/${slug}`)
127
+ if (!RESERVED_COLLECTION_SLUGS.has(slug)) out.push(`/${slug}`)
128
+ }
129
+ return out
130
+ }
131
+
132
+ /** Every route pattern AdminRoot can resolve under `config`. */
133
+ export function adminRoutePatterns(config?: ConfigLike): string[] {
134
+ return [...ADMIN_STATIC_ROUTE_PATTERNS, ...SEO_DEEP_PATHS, ...collectionRoutePatterns(config)]
135
+ }
136
+
137
+ /**
138
+ * True when `path` resolves to a real admin view (i.e. is NOT the 404 fallback)
139
+ * under `config`. This is the contract every plugin `adminNavItems` path must
140
+ * satisfy — see the `plugin-nav-resolves` test.
141
+ */
142
+ export function adminPathResolves(path: string, config?: ConfigLike): boolean {
143
+ return adminRoutePatterns(config).some((pattern) => matchesRoutePattern(path, pattern))
144
+ }