import type { SessionView } from '../../ops/types.ts'; import { type Policies } from '../../policy/index.ts'; import { type ShellArray } from '../../shell/array.ts'; import type { ElementOps } from '../../shell/types.ts'; import type { ShellValue } from '../../shell/variable.ts'; import { VarAttr } from '../../shell/variable.ts'; import type { Session } from './session.ts'; /** * The one copy-out of a session's environment. * * Every tier that hands the env onward as a process view (command * opts, `inv.env`, guest `RunArgs.env`, the `env` builtin) copies * through here, so the hidden-vars filter lands on all of them by * construction rather than on however many hand-rolled copies someone * remembers. The copy keeps the null prototype session records carry. * * *Exported* names only, which is what makes this the process view * rather than a second spelling of `visibleEnv`. bash puts a variable * in a child's environment when it carries the export attribute, not * when it happens to hold a string: `X=hello` is absent from `env` and * `export Y=world` is present. An unset name carrying the attribute * (`export Z`) is absent too, which falls out of the value check * rather than needing its own arm. */ export declare function envSnapshot(session: Session): Record; /** * The names carrying the export attribute, sorted, hidden removed. * * Wider than `envSnapshot`'s keys by exactly the unset ones: a name * `export Z` marked but never assigned is listed by `export -p` as * `declare -x Z` while staying out of the environment. So the printers * read this and the process view reads `envSnapshot`, rather than one * of them re-deriving the other's filter. */ export declare function exportedNames(session: Session): string[]; /** * The name a `declare -n` reference points at, null otherwise. Null * also for a reference declared but not yet aimed (`declare -n r` * before `r=v`): bash treats the first assignment as naming the target, * so until then it stands for nothing. */ export declare function namerefTarget(session: Session, name: string): string | null; /** * The variable a name stands for, following `declare -n` chains. A name * that is not a reference is its own answer. A chain that comes back to * itself (`declare -n a=b; declare -n b=a`) is bash's circular name * reference, read as unset: it resolves to the empty name, which no * record has, so a reader sees unset and a writer falls back to the * reference's own record. The warning line is the one part not * reproduced. */ export declare function deref(session: Session, name: string): string; /** The variable's value, null when unset or hidden. Sync on purpose: * `$X` expansion is the hot path, so a read stays a record lookup plus * the hidden check. A name reference reads its target. */ export declare function envGet(session: Session, name: string): string | null; /** * The env mapping a reader tier should resolve names against. * * Always a filtered copy, never `session.env`: that getter is itself a * projection built fresh per access, so handing it out would copy the * store anyway and freeze the answer at that moment. TS diverges from * python's lazy mapping view deliberately: expansion sites read records * with plain property access, so a copy is the shape they already * consume, and env sizes make the copy cost noise. * * The *shell* view, and no longer a synonym for `envSnapshot`: this is * what `$X`, arithmetic, `[[ ]]`, `IFS` and the bare `set` listing * resolve against, and they see every variable, exported or not. The * two were the same function while the process view was also "every * string", and reusing it once the process view narrowed would have * stopped `$X` resolving a plain assignment. python kept them separate * all along (`_VisibleEnv` beside `env_snapshot`); this is TS catching * up to it. */ export declare function visibleEnv(session: Session): Record; /** * The arrays mapping a reader tier should resolve names against. * * The arrays twin of `visibleEnv`: the embedder can seed * `session.arrays` before narrowing, so a hidden name can hold an * array and array reads need the same filter env reads get. */ export declare function visibleArrays(session: Session): Record; /** * The associative arrays a reader tier should resolve names against. * * The third sibling beside `visibleEnv` and `visibleArrays`, for the * same reason both exist: the embedder can seed a hidden name with any * value shape, so every reader tier filters the same way. */ export declare function visibleAssocs(session: Session): Record>; /** * Write one variable through the session plane's gate. * * General over variable shapes: a string stores a scalar, a ShellArray * stores a whole array, and the two storages stay exclusive. Semantics * live here once — the hidden refusal, readonly refusal, the * `preSession` policy gate (whose context value renders an array as * its present elements joined by spaces), then the store — so every * writer states them the same way whichever tier or spelling asked. * Writers with richer mechanics (subscripts, appends, holes) compute * the resulting value on a copy and hand it here, so a denial never * leaves a half-applied write. Null policies gate nothing (a writer * outside a workspace). Throws PolicyDenied when the name is hidden * for this session (a landed write would clobber the real value the * host's wiring still reads; a swallowed one would gaslight the * writer — the vars twin of EACCES on a create into hidden path * space), ReadonlyVariableError when the name is readonly, and * PolicyDenied when a preSession policy refuses the write. */ /** * Refuse a write that names a hidden variable. * * The sync half of `setVar`'s hidden gate, shared with the * expansion-time writers that land on the raw env (`${X:=d}`, * `$((X=5))`, `printf -v`): a landed write would clobber the real * value the host's wiring still reads, and a swallowed one would * gaslight the writer; refuse loudly instead, the vars twin of EACCES * on a create into hidden path space. */ /** * Remove one surrounding quote pair from an associative subscript. * * An arithmetic reference carries its subscript verbatim, so `m["x"]` * arrives with the quotes bash would have removed; one layer comes off * and anything else is the key itself. */ export declare function stripKeyQuotes(text: string): string; /** * Resolve an indexed subscript in arithmetic context. * * bash evaluates indexed subscripts as arithmetic (`a[i+1]`); an * unresolvable expression indexes element 0, mirroring bash's * unset-name-is-zero arithmetic rule. */ export declare function elementIndex(subscript: string, env: Readonly>, elements?: ElementOps | null): number; /** Element callbacks bound to one session, for `evaluateArith`. */ export declare function sessionElements(session: Session): ElementOps; export declare function ensureVarVisible(session: Session, name: string): void; /** * The session plane's view: five facts bound to one session. * * The one constructor every tier uses — builtins, the command * dispatcher, a bare unit test — so the gate cannot be skipped by * picking a different door. The view is the whole capability: it * carries no handle back to the raw session. */ /** * Write a variable without consulting the gate. * * For seeding a session before it is handed out -- the embedder * populating an environment, a test arranging state. `visibleArrays` * already names this case ("the embedder can seed session.arrays before * narrowing"). Anything reached from a command line goes through * `SessionView.set` instead, which is the whole point of the store being * read-only from outside. */ export declare function seedVar(session: Session, name: string, value: ShellValue): void; /** * Turn one attribute on or off, creating the name if needed. * * bash's `readonly NAME` / `export NAME` on a name that does not exist * yet marks it anyway, and the name stays *unset*: GNU prints * `declare -r ONLY` with no value and `${ONLY-d}` still expands to `d`. * So the record is created with no value, not with an empty string. * * A null attribute changes no attribute and only ensures the name * exists, which is what a bare `local L` / `declare D` does: GNU answers * `declare -- L` and `${L-d}` still expands to `d`, so those two cannot * route through a value writer either. */ export declare function setAttr(session: Session, name: string, attr: VarAttr | null, on?: boolean): void; export declare function sessionView(session: Session, policies?: Policies | null): SessionView; //# sourceMappingURL=state.d.ts.map