Documentation
¶
Overview ¶
Package cli is PayCLI's command tree and the only place in the program that is allowed to see the process itself.
Everything ambient — argv, the environment, the three standard streams, the wall clock, the HTTP transport and the on-disk directory layout — enters through App and is carried to every command by Runtime. That is what makes whole-command golden tests possible in-process (§17.3): a test builds an App over bytes.Buffers and a fixture server's RoundTripper and asserts on the captured stdout, stderr and the returned exit code.
§3.1 makes this a CI-enforced rule: app.go is the only file outside cmd/ that may reference os.Stdout, os.Stderr, os.Stdin, os.Args, os.Getenv, os.Exit or time.Now.
Index ¶
- Constants
- Variables
- func CompleteBlockSlugs(rt *Runtime) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective)
- func CompleteCensusBlockTypes(rt *Runtime) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective)
- func CompleteCensusFieldPaths(rt *Runtime, entityArg bool, ...) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective)
- func CompleteCollections(rt *Runtime) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective)
- func CompleteEntities(rt *Runtime) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective)
- func CompleteEntitiesVariadic(rt *Runtime) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective)
- func CompleteEntityFlag(rt *Runtime) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective)
- func CompleteEnum(values ...string) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective)
- func CompleteFieldPaths(rt *Runtime, mode FieldMode) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective)
- func CompleteGlobals(rt *Runtime) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective)
- func CompleteProfiles(rt *Runtime) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective)
- func Handle(rt *Runtime, name string, h Handler) func(*cobra.Command, []string) error
- func Main() int
- func PathAdvice(exe string, pathEntries []string, home string) string
- func Register(f factory)
- func Run(ctx context.Context, app App) (code int)
- func SetHelp(cmd *cobra.Command, h *Help)
- func UpdateHint(statePath, currentVersion string) string
- func WhereOperatorAliases() []string
- type App
- type ArgSpec
- type BackupResult
- type BackupTarget
- type Check
- type CommandSpec
- type Deps
- func (d *Deps) BackupBeforeWrite(ctx context.Context, command string, bt BackupTarget) (*BackupResult, error)
- func (d *Deps) BackupPreview(command string, bt BackupTarget) *backupPreview
- func (d *Deps) BackupsEnabled() bool
- func (d *Deps) ResolveDocBySlug(ctx context.Context, t *collTarget, slug string, o SlugLookup) (*DocRef, error)
- type DiscoverOptions
- type DocRef
- type Example
- type FieldMode
- type FlagInfo
- type FlagSpec
- type Handler
- type Help
- type Mistake
- type OutputSpec
- type Runtime
- func (rt *Runtime) Audit() *audit.Logger
- func (rt *Runtime) Cache() *cache.Store
- func (rt *Runtime) CachedManifest() (*discovery.Manifest, bool)
- func (rt *Runtime) CachedShard(slug string, kind cache.EntityKind) (*discovery.Shard, bool)
- func (rt *Runtime) Client(ctx context.Context) (*payload.Client, error)
- func (rt *Runtime) Confirmer() *safety.Confirmer
- func (rt *Runtime) Credential(ctx context.Context) (*secret.Credential, error)
- func (rt *Runtime) Discovery(ctx context.Context) (*discovery.Manifest, error)
- func (rt *Runtime) Elapsed() time.Duration
- func (rt *Runtime) Meta() output.Meta
- func (rt *Runtime) NoRaw() bool
- func (rt *Runtime) Now() time.Time
- func (rt *Runtime) PreviewSecret() (*secret.PreviewSecret, error)
- func (rt *Runtime) RunDiscovery(ctx context.Context, opts DiscoverOptions) (*discovery.Manifest, error)
- func (rt *Runtime) Scope() (cache.Scope, error)
- func (rt *Runtime) SecretStore() *secret.Store
- func (rt *Runtime) Secrets() []string
- func (rt *Runtime) Session() *cache.Session
- func (rt *Runtime) SetDataBytes(n int64)
- func (rt *Runtime) Shard(ctx context.Context, slug string, kind cache.EntityKind) (*discovery.Shard, bool)
- func (rt *Runtime) Stderr() io.Writer
- func (rt *Runtime) Stdin() io.Reader
- func (rt *Runtime) Warn(w ...output.Warning)
- func (rt *Runtime) Warnf(code, format string, args ...any)
- func (rt *Runtime) Warnings() []output.Warning
- type SlugLookup
Constants ¶
const ( // WarnBackupSkipped names targeted documents the backup read did not // return. The write still runs — it will answer for those ids itself // (usually doc_not_found) — but nothing was saved for them. WarnBackupSkipped = "backup_skipped" // WarnBackupsOff is `pay backups …` run with no backup directory. WarnBackupsOff = "backups_disabled" // WarnBackupRedacted names the credential values a backup masked: the // file does not hold them, so a restore cannot bring them back. WarnBackupRedacted = "backup_redacted" )
Warning codes raised by the backup hook.
const ( // WarnRestoredAsDraft: the backup holds a draft, the live document is // published, so the restore saved a new draft instead of unpublishing. WarnRestoredAsDraft = "restored_as_draft" // WarnRecreatedNewID: --recreate made a new document; the id changed. WarnRecreatedNewID = "backup_recreated_new_id" // WarnRecreateIgnored: --recreate was passed but the document exists. WarnRecreateIgnored = "recreate_not_needed" // WarnFieldsNotRestored: fields the restore deliberately did not send. WarnFieldsNotRestored = "backup_fields_not_restored" // WarnRecreatedInTrash: the backup was of a trashed document, and so is // the re-created one. WarnRecreatedInTrash = "backup_recreated_in_trash" // WarnPublishedNotRestored: the backup holds a published state under a // newer draft, and this restore did not put it back. WarnPublishedNotRestored = "published_state_not_restored" // WarnRestoreTwoSteps: the dry run of a restore that writes the backup's // published state and then its draft on top — two versions. WarnRestoreTwoSteps = "restore_two_steps" )
Warning codes `pay backups restore` raises.
const ( // WarnNeverPublished marks a --draft-vs-published diff whose "published" // side is not a published document. WarnNeverPublished = "never_published" // WarnFieldNotOnDocument marks body keys the stored document does not // have — usually a typo, which Payload drops without an error. WarnFieldNotOnDocument = "field_not_on_document" // WarnBodyIDMismatch marks a body whose own id names another document. WarnBodyIDMismatch = "body_id_mismatch" // WarnBodyPublishes marks a body carrying _status "published": the write // publishes even when it is sent with --draft. WarnBodyPublishes = "body_publishes" )
Warning codes `pay diff` raises.
const ( CheckOK = "ok" CheckWarn = "warn" CheckFail = "fail" CheckUnknown = "unknown" CheckSkipped = "skipped" )
Check statuses. `unknown` is a first-class answer: a fact PayCLI could not establish is never reported as a pass or a failure (§7.6).
const ( // DetailCap is how many per-collection detail entries the default tier // emits. The SLUG LIST IS NEVER TRUNCATED — data.collection_slugs always // holds every slug, because it is the single most load-bearing thing this // command returns. DetailCap = 40 // DefaultMaxBytes is --max-bytes' default: above it, --full refuses. DefaultMaxBytes = 400 << 10 )
§18's tiers.
const ( // WarnRedactedNotSent says masked values in merged fields were left out // of the body. WarnRedactedNotSent = "redacted_not_sent" // WarnRedactedRemoved says masked keys inside rich text or json had no // stored value to be restored from and were removed from the value. WarnRedactedRemoved = "redacted_removed" )
Warning codes this file raises.
const ( // WarnOrphanRows reports orphan symptoms observed after a write. WarnOrphanRows = "orphan_rows" // WarnOrphanRisk predicts them before a write. WarnOrphanRisk = "orphan_risk" // WarnEmptyRows reports `{}` rows in a document that was read. WarnEmptyRows = "empty_rows" // WarnOrphanCheckIncomplete says the stored row could not be read back // after the write, so orphan rows were neither confirmed nor ruled out. WarnOrphanCheckIncomplete = "orphan_check_incomplete" // WarnResetNestedNotNeeded says --reset-nested had nothing to do. WarnResetNestedNotNeeded = "reset_nested_not_needed" // WarnResetNestedIncomplete says a carrier phase failed after an earlier // one was written; the requested body was still written. WarnResetNestedIncomplete = "reset_nested_incomplete" // WarnPendingDraftSuperseded says a bulk non-draft write replaces // pending drafts instead of building on them (§10.2.3). WarnPendingDraftSuperseded = "pending_draft_superseded" // WarnResetNestedUnresolved names `{}` rows whose block type no version // of the document could name, so no carrier could clear them. WarnResetNestedUnresolved = "reset_nested_unresolved" )
Warning codes of §10.2.1.
const ( // WarnUpstreamError marks a stage that did nothing because its input was // already an error envelope. WarnUpstreamError = "upstream_error" // WarnBlocksFieldInferred marks a field chosen by looking at the document // rather than at the project's schema. WarnBlocksFieldInferred = "blocks_field_inferred" // WarnFieldAbsent marks a --field the document does not carry, which is // almost always a --select that trimmed it away. WarnFieldAbsent = "field_absent" // WarnPopulatedRelationship marks a row that carries an expanded // relationship object where the API expects an id. WarnPopulatedRelationship = "populated_relationship" // WarnEnvelopeUnwrapped marks a --data that was handed a whole PayCLI // envelope and was read as its .data. WarnEnvelopeUnwrapped = "envelope_unwrapped" )
warn codes this file raises.
const ( GroupDiscovery = "discovery" GroupRead = "read" GroupWrite = "write" GroupEdit = "edit" GroupFiles = "files" GroupAdmin = "admin" GroupOther = "other" )
Command groups, so `pay --help` reads as a map of the tool rather than an alphabetical wall. A command that sets no GroupID lands in "other".
const ( PathSourceBreadcrumbs = "breadcrumbs" PathSourceTemplate = "template" PathSourceSlug = "slug" PathSourceHome = "home" )
Path sources, in resolution order (F9).
const ( WarnURLPathGuessed = "url_path_guessed" WarnURLNotLive = "url_not_live" WarnPreviewNoAuth = "preview_credential_withheld" )
Warning codes `pay url` emits.
const CompletionBudget = 100 * time.Millisecond
CompletionBudget is §9.9's hard limit. A shell that hangs on TAB is worse than one that suggests nothing, so every completion function checks the budget before and after the one cache read it is allowed to make.
const CookieFilePerm = 0o600
CookieFilePerm is the preview cookie file's mode: the cookie IS draft access to the whole site for as long as the build lives.
const DefaultSlugField = "slug"
DefaultSlugField is the field ResolveDocBySlug matches when SlugLookup.Field is empty: the Payload website template's (and the slug field plugin's) name.
const ( // WarnBlockTypeOmitted marks a `pay blocks add <blockType>` whose target // is a plain array field: the new row was added without the blockType. WarnBlockTypeOmitted = "block_type_omitted" )
const WarnBodyStatusIgnored = "body_status_ignored"
WarnBodyStatusIgnored says a body's _status was removed: in upsert and sync the publication state is set by --draft/--publish (a manifest's "status") and nothing else. Leaving it in would reopen the body_publishes footgun — Payload publishes any write whose body says _status "published", ?draft=true notwithstanding (payload@3.87.1 collections/operations/ utilities/update.js, isSavingDraft).
const WarnConfigPathAnchored = "config_path_anchored"
WarnConfigPathAnchored: `pay config set` stored a relative path as the absolute path it means.
const WarnHookRewroteUnsent = "hook_rewrote_unsent"
WarnHookRewroteUnsent says a write changed fields the body declares but did not send (their value was already stored): a server hook fills fields a request leaves out.
const WarnMatchValueNormalized = "match_value_normalized"
WarnMatchValueNormalized says the server stored a match field in another form than the body sent (a slug-formatting hook): the next plan or upsert, which matches on the body's value, will not find the document.
const WarnPublishesPendingDraft = "publishes_pending_draft"
WarnPublishesPendingDraft says a write that publishes also publishes the document's pending draft (whose changes the caller may not have made).
const WarnRefTargetUnchecked = "ref_target_unchecked"
WarnRefTargetUnchecked says references sit in fields whose relationTo no schema source knows, so a reference naming the wrong collection could not be caught.
const WarnRelationIDNotNumeric = "relation_id_not_numeric"
WarnRelationIDNotNumeric says a {relationTo, value} pair names a document of a numeric-id collection by a value that is not a number: a Markdown link written as [text](pay:pages/about), where "about" is a slug.
const WarnSavedAsDraft = "saved_as_draft"
WarnSavedAsDraft says a write with status keep was saved into the pending draft of a published document: the live document did not change.
const WarnStaleIndex = "stale_index"
WarnStaleIndex marks a nested --field that enters a row BY POSITION of an array an earlier stage of the same pipe reordered or resized.
Variables ¶
var BulkExitCodes = []int{ apierr.ExitOK, apierr.ExitInternal, apierr.ExitAuth, apierr.ExitThrottled, apierr.ExitNotFound, apierr.ExitValidation, apierr.ExitNetwork, apierr.ExitPartial, apierr.ExitAccessDenied, apierr.ExitConfig, apierr.ExitCapability, apierr.ExitConfirmationRequired, }
BulkExitCodes adds §12.5's partial commit and §12's confirmation gate. 7 is the one an agent must never auto-retry.
var DestructiveExitCodes = []int{ apierr.ExitOK, apierr.ExitInternal, apierr.ExitAuth, apierr.ExitThrottled, apierr.ExitNotFound, apierr.ExitValidation, apierr.ExitNetwork, apierr.ExitAccessDenied, apierr.ExitConfig, apierr.ExitCapability, apierr.ExitConfirmationRequired, }
DestructiveExitCodes adds §12's confirmation gate to a single-document write.
var ReadExitCodes = []int{ apierr.ExitOK, apierr.ExitInternal, apierr.ExitAuth, apierr.ExitThrottled, apierr.ExitNotFound, apierr.ExitValidation, apierr.ExitNetwork, apierr.ExitAccessDenied, apierr.ExitConfig, apierr.ExitCapability, }
ReadExitCodes is what any command that reads from the server can return.
var WriteExitCodes = ReadExitCodes
WriteExitCodes is ReadExitCodes for a single-document write: same failures, and nothing bulk-specific.
Functions ¶
func CompleteBlockSlugs ¶ added in v0.2.0
func CompleteBlockSlugs(rt *Runtime) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective)
CompleteProfiles completes --profile from the two config files. It reads no credentials and never touches the keychain. CompleteBlockSlugs completes `pay describe <entity> --block <slug>` from the cached shard's block schemas and the cached block census (§7.10c) — on a project with introspection disabled the census is the only source of slugs.
It suggests the slugs, never the GraphQL interfaceNames: an interfaceName is exactly the value Payload silently drops (§7.10), so offering one on TAB would be a suggestion that produces a 201 and no content.
func CompleteCensusBlockTypes ¶ added in v0.3.0
func CompleteCensusBlockTypes(rt *Runtime) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective)
CompleteCensusBlockTypes completes the <blockType> argument of `pay blocks schema|example|new|add`: the entity named by --collection when it is given, otherwise every entity the cached census read.
func CompleteCensusFieldPaths ¶ added in v0.3.0
func CompleteCensusFieldPaths(rt *Runtime, entityArg bool, extra func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective)) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective)
CompleteCensusFieldPaths completes a blocks-field --field for the catalog verbs and `pay describe`: the entity's declared blocks fields plus every pattern the census saw (`layout`, `layout[].blocks`) and the parent-scoped form (`group.blocks`). The entity is --collection when the command has one and it is set, else the first positional argument when entityArg says that argument IS an entity (`pay blocks types pages`, `pay describe pages`); otherwise (`pay blocks schema text`) every entity the census read. extra, when set, supplies the command's ordinary field paths as well (describe's --field takes any field).
func CompleteCollections ¶
func CompleteCollections(rt *Runtime) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective)
CompleteCollections completes a collection slug from the cached index.
func CompleteEntities ¶
func CompleteEntities(rt *Runtime) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective)
CompleteEntities completes a collection OR global slug, for `pay describe`.
func CompleteEntitiesVariadic ¶ added in v0.3.0
func CompleteEntitiesVariadic(rt *Runtime) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective)
CompleteEntitiesVariadic completes collection or global slugs for a command that takes several (`pay blocks learn pages ctas`), skipping those given.
func CompleteEntityFlag ¶ added in v0.3.0
func CompleteEntityFlag(rt *Runtime) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective)
CompleteEntityFlag completes a flag whose value is a collection or global slug (`--collection`), whatever positional arguments are already given.
func CompleteEnum ¶
func CompleteEnum(values ...string) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective)
CompleteEnum completes a fixed value set, for --output and friends.
func CompleteFieldPaths ¶
func CompleteFieldPaths(rt *Runtime, mode FieldMode) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective)
CompleteFieldPaths completes a field path for the collection already on the command line. It decodes at most the single shard for that collection (§9.9); a missing or generation-mismatched shard yields nothing.
func CompleteGlobals ¶
func CompleteGlobals(rt *Runtime) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective)
CompleteGlobals completes a global slug from the cached index.
func CompleteProfiles ¶
func Handle ¶
Handle adapts a Handler to cobra's RunE. `name` is the envelope's `command` field and the audit log's command name; it is the space-joined command path without the "pay" prefix ("auth login", "find").
Handle is the ONLY place a command's output reaches a stream. A Handler that returns (nil, nil) is a programming error and surfaces as exit 1.
func Main ¶
func Main() int
Main is the entry point cmd/pay/main.go calls. It returns the exit status instead of taking it, so nothing below cmd/ ever calls os.Exit.
func PathAdvice ¶ added in v0.3.0
PathAdvice is the one remedy text for "the binary's directory is not on $PATH", shared by `pay doctor` and install.sh (which prints the same sentences). The robust fix is a link from a directory the shell ALREADY searches; editing rc files helps only the shells that read them.
func Register ¶
func Register(f factory)
Register adds a subcommand factory to the root tree.
Every command file calls this from an init(), so root.go never has to name the individual commands and several agents can add commands to the same package without editing a shared switch. Registration order does not matter: the tree is sorted by command name before assembly, which makes `pay --help` and the alias-resolution order deterministic.
func Run ¶
Run executes one PayCLI invocation and returns its exit status. It never panics out to the caller: a panic in a command is converted to exit 1 with an `internal` envelope, because an agent parsing stdout must always get an envelope.
func UpdateHint ¶
UpdateHint is the one-line notice `pay version` and `pay doctor` print when a newer release was recorded by an earlier --check. It never performs I/O beyond reading the state file, so it is safe on every command path.
func WhereOperatorAliases ¶
func WhereOperatorAliases() []string
WhereOperatorAliases is the flat alias list §10.4 puts on the --where flag.
Types ¶
type App ¶
type App struct {
// Args is os.Args[1:] — the program name is not included.
Args []string
// Env is os.Environ()'s "NAME=value" form.
Env []string
Stdin io.Reader
Stdout io.Writer
Stderr io.Writer
// Now is the only clock the program has. Tests pin it.
Now func() time.Time
// HTTP replaces the transport internal/payload would otherwise build. A
// test points it at an httptest.Server; production leaves it nil.
HTTP http.RoundTripper
// Dirs overrides the §4.1 directory layout wholesale. A zero value is
// derived from Env.
Dirs config.Paths
// WorkDir is the directory project discovery (§4.3) walks up from.
WorkDir string
// Terminal facts. False is the safe answer: PayCLI never changes output
// shape based on a TTY (§10), it only uses these for the interactive
// confirmation prompt (§12.2) and the "you typed a key on a terminal"
// warning (§5.1 step 3).
StdinIsTTY bool
StdoutIsTTY bool
StderrIsTTY bool
// NoSignals disables the SIGINT/SIGTERM handler. Tests set it; the
// in-process handler would otherwise leak across `go test`.
NoSignals bool
// Executable is the path the running binary was started from, symlinks
// NOT resolved (os.Executable). `pay doctor` checks that its directory is
// on $PATH. Empty means unknown, and the check reports `unknown`.
Executable string
}
App is the injected process surface. A zero value is unusable; Run substitutes inert defaults (io.Discard, a fixed clock) for anything left nil so that a malformed App can never panic mid-command.
type ArgSpec ¶
type ArgSpec struct {
Name string `json:"name"`
Required bool `json:"required"`
Type string `json:"type"`
ValuesFrom string `json:"values_from,omitempty"`
Values []string `json:"values,omitempty"`
Example string `json:"example,omitempty"`
}
ArgSpec documents one positional argument (§10.4).
type BackupResult ¶ added in v0.3.0
type BackupResult struct {
// Paths are the files written (or, for documents this invocation had
// already backed up, the file written the first time).
Paths []string
// Skipped are the ids the backup read did not return.
Skipped []any
// Redacted are the values masked in the files, as "<doc>: <path>". They
// are not in the backup, so a restore cannot bring them back.
Redacted []string
}
BackupResult is what one backup pass produced.
type BackupTarget ¶ added in v0.3.0
type BackupTarget struct {
Collection *collTarget
Global *globalTarget
IDs []any
Params query.Params
}
BackupTarget names the documents a write is about to change.
Exactly one of Collection and Global is set. IDs are the collection document ids; when a writeOp carries the target, nil IDs means "the ids the writeOp was given" (withIDs), which is how the bulk verbs hand over the ids §12.3 resolved. Params are the WRITE's query parameters: only Locale, FallbackLocale and Trash are consulted — the read always uses depth=0, and draft=true exactly when the entity has drafts.
type Check ¶
type Check struct {
Name string `json:"name"`
Status string `json:"status"`
Detail string `json:"detail"`
Hint string `json:"hint,omitempty"`
Value any `json:"value,omitempty"`
}
Check is one diagnostic line.
type CommandSpec ¶
type CommandSpec struct {
Path []string `json:"path"`
Short string `json:"short"`
Args []ArgSpec `json:"args"`
Flags []FlagSpec `json:"flags"`
Subcommands []string `json:"subcommands,omitempty"`
Output OutputSpec `json:"output"`
ExitCodes []int `json:"exit_codes"`
Examples []Example `json:"examples"`
Mistakes []Mistake `json:"common_mistakes,omitempty"`
SeeAlso []string `json:"see_also,omitempty"`
}
CommandSpec is §10.4's machine-readable help.
type Deps ¶
type Deps struct {
// RT is the shared runtime.
RT *Runtime
// Client is the configured Payload REST client.
Client *payload.Client
// Manifest is the discovery index, or nil when discovery could not answer.
// A nil manifest disables every client-side rejection rather than inventing
// one, which is §9.3's tri-state rule applied at the top.
Manifest *discovery.Manifest
// FetchURL downloads a remote upload source (§13). It is a field so unit
// tests never reach the network.
FetchURL func(ctx context.Context, rawurl string) (body io.ReadCloser, contentType string, size int64, err error)
// contains filtered or unexported fields
}
Deps is one data command's resolved dependencies.
func (*Deps) BackupBeforeWrite ¶ added in v0.3.0
func (d *Deps) BackupBeforeWrite(ctx context.Context, command string, bt BackupTarget) (*BackupResult, error)
BackupBeforeWrite is the exported §12.8 hook: it backs up every document bt names and returns the files. With backups off it does nothing and returns an empty result. Any failure — the read or the file — is backup_failed (exit 1) with the --no-backup hint, and the caller MUST NOT send its write.
func (*Deps) BackupPreview ¶ added in v0.3.0
func (d *Deps) BackupPreview(command string, bt BackupTarget) *backupPreview
BackupPreview is would_backup for a dry run: the files the real run would write, without reading or writing anything. nil when backups are off.
func (*Deps) BackupsEnabled ¶ added in v0.3.0
BackupsEnabled reports whether a write in this invocation will be backed up. A caller that must do extra work only to name the documents (resolve ids for the passthrough delete, look up a version's parent) checks this first, so a user without backups never pays for it.
func (*Deps) ResolveDocBySlug ¶ added in v0.3.0
func (d *Deps) ResolveDocBySlug(ctx context.Context, t *collTarget, slug string, o SlugLookup) (*DocRef, error)
ResolveDocBySlug finds exactly one document of collection t whose slug field equals slug, in one bounded request (limit 2, id-only select):
- no match -> doc_not_found (exit 4), with a hint that names --draft when the lookup did not use it (the slug may exist only in a draft);
- several -> slug_ambiguous (exit 5), with the matching ids in error.did_you_mean;
- exactly one -> its DocRef.
It validates the slug field against the collection's field shard when one is known (a Payload `where` on an unknown field is a 400 QueryError, or worse a silent match-all on some adapters), and never guesses a field that is not there. Callers pass the same --draft/--trash/--locale they will use for the follow-up read, so the id they get is the document they will then read.
type DiscoverOptions ¶
DiscoverOptions are the knobs `pay discover` exposes. The zero value is what every other command uses.
type DocRef ¶ added in v0.3.0
type DocRef struct {
// ID is the id exactly as Payload returned it (a JSON number on Postgres,
// a string on MongoDB), for envelopes.
ID any
// IDString is the same id rendered for a URL path or a next.cmd.
IDString string
// Slug is the value that matched.
Slug string
}
DocRef is the one document a slug resolved to.
type FieldMode ¶
type FieldMode string
FieldMode selects which field-path projection a completion offers.
const ( // FieldQueryable completes --where / --or paths. FieldQueryable FieldMode = "queryable" // FieldSortable completes --sort. FieldSortable FieldMode = "sortable" // FieldSelectable completes --select / --select-exclude. FieldSelectable FieldMode = "selectable" // FieldDate completes --date-field. FieldDate FieldMode = "date" )
type FlagInfo ¶
type FlagInfo struct {
Grammar string `json:"grammar,omitempty"`
Operators []string `json:"operators,omitempty"`
Values []string `json:"values,omitempty"`
Repeatable bool `json:"repeatable,omitempty"`
Min *int `json:"min,omitempty"`
Max *int `json:"max,omitempty"`
// Note is printed in the FLAGS section, e.g. "no-op on this project:
// localization is disabled".
Note string `json:"note,omitempty"`
}
FlagInfo is the §10.4 detail for one flag.
type FlagSpec ¶
type FlagSpec struct {
Name string `json:"name"`
Shorthand string `json:"shorthand,omitempty"`
Type string `json:"type"`
Repeatable bool `json:"repeatable"`
Default any `json:"default"`
Usage string `json:"usage"`
Grammar string `json:"grammar,omitempty"`
Operators []string `json:"operators,omitempty"`
Values []string `json:"values,omitempty"`
Min *int `json:"min,omitempty"`
Max *int `json:"max,omitempty"`
}
FlagSpec is one flag of a CommandSpec.
type Handler ¶
Handler is the shape every PayCLI command implements. Returning an envelope and an error is deliberate: the envelope is rendered when err is nil, and the error is normalised into an error envelope otherwise, so no command has to know about exit codes, --path, --output or meta.
type Help ¶
type Help struct {
// Synopsis lines are printed verbatim under SYNOPSIS, metavariables and
// all.
Synopsis []string
// Long is optional prose printed under the one-line Short.
Long string
// Discovered renders section 3 for this command. Returning nil falls back
// to the shared collection inventory when Collections is true.
Discovered func(rt *Runtime, m *discovery.Manifest) []string
// Collections asks for the shared "collections in this project" block in
// section 3.
Collections bool
// Globals asks for the globals inventory in section 3.
Globals bool
// Where and Sort switch on sections 4 and 5. They belong on any command
// that accepts --where or --sort.
Where bool
Sort bool
// Args documents the positional arguments for §10.4.
Args []ArgSpec
// FlagInfo adds §10.4 detail (grammar, operators, bounds) that pflag
// cannot express, keyed by flag name.
FlagInfo map[string]FlagInfo
Output OutputSpec
ExitCodes []int
Examples []Example
Mistakes []Mistake
SeeAlso []string
// Notes are extra bullet lines printed after FLAGS. Use them for the
// "this flag is a no-op on this project" callouts §10.5 item 6 requires.
Notes []string
}
Help is the §10.5 model for one command's help text. Every command supplies the parts that cannot be derived from its cobra definition; the flag table, the command path and the subcommand list are read off cobra itself so the two can never drift.
A command with no Help still renders all eleven sections — it simply has no examples and no mistakes to show. That is a visible hole rather than a silent one, which is the point.
type Mistake ¶
Mistake is one numbered anti-pattern and its correction. §10.5's hard rule: every "you cannot X" is followed by "do Y instead", which is why Right is not optional.
type OutputSpec ¶
type OutputSpec struct {
Kind output.DataKind `json:"data_kind"`
Paginated bool `json:"paginated,omitempty"`
Skeleton string `json:"skeleton,omitempty"`
}
OutputSpec is §10.4's output block.
type Runtime ¶
type Runtime struct {
App App
// Env is the environment snapshot every layer reads from.
Env config.Env
// Paths is the resolved §4.1 layout.
Paths config.Paths
// Project is the detected Payload project (§4.3), never nil.
Project *config.Project
// UserFile and ProjectFile are the two config layers, never nil.
UserFile *config.File
ProjectFile *config.File
// Cfg is the resolved configuration. Nil until the persistent pre-run has
// executed, which is why every command handler receives it already set.
Cfg *config.Resolved
// Command is the dotted command path of the command being run ("auth
// login"), used for envelope.command and the audit log.
Command string
// Out renders envelopes. Commands must not write to App.Stdout directly.
Out *output.Writer
// Log is the structured logger; never nil.
Log *slog.Logger
// Flags is the parsed root flag state, exposed so a command can tell
// "flag not given" from "flag given the default value".
Flags *rootFlags
// contains filtered or unexported fields
}
Runtime is the per-invocation world every command is handed. It owns the resolved configuration, the lazily built client, the cache session, the logger, the audit log and the renderer.
Everything expensive is lazy and memoised: `pay version` must work on a machine with no config, no network and no cache, so a Runtime that never resolves a credential never touches the keychain.
func (*Runtime) Cache ¶
Cache is the discovery cache store. It is permanently disabled (every read a miss, every write a no-op) under --no-cache.
func (*Runtime) CachedManifest ¶
CachedManifest returns the discovery index from disk without any possibility of a network call. Help text (§10.5) and shell completion (§9.9) use this and nothing else: both must render instantly on a cold cache rather than block.
func (*Runtime) CachedShard ¶
CachedShard is the offline form used by completion and help, which may never trigger discovery.
func (*Runtime) Client ¶
Client builds the Payload client for the resolved profile and credential.
It never hands out a client whose auth-collection slug is still §7.0's "auto" placeholder: in api-key mode the slug is part of the Authorization header, and a wrong slug answers HTTP 200 with the anonymous view rather than an error. resolveAuthCollection runs the §7.0 ladder (configured → cached → Stage -1) before the client escapes this function.
func (*Runtime) Credential ¶
Credential resolves §5.1's chain once per invocation.
func (*Runtime) Discovery ¶
Discovery returns the discovery index, running §7's pipeline when the cache cannot answer. It is memoised per invocation.
func (*Runtime) PreviewSecret ¶ added in v0.3.0
func (rt *Runtime) PreviewSecret() (*secret.PreviewSecret, error)
PreviewSecret resolves F9's preview-secret chain once per invocation (PAY_PREVIEW_SECRET_<P>, PAY_PREVIEW_SECRET, the profile's preview_secret_env, credentials.json). A nil secret with a nil error means none is configured; whether that is fatal is the caller's call, because a preview_path without {secret} needs none.
Like Credential it re-arms the logger, so the literal is scrubbed from every later log line on top of the per-request URL scrubbing the payload client does.
func (*Runtime) RunDiscovery ¶
func (rt *Runtime) RunDiscovery(ctx context.Context, opts DiscoverOptions) (*discovery.Manifest, error)
RunDiscovery executes §7's pipeline and persists the result (§8.7).
func (*Runtime) SecretStore ¶
SecretStore is the credentials.json + keychain store for this profile set.
func (*Runtime) Secrets ¶
Secrets returns the literal credential values that must be scrubbed from every log line and every rendered byte (§5.3). It never resolves a credential on its own.
func (*Runtime) SetDataBytes ¶
SetDataBytes makes meta.bytes report the size of the rendered payload rather than the bytes read from the network. `pay explain` is the case §18 names.
func (*Runtime) Shard ¶
func (rt *Runtime) Shard(ctx context.Context, slug string, kind cache.EntityKind) (*discovery.Shard, bool)
Shard returns one entity's field schema, decoding it from the cache when the current invocation did not produce it.
func (*Runtime) Warn ¶
Warn records an envelope warning. Duplicates (same code and message) are collapsed so a fan-out cannot emit the same advice a hundred times.
type SlugLookup ¶ added in v0.3.0
type SlugLookup struct {
// Field is the field to match; "" means DefaultSlugField.
Field string
// Draft matches against each document's NEWEST draft (?draft=true). A
// slug that was changed in an unpublished draft is found only this way;
// without it the match runs against the stored (published, or
// never-published) state, exactly like a bare `pay find`.
Draft bool
// Trash includes soft-deleted documents.
Trash bool
// Locale matches a localized slug in this locale ("" = the default).
Locale string
}
SlugLookup says how ResolveDocBySlug searches.
Source Files
¶
- access.go
- app.go
- apply.go
- audit.go
- auth.go
- auth_preview.go
- backup.go
- backups.go
- blocks.go
- blocks_catalog.go
- blocks_census.go
- blocks_path.go
- cache.go
- can.go
- collections.go
- complete.go
- complete_blocks.go
- completion.go
- config.go
- count.go
- create.go
- delete.go
- describe.go
- diff.go
- discover.go
- docresolve.go
- doctor.go
- doctor_census.go
- doctor_site.go
- download.go
- duplicate.go
- explain.go
- find.go
- get.go
- globals.go
- help.go
- idmatch.go
- lexical.go
- local.go
- masked.go
- opmemo.go
- orphans.go
- outline.go
- pendingdraft.go
- pipeline.go
- plan.go
- profile.go
- pubguard.go
- publish.go
- raw.go
- refs.go
- reset_nested.go
- restore.go
- richtext.go
- richtext_preimage.go
- root.go
- selfupdate.go
- skills.go
- skills_project.go
- sync.go
- update.go
- upload.go
- upsert.go
- url.go
- url_preview.go
- version.go
- versions.go
- whoami.go