import type { Writable } from 'node:stream'; import { type EmitResult, type Signer } from './archive.ts'; import { type VerificationResult, type VerifyOptions, type ArchiveSource, type ManifestFields } from './manifest.ts'; /** What a build wrote, and what it signed. */ export interface BuildResult extends EmitResult { /** Where the archive was written, or null when it went to a stream. */ output: string | null; /** Member names in the finished archive, excluding `AUTHORITY.PEM`. */ members: string[]; /** Size of the written file in bytes, when it went to a path. */ size?: number | undefined; } /** Where a build's bytes go: a path, a caller's stream, or stdout. */ interface Destination { /** Where to write the archive. */ output?: string | undefined; /** An open stream to write to instead. The caller closes it. */ stream?: Writable | undefined; } export interface CreateOptions extends Destination { /** Base directory the file list is relative to (default: '.'). */ base?: string | undefined; /** Member names, relative to `base`. */ files: string[]; /** * A launcher or binary to put in front of the archive, making the result * self-running. This decides the archive's shape for good: signing keeps * it, and an audit reviews it with everything else. */ prefix?: string | undefined; hashAlg?: string | undefined; signAlg?: string | undefined; /** Sign as it is built. Both must be given together. */ key?: Buffer | string | undefined; chain?: string | undefined; /** A two-phase signer, instead of `key`/`chain`. */ signer?: Signer | undefined; /** * One time for every member, instead of each file's own: what a rebuild * dates its files, so it makes the same archive. `parseDate()` reads one * from an ISO 8601 string. */ date?: Temporal.Instant | undefined; } export interface SignOptions extends Destination { /** Path to the archive to sign. Its prefix, if it has one, is kept as it is. */ source: string; /** Make the output executable; implied when the archive has a prefix. */ executable?: boolean | undefined; hashAlg?: string | undefined; signAlg?: string | undefined; key?: Buffer | string | undefined; chain?: string | undefined; signer?: Signer | undefined; } export interface VerifyBundleOptions extends VerifyOptions { /** * Extra trusted roots, as PEM text or as paths to PEM files — the * convenience form of `extraRoots`, which takes PEM text only. */ roots?: string[] | undefined; } export interface RunOptions { /** Extra trusted roots, as PEM text or paths to PEM files. */ roots?: string[] | undefined; identity?: string | undefined; issuer?: string | undefined; /** Require attestations from these attesters, as `[kind@]did`. */ attesters?: string[] | undefined; /** How many of `attesters` must have attested (default: all of them). */ quorum?: number | undefined; /** Milliseconds a cached attestation proof stays good for. */ maxAge?: number | undefined; /** Refuse an archive any of these DIDs has marked bad. */ block?: string[] | undefined; /** Run an archive whose signature is good but whose chain is unanchored. */ allowUntrusted?: boolean | undefined; /** Arguments handed to the application inside the archive. */ args?: string[] | undefined; } /** What an archive says about itself, with no trust decision attached. */ export interface Inspection { /** Member names, excluding `AUTHORITY.PEM`. */ members: string[]; /** Whether the archive carries a signature marker at all. */ signed: boolean; /** The whole-file hash the marker records, hex. */ hash?: string | undefined; /** Names of the unsigned attributes carried beside the signature. */ fields: string[]; /** The manifest's declared algorithms and certificate chain. */ manifest?: ManifestFields | undefined; } /** * Build an archive from a base directory and a list of files, optionally * signing it and optionally prepending a launcher or binary. */ export declare function createBundle(options: CreateOptions): Promise; /** * Sign an existing archive: its members are read out, laid down again behind * the archive's own prefix, and the finished bytes are hashed and signed as a * whole. `output` may be the archive itself — signing in place — since the * result replaces it only once it is complete. The prefix — the shape * of the result — is decided when the archive is created, so the archive an * audit reviewed is the one that is signed. */ export declare function signBundle(options: SignOptions): Promise; /** * Where signing `source` writes by default: the same name without its * `.unsigned` — `app.unsigned.nzip` becomes `app.nzip`, an executable * `app.unsigned` becomes `app`, `app.unsigned.exe` becomes `app.exe` — and, * for a name that does not say it is unsigned, the archive itself, signed in * place. Every bundle is an `.nzip`, signed or not; the `.unsigned` is only a * convention for keeping the two apart while both are around. */ export declare function signedName(source: string): string; /** * Put an existing archive behind a different prefix, unsigned — a node binary * with the verifier in it, for an executable. Its result is a new archive to * review and then sign; any signature the source had does not carry over. */ export declare function prefixBundle(options: Destination & { source: string; prefix: string; hashAlg?: string | undefined; }): Promise; /** A signer backed by a private key and certificate chain read from disk. */ export declare function fileSigner({ key, chain, signAlg }: { key: string; chain: string; signAlg?: string | undefined; }): Signer; /** * Verify an archive: recompute the whole-file hash, check the signature over it * against the leaf certificate, check every member's own digest, and decide * whether the certificate chain means anything to us. */ export declare function verifyBundle(source: ArchiveSource, options?: VerifyBundleOptions): Promise; /** The synchronous form, for callers on a path that cannot await — a mount. */ export declare function verifyBundleSync(source: ArchiveSource, options?: VerifyBundleOptions): VerificationResult; /** * What an archive claims about itself — its members, whether it is signed at * all, and what its manifest declares. This is the cheap "what am I looking at" * call; `verifyBundle` is the expensive one that answers whether any of it is * true, and nothing here should be believed until it has run. */ export declare function inspectBundle(source: string): Inspection; /** * Check a signed archive, mount it through the verifying provider, and run what * is inside — in this process. The mount is the enforcement: the provider * verifies before it hands back a filesystem, and every member is re-hashed * against its signed digest as it is read, for as long as the process lives. * * This used to re-exec node with `-r --vfs-load `, which * gave the application a process of its own and cost more than it was worth: * a preload has to be a real file, and it is not when this package is itself * running out of an archive — which is how the published CLI runs. Mounting * here needs no preload, because the provider is registered in the process * doing the mounting. * * What is given up is isolation: the application shares this process, and this * package's modules are loaded in it. Anyone who wants a child can have one — * `mountArgv()` names the node arguments for it. */ export declare function runBundle(archive: string, options?: RunOptions): Promise; /** * The node arguments that mount `archive` as the filesystem and run the program * inside it, with this package's verifying provider preloaded. Anything after * these is the application's own argv — the trailing `--` is what makes that * true, since without it node claims any argument that looks like one of its * own flags and the application never sees it. */ export declare function mountArgv(archive: string): string[]; /** * The absolute path of the preload that registers the verifying provider, as a * real path `node -r` can resolve. */ export declare function registerPath(): string; export {}; //# sourceMappingURL=api.d.ts.map