@struktoai/mirage-core
Version:
A Unified Virtual Filesystem For AI Agents
119 lines • 4.42 kB
JavaScript
// ========= 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