export declare const DEFAULT_REGISTRY_URL = "https://registry.npmjs.org/"; /** * A configuration file to merge, and how hard to insist on reading it. * `optional` files are skipped with a log line when they exist but cannot * be read, for files the user did not choose to put there themselves. */ export interface NpmrcFile { path: string; optional?: boolean; } /** The prefix that marks an environment variable as npm configuration. */ export declare const NPM_CONFIG_ENV_PREFIX = "npm_config_"; /** * Where a config value came from. Structured rather than a display string: * an environment variable is named by its verbatim spelling, which is what * the user can actually search for — the key stored in the config map has * the prefix stripped and may be case-folded. */ export type ConfigOrigin = { kind: 'file'; path: string; } | { kind: 'env'; variable: string; }; export interface LoadedNpmrcConfig { config: NpmrcConfig; /** The config files consulted, highest precedence first. */ files: string[]; /** * Optional files that could not be read, and were therefore skipped. Any * credentials they hold went unused, which is worth saying out loud when * a download later fails to authenticate. */ unreadable: string[]; /** * Which source each key came from. A credential that a registry rejects * is far easier to fix when the error can name where it came from, which * the merged map alone cannot say. */ origins: Map; } /** * Merged `.npmrc` configuration: a flat key → raw value map. Values keep * any `${VAR}` references unexpanded until they're actually used, so an * unset environment variable in an unrelated line never breaks anything. */ export type NpmrcConfig = Map; export declare class NpmrcEnvVarError extends Error { constructor(key: string, varName: string); } /** * Parses a single `.npmrc` file's content. Only the simple `key=value` * subset of npm's ini format is supported (comments with `#`/`;`, * whitespace trimming); ini sections do not occur in npm configs. */ export declare function parseNpmrc(content: string): NpmrcConfig; /** * Extracts npm configuration from `npm_config_*` environment variables * (e.g. `npm_config_registry`, commonly set in CI and by package managers * running lifecycle scripts). In npm's precedence order these sit above * every `.npmrc` file. The key is stored both verbatim and lowercased, * because plain keys are written in any case (`NPM_CONFIG_REGISTRY`) while * nerf-darted auth keys carry a case-sensitive spelling * (`npm_config_//host/:_authToken`). */ export declare function npmrcConfigFromEnv(env: NodeJS.ProcessEnv): NpmrcConfig; /** * Loads and merges npm configuration in precedence order: `npm_config_*` * environment variables first, then `.npmrc` files with entries from * earlier paths winning over later ones (pass project first, then user). * Missing files are skipped. */ export declare function loadNpmrcConfig(files: NpmrcFile[], env?: NodeJS.ProcessEnv): Promise; /** * The file pnpm keeps its global registry credentials in. pnpm 11 stopped * writing them to `.npmrc`: `pnpm login` writes `auth.ini` in pnpm's global * config directory instead, so a logged-in pnpm user looks unauthenticated * to anything that only reads `.npmrc`. * * The directory resolution mirrors pnpm's own `getConfigDir` branch for * branch. Note that `PNPM_HOME` is deliberately NOT consulted: pnpm uses it * for the data and state directories, never for the config directory. */ export declare function pnpmAuthIniPath(env: NodeJS.ProcessEnv, platform: NodeJS.Platform, homedir: string): string; export interface NpmrcPathsOptions { /** Workspace root, whose `.npmrc` is consulted. */ workspaceRoot: string; /** * The directory the Checkly project lives in (a workspace member in a * monorepo), whose `.npmrc` takes precedence over the workspace root's. */ contextDir?: string; homedir?: string; /** pnpm's global `auth.ini`. Consulted whenever it is provided. */ pnpmAuthFile?: string; /** * True when the project's lockfile is pnpm's, which is when `auth.ini` * outranks the user `.npmrc` — matching pnpm's own precedence. For any * other package manager it ranks below. * * Note that precedence applies per key, as it does in npm and pnpm, not * per registry: a lower-ranked file's `_authToken` still wins over a * higher-ranked file's `username`/`_password` for the same registry, * because the credential kinds are distinct keys and `resolveAuthHeader` * prefers a token over basic auth. npm's own config cascade behaves the * same way, and a scope-qualified key beats an unscoped one for the same * registry for the same reason. */ pnpmAuthFilePreferred?: boolean; } /** * The configuration files relevant to a project, highest precedence first: * the directory the Checkly project lives in (the nearest project config, * which may be a workspace member), the workspace root, then pnpm's global * `auth.ini` and the user-level `.npmrc` in whichever order the project's * package manager implies. (npm's global and builtin configs are not * consulted.) */ export declare function defaultNpmrcPaths(options: NpmrcPathsOptions): NpmrcFile[]; /** * The registry a package resolves to, or the reason nothing can be * requested from it. * * A configured value is never quietly replaced by a default — resolving a * private package against the public registry would disclose its name — so * a broken one has to be reported rather than substituted. That is a * discriminated result rather than an unusable URL string because the * caller composes a path onto `url` and requests it: with * `registry=https://` the composed URL parses with the PACKAGE NAME as its * host, and the request, along with any credential nerf-darted to it, goes * to whoever owns that name. A rule that can send a token somewhere * unintended belongs in the type rather than in a comment a future caller * may not read. * * `key` names the entry to blame, absent only when nothing configured a * registry and the public npm one was assumed — which is always usable. */ export type ResolvedRegistry = UsableRegistry | { usable: false; key: string; }; /** A registry a request can actually be composed for and sent to. */ export interface UsableRegistry { usable: true; url: string; key?: string; } /** * Resolves the registry for a package name: the `@scope:registry` entry if * the package is scoped and one exists, the `registry` entry otherwise, * falling back to the public npm registry. */ export declare function resolveRegistry(config: NpmrcConfig, packageName: string, env?: NodeJS.ProcessEnv): ResolvedRegistry; export interface ResolvedAuth { /** The `Authorization` header value to send. */ header: string; /** * Every config key that contributed, in the spelling that matched. * Paired with `LoadedNpmrcConfig`'s `origins`, these name the file or * environment variable a rejected credential came from — indispensable * once several sources can supply one. `username` + `_password` yields * two keys rather than one: because precedence is * per key, the halves routinely come from different files, and the * password (the half that actually expires) is the one worth naming. */ keys: string[]; } /** * Resolves the `Authorization` header applicable to a URL, matching npm's * "nerf dart" scheme: credentials are keyed by the registry URL minus its * protocol (`//host/path/:_authToken=...`). Every dart is probed in both * slash-spellings, canonical first at each depth — `dartSpellings` says * why both are honored. npm's walk agrees at every depth above the * request's own; at that deepest depth npm probes only the URL's literal * spelling, a difference observable only with a key at exactly the * request's full path — not a key anything writes. * * `pnpm login --scope=@acme` writes a scope-qualified key instead * (`//host/:@acme:_authToken=...`, or equivalently `//host/@acme/:_authToken`), * so the package being downloaded decides which keys apply. Mirroring pnpm, * every scoped key is tried before any unscoped one — a shallow scoped * credential outranks a deeper unscoped one, rather than the two being * interleaved by depth. An unscoped package never falls back to a scoped * key: a scoped token belongs to one organisation by construction, and * reusing it elsewhere would send that organisation's credential somewhere * it was never meant to go. * * Scope-qualified keys are honored for every project, not only pnpm ones: * npm, yarn, bun and pnpm 10 ignore the spelling entirely, but writing one * is an unambiguous statement of which token that scope should use, and * refusing to read it would leave a user whose only login is * `pnpm login --scope` unauthenticated for exactly the packages the key * names. * * Returns undefined when no credentials match. */ export declare function resolveAuthHeader(config: NpmrcConfig, url: string, packageName: string, env?: NodeJS.ProcessEnv): ResolvedAuth | undefined;