@struktoai/mirage-core
Version:
A Unified Virtual Filesystem For AI Agents
308 lines • 18.1 kB
TypeScript
import type { RedirectResult } from '../../../../context/session_context.ts';
import type { ParseScope } from '../../../../shell/parse/scope.ts';
import { type ShellValue, type ShellVar, VarAttr, VarKind } from '../../../../shell/variable.ts';
import type { SessionView } from '../../../../view/types.ts';
import { type SessionState } from '../../../session/session.ts';
import type { AttrMarks, DeclarationOperand } from './types.ts';
/**
* Put a declaration's value-shaping marks on a name before its value
* stores. The session view coerces on write by reading the record's attributes, so
* for the declaration's *own* value to coerce (`declare -i n=3+4` stores
* `7`), the attribute has to be there first; a `+` letter comes off first
* too, so `declare -i N=5; declare +i N+=x` stores `5x`. Gated like every
* other mark, and a no-op with nothing to shape. `followRef` is the write's:
* a `-n` declaration shapes the reference itself.
*/
export declare function premark(view: SessionView, name: string, shaping: AttrMarks, followRef?: boolean): Promise<void>;
/**
* The array kind a declaration's `-a` / `-A` asks for, `-A` winning when both
* are given (bash's `export -aA B=(1)` builds a map), or null for neither.
*/
export declare function declaredKind(flags: ReadonlySet<string>): VarKind | null;
/**
* The value a declaration's `NAME=...` lands on: the variable a `declare -n`
* reference names.
*/
export declare function heldValue(session: SessionState, name: string): ShellValue | null;
/**
* The attributes a new local takes from the variable it shadows: the export
* mark alone (`local I=2+3` over `declare -i I` stores `2+3`), or with `-I`
* every one but a reference, as bash's `local -I` keeps `-i` and drops `-n`.
*/
export declare function localAttrs(v: ShellVar | undefined, inherit: boolean): Set<VarAttr>;
/**
* Reset a name the running function just shadowed to what a new local starts
* as: unset, with the attributes `localAttrs` keeps, or under `-I` the
* shadowed value too, so `local -I A=new` over `A=(old keep)` writes element
* 0 of `(old keep)`. This is the scope's own bookkeeping, not a session
* write: the caller's record is the frame's to put back on return, so no
* policy is asked to delete it. The local's value lands later through the
* gated session view, which judges that write.
*/
export declare function startLocal(session: SessionState, name: string, inherit: boolean): void;
/**
* bash's refusal when a declared array kind meets a value of the other
* kind, or null when they agree.
*/
export declare function kindConflict(held: ShellValue | null, kind: VarKind | null): string | null;
/**
* What a declaration's `NAME=value` stores, and the elements it assigns
* (`coerceValue`). An array keeps its kind and takes the value at element 0
* (key `"0"` in a map), as a plain `NAME=value` does, leaving the other
* elements as stored; otherwise `-A` makes the map `([0]=value)` and `-a`
* the one-element array, a held scalar converting to that element first,
* and with neither the value stays a scalar. A `NAME+=value` arrives here
* as `appended` hands it.
*/
export declare function scalarValue(held: ShellValue | null, value: string, kind: VarKind | null): [ShellValue, ReadonlySet<number | string> | null];
/**
* Whether a listing's `-a` / `-A` keep `name`: `-a` lists only indexed
* arrays, `-A` only associative ones, both nothing.
*/
export declare function kindListed(session: SessionState, name: string, flags: ReadonlySet<string>): boolean;
/**
* Put `attr` on the variable a write to `name` landed on. The write's gate
* covered `checked`, the target before it, so the mark rides on that
* decision; a write that re-aimed an unset `declare -n` reference
* (`declare -n r; export r=X`) landed on a target no gate has seen, so that
* mark goes through the gated session view, as does the reference mark itself
* (`+n`), which belongs to the reference's own record. `followRef` is false
* when the write was a `declare -n` declaration's, on the reference itself.
*/
export declare function markWritten(session: SessionState, view: SessionView, name: string, checked: string, attr: VarAttr, on?: boolean, followRef?: boolean): Promise<void>;
/**
* Put a declaration's attribute marks on what one operand landed on, as
* soon as it lands: `declare -r R=1 R=2` refuses the second write, and
* under `-g` the global record takes them. A written operand's marks ride
* on its write's gate (`markWritten`); a bare one (`checked` null) wrote
* nothing, so each mark goes through the gated session view.
*/
export declare function stampMarks(session: SessionState, view: SessionView, name: string, checked: string | null, marks: AttrMarks, followRef?: boolean): Promise<void>;
/**
* Take the mark off an unaimed `declare -n` reference a declared array kind
* is about to land on, silently, as bash's `export -a ref=v` does (an
* undeclared array warns at the session view).
*/
export declare function dropReference(session: SessionState, view: SessionView, name: string): Promise<void>;
/**
* A name's own record, undefined when unset or hidden: a hidden name reads
* as unset, so no refusal can quote or describe its value.
*/
export declare function visibleRecord(session: SessionState, name: string): ShellVar | undefined;
/**
* The line a `+letter` earns on one operand, if any. Two letters cannot be
* taken off: `+r` on a readonly name is `declare: R: readonly variable` and
* the name stays frozen, as is `+n` on a frozen reference; `+a` / `+A` on an array is `cannot destroy array
* variables in this way`, since the kind is what the value is, not a mark.
* Either skips that operand's value and marks, and the others still declare
* (pinned on 5.2.37).
*/
export declare function plusRefusal(cmd: string, session: SessionState, view: SessionView, name: string, plus: string): string | null;
/**
* Store a declaration's array literals through the session view, the first
* of bash's two passes over a declaration.
*
* bash stores every literal before it runs any other operand, then goes
* through all of them in order, assigning the plain values and marking each
* name, a literal's included, at its own place: so `declare -r R=1 R=(2)`
* stores `(2)`, writes 1 over element 0 and freezes `R`, and a fatal literal
* leaves every other operand undone (pinned on 5.2.37). Only the
* value-shaping attributes go on before a literal stores (`shaping`); the
* caller's second pass puts the rest on the literals `stored` reports, by
* position, against the variable each write's gate cleared, so an operand
* that re-aims a reference in between cannot carry a mark past the gate.
*
* The builtin owns the store; readonly is the shell's rule, checked per name
* before the session view, and the session view's gate covers the policy half. Names are
* processed in order, so an earlier operand stays stored when a later one
* refuses, as bash does. A readonly refusal or kind conflict of an array
* literal is a variable-assignment error in GNU, not a builtin failure: for
* `export`/`readonly` (and `declare` at top level) `fatal` abandons the rest
* of the line, while `local` and a function-scoped `declare` refuse in the
* builtin's voice into `errors` and the body keeps running (pinned on bash
* 5.2, debian:stable-slim); under `-g` a readonly name refuses fatally even
* inside a function, a kind conflict does not. Returns the refusal result,
* or null.
*
* Inside a function `declare` and `local` make each name local, starting as
* `startLocal` leaves it (with `-I`, the value it shadows); `export` and
* `readonly` (`VISIBLE_SCOPE_BUILTINS`) and `-g` write the visible one.
*
* `kind` is the kind `-a` / `-A` declared: `-A` builds every literal as an
* associative map, and without it a name that already holds one still
* builds a map, since a plain `m+=([k]=v)` keeps the variable's own kind.
* `warnings` is filled with the `must use subscript` lines for the plain
* words a keyed associative literal cannot take; GNU stores the valid
* elements and the status stays 0.
*/
export declare function storeStagedArrays(cmd: string, session: SessionState, view: SessionView, operands: readonly DeclarationOperand[], errors: string[], warnings: string[], fatal?: boolean, stored?: Map<number, string> | null, kind?: VarKind | null, shaping?: AttrMarks, globalScope?: boolean, inherit?: boolean): Promise<RedirectResult | null>;
/**
* Quote a value the way bash `declare -p` / `export -p` does.
*
* A value holding any control character takes the `$'...'` form, with the
* named escapes bash uses (`\a \b \t \n \v \f \r`, and `\E` for escape) and
* three-digit octal for the rest; `"`, `$` and backtick need no escaping
* there because `$'...'` does not expand. Everything else is double-quoted
* with escapes for `\`, `"`, `$` and backtick. Non-ASCII printable text
* stays literal, which is what bash emits in a UTF-8 locale.
*/
export declare function bashDeclareQuote(value: string): string;
export declare function splitDeclFlags(args: readonly DeclarationOperand[], allowed: Set<string>): {
flags: Set<string>;
names: DeclarationOperand[];
bad: string | null;
};
/**
* The `=(...)` tail of an associative `declare` line.
*
* Sorted keys (mirage's pinned order, where GNU prints hash order) and
* GNU's trailing space before the closing paren, which an empty map
* does not carry: `m=([a]="1" )` but `m=()`.
*/
export declare function assocBody(amap: Readonly<Record<string, string>>): string;
/**
* A declaration operand as its name, whether it appends, and its value, null
* for a bare name: `X+=y` appends `y` to `X`.
*/
export declare function operandParts(word: string): [string, boolean, string | null];
/**
* GNU's `not a valid identifier` line for one declaration operand.
*
* A declaration builtin refuses a name it cannot declare rather than
* storing it: `export 1BAD=x` used to land a variable that `$1BAD` can
* never name back (bash reads that as `$1` then `BAD`) and then shipped
* it to every child environment.
*
* Which text GNU quotes depends on why the word failed, and both
* spellings are pinned. A word that is not a valid assignment at all is
* echoed whole (``export: `1BAD=x'``); a word whose target parses but is
* not a plain name -- an array element -- is echoed as just that target
* (``export: `arr[0]'``), since the value it would have taken is not
* what is wrong with it.
*/
export declare function identifierRefusal(cmd: string, word: string): string | null;
/**
* A declaration's answer once every operand ran: each warning, then each
* refusal, one line apiece, and exit 1 when an operand refused; an empty
* refusal fails without a word, as bash's do for a reference given `-i`. The good
* operands on the same line are already stored: GNU reports each and keeps
* going, so `export GOOD=1 1BAD=x GOOD2=2` exports both good names. A
* warning alone (`must use subscript`) leaves the status 0.
*/
export declare function declarationResult(cmd: string, errors: readonly string[], warnings?: readonly string[], failed?: boolean): RedirectResult;
/**
* The `declare -p` line for one name, or null when it has none.
*
* The attribute cluster is `attrLetters`, which is why this renders
* `declare -rx` and `declare -ar` without a table of its own: the record
* already knows its own letters and their print order. bash spells an
* empty cluster `--`, and that spelling is the caller's because only a
* `declare` line needs it.
*
* A hidden name answers null, the same way `isReadonly` answers false for
* one: reporting it as declared would leak it.
*/
export declare function declareLine(session: SessionState, name: string): string | null;
/**
* Whether a no-name `declare` listing's letters keep `name`: `-a` / `-A`
* narrow it to that array kind (`kindListed`), and any of `-i -l -n -r -t
* -u -x` keeps a name carrying one of them.
*/
export declare function declarationListed(session: SessionState, name: string, flags: ReadonlySet<string>): boolean;
/**
* Run `declare -p`: render declarations for names, or for all; with no
* names the declaration's letters narrow the list (`declarationListed`).
*/
export declare function handleDeclarePrint(names: string[], session: SessionState, flags?: ReadonlySet<string>): RedirectResult;
/**
* The letters `declare` prints a function with: `f`, then `r` when
* `readonly -f` froze it and `x` when `export -f` marked it.
*/
export declare function functionFlags(session: SessionState, name: string): string;
/**
* Print functions as `declare` lists them. A body prints as bash renders it
* (`storedFunctionText`), followed with `marks` by a `declare -fx NAME` line
* when the function has an attribute; without bodies each function is its
* `declare` line, or its bare name.
*/
export declare function functionLines(session: SessionState, names: readonly string[], bodies: boolean, marks: boolean, parser?: ParseScope): string[];
/**
* Run the function half of `declare`: `-f` / `-F`.
*
* `-p` only prints, whatever attributes come with it: `-F NAME` the
* attribute line, `-f NAME` the body and, for a function with an attribute,
* that line (`functionLines`); a missing name is `not found`, exit 1.
* Without `-p`, `-r` freezes the named functions as `readonly -f` does, `-x`
* marks them for export and `+x` takes the mark off, printing nothing; a `+`
* letter wins over its `-` twin, and `+r` refuses a frozen function, which
* then keeps every attribute (`readonly function`, exit 1); with no
* attribute `-F NAME` prints the name and `-f NAME` the body, and a missing
* name is exit 1 with no message. With no names every function
* lists as `-p` prints it; `-r` or `-x` narrows the list to the functions
* holding either attribute, and a `+` attribute does not.
*/
export declare function handleDeclareFunctions(cmd: string, session: SessionState, flags: ReadonlySet<string>, names: readonly string[], plus: ReadonlySet<string>, parser?: ParseScope): RedirectResult;
/**
* Run `export` or `readonly`: mark names, or print them. An invalid option
* letter fails with status 2 and the GNU usage line. `-f` marks functions
* instead (`markFunctions`). With no names, every name carrying the
* keyword's mark prints as `declare -p` prints it, the whole cluster
* (`declare -rx R="1"`), a reference as itself rather than its target; `-a`
* / `-A` narrow the listing to that array kind (`kindListed`). Otherwise
* each operand is assigned and marked through the gated view
* (`markVariables`); `-a` / `-A` shape only an assigned value, and
* `export -n` takes the mark off.
*/
export declare function markNames(assignments: readonly DeclarationOperand[], session: SessionState, state: SessionView | null, attr: VarAttr, parser?: ParseScope): Promise<RedirectResult>;
/**
* Run `readonly -f` or `export -f`: mark functions, or list them. A name
* that is not a function is `not a function`, exit 1, and the other operands
* are still marked (or, with `on` false, unmarked), in the order typed. An
* array literal (`export -f ARR=(a b)`) still stores first, with no
* attribute and its `must use subscript` warnings, and its name is then
* checked at its place, as bash assigns every literal before it looks for
* the functions. With no names the marked functions print as bodies, each
* followed by its `declare` line.
*/
export declare function markFunctions(cmd: string, session: SessionState, marked: Set<string>, operands: readonly DeclarationOperand[], on: boolean, state?: SessionView | null, parser?: ParseScope, kind?: VarKind | null): Promise<RedirectResult>;
/**
* Run `export` or `readonly` over its operands: assign each value and put
* the keyword's mark on, or with `on` false take it off (`export -n`).
* bash's two passes (`storeStagedArrays`): every array literal stores first,
* then each operand in order is assigned and marked, a literal's name at its
* own place. So `readonly R=1 R=2 X=3` keeps 1, refuses the second write and
* still sets `X`, and `readonly A=(1) A=(2)` keeps `(2)` while a later `A=3`
* refuses.
*
* Under `set -x` each assignment is traced as it is made, among the refusals
* and under the command's redirects (`+ r=2` then `r: readonly variable`); a
* bad name or option traces nothing, and with `-a` / `-A` bash assigns as
* `declare` does, untraced.
*/
export declare function markVariables(cmd: string, session: SessionState, view: SessionView, operands: readonly DeclarationOperand[], attr: VarAttr, on: boolean, kind: VarKind | null): Promise<RedirectResult>;
/**
* Record the caller's array before a function shadows `name`.
*
* `local -a` / `declare -a` inside a function shadow the caller's array,
* so the old value (or its absence) has to be remembered for the teardown
* in `executeCommand`. Returns true when a function scope is active, so
* the caller should shadow rather than reuse whatever is already there.
*/
export declare function noteLocalArray(session: SessionState, name: string): boolean;
/**
* The line `declare -n NAME=TARGET` earns when TARGET is unusable: bash
* refuses a target that is not a variable name, a self reference, and
* (mirage-only) a target spelled as an array element, since the resolver
* maps names to names.
*/
export declare function namerefRefusal(cmd: string, name: string, target: string): string | null;
/**
* The line the name a `declare -n` operand lands on earns, ahead of its
* readonly mark (pinned on 5.2.37). An array cannot become a reference
* (`reference variable cannot be an array`). A given value was judged on
* its own (`namerefRefusal`); a bare `declare -n NAME` aims the name at the
* value it already holds, so that value has to name a variable, though here
* it may name NAME itself.
*/
export declare function referenceRefusal(cmd: string, name: string, own: ShellVar | undefined, bare: boolean): string | null;
//# sourceMappingURL=declare.d.ts.map