Skip to content

Admin config identifies its collection with slug, which holds a path #95

Description

@58bits

Summary

CollectionAdminConfig and SingletonAdminConfig identify their target collection with a field named slug, while the thing it holds is a collection's path. defineAdmin() literally assigns slug: schema.path. The two names should agree, and path is the right one — slug names nothing that exists elsewhere in the model.

// packages/core/src/@types/admin-types.ts
export function defineAdmin<T = any>(
  schema: MultiCollectionDefinition,
  config: Omit<CollectionAdminConfig<T>, 'slug' | 'singleton'>
): CollectionAdminConfig<T> {
  return { ...config, singleton: false, slug: schema.path }
}

validate-admin-configs.ts:170 already documents the rule in terms that give the game away:

1. Slug pairing — admin.slug matches exactly one collection.path.

Why it is worth fixing rather than tolerating

This is not only cosmetic. It caused a silent failure in the 6.0 pre-upgrade capability scan, a tool whose entire job is to warn before content breaks.

apps/webapp/src/lib/richtext-capability-targets.ts resolved a field's editor with:

const adminForCollection = (config.admin ?? []).find(
  (entry: any) => entry.path === collection.path   // always undefined === '<path>'
)

Every collection-level field override therefore fell through to the globally registered editor, and the generated manifest overstated what those fields accept — the dangerous direction. Measured against www.forru.org: eleven fields reported 26 node types where their minimal and compact editors register 8 to 10, and the scan reported zero findings where a correct manifest reports four.

Two things kept it invisible:

  1. The (entry: any) cast meant .path on a type with no path was not a compile error.
  2. The unit test did cover the collection branch and passed, because its fixture was hand-written as path: 'pages' — invented to match the implementation rather than what defineAdmin() returns.

Block-level overrides were unaffected (they resolve through blockType, a key that exists), which is why it survived: the reference app's only narrowed fields sit inside blocks, so the collection branch was never exercised by real config.

Fixed in d1511472 (reference app) and ported downstream, but the underlying naming mismatch remains.

Scope of the rename

Small, and contained to @byline/core.

Nobody writes it. slug is Omitted from what callers pass to defineAdmin() / defineSingletonAdmin(); both derive it from schema.path. No downstream application sets it.

Almost nobody reads it — 12 sites, all in this repo:

Location Reads Notes
packages/core/src/config/validate-admin-configs.ts 8 mostly error-message text
packages/core/src/config/config.ts 1 getCollectionAdminConfig lookup
packages/core/src/config/group-collections.ts 1
apps/webapp/src/lib/richtext-capability-targets.ts 1 the one above

Checked across all three known downstream applications (modulus-learning.org, www.forru.org, bylinecms.app): zero admin-config slug references. Every slug occurrence in those repos is an unrelated content/URL slug.

Compatibility

Renaming a field on an exported type is nominally breaking for anyone who built an admin config as an object literal instead of calling defineAdmin(). No known consumer does. Confirmed acceptable as a non-major on that basis, since there are no other downstream applications we are aware of.

Suggested change

  1. Rename slug to path on CollectionAdminConfig and SingletonAdminConfig.
  2. Update defineAdmin / defineSingletonAdmin to assign path: schema.path, and their Omit<…, 'slug' | 'singleton'> signatures.
  3. Update the ~10 read sites, including the error strings, which currently say "Admin resource" and "Slug pairing".
  4. Update apps/webapp/src/lib/richtext-capability-targets.ts and the copy in www.forru.org when it takes the release.
  5. Keep the typed parameter rather than restoring (entry: any) — that annotation is what turns this class of mistake into a compile error.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions