Detector::Specification::PayloadCms
Payload CMS generates a REST surface from its collection and global
configs: /api/<slug> for collections, /api/globals/<slug> for
globals, plus whatever endpoints: [...] declares.
CollectionConfig / GlobalConfig are types exported by the
payload package and appear essentially nowhere else, which is what
separates a Payload config from the many unrelated TS files that also
carry slug: and fields: (Astro content collections, Sanity
schemas, Keystone lists).
The deliberate cost is plain-JS configs with no type annotation.
Matching bare slug: + fields: would trip on all three of the
above, so that gap is accepted.
Constants
Single combined gate, checked before anything else. This detector is
applicable to every JS/TS file in the tree and is non-idempotent, so
detect runs on all of them for the whole scan — and vendored
bundles (compiled/*.min.js) can be megabytes each. Running the
individual markers unconditionally meant three full scans per file
and cost ~4x the total scan time on a large TS monorepo.
A config object always declares both.
Class methods
The tech name without needing an instance, so the registry can be read off the classes themselves rather than from a parallel list.
Instance methods
Cheap filename-only filter the detector pass uses to skip
detect on files the detector cannot possibly match. The
default true preserves prior behavior (every detector runs on
every file). Override with the same predicate the body of
detect starts with — e.g., filename.ends_with?(".py") for a
Python framework detector — so the detector loop avoids the
detect dispatch on files outside the detector's language.
On large codebases (saleor's 4255 .py files) this lifts ~100
virtual detect calls per file out of the hot loop because
most detectors' inner first-line is exactly this kind of cheap
filename check.