/** * @license * Copyright 2026 Steven Roussey * SPDX-License-Identifier: Apache-2.0 */ import type { IExecuteContext, TaskEntitlements } from "@workglow/task-graph"; import { CreateWorkflow } from "@workglow/task-graph"; import type { DataPortSchema } from "@workglow/util/schema"; import type { FileSedTaskConfig, FileSedTaskInput, FileSedTaskOutput, SedLineSubstituter, SedOptions } from "./FileSedTask"; import { FileSedTask as BaseFileSedTask } from "./FileSedTask"; export type { FileSedTaskConfig, FileSedTaskInput, FileSedTaskOutput }; /** * Server-only task for substituting text in files on the filesystem, on top of * the base task's http(s) handling. * * The file is streamed line-by-line rather than loaded into memory, and split * into lines with a hard per-line cap ({@link DEFAULT_LIMITS.grepMaxLineChars}) * — a longer physical line is truncated to that length and the remainder * discarded, so a file with no line terminator cannot exhaust memory. The file * on disk is never modified — there is no in-place (`sed -i`) mode. * * A local path is resolved and realpath'd before it is opened, and constrained * to `config.roots` — which defaults to the process working directory, so a * task with no stated root reads from there and nowhere else. Set * `config.allowAnyRoot` to opt out. Reading requires the `filesystem:read` * entitlement. * * Only available in Node.js and Bun environments. For cross-platform * substitution (including browser), use FileSedTask with an http(s) URL. */ export declare class FileSedTask extends BaseFileSedTask { static configSchema(): DataPortSchema; static entitlements(): TaskEntitlements; /** * Declares whichever half of the surface this url actually uses: the fetch * entitlements for http(s), otherwise `filesystem:read` scoped to the * resolved real path. An unknown url fails closed to both, unscoped. * * Never throws — entitlement evaluation runs before `execute()` and must * produce a declaration for any input, so an unresolvable path degrades to * the unscoped declaration and is refused later, at open time. */ entitlements(): TaskEntitlements; /** * Refuses a path the instance did not declare. Entitlements are evaluated * on the unresolved input, so without this a declare-then-swap would let the * open authorize itself — and a standalone `fileSed(...)` with no graph and * no enforcer would honour no `roots` at all. */ private assertResolvedPathDeclared; /** * Runs the substitution inside a `vm` context under a wall-clock budget, so * a catastrophically backtracking pattern fails instead of wedging the event * loop. Overriding here covers both branches: the http branch reaches * `super.execute`, which uses the substituter this returns. * * `fixedString` never enters `vm` — an escaped literal cannot backtrack, and * the `vm` hop would cost ~4x for nothing. */ protected createSubstituter(pattern: string, replacement: string, options: SedOptions): SedLineSubstituter; execute(input: FileSedTaskInput, context: IExecuteContext): Promise; } export declare const fileSed: (input: FileSedTaskInput, config?: FileSedTaskConfig) => Promise<{ linesChanged: number; replacementCount: number; text: string; truncated: boolean; }>; declare module "@workglow/task-graph" { interface Workflow { fileSed: CreateWorkflow; } }