class

Detector::Specification::PayloadCms

Inherits Detector < Reference < Object

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

BUILD_CONFIG = /\bbuildConfig\s*\(/
COLLECTION_MARKER = /\bCollectionConfig\b/
CONFIG_EXTENSIONS = {".ts", ".tsx", ".js", ".mjs", ".cjs", ".mts", ".cts"}
FIELDS_MARKER = /\bfields\s*:\s*\[/
GLOBAL_MARKER = /\bGlobalConfig\b/
PAYLOAD_MARKER = /\bCollectionConfig\b|\bGlobalConfig\b|\bbuildConfig\s*\(/

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.

SLUG_MARKER = /\bslug\s*:\s*['"]/

A config object always declares both.

Class methods

tech_name

The tech name without needing an instance, so the registry can be read off the classes themselves rather than from a parallel list.

Source

Instance methods

applicable?(filename : String) : Bool

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.

Source
detect(filename : String, file_contents : String) : Bool
Source
idempotent?

Registers every collection, global and config path in CodeLocator.

Source
set_name

Registers every collection, global and config path in CodeLocator.

Source