-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Summary
Version 4 focuses on full type-safety for $-based fluent shell execution and modularization of its fluent interface.
createShell() will now provide $ with output-mode-dependent handles while keeping result behavior unchanged.
The FluentPromise abstraction will be split into its own file (and prepared for future npm release).
Motivation
-
Simplify usage —
createShell()instantly returns a fluent interface without.asFluent(). -
Strengthen TypeScript inference:
live→ handle exposes only.result()capture/all→ fullPromiseLike<string>chain with.toLines(),.parse(),.safeParse().
-
Keep compatibility with existing
ExecutionResultdesign (stdout/stderrremainnullinlive). -
Decouple the fluent interface into an independent reusable module (
FluentPromise).
Key Changes
-
createShell()- Returns a
Shellinstance with a$property (fluent executor) by default. .run()/.safeRun()remain functional but are marked@deprecated.
- Returns a
-
DollarFunction(Fluent entrypoint)-
Tagged template and function-call overloads return mode-specific handle types.
-
Example:
const $ = createShell({ outputMode: 'live' }).$; const r = await $`npm run dev`.result(); // OK await $`npm run dev`; // ❌ TS error
-
-
Type System Enhancements
-
Conditional
HandleForMode<M>:type HandleForMode<M extends OutputMode> = CaptureForMode<M> extends true ? (BaseHandle<M> & FluentPromise) : BaseHandle<M>;
-
Keeps original
ExecutionResult,StrictResult, andSafeResultuntouched.
-
-
FluentPromiseExtraction-
New file:
src/fluent/FluentPromise.ts -
Defines the reusable fluent helper surface:
export type FluentPromise = PromiseLike<string> & { toLines(): Promise<string[]>; parse<T extends StandardSchemaV1>(schema: T): Promise<InferOutput<T>>; safeParse<T extends StandardSchemaV1>(schema: T): Promise<ValidationResult<InferOutput<T>>>; };
-
Shell imports this for its fluent handles.
-
Future npm target:
@thaitype/fluent-promise
-
-
Runtime Behavior (unchanged)
liveusesinheritI/O; returnsnulloutputs.capture/allbuffer as before.safeRun()and.result()never throw.
File Structure
src/
fluent/
FluentPromise.ts
index.ts
shell/
Shell.ts
standard-schema.ts
index.ts
Examples
const shell = createShell({ outputMode: 'capture' });
const $ = shell.$;
// capture / all modes
const msg = await $`echo hello`; // "hello"
const cfg = await $('cat package.json', { outputMode: 'all' }).parse(ConfigSchema);
// live mode
const liveShell = createShell({ outputMode: 'live' });
const $live = liveShell.$;
const res = await $live`npm run dev`.result(); // OK, no toLines()Migration Notes
- Existing
.run()/.safeRun()continue working but show@deprecatedhint. - No runtime changes: scripts using
capture/allremain identical. FluentPromisecan be imported directly for independent reuse.
Future Plans
- Publish
@thaitype/fluent-promisepackage. - Add optional stream hooks (
tap()) or stdin piping utilities. - Evaluate typed pipeline chaining for non-shell async tasks.