UNPKG

@struktoai/mirage-core

Version:

A Unified Virtual Filesystem For AI Agents

119 lines • 4.42 kB
// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. ========= // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ========= Copyright 2026 @ Strukto.AI All Rights Reserved. ========= import { stdinStat, stdinStream } from "../utils/stream.js"; import { IOResult } from "../../../io/types.js"; import { OutputStream } from "../../../io/stream.js"; import { closeStream, openStream, openStreamSync } from "../../../rs/stream.js"; import { StreamRefusal } from "../../../rs/errors.js"; import { refused } from "../../../rs/scan.js"; import { byteView } from "../../../shell/bytes.js"; import { resolveSource, streamOutput } from "../utils/stream.js"; import { operandsIo, reportedStream, splitReadable } from "../utils/operands.js"; import { FlagView } from "../../spec/flag_view.js"; import {} from "../../spec/types.js"; import { specOf } from "../../spec/builtins.js"; const ENC = new TextEncoder(); export const OPTIONS = [ 'bytes', 'characters', 'fields', 'F', 'delimiter', 'no_partial', 'complement', 'only_delimited', 'args_O', 'output_delimiter', 'w', 'whitespace_delimited', 'zero_terminated', ]; /** * cut's engine config, refused by the engine before any operand is resolved: * every option as typed, in typed order, a switch as the empty text. A * `--whitespace-delimited` without `=` goes as null, since * `--whitespace-delimited=` reads as a prefix of `trimmed`. Mirrors Python's * `cut_config`. */ export function cutConfig(bag) { const fl = new FlagView(bag, specOf('cut')); const options = fl .occurrences(...OPTIONS) .filter(([, value]) => value !== false) .map(([name, value]) => [ name, value !== true ? byteView(String(value)) : name === 'whitespace_delimited' ? null : '', ]); const config = { options }; try { openStreamSync('cut', config).close(); } catch (error) { if (!(error instanceof StreamRefusal)) throw error; return refused(error); } return config; } /** Run cut over resolved operands with `cutConfig`'s config, read before the * operands were. Mirrors Python's `cut_generic`. */ export async function cutGeneric(config, paths, ctx, stream, stat) { stream = stdinStream(stream, ctx.stdin); const engine = await openStream('cut', config); if (paths.length > 0) { let inspected; try { inspected = await splitReadable(paths, stdinStat(stat), 'cut'); } catch (error) { engine.close(); throw error; } const [ok, err] = inspected; const io = operandsIo(err); if (ok.length === 0 && err !== '') { engine.close(); return [null, io]; } async function* outputs() { try { for (const [index, operand] of ok.entries()) { const current = index === 0 ? engine : await openStream('cut', config); try { yield* reportedStream(streamOutput(current, stream(operand), ctx.signal), io, operand, 'cut'); } finally { await closeStream(current); } } } finally { await closeStream(engine); } } const out = new OutputStream(outputs()[Symbol.asyncIterator](), () => closeStream(engine)); return [out, io]; } let source; try { source = resolveSource(ctx.stdin); } catch (error) { engine.close(); const message = error instanceof Error ? error.message : String(error); return [null, new IOResult({ exitCode: 1, stderr: ENC.encode(`${message}\n`) })]; } return [streamOutput(engine, source, ctx.signal), new IOResult()]; } //# sourceMappingURL=cut.js.map