import * as internal from "./internal.js"; /** Something an expression can depend on, such as a step or a job. */ export type ExpressionSource = { readonly id: string; }; /** Values that can appear in ternary `.then()` / `.else()` branches. */ export type TernaryValue = string | number | boolean | ExpressionValue; /** Values that can be compared against: a literal or another expression. */ export type Operand = string | number | boolean | ExpressionValue; /** * An expression that resolves to a value inside a GitHub Actions workflow. * Supports fluent comparison methods that produce Conditions. */ export declare class ExpressionValue { #private; constructor(expression: string, source?: ExpressionSource | ReadonlySet); /** all expression sources referenced by this value */ get [internal.allSources](): ReadonlySet; /** raw expression text without `${{ }}` wrapping */ get expression(): string; /** `this == value`, simplified when this value is a known literal */ equals(value: Operand): Condition; /** `this != value`, simplified when this value is a known literal */ notEquals(value: Operand): Condition; /** `startsWith(this, prefix)` */ startsWith(prefix: string | ExpressionValue): Condition; /** `endsWith(this, suffix)` */ endsWith(suffix: string | ExpressionValue): Condition; /** `contains(this, substring)` */ contains(substring: string | ExpressionValue): Condition; /** `!(this)`, treating this value as a boolean */ not(): Condition; /** concatenate this value with additional strings, numbers, or expressions */ concat(...parts: ConcatPart[]): ExpressionValue; /** `this > value` */ greaterThan(value: number | ExpressionValue): Condition; /** `this >= value` */ greaterThanOrEqual(value: number | ExpressionValue): Condition; /** `this < value` */ lessThan(value: number | ExpressionValue): Condition; /** `this <= value` */ lessThanOrEqual(value: number | ExpressionValue): Condition; /** wrap this value in GitHub's `toJSON()` function */ toJSON(): ExpressionValue; /** wrap in `${{ }}` for use in YAML */ toString(): string; } /** * A boolean condition used in `if` fields. Supports fluent `.and()`, `.or()`, * `.not()` composition. Tracks all ExpressionSources referenced so that * dependencies can be inferred automatically. */ export declare abstract class Condition { readonly sources: ReadonlySet; constructor(sources: ReadonlySet); /** `this && other`, simplifying always-true/always-false operands */ and(other: Condition | boolean): Condition; /** `this || other`, simplifying always-true/always-false operands */ or(other: Condition | boolean): Condition; /** `!this`, simplifying where the negation can be expressed directly */ not(): Condition; /** * Starts a ternary expression: `condition && trueValue || falseValue`. * * ```ts * const runner = os.equals("linux").then("ubuntu-latest").else("macos-latest"); * // => matrix.os == 'linux' && 'ubuntu-latest' || 'macos-latest' * ``` * * Throws when the value is a falsy literal, which the encoding can't * represent. */ then(value: TernaryValue): ThenBuilder; /** * Returns the flat AND terms of this condition. Used by condition * simplification to detect absorption (A || A && B → A). */ [internal.getAndTerms](): string[]; /** returns the flat AND children of this condition as Condition objects */ [internal.flattenAnd](): Condition[]; /** returns the flat OR children of this condition as Condition objects */ [internal.flattenOr](): Condition[]; /** * Gets if this condition is statically known to be true, such as * `conditions.isTrue()` or a comparison of two equal literals. Steps and * jobs with such a condition serialize without an `if`. */ isAlwaysTrue(): boolean; /** * Gets if this condition is statically known to be false. Steps with such a * condition are dropped from the generated job entirely. */ isAlwaysFalse(): boolean; /** * Gets if this condition could evaluate to true at runtime, meaning it is * not statically known to be false. Handy for deciding in a script whether a * conditional step will be emitted at all. */ isPossiblyTrue(): boolean; /** * Returns a condition that renders identically but additionally tracks the * given sources. Simplification uses this when it drops a duplicate term * whose sources the surviving term doesn't already have. */ abstract [internal.withSources](sources: ReadonlySet): Condition; /** render without `${{ }}` wrapping */ abstract toExpression(): string; /** render wrapped in `${{ }}` for YAML `if` fields */ toString(): string; } /** comparison operators supported in GitHub Actions expressions */ export type ComparisonOp = "==" | "!=" | ">" | ">=" | "<" | "<="; /** `left op right` where op is ==, !=, >, >=, <, or <= */ export declare class ComparisonCondition extends Condition { #private; constructor(left: string, op: ComparisonOp, right: Operand, sources: ReadonlySet); not(): Condition; [internal.withSources](sources: ReadonlySet): ComparisonCondition; toExpression(): string; } /** `fn(arg1, arg2, ...)` */ export declare class FunctionCallCondition extends Condition { #private; constructor(fn: string, args: string[], sources: ReadonlySet); [internal.withSources](sources: ReadonlySet): FunctionCallCondition; toExpression(): string; } /** wraps a raw expression string as a Condition */ export declare class RawCondition extends Condition { #private; constructor(expression: string, sources: ReadonlySet); isAlwaysTrue(): boolean; isAlwaysFalse(): boolean; not(): Condition; [internal.withSources](sources: ReadonlySet): RawCondition; toExpression(): string; } /** Creates an ExpressionValue from a raw expression string. */ export declare function expr(expression: string): ExpressionValue; /** Common condition helpers for GitHub Actions workflows. */ export declare const conditions: { /** A condition that is always true. Simplifies away in `.and()` / `.or()`. */ readonly isTrue: () => Condition; /** A condition that is always false. Simplifies away in `.and()` / `.or()`. */ readonly isFalse: () => Condition; /** Status check functions for use in step/job `if` fields. */ readonly status: { /** Run regardless of previous step outcome. */ readonly always: () => Condition; /** Run only when all previous steps succeeded (default behavior). */ readonly success: () => Condition; /** Run only when a previous step has failed. */ readonly failure: () => Condition; /** Run only when the workflow was cancelled. */ readonly cancelled: () => Condition; }; /** * Check if the ref is a tag. Without arguments, matches any tag. * With a tag name, matches that specific tag. * * ```ts * conditions.isTag() // startsWith(github.ref, 'refs/tags/') * conditions.isTag("v1.0.0") // github.ref == 'refs/tags/v1.0.0' * ``` */ readonly isTag: (tag?: string) => Condition; /** * Check if the ref is a specific branch. * * ```ts * conditions.isBranch("main") // github.ref == 'refs/heads/main' * ``` */ readonly isBranch: (branch: string) => Condition; /** * Check the event that triggered the workflow. * * ```ts * conditions.isEvent("pull_request") // github.event_name == 'pull_request' * ``` */ readonly isEvent: (event: string) => Condition; /** * Check if the event is a pull request. * * ```ts * conditions.isPr() // github.event_name == 'pull_request' * ``` */ readonly isPr: () => Condition; /** * Check the repository (owner/name). * * ```ts * conditions.isRepository("denoland/deno") // github.repository == 'denoland/deno' * ``` */ readonly isRepository: (repo: string) => Condition; /** * Check if the pull request is a draft. * * ```ts * conditions.isDraftPr() // github.event.pull_request.draft == true * ``` */ readonly isDraftPr: () => Condition; /** * Check if the pull request has a specific label. * * ```ts * conditions.hasLabel("ci-full") // contains(github.event.pull_request.labels.*.name, 'ci-full') * ``` */ readonly hasPrLabel: (label: string) => Condition; /** * Check the runner operating system. * * ```ts * conditions.isRunnerOs("Linux") // runner.os == 'Linux' * conditions.isRunnerOs("macOS") // runner.os == 'macOS' * conditions.isRunnerOs("Windows") // runner.os == 'Windows' * ``` */ readonly isRunnerOs: (os: "Linux" | "macOS" | "Windows") => Condition; /** * Check the runner architecture. * * ```ts * conditions.isRunnerArch("X86") // runner.arch == 'X86' * conditions.isRunnerArch("X64") // runner.arch == 'X64' * conditions.isRunnerArch("ARM") // runner.arch == 'ARM' * conditions.isRunnerArch("ARM64") // runner.arch == 'ARM64' * ``` */ readonly isRunnerArch: (arch: "X86" | "X64" | "ARM" | "ARM64") => Condition; }; /** Checks if a condition-like value always evaluates to true. */ export declare function isAlwaysTrue(c: Condition | ExpressionValue | string): boolean; /** Checks if a condition-like value always evaluates to false. */ export declare function isAlwaysFalse(c: Condition | ExpressionValue | string): boolean; /** * Renders a value as a GitHub Actions literal. Strings are single quoted with * any embedded single quotes doubled, which is how they are escaped. */ export declare function formatLiteral(value: string | number | boolean): string; /** Collects the sources of any number of expression values or conditions. */ export declare function sourcesFrom(...values: (ExpressionValue | Condition)[]): ReadonlySet; /** * Intermediate builder after `.then(value)`. Call `.else()` to produce the * final `ExpressionValue`, or `.elseIf()` to add another branch. */ export declare class ThenBuilder { #private; constructor(branches: TernaryBranch[], sources: ReadonlySet); /** Add another conditional branch. */ elseIf(condition: Condition): ElseIfBuilder; /** * Finalize the ternary with a default value. * * ```ts * os.equals("linux").then("ubuntu-latest").else("macos-latest") * // => matrix.os == 'linux' && 'ubuntu-latest' || 'macos-latest' * ``` */ else(value: TernaryValue): ExpressionValue; } /** * Intermediate builder after `.elseIf(condition)`. Call `.then()` to provide * the value for this branch. */ export declare class ElseIfBuilder { #private; constructor(branches: TernaryBranch[], sources: ReadonlySet, condition: Condition); /** * Provide the value for this branch. Throws when the value is a falsy * literal, which the encoding can't represent. */ then(value: TernaryValue): ThenBuilder; } interface TernaryBranch { condition: Condition; value: TernaryValue; } /** a part of a concatenation: plain string, number, or expression */ export type ConcatPart = string | number | ExpressionValue; /** * Concatenates strings, numbers, and expressions into a single value. * Expression parts are wrapped in `${{ }}` when serialized for YAML, * and use the `format()` function when used inside expression contexts. * * ```ts * const name = concat("build-", expr("matrix.os")); * name.toString() // => "build-${{ matrix.os }}" * name.expression // => "format('build-{0}', matrix.os)" * * const full = concat("build-", expr("matrix.os"), "-", expr("matrix.arch")); * full.toString() // => "build-${{ matrix.os }}-${{ matrix.arch }}" * ``` */ export declare function concat(...parts: ConcatPart[]): ExpressionValue; /** * Parses a JSON string into an object/value. Wraps in `fromJSON()` in GitHub * Actions expression contexts. * * ```ts * const matrix = fromJSON(expr("needs.setup.outputs.matrix")); * matrix.toString() // => "${{ fromJSON(needs.setup.outputs.matrix) }}" * ``` */ export declare function fromJSON(value: string | ExpressionValue): ExpressionValue; /** * Serializes a value to JSON. Wraps in `toJSON()` in GitHub Actions expression * contexts. * * ```ts * const json = toJSON(expr("github.event")); * json.toString() // => "${{ toJSON(github.event) }}" * ``` */ export declare function toJSON(value: ExpressionValue): ExpressionValue; /** Computes a hash of files matching the given glob patterns. */ export declare function hashFiles(...patterns: (string | ExpressionValue)[]): ExpressionValue; /** * Joins an array expression with an optional separator. Wraps in `join()` in * GitHub Actions expression contexts. * * ```ts * const labels = join(expr("github.event.pull_request.labels.*.name"), ", "); * labels.toString() // => "${{ join(github.event.pull_request.labels.*.name, ', ') }}" * ``` */ export declare function join(value: ExpressionValue, separator?: string): ExpressionValue; /** Creates an ExpressionValue or Condition from a literal value. */ export declare function literal(value: boolean): Condition; export declare function literal(value: string | number): ExpressionValue; /** Maps a property type to Condition (for booleans/conditions) or ExpressionValue (for values). */ export type ExprOf = [T] extends [boolean | Condition] ? Condition : ExpressionValue; /** Maps all properties of an object to their expression/condition form. */ export type ExprMap> = { readonly [K in keyof T & string]: ExprOf; }; /** * Converts an object with plain values into an object with typed * Condition/ExpressionValue properties. Booleans become Conditions, * strings/numbers become ExpressionValues that serialize inline. */ export declare function defineExprObj>(obj: T): ExprMap; export {}; //# sourceMappingURL=expression.d.ts.map