/** * The file inside the code bundle that carries the `runner.registries` * configuration. This path is a contract with Checkly runners: when the * file is present, the runner routes package installs through a local * registry that selects upstreams according to the routing rules within. * * Pattern matching semantics are defined by the matcher in * `services/embedded-packages/spec.ts` (single `*` never crosses the `/` * scope separator, `**` does, and a `**` directly before a `/` may match * zero segments); runners must reproduce them exactly — off-the-shelf * glob matchers differ, e.g. on a `**` that is not a whole segment. * * When the file is present it is authoritative for the runner's package * installs: registries, credentials and TLS settings in the bundle's own * config files (`.npmrc`, `pnpm-workspace.yaml`, `.yarnrc.yml`) are not * consulted — the runner only scans them for scoped registry routes the * package manager itself would follow, so it can override those * client-side. Upstream TLS trust extends via the `NODE_EXTRA_CA_CERTS` * environment variable, and proxying honors `HTTP(S)_PROXY`/`NO_PROXY`. * Embedded packages (`.checkly/embedded-packages/`) always take priority * over any routing. * * Runner support must be deployed before a CLI release starts writing * this file: a runner that predates the feature ignores the file * entirely and installs from the bundle's own registry configuration, * with no error anywhere. */ export declare const REGISTRIES_ARCHIVE_PATH = ".checkly/config/registries.json"; /** * The format version written into {@link REGISTRIES_ARCHIVE_PATH}. Runners * reject versions they do not know, so the version only changes when the * file's meaning changes in a way an older runner must not silently * misread. */ export declare const REGISTRIES_FILE_VERSION = 1; /** * Credentials the runner presents to an upstream registry. The token must * be exactly one `${VAR}` environment variable reference: the value is * resolved from the check's environment variables on the runner, never on * the machine running the CLI, so the secret value appears in neither the * configuration nor the uploaded code bundle. Anything else — a literal * token, or a literal mixed with a reference — is rejected at config load. */ export type UpstreamAuth = { type: 'bearer'; /** * A `${VAR}` reference to the environment variable holding the token, * e.g. `'${NPM_TOKEN}'` (in single quotes, so no shell or template * expansion happens locally). */ token: string; }; /** * An npm registry the runner may install packages from. */ export interface Upstream { /** * The registry base URL, e.g. `'https://registry.npmjs.org/'`. Package * paths are appended to it, so the URL must not carry a query, fragment * or inline `user:password` credentials — use `auth` for credentials. A * missing trailing slash is added when the configuration is shipped, * since `https://host/npm` and `https://host/npm/` compose differently. */ url: string; auth?: UpstreamAuth; } /** * Routes packages matching `pattern` to one or more upstreams. The runner * tries the listed upstreams in order and uses the first one that serves * the package; a 404 or an unreachable upstream moves on to the next. * * Fallthrough is deliberately confined to the rule's own upstream list: * when every listed upstream misses, the install fails rather than * falling through to a later, broader rule. Falling back to a broader * rule would silently send private package names to whatever upstream * that rule names — the dependency-confusion attack in one move. To allow * a fallback registry for a scope, list it in the scope's own rule. */ /** * Equivalent of TypeScript 5.4's `NoInfer` intrinsic, spelled as a * deferred conditional so the published declarations do not force * consumer projects onto TypeScript 5.4+. */ type NoInferCompat = [T][T extends unknown ? 0 : never]; export interface PackageRoutingRule { /** * A package name pattern with the same wildcard syntax as * `bundle.packages.embed`: a single `*` never crosses the `/` scope * separator, a `**` does, and a `**` directly before a `/` may together * with it match nothing, so `'**' + '/utils'` matches both `utils` and * `@acme/utils`. Exclusion (`!`) patterns are not supported here — each * rule stands alone, so there is nothing for an exclusion to subtract * from. */ pattern: string; /** * Names of upstreams to try in order; each must be a key of * {@link Registries.upstreams}. */ upstreams: NoInferCompat[]; } /** * Registry routing configuration for Checkly runners * (`runner.registries` in `checkly.config.ts`). Rules apply first-match- * wins, top-down: specific rules first, and the last rule must be the * `'**'` match-all fallback — a rule placed after it could never match. */ export interface Registries { upstreams: Record; packages: PackageRoutingRule[]; } /** * The literal pattern the final routing rule must have so that all * packages have a route. Only this exact spelling is recognized: an * equivalent wildcard pattern (`'***'`, or a broad pattern that happens * to match everything) neither satisfies the requirement nor triggers * the dead-rule check for rules placed after it. */ export declare const MATCH_ALL_PATTERN = "**"; /** * Walks a registries value, reporting every issue through `onIssue` so * that all of them surface in a single run — the config loader turns each * one into its own diagnostic. Messages name the offending part relative * to the registries block itself. Invalid URLs and tokens are * deliberately never echoed back — a malformed registry URL may carry an * inline credential. * * Structural problems gate their dependents: an `upstreams` block that is * not an object (or is empty) skips the per-rule upstream-existence * checks (they would all fail spuriously), and a rule whose pattern is * invalid skips the match-all checks for that rule. * * Plain-JS configs bypass the TypeScript type, so the shape must be * enforced at runtime, exactly as `validateBundle` does for * `bundle.packages`. */ export declare function collectRegistriesIssues(value: unknown, onIssue: (issue: Error) => void): void; /** * Validates the value of `runner.registries` and returns it typed, * throwing the first issue found. Invalid URLs and tokens are never * echoed back — a malformed registry URL may carry an inline credential. */ export declare function validateRegistries(value: unknown): Registries; /** * Serializes a validated configuration into the canonical contents of * {@link REGISTRIES_ARCHIVE_PATH}. Only known fields are written, and * upstream names are sorted so the output (and with it the dependency * cache hash) does not change when the config file merely reorders * entries. Rule order is semantic (first match wins) and is preserved * as-is. Upstream URLs are written in WHATWG-normalized form with a * trailing slash guaranteed, so runners can compose package paths onto * them by concatenation. Auth tokens are written unexpanded: the `${VAR}` * reference is resolved on the runner. */ export declare function serializeRegistries(registries: Registries): string; export {};