import type { Accessor } from '../../../accessor/base.ts';
import type { IndexCacheStore } from '../../../cache/index/store.ts';
import type { StatOverlay } from '../../../ops/types.ts';
import type { FindOptions } from '../../../resource/base.ts';
import { PathSpec, type CopyFn, type FindFn, type FileStat, type MoveFn, type ReadBytesFn, type ReadStreamFn, type ReaddirFn, type StatFn } from '../../../types.ts';
import type { ChildMounts } from '../../../ops/types.ts';
import type { DuEntries } from '../generic/du.ts';
import type { AggregateFn, CommandFnResult, CommandOpts, ProvisionFn } from '../../config.ts';
export type ReaddirOp = ReaddirFn<[
accessor: A,
path: PathSpec,
index?: IndexCacheStore
]>;
type ReadBytesOp = ReadBytesFn<[
accessor: A,
path: PathSpec,
index?: IndexCacheStore
]>;
type ReadStreamOp = ReadStreamFn<[
accessor: A,
path: PathSpec,
index?: IndexCacheStore
]>;
export type StatOp = StatFn<[
accessor: A,
path: PathSpec,
index?: IndexCacheStore
]>;
type WriteOp = (accessor: A, path: PathSpec, data: Uint8Array) => Promise;
type ExistsOp = (accessor: A, path: PathSpec) => Promise;
type PathOp = (accessor: A, path: PathSpec) => Promise;
type RmdirOp = (accessor: A, path: PathSpec, index?: IndexCacheStore) => Promise;
type MkdirOp = (accessor: A, path: PathSpec, parents?: boolean) => Promise;
type RenameOp = MoveFn<[accessor: A, src: PathSpec, dst: PathSpec]>;
type CopyOp = CopyFn<[accessor: A, src: PathSpec, dst: PathSpec]>;
type FindOp = FindFn<[
accessor: A,
path: PathSpec,
options: FindOptions
]>;
type DuSizeOp = (accessor: A, path: PathSpec, index?: IndexCacheStore) => Promise;
type DuEntriesOp = (accessor: A, path: PathSpec, index?: IndexCacheStore) => Promise;
export type ResolveGlobOp = (accessor: A, paths: readonly PathSpec[], index?: IndexCacheStore) => Promise;
export declare function makeResolveGlob(readdir: ReaddirOp, maxGlobMatches?: number, children?: ChildMounts): ResolveGlobOp;
export interface DuOps {
size: DuSizeOp;
entries: DuEntriesOp;
}
export interface CommandIO {
readdir: ReaddirOp;
readBytes: ReadBytesOp;
readRange?: (accessor: A, path: PathSpec, index: IndexCacheStore | undefined, offset: number, size: number | null) => Promise;
readStream: ReadStreamOp;
stat: StatOp;
isMounted: (accessor: A) => boolean;
local?: boolean;
maxGlobMatches?: number;
write?: WriteOp;
exists?: ExistsOp;
mkdir?: MkdirOp;
unlink?: PathOp;
rmdir?: RmdirOp;
rmR?: PathOp;
rename?: RenameOp;
copy?: CopyOp;
dirCopy?: CopyOp;
create?: PathOp;
truncate?: (accessor: A, path: PathSpec, length: number) => Promise;
find?: FindOp;
du?: DuOps;
maxDuEntries?: number;
append?: (accessor: A, path: PathSpec, data: Uint8Array) => Promise;
setAttrs?: (...args: any[]) => unknown;
globChildren?: ChildMounts;
}
export declare function resolveGlobOf(ops: CommandIO): ResolveGlobOp;
/** Refuse a relocation that would surface a hidden path.
*
* A rename or a native directory copy re-anchors everything below its
* source, and a hide's coverage does not move with the content, so
* hidden bytes would land at paths the session can see. EACCES on the
* source, which mv and cp render in GNU's permission-denied voice.
* Only a directory has anything below it to re-anchor, so callers
* check this for a source they know is a directory and skip it for a
* file. */
export declare function refuseReveal(src: PathSpec, dst: PathSpec): void;
/**
* Return `ops` whose slots refuse hidden paths like missing ones.
*
* The commands factory hands this copy to every generic command, the
* same shape as `withReadCache`, so hidden-path enforcement lands once
* for the whole command tier (resolveGlobOf derives from the wrapped
* readdir). The backends' own IO constants stay raw: the ops tables
* built from them serve the dispatcher, which enforces hiding itself
* at the door. The guards read the current session at call time, so
* one wrapped copy is shared across sessions.
*/
export declare function withHiddenGuard(ops: CommandIO): CommandIO;
/**
* Return `ops` whose content and mutation slots ask the admitted
* command's gate before touching a path.
*
* The rule arms' counterpart of `withHiddenGuard`, wrapped inside it so
* a hidden path still answers ENOENT before any rule can name it. The
* gate judged the line's operands; this is how a walk (`grep -r`, `find`,
* `du`, `cp -r`, `tar`) is held to the same rules on the entries it
* reaches below them. `stat` and `exists` stay unguarded, because deny
* means present and refused, not absent: a listing shows a refused
* entry's name and size, and the read of it is what fails, as GNU reports
* an unreadable file. `readdir` asks about the directory being listed,
* never filters its names. A backend's native `find`/`du` are not
* wrapped: the builders route to the readdir walk while a path rule
* scopes the command (`pathRulesActive`), so every entry passes through
* here.
*/
export declare function withRuleGuard(ops: CommandIO): CommandIO;
/**
* Return `ops` whose mutation slots hold each written path to its
* region's effective mode.
*
* The per-path half of the mount's write gate, innermost of the three
* guards: hides answer ENOENT first, rules refuse next, and only a path
* both leave standing is judged for its mode, the same order the op
* door applies. Reads are never wrapped, because `READ` allows them
* everywhere the other guards do; a copy's source is a read too, so
* only its destination answers, while a rename mutates both endpoints.
*/
export declare function withModeGuard(ops: CommandIO): CommandIO;
/**
* Return `ops` under the whole path axis: hides answer ENOENT first,
* rules refuse next, the mode speaks last.
*
* The one spelling of the guard chain, used by the commands factory
* for every generic command and by a bespoke command family that
* consumes a `CommandIO` directly (the object-store overrides), so an
* override enforces the session's path axis exactly like the generic
* it replaces.
*/
export declare function withPathGuards(ops: CommandIO): CommandIO;
/**
* Return `ops` whose content and mutation slots admit each PathSpec
* through the workspace's coded preOps hooks.
*
* The coded-policy arm of the guard chain, applied outside the cache
* wraps so admission fires before a warm serve, the dispatcher's own
* order. The surface is the rule guard's plus readdir: content reads
* (readBytes, readStream, readRange), every mutation slot, and the
* directory a readdir lists. stat/exists and the native find/du slots
* stay unguarded as presence facts, the mode-000 shape the rule guard
* already states, so a denied entry still lists and stats while the
* read of it is what fails. Inert unless a dispatched command bound
* policies overriding preOps (`opPolicyScope`, with the mount prefix
* and session identity captured at wrap time so a lazily drained
* reader still answers as the command that bound it, see
* `livePolicyScope`; `prefix` arrives from the wrap site because the
* fallback mount-gate storage resolves by path, which a drained
* reader no longer has a live gate for).
*/
export declare function withPolicyGuard(ops: CommandIO, prefix?: string): CommandIO;
/**
* Guard one bare backend write the way the adapter guards a slot.
*
* For a bespoke command wired from loose functions rather than a
* `CommandIO` (the google `rm` family binds an index-threaded unlink):
* the same chain in the same order, judging the written path. A hidden
* path answers ENOENT, the flavor of the flat mutation slots. The
* policy arm rides outermost, as it does on the slot chain, and reads
* the live context (this wrap happens at registration, its handlers
* are eager).
*/
export declare function withWriteGuards(fn: (accessor: A, path: PathSpec, index?: IndexCacheStore) => Promise | R): (accessor: A, path: PathSpec, index?: IndexCacheStore) => Promise;
/**
* A `readRange` slot built from a backend read that already takes a byte
* window as its options argument.
*
* Without the slot the ops factory reads the whole object and slices, so
* `head -c 100` on a 2 GiB S3 key downloads 2 GiB. Python has pushed the
* window down on every one of these backends since the slot existed by
* pointing `read_range` at its own `read_bytes`; this is the same move,
* spelled for a read whose window arrives in an options object.
*
* Args:
* read: the backend's whole-file read, whose fourth argument is an
* `{offset?, size?}` window.
*/
export declare function rangeOf(read: (accessor: A, path: PathSpec, index: IndexCacheStore | undefined, options: {
offset?: number;
size?: number;
}) => Promise): NonNullable['readRange']>;
export declare function dirAwareStat(ops: CommandIO, accessor: A, opts: CommandOpts): (p: PathSpec) => Promise;
export declare function overlaidStat(stat: (p: PathSpec) => Promise, overlay: StatOverlay | undefined): (p: PathSpec) => Promise;
export declare function requireOp(op: T | undefined, name: string): T;
/**
* Return `ops` whose reads refuse a directory with GNU's EISDIR.
*
* The read family's counterpart of `withHiddenGuard` and
* `withSlashGuard`: reading a directory is never a legitimate call, so
* the refusal belongs to the slot rather than to each builder's wiring.
* It used to belong to the wiring, and 23 of the read builders passed the
* raw `ops.readStream` instead, so a directory on a keyed backend
* reported ENOENT.
*
* Refined after the failure, never before it, so a read that succeeds
* costs exactly what it did. The refusal is built from the operand's own
* PathSpec, so it carries the virtual path: a raw disk error names the
* host path, which is the mount's own business and must not reach a
* user-facing line.
*
* Mirrors the Python `with_dir_guard`.
*/
export declare function withDirGuard(ops: CommandIO): CommandIO;
export declare function dirAwareStream(ops: CommandIO, accessor: A, opts: CommandOpts): (p: PathSpec) => AsyncIterable;
export type BuilderFn = (ops: CommandIO, accessor: A, paths: PathSpec[], texts: string[], opts: CommandOpts) => Promise | CommandFnResult;
export type Operation = 'write' | 'exists' | 'mkdir' | 'unlink' | 'rmdir' | 'rename' | 'copy' | 'truncate';
export declare function supports(ops: CommandIO, requirements: readonly Operation[]): boolean;
export interface Builder {
name: string;
fn: BuilderFn;
provision?: (stat: StatOp) => ProvisionFn;
write?: boolean;
aggregate?: AggregateFn;
read?: boolean;
/**
* Backend ops the command cannot run without. A backend missing any of
* them does not get the command registered at all, rather than getting a
* command that throws on every invocation. `write: true` is not enough on
* its own: rmdir needs `rmdir`, truncate needs `truncate`, and a backend
* can have `write` without either.
*/
requirements?: readonly Operation[];
}
export {};
//# sourceMappingURL=adapter.d.ts.map