diff --git a/.dagger/modules/packager/dagger.json b/.dagger/modules/packager/dagger.json new file mode 100644 index 0000000..5f38e6a --- /dev/null +++ b/.dagger/modules/packager/dagger.json @@ -0,0 +1,14 @@ +{ + "name": "packager", + "engineVersion": "v1.0.0-0", + "sdk": { + "source": "dang" + }, + "dependencies": [ + { + "name": "polyfill", + "source": "github.com/dagger/polyfill@main", + "pin": "16627066d1852106320bdc0cfa0e5f901efe5970" + } + ] +} diff --git a/.dagger/modules/packager/main.dang b/.dagger/modules/packager/main.dang new file mode 100644 index 0000000..e9d9123 --- /dev/null +++ b/.dagger/modules/packager/main.dang @@ -0,0 +1,59 @@ +""" +Builds the TypeScript SDK library artifacts this repo ships. + +The SDK module reads them straight off its own source at generate time, so +whatever this produces has to be committed. Everything lands under `library/`, +laid out the way the library source expects it, and is refreshed by +`dagger generate`. +""" +type Packager { + """ + Workspace-relative directory holding the library. + """ + let libraryPath: String! = "library" + + """ + Directory holding the library's own generated bindings, relative to + libraryPath. Matches the layout of the library source they are compiled with, + where the runtime they import sits at ../common/context.js. + """ + let bindingsPath: String! = "src/api" + + """ + Regenerate the TypeScript library's own bindings (client.gen.ts) from the + running engine's schema. + + The schema comes from the session rather than from a module: a plain session + serves no modules, so introspecting it yields the core API alone — which is + exactly what a library binds. That one step is why this opens a nested + session; rendering the bindings from the resulting JSON does not. + """ + libraryBindings(ws: Workspace!): Changeset! @generate { + let bindings = codegen(ws) + .withExec(["codegen", "introspect", "--output", "/schema.json"], experimentalPrivilegedNesting: true) + .withExec(["codegen", "library", "--introspection-json-path", "/schema.json", "--output", "/out"]) + .directory("/out") + + polyfill.workspace(ws).fork + .withDirectory(libraryPath + "/" + bindingsPath, bindings) + .changes + } + + """ + Container with the codegen helper compiled and on PATH at + /usr/local/bin/codegen. Read from the workspace rather than this module's own + source: the helper lives at the repo root, outside the module directory. The + path is workspace-root-absolute, so generating from a subdirectory still + finds it. + """ + let codegen(ws: Workspace!): Container! { + container + .from("golang:1.25-alpine") + .withoutEntrypoint + .withMountedCache("/go/pkg/mod", cacheVolume("go-mod")) + .withMountedCache("/root/.cache/go-build", cacheVolume("go-build")) + .withDirectory("/helper", ws.directory("/helpers/codegen")) + .withWorkdir("/helper") + .withExec(["go", "build", "-o", "/usr/local/bin/codegen", "."]) + } +} diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..c18deac --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +/library/src/api/client.gen.ts linguist-generated diff --git a/dagger.toml b/dagger.toml index 09cbb79..e641702 100644 --- a/dagger.toml +++ b/dagger.toml @@ -9,6 +9,9 @@ [modules.e2e] source = ".dagger/modules/e2e" +[modules.packager] +source = ".dagger/modules/packager" + [modules.typescript-sdk] source = "." check.skip = ["*"] diff --git a/helpers/codegen/introspect.go b/helpers/codegen/introspect.go new file mode 100644 index 0000000..ed6bf6e --- /dev/null +++ b/helpers/codegen/introspect.go @@ -0,0 +1,89 @@ +package main + +import ( + "bytes" + "encoding/json" + "flag" + "fmt" + "net/http" + "os" + + "codegen/introspection" +) + +// Env vars the engine injects into a nested exec, pointing at the session's +// GraphQL endpoint (engine/client/client.go). +const ( + sessionPortEnv = "DAGGER_SESSION_PORT" + sessionTokenEnv = "DAGGER_SESSION_TOKEN" +) + +// runIntrospect dumps the session's introspection schema. +// +// This is the only subcommand that talks to the engine, and it does so over +// plain HTTP against the nested session rather than through the Go SDK: the +// generation subcommands stay dependency-free and never open a session of their +// own. The schema a plain session serves is core-only — no module is installed +// in it — which is exactly what library bindings are generated from. +func runIntrospect(args []string) error { + fs := flag.NewFlagSet("introspect", flag.ExitOnError) + output := fs.String("output", "", "path to write the introspection schema JSON to (default stdout)") + if err := fs.Parse(args); err != nil { + return err + } + + port, ok := os.LookupEnv(sessionPortEnv) + if !ok { + return fmt.Errorf("%s is not set: introspect must run in a nested exec (experimentalPrivilegedNesting)", sessionPortEnv) + } + + body, err := json.Marshal(map[string]string{ + "query": introspection.Query, + "operationName": "IntrospectionQuery", + }) + if err != nil { + return fmt.Errorf("marshal introspection query: %w", err) + } + + req, err := http.NewRequest(http.MethodPost, "http://127.0.0.1:"+port+"/query", bytes.NewReader(body)) + if err != nil { + return fmt.Errorf("build introspection request: %w", err) + } + req.Header.Set("Content-Type", "application/json") + req.SetBasicAuth(os.Getenv(sessionTokenEnv), "") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return fmt.Errorf("introspection query: %w", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("introspection query: unexpected status %s", resp.Status) + } + + // The generators consume the payload under "data" — the same shape as the + // introspection JSON the engine hands to codegen elsewhere. + var envelope struct { + Data json.RawMessage `json:"data"` + Errors []struct { + Message string `json:"message"` + } `json:"errors"` + } + if err := json.NewDecoder(resp.Body).Decode(&envelope); err != nil { + return fmt.Errorf("decode introspection response: %w", err) + } + if len(envelope.Errors) > 0 { + return fmt.Errorf("introspection query: %s", envelope.Errors[0].Message) + } + if len(envelope.Data) == 0 { + return fmt.Errorf("introspection query returned no data") + } + + if *output == "" { + _, err = os.Stdout.Write(envelope.Data) + return err + } + + return os.WriteFile(*output, envelope.Data, 0o644) +} diff --git a/helpers/codegen/main.go b/helpers/codegen/main.go index b88a8bf..377b877 100644 --- a/helpers/codegen/main.go +++ b/helpers/codegen/main.go @@ -7,9 +7,13 @@ // codegen client — a standalone client (dagger.gen.ts for the core types, plus // one .gen.ts per module in the bound module's // closure), importing @dagger.io/dagger. +// codegen library — the SDK library's own bindings, importing the runtime they +// ship alongside. // -// It is intentionally engine-free: the schema and the bound module's metadata -// are supplied as files, so no nested engine session is opened. +// Generation is engine-free: the schema and the bound module's metadata are +// supplied as files, so no session is opened. `codegen introspect` is the one +// exception — it dumps the session schema the library bindings are generated +// from, over plain HTTP, and only runs in this repo's own generate step. package main import ( @@ -64,11 +68,50 @@ func run(args []string) error { return runModule(args[1:]) case "client": return runClient(args[1:]) + case "library": + return runLibrary(args[1:]) + case "introspect": + return runIntrospect(args[1:]) default: - return fmt.Errorf("unknown command %q (want module or client)", args[0]) + return fmt.Errorf("unknown command %q (want module, client, library or introspect)", args[0]) } } +// runLibrary regenerates the SDK library's own bindings. They ship inside the +// library, so they reach the runtime by relative source path rather than +// through the bundle or the package name — the third import arm. The schema is +// the plain session schema (see `codegen introspect`): core only, unscrubbed. +func runLibrary(args []string) error { + fs := flag.NewFlagSet("library", flag.ExitOnError) + var ( + introspectionPath = fs.String("introspection-json-path", "", "path to the introspection schema JSON") + outputDir = fs.String("output", ".", "output directory for the generated bindings") + ) + if err := fs.Parse(args); err != nil { + return err + } + + schema, schemaVersion, err := loadSchema(*introspectionPath) + if err != nil { + return err + } + + cfg := generator.Config{OutputDir: *outputDir} + gen := &typescriptgenerator.TypeScriptGenerator{Config: cfg} + + ctx := context.Background() + state, err := gen.GenerateLibrary(ctx, schema, schemaVersion) + if err != nil { + return fmt.Errorf("generate library: %w", err) + } + + if err := generator.Overlay(ctx, state.Overlay, cfg.OutputDir); err != nil { + return fmt.Errorf("write generated library bindings: %w", err) + } + + return nil +} + func runModule(args []string) error { fs := flag.NewFlagSet("module", flag.ExitOnError) var ( diff --git a/library/src/api/client.gen.ts b/library/src/api/client.gen.ts new file mode 100644 index 0000000..7449b1f --- /dev/null +++ b/library/src/api/client.gen.ts @@ -0,0 +1,19512 @@ +/** + * This file was auto-generated by `client-gen`. + * Do not make direct changes to the file. + */ +import { Context, BaseClient } from "../common/context.js" + + + +/** + * Declare a number as float in the Dagger API. + */ +export type float = number + +// BaseClient is re-exported so consumers that previously did +// `import { BaseClient } from "./client.gen.js"` keep working. The class +// itself lives in the common SDK runtime (see ../common/context.ts) so that +// per-dependency generated files can extend it without the ESM cycle that +// arises once client.gen.ts `export *`s those dep files. +export { BaseClient } + +export type AddressDirectoryOpts = { + exclude?: string[] + include?: string[] + gitignore?: boolean + noCache?: boolean +} + +export type AddressFileOpts = { + exclude?: string[] + include?: string[] + gitignore?: boolean + noCache?: boolean +} + +export type BuildArg = { + /** + * The build argument name. + */ + name: string + + /** + * The build argument value. + */ + value: string +} + +/** + * Sharing mode of the cache volume. + */ +export enum CacheSharingMode { + + /** + * Shares the cache volume amongst many build pipelines, but will serialize the writes + */ + Locked = "LOCKED", + + /** + * Keeps a cache volume for a single build pipeline + */ + Private = "PRIVATE", + + /** + * Shares the cache volume amongst many build pipelines + */ + Shared = "SHARED", +} + +/** + * Utility function to convert a CacheSharingMode value to its name so + * it can be uses as argument to call a exposed function. + */ +export function CacheSharingModeValueToName(value: CacheSharingMode): string { + switch (value) { + case CacheSharingMode.Locked: + return "LOCKED" + case CacheSharingMode.Private: + return "PRIVATE" + case CacheSharingMode.Shared: + return "SHARED" + default: + return value + } +} + +/** + * Utility function to convert a CacheSharingMode name to its value so + * it can be properly used inside the module runtime. + */ +export function CacheSharingModeNameToValue(name: string): CacheSharingMode { + switch (name) { + case "LOCKED": + return CacheSharingMode.Locked + case "PRIVATE": + return CacheSharingMode.Private + case "SHARED": + return CacheSharingMode.Shared + default: + return name as CacheSharingMode + } +} +export type ChangesetWithChangesetOpts = { + /** + * What to do on a merge conflict + */ + onConflict?: ChangesetMergeConflict +} + +export type ChangesetWithChangesetsOpts = { + /** + * What to do on a merge conflict + */ + onConflict?: ChangesetsMergeConflict +} + +/** + * Strategy to use when merging changesets with conflicting changes. + */ +export enum ChangesetMergeConflict { + + /** + * Attempt the merge and fail if git merge fails due to conflicts + */ + Fail = "FAIL", + + /** + * Fail before attempting merge if file-level conflicts are detected + */ + FailEarly = "FAIL_EARLY", + + /** + * Let git create conflict markers in files. For modify/delete conflicts, keeps the modified version. Fails on binary conflicts. + */ + LeaveConflictMarkers = "LEAVE_CONFLICT_MARKERS", + + /** + * The conflict is resolved by applying the version of the calling changeset + */ + PreferOurs = "PREFER_OURS", + + /** + * The conflict is resolved by applying the version of the other changeset + */ + PreferTheirs = "PREFER_THEIRS", +} + +/** + * Utility function to convert a ChangesetMergeConflict value to its name so + * it can be uses as argument to call a exposed function. + */ +export function ChangesetMergeConflictValueToName(value: ChangesetMergeConflict): string { + switch (value) { + case ChangesetMergeConflict.Fail: + return "FAIL" + case ChangesetMergeConflict.FailEarly: + return "FAIL_EARLY" + case ChangesetMergeConflict.LeaveConflictMarkers: + return "LEAVE_CONFLICT_MARKERS" + case ChangesetMergeConflict.PreferOurs: + return "PREFER_OURS" + case ChangesetMergeConflict.PreferTheirs: + return "PREFER_THEIRS" + default: + return value + } +} + +/** + * Utility function to convert a ChangesetMergeConflict name to its value so + * it can be properly used inside the module runtime. + */ +export function ChangesetMergeConflictNameToValue(name: string): ChangesetMergeConflict { + switch (name) { + case "FAIL": + return ChangesetMergeConflict.Fail + case "FAIL_EARLY": + return ChangesetMergeConflict.FailEarly + case "LEAVE_CONFLICT_MARKERS": + return ChangesetMergeConflict.LeaveConflictMarkers + case "PREFER_OURS": + return ChangesetMergeConflict.PreferOurs + case "PREFER_THEIRS": + return ChangesetMergeConflict.PreferTheirs + default: + return name as ChangesetMergeConflict + } +} +/** + * Strategy to use when merging multiple changesets with git octopus merge. + */ +export enum ChangesetsMergeConflict { + + /** + * Attempt the octopus merge and fail if git merge fails due to conflicts + */ + Fail = "FAIL", + + /** + * Fail before attempting merge if file-level conflicts are detected between any changesets + */ + FailEarly = "FAIL_EARLY", +} + +/** + * Utility function to convert a ChangesetsMergeConflict value to its name so + * it can be uses as argument to call a exposed function. + */ +export function ChangesetsMergeConflictValueToName(value: ChangesetsMergeConflict): string { + switch (value) { + case ChangesetsMergeConflict.Fail: + return "FAIL" + case ChangesetsMergeConflict.FailEarly: + return "FAIL_EARLY" + default: + return value + } +} + +/** + * Utility function to convert a ChangesetsMergeConflict name to its value so + * it can be properly used inside the module runtime. + */ +export function ChangesetsMergeConflictNameToValue(name: string): ChangesetsMergeConflict { + switch (name) { + case "FAIL": + return ChangesetsMergeConflict.Fail + case "FAIL_EARLY": + return ChangesetsMergeConflict.FailEarly + default: + return name as ChangesetsMergeConflict + } +} +export type CheckGroupRunOpts = { + /** + * If true, stop running checks as soon as any check fails. + */ + failFast?: boolean +} + +export type ContainerAsServiceOpts = { + /** + * Command to run instead of the container's default command (e.g., ["go", "run", "main.go"]). + * + * If empty, the container's default command is used. + */ + args?: string[] + + /** + * If the container has an entrypoint, prepend it to the args. + */ + useEntrypoint?: boolean + + /** + * Provides Dagger access to the executed command. + */ + experimentalPrivilegedNesting?: boolean + + /** + * Execute the command with all root capabilities. This is similar to running a command with "sudo" or executing "docker run" with the "--privileged" flag. Containerization does not provide any security guarantees when using this option. It should only be used when absolutely necessary and only with trusted commands. + */ + insecureRootCapabilities?: boolean + + /** + * Replace "${VAR}" or "$VAR" in the args according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + expand?: boolean + + /** + * If set, skip the automatic init process injected into containers by default. + * + * This should only be used if the user requires that their exec process be the pid 1 process in the container. Otherwise it may result in unexpected behavior. + */ + noInit?: boolean +} + +export type ContainerAsTarballOpts = { + /** + * Identifiers for other platform specific containers. + * + * Used for multi-platform images. + */ + platformVariants?: Container[] + + /** + * Force each layer of the image to use the specified compression algorithm. + * + * If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. + */ + forcedCompression?: ImageLayerCompression + + /** + * Use the specified media types for the image's layers. + * + * Defaults to OCI, which is largely compatible with most recent container runtimes, but Docker may be needed for older runtimes without OCI support. + */ + mediaTypes?: ImageMediaTypes +} + +export type ContainerDirectoryOpts = { + /** + * Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + expand?: boolean +} + +export type ContainerExistsOpts = { + /** + * If specified, also validate the type of file (e.g. "REGULAR_TYPE", "DIRECTORY_TYPE", or "SYMLINK_TYPE"). + */ + expectedType?: ExistsType + + /** + * If specified, do not follow symlinks. + */ + doNotFollowSymlinks?: boolean + + /** + * Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + expand?: boolean +} + +export type ContainerExportOpts = { + /** + * Identifiers for other platform specific containers. + * + * Used for multi-platform image. + */ + platformVariants?: Container[] + + /** + * Force each layer of the exported image to use the specified compression algorithm. + * + * If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. + */ + forcedCompression?: ImageLayerCompression + + /** + * Use the specified media types for the exported image's layers. + * + * Defaults to OCI, which is largely compatible with most recent container runtimes, but Docker may be needed for older runtimes without OCI support. + */ + mediaTypes?: ImageMediaTypes + + /** + * Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + expand?: boolean +} + +export type ContainerExportImageOpts = { + /** + * Identifiers for other platform specific containers. + * + * Used for multi-platform image. + */ + platformVariants?: Container[] + + /** + * Force each layer of the exported image to use the specified compression algorithm. + * + * If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. + */ + forcedCompression?: ImageLayerCompression + + /** + * Use the specified media types for the exported image's layers. + * + * Defaults to OCI, which is largely compatible with most recent container runtimes, but Docker may be needed for older runtimes without OCI support. + */ + mediaTypes?: ImageMediaTypes +} + +export type ContainerFileOpts = { + /** + * Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo.txt"). + */ + expand?: boolean +} + +export type ContainerFromOpts = { + /** + * Service to use as the registry endpoint for the image address. + * + * The service will be started only for this pull. + */ + registryService?: Service + + /** + * Protocol to use for registry communication. + * + * Defaults to "HTTPS". Use "HTTP" only for plain HTTP registries. + */ + protocol?: RegistryProtocol + + /** + * Allow HTTPS registry communication without verifying the server certificate. + */ + insecureSkipTLSVerify?: boolean +} + +export type ContainerImportOpts = { + /** + * Identifies the tag to import from the archive, if the archive bundles multiple tags. + */ + tag?: string +} + +export type ContainerLayerOpts = { + /** + * Force each layer of the image to use the specified compression algorithm. + * + * If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. + */ + forcedCompression?: ImageLayerCompression + + /** + * Media types to use for image layers. Defaults to OCI. + */ + mediaTypes?: ImageMediaTypes +} + +export type ContainerManifestOpts = { + /** + * Force each layer of the image to use the specified compression algorithm. + * + * If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. + */ + forcedCompression?: ImageLayerCompression + + /** + * Media types to use for image layers. Defaults to OCI. + */ + mediaTypes?: ImageMediaTypes +} + +export type ContainerPublishOpts = { + /** + * Identifiers for other platform specific containers. + * + * Used for multi-platform image. + */ + platformVariants?: Container[] + + /** + * Force each layer of the published image to use the specified compression algorithm. + * + * If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. + */ + forcedCompression?: ImageLayerCompression + + /** + * Use the specified media types for the published image's layers. + * + * Defaults to "OCI", which is compatible with most recent registries, but "Docker" may be needed for older registries without OCI support. + */ + mediaTypes?: ImageMediaTypes + + /** + * Service to use as the registry endpoint for the image address. + * + * The service will be started only for this push. + */ + registryService?: Service + + /** + * Protocol to use for registry communication. + * + * Defaults to "HTTPS". Use "HTTP" only for plain HTTP registries. + */ + protocol?: RegistryProtocol + + /** + * Allow HTTPS registry communication without verifying the server certificate. + */ + insecureSkipTLSVerify?: boolean +} + +export type ContainerStatOpts = { + /** + * If specified, do not follow symlinks. + */ + doNotFollowSymlinks?: boolean +} + +export type ContainerTerminalOpts = { + /** + * If set, override the container's default terminal command and invoke these command arguments instead. + */ + cmd?: string[] + + /** + * Provides Dagger access to the executed command. + */ + experimentalPrivilegedNesting?: boolean + + /** + * Execute the command with all root capabilities. This is similar to running a command with "sudo" or executing "docker run" with the "--privileged" flag. Containerization does not provide any security guarantees when using this option. It should only be used when absolutely necessary and only with trusted commands. + */ + insecureRootCapabilities?: boolean +} + +export type ContainerUpOpts = { + /** + * Bind each tunnel port to a random port on the host. + */ + random?: boolean + + /** + * List of frontend/backend port mappings to forward. + * + * Frontend is the port accepting traffic on the host, backend is the service port. + */ + ports?: PortForward[] + + /** + * Command to run instead of the container's default command (e.g., ["go", "run", "main.go"]). + * + * If empty, the container's default command is used. + */ + args?: string[] + + /** + * If the container has an entrypoint, prepend it to the args. + */ + useEntrypoint?: boolean + + /** + * Provides Dagger access to the executed command. + */ + experimentalPrivilegedNesting?: boolean + + /** + * Execute the command with all root capabilities. This is similar to running a command with "sudo" or executing "docker run" with the "--privileged" flag. Containerization does not provide any security guarantees when using this option. It should only be used when absolutely necessary and only with trusted commands. + */ + insecureRootCapabilities?: boolean + + /** + * Replace "${VAR}" or "$VAR" in the args according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + expand?: boolean + + /** + * If set, skip the automatic init process injected into containers by default. + * + * This should only be used if the user requires that their exec process be the pid 1 process in the container. Otherwise it may result in unexpected behavior. + */ + noInit?: boolean +} + +export type ContainerWithDefaultTerminalCmdOpts = { + /** + * Provides Dagger access to the executed command. + */ + experimentalPrivilegedNesting?: boolean + + /** + * Execute the command with all root capabilities. This is similar to running a command with "sudo" or executing "docker run" with the "--privileged" flag. Containerization does not provide any security guarantees when using this option. It should only be used when absolutely necessary and only with trusted commands. + */ + insecureRootCapabilities?: boolean +} + +export type ContainerWithDirectoryOpts = { + /** + * Patterns to exclude in the written directory (e.g. ["node_modules/**", ".gitignore", ".git/"]). + */ + exclude?: string[] + + /** + * Patterns to include in the written directory (e.g. ["*.go", "go.mod", "go.sum"]). + */ + include?: string[] + + /** + * Apply .gitignore rules when writing the directory. + */ + gitignore?: boolean + + /** + * A user:group to set for the directory and its contents. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + */ + owner?: string + + /** + * Set the owner to the container's current user. + */ + inheritOwner?: boolean + + /** + * Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + expand?: boolean + permissions?: number +} + +export type ContainerWithDockerHealthcheckOpts = { + /** + * When true, command must be a single element, which is run using the container's shell + */ + shell?: boolean + + /** + * Interval between running healthcheck. Example: "30s" + */ + interval?: string + + /** + * Healthcheck timeout. Example: "3s" + */ + timeout?: string + + /** + * StartPeriod allows for failures during this initial startup period which do not count towards maximum number of retries. Example: "0s" + */ + startPeriod?: string + + /** + * StartInterval configures the duration between checks during the startup phase. Example: "5s" + */ + startInterval?: string + + /** + * The maximum number of consecutive failures before the container is marked as unhealthy. Example: "3" + */ + retries?: number +} + +export type ContainerWithEntrypointOpts = { + /** + * Don't reset the default arguments when setting the entrypoint. By default it is reset, since entrypoint and default args are often tightly coupled. + */ + keepDefaultArgs?: boolean +} + +export type ContainerWithEnvVariableOpts = { + /** + * Replace "${VAR}" or "$VAR" in the value according to the current environment variables defined in the container (e.g. "/opt/bin:$PATH"). + */ + expand?: boolean +} + +export type ContainerWithExecOpts = { + /** + * Apply the OCI entrypoint, if present, by prepending it to the args. Ignored by default. + */ + useEntrypoint?: boolean + + /** + * Content to write to the command's standard input. Example: "Hello world") + */ + stdin?: string + + /** + * Redirect the command's standard input from a file in the container. Example: "./stdin.txt" + */ + redirectStdin?: string + + /** + * Redirect the command's standard output to a file in the container. Example: "./stdout.txt" + */ + redirectStdout?: string + + /** + * Redirect the command's standard error to a file in the container. Example: "./stderr.txt" + */ + redirectStderr?: string + + /** + * Exit codes this command is allowed to exit with without error + */ + expect?: ReturnType + + /** + * Provides Dagger access to the executed command. + */ + experimentalPrivilegedNesting?: boolean + + /** + * Execute the command with all root capabilities. Like --privileged in Docker + * + * DANGER: this grants the command full access to the host system. Only use when 1) you trust the command being executed and 2) you specifically need this level of access. + */ + insecureRootCapabilities?: boolean + + /** + * Replace "${VAR}" or "$VAR" in the args according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + expand?: boolean + + /** + * Skip the automatic init process injected into containers by default. + * + * Only use this if you specifically need the command to be pid 1 in the container. Otherwise it may result in unexpected behavior. If you're not sure, you don't need this. + */ + noInit?: boolean +} + +export type ContainerWithExposedPortOpts = { + /** + * Network protocol. Example: "tcp" + */ + protocol?: NetworkProtocol + + /** + * Port description. Example: "payment API endpoint" + */ + description?: string + + /** + * Skip the health check when run as a service. + */ + experimentalSkipHealthcheck?: boolean +} + +export type ContainerWithFileOpts = { + /** + * Permissions of the new file. Example: 0600 + */ + permissions?: number + + /** + * A user:group to set for the file. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + */ + owner?: string + + /** + * Set the owner to the container's current user. + */ + inheritOwner?: boolean + + /** + * Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo.txt"). + */ + expand?: boolean +} + +export type ContainerWithFilesOpts = { + /** + * Permission given to the copied files (e.g., 0600). + */ + permissions?: number + + /** + * A user:group to set for the files. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + */ + owner?: string + + /** + * Set the owner to the container's current user. + */ + inheritOwner?: boolean + + /** + * Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo.txt"). + */ + expand?: boolean +} + +export type ContainerWithMountedCacheOpts = { + /** + * Identifier of the directory to use as the cache volume's root. + */ + source?: Directory + + /** + * Sharing mode of the cache volume. + */ + sharing?: CacheSharingMode + + /** + * A user:group to set for the mounted cache directory. + * + * Note that this changes the ownership of the specified mount along with the initial filesystem provided by source (if any). It does not have any effect if/when the cache has already been created. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + */ + owner?: string + + /** + * Set the owner to the container's current user. + */ + inheritOwner?: boolean + + /** + * Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + expand?: boolean +} + +export type ContainerWithMountedDirectoryOpts = { + /** + * A user:group to set for the mounted directory and its contents. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + */ + owner?: string + + /** + * Set the owner to the container's current user. + */ + inheritOwner?: boolean + + /** + * Mount the directory read-only. + */ + readOnly?: boolean + + /** + * Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + expand?: boolean +} + +export type ContainerWithMountedFileOpts = { + /** + * A user or user:group to set for the mounted file. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + */ + owner?: string + + /** + * Set the owner to the container's current user. + */ + inheritOwner?: boolean + + /** + * Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo.txt"). + */ + expand?: boolean +} + +export type ContainerWithMountedSecretOpts = { + /** + * A user:group to set for the mounted secret. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + */ + owner?: string + + /** + * Set the owner to the container's current user. + */ + inheritOwner?: boolean + + /** + * Permission given to the mounted secret (e.g., 0600). + * + * This option requires an owner to be set to be active. + */ + mode?: number + + /** + * Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + expand?: boolean +} + +export type ContainerWithMountedTempOpts = { + /** + * Size of the temporary directory in bytes. + */ + size?: number + + /** + * Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + expand?: boolean +} + +export type ContainerWithMountedVolumeOpts = { + /** + * Mount the volume read-only. + */ + readOnly?: boolean + + /** + * Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + expand?: boolean +} + +export type ContainerWithNewFileOpts = { + /** + * Permissions of the new file. Example: 0600 + */ + permissions?: number + + /** + * A user:group to set for the file. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + */ + owner?: string + + /** + * Set the owner to the container's current user. + */ + inheritOwner?: boolean + + /** + * Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo.txt"). + */ + expand?: boolean +} + +export type ContainerWithSymlinkOpts = { + /** + * Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo.txt"). + */ + expand?: boolean +} + +export type ContainerWithUnixSocketOpts = { + /** + * A user:group to set for the mounted socket. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + */ + owner?: string + + /** + * Set the owner to the container's current user. + */ + inheritOwner?: boolean + + /** + * Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + expand?: boolean +} + +export type ContainerWithWorkdirOpts = { + /** + * Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + expand?: boolean +} + +export type ContainerWithoutDirectoryOpts = { + /** + * Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + expand?: boolean +} + +export type ContainerWithoutEntrypointOpts = { + /** + * Don't remove the default arguments when unsetting the entrypoint. + */ + keepDefaultArgs?: boolean +} + +export type ContainerWithoutExposedPortOpts = { + /** + * Port protocol to unexpose + */ + protocol?: NetworkProtocol +} + +export type ContainerWithoutFileOpts = { + /** + * Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo.txt"). + */ + expand?: boolean +} + +export type ContainerWithoutFilesOpts = { + /** + * Replace "${VAR}" or "$VAR" in the value of paths according to the current environment variables defined in the container (e.g. "/$VAR/foo.txt"). + */ + expand?: boolean +} + +export type ContainerWithoutMountOpts = { + /** + * Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + expand?: boolean +} + +export type ContainerWithoutUnixSocketOpts = { + /** + * Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + expand?: boolean +} + +export type CurrentModuleAsSdkOpts = { + /** + * The workspace to resolve SDK-role data against. Defaults to the current workspace. + */ + workspace?: Workspace +} + +export type CurrentModuleGeneratorsOpts = { + /** + * Only include generators matching the specified patterns + */ + include?: string[] +} + +export type CurrentModuleWorkdirOpts = { + /** + * Exclude artifacts that match the given pattern (e.g., ["node_modules/", ".git*"]). + */ + exclude?: string[] + + /** + * Include only artifacts that match the given pattern (e.g., ["app/", "package.*"]). + */ + include?: string[] + + /** + * Apply .gitignore filter rules inside the directory + */ + gitignore?: boolean +} + +/** + * The type of change for a diff stat entry. + */ +export enum DiffStatKind { + + /** + * A file or directory was added. + */ + Added = "ADDED", + + /** + * A file was modified. + */ + Modified = "MODIFIED", + + /** + * A file or directory was removed. + */ + Removed = "REMOVED", + + /** + * A file was renamed. + */ + Renamed = "RENAMED", +} + +/** + * Utility function to convert a DiffStatKind value to its name so + * it can be uses as argument to call a exposed function. + */ +export function DiffStatKindValueToName(value: DiffStatKind): string { + switch (value) { + case DiffStatKind.Added: + return "ADDED" + case DiffStatKind.Modified: + return "MODIFIED" + case DiffStatKind.Removed: + return "REMOVED" + case DiffStatKind.Renamed: + return "RENAMED" + default: + return value + } +} + +/** + * Utility function to convert a DiffStatKind name to its value so + * it can be properly used inside the module runtime. + */ +export function DiffStatKindNameToValue(name: string): DiffStatKind { + switch (name) { + case "ADDED": + return DiffStatKind.Added + case "MODIFIED": + return DiffStatKind.Modified + case "REMOVED": + return DiffStatKind.Removed + case "RENAMED": + return DiffStatKind.Renamed + default: + return name as DiffStatKind + } +} +export type DirectoryAsModuleOpts = { + /** + * An optional subpath of the directory which contains the module's configuration file. + * + * If not set, the module source code is loaded from the root of the directory. + */ + sourceRootPath?: string +} + +export type DirectoryAsModuleSourceOpts = { + /** + * An optional subpath of the directory which contains the module's configuration file. + * + * If not set, the module source code is loaded from the root of the directory. + */ + sourceRootPath?: string +} + +export type DirectoryAsWorkspaceOpts = { + /** + * Current working directory inside the workspace root. Defaults to the workspace root. + */ + cwd?: string +} + +export type DirectoryDockerBuildOpts = { + /** + * Path to the Dockerfile to use (e.g., "frontend.Dockerfile"). + */ + dockerfile?: string + + /** + * The platform to build. + */ + platform?: Platform + + /** + * Build arguments to use in the build. + */ + buildArgs?: BuildArg[] + + /** + * Target build stage to build. + */ + target?: string + + /** + * Secrets to pass to the build. + * + * They will be mounted at /run/secrets/[secret-name]. + */ + secrets?: Secret[] + + /** + * If set, skip the automatic init process injected into containers created by RUN statements. + * + * This should only be used if the user requires that their exec processes be the pid 1 process in the container. Otherwise it may result in unexpected behavior. + */ + noInit?: boolean + + /** + * A socket to use for SSH authentication during the build + * + * (e.g., for Dockerfile RUN --mount=type=ssh instructions). + * + * Typically obtained via host.unixSocket() pointing to the SSH_AUTH_SOCK. + */ + ssh?: Socket +} + +export type DirectoryEntriesOpts = { + /** + * Location of the directory to look at (e.g., "/src"). + */ + path?: string +} + +export type DirectoryExistsOpts = { + /** + * If specified, also validate the type of file (e.g. "REGULAR_TYPE", "DIRECTORY_TYPE", or "SYMLINK_TYPE"). + */ + expectedType?: ExistsType + + /** + * If specified, do not follow symlinks. + */ + doNotFollowSymlinks?: boolean +} + +export type DirectoryExportOpts = { + /** + * If true, then the host directory will be wiped clean before exporting so that it exactly matches the directory being exported; this means it will delete any files on the host that aren't in the exported dir. If false (the default), the contents of the directory will be merged with any existing contents of the host directory, leaving any existing files on the host that aren't in the exported directory alone. + */ + wipe?: boolean +} + +export type DirectoryFilterOpts = { + /** + * If set, paths matching one of these glob patterns is excluded from the new snapshot. Example: ["node_modules/", ".git*", ".env"] + */ + exclude?: string[] + + /** + * If set, only paths matching one of these glob patterns is included in the new snapshot. Example: (e.g., ["app/", "package.*"]). + */ + include?: string[] + + /** + * If set, apply .gitignore rules when filtering the directory. + */ + gitignore?: boolean +} + +export type DirectorySearchOpts = { + /** + * Directory or file paths to search + */ + paths?: string[] + + /** + * Glob patterns to match (e.g., "*.md") + */ + globs?: string[] + + /** + * The text to match. + */ + pattern: string + + /** + * Interpret the pattern as a literal string instead of a regular expression. + */ + literal?: boolean + + /** + * Enable searching across multiple lines. + */ + multiline?: boolean + + /** + * Allow the . pattern to match newlines in multiline mode. + */ + dotall?: boolean + + /** + * Enable case-insensitive matching. + */ + insensitive?: boolean + + /** + * Honor .gitignore, .ignore, and .rgignore files. + */ + skipIgnored?: boolean + + /** + * Skip hidden files (files starting with .). + */ + skipHidden?: boolean + + /** + * Only return matching files, not lines and content + */ + filesOnly?: boolean + + /** + * Limit the number of results to return + */ + limit?: number +} + +export type DirectoryStatOpts = { + /** + * If specified, do not follow symlinks. + */ + doNotFollowSymlinks?: boolean +} + +export type DirectoryTerminalOpts = { + /** + * If set, override the default container used for the terminal. + */ + container?: Container + + /** + * If set, override the container's default terminal command and invoke these command arguments instead. + */ + cmd?: string[] + + /** + * Provides Dagger access to the executed command. + */ + experimentalPrivilegedNesting?: boolean + + /** + * Execute the command with all root capabilities. This is similar to running a command with "sudo" or executing "docker run" with the "--privileged" flag. Containerization does not provide any security guarantees when using this option. It should only be used when absolutely necessary and only with trusted commands. + */ + insecureRootCapabilities?: boolean +} + +export type DirectoryWithDirectoryOpts = { + /** + * Exclude artifacts that match the given pattern (e.g., ["node_modules/", ".git*"]). + */ + exclude?: string[] + + /** + * Include only artifacts that match the given pattern (e.g., ["app/", "package.*"]). + */ + include?: string[] + + /** + * Apply .gitignore filter rules inside the directory + */ + gitignore?: boolean + + /** + * A user:group to set for the copied directory and its contents. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + */ + owner?: string + + /** + * Permission given to the copied directory and contents (e.g., 0755). + */ + permissions?: number +} + +export type DirectoryWithFileOpts = { + /** + * Permission given to the copied file (e.g., 0600). + */ + permissions?: number + + /** + * A user:group to set for the copied directory and its contents. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + */ + owner?: string +} + +export type DirectoryWithFilesOpts = { + /** + * Permission given to the copied files (e.g., 0600). + */ + permissions?: number +} + +export type DirectoryWithNewDirectoryOpts = { + /** + * Permission granted to the created directory (e.g., 0777). + */ + permissions?: number +} + +export type DirectoryWithNewFileOpts = { + /** + * Permissions of the new file. Example: 0600 + */ + permissions?: number +} + +export type EngineCacheEntrySetOpts = { + key?: string +} + +export type EngineCachePruneOpts = { + /** + * Use the engine-wide default pruning policy if true, otherwise prune the whole cache of any releasable entries. + */ + useDefaultPolicy?: boolean + + /** + * Override the maximum disk space to keep before pruning (e.g. "200GB" or "80%"). + */ + maxUsedSpace?: string + + /** + * Override the minimum disk space to retain during pruning (e.g. "500GB" or "10%"). + */ + reservedSpace?: string + + /** + * Override the minimum free disk space target during pruning (e.g. "20GB" or "20%"). + */ + minFreeSpace?: string + + /** + * Override the target disk space to keep after pruning (e.g. "200GB" or "50%"). + */ + targetSpace?: string +} + +export type EnvChecksOpts = { + /** + * Only include checks matching the specified patterns + */ + include?: string[] + + /** + * When true, only return annotated check functions; exclude generate-as-checks + */ + noGenerate?: boolean +} + +export type EnvServicesOpts = { + /** + * Only include services matching the specified patterns + */ + include?: string[] +} + +export type EnvFileGetOpts = { + /** + * Return the value exactly as written to the file. No quote removal or variable expansion + */ + raw?: boolean +} + +export type EnvFileVariablesOpts = { + /** + * Return values exactly as written to the file. No quote removal or variable expansion + */ + raw?: boolean +} + +/** + * File type. + */ +export enum ExistsType { + + /** + * Tests path is a directory + */ + DirectoryType = "DIRECTORY_TYPE", + + /** + * Tests path is a regular file + */ + RegularType = "REGULAR_TYPE", + + /** + * Tests path is a symlink + */ + SymlinkType = "SYMLINK_TYPE", +} + +/** + * Utility function to convert a ExistsType value to its name so + * it can be uses as argument to call a exposed function. + */ +export function ExistsTypeValueToName(value: ExistsType): string { + switch (value) { + case ExistsType.DirectoryType: + return "DIRECTORY_TYPE" + case ExistsType.RegularType: + return "REGULAR_TYPE" + case ExistsType.SymlinkType: + return "SYMLINK_TYPE" + default: + return value + } +} + +/** + * Utility function to convert a ExistsType name to its value so + * it can be properly used inside the module runtime. + */ +export function ExistsTypeNameToValue(name: string): ExistsType { + switch (name) { + case "DIRECTORY_TYPE": + return ExistsType.DirectoryType + case "REGULAR_TYPE": + return ExistsType.RegularType + case "SYMLINK_TYPE": + return ExistsType.SymlinkType + default: + return name as ExistsType + } +} +export type FileAsEnvFileOpts = { + /** + * Replace "${VAR}" or "$VAR" with the value of other vars + * + * @deprecated Variable expansion is now enabled by default + */ + expand?: boolean +} + +export type FileContentsOpts = { + /** + * Start reading after this line + */ + offsetLines?: number + + /** + * Maximum number of lines to read + */ + limitLines?: number +} + +export type FileDigestOpts = { + /** + * If true, exclude metadata from the digest. + */ + excludeMetadata?: boolean +} + +export type FileExportOpts = { + /** + * If allowParentDirPath is true, the path argument can be a directory path, in which case the file will be created in that directory. + */ + allowParentDirPath?: boolean +} + +export type FileSearchOpts = { + /** + * Interpret the pattern as a literal string instead of a regular expression. + */ + literal?: boolean + + /** + * Enable searching across multiple lines. + */ + multiline?: boolean + + /** + * Allow the . pattern to match newlines in multiline mode. + */ + dotall?: boolean + + /** + * Enable case-insensitive matching. + */ + insensitive?: boolean + + /** + * Honor .gitignore, .ignore, and .rgignore files. + */ + skipIgnored?: boolean + + /** + * Skip hidden files (files starting with .). + */ + skipHidden?: boolean + + /** + * Only return matching files, not lines and content + */ + filesOnly?: boolean + + /** + * Limit the number of results to return + */ + limit?: number + paths?: string[] + globs?: string[] +} + +export type FileWithReplacedOpts = { + /** + * Replace all occurrences of the pattern. + */ + all?: boolean + + /** + * Replace the first match starting from the specified line. + */ + firstFrom?: number +} + +/** + * File type. + */ +export enum FileType { + + /** + * directory file type + */ + Directory = "DIRECTORY", + + /** + * directory file type + */ + DirectoryType = FileType.Directory, + + /** + * regular file type + */ + Regular = "REGULAR", + + /** + * regular file type + */ + RegularType = FileType.Regular, + + /** + * symlink file type + */ + Symlink = "SYMLINK", + + /** + * symlink file type + */ + SymlinkType = FileType.Symlink, + + /** + * unknown file type + */ + Unknown = "UNKNOWN", +} + +/** + * Utility function to convert a FileType value to its name so + * it can be uses as argument to call a exposed function. + */ +export function FileTypeValueToName(value: FileType): string { + switch (value) { + case FileType.Directory: + return "DIRECTORY" + case FileType.Regular: + return "REGULAR" + case FileType.Symlink: + return "SYMLINK" + case FileType.Unknown: + return "UNKNOWN" + default: + return value + } +} + +/** + * Utility function to convert a FileType name to its value so + * it can be properly used inside the module runtime. + */ +export function FileTypeNameToValue(name: string): FileType { + switch (name) { + case "DIRECTORY": + return FileType.Directory + case "REGULAR": + return FileType.Regular + case "SYMLINK": + return FileType.Symlink + case "UNKNOWN": + return FileType.Unknown + default: + return name as FileType + } +} +export type FunctionWithArgOpts = { + /** + * A doc string for the argument, if any + */ + description?: string + + /** + * A default value to use for this argument if not explicitly set by the caller, if any + */ + defaultValue?: JSON + + /** + * If the argument is a Directory or File type, default to load path from context directory, relative to root directory. + */ + defaultPath?: string + + /** + * Patterns to ignore when loading the contextual argument value. + */ + ignore?: string[] + + /** + * The source map for the argument definition. + */ + sourceMap?: SourceMap + + /** + * If deprecated, the reason or migration path. + */ + deprecated?: string + defaultAddress?: string +} + +export type FunctionWithCachePolicyOpts = { + /** + * The TTL for the cache policy, if applicable. Provided as a duration string, e.g. "5m", "1h30s". + */ + timeToLive?: string +} + +export type FunctionWithDeprecatedOpts = { + /** + * Reason or migration path describing the deprecation. + */ + reason?: string +} + +/** + * The behavior configured for function result caching. + */ +export enum FunctionCachePolicy { + Default = "Default", + Never = "Never", + PerSession = "PerSession", +} + +/** + * Utility function to convert a FunctionCachePolicy value to its name so + * it can be uses as argument to call a exposed function. + */ +export function FunctionCachePolicyValueToName(value: FunctionCachePolicy): string { + switch (value) { + case FunctionCachePolicy.Default: + return "Default" + case FunctionCachePolicy.Never: + return "Never" + case FunctionCachePolicy.PerSession: + return "PerSession" + default: + return value + } +} + +/** + * Utility function to convert a FunctionCachePolicy name to its value so + * it can be properly used inside the module runtime. + */ +export function FunctionCachePolicyNameToValue(name: string): FunctionCachePolicy { + switch (name) { + case "Default": + return FunctionCachePolicy.Default + case "Never": + return FunctionCachePolicy.Never + case "PerSession": + return FunctionCachePolicy.PerSession + default: + return name as FunctionCachePolicy + } +} +export type GeneratorGroupChangesOpts = { + /** + * Strategy to apply on conflicts between generators + */ + onConflict?: ChangesetsMergeConflict +} + +export type GitRefAsWorkspaceOpts = { + /** + * Current working directory inside the workspace root. Defaults to the workspace root. + */ + cwd?: string +} + +export type GitRefTreeOpts = { + /** + * Set to true to discard .git directory. + */ + discardGitDir?: boolean + + /** + * The depth of the tree to fetch. + */ + depth?: number + + /** + * Set to true to populate tag refs in the local checkout .git. + */ + includeTags?: boolean +} + +export type GitRepositoryAsWorkspaceOpts = { + /** + * Current working directory inside the workspace root. Defaults to the workspace root. + */ + cwd?: string +} + +export type GitRepositoryBranchesOpts = { + /** + * Glob patterns (e.g., "refs/tags/v*"). + */ + patterns?: string[] +} + +export type GitRepositoryTagsOpts = { + /** + * Glob patterns (e.g., "refs/tags/v*"). + */ + patterns?: string[] +} + +export type HostDirectoryOpts = { + /** + * Exclude artifacts that match the given pattern (e.g., ["node_modules/", ".git*"]). + */ + exclude?: string[] + + /** + * Include only artifacts that match the given pattern (e.g., ["app/", "package.*"]). + */ + include?: string[] + + /** + * If true, the directory will always be reloaded from the host. + */ + noCache?: boolean + + /** + * Apply .gitignore filter rules inside the directory + */ + gitignore?: boolean +} + +export type HostFileOpts = { + /** + * If true, the file will always be reloaded from the host. + */ + noCache?: boolean +} + +export type HostFindUpOpts = { + noCache?: boolean +} + +export type HostServiceOpts = { + /** + * Upstream host to forward traffic to. + */ + host?: string +} + +export type HostTunnelOpts = { + /** + * Map each service port to the same port on the host, as if the service were running natively. + * + * Note: enabling may result in port conflicts. + */ + native?: boolean + + /** + * Configure explicit port forwarding rules for the tunnel. + * + * If a port's frontend is unspecified or 0, a random port will be chosen by the host. + * + * If no ports are given, all of the service's ports are forwarded. If native is true, each port maps to the same port on the host. If native is false, each port maps to a random port chosen by the host. + * + * If ports are given and native is true, the ports are additive. + */ + ports?: PortForward[] +} + +/** + * A unique identifier for an object. + */ +export type ID = string & {__ID: never} + +/** + * Compression algorithm to use for image layers. + */ +export enum ImageLayerCompression { + EstarGz = "EStarGZ", + Estargz = ImageLayerCompression.EstarGz, + Gzip = "Gzip", + Uncompressed = "Uncompressed", + Zstd = "Zstd", +} + +/** + * Utility function to convert a ImageLayerCompression value to its name so + * it can be uses as argument to call a exposed function. + */ +export function ImageLayerCompressionValueToName(value: ImageLayerCompression): string { + switch (value) { + case ImageLayerCompression.EstarGz: + return "EStarGZ" + case ImageLayerCompression.Gzip: + return "Gzip" + case ImageLayerCompression.Uncompressed: + return "Uncompressed" + case ImageLayerCompression.Zstd: + return "Zstd" + default: + return value + } +} + +/** + * Utility function to convert a ImageLayerCompression name to its value so + * it can be properly used inside the module runtime. + */ +export function ImageLayerCompressionNameToValue(name: string): ImageLayerCompression { + switch (name) { + case "EStarGZ": + return ImageLayerCompression.EstarGz + case "Gzip": + return ImageLayerCompression.Gzip + case "Uncompressed": + return ImageLayerCompression.Uncompressed + case "Zstd": + return ImageLayerCompression.Zstd + default: + return name as ImageLayerCompression + } +} +/** + * Mediatypes to use in published or exported image metadata. + */ +export enum ImageMediaTypes { + Docker = "DockerMediaTypes", + DockerMediaTypes = ImageMediaTypes.Docker, + Oci = "OCIMediaTypes", + OcimediaTypes = ImageMediaTypes.Oci, +} + +/** + * Utility function to convert a ImageMediaTypes value to its name so + * it can be uses as argument to call a exposed function. + */ +export function ImageMediaTypesValueToName(value: ImageMediaTypes): string { + switch (value) { + case ImageMediaTypes.Docker: + return "DOCKER" + case ImageMediaTypes.Oci: + return "OCI" + default: + return value + } +} + +/** + * Utility function to convert a ImageMediaTypes name to its value so + * it can be properly used inside the module runtime. + */ +export function ImageMediaTypesNameToValue(name: string): ImageMediaTypes { + switch (name) { + case "DOCKER": + return ImageMediaTypes.Docker + case "OCI": + return ImageMediaTypes.Oci + default: + return name as ImageMediaTypes + } +} +/** + * An arbitrary JSON-encoded value. + */ +export type JSON = string & {__JSON: never} + +export type JSONValueContentsOpts = { + /** + * Pretty-print + */ + pretty?: boolean + + /** + * Optional line prefix + */ + indent?: string +} + +export type LLMLoopOpts = { + /** + * Cap the number of steps. The loop fails if the cap is reached before the model ends its turn. + */ + maxSteps?: number + + /** + * Cap the model's output tokens on each step. Defaults to the model's maximum. + */ + maxTokens?: number +} + +export type LLMStepOpts = { + /** + * Cap the model's output tokens for this step. Defaults to the model's maximum. + */ + maxTokens?: number +} + +export type LLMWithModelOpts = { + /** + * The provider serving the model, e.g. "openai". Overrides the provider otherwise inferred from the model name — useful when the name matches no known pattern (e.g. a fine-tune), or matches the wrong one. + */ + provider?: string +} + +export type LLMWithResponseOpts = { + /** + * Uncached input tokens sent + */ + inputTokens?: number + + /** + * Tokens received from the model, including text and tool calls + */ + outputTokens?: number + + /** + * Cached input tokens read + */ + cachedTokenReads?: number + + /** + * Cached input tokens written + */ + cachedTokenWrites?: number + + /** + * Total tokens consumed by this response + */ + totalTokens?: number +} + +export type LLMContentBlockInput = { + /** + * The arguments to pass to the tool (for TOOL_CALL kind). + */ + arguments?: JSON + + /** + * The unique ID of a tool call (for TOOL_CALL or TOOL_RESULT kinds). + */ + callId?: string + + /** + * Whether the tool call resulted in an error (for TOOL_RESULT kind). + */ + errored?: boolean + + /** + * The kind of content block. + */ + kind: LLMContentBlockKind + + /** + * Provider-specific opaque data (e.g. Anthropic thinking signature). + */ + signature?: string + + /** + * Text content (for TEXT, THINKING, or TOOL_RESULT kinds). + */ + text?: string + + /** + * The name of the tool to call (for TOOL_CALL kind). + */ + toolName?: string +} + +/** + * The kind of content in a message block. + */ +export enum LLMContentBlockKind { + + /** + * Plain text content. + */ + Text = "TEXT", + + /** + * Model thinking/reasoning content (e.g. Anthropic extended thinking). + */ + Thinking = "THINKING", + + /** + * A tool/function call from the model. + */ + ToolCall = "TOOL_CALL", + + /** + * A tool/function result. + */ + ToolResult = "TOOL_RESULT", +} + +/** + * Utility function to convert a LLMContentBlockKind value to its name so + * it can be uses as argument to call a exposed function. + */ +export function LLMContentBlockKindValueToName(value: LLMContentBlockKind): string { + switch (value) { + case LLMContentBlockKind.Text: + return "TEXT" + case LLMContentBlockKind.Thinking: + return "THINKING" + case LLMContentBlockKind.ToolCall: + return "TOOL_CALL" + case LLMContentBlockKind.ToolResult: + return "TOOL_RESULT" + default: + return value + } +} + +/** + * Utility function to convert a LLMContentBlockKind name to its value so + * it can be properly used inside the module runtime. + */ +export function LLMContentBlockKindNameToValue(name: string): LLMContentBlockKind { + switch (name) { + case "TEXT": + return LLMContentBlockKind.Text + case "THINKING": + return LLMContentBlockKind.Thinking + case "TOOL_CALL": + return LLMContentBlockKind.ToolCall + case "TOOL_RESULT": + return LLMContentBlockKind.ToolResult + default: + return name as LLMContentBlockKind + } +} +/** + * The role that generated a message. + */ +export enum LLMMessageRole { + + /** + * A reply from the model. + */ + Assistant = "ASSISTANT", + + /** + * A system prompt. + */ + System = "SYSTEM", + + /** + * A user prompt or tool response. + */ + User = "USER", +} + +/** + * Utility function to convert a LLMMessageRole value to its name so + * it can be uses as argument to call a exposed function. + */ +export function LLMMessageRoleValueToName(value: LLMMessageRole): string { + switch (value) { + case LLMMessageRole.Assistant: + return "ASSISTANT" + case LLMMessageRole.System: + return "SYSTEM" + case LLMMessageRole.User: + return "USER" + default: + return value + } +} + +/** + * Utility function to convert a LLMMessageRole name to its value so + * it can be properly used inside the module runtime. + */ +export function LLMMessageRoleNameToValue(name: string): LLMMessageRole { + switch (name) { + case "ASSISTANT": + return LLMMessageRole.Assistant + case "SYSTEM": + return LLMMessageRole.System + case "USER": + return LLMMessageRole.User + default: + return name as LLMMessageRole + } +} +export type ModuleChecksOpts = { + /** + * Only include checks matching the specified patterns + */ + include?: string[] + + /** + * When true, only return annotated check functions; exclude generate-as-checks + */ + noGenerate?: boolean +} + +export type ModuleGeneratorsOpts = { + /** + * Only include generators matching the specified patterns + */ + include?: string[] +} + +export type ModuleServeOpts = { + /** + * Expose the dependencies of this module to the client + */ + includeDependencies?: boolean + + /** + * Install the module as the entrypoint, promoting its main-object methods onto the Query root + */ + entrypoint?: boolean +} + +export type ModuleServicesOpts = { + /** + * Only include services matching the specified patterns + */ + include?: string[] +} + +/** + * Experimental features of a module + */ +export enum ModuleSourceExperimentalFeature { + + /** + * Self calls + */ + SelfCalls = "SELF_CALLS", +} + +/** + * Utility function to convert a ModuleSourceExperimentalFeature value to its name so + * it can be uses as argument to call a exposed function. + */ +export function ModuleSourceExperimentalFeatureValueToName(value: ModuleSourceExperimentalFeature): string { + switch (value) { + case ModuleSourceExperimentalFeature.SelfCalls: + return "SELF_CALLS" + default: + return value + } +} + +/** + * Utility function to convert a ModuleSourceExperimentalFeature name to its value so + * it can be properly used inside the module runtime. + */ +export function ModuleSourceExperimentalFeatureNameToValue(name: string): ModuleSourceExperimentalFeature { + switch (name) { + case "SELF_CALLS": + return ModuleSourceExperimentalFeature.SelfCalls + default: + return name as ModuleSourceExperimentalFeature + } +} +/** + * The kind of module source. + */ +export enum ModuleSourceKind { + Dir = "DIR_SOURCE", + DirSource = ModuleSourceKind.Dir, + Git = "GIT_SOURCE", + GitSource = ModuleSourceKind.Git, + Local = "LOCAL_SOURCE", + LocalSource = ModuleSourceKind.Local, +} + +/** + * Utility function to convert a ModuleSourceKind value to its name so + * it can be uses as argument to call a exposed function. + */ +export function ModuleSourceKindValueToName(value: ModuleSourceKind): string { + switch (value) { + case ModuleSourceKind.Dir: + return "DIR" + case ModuleSourceKind.Git: + return "GIT" + case ModuleSourceKind.Local: + return "LOCAL" + default: + return value + } +} + +/** + * Utility function to convert a ModuleSourceKind name to its value so + * it can be properly used inside the module runtime. + */ +export function ModuleSourceKindNameToValue(name: string): ModuleSourceKind { + switch (name) { + case "DIR": + return ModuleSourceKind.Dir + case "GIT": + return ModuleSourceKind.Git + case "LOCAL": + return ModuleSourceKind.Local + default: + return name as ModuleSourceKind + } +} +/** + * Transport layer network protocol associated to a port. + */ +export enum NetworkProtocol { + Tcp = "TCP", + Udp = "UDP", +} + +/** + * Utility function to convert a NetworkProtocol value to its name so + * it can be uses as argument to call a exposed function. + */ +export function NetworkProtocolValueToName(value: NetworkProtocol): string { + switch (value) { + case NetworkProtocol.Tcp: + return "TCP" + case NetworkProtocol.Udp: + return "UDP" + default: + return value + } +} + +/** + * Utility function to convert a NetworkProtocol name to its value so + * it can be properly used inside the module runtime. + */ +export function NetworkProtocolNameToValue(name: string): NetworkProtocol { + switch (name) { + case "TCP": + return NetworkProtocol.Tcp + case "UDP": + return NetworkProtocol.Udp + default: + return name as NetworkProtocol + } +} +export type PipelineLabel = { + /** + * Label name. + */ + name: string + + /** + * Label value. + */ + value: string +} + +/** + * The platform config OS and architecture in a Container. + * + * The format is [os]/[platform]/[version] (e.g., "darwin/arm64/v7", "windows/amd64", "linux/arm64"). + */ +export type Platform = string & {__Platform: never} + +export type PortForward = { + /** + * Destination port for traffic. + */ + backend: number + + /** + * Port to expose to clients. If unspecified, a default will be chosen. + */ + frontend?: number + + /** + * Transport layer protocol to use for traffic. + */ + protocol?: NetworkProtocol +} + +export type ClientCacheVolumeOpts = { + /** + * Identifier of the directory to use as the cache volume's root. + */ + source?: Directory + + /** + * Sharing mode of the cache volume. + */ + sharing?: CacheSharingMode + + /** + * A user:group to set for the cache volume root. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + */ + owner?: string +} + +export type ClientContainerOpts = { + /** + * Platform to initialize the container with. Defaults to the native platform of the current engine + */ + platform?: Platform +} + +export type ClientCurrentTypeDefsOpts = { + /** + * Return the full referenced typedef closure instead of only top-level served typedefs. + */ + returnAllTypes?: boolean + + /** + * Strip core API functions from the Query type, leaving only module-sourced functions (constructors, entrypoint proxies, etc.). + * + * Core types (Container, Directory, etc.) are kept so return types and method chaining still work. + */ + hideCore?: boolean +} + +export type ClientEnvOpts = { + /** + * Give the environment the same privileges as the caller: core API including host access, current module, and dependencies + */ + privileged?: boolean + + /** + * Allow new outputs to be declared and saved in the environment + */ + writable?: boolean +} + +export type ClientEnvFileOpts = { + /** + * Replace "${VAR}" or "$VAR" with the value of other vars + * + * @deprecated Variable expansion is now enabled by default + */ + expand?: boolean +} + +export type ClientFileOpts = { + /** + * Permissions of the new file. Example: 0600 + */ + permissions?: number +} + +export type ClientGitOpts = { + /** + * DEPRECATED: Set to true to keep .git directory. + * + * @deprecated Set to true to keep .git directory. + */ + keepGitDir?: boolean + + /** + * Set SSH known hosts + */ + sshKnownHosts?: string + + /** + * Set SSH auth socket + */ + sshAuthSocket?: Socket + + /** + * Username used to populate the password during basic HTTP Authorization + */ + httpAuthUsername?: string + + /** + * Secret used to populate the password during basic HTTP Authorization + */ + httpAuthToken?: Secret + + /** + * Secret used to populate the Authorization HTTP header + */ + httpAuthHeader?: Secret + + /** + * A service which must be started before the repo is fetched. + */ + experimentalServiceHost?: Service +} + +export type ClientHttpOpts = { + /** + * File name to use for the file. Defaults to the last part of the URL. + */ + name?: string + + /** + * Permissions to set on the file. + */ + permissions?: number + + /** + * Expected digest of the downloaded content (e.g., "sha256:..."). + */ + checksum?: string + + /** + * Secret used to populate the Authorization HTTP header + */ + authHeader?: Secret + + /** + * A service which must be started before the URL is fetched. + */ + experimentalServiceHost?: Service +} + +export type ClientLLMOpts = { + /** + * The model to converse with, e.g. "claude-sonnet-4-5" or "gpt-5.4". Defaults to the configured default model. + */ + model?: string + + /** + * The provider serving the model, e.g. "openai". Overrides the provider otherwise inferred from the model name — useful when the name matches no known pattern (e.g. a fine-tune), or matches the wrong one. + */ + provider?: string +} + +export type ClientModuleSourceOpts = { + /** + * The pinned version of the module source + */ + refPin?: string + + /** + * If true, do not attempt to find a module config file in a parent directory of the provided path. Only relevant for local module sources. + */ + disableFindUp?: boolean + + /** + * If true, do not error out if the provided ref string is a local path and does not exist yet. Useful when initializing new modules in directories that don't exist yet. + */ + allowNotExists?: boolean + + /** + * If set, error out if the ref string is not of the provided requireKind. + */ + requireKind?: ModuleSourceKind +} + +export type ClientSecretOpts = { + /** + * If set, the given string will be used as the cache key for this secret. This means that any secrets with the same cache key will be considered equivalent in terms of cache lookups, even if they have different URIs or plaintext values. + * + * For example, two secrets with the same cache key provided as secret env vars to other wise equivalent containers will result in the container withExecs hitting the cache for each other. + * + * If not set, the cache key for the secret will be derived from its plaintext value as looked up when the secret is constructed. + */ + cacheKey?: string +} + +export type ClientSshfsVolumeOpts = { + /** + * known_hosts material used to verify the remote host key. Required unless insecureSkipHostKeyCheck is true. + */ + knownHosts?: Secret + + /** + * Optional cache equivalence key. If set, volumes with the same cacheKey may be considered equivalent for cache lookups, still subject to their resource dependencies. + */ + cacheKey?: string + + /** + * Disable SSH host key verification. This is insecure and must be explicitly opted into. + */ + insecureSkipHostKeyCheck?: boolean + + /** + * Service to use as the SSHFS network endpoint while verifying the original host key. + */ + experimentalServiceHost?: Service +} + +/** + * Transport protocol to use for registry operations. + */ +export enum RegistryProtocol { + Http = "HTTP", + Https = "HTTPS", +} + +/** + * Utility function to convert a RegistryProtocol value to its name so + * it can be uses as argument to call a exposed function. + */ +export function RegistryProtocolValueToName(value: RegistryProtocol): string { + switch (value) { + case RegistryProtocol.Http: + return "HTTP" + case RegistryProtocol.Https: + return "HTTPS" + default: + return value + } +} + +/** + * Utility function to convert a RegistryProtocol name to its value so + * it can be properly used inside the module runtime. + */ +export function RegistryProtocolNameToValue(name: string): RegistryProtocol { + switch (name) { + case "HTTP": + return RegistryProtocol.Http + case "HTTPS": + return RegistryProtocol.Https + default: + return name as RegistryProtocol + } +} +/** + * Expected return type of an execution + */ +export enum ReturnType { + + /** + * Any execution (exit codes 0-127 and 192-255) + */ + Any = "ANY", + + /** + * A failed execution (exit codes 1-127 and 192-255) + */ + Failure = "FAILURE", + + /** + * A successful execution (exit code 0) + */ + Success = "SUCCESS", +} + +/** + * Utility function to convert a ReturnType value to its name so + * it can be uses as argument to call a exposed function. + */ +export function ReturnTypeValueToName(value: ReturnType): string { + switch (value) { + case ReturnType.Any: + return "ANY" + case ReturnType.Failure: + return "FAILURE" + case ReturnType.Success: + return "SUCCESS" + default: + return value + } +} + +/** + * Utility function to convert a ReturnType name to its value so + * it can be properly used inside the module runtime. + */ +export function ReturnTypeNameToValue(name: string): ReturnType { + switch (name) { + case "ANY": + return ReturnType.Any + case "FAILURE": + return ReturnType.Failure + case "SUCCESS": + return ReturnType.Success + default: + return name as ReturnType + } +} +export type ServiceEndpointOpts = { + /** + * The exposed port number for the endpoint + */ + port?: number + + /** + * Return a URL with the given scheme, eg. http for http:// + */ + scheme?: string +} + +export type ServiceStopOpts = { + /** + * Immediately kill the service without waiting for a graceful exit + */ + kill?: boolean +} + +export type ServiceTerminalOpts = { + cmd?: string[] +} + +export type ServiceUpOpts = { + /** + * List of frontend/backend port mappings to forward. + * + * Frontend is the port accepting traffic on the host, backend is the service port. + */ + ports?: PortForward[] + + /** + * Bind each tunnel port to a random port on the host. + */ + random?: boolean +} + +export type TypeDefWithEnumOpts = { + /** + * A doc string for the enum, if any + */ + description?: string + + /** + * The source map for the enum definition. + */ + sourceMap?: SourceMap +} + +export type TypeDefWithEnumMemberOpts = { + /** + * The value of the member in the enum + */ + value?: string + + /** + * A doc string for the member, if any + */ + description?: string + + /** + * The source map for the enum member definition. + */ + sourceMap?: SourceMap + + /** + * If deprecated, the reason or migration path. + */ + deprecated?: string +} + +export type TypeDefWithEnumValueOpts = { + /** + * A doc string for the value, if any + */ + description?: string + + /** + * The source map for the enum value definition. + */ + sourceMap?: SourceMap + + /** + * If deprecated, the reason or migration path. + */ + deprecated?: string +} + +export type TypeDefWithFieldOpts = { + /** + * A doc string for the field, if any + */ + description?: string + + /** + * The source map for the field definition. + */ + sourceMap?: SourceMap + + /** + * If deprecated, the reason or migration path. + */ + deprecated?: string +} + +export type TypeDefWithInterfaceOpts = { + description?: string + sourceMap?: SourceMap +} + +export type TypeDefWithObjectOpts = { + description?: string + sourceMap?: SourceMap + deprecated?: string +} + +export type TypeDefWithScalarOpts = { + description?: string +} + +/** + * Distinguishes the different kinds of TypeDefs. + */ +export enum TypeDefKind { + + /** + * A boolean value. + */ + Boolean = "BOOLEAN_KIND", + + /** + * A boolean value. + */ + BooleanKind = TypeDefKind.Boolean, + + /** + * A GraphQL enum type and its values + * + * Always paired with an EnumTypeDef. + */ + Enum = "ENUM_KIND", + + /** + * A GraphQL enum type and its values + * + * Always paired with an EnumTypeDef. + */ + EnumKind = TypeDefKind.Enum, + + /** + * A float value. + */ + Float = "FLOAT_KIND", + + /** + * A float value. + */ + FloatKind = TypeDefKind.Float, + + /** + * A graphql input type, used only when representing the core API via TypeDefs. + */ + Input = "INPUT_KIND", + + /** + * A graphql input type, used only when representing the core API via TypeDefs. + */ + InputKind = TypeDefKind.Input, + + /** + * An integer value. + */ + Integer = "INTEGER_KIND", + + /** + * An integer value. + */ + IntegerKind = TypeDefKind.Integer, + + /** + * Always paired with an InterfaceTypeDef. + * + * A named type of functions that can be matched+implemented by other objects+interfaces. + */ + Interface = "INTERFACE_KIND", + + /** + * Always paired with an InterfaceTypeDef. + * + * A named type of functions that can be matched+implemented by other objects+interfaces. + */ + InterfaceKind = TypeDefKind.Interface, + + /** + * Always paired with a ListTypeDef. + * + * A list of values all having the same type. + */ + List = "LIST_KIND", + + /** + * Always paired with a ListTypeDef. + * + * A list of values all having the same type. + */ + ListKind = TypeDefKind.List, + + /** + * Always paired with an ObjectTypeDef. + * + * A named type defined in the GraphQL schema, with fields and functions. + */ + Object = "OBJECT_KIND", + + /** + * Always paired with an ObjectTypeDef. + * + * A named type defined in the GraphQL schema, with fields and functions. + */ + ObjectKind = TypeDefKind.Object, + + /** + * A scalar value of any basic kind. + */ + Scalar = "SCALAR_KIND", + + /** + * A scalar value of any basic kind. + */ + ScalarKind = TypeDefKind.Scalar, + + /** + * A string value. + */ + String = "STRING_KIND", + + /** + * A string value. + */ + StringKind = TypeDefKind.String, + + /** + * A special kind used to signify that no value is returned. + * + * This is used for functions that have no return value. The outer TypeDef specifying this Kind is always Optional, as the Void is never actually represented. + */ + Void = "VOID_KIND", + + /** + * A special kind used to signify that no value is returned. + * + * This is used for functions that have no return value. The outer TypeDef specifying this Kind is always Optional, as the Void is never actually represented. + */ + VoidKind = TypeDefKind.Void, +} + +/** + * Utility function to convert a TypeDefKind value to its name so + * it can be uses as argument to call a exposed function. + */ +export function TypeDefKindValueToName(value: TypeDefKind): string { + switch (value) { + case TypeDefKind.Boolean: + return "BOOLEAN" + case TypeDefKind.Enum: + return "ENUM" + case TypeDefKind.Float: + return "FLOAT" + case TypeDefKind.Input: + return "INPUT" + case TypeDefKind.Integer: + return "INTEGER" + case TypeDefKind.Interface: + return "INTERFACE" + case TypeDefKind.List: + return "LIST" + case TypeDefKind.Object: + return "OBJECT" + case TypeDefKind.Scalar: + return "SCALAR" + case TypeDefKind.String: + return "STRING" + case TypeDefKind.Void: + return "VOID" + default: + return value + } +} + +/** + * Utility function to convert a TypeDefKind name to its value so + * it can be properly used inside the module runtime. + */ +export function TypeDefKindNameToValue(name: string): TypeDefKind { + switch (name) { + case "BOOLEAN": + return TypeDefKind.Boolean + case "ENUM": + return TypeDefKind.Enum + case "FLOAT": + return TypeDefKind.Float + case "INPUT": + return TypeDefKind.Input + case "INTEGER": + return TypeDefKind.Integer + case "INTERFACE": + return TypeDefKind.Interface + case "LIST": + return TypeDefKind.List + case "OBJECT": + return TypeDefKind.Object + case "SCALAR": + return TypeDefKind.Scalar + case "STRING": + return TypeDefKind.String + case "VOID": + return TypeDefKind.Void + default: + return name as TypeDefKind + } +} +/** + * The absence of a value. + * + * A Null Void is used as a placeholder for resolvers that do not return anything. + */ +export type Void = string & {__Void: never} + +export type WorkspaceChecksOpts = { + /** + * Only include checks matching the specified patterns + */ + include?: string[] + + /** + * Skip checks matching the specified patterns + */ + skip?: string[] + + /** + * When true, only return annotated check functions; exclude generate-as-checks + */ + noGenerate?: boolean + + /** + * When true, only return generate-as-checks; exclude annotated check functions + */ + onlyGenerate?: boolean +} + +export type WorkspaceConfigReadOpts = { + /** + * Dotted key path (e.g. modules.greeter.source). Empty for full config. + */ + key?: string +} + +export type WorkspaceDirectoryOpts = { + /** + * Exclude artifacts that match the given pattern (e.g., ["node_modules/", ".git*"]). + */ + exclude?: string[] + + /** + * Include only artifacts that match the given pattern (e.g., ["app/", "package.*"]). + */ + include?: string[] + + /** + * Apply .gitignore filter rules inside the directory. + */ + gitignore?: boolean +} + +export type WorkspaceFindUpOpts = { + /** + * Path to start the search from. Relative paths resolve from the workspace cwd; absolute paths resolve from the workspace root. + */ + from?: string +} + +export type WorkspaceGeneratorsOpts = { + /** + * Only include generators matching the specified patterns + */ + include?: string[] +} + +export type WorkspaceSearchOpts = { + /** + * Directory or file paths to search + */ + paths?: string[] + + /** + * Glob patterns to match (e.g., "*.md") + */ + globs?: string[] + + /** + * The text to match. + */ + pattern: string + + /** + * Interpret the pattern as a literal string instead of a regular expression. + */ + literal?: boolean + + /** + * Enable searching across multiple lines. + */ + multiline?: boolean + + /** + * Allow the . pattern to match newlines in multiline mode. + */ + dotall?: boolean + + /** + * Enable case-insensitive matching. + */ + insensitive?: boolean + + /** + * Honor .gitignore, .ignore, and .rgignore files. + */ + skipIgnored?: boolean + + /** + * Skip hidden files (files starting with .). + */ + skipHidden?: boolean + + /** + * Only return matching files, not lines and content + */ + filesOnly?: boolean + + /** + * Limit the number of results to return + */ + limit?: number +} + +export type WorkspaceServicesOpts = { + /** + * Only include services matching the specified patterns + */ + include?: string[] +} + +export type WorkspaceWithConfigEnvOpts = { + /** + * Write to the workspace config directory at the workspace cwd. + */ + here?: boolean +} + +export type WorkspaceWithConfigValueOpts = { + /** + * List value to set. Elements are stored verbatim, with no auto-detection. Mutually exclusive with value. + */ + values?: string[] + + /** + * Write to the workspace config directory at the workspace cwd. + */ + here?: boolean +} + +export type WorkspaceWithInitClientOpts = { + /** + * SDK-specific init arguments. + */ + args?: JSON + + /** + * Write to the workspace config directory at the workspace cwd. + */ + here?: boolean +} + +export type WorkspaceWithInitModuleOpts = { + /** + * Workspace-relative path for the new module. + */ + path?: string + + /** + * Source subpath within the new module. + */ + source?: string + + /** + * Additional include patterns for the module. + */ + include?: string[] + + /** + * SDK-specific init arguments. + */ + args?: JSON + + /** + * Write to the workspace config directory at the workspace cwd. + */ + here?: boolean +} + +export type WorkspaceWithModuleOpts = { + /** + * Override name for the installed module entry. + */ + name?: string + + /** + * Write to the workspace config directory at the workspace cwd. + */ + here?: boolean +} + +export type WorkspaceWithNewFileOpts = { + /** + * Permissions of the new file. + */ + permissions?: number +} + +export type WorkspaceWithSdkOpts = { + /** + * Override name for the installed SDK entry. + */ + name?: string + + /** + * Write to the workspace config directory at the workspace cwd. + */ + here?: boolean + + /** + * User-facing SDK name to persist under `[modules..as-sdk] name = ...`. + */ + asSdkName?: string +} + +export type WorkspaceWithoutConfigEnvOpts = { + /** + * Write to the workspace config directory at the workspace cwd. + */ + here?: boolean +} + +export type WorkspaceWithoutConfigValueOpts = { + /** + * Write to the workspace config directory at the workspace cwd. + */ + here?: boolean +} + +export type WorkspaceWithoutModuleOpts = { + /** + * Write to the workspace config directory at the workspace cwd. + */ + here?: boolean +} + +export type WorkspaceWithoutSdkOpts = { + /** + * Write to the workspace config directory at the workspace cwd. + */ + here?: boolean +} + +export type __DirectiveArgsOpts = { + includeDeprecated?: boolean +} + +export type __FieldArgsOpts = { + includeDeprecated?: boolean +} + +export type __TypeEnumValuesOpts = { + includeDeprecated?: boolean +} + +export type __TypeFieldsOpts = { + includeDeprecated?: boolean +} + +export type __TypeInputFieldsOpts = { + includeDeprecated?: boolean +} + + +/** + * A standardized address to load containers, directories, secrets, and other object types. Address format depends on the type, and is validated at type selection. + */ +export class Address extends BaseClient { + private readonly _id?: ID = undefined + private readonly _value?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _value?: string, + ) { + super(ctx) + + this._id = _id + this._value = _value + } + + /** + * A unique identifier for this Address. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Load a container from the address. + */ + container = (): Container => { + + const ctx = this._ctx.select( + "container", + ) + return new Container(ctx) + } + + /** + * Load a directory from the address. + */ + directory = (opts?: AddressDirectoryOpts): Directory => { + + const ctx = this._ctx.select( + "directory", + { ...opts }, + ) + return new Directory(ctx) + } + + /** + * Load a file from the address. + */ + file = (opts?: AddressFileOpts): File => { + + const ctx = this._ctx.select( + "file", + { ...opts }, + ) + return new File(ctx) + } + + /** + * Load a git ref (branch, tag or commit) from the address. + */ + gitRef = (): GitRef => { + + const ctx = this._ctx.select( + "gitRef", + ) + return new GitRef(ctx) + } + + /** + * Load a git repository from the address. + */ + gitRepository = (): GitRepository => { + + const ctx = this._ctx.select( + "gitRepository", + ) + return new GitRepository(ctx) + } + + /** + * Load a secret from the address. + */ + secret = (): Secret => { + + const ctx = this._ctx.select( + "secret", + ) + return new Secret(ctx) + } + + /** + * Load a service from the address. + */ + service = (): Service => { + + const ctx = this._ctx.select( + "service", + ) + return new Service(ctx) + } + + /** + * Load a local socket from the address. + */ + socket = (): Socket => { + + const ctx = this._ctx.select( + "socket", + ) + return new Socket(ctx) + } + + /** + * The address value + */ + value = async (): Promise => { + if (this._value) { + return this._value + } + + const ctx = this._ctx.select( + "value", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Load a volume from the address. + */ + volume = (): Volume => { + + const ctx = this._ctx.select( + "volume", + ) + return new Volume(ctx) + } +} + + +export class Binding extends BaseClient { + private readonly _id?: ID = undefined + private readonly _asString?: string = undefined + private readonly _digest?: string = undefined + private readonly _isNull?: boolean = undefined + private readonly _name?: string = undefined + private readonly _typeName?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _asString?: string, + _digest?: string, + _isNull?: boolean, + _name?: string, + _typeName?: string, + ) { + super(ctx) + + this._id = _id + this._asString = _asString + this._digest = _digest + this._isNull = _isNull + this._name = _name + this._typeName = _typeName + } + + /** + * A unique identifier for this Binding. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Retrieve the binding value, as type Address + */ + asAddress = (): Address => { + + const ctx = this._ctx.select( + "asAddress", + ) + return new Address(ctx) + } + + /** + * Retrieve the binding value, as type CacheVolume + */ + asCacheVolume = (): CacheVolume => { + + const ctx = this._ctx.select( + "asCacheVolume", + ) + return new CacheVolume(ctx) + } + + /** + * Retrieve the binding value, as type Changeset + */ + asChangeset = (): Changeset => { + + const ctx = this._ctx.select( + "asChangeset", + ) + return new Changeset(ctx) + } + + /** + * Retrieve the binding value, as type Check + */ + asCheck = (): Check => { + + const ctx = this._ctx.select( + "asCheck", + ) + return new Check(ctx) + } + + /** + * Retrieve the binding value, as type CheckGroup + */ + asCheckGroup = (): CheckGroup => { + + const ctx = this._ctx.select( + "asCheckGroup", + ) + return new CheckGroup(ctx) + } + + /** + * Retrieve the binding value, as type Cloud + */ + asCloud = (): Cloud => { + + const ctx = this._ctx.select( + "asCloud", + ) + return new Cloud(ctx) + } + + /** + * Retrieve the binding value, as type Container + */ + asContainer = (): Container => { + + const ctx = this._ctx.select( + "asContainer", + ) + return new Container(ctx) + } + + /** + * Retrieve the binding value, as type CurrentModuleAsSDK + */ + asCurrentModuleAsSDK = (): CurrentModuleAsSDK => { + + const ctx = this._ctx.select( + "asCurrentModuleAsSDK", + ) + return new CurrentModuleAsSDK(ctx) + } + + /** + * Retrieve the binding value, as type CurrentModuleAsSDKClient + */ + asCurrentModuleAsSDKClient = (): CurrentModuleAsSDKClient => { + + const ctx = this._ctx.select( + "asCurrentModuleAsSDKClient", + ) + return new CurrentModuleAsSDKClient(ctx) + } + + /** + * Retrieve the binding value, as type CurrentModuleAsSDKModule + */ + asCurrentModuleAsSDKModule = (): CurrentModuleAsSDKModule => { + + const ctx = this._ctx.select( + "asCurrentModuleAsSDKModule", + ) + return new CurrentModuleAsSDKModule(ctx) + } + + /** + * Retrieve the binding value, as type DiffStat + */ + asDiffStat = (): DiffStat => { + + const ctx = this._ctx.select( + "asDiffStat", + ) + return new DiffStat(ctx) + } + + /** + * Retrieve the binding value, as type Directory + */ + asDirectory = (): Directory => { + + const ctx = this._ctx.select( + "asDirectory", + ) + return new Directory(ctx) + } + + /** + * Retrieve the binding value, as type Env + */ + asEnv = (): Env => { + + const ctx = this._ctx.select( + "asEnv", + ) + return new Env(ctx) + } + + /** + * Retrieve the binding value, as type EnvFile + */ + asEnvFile = (): EnvFile => { + + const ctx = this._ctx.select( + "asEnvFile", + ) + return new EnvFile(ctx) + } + + /** + * Retrieve the binding value, as type File + */ + asFile = (): File => { + + const ctx = this._ctx.select( + "asFile", + ) + return new File(ctx) + } + + /** + * Retrieve the binding value, as type Generator + */ + asGenerator = (): Generator => { + + const ctx = this._ctx.select( + "asGenerator", + ) + return new Generator(ctx) + } + + /** + * Retrieve the binding value, as type GeneratorGroup + */ + asGeneratorGroup = (): GeneratorGroup => { + + const ctx = this._ctx.select( + "asGeneratorGroup", + ) + return new GeneratorGroup(ctx) + } + + /** + * Retrieve the binding value, as type GitRef + */ + asGitRef = (): GitRef => { + + const ctx = this._ctx.select( + "asGitRef", + ) + return new GitRef(ctx) + } + + /** + * Retrieve the binding value, as type GitRepository + */ + asGitRepository = (): GitRepository => { + + const ctx = this._ctx.select( + "asGitRepository", + ) + return new GitRepository(ctx) + } + + /** + * Retrieve the binding value, as type HTTPState + */ + asHTTPState = (): HTTPState => { + + const ctx = this._ctx.select( + "asHTTPState", + ) + return new HTTPState(ctx) + } + + /** + * Retrieve the binding value, as type JSONValue + */ + asJSONValue = (): JSONValue => { + + const ctx = this._ctx.select( + "asJSONValue", + ) + return new JSONValue(ctx) + } + + /** + * Retrieve the binding value, as type LLMContentBlock + */ + asLLMContentBlock = (): LLMContentBlock => { + + const ctx = this._ctx.select( + "asLLMContentBlock", + ) + return new LLMContentBlock(ctx) + } + + /** + * Retrieve the binding value, as type LLMMessage + */ + asLLMMessage = (): LLMMessage => { + + const ctx = this._ctx.select( + "asLLMMessage", + ) + return new LLMMessage(ctx) + } + + /** + * Retrieve the binding value, as type Module + */ + asModule = (): Module_ => { + + const ctx = this._ctx.select( + "asModule", + ) + return new Module_(ctx) + } + + /** + * Retrieve the binding value, as type ModuleConfigClient + */ + asModuleConfigClient = (): ModuleConfigClient => { + + const ctx = this._ctx.select( + "asModuleConfigClient", + ) + return new ModuleConfigClient(ctx) + } + + /** + * Retrieve the binding value, as type ModuleSource + */ + asModuleSource = (): ModuleSource => { + + const ctx = this._ctx.select( + "asModuleSource", + ) + return new ModuleSource(ctx) + } + + /** + * Retrieve the binding value, as type Schema + */ + asSchema = (): Schema => { + + const ctx = this._ctx.select( + "asSchema", + ) + return new Schema(ctx) + } + + /** + * Retrieve the binding value, as type SearchResult + */ + asSearchResult = (): SearchResult => { + + const ctx = this._ctx.select( + "asSearchResult", + ) + return new SearchResult(ctx) + } + + /** + * Retrieve the binding value, as type SearchSubmatch + */ + asSearchSubmatch = (): SearchSubmatch => { + + const ctx = this._ctx.select( + "asSearchSubmatch", + ) + return new SearchSubmatch(ctx) + } + + /** + * Retrieve the binding value, as type Secret + */ + asSecret = (): Secret => { + + const ctx = this._ctx.select( + "asSecret", + ) + return new Secret(ctx) + } + + /** + * Retrieve the binding value, as type Service + */ + asService = (): Service => { + + const ctx = this._ctx.select( + "asService", + ) + return new Service(ctx) + } + + /** + * Retrieve the binding value, as type Socket + */ + asSocket = (): Socket => { + + const ctx = this._ctx.select( + "asSocket", + ) + return new Socket(ctx) + } + + /** + * Retrieve the binding value, as type Stat + */ + asStat = (): Stat => { + + const ctx = this._ctx.select( + "asStat", + ) + return new Stat(ctx) + } + + /** + * Returns the binding's string value + */ + asString = async (): Promise => { + if (this._asString) { + return this._asString + } + + const ctx = this._ctx.select( + "asString", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Retrieve the binding value, as type Up + */ + asUp = (): Up => { + + const ctx = this._ctx.select( + "asUp", + ) + return new Up(ctx) + } + + /** + * Retrieve the binding value, as type UpGroup + */ + asUpGroup = (): UpGroup => { + + const ctx = this._ctx.select( + "asUpGroup", + ) + return new UpGroup(ctx) + } + + /** + * Retrieve the binding value, as type Volume + */ + asVolume = (): Volume => { + + const ctx = this._ctx.select( + "asVolume", + ) + return new Volume(ctx) + } + + /** + * Retrieve the binding value, as type Workspace + */ + asWorkspace = (): Workspace => { + + const ctx = this._ctx.select( + "asWorkspace", + ) + return new Workspace(ctx) + } + + /** + * Retrieve the binding value, as type WorkspaceGit + */ + asWorkspaceGit = (): WorkspaceGit => { + + const ctx = this._ctx.select( + "asWorkspaceGit", + ) + return new WorkspaceGit(ctx) + } + + /** + * Retrieve the binding value, as type WorkspaceMigration + */ + asWorkspaceMigration = (): WorkspaceMigration => { + + const ctx = this._ctx.select( + "asWorkspaceMigration", + ) + return new WorkspaceMigration(ctx) + } + + /** + * Retrieve the binding value, as type WorkspaceMigrationStep + */ + asWorkspaceMigrationStep = (): WorkspaceMigrationStep => { + + const ctx = this._ctx.select( + "asWorkspaceMigrationStep", + ) + return new WorkspaceMigrationStep(ctx) + } + + /** + * Retrieve the binding value, as type WorkspaceModule + */ + asWorkspaceModule = (): WorkspaceModule => { + + const ctx = this._ctx.select( + "asWorkspaceModule", + ) + return new WorkspaceModule(ctx) + } + + /** + * Retrieve the binding value, as type WorkspaceModuleSetting + */ + asWorkspaceModuleSetting = (): WorkspaceModuleSetting => { + + const ctx = this._ctx.select( + "asWorkspaceModuleSetting", + ) + return new WorkspaceModuleSetting(ctx) + } + + /** + * Retrieve the binding value, as type WorkspaceSDK + */ + asWorkspaceSDK = (): WorkspaceSDK => { + + const ctx = this._ctx.select( + "asWorkspaceSDK", + ) + return new WorkspaceSDK(ctx) + } + + /** + * Returns the digest of the binding value + */ + digest = async (): Promise => { + if (this._digest) { + return this._digest + } + + const ctx = this._ctx.select( + "digest", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Returns true if the binding is null + */ + isNull = async (): Promise => { + if (this._isNull) { + return this._isNull + } + + const ctx = this._ctx.select( + "isNull", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Returns the binding name + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Returns the binding type + */ + typeName = async (): Promise => { + if (this._typeName) { + return this._typeName + } + + const ctx = this._ctx.select( + "typeName", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + + + + + + + +/** + * A directory whose contents persist across runs. + */ +export class CacheVolume extends BaseClient { + private readonly _id?: ID = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + ) { + super(ctx) + + this._id = _id + } + + /** + * A unique identifier for this CacheVolume. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * A comparison between two directories representing changes that can be applied. + */ +export class Changeset extends BaseClient { + private readonly _id?: ID = undefined + private readonly _export?: string = undefined + private readonly _isEmpty?: boolean = undefined + private readonly _sync?: ID = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _export?: string, + _isEmpty?: boolean, + _sync?: ID, + ) { + super(ctx) + + this._id = _id + this._export = _export + this._isEmpty = _isEmpty + this._sync = _sync + } + + /** + * A unique identifier for this Changeset. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Files and directories that were added in the newer directory. + */ + addedPaths = async (): Promise => { + const ctx = this._ctx.select( + "addedPaths", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The newer/upper snapshot. + */ + after = (): Directory => { + + const ctx = this._ctx.select( + "after", + ) + return new Directory(ctx) + } + + /** + * Return a Git-compatible patch of the changes + */ + asPatch = (): File => { + + const ctx = this._ctx.select( + "asPatch", + ) + return new File(ctx) + } + + /** + * The older/lower snapshot to compare against. + */ + before = (): Directory => { + + const ctx = this._ctx.select( + "before", + ) + return new Directory(ctx) + } + + /** + * Structured per-path diff statistics (kind and line counts) for this changeset. + */ + diffStats = async (): Promise => { + type diffStats = { + id: ID + } + + const ctx = this._ctx.select( + "diffStats", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new DiffStat(ctx.copy().selectNode(r.id, "DiffStat"))) + } + + /** + * Applies the diff represented by this changeset to a path on the host. + * @param path Location of the copied directory (e.g., "logs/"). + */ + export = async (path: string): Promise => { + if (this._export) { + return this._export + } + + const ctx = this._ctx.select( + "export", + { path}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Returns true if the changeset is empty (i.e. there are no changes). + */ + isEmpty = async (): Promise => { + if (this._isEmpty) { + return this._isEmpty + } + + const ctx = this._ctx.select( + "isEmpty", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Return a snapshot containing only the created and modified files + */ + layer = (): Directory => { + + const ctx = this._ctx.select( + "layer", + ) + return new Directory(ctx) + } + + /** + * Files and directories that existed before and were updated in the newer directory. + */ + modifiedPaths = async (): Promise => { + const ctx = this._ctx.select( + "modifiedPaths", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Files and directories that were removed. Directories are indicated by a trailing slash, and their child paths are not included. + */ + removedPaths = async (): Promise => { + const ctx = this._ctx.select( + "removedPaths", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Force evaluation in the engine. + */ + sync = async (): Promise => { + const ctx = this._ctx.select( + "sync", + ) + + const response: Awaited = await ctx.execute() + + + return new Changeset(ctx.copy().selectNode(response, "Changeset")) + } + + /** + * Add changes to an existing changeset + * + * By default the operation will fail in case of conflicts, for instance a file modified in both changesets. The behavior can be adjusted using onConflict argument + * @param changes Changes to merge into the actual changeset + * @param opts.onConflict What to do on a merge conflict + */ + withChangeset = (changes: Changeset, opts?: ChangesetWithChangesetOpts): Changeset => { + const metadata = { + onConflict: { is_enum: true, value_to_name: ChangesetMergeConflictValueToName }, + } + + + const ctx = this._ctx.select( + "withChangeset", + { changes, ...opts, __metadata: metadata }, + ) + return new Changeset(ctx) + } + + /** + * Add changes from multiple changesets using git octopus merge strategy + * + * This is more efficient than chaining multiple withChangeset calls when merging many changesets. + * + * Only FAIL and FAIL_EARLY conflict strategies are supported (octopus merge cannot use -X ours/theirs). + * @param changes List of changesets to merge into the actual changeset + * @param opts.onConflict What to do on a merge conflict + */ + withChangesets = (changes: Changeset[], opts?: ChangesetWithChangesetsOpts): Changeset => { + const metadata = { + onConflict: { is_enum: true, value_to_name: ChangesetsMergeConflictValueToName }, + } + + + const ctx = this._ctx.select( + "withChangesets", + { changes, ...opts, __metadata: metadata }, + ) + return new Changeset(ctx) + } + + /** + * Call the provided function with current Changeset. + * + * This is useful for reusability and readability by not breaking the calling chain. + */ + with = (arg: (param: Changeset) => Changeset) => { + return arg(this) + } +} + + + + + + +export class Check extends BaseClient { + private readonly _id?: ID = undefined + private readonly _checkType?: string = undefined + private readonly _completed?: boolean = undefined + private readonly _description?: string = undefined + private readonly _name?: string = undefined + private readonly _passed?: boolean = undefined + private readonly _resultEmoji?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _checkType?: string, + _completed?: boolean, + _description?: string, + _name?: string, + _passed?: boolean, + _resultEmoji?: string, + ) { + super(ctx) + + this._id = _id + this._checkType = _checkType + this._completed = _completed + this._description = _description + this._name = _name + this._passed = _passed + this._resultEmoji = _resultEmoji + } + + /** + * A unique identifier for this Check. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The type of check: 'check' for annotated checks, 'generate' for generate-as-checks + */ + checkType = async (): Promise => { + if (this._checkType) { + return this._checkType + } + + const ctx = this._ctx.select( + "checkType", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Whether the check completed + */ + completed = async (): Promise => { + if (this._completed) { + return this._completed + } + + const ctx = this._ctx.select( + "completed", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The description of the check + */ + description = async (): Promise => { + if (this._description) { + return this._description + } + + const ctx = this._ctx.select( + "description", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * If the check failed, this is the error + */ + error = (): Error => { + + const ctx = this._ctx.select( + "error", + ) + return new Error(ctx) + } + + /** + * Return the fully qualified name of the check + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The original module in which the check has been defined + */ + originalModule = (): Module_ => { + + const ctx = this._ctx.select( + "originalModule", + ) + return new Module_(ctx) + } + + /** + * Whether the check passed + */ + passed = async (): Promise => { + if (this._passed) { + return this._passed + } + + const ctx = this._ctx.select( + "passed", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The path of the check within its module + */ + path = async (): Promise => { + const ctx = this._ctx.select( + "path", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * An emoji representing the result of the check + */ + resultEmoji = async (): Promise => { + if (this._resultEmoji) { + return this._resultEmoji + } + + const ctx = this._ctx.select( + "resultEmoji", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Execute the check + */ + run = (): Check => { + + const ctx = this._ctx.select( + "run", + ) + return new Check(ctx) + } + + /** + * Call the provided function with current Check. + * + * This is useful for reusability and readability by not breaking the calling chain. + */ + with = (arg: (param: Check) => Check) => { + return arg(this) + } +} + + +export class CheckGroup extends BaseClient { + private readonly _id?: ID = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + ) { + super(ctx) + + this._id = _id + } + + /** + * A unique identifier for this CheckGroup. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Return a list of individual checks and their details + */ + list = async (): Promise => { + type list = { + id: ID + } + + const ctx = this._ctx.select( + "list", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new Check(ctx.copy().selectNode(r.id, "Check"))) + } + + /** + * Generate a markdown report + */ + report = (): File => { + + const ctx = this._ctx.select( + "report", + ) + return new File(ctx) + } + + /** + * Execute all selected checks + * @param opts.failFast If true, stop running checks as soon as any check fails. + */ + run = (opts?: CheckGroupRunOpts): CheckGroup => { + + const ctx = this._ctx.select( + "run", + { ...opts }, + ) + return new CheckGroup(ctx) + } + + /** + * Call the provided function with current CheckGroup. + * + * This is useful for reusability and readability by not breaking the calling chain. + */ + with = (arg: (param: CheckGroup) => CheckGroup) => { + return arg(this) + } +} + +/** + * An internal persistent filesync mirror. + */ +export class ClientFilesyncMirror extends BaseClient { + private readonly _id?: ID = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + ) { + super(ctx) + + this._id = _id + } + + /** + * A unique identifier for this ClientFilesyncMirror. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * Dagger Cloud configuration and state + */ +export class Cloud extends BaseClient { + private readonly _id?: ID = undefined + private readonly _traceURL?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _traceURL?: string, + ) { + super(ctx) + + this._id = _id + this._traceURL = _traceURL + } + + /** + * A unique identifier for this Cloud. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The trace URL for the current session + */ + traceURL = async (): Promise => { + if (this._traceURL) { + return this._traceURL + } + + const ctx = this._ctx.select( + "traceURL", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * An OCI-compatible container, also known as a Docker container. + */ +export class Container extends BaseClient { + private readonly _id?: ID = undefined + private readonly _combinedOutput?: string = undefined + private readonly _envVariable?: string = undefined + private readonly _exists?: boolean = undefined + private readonly _exitCode?: number = undefined + private readonly _export?: string = undefined + private readonly _exportImage?: Void = undefined + private readonly _imageRef?: string = undefined + private readonly _label?: string = undefined + private readonly _platform?: Platform = undefined + private readonly _publish?: string = undefined + private readonly _stderr?: string = undefined + private readonly _stdout?: string = undefined + private readonly _sync?: ID = undefined + private readonly _up?: Void = undefined + private readonly _user?: string = undefined + private readonly _workdir?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _combinedOutput?: string, + _envVariable?: string, + _exists?: boolean, + _exitCode?: number, + _export?: string, + _exportImage?: Void, + _imageRef?: string, + _label?: string, + _platform?: Platform, + _publish?: string, + _stderr?: string, + _stdout?: string, + _sync?: ID, + _up?: Void, + _user?: string, + _workdir?: string, + ) { + super(ctx) + + this._id = _id + this._combinedOutput = _combinedOutput + this._envVariable = _envVariable + this._exists = _exists + this._exitCode = _exitCode + this._export = _export + this._exportImage = _exportImage + this._imageRef = _imageRef + this._label = _label + this._platform = _platform + this._publish = _publish + this._stderr = _stderr + this._stdout = _stdout + this._sync = _sync + this._up = _up + this._user = _user + this._workdir = _workdir + } + + /** + * A unique identifier for this Container. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Turn the container into a Service. + * + * Be sure to set any exposed ports before this conversion. + * @param opts.args Command to run instead of the container's default command (e.g., ["go", "run", "main.go"]). + * + * If empty, the container's default command is used. + * @param opts.useEntrypoint If the container has an entrypoint, prepend it to the args. + * @param opts.experimentalPrivilegedNesting Provides Dagger access to the executed command. + * @param opts.insecureRootCapabilities Execute the command with all root capabilities. This is similar to running a command with "sudo" or executing "docker run" with the "--privileged" flag. Containerization does not provide any security guarantees when using this option. It should only be used when absolutely necessary and only with trusted commands. + * @param opts.expand Replace "${VAR}" or "$VAR" in the args according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + * @param opts.noInit If set, skip the automatic init process injected into containers by default. + * + * This should only be used if the user requires that their exec process be the pid 1 process in the container. Otherwise it may result in unexpected behavior. + */ + asService = (opts?: ContainerAsServiceOpts): Service => { + + const ctx = this._ctx.select( + "asService", + { ...opts }, + ) + return new Service(ctx) + } + + /** + * Package the container state as an OCI image, and return it as a tar archive + * @param opts.platformVariants Identifiers for other platform specific containers. + * + * Used for multi-platform images. + * @param opts.forcedCompression Force each layer of the image to use the specified compression algorithm. + * + * If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. + * @param opts.mediaTypes Use the specified media types for the image's layers. + * + * Defaults to OCI, which is largely compatible with most recent container runtimes, but Docker may be needed for older runtimes without OCI support. + */ + asTarball = (opts?: ContainerAsTarballOpts): File => { + const metadata = { + forcedCompression: { is_enum: true, value_to_name: ImageLayerCompressionValueToName }, + mediaTypes: { is_enum: true, value_to_name: ImageMediaTypesValueToName }, + } + + + const ctx = this._ctx.select( + "asTarball", + { ...opts, __metadata: metadata }, + ) + return new File(ctx) + } + + /** + * The combined buffered standard output and standard error stream of the last executed command + * + * Returns an error if no command was executed + */ + combinedOutput = async (): Promise => { + if (this._combinedOutput) { + return this._combinedOutput + } + + const ctx = this._ctx.select( + "combinedOutput", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Return the container's default arguments. + */ + defaultArgs = async (): Promise => { + const ctx = this._ctx.select( + "defaultArgs", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Retrieve a directory from the container's root filesystem + * + * Mounts are included. + * @param path The path of the directory to retrieve (e.g., "./src"). + * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + directory = (path: string, opts?: ContainerDirectoryOpts): Directory => { + + const ctx = this._ctx.select( + "directory", + { path, ...opts }, + ) + return new Directory(ctx) + } + + /** + * Retrieves this container's configured docker healthcheck. + */ + dockerHealthcheck = (): HealthcheckConfig => { + + const ctx = this._ctx.select( + "dockerHealthcheck", + ) + return new HealthcheckConfig(ctx) + } + + /** + * Return the container's OCI entrypoint. + */ + entrypoint = async (): Promise => { + const ctx = this._ctx.select( + "entrypoint", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Retrieves the value of the specified persistent environment variable. + * @param name The name of the environment variable to retrieve (e.g., "PATH"). + */ + envVariable = async (name: string): Promise => { + if (this._envVariable) { + return this._envVariable + } + + const ctx = this._ctx.select( + "envVariable", + { name}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Retrieves the list of persistent environment variables configured on the container. + */ + envVariables = async (): Promise => { + type envVariables = { + id: ID + } + + const ctx = this._ctx.select( + "envVariables", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new EnvVariable(ctx.copy().selectNode(r.id, "EnvVariable"))) + } + + /** + * check if a file or directory exists + * @param path Path to check (e.g., "/file.txt"). + * @param opts.expectedType If specified, also validate the type of file (e.g. "REGULAR_TYPE", "DIRECTORY_TYPE", or "SYMLINK_TYPE"). + * @param opts.doNotFollowSymlinks If specified, do not follow symlinks. + * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + exists = async (path: string, + opts?: ContainerExistsOpts): Promise => { + if (this._exists) { + return this._exists + } + + const metadata = { + expectedType: { is_enum: true, value_to_name: ExistsTypeValueToName }, + } + + const ctx = this._ctx.select( + "exists", + { path, ...opts, __metadata: metadata}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The exit code of the last executed command + * + * Returns an error if no command was executed + */ + exitCode = async (): Promise => { + if (this._exitCode) { + return this._exitCode + } + + const ctx = this._ctx.select( + "exitCode", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * EXPERIMENTAL API! Subject to change/removal at any time. + * + * Configures all available GPUs on the host to be accessible to this container. + * + * This currently works for Nvidia devices only. + */ + experimentalWithAllGPUs = (): Container => { + + const ctx = this._ctx.select( + "experimentalWithAllGPUs", + ) + return new Container(ctx) + } + + /** + * EXPERIMENTAL API! Subject to change/removal at any time. + * + * Configures the provided list of devices to be accessible to this container. + * + * This currently works for Nvidia devices only. + * @param devices List of devices to be accessible to this container. + */ + experimentalWithGPU = (devices: string[]): Container => { + + const ctx = this._ctx.select( + "experimentalWithGPU", + { devices }, + ) + return new Container(ctx) + } + + /** + * Writes the container as an OCI tarball to the destination file path on the host. + * + * It can also export platform variants. + * @param path Host's destination path (e.g., "./tarball"). + * + * Path can be relative to the engine's workdir or absolute. + * @param opts.platformVariants Identifiers for other platform specific containers. + * + * Used for multi-platform image. + * @param opts.forcedCompression Force each layer of the exported image to use the specified compression algorithm. + * + * If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. + * @param opts.mediaTypes Use the specified media types for the exported image's layers. + * + * Defaults to OCI, which is largely compatible with most recent container runtimes, but Docker may be needed for older runtimes without OCI support. + * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + export = async (path: string, + opts?: ContainerExportOpts): Promise => { + if (this._export) { + return this._export + } + + const metadata = { + forcedCompression: { is_enum: true, value_to_name: ImageLayerCompressionValueToName }, + mediaTypes: { is_enum: true, value_to_name: ImageMediaTypesValueToName }, + } + + const ctx = this._ctx.select( + "export", + { path, ...opts, __metadata: metadata}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Exports the container as an image to the host's container image store. + * @param name Name of image to export to in the host's store + * @param opts.platformVariants Identifiers for other platform specific containers. + * + * Used for multi-platform image. + * @param opts.forcedCompression Force each layer of the exported image to use the specified compression algorithm. + * + * If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. + * @param opts.mediaTypes Use the specified media types for the exported image's layers. + * + * Defaults to OCI, which is largely compatible with most recent container runtimes, but Docker may be needed for older runtimes without OCI support. + */ + exportImage = async (name: string, + opts?: ContainerExportImageOpts): Promise => { + if (this._exportImage) { + return + } + + const metadata = { + forcedCompression: { is_enum: true, value_to_name: ImageLayerCompressionValueToName }, + mediaTypes: { is_enum: true, value_to_name: ImageMediaTypesValueToName }, + } + + const ctx = this._ctx.select( + "exportImage", + { name, ...opts, __metadata: metadata}, + ) + + await ctx.execute() + + + } + + /** + * Retrieves the list of exposed ports. + * + * This includes ports already exposed by the image, even if not explicitly added with dagger. + */ + exposedPorts = async (): Promise => { + type exposedPorts = { + id: ID + } + + const ctx = this._ctx.select( + "exposedPorts", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new Port(ctx.copy().selectNode(r.id, "Port"))) + } + + /** + * Retrieves a file at the given path. + * + * Mounts are included. + * @param path The path of the file to retrieve (e.g., "./README.md"). + * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo.txt"). + */ + file = (path: string, opts?: ContainerFileOpts): File => { + + const ctx = this._ctx.select( + "file", + { path, ...opts }, + ) + return new File(ctx) + } + + /** + * Download a container image, and apply it to the container state. All previous state will be lost. + * @param address Address of the container image to download, in standard OCI ref format. Example:"registry.dagger.io/engine:latest" + * @param opts.registryService Service to use as the registry endpoint for the image address. + * + * The service will be started only for this pull. + * @param opts.protocol Protocol to use for registry communication. + * + * Defaults to "HTTPS". Use "HTTP" only for plain HTTP registries. + * @param opts.insecureSkipTLSVerify Allow HTTPS registry communication without verifying the server certificate. + */ + from = (address: string, opts?: ContainerFromOpts): Container => { + const metadata = { + protocol: { is_enum: true, value_to_name: RegistryProtocolValueToName }, + } + + + const ctx = this._ctx.select( + "from", + { address, ...opts, __metadata: metadata }, + ) + return new Container(ctx) + } + + /** + * The unique image reference which can only be retrieved immediately after the 'Container.From' call. + */ + imageRef = async (): Promise => { + if (this._imageRef) { + return this._imageRef + } + + const ctx = this._ctx.select( + "imageRef", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Reads the container from an OCI tarball. + * @param source File to read the container from. + * @param opts.tag Identifies the tag to import from the archive, if the archive bundles multiple tags. + */ + import_ = (source: File, opts?: ContainerImportOpts): Container => { + + const ctx = this._ctx.select( + "import", + { source, ...opts }, + ) + return new Container(ctx) + } + + /** + * Retrieves the value of the specified label. + * @param name The name of the label (e.g., "org.opencontainers.artifact.created"). + */ + label = async (name: string): Promise => { + if (this._label) { + return this._label + } + + const ctx = this._ctx.select( + "label", + { name}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Retrieves the list of labels passed to container. + */ + labels = async (): Promise => { + type labels = { + id: ID + } + + const ctx = this._ctx.select( + "labels", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new Label(ctx.copy().selectNode(r.id, "Label"))) + } + + /** + * Returns the image layer or configuration blob with the given digest as a File. + * @param id Digest of the layer or configuration blob (e.g. "sha256:abc123..."). + * @param opts.forcedCompression Force each layer of the image to use the specified compression algorithm. + * + * If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. + * @param opts.mediaTypes Media types to use for image layers. Defaults to OCI. + */ + layer = (id: string, opts?: ContainerLayerOpts): File => { + const metadata = { + forcedCompression: { is_enum: true, value_to_name: ImageLayerCompressionValueToName }, + mediaTypes: { is_enum: true, value_to_name: ImageMediaTypesValueToName }, + } + + + const ctx = this._ctx.select( + "layer", + { id, ...opts, __metadata: metadata }, + ) + return new File(ctx) + } + + /** + * Computes and returns the manifest for this container as a File. + * @param opts.forcedCompression Force each layer of the image to use the specified compression algorithm. + * + * If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. + * @param opts.mediaTypes Media types to use for image layers. Defaults to OCI. + */ + manifest = (opts?: ContainerManifestOpts): File => { + const metadata = { + forcedCompression: { is_enum: true, value_to_name: ImageLayerCompressionValueToName }, + mediaTypes: { is_enum: true, value_to_name: ImageMediaTypesValueToName }, + } + + + const ctx = this._ctx.select( + "manifest", + { ...opts, __metadata: metadata }, + ) + return new File(ctx) + } + + /** + * Retrieves the list of paths where a directory is mounted. + */ + mounts = async (): Promise => { + const ctx = this._ctx.select( + "mounts", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The platform this container executes and publishes as. + */ + platform = async (): Promise => { + if (this._platform) { + return this._platform + } + + const ctx = this._ctx.select( + "platform", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Package the container state as an OCI image, and publish it to a registry + * + * Returns the fully qualified address of the published image, with digest + * @param address The OCI address to publish to + * + * Same format as "docker push". Example: "registry.example.com/user/repo:tag" + * @param opts.platformVariants Identifiers for other platform specific containers. + * + * Used for multi-platform image. + * @param opts.forcedCompression Force each layer of the published image to use the specified compression algorithm. + * + * If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. + * @param opts.mediaTypes Use the specified media types for the published image's layers. + * + * Defaults to "OCI", which is compatible with most recent registries, but "Docker" may be needed for older registries without OCI support. + * @param opts.registryService Service to use as the registry endpoint for the image address. + * + * The service will be started only for this push. + * @param opts.protocol Protocol to use for registry communication. + * + * Defaults to "HTTPS". Use "HTTP" only for plain HTTP registries. + * @param opts.insecureSkipTLSVerify Allow HTTPS registry communication without verifying the server certificate. + */ + publish = async (address: string, + opts?: ContainerPublishOpts): Promise => { + if (this._publish) { + return this._publish + } + + const metadata = { + forcedCompression: { is_enum: true, value_to_name: ImageLayerCompressionValueToName }, + mediaTypes: { is_enum: true, value_to_name: ImageMediaTypesValueToName }, + protocol: { is_enum: true, value_to_name: RegistryProtocolValueToName }, + } + + const ctx = this._ctx.select( + "publish", + { address, ...opts, __metadata: metadata}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Return a snapshot of the container's root filesystem. The snapshot can be modified then written back using withRootfs. Use that method for filesystem modifications. + */ + rootfs = (): Directory => { + + const ctx = this._ctx.select( + "rootfs", + ) + return new Directory(ctx) + } + + /** + * Return file status + * @param path Path to check (e.g., "/file.txt"). + * @param opts.doNotFollowSymlinks If specified, do not follow symlinks. + */ + stat = (path: string, opts?: ContainerStatOpts): Stat => { + + const ctx = this._ctx.select( + "stat", + { path, ...opts }, + ) + return new Stat(ctx) + } + + /** + * The buffered standard error stream of the last executed command + * + * Returns an error if no command was executed + */ + stderr = async (): Promise => { + if (this._stderr) { + return this._stderr + } + + const ctx = this._ctx.select( + "stderr", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The buffered standard output stream of the last executed command + * + * Returns an error if no command was executed + */ + stdout = async (): Promise => { + if (this._stdout) { + return this._stdout + } + + const ctx = this._ctx.select( + "stdout", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Forces evaluation of the pipeline in the engine. + * + * It doesn't run the default command if no exec has been set. + */ + sync = async (): Promise => { + const ctx = this._ctx.select( + "sync", + ) + + const response: Awaited = await ctx.execute() + + + return new Container(ctx.copy().selectNode(response, "Container")) + } + + /** + * Opens an interactive terminal for this container using its configured default terminal command if not overridden by args (or sh as a fallback default). + * @param opts.cmd If set, override the container's default terminal command and invoke these command arguments instead. + * @param opts.experimentalPrivilegedNesting Provides Dagger access to the executed command. + * @param opts.insecureRootCapabilities Execute the command with all root capabilities. This is similar to running a command with "sudo" or executing "docker run" with the "--privileged" flag. Containerization does not provide any security guarantees when using this option. It should only be used when absolutely necessary and only with trusted commands. + */ + terminal = (opts?: ContainerTerminalOpts): Container => { + + const ctx = this._ctx.select( + "terminal", + { ...opts }, + ) + return new Container(ctx) + } + + /** + * Starts a Service and creates a tunnel that forwards traffic from the caller's network to that service. + * + * Be sure to set any exposed ports before calling this api. + * @param opts.random Bind each tunnel port to a random port on the host. + * @param opts.ports List of frontend/backend port mappings to forward. + * + * Frontend is the port accepting traffic on the host, backend is the service port. + * @param opts.args Command to run instead of the container's default command (e.g., ["go", "run", "main.go"]). + * + * If empty, the container's default command is used. + * @param opts.useEntrypoint If the container has an entrypoint, prepend it to the args. + * @param opts.experimentalPrivilegedNesting Provides Dagger access to the executed command. + * @param opts.insecureRootCapabilities Execute the command with all root capabilities. This is similar to running a command with "sudo" or executing "docker run" with the "--privileged" flag. Containerization does not provide any security guarantees when using this option. It should only be used when absolutely necessary and only with trusted commands. + * @param opts.expand Replace "${VAR}" or "$VAR" in the args according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + * @param opts.noInit If set, skip the automatic init process injected into containers by default. + * + * This should only be used if the user requires that their exec process be the pid 1 process in the container. Otherwise it may result in unexpected behavior. + */ + up = async ( + opts?: ContainerUpOpts): Promise => { + if (this._up) { + return + } + + const ctx = this._ctx.select( + "up", + { ...opts}, + ) + + await ctx.execute() + + + } + + /** + * Retrieves the user to be set for all commands. + */ + user = async (): Promise => { + if (this._user) { + return this._user + } + + const ctx = this._ctx.select( + "user", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Retrieves this container plus the given OCI annotation. + * @param name The name of the annotation. + * @param value The value of the annotation. + */ + withAnnotation = (name: string, value: string): Container => { + + const ctx = this._ctx.select( + "withAnnotation", + { name, value }, + ) + return new Container(ctx) + } + + /** + * Configures default arguments for future commands. Like CMD in Dockerfile. + * @param args Arguments to prepend to future executions (e.g., ["-v", "--no-cache"]). + */ + withDefaultArgs = (args: string[]): Container => { + + const ctx = this._ctx.select( + "withDefaultArgs", + { args }, + ) + return new Container(ctx) + } + + /** + * Set the default command to invoke for the container's terminal API. + * @param args The args of the command. + * @param opts.experimentalPrivilegedNesting Provides Dagger access to the executed command. + * @param opts.insecureRootCapabilities Execute the command with all root capabilities. This is similar to running a command with "sudo" or executing "docker run" with the "--privileged" flag. Containerization does not provide any security guarantees when using this option. It should only be used when absolutely necessary and only with trusted commands. + */ + withDefaultTerminalCmd = (args: string[], opts?: ContainerWithDefaultTerminalCmdOpts): Container => { + + const ctx = this._ctx.select( + "withDefaultTerminalCmd", + { args, ...opts }, + ) + return new Container(ctx) + } + + /** + * Return a new container snapshot, with a directory added to its filesystem + * @param path Location of the written directory (e.g., "/tmp/directory"). + * @param source Identifier of the directory to write + * @param opts.exclude Patterns to exclude in the written directory (e.g. ["node_modules/**", ".gitignore", ".git/"]). + * @param opts.include Patterns to include in the written directory (e.g. ["*.go", "go.mod", "go.sum"]). + * @param opts.gitignore Apply .gitignore rules when writing the directory. + * @param opts.owner A user:group to set for the directory and its contents. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + * @param opts.inheritOwner Set the owner to the container's current user. + * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + withDirectory = (path: string, source: Directory, opts?: ContainerWithDirectoryOpts): Container => { + + const ctx = this._ctx.select( + "withDirectory", + { path, source, ...opts }, + ) + return new Container(ctx) + } + + /** + * Retrieves this container with the specificed docker healtcheck command set. + * @param args Healthcheck command to execute. Example: ["go", "run", "main.go"]. + * @param opts.shell When true, command must be a single element, which is run using the container's shell + * @param opts.interval Interval between running healthcheck. Example: "30s" + * @param opts.timeout Healthcheck timeout. Example: "3s" + * @param opts.startPeriod StartPeriod allows for failures during this initial startup period which do not count towards maximum number of retries. Example: "0s" + * @param opts.startInterval StartInterval configures the duration between checks during the startup phase. Example: "5s" + * @param opts.retries The maximum number of consecutive failures before the container is marked as unhealthy. Example: "3" + */ + withDockerHealthcheck = (args: string[], opts?: ContainerWithDockerHealthcheckOpts): Container => { + + const ctx = this._ctx.select( + "withDockerHealthcheck", + { args, ...opts }, + ) + return new Container(ctx) + } + + /** + * Set an OCI-style entrypoint. It will be included in the container's OCI configuration. Note, withExec ignores the entrypoint by default. + * @param args Arguments of the entrypoint. Example: ["go", "run"]. + * @param opts.keepDefaultArgs Don't reset the default arguments when setting the entrypoint. By default it is reset, since entrypoint and default args are often tightly coupled. + */ + withEntrypoint = (args: string[], opts?: ContainerWithEntrypointOpts): Container => { + + const ctx = this._ctx.select( + "withEntrypoint", + { args, ...opts }, + ) + return new Container(ctx) + } + + /** + * Export environment variables from an env-file to the container. + * @param source Identifier of the envfile + */ + withEnvFileVariables = (source: EnvFile): Container => { + + const ctx = this._ctx.select( + "withEnvFileVariables", + { source }, + ) + return new Container(ctx) + } + + /** + * Set a new environment variable in the container. + * @param name Name of the environment variable (e.g., "HOST"). + * @param value Value of the environment variable. (e.g., "localhost"). + * @param opts.expand Replace "${VAR}" or "$VAR" in the value according to the current environment variables defined in the container (e.g. "/opt/bin:$PATH"). + */ + withEnvVariable = (name: string, value: string, opts?: ContainerWithEnvVariableOpts): Container => { + + const ctx = this._ctx.select( + "withEnvVariable", + { name, value, ...opts }, + ) + return new Container(ctx) + } + + /** + * Raise an error. + * @param err Message of the error to raise. If empty, the error will be ignored. + */ + withError = (err: string): Container => { + + const ctx = this._ctx.select( + "withError", + { err }, + ) + return new Container(ctx) + } + + /** + * Execute a command in the container, and return a new snapshot of the container state after execution. + * @param args Command to execute. Must be valid exec() arguments, not a shell command. Example: ["go", "run", "main.go"]. + * + * To run a shell command, execute the shell and pass the shell command as argument. Example: ["sh", "-c", "ls -l | grep foo"] + * + * Defaults to the container's default arguments (see "defaultArgs" and "withDefaultArgs"). + * @param opts.useEntrypoint Apply the OCI entrypoint, if present, by prepending it to the args. Ignored by default. + * @param opts.stdin Content to write to the command's standard input. Example: "Hello world") + * @param opts.redirectStdin Redirect the command's standard input from a file in the container. Example: "./stdin.txt" + * @param opts.redirectStdout Redirect the command's standard output to a file in the container. Example: "./stdout.txt" + * @param opts.redirectStderr Redirect the command's standard error to a file in the container. Example: "./stderr.txt" + * @param opts.expect Exit codes this command is allowed to exit with without error + * @param opts.experimentalPrivilegedNesting Provides Dagger access to the executed command. + * @param opts.insecureRootCapabilities Execute the command with all root capabilities. Like --privileged in Docker + * + * DANGER: this grants the command full access to the host system. Only use when 1) you trust the command being executed and 2) you specifically need this level of access. + * @param opts.expand Replace "${VAR}" or "$VAR" in the args according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + * @param opts.noInit Skip the automatic init process injected into containers by default. + * + * Only use this if you specifically need the command to be pid 1 in the container. Otherwise it may result in unexpected behavior. If you're not sure, you don't need this. + */ + withExec = (args: string[], opts?: ContainerWithExecOpts): Container => { + const metadata = { + expect: { is_enum: true, value_to_name: ReturnTypeValueToName }, + } + + + const ctx = this._ctx.select( + "withExec", + { args, ...opts, __metadata: metadata }, + ) + return new Container(ctx) + } + + /** + * Expose a network port. Like EXPOSE in Dockerfile (but with healthcheck support) + * + * Exposed ports serve two purposes: + * + * - For health checks and introspection, when running services + * + * - For setting the EXPOSE OCI field when publishing the container + * @param port Port number to expose. Example: 8080 + * @param opts.protocol Network protocol. Example: "tcp" + * @param opts.description Port description. Example: "payment API endpoint" + * @param opts.experimentalSkipHealthcheck Skip the health check when run as a service. + */ + withExposedPort = (port: number, opts?: ContainerWithExposedPortOpts): Container => { + const metadata = { + protocol: { is_enum: true, value_to_name: NetworkProtocolValueToName }, + } + + + const ctx = this._ctx.select( + "withExposedPort", + { port, ...opts, __metadata: metadata }, + ) + return new Container(ctx) + } + + /** + * Return a container snapshot with a file added + * @param path Path of the new file. Example: "/path/to/new-file.txt" + * @param source File to add + * @param opts.permissions Permissions of the new file. Example: 0600 + * @param opts.owner A user:group to set for the file. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + * @param opts.inheritOwner Set the owner to the container's current user. + * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo.txt"). + */ + withFile = (path: string, source: File, opts?: ContainerWithFileOpts): Container => { + + const ctx = this._ctx.select( + "withFile", + { path, source, ...opts }, + ) + return new Container(ctx) + } + + /** + * Retrieves this container plus the contents of the given files copied to the given path. + * @param path Location where copied files should be placed (e.g., "/src"). + * @param sources Identifiers of the files to copy. + * @param opts.permissions Permission given to the copied files (e.g., 0600). + * @param opts.owner A user:group to set for the files. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + * @param opts.inheritOwner Set the owner to the container's current user. + * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo.txt"). + */ + withFiles = (path: string, sources: File[], opts?: ContainerWithFilesOpts): Container => { + + const ctx = this._ctx.select( + "withFiles", + { path, sources, ...opts }, + ) + return new Container(ctx) + } + + /** + * Retrieves this container plus the given label. + * @param name The name of the label (e.g., "org.opencontainers.artifact.created"). + * @param value The value of the label (e.g., "2023-01-01T00:00:00Z"). + */ + withLabel = (name: string, value: string): Container => { + + const ctx = this._ctx.select( + "withLabel", + { name, value }, + ) + return new Container(ctx) + } + + /** + * Retrieves this container plus a cache volume mounted at the given path. + * @param path Location of the cache directory (e.g., "/root/.npm"). + * @param cache Identifier of the cache volume to mount. + * @param opts.source Identifier of the directory to use as the cache volume's root. + * @param opts.sharing Sharing mode of the cache volume. + * @param opts.owner A user:group to set for the mounted cache directory. + * + * Note that this changes the ownership of the specified mount along with the initial filesystem provided by source (if any). It does not have any effect if/when the cache has already been created. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + * @param opts.inheritOwner Set the owner to the container's current user. + * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + withMountedCache = (path: string, cache: CacheVolume, opts?: ContainerWithMountedCacheOpts): Container => { + const metadata = { + sharing: { is_enum: true, value_to_name: CacheSharingModeValueToName }, + } + + + const ctx = this._ctx.select( + "withMountedCache", + { path, cache, ...opts, __metadata: metadata }, + ) + return new Container(ctx) + } + + /** + * Retrieves this container plus a directory mounted at the given path. + * @param path Location of the mounted directory (e.g., "/mnt/directory"). + * @param source Identifier of the mounted directory. + * @param opts.owner A user:group to set for the mounted directory and its contents. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + * @param opts.inheritOwner Set the owner to the container's current user. + * @param opts.readOnly Mount the directory read-only. + * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + withMountedDirectory = (path: string, source: Directory, opts?: ContainerWithMountedDirectoryOpts): Container => { + + const ctx = this._ctx.select( + "withMountedDirectory", + { path, source, ...opts }, + ) + return new Container(ctx) + } + + /** + * Retrieves this container plus a file mounted at the given path. + * @param path Location of the mounted file (e.g., "/tmp/file.txt"). + * @param source Identifier of the mounted file. + * @param opts.owner A user or user:group to set for the mounted file. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + * @param opts.inheritOwner Set the owner to the container's current user. + * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo.txt"). + */ + withMountedFile = (path: string, source: File, opts?: ContainerWithMountedFileOpts): Container => { + + const ctx = this._ctx.select( + "withMountedFile", + { path, source, ...opts }, + ) + return new Container(ctx) + } + + /** + * Retrieves this container plus a secret mounted into a file at the given path. + * @param path Location of the secret file (e.g., "/tmp/secret.txt"). + * @param source Identifier of the secret to mount. + * @param opts.owner A user:group to set for the mounted secret. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + * @param opts.inheritOwner Set the owner to the container's current user. + * @param opts.mode Permission given to the mounted secret (e.g., 0600). + * + * This option requires an owner to be set to be active. + * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + withMountedSecret = (path: string, source: Secret, opts?: ContainerWithMountedSecretOpts): Container => { + + const ctx = this._ctx.select( + "withMountedSecret", + { path, source, ...opts }, + ) + return new Container(ctx) + } + + /** + * Retrieves this container plus a temporary directory mounted at the given path. Any writes will be ephemeral to a single withExec call; they will not be persisted to subsequent withExecs. + * @param path Location of the temporary directory (e.g., "/tmp/temp_dir"). + * @param opts.size Size of the temporary directory in bytes. + * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + withMountedTemp = (path: string, opts?: ContainerWithMountedTempOpts): Container => { + + const ctx = this._ctx.select( + "withMountedTemp", + { path, ...opts }, + ) + return new Container(ctx) + } + + /** + * Retrieves this container plus a volume mounted at the given path. + * @param path Location of the volume mount (e.g., "/mnt/volume"). + * @param volume Identifier of the volume to mount. + * @param opts.readOnly Mount the volume read-only. + * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + withMountedVolume = (path: string, volume: Volume, opts?: ContainerWithMountedVolumeOpts): Container => { + + const ctx = this._ctx.select( + "withMountedVolume", + { path, volume, ...opts }, + ) + return new Container(ctx) + } + + /** + * Return a new container snapshot, with a file added to its filesystem with text content + * @param path Path of the new file. May be relative or absolute. Example: "README.md" or "/etc/profile" + * @param contents Contents of the new file. Example: "Hello world!" + * @param opts.permissions Permissions of the new file. Example: 0600 + * @param opts.owner A user:group to set for the file. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + * @param opts.inheritOwner Set the owner to the container's current user. + * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo.txt"). + */ + withNewFile = (path: string, contents: string, opts?: ContainerWithNewFileOpts): Container => { + + const ctx = this._ctx.select( + "withNewFile", + { path, contents, ...opts }, + ) + return new Container(ctx) + } + + /** + * Attach credentials for future publishing to a registry. Use in combination with publish + * @param address The image address that needs authentication. Same format as "docker push". Example: "registry.dagger.io/dagger:latest" + * @param username The username to authenticate with. Example: "alice" + * @param secret The API key, password or token to authenticate to this registry + */ + withRegistryAuth = (address: string, username: string, secret: Secret): Container => { + + const ctx = this._ctx.select( + "withRegistryAuth", + { address, username, secret }, + ) + return new Container(ctx) + } + + /** + * Change the container's root filesystem. The previous root filesystem will be lost. + * @param directory The new root filesystem. + */ + withRootfs = (directory: Directory): Container => { + + const ctx = this._ctx.select( + "withRootfs", + { directory }, + ) + return new Container(ctx) + } + + /** + * Set a new environment variable, using a secret value + * @param name Name of the secret variable (e.g., "API_SECRET"). + * @param secret Identifier of the secret value. + */ + withSecretVariable = (name: string, secret: Secret): Container => { + + const ctx = this._ctx.select( + "withSecretVariable", + { name, secret }, + ) + return new Container(ctx) + } + + /** + * Establish a runtime dependency from a container to a network service. + * + * The service will be started automatically when needed and detached when it is no longer needed, executing the default command if none is set. + * + * The service will be reachable from the container via the provided hostname alias. + * + * The service dependency will also convey to any files or directories produced by the container. + * @param alias Hostname that will resolve to the target service (only accessible from within this container) + * @param service The target service + */ + withServiceBinding = (alias: string, service: Service): Container => { + + const ctx = this._ctx.select( + "withServiceBinding", + { alias, service }, + ) + return new Container(ctx) + } + + /** + * Return a snapshot with a symlink + * @param target Location of the file or directory to link to (e.g., "/existing/file"). + * @param linkName Location where the symbolic link will be created (e.g., "/new-file-link"). + * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo.txt"). + */ + withSymlink = (target: string, linkName: string, opts?: ContainerWithSymlinkOpts): Container => { + + const ctx = this._ctx.select( + "withSymlink", + { target, linkName, ...opts }, + ) + return new Container(ctx) + } + + /** + * Retrieves this container plus a socket forwarded to the given Unix socket path. + * @param path Location of the forwarded Unix socket (e.g., "/tmp/socket"). + * @param source Identifier of the socket to forward. + * @param opts.owner A user:group to set for the mounted socket. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + * @param opts.inheritOwner Set the owner to the container's current user. + * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + withUnixSocket = (path: string, source: Socket, opts?: ContainerWithUnixSocketOpts): Container => { + + const ctx = this._ctx.select( + "withUnixSocket", + { path, source, ...opts }, + ) + return new Container(ctx) + } + + /** + * Retrieves this container with a different command user. + * @param name The user to set (e.g., "root"). + */ + withUser = (name: string): Container => { + + const ctx = this._ctx.select( + "withUser", + { name }, + ) + return new Container(ctx) + } + + /** + * Set a new non-secret environment variable for future execs without invalidating exec cache when only its value changes. + * + * This is an expert-only escape hatch. If a volatile value affects observable exec results, stale cached results may be reused. + * @param name Name of the volatile variable (e.g., "CI_RUN_ID"). + * @param value Value of the volatile variable. + */ + withVolatileVariable = (name: string, value: string): Container => { + + const ctx = this._ctx.select( + "withVolatileVariable", + { name, value }, + ) + return new Container(ctx) + } + + /** + * Change the container's working directory. Like WORKDIR in Dockerfile. + * @param path The path to set as the working directory (e.g., "/app"). + * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + withWorkdir = (path: string, opts?: ContainerWithWorkdirOpts): Container => { + + const ctx = this._ctx.select( + "withWorkdir", + { path, ...opts }, + ) + return new Container(ctx) + } + + /** + * Retrieves this container minus the given OCI annotation. + * @param name The name of the annotation. + */ + withoutAnnotation = (name: string): Container => { + + const ctx = this._ctx.select( + "withoutAnnotation", + { name }, + ) + return new Container(ctx) + } + + /** + * Remove the container's default arguments. + */ + withoutDefaultArgs = (): Container => { + + const ctx = this._ctx.select( + "withoutDefaultArgs", + ) + return new Container(ctx) + } + + /** + * Return a new container snapshot, with a directory removed from its filesystem + * @param path Location of the directory to remove (e.g., ".github/"). + * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + withoutDirectory = (path: string, opts?: ContainerWithoutDirectoryOpts): Container => { + + const ctx = this._ctx.select( + "withoutDirectory", + { path, ...opts }, + ) + return new Container(ctx) + } + + /** + * Retrieves this container without a configured docker healtcheck command. + */ + withoutDockerHealthcheck = (): Container => { + + const ctx = this._ctx.select( + "withoutDockerHealthcheck", + ) + return new Container(ctx) + } + + /** + * Reset the container's OCI entrypoint. + * @param opts.keepDefaultArgs Don't remove the default arguments when unsetting the entrypoint. + */ + withoutEntrypoint = (opts?: ContainerWithoutEntrypointOpts): Container => { + + const ctx = this._ctx.select( + "withoutEntrypoint", + { ...opts }, + ) + return new Container(ctx) + } + + /** + * Retrieves this container minus the given environment variable. + * @param name The name of the environment variable (e.g., "HOST"). + */ + withoutEnvVariable = (name: string): Container => { + + const ctx = this._ctx.select( + "withoutEnvVariable", + { name }, + ) + return new Container(ctx) + } + + /** + * Unexpose a previously exposed port. + * @param port Port number to unexpose + * @param opts.protocol Port protocol to unexpose + */ + withoutExposedPort = (port: number, opts?: ContainerWithoutExposedPortOpts): Container => { + const metadata = { + protocol: { is_enum: true, value_to_name: NetworkProtocolValueToName }, + } + + + const ctx = this._ctx.select( + "withoutExposedPort", + { port, ...opts, __metadata: metadata }, + ) + return new Container(ctx) + } + + /** + * Retrieves this container with the file at the given path removed. + * @param path Location of the file to remove (e.g., "/file.txt"). + * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo.txt"). + */ + withoutFile = (path: string, opts?: ContainerWithoutFileOpts): Container => { + + const ctx = this._ctx.select( + "withoutFile", + { path, ...opts }, + ) + return new Container(ctx) + } + + /** + * Return a new container spanshot with specified files removed + * @param paths Paths of the files to remove. Example: ["foo.txt, "/root/.ssh/config" + * @param opts.expand Replace "${VAR}" or "$VAR" in the value of paths according to the current environment variables defined in the container (e.g. "/$VAR/foo.txt"). + */ + withoutFiles = (paths: string[], opts?: ContainerWithoutFilesOpts): Container => { + + const ctx = this._ctx.select( + "withoutFiles", + { paths, ...opts }, + ) + return new Container(ctx) + } + + /** + * Retrieves this container minus the given environment label. + * @param name The name of the label to remove (e.g., "org.opencontainers.artifact.created"). + */ + withoutLabel = (name: string): Container => { + + const ctx = this._ctx.select( + "withoutLabel", + { name }, + ) + return new Container(ctx) + } + + /** + * Retrieves this container after unmounting everything at the given path. + * @param path Location of the cache directory (e.g., "/root/.npm"). + * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + withoutMount = (path: string, opts?: ContainerWithoutMountOpts): Container => { + + const ctx = this._ctx.select( + "withoutMount", + { path, ...opts }, + ) + return new Container(ctx) + } + + /** + * Retrieves this container without the registry authentication of a given address. + * @param address Registry's address to remove the authentication from. + * + * Formatted as [host]/[user]/[repo]:[tag] (e.g. docker.io/dagger/dagger:main). + */ + withoutRegistryAuth = (address: string): Container => { + + const ctx = this._ctx.select( + "withoutRegistryAuth", + { address }, + ) + return new Container(ctx) + } + + /** + * Retrieves this container minus the given environment variable containing the secret. + * @param name The name of the environment variable (e.g., "HOST"). + */ + withoutSecretVariable = (name: string): Container => { + + const ctx = this._ctx.select( + "withoutSecretVariable", + { name }, + ) + return new Container(ctx) + } + + /** + * Retrieves this container with a previously added Unix socket removed. + * @param path Location of the socket to remove (e.g., "/tmp/socket"). + * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + withoutUnixSocket = (path: string, opts?: ContainerWithoutUnixSocketOpts): Container => { + + const ctx = this._ctx.select( + "withoutUnixSocket", + { path, ...opts }, + ) + return new Container(ctx) + } + + /** + * Retrieves this container with an unset command user. + * + * Should default to root. + */ + withoutUser = (): Container => { + + const ctx = this._ctx.select( + "withoutUser", + ) + return new Container(ctx) + } + + /** + * Retrieves this container minus the given volatile environment variable. + * @param name The name of the volatile environment variable (e.g., "CI_RUN_ID"). + */ + withoutVolatileVariable = (name: string): Container => { + + const ctx = this._ctx.select( + "withoutVolatileVariable", + { name }, + ) + return new Container(ctx) + } + + /** + * Unset the container's working directory. + * + * Should default to "/". + */ + withoutWorkdir = (): Container => { + + const ctx = this._ctx.select( + "withoutWorkdir", + ) + return new Container(ctx) + } + + /** + * Retrieves the working directory for all commands. + */ + workdir = async (): Promise => { + if (this._workdir) { + return this._workdir + } + + const ctx = this._ctx.select( + "workdir", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Call the provided function with current Container. + * + * This is useful for reusability and readability by not breaking the calling chain. + */ + with = (arg: (param: Container) => Container) => { + return arg(this) + } +} + +/** + * Reflective module API provided to functions at runtime. + */ +export class CurrentModule extends BaseClient { + private readonly _id?: ID = undefined + private readonly _name?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _name?: string, + ) { + super(ctx) + + this._id = _id + this._name = _name + } + + /** + * A unique identifier for this CurrentModule. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Treat the currently executing module as an SDK installed in the given workspace, exposing the modules and clients it manages. + * + * Errors if the current module is not installed as an SDK in this workspace. + * @param opts.workspace The workspace to resolve SDK-role data against. Defaults to the current workspace. + */ + asSDK = (opts?: CurrentModuleAsSdkOpts): CurrentModuleAsSDK => { + + const ctx = this._ctx.select( + "asSDK", + { ...opts }, + ) + return new CurrentModuleAsSDK(ctx) + } + + /** + * The dependencies of the module. + */ + dependencies = async (): Promise => { + type dependencies = { + id: ID + } + + const ctx = this._ctx.select( + "dependencies", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new Module_(ctx.copy().selectNode(r.id, "Module"))) + } + + /** + * The generated files and directories made on top of the module source's context directory. + */ + generatedContextDirectory = (): Directory => { + + const ctx = this._ctx.select( + "generatedContextDirectory", + ) + return new Directory(ctx) + } + + /** + * Return all generators defined by the module + * @param opts.include Only include generators matching the specified patterns + * @experimental + */ + generators = (opts?: CurrentModuleGeneratorsOpts): GeneratorGroup => { + + const ctx = this._ctx.select( + "generators", + { ...opts }, + ) + return new GeneratorGroup(ctx) + } + + /** + * The name of the module being executed in + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The directory containing the module's source code loaded into the engine (plus any generated code that may have been created). + */ + source = (): Directory => { + + const ctx = this._ctx.select( + "source", + ) + return new Directory(ctx) + } + + /** + * Load a directory from the module's scratch working directory, including any changes that may have been made to it during module function execution. + * @param path Location of the directory to access (e.g., "."). + * @param opts.exclude Exclude artifacts that match the given pattern (e.g., ["node_modules/", ".git*"]). + * @param opts.include Include only artifacts that match the given pattern (e.g., ["app/", "package.*"]). + * @param opts.gitignore Apply .gitignore filter rules inside the directory + */ + workdir = (path: string, opts?: CurrentModuleWorkdirOpts): Directory => { + + const ctx = this._ctx.select( + "workdir", + { path, ...opts }, + ) + return new Directory(ctx) + } + + /** + * Load a file from the module's scratch working directory, including any changes that may have been made to it during module function execution.Load a file from the module's scratch working directory, including any changes that may have been made to it during module function execution. + * @param path Location of the file to retrieve (e.g., "README.md"). + */ + workdirFile = (path: string): File => { + + const ctx = this._ctx.select( + "workdirFile", + { path }, + ) + return new File(ctx) + } +} + +/** + * The SDK-role data for the currently executing module, as installed in the active workspace. + */ +export class CurrentModuleAsSDK extends BaseClient { + private readonly _id?: ID = undefined + private readonly _name?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _name?: string, + ) { + super(ctx) + + this._id = _id + this._name = _name + } + + /** + * A unique identifier for this CurrentModuleAsSDK. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The generated clients this SDK produces in the workspace. + */ + clients = async (): Promise => { + type clients = { + id: ID + } + + const ctx = this._ctx.select( + "clients", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new CurrentModuleAsSDKClient(ctx.copy().selectNode(r.id, "CurrentModuleAsSDKClient"))) + } + + /** + * The workspace-local modules this SDK authors and manages. + */ + modules = async (): Promise => { + type modules = { + id: ID + } + + const ctx = this._ctx.select( + "modules", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new CurrentModuleAsSDKModule(ctx.copy().selectNode(r.id, "CurrentModuleAsSDKModule"))) + } + + /** + * The user-facing name of this SDK in the workspace. + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * A generated client the current SDK produces in the workspace. + */ +export class CurrentModuleAsSDKClient extends BaseClient { + private readonly _id?: ID = undefined + private readonly _module?: string = undefined + private readonly _path?: string = undefined + private readonly _pin?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _module?: string, + _path?: string, + _pin?: string, + ) { + super(ctx) + + this._id = _id + this._module = _module + this._path = _path + this._pin = _pin + } + + /** + * A unique identifier for this CurrentModuleAsSDKClient. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The module the client is bound to (workspace-relative path or canonical ref). + */ + module_ = async (): Promise => { + if (this._module) { + return this._module + } + + const ctx = this._ctx.select( + "module", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The resolved module source this client is bound to, including its dependency closure and pinned version. + */ + moduleSource = (): ModuleSource => { + + const ctx = this._ctx.select( + "moduleSource", + ) + return new ModuleSource(ctx) + } + + /** + * Workspace-root-relative path of the generated client. + */ + path = async (): Promise => { + if (this._path) { + return this._path + } + + const ctx = this._ctx.select( + "path", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The pinned version of the bound module, if any. + */ + pin = async (): Promise => { + if (this._pin) { + return this._pin + } + + const ctx = this._ctx.select( + "pin", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * A workspace-local module managed by the current SDK. + */ +export class CurrentModuleAsSDKModule extends BaseClient { + private readonly _id?: ID = undefined + private readonly _path?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _path?: string, + ) { + super(ctx) + + this._id = _id + this._path = _path + } + + /** + * A unique identifier for this CurrentModuleAsSDKModule. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Workspace-root-relative path to the managed module. + */ + path = async (): Promise => { + if (this._path) { + return this._path + } + + const ctx = this._ctx.select( + "path", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + + +export class DiffStat extends BaseClient { + private readonly _id?: ID = undefined + private readonly _addedLines?: number = undefined + private readonly _kind?: DiffStatKind = undefined + private readonly _oldPath?: string = undefined + private readonly _path?: string = undefined + private readonly _removedLines?: number = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _addedLines?: number, + _kind?: DiffStatKind, + _oldPath?: string, + _path?: string, + _removedLines?: number, + ) { + super(ctx) + + this._id = _id + this._addedLines = _addedLines + this._kind = _kind + this._oldPath = _oldPath + this._path = _path + this._removedLines = _removedLines + } + + /** + * A unique identifier for this DiffStat. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Number of added lines for this path. + */ + addedLines = async (): Promise => { + if (this._addedLines) { + return this._addedLines + } + + const ctx = this._ctx.select( + "addedLines", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Type of change. + */ + kind = async (): Promise => { + if (this._kind) { + return this._kind + } + + const ctx = this._ctx.select( + "kind", + ) + + const response: Awaited = await ctx.execute() + + return DiffStatKindNameToValue(response) + } + + /** + * Previous path of the file, set only for renames. + */ + oldPath = async (): Promise => { + if (this._oldPath) { + return this._oldPath + } + + const ctx = this._ctx.select( + "oldPath", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Path of the changed file or directory. + */ + path = async (): Promise => { + if (this._path) { + return this._path + } + + const ctx = this._ctx.select( + "path", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Number of removed lines for this path. + */ + removedLines = async (): Promise => { + if (this._removedLines) { + return this._removedLines + } + + const ctx = this._ctx.select( + "removedLines", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + + + +/** + * A directory. + */ +export class Directory extends BaseClient { + private readonly _id?: ID = undefined + private readonly _digest?: string = undefined + private readonly _exists?: boolean = undefined + private readonly _export?: string = undefined + private readonly _findUp?: string = undefined + private readonly _name?: string = undefined + private readonly _sync?: ID = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _digest?: string, + _exists?: boolean, + _export?: string, + _findUp?: string, + _name?: string, + _sync?: ID, + ) { + super(ctx) + + this._id = _id + this._digest = _digest + this._exists = _exists + this._export = _export + this._findUp = _findUp + this._name = _name + this._sync = _sync + } + + /** + * A unique identifier for this Directory. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Converts this directory to a local git repository + */ + asGit = (): GitRepository => { + + const ctx = this._ctx.select( + "asGit", + ) + return new GitRepository(ctx) + } + + /** + * Load the directory as a Dagger module source + * @param opts.sourceRootPath An optional subpath of the directory which contains the module's configuration file. + * + * If not set, the module source code is loaded from the root of the directory. + */ + asModule = (opts?: DirectoryAsModuleOpts): Module_ => { + + const ctx = this._ctx.select( + "asModule", + { ...opts }, + ) + return new Module_(ctx) + } + + /** + * Load the directory as a Dagger module source + * @param opts.sourceRootPath An optional subpath of the directory which contains the module's configuration file. + * + * If not set, the module source code is loaded from the root of the directory. + */ + asModuleSource = (opts?: DirectoryAsModuleSourceOpts): ModuleSource => { + + const ctx = this._ctx.select( + "asModuleSource", + { ...opts }, + ) + return new ModuleSource(ctx) + } + + /** + * Creates a synthetic workspace from this directory. + * @param opts.cwd Current working directory inside the workspace root. Defaults to the workspace root. + */ + asWorkspace = (opts?: DirectoryAsWorkspaceOpts): Workspace => { + + const ctx = this._ctx.select( + "asWorkspace", + { ...opts }, + ) + return new Workspace(ctx) + } + + /** + * Return the difference between this directory and another directory, typically an older snapshot. + * + * The difference is encoded as a changeset, which also tracks removed files, and can be applied to other directories. + * @param from The base directory snapshot to compare against + */ + changes = (from: Directory): Changeset => { + + const ctx = this._ctx.select( + "changes", + { from }, + ) + return new Changeset(ctx) + } + + /** + * Change the owner of the directory contents recursively. + * @param path Path of the directory to change ownership of (e.g., "/"). + * @param owner A user:group to set for the mounted directory and its contents. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + */ + chown = (path: string, owner: string): Directory => { + + const ctx = this._ctx.select( + "chown", + { path, owner }, + ) + return new Directory(ctx) + } + + /** + * Return the difference between this directory and an another directory. The difference is encoded as a directory. + * @param other The directory to compare against + */ + diff = (other: Directory): Directory => { + + const ctx = this._ctx.select( + "diff", + { other }, + ) + return new Directory(ctx) + } + + /** + * Return the directory's digest. The format of the digest is not guaranteed to be stable between releases of Dagger. It is guaranteed to be stable between invocations of the same Dagger engine. + */ + digest = async (): Promise => { + if (this._digest) { + return this._digest + } + + const ctx = this._ctx.select( + "digest", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Retrieves a directory at the given path. + * @param path Location of the directory to retrieve. Example: "/src" + */ + directory = (path: string): Directory => { + + const ctx = this._ctx.select( + "directory", + { path }, + ) + return new Directory(ctx) + } + + /** + * Use Dockerfile compatibility to build a container from this directory. Only use this function for Dockerfile compatibility. Otherwise use the native Container type directly, it is feature-complete and supports all Dockerfile features. + * @param opts.dockerfile Path to the Dockerfile to use (e.g., "frontend.Dockerfile"). + * @param opts.platform The platform to build. + * @param opts.buildArgs Build arguments to use in the build. + * @param opts.target Target build stage to build. + * @param opts.secrets Secrets to pass to the build. + * + * They will be mounted at /run/secrets/[secret-name]. + * @param opts.noInit If set, skip the automatic init process injected into containers created by RUN statements. + * + * This should only be used if the user requires that their exec processes be the pid 1 process in the container. Otherwise it may result in unexpected behavior. + * @param opts.ssh A socket to use for SSH authentication during the build + * + * (e.g., for Dockerfile RUN --mount=type=ssh instructions). + * + * Typically obtained via host.unixSocket() pointing to the SSH_AUTH_SOCK. + */ + dockerBuild = (opts?: DirectoryDockerBuildOpts): Container => { + + const ctx = this._ctx.select( + "dockerBuild", + { ...opts }, + ) + return new Container(ctx) + } + + /** + * Returns a list of files and directories at the given path. + * @param opts.path Location of the directory to look at (e.g., "/src"). + */ + entries = async ( + opts?: DirectoryEntriesOpts): Promise => { + const ctx = this._ctx.select( + "entries", + { ...opts}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * check if a file or directory exists + * @param path Path to check (e.g., "/file.txt"). + * @param opts.expectedType If specified, also validate the type of file (e.g. "REGULAR_TYPE", "DIRECTORY_TYPE", or "SYMLINK_TYPE"). + * @param opts.doNotFollowSymlinks If specified, do not follow symlinks. + */ + exists = async (path: string, + opts?: DirectoryExistsOpts): Promise => { + if (this._exists) { + return this._exists + } + + const metadata = { + expectedType: { is_enum: true, value_to_name: ExistsTypeValueToName }, + } + + const ctx = this._ctx.select( + "exists", + { path, ...opts, __metadata: metadata}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Writes the contents of the directory to a path on the host. + * @param path Location of the copied directory (e.g., "logs/"). + * @param opts.wipe If true, then the host directory will be wiped clean before exporting so that it exactly matches the directory being exported; this means it will delete any files on the host that aren't in the exported dir. If false (the default), the contents of the directory will be merged with any existing contents of the host directory, leaving any existing files on the host that aren't in the exported directory alone. + */ + export = async (path: string, + opts?: DirectoryExportOpts): Promise => { + if (this._export) { + return this._export + } + + const ctx = this._ctx.select( + "export", + { path, ...opts}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Retrieve a file at the given path. + * @param path Location of the file to retrieve (e.g., "README.md"). + */ + file = (path: string): File => { + + const ctx = this._ctx.select( + "file", + { path }, + ) + return new File(ctx) + } + + /** + * Return a snapshot with some paths included or excluded + * @param opts.exclude If set, paths matching one of these glob patterns is excluded from the new snapshot. Example: ["node_modules/", ".git*", ".env"] + * @param opts.include If set, only paths matching one of these glob patterns is included in the new snapshot. Example: (e.g., ["app/", "package.*"]). + * @param opts.gitignore If set, apply .gitignore rules when filtering the directory. + */ + filter = (opts?: DirectoryFilterOpts): Directory => { + + const ctx = this._ctx.select( + "filter", + { ...opts }, + ) + return new Directory(ctx) + } + + /** + * Search up the directory tree for a file or directory, and return its path. If no match, return null + * @param name The name of the file or directory to search for + * @param start The path to start the search from + */ + findUp = async (name: string, start: string): Promise => { + if (this._findUp) { + return this._findUp + } + + const ctx = this._ctx.select( + "findUp", + { name, start}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Returns a list of files and directories that matche the given pattern. + * @param pattern Pattern to match (e.g., "*.md"). + */ + glob = async (pattern: string): Promise => { + const ctx = this._ctx.select( + "glob", + { pattern}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Returns the name of the directory. + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Searches for content matching the given regular expression or literal string. + * + * Uses Rust regex syntax; escape literal ., [, ], {, }, | with backslashes. + * @param opts.paths Directory or file paths to search + * @param opts.globs Glob patterns to match (e.g., "*.md") + * @param opts.pattern The text to match. + * @param opts.literal Interpret the pattern as a literal string instead of a regular expression. + * @param opts.multiline Enable searching across multiple lines. + * @param opts.dotall Allow the . pattern to match newlines in multiline mode. + * @param opts.insensitive Enable case-insensitive matching. + * @param opts.skipIgnored Honor .gitignore, .ignore, and .rgignore files. + * @param opts.skipHidden Skip hidden files (files starting with .). + * @param opts.filesOnly Only return matching files, not lines and content + * @param opts.limit Limit the number of results to return + */ + search = async ( + opts?: DirectorySearchOpts): Promise => { + type search = { + id: ID + } + + const ctx = this._ctx.select( + "search", + { ...opts}, + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new SearchResult(ctx.copy().selectNode(r.id, "SearchResult"))) + } + + /** + * Return file status + * @param path Path to stat (e.g., "/file.txt"). + * @param opts.doNotFollowSymlinks If specified, do not follow symlinks. + */ + stat = (path: string, opts?: DirectoryStatOpts): Stat => { + + const ctx = this._ctx.select( + "stat", + { path, ...opts }, + ) + return new Stat(ctx) + } + + /** + * Force evaluation in the engine. + */ + sync = async (): Promise => { + const ctx = this._ctx.select( + "sync", + ) + + const response: Awaited = await ctx.execute() + + + return new Directory(ctx.copy().selectNode(response, "Directory")) + } + + /** + * Opens an interactive terminal in new container with this directory mounted inside. + * @param opts.container If set, override the default container used for the terminal. + * @param opts.cmd If set, override the container's default terminal command and invoke these command arguments instead. + * @param opts.experimentalPrivilegedNesting Provides Dagger access to the executed command. + * @param opts.insecureRootCapabilities Execute the command with all root capabilities. This is similar to running a command with "sudo" or executing "docker run" with the "--privileged" flag. Containerization does not provide any security guarantees when using this option. It should only be used when absolutely necessary and only with trusted commands. + */ + terminal = (opts?: DirectoryTerminalOpts): Directory => { + + const ctx = this._ctx.select( + "terminal", + { ...opts }, + ) + return new Directory(ctx) + } + + /** + * Return a directory with changes from another directory applied to it. + * @param changes Changes to apply to the directory + */ + withChanges = (changes: Changeset): Directory => { + + const ctx = this._ctx.select( + "withChanges", + { changes }, + ) + return new Directory(ctx) + } + + /** + * Return a snapshot with a directory added + * @param path Location of the written directory (e.g., "/src/"). + * @param source Identifier of the directory to copy. + * @param opts.exclude Exclude artifacts that match the given pattern (e.g., ["node_modules/", ".git*"]). + * @param opts.include Include only artifacts that match the given pattern (e.g., ["app/", "package.*"]). + * @param opts.gitignore Apply .gitignore filter rules inside the directory + * @param opts.owner A user:group to set for the copied directory and its contents. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + * @param opts.permissions Permission given to the copied directory and contents (e.g., 0755). + */ + withDirectory = (path: string, source: Directory, opts?: DirectoryWithDirectoryOpts): Directory => { + + const ctx = this._ctx.select( + "withDirectory", + { path, source, ...opts }, + ) + return new Directory(ctx) + } + + /** + * Raise an error. + * @param err Message of the error to raise. If empty, the error will be ignored. + */ + withError = (err: string): Directory => { + + const ctx = this._ctx.select( + "withError", + { err }, + ) + return new Directory(ctx) + } + + /** + * Retrieves this directory plus the contents of the given file copied to the given path. + * @param path Location of the copied file (e.g., "/file.txt"). + * @param source Identifier of the file to copy. + * @param opts.permissions Permission given to the copied file (e.g., 0600). + * @param opts.owner A user:group to set for the copied directory and its contents. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + */ + withFile = (path: string, source: File, opts?: DirectoryWithFileOpts): Directory => { + + const ctx = this._ctx.select( + "withFile", + { path, source, ...opts }, + ) + return new Directory(ctx) + } + + /** + * Retrieves this directory plus the contents of the given files copied to the given path. + * @param path Location where copied files should be placed (e.g., "/src"). + * @param sources Identifiers of the files to copy. + * @param opts.permissions Permission given to the copied files (e.g., 0600). + */ + withFiles = (path: string, sources: File[], opts?: DirectoryWithFilesOpts): Directory => { + + const ctx = this._ctx.select( + "withFiles", + { path, sources, ...opts }, + ) + return new Directory(ctx) + } + + /** + * Retrieves this directory plus a new directory created at the given path. + * @param path Location of the directory created (e.g., "/logs"). + * @param opts.permissions Permission granted to the created directory (e.g., 0777). + */ + withNewDirectory = (path: string, opts?: DirectoryWithNewDirectoryOpts): Directory => { + + const ctx = this._ctx.select( + "withNewDirectory", + { path, ...opts }, + ) + return new Directory(ctx) + } + + /** + * Return a snapshot with a new file added + * @param path Path of the new file. Example: "foo/bar.txt" + * @param contents Contents of the new file. Example: "Hello world!" + * @param opts.permissions Permissions of the new file. Example: 0600 + */ + withNewFile = (path: string, contents: string, opts?: DirectoryWithNewFileOpts): Directory => { + + const ctx = this._ctx.select( + "withNewFile", + { path, contents, ...opts }, + ) + return new Directory(ctx) + } + + /** + * Retrieves this directory with the given Git-compatible patch applied. + * @param patch Patch to apply (e.g., "diff --git a/file.txt b/file.txt\nindex 1234567..abcdef8 100644\n--- a/file.txt\n+++ b/file.txt\n@@ -1,1 +1,1 @@\n-Hello\n+World\n"). + * @experimental + */ + withPatch = (patch: string): Directory => { + + const ctx = this._ctx.select( + "withPatch", + { patch }, + ) + return new Directory(ctx) + } + + /** + * Retrieves this directory with the given Git-compatible patch file applied. + * @param patch File containing the patch to apply + * @experimental + */ + withPatchFile = (patch: File): Directory => { + + const ctx = this._ctx.select( + "withPatchFile", + { patch }, + ) + return new Directory(ctx) + } + + /** + * Return a snapshot with a symlink + * @param target Location of the file or directory to link to (e.g., "/existing/file"). + * @param linkName Location where the symbolic link will be created (e.g., "/new-file-link"). + */ + withSymlink = (target: string, linkName: string): Directory => { + + const ctx = this._ctx.select( + "withSymlink", + { target, linkName }, + ) + return new Directory(ctx) + } + + /** + * Retrieves this directory with all file/dir timestamps set to the given time. + * @param timestamp Timestamp to set dir/files in. + * + * Formatted in seconds following Unix epoch (e.g., 1672531199). + */ + withTimestamps = (timestamp: number): Directory => { + + const ctx = this._ctx.select( + "withTimestamps", + { timestamp }, + ) + return new Directory(ctx) + } + + /** + * Return a snapshot with a subdirectory removed + * @param path Path of the subdirectory to remove. Example: ".github/workflows" + */ + withoutDirectory = (path: string): Directory => { + + const ctx = this._ctx.select( + "withoutDirectory", + { path }, + ) + return new Directory(ctx) + } + + /** + * Return a snapshot with a file removed + * @param path Path of the file to remove (e.g., "/file.txt"). + */ + withoutFile = (path: string): Directory => { + + const ctx = this._ctx.select( + "withoutFile", + { path }, + ) + return new Directory(ctx) + } + + /** + * Return a snapshot with files removed + * @param paths Paths of the files to remove (e.g., ["/file.txt"]). + */ + withoutFiles = (paths: string[]): Directory => { + + const ctx = this._ctx.select( + "withoutFiles", + { paths }, + ) + return new Directory(ctx) + } + + /** + * Call the provided function with current Directory. + * + * This is useful for reusability and readability by not breaking the calling chain. + */ + with = (arg: (param: Directory) => Directory) => { + return arg(this) + } +} + +/** + * The Dagger engine configuration and state + */ +export class Engine extends BaseClient { + private readonly _id?: ID = undefined + private readonly _name?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _name?: string, + ) { + super(ctx) + + this._id = _id + this._name = _name + } + + /** + * A unique identifier for this Engine. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The list of connected client IDs + */ + clients = async (): Promise => { + const ctx = this._ctx.select( + "clients", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The local engine cache state tracked by dagql + */ + localCache = (): EngineCache => { + + const ctx = this._ctx.select( + "localCache", + ) + return new EngineCache(ctx) + } + + /** + * The name of the engine instance. + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * A cache storage for the Dagger engine + */ +export class EngineCache extends BaseClient { + private readonly _id?: ID = undefined + private readonly _maxUsedSpace?: number = undefined + private readonly _minFreeSpace?: number = undefined + private readonly _prune?: Void = undefined + private readonly _reservedSpace?: number = undefined + private readonly _targetSpace?: number = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _maxUsedSpace?: number, + _minFreeSpace?: number, + _prune?: Void, + _reservedSpace?: number, + _targetSpace?: number, + ) { + super(ctx) + + this._id = _id + this._maxUsedSpace = _maxUsedSpace + this._minFreeSpace = _minFreeSpace + this._prune = _prune + this._reservedSpace = _reservedSpace + this._targetSpace = _targetSpace + } + + /** + * A unique identifier for this EngineCache. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The current set of entries in the cache + */ + entrySet = (opts?: EngineCacheEntrySetOpts): EngineCacheEntrySet => { + + const ctx = this._ctx.select( + "entrySet", + { ...opts }, + ) + return new EngineCacheEntrySet(ctx) + } + + /** + * The maximum bytes to keep in the cache without pruning. + */ + maxUsedSpace = async (): Promise => { + if (this._maxUsedSpace) { + return this._maxUsedSpace + } + + const ctx = this._ctx.select( + "maxUsedSpace", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The target amount of free disk space the garbage collector will attempt to leave. + */ + minFreeSpace = async (): Promise => { + if (this._minFreeSpace) { + return this._minFreeSpace + } + + const ctx = this._ctx.select( + "minFreeSpace", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Prune the cache of releaseable entries + * @param opts.useDefaultPolicy Use the engine-wide default pruning policy if true, otherwise prune the whole cache of any releasable entries. + * @param opts.maxUsedSpace Override the maximum disk space to keep before pruning (e.g. "200GB" or "80%"). + * @param opts.reservedSpace Override the minimum disk space to retain during pruning (e.g. "500GB" or "10%"). + * @param opts.minFreeSpace Override the minimum free disk space target during pruning (e.g. "20GB" or "20%"). + * @param opts.targetSpace Override the target disk space to keep after pruning (e.g. "200GB" or "50%"). + */ + prune = async ( + opts?: EngineCachePruneOpts): Promise => { + if (this._prune) { + return + } + + const ctx = this._ctx.select( + "prune", + { ...opts}, + ) + + await ctx.execute() + + + } + + /** + * The minimum amount of disk space this policy is guaranteed to retain. + */ + reservedSpace = async (): Promise => { + if (this._reservedSpace) { + return this._reservedSpace + } + + const ctx = this._ctx.select( + "reservedSpace", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The target number of bytes to keep when pruning. + */ + targetSpace = async (): Promise => { + if (this._targetSpace) { + return this._targetSpace + } + + const ctx = this._ctx.select( + "targetSpace", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * An individual cache entry in a cache entry set + */ +export class EngineCacheEntry extends BaseClient { + private readonly _id?: ID = undefined + private readonly _activelyUsed?: boolean = undefined + private readonly _createdTimeUnixNano?: number = undefined + private readonly _dagqlCall?: string = undefined + private readonly _description?: string = undefined + private readonly _diskSpaceBytes?: number = undefined + private readonly _mostRecentUseTimeUnixNano?: number = undefined + private readonly _recordType?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _activelyUsed?: boolean, + _createdTimeUnixNano?: number, + _dagqlCall?: string, + _description?: string, + _diskSpaceBytes?: number, + _mostRecentUseTimeUnixNano?: number, + _recordType?: string, + ) { + super(ctx) + + this._id = _id + this._activelyUsed = _activelyUsed + this._createdTimeUnixNano = _createdTimeUnixNano + this._dagqlCall = _dagqlCall + this._description = _description + this._diskSpaceBytes = _diskSpaceBytes + this._mostRecentUseTimeUnixNano = _mostRecentUseTimeUnixNano + this._recordType = _recordType + } + + /** + * A unique identifier for this EngineCacheEntry. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Whether the cache entry is actively being used. + */ + activelyUsed = async (): Promise => { + if (this._activelyUsed) { + return this._activelyUsed + } + + const ctx = this._ctx.select( + "activelyUsed", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The time the cache entry was created, in Unix nanoseconds. + */ + createdTimeUnixNano = async (): Promise => { + if (this._createdTimeUnixNano) { + return this._createdTimeUnixNano + } + + const ctx = this._ctx.select( + "createdTimeUnixNano", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The DagQL call that produced this cache entry. + */ + dagqlCall = async (): Promise => { + if (this._dagqlCall) { + return this._dagqlCall + } + + const ctx = this._ctx.select( + "dagqlCall", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The description of the cache entry. + */ + description = async (): Promise => { + if (this._description) { + return this._description + } + + const ctx = this._ctx.select( + "description", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The disk space used by the cache entry. + */ + diskSpaceBytes = async (): Promise => { + if (this._diskSpaceBytes) { + return this._diskSpaceBytes + } + + const ctx = this._ctx.select( + "diskSpaceBytes", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The most recent time the cache entry was used, in Unix nanoseconds. + */ + mostRecentUseTimeUnixNano = async (): Promise => { + if (this._mostRecentUseTimeUnixNano) { + return this._mostRecentUseTimeUnixNano + } + + const ctx = this._ctx.select( + "mostRecentUseTimeUnixNano", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The type of the cache record (e.g. regular, internal, frontend, source.local, source.git.checkout, exec.cachemount). + */ + recordType = async (): Promise => { + if (this._recordType) { + return this._recordType + } + + const ctx = this._ctx.select( + "recordType", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The storage record types represented by this cache entry. + */ + recordTypes = async (): Promise => { + const ctx = this._ctx.select( + "recordTypes", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * A set of cache entries returned by a query to a cache + */ +export class EngineCacheEntrySet extends BaseClient { + private readonly _id?: ID = undefined + private readonly _diskSpaceBytes?: number = undefined + private readonly _entryCount?: number = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _diskSpaceBytes?: number, + _entryCount?: number, + ) { + super(ctx) + + this._id = _id + this._diskSpaceBytes = _diskSpaceBytes + this._entryCount = _entryCount + } + + /** + * A unique identifier for this EngineCacheEntrySet. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The total disk space used by the cache entries in this set. + */ + diskSpaceBytes = async (): Promise => { + if (this._diskSpaceBytes) { + return this._diskSpaceBytes + } + + const ctx = this._ctx.select( + "diskSpaceBytes", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The list of individual cache entries in the set + */ + entries = async (): Promise => { + type entries = { + id: ID + } + + const ctx = this._ctx.select( + "entries", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new EngineCacheEntry(ctx.copy().selectNode(r.id, "EngineCacheEntry"))) + } + + /** + * The number of cache entries in this set. + */ + entryCount = async (): Promise => { + if (this._entryCount) { + return this._entryCount + } + + const ctx = this._ctx.select( + "entryCount", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * A definition of a custom enum defined in a Module. + */ +export class EnumTypeDef extends BaseClient { + private readonly _id?: ID = undefined + private readonly _description?: string = undefined + private readonly _name?: string = undefined + private readonly _sourceModuleName?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _description?: string, + _name?: string, + _sourceModuleName?: string, + ) { + super(ctx) + + this._id = _id + this._description = _description + this._name = _name + this._sourceModuleName = _sourceModuleName + } + + /** + * A unique identifier for this EnumTypeDef. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * A doc string for the enum, if any. + */ + description = async (): Promise => { + if (this._description) { + return this._description + } + + const ctx = this._ctx.select( + "description", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The members of the enum. + */ + members = async (): Promise => { + type members = { + id: ID + } + + const ctx = this._ctx.select( + "members", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new EnumValueTypeDef(ctx.copy().selectNode(r.id, "EnumValueTypeDef"))) + } + + /** + * The name of the enum. + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The location of this enum declaration. + */ + sourceMap = (): SourceMap => { + + const ctx = this._ctx.select( + "sourceMap", + ) + return new SourceMap(ctx) + } + + /** + * If this EnumTypeDef is associated with a Module, the name of the module. Unset otherwise. + */ + sourceModuleName = async (): Promise => { + if (this._sourceModuleName) { + return this._sourceModuleName + } + + const ctx = this._ctx.select( + "sourceModuleName", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The members of the enum. + * @deprecated use members instead + */ + values = async (): Promise => { + type values = { + id: ID + } + + const ctx = this._ctx.select( + "values", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new EnumValueTypeDef(ctx.copy().selectNode(r.id, "EnumValueTypeDef"))) + } +} + +/** + * A definition of a value in a custom enum defined in a Module. + */ +export class EnumValueTypeDef extends BaseClient { + private readonly _id?: ID = undefined + private readonly _deprecated?: string = undefined + private readonly _description?: string = undefined + private readonly _name?: string = undefined + private readonly _value?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _deprecated?: string, + _description?: string, + _name?: string, + _value?: string, + ) { + super(ctx) + + this._id = _id + this._deprecated = _deprecated + this._description = _description + this._name = _name + this._value = _value + } + + /** + * A unique identifier for this EnumValueTypeDef. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The reason this enum member is deprecated, if any. + */ + deprecated = async (): Promise => { + if (this._deprecated) { + return this._deprecated + } + + const ctx = this._ctx.select( + "deprecated", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * A doc string for the enum member, if any. + */ + description = async (): Promise => { + if (this._description) { + return this._description + } + + const ctx = this._ctx.select( + "description", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The name of the enum member. + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The location of this enum member declaration. + */ + sourceMap = (): SourceMap => { + + const ctx = this._ctx.select( + "sourceMap", + ) + return new SourceMap(ctx) + } + + /** + * The value of the enum member + */ + value = async (): Promise => { + if (this._value) { + return this._value + } + + const ctx = this._ctx.select( + "value", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + + +export class Env extends BaseClient { + private readonly _id?: ID = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + ) { + super(ctx) + + this._id = _id + } + + /** + * A unique identifier for this Env. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Return the check with the given name from the installed modules. Must match exactly one check. + * @param name The name of the check to retrieve + * @experimental + */ + check = (name: string): Check => { + + const ctx = this._ctx.select( + "check", + { name }, + ) + return new Check(ctx) + } + + /** + * Return all checks defined by the installed modules + * @param opts.include Only include checks matching the specified patterns + * @param opts.noGenerate When true, only return annotated check functions; exclude generate-as-checks + * @experimental + */ + checks = (opts?: EnvChecksOpts): CheckGroup => { + + const ctx = this._ctx.select( + "checks", + { ...opts }, + ) + return new CheckGroup(ctx) + } + + /** + * Retrieves an input binding by name + */ + input = (name: string): Binding => { + + const ctx = this._ctx.select( + "input", + { name }, + ) + return new Binding(ctx) + } + + /** + * Returns all input bindings provided to the environment + */ + inputs = async (): Promise => { + type inputs = { + id: ID + } + + const ctx = this._ctx.select( + "inputs", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new Binding(ctx.copy().selectNode(r.id, "Binding"))) + } + + /** + * Retrieves an output binding by name + */ + output = (name: string): Binding => { + + const ctx = this._ctx.select( + "output", + { name }, + ) + return new Binding(ctx) + } + + /** + * Returns all declared output bindings for the environment + */ + outputs = async (): Promise => { + type outputs = { + id: ID + } + + const ctx = this._ctx.select( + "outputs", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new Binding(ctx.copy().selectNode(r.id, "Binding"))) + } + + /** + * Return all services defined by the installed modules + * @param opts.include Only include services matching the specified patterns + * @experimental + */ + services = (opts?: EnvServicesOpts): UpGroup => { + + const ctx = this._ctx.select( + "services", + { ...opts }, + ) + return new UpGroup(ctx) + } + + /** + * Create or update a binding of type Address in the environment + * @param name The name of the binding + * @param value The Address value to assign to the binding + * @param description The purpose of the input + */ + withAddressInput = (name: string, value: Address, description: string): Env => { + + const ctx = this._ctx.select( + "withAddressInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired Address output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withAddressOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withAddressOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type CacheVolume in the environment + * @param name The name of the binding + * @param value The CacheVolume value to assign to the binding + * @param description The purpose of the input + */ + withCacheVolumeInput = (name: string, value: CacheVolume, description: string): Env => { + + const ctx = this._ctx.select( + "withCacheVolumeInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired CacheVolume output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withCacheVolumeOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withCacheVolumeOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type Changeset in the environment + * @param name The name of the binding + * @param value The Changeset value to assign to the binding + * @param description The purpose of the input + */ + withChangesetInput = (name: string, value: Changeset, description: string): Env => { + + const ctx = this._ctx.select( + "withChangesetInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired Changeset output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withChangesetOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withChangesetOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type CheckGroup in the environment + * @param name The name of the binding + * @param value The CheckGroup value to assign to the binding + * @param description The purpose of the input + */ + withCheckGroupInput = (name: string, value: CheckGroup, description: string): Env => { + + const ctx = this._ctx.select( + "withCheckGroupInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired CheckGroup output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withCheckGroupOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withCheckGroupOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type Check in the environment + * @param name The name of the binding + * @param value The Check value to assign to the binding + * @param description The purpose of the input + */ + withCheckInput = (name: string, value: Check, description: string): Env => { + + const ctx = this._ctx.select( + "withCheckInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired Check output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withCheckOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withCheckOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type Cloud in the environment + * @param name The name of the binding + * @param value The Cloud value to assign to the binding + * @param description The purpose of the input + */ + withCloudInput = (name: string, value: Cloud, description: string): Env => { + + const ctx = this._ctx.select( + "withCloudInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired Cloud output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withCloudOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withCloudOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type Container in the environment + * @param name The name of the binding + * @param value The Container value to assign to the binding + * @param description The purpose of the input + */ + withContainerInput = (name: string, value: Container, description: string): Env => { + + const ctx = this._ctx.select( + "withContainerInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired Container output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withContainerOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withContainerOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Installs the current module into the environment, exposing its functions to the model + * + * Contextual path arguments will be populated using the environment's workspace. + */ + withCurrentModule = (): Env => { + + const ctx = this._ctx.select( + "withCurrentModule", + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type CurrentModuleAsSDKClient in the environment + * @param name The name of the binding + * @param value The CurrentModuleAsSDKClient value to assign to the binding + * @param description The purpose of the input + */ + withCurrentModuleAsSDKClientInput = (name: string, value: CurrentModuleAsSDKClient, description: string): Env => { + + const ctx = this._ctx.select( + "withCurrentModuleAsSDKClientInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired CurrentModuleAsSDKClient output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withCurrentModuleAsSDKClientOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withCurrentModuleAsSDKClientOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type CurrentModuleAsSDK in the environment + * @param name The name of the binding + * @param value The CurrentModuleAsSDK value to assign to the binding + * @param description The purpose of the input + */ + withCurrentModuleAsSDKInput = (name: string, value: CurrentModuleAsSDK, description: string): Env => { + + const ctx = this._ctx.select( + "withCurrentModuleAsSDKInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type CurrentModuleAsSDKModule in the environment + * @param name The name of the binding + * @param value The CurrentModuleAsSDKModule value to assign to the binding + * @param description The purpose of the input + */ + withCurrentModuleAsSDKModuleInput = (name: string, value: CurrentModuleAsSDKModule, description: string): Env => { + + const ctx = this._ctx.select( + "withCurrentModuleAsSDKModuleInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired CurrentModuleAsSDKModule output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withCurrentModuleAsSDKModuleOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withCurrentModuleAsSDKModuleOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired CurrentModuleAsSDK output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withCurrentModuleAsSDKOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withCurrentModuleAsSDKOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type DiffStat in the environment + * @param name The name of the binding + * @param value The DiffStat value to assign to the binding + * @param description The purpose of the input + */ + withDiffStatInput = (name: string, value: DiffStat, description: string): Env => { + + const ctx = this._ctx.select( + "withDiffStatInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired DiffStat output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withDiffStatOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withDiffStatOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type Directory in the environment + * @param name The name of the binding + * @param value The Directory value to assign to the binding + * @param description The purpose of the input + */ + withDirectoryInput = (name: string, value: Directory, description: string): Env => { + + const ctx = this._ctx.select( + "withDirectoryInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired Directory output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withDirectoryOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withDirectoryOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type EnvFile in the environment + * @param name The name of the binding + * @param value The EnvFile value to assign to the binding + * @param description The purpose of the input + */ + withEnvFileInput = (name: string, value: EnvFile, description: string): Env => { + + const ctx = this._ctx.select( + "withEnvFileInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired EnvFile output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withEnvFileOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withEnvFileOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type Env in the environment + * @param name The name of the binding + * @param value The Env value to assign to the binding + * @param description The purpose of the input + */ + withEnvInput = (name: string, value: Env, description: string): Env => { + + const ctx = this._ctx.select( + "withEnvInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired Env output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withEnvOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withEnvOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type File in the environment + * @param name The name of the binding + * @param value The File value to assign to the binding + * @param description The purpose of the input + */ + withFileInput = (name: string, value: File, description: string): Env => { + + const ctx = this._ctx.select( + "withFileInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired File output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withFileOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withFileOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type GeneratorGroup in the environment + * @param name The name of the binding + * @param value The GeneratorGroup value to assign to the binding + * @param description The purpose of the input + */ + withGeneratorGroupInput = (name: string, value: GeneratorGroup, description: string): Env => { + + const ctx = this._ctx.select( + "withGeneratorGroupInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired GeneratorGroup output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withGeneratorGroupOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withGeneratorGroupOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type Generator in the environment + * @param name The name of the binding + * @param value The Generator value to assign to the binding + * @param description The purpose of the input + */ + withGeneratorInput = (name: string, value: Generator, description: string): Env => { + + const ctx = this._ctx.select( + "withGeneratorInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired Generator output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withGeneratorOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withGeneratorOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type GitRef in the environment + * @param name The name of the binding + * @param value The GitRef value to assign to the binding + * @param description The purpose of the input + */ + withGitRefInput = (name: string, value: GitRef, description: string): Env => { + + const ctx = this._ctx.select( + "withGitRefInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired GitRef output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withGitRefOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withGitRefOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type GitRepository in the environment + * @param name The name of the binding + * @param value The GitRepository value to assign to the binding + * @param description The purpose of the input + */ + withGitRepositoryInput = (name: string, value: GitRepository, description: string): Env => { + + const ctx = this._ctx.select( + "withGitRepositoryInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired GitRepository output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withGitRepositoryOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withGitRepositoryOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type HTTPState in the environment + * @param name The name of the binding + * @param value The HTTPState value to assign to the binding + * @param description The purpose of the input + */ + withHTTPStateInput = (name: string, value: HTTPState, description: string): Env => { + + const ctx = this._ctx.select( + "withHTTPStateInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired HTTPState output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withHTTPStateOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withHTTPStateOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type JSONValue in the environment + * @param name The name of the binding + * @param value The JSONValue value to assign to the binding + * @param description The purpose of the input + */ + withJSONValueInput = (name: string, value: JSONValue, description: string): Env => { + + const ctx = this._ctx.select( + "withJSONValueInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired JSONValue output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withJSONValueOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withJSONValueOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type LLMContentBlock in the environment + * @param name The name of the binding + * @param value The LLMContentBlock value to assign to the binding + * @param description The purpose of the input + */ + withLLMContentBlockInput = (name: string, value: LLMContentBlock, description: string): Env => { + + const ctx = this._ctx.select( + "withLLMContentBlockInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired LLMContentBlock output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withLLMContentBlockOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withLLMContentBlockOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type LLMMessage in the environment + * @param name The name of the binding + * @param value The LLMMessage value to assign to the binding + * @param description The purpose of the input + */ + withLLMMessageInput = (name: string, value: LLMMessage, description: string): Env => { + + const ctx = this._ctx.select( + "withLLMMessageInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired LLMMessage output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withLLMMessageOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withLLMMessageOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Sets the main module for this environment (the project being worked on) + * + * Contextual path arguments will be populated using the environment's workspace. + */ + withMainModule = (module_: Module_): Env => { + + const ctx = this._ctx.select( + "withMainModule", + { + module:module_ }, + ) + return new Env(ctx) + } + + /** + * Installs a module into the environment, exposing its functions to the model + * + * Contextual path arguments will be populated using the environment's workspace. + * @deprecated Use withMainModule instead + */ + withModule = (module_: Module_): Env => { + + const ctx = this._ctx.select( + "withModule", + { + module:module_ }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type ModuleConfigClient in the environment + * @param name The name of the binding + * @param value The ModuleConfigClient value to assign to the binding + * @param description The purpose of the input + */ + withModuleConfigClientInput = (name: string, value: ModuleConfigClient, description: string): Env => { + + const ctx = this._ctx.select( + "withModuleConfigClientInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired ModuleConfigClient output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withModuleConfigClientOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withModuleConfigClientOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type Module in the environment + * @param name The name of the binding + * @param value The Module value to assign to the binding + * @param description The purpose of the input + */ + withModuleInput = (name: string, value: Module_, description: string): Env => { + + const ctx = this._ctx.select( + "withModuleInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired Module output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withModuleOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withModuleOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type ModuleSource in the environment + * @param name The name of the binding + * @param value The ModuleSource value to assign to the binding + * @param description The purpose of the input + */ + withModuleSourceInput = (name: string, value: ModuleSource, description: string): Env => { + + const ctx = this._ctx.select( + "withModuleSourceInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired ModuleSource output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withModuleSourceOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withModuleSourceOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type Schema in the environment + * @param name The name of the binding + * @param value The Schema value to assign to the binding + * @param description The purpose of the input + */ + withSchemaInput = (name: string, value: Schema, description: string): Env => { + + const ctx = this._ctx.select( + "withSchemaInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired Schema output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withSchemaOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withSchemaOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type SearchResult in the environment + * @param name The name of the binding + * @param value The SearchResult value to assign to the binding + * @param description The purpose of the input + */ + withSearchResultInput = (name: string, value: SearchResult, description: string): Env => { + + const ctx = this._ctx.select( + "withSearchResultInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired SearchResult output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withSearchResultOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withSearchResultOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type SearchSubmatch in the environment + * @param name The name of the binding + * @param value The SearchSubmatch value to assign to the binding + * @param description The purpose of the input + */ + withSearchSubmatchInput = (name: string, value: SearchSubmatch, description: string): Env => { + + const ctx = this._ctx.select( + "withSearchSubmatchInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired SearchSubmatch output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withSearchSubmatchOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withSearchSubmatchOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type Secret in the environment + * @param name The name of the binding + * @param value The Secret value to assign to the binding + * @param description The purpose of the input + */ + withSecretInput = (name: string, value: Secret, description: string): Env => { + + const ctx = this._ctx.select( + "withSecretInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired Secret output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withSecretOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withSecretOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type Service in the environment + * @param name The name of the binding + * @param value The Service value to assign to the binding + * @param description The purpose of the input + */ + withServiceInput = (name: string, value: Service, description: string): Env => { + + const ctx = this._ctx.select( + "withServiceInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired Service output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withServiceOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withServiceOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type Socket in the environment + * @param name The name of the binding + * @param value The Socket value to assign to the binding + * @param description The purpose of the input + */ + withSocketInput = (name: string, value: Socket, description: string): Env => { + + const ctx = this._ctx.select( + "withSocketInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired Socket output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withSocketOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withSocketOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type Stat in the environment + * @param name The name of the binding + * @param value The Stat value to assign to the binding + * @param description The purpose of the input + */ + withStatInput = (name: string, value: Stat, description: string): Env => { + + const ctx = this._ctx.select( + "withStatInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired Stat output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withStatOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withStatOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Provides a string input binding to the environment + * @param name The name of the binding + * @param value The string value to assign to the binding + * @param description The description of the input + */ + withStringInput = (name: string, value: string, description: string): Env => { + + const ctx = this._ctx.select( + "withStringInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declares a desired string output binding + * @param name The name of the binding + * @param description The description of the output + */ + withStringOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withStringOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type UpGroup in the environment + * @param name The name of the binding + * @param value The UpGroup value to assign to the binding + * @param description The purpose of the input + */ + withUpGroupInput = (name: string, value: UpGroup, description: string): Env => { + + const ctx = this._ctx.select( + "withUpGroupInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired UpGroup output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withUpGroupOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withUpGroupOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type Up in the environment + * @param name The name of the binding + * @param value The Up value to assign to the binding + * @param description The purpose of the input + */ + withUpInput = (name: string, value: Up, description: string): Env => { + + const ctx = this._ctx.select( + "withUpInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired Up output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withUpOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withUpOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type Volume in the environment + * @param name The name of the binding + * @param value The Volume value to assign to the binding + * @param description The purpose of the input + */ + withVolumeInput = (name: string, value: Volume, description: string): Env => { + + const ctx = this._ctx.select( + "withVolumeInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired Volume output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withVolumeOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withVolumeOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Returns a new environment with the provided workspace + * @param workspace The directory to set as the host filesystem + */ + withWorkspace = (workspace: Directory): Env => { + + const ctx = this._ctx.select( + "withWorkspace", + { workspace }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type WorkspaceGit in the environment + * @param name The name of the binding + * @param value The WorkspaceGit value to assign to the binding + * @param description The purpose of the input + */ + withWorkspaceGitInput = (name: string, value: WorkspaceGit, description: string): Env => { + + const ctx = this._ctx.select( + "withWorkspaceGitInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired WorkspaceGit output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withWorkspaceGitOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withWorkspaceGitOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type Workspace in the environment + * @param name The name of the binding + * @param value The Workspace value to assign to the binding + * @param description The purpose of the input + */ + withWorkspaceInput = (name: string, value: Workspace, description: string): Env => { + + const ctx = this._ctx.select( + "withWorkspaceInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type WorkspaceMigration in the environment + * @param name The name of the binding + * @param value The WorkspaceMigration value to assign to the binding + * @param description The purpose of the input + */ + withWorkspaceMigrationInput = (name: string, value: WorkspaceMigration, description: string): Env => { + + const ctx = this._ctx.select( + "withWorkspaceMigrationInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired WorkspaceMigration output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withWorkspaceMigrationOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withWorkspaceMigrationOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type WorkspaceMigrationStep in the environment + * @param name The name of the binding + * @param value The WorkspaceMigrationStep value to assign to the binding + * @param description The purpose of the input + */ + withWorkspaceMigrationStepInput = (name: string, value: WorkspaceMigrationStep, description: string): Env => { + + const ctx = this._ctx.select( + "withWorkspaceMigrationStepInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired WorkspaceMigrationStep output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withWorkspaceMigrationStepOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withWorkspaceMigrationStepOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type WorkspaceModule in the environment + * @param name The name of the binding + * @param value The WorkspaceModule value to assign to the binding + * @param description The purpose of the input + */ + withWorkspaceModuleInput = (name: string, value: WorkspaceModule, description: string): Env => { + + const ctx = this._ctx.select( + "withWorkspaceModuleInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired WorkspaceModule output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withWorkspaceModuleOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withWorkspaceModuleOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type WorkspaceModuleSetting in the environment + * @param name The name of the binding + * @param value The WorkspaceModuleSetting value to assign to the binding + * @param description The purpose of the input + */ + withWorkspaceModuleSettingInput = (name: string, value: WorkspaceModuleSetting, description: string): Env => { + + const ctx = this._ctx.select( + "withWorkspaceModuleSettingInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired WorkspaceModuleSetting output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withWorkspaceModuleSettingOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withWorkspaceModuleSettingOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired Workspace output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withWorkspaceOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withWorkspaceOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Create or update a binding of type WorkspaceSDK in the environment + * @param name The name of the binding + * @param value The WorkspaceSDK value to assign to the binding + * @param description The purpose of the input + */ + withWorkspaceSDKInput = (name: string, value: WorkspaceSDK, description: string): Env => { + + const ctx = this._ctx.select( + "withWorkspaceSDKInput", + { name, value, description }, + ) + return new Env(ctx) + } + + /** + * Declare a desired WorkspaceSDK output to be assigned in the environment + * @param name The name of the binding + * @param description A description of the desired value of the binding + */ + withWorkspaceSDKOutput = (name: string, description: string): Env => { + + const ctx = this._ctx.select( + "withWorkspaceSDKOutput", + { name, description }, + ) + return new Env(ctx) + } + + /** + * Returns a new environment without any outputs + */ + withoutOutputs = (): Env => { + + const ctx = this._ctx.select( + "withoutOutputs", + ) + return new Env(ctx) + } + workspace = (): Directory => { + + const ctx = this._ctx.select( + "workspace", + ) + return new Directory(ctx) + } + + /** + * Call the provided function with current Env. + * + * This is useful for reusability and readability by not breaking the calling chain. + */ + with = (arg: (param: Env) => Env) => { + return arg(this) + } +} + +/** + * A collection of environment variables. + */ +export class EnvFile extends BaseClient { + private readonly _id?: ID = undefined + private readonly _exists?: boolean = undefined + private readonly _get?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _exists?: boolean, + _get?: string, + ) { + super(ctx) + + this._id = _id + this._exists = _exists + this._get = _get + } + + /** + * A unique identifier for this EnvFile. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Return as a file + */ + asFile = (): File => { + + const ctx = this._ctx.select( + "asFile", + ) + return new File(ctx) + } + + /** + * Check if a variable exists + * @param name Variable name + */ + exists = async (name: string): Promise => { + if (this._exists) { + return this._exists + } + + const ctx = this._ctx.select( + "exists", + { name}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Lookup a variable (last occurrence wins) and return its value, or an empty string + * @param name Variable name + * @param opts.raw Return the value exactly as written to the file. No quote removal or variable expansion + */ + get = async (name: string, + opts?: EnvFileGetOpts): Promise => { + if (this._get) { + return this._get + } + + const ctx = this._ctx.select( + "get", + { name, ...opts}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Filters variables by prefix and removes the pref from keys. Variables without the prefix are excluded. For example, with the prefix "MY_APP_" and variables: MY_APP_TOKEN=topsecret MY_APP_NAME=hello FOO=bar the resulting environment will contain: TOKEN=topsecret NAME=hello + * @param prefix The prefix to filter by + */ + namespace_ = (prefix: string): EnvFile => { + + const ctx = this._ctx.select( + "namespace", + { prefix }, + ) + return new EnvFile(ctx) + } + + /** + * Return all variables + * @param opts.raw Return values exactly as written to the file. No quote removal or variable expansion + */ + variables = async ( + opts?: EnvFileVariablesOpts): Promise => { + type variables = { + id: ID + } + + const ctx = this._ctx.select( + "variables", + { ...opts}, + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new EnvVariable(ctx.copy().selectNode(r.id, "EnvVariable"))) + } + + /** + * Add a variable + * @param name Variable name + * @param value Variable value + */ + withVariable = (name: string, value: string): EnvFile => { + + const ctx = this._ctx.select( + "withVariable", + { name, value }, + ) + return new EnvFile(ctx) + } + + /** + * Remove all occurrences of the named variable + * @param name Variable name + */ + withoutVariable = (name: string): EnvFile => { + + const ctx = this._ctx.select( + "withoutVariable", + { name }, + ) + return new EnvFile(ctx) + } + + /** + * Call the provided function with current EnvFile. + * + * This is useful for reusability and readability by not breaking the calling chain. + */ + with = (arg: (param: EnvFile) => EnvFile) => { + return arg(this) + } +} + +/** + * An environment variable name and value. + */ +export class EnvVariable extends BaseClient { + private readonly _id?: ID = undefined + private readonly _name?: string = undefined + private readonly _value?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _name?: string, + _value?: string, + ) { + super(ctx) + + this._id = _id + this._name = _name + this._value = _value + } + + /** + * A unique identifier for this EnvVariable. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The environment variable name. + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The environment variable value. + */ + value = async (): Promise => { + if (this._value) { + return this._value + } + + const ctx = this._ctx.select( + "value", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + + +export class Error extends BaseClient { + private readonly _id?: ID = undefined + private readonly _message?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _message?: string, + ) { + super(ctx) + + this._id = _id + this._message = _message + } + + /** + * A unique identifier for this Error. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * A description of the error. + */ + message = async (): Promise => { + if (this._message) { + return this._message + } + + const ctx = this._ctx.select( + "message", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The extensions of the error. + */ + values = async (): Promise => { + type values = { + id: ID + } + + const ctx = this._ctx.select( + "values", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new ErrorValue(ctx.copy().selectNode(r.id, "ErrorValue"))) + } + + /** + * Add a value to the error. + * @param name The name of the value. + * @param value The value to store on the error. + */ + withValue = (name: string, value: JSON): Error => { + + const ctx = this._ctx.select( + "withValue", + { name, value }, + ) + return new Error(ctx) + } + + /** + * Call the provided function with current Error. + * + * This is useful for reusability and readability by not breaking the calling chain. + */ + with = (arg: (param: Error) => Error) => { + return arg(this) + } +} + + +export class ErrorValue extends BaseClient { + private readonly _id?: ID = undefined + private readonly _name?: string = undefined + private readonly _value?: JSON = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _name?: string, + _value?: JSON, + ) { + super(ctx) + + this._id = _id + this._name = _name + this._value = _value + } + + /** + * A unique identifier for this ErrorValue. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The name of the value. + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The value. + */ + value = async (): Promise => { + if (this._value) { + return this._value + } + + const ctx = this._ctx.select( + "value", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + + + +/** + * An object that can be exported to the host. + * + * Calling export writes the object to a path on the host filesystem and returns the path that was written. + */ +export interface Exportable { + id(): Promise + export(path: string): Promise +} + +export class _ExportableClient extends BaseClient { + private readonly _id?: ID = undefined + private readonly _export?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _export?: string, + ) { + super(ctx) + + this._id = _id + this._export = _export + } + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + export = async (path: string): Promise => { + if (this._export) { + return this._export + } + + const ctx = this._ctx.select( + "export", + { path}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * A definition of a field on a custom object defined in a Module. + * + * A field on an object has a static value, as opposed to a function on an object whose value is computed by invoking code (and can accept arguments). + */ +export class FieldTypeDef extends BaseClient { + private readonly _id?: ID = undefined + private readonly _deprecated?: string = undefined + private readonly _description?: string = undefined + private readonly _name?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _deprecated?: string, + _description?: string, + _name?: string, + ) { + super(ctx) + + this._id = _id + this._deprecated = _deprecated + this._description = _description + this._name = _name + } + + /** + * A unique identifier for this FieldTypeDef. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The reason this enum member is deprecated, if any. + */ + deprecated = async (): Promise => { + if (this._deprecated) { + return this._deprecated + } + + const ctx = this._ctx.select( + "deprecated", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * A doc string for the field, if any. + */ + description = async (): Promise => { + if (this._description) { + return this._description + } + + const ctx = this._ctx.select( + "description", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The name of the field in lowerCamelCase format. + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The location of this field declaration. + */ + sourceMap = (): SourceMap => { + + const ctx = this._ctx.select( + "sourceMap", + ) + return new SourceMap(ctx) + } + + /** + * The type of the field. + */ + typeDef = (): TypeDef => { + + const ctx = this._ctx.select( + "typeDef", + ) + return new TypeDef(ctx) + } +} + +/** + * A file. + */ +export class File extends BaseClient { + private readonly _id?: ID = undefined + private readonly _contents?: string = undefined + private readonly _digest?: string = undefined + private readonly _export?: string = undefined + private readonly _name?: string = undefined + private readonly _size?: number = undefined + private readonly _sync?: ID = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _contents?: string, + _digest?: string, + _export?: string, + _name?: string, + _size?: number, + _sync?: ID, + ) { + super(ctx) + + this._id = _id + this._contents = _contents + this._digest = _digest + this._export = _export + this._name = _name + this._size = _size + this._sync = _sync + } + + /** + * A unique identifier for this File. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Parse as an env file + * @param opts.expand Replace "${VAR}" or "$VAR" with the value of other vars + */ + asEnvFile = (opts?: FileAsEnvFileOpts): EnvFile => { + + const ctx = this._ctx.select( + "asEnvFile", + { ...opts }, + ) + return new EnvFile(ctx) + } + + /** + * Parse the file contents as JSON. + */ + asJSON = (): JSONValue => { + + const ctx = this._ctx.select( + "asJSON", + ) + return new JSONValue(ctx) + } + + /** + * Change the owner of the file recursively. + * @param owner A user:group to set for the file. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + */ + chown = (owner: string): File => { + + const ctx = this._ctx.select( + "chown", + { owner }, + ) + return new File(ctx) + } + + /** + * Retrieves the contents of the file. + * @param opts.offsetLines Start reading after this line + * @param opts.limitLines Maximum number of lines to read + */ + contents = async ( + opts?: FileContentsOpts): Promise => { + if (this._contents) { + return this._contents + } + + const ctx = this._ctx.select( + "contents", + { ...opts}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Return the file's digest. The format of the digest is not guaranteed to be stable between releases of Dagger. It is guaranteed to be stable between invocations of the same Dagger engine. + * @param opts.excludeMetadata If true, exclude metadata from the digest. + */ + digest = async ( + opts?: FileDigestOpts): Promise => { + if (this._digest) { + return this._digest + } + + const ctx = this._ctx.select( + "digest", + { ...opts}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Writes the file to a file path on the host. + * @param path Location of the written directory (e.g., "output.txt"). + * @param opts.allowParentDirPath If allowParentDirPath is true, the path argument can be a directory path, in which case the file will be created in that directory. + */ + export = async (path: string, + opts?: FileExportOpts): Promise => { + if (this._export) { + return this._export + } + + const ctx = this._ctx.select( + "export", + { path, ...opts}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Retrieves the name of the file. + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Searches for content matching the given regular expression or literal string. + * + * Uses Rust regex syntax; escape literal ., [, ], {, }, | with backslashes. + * @param pattern The text to match. + * @param opts.literal Interpret the pattern as a literal string instead of a regular expression. + * @param opts.multiline Enable searching across multiple lines. + * @param opts.dotall Allow the . pattern to match newlines in multiline mode. + * @param opts.insensitive Enable case-insensitive matching. + * @param opts.skipIgnored Honor .gitignore, .ignore, and .rgignore files. + * @param opts.skipHidden Skip hidden files (files starting with .). + * @param opts.filesOnly Only return matching files, not lines and content + * @param opts.limit Limit the number of results to return + */ + search = async (pattern: string, + opts?: FileSearchOpts): Promise => { + type search = { + id: ID + } + + const ctx = this._ctx.select( + "search", + { pattern, ...opts}, + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new SearchResult(ctx.copy().selectNode(r.id, "SearchResult"))) + } + + /** + * Retrieves the size of the file, in bytes. + */ + size = async (): Promise => { + if (this._size) { + return this._size + } + + const ctx = this._ctx.select( + "size", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Return file status + */ + stat = (): Stat => { + + const ctx = this._ctx.select( + "stat", + ) + return new Stat(ctx) + } + + /** + * Force evaluation in the engine. + */ + sync = async (): Promise => { + const ctx = this._ctx.select( + "sync", + ) + + const response: Awaited = await ctx.execute() + + + return new File(ctx.copy().selectNode(response, "File")) + } + + /** + * Retrieves this file with its name set to the given name. + * @param name Name to set file to. + */ + withName = (name: string): File => { + + const ctx = this._ctx.select( + "withName", + { name }, + ) + return new File(ctx) + } + + /** + * Retrieves the file with content replaced with the given text. + * + * If 'all' is true, all occurrences of the pattern will be replaced. + * + * If 'firstAfter' is specified, only the first match starting at the specified line will be replaced. + * + * If neither are specified, and there are multiple matches for the pattern, this will error. + * + * If there are no matches for the pattern, this will error. + * @param search The text to match. + * @param replacement The text to match. + * @param opts.all Replace all occurrences of the pattern. + * @param opts.firstFrom Replace the first match starting from the specified line. + */ + withReplaced = (search: string, replacement: string, opts?: FileWithReplacedOpts): File => { + + const ctx = this._ctx.select( + "withReplaced", + { search, replacement, ...opts }, + ) + return new File(ctx) + } + + /** + * Retrieves this file with its created/modified timestamps set to the given time. + * @param timestamp Timestamp to set dir/files in. + * + * Formatted in seconds following Unix epoch (e.g., 1672531199). + */ + withTimestamps = (timestamp: number): File => { + + const ctx = this._ctx.select( + "withTimestamps", + { timestamp }, + ) + return new File(ctx) + } + + /** + * Call the provided function with current File. + * + * This is useful for reusability and readability by not breaking the calling chain. + */ + with = (arg: (param: File) => File) => { + return arg(this) + } +} + + + + + +/** + * Function represents a resolver provided by a Module. + * + * A function always evaluates against a parent object and is given a set of named arguments. + */ +export class Function_ extends BaseClient { + private readonly _id?: ID = undefined + private readonly _deprecated?: string = undefined + private readonly _description?: string = undefined + private readonly _name?: string = undefined + private readonly _sourceModuleName?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _deprecated?: string, + _description?: string, + _name?: string, + _sourceModuleName?: string, + ) { + super(ctx) + + this._id = _id + this._deprecated = _deprecated + this._description = _description + this._name = _name + this._sourceModuleName = _sourceModuleName + } + + /** + * A unique identifier for this Function. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Arguments accepted by the function, if any. + */ + args = async (): Promise => { + type args = { + id: ID + } + + const ctx = this._ctx.select( + "args", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new FunctionArg(ctx.copy().selectNode(r.id, "FunctionArg"))) + } + + /** + * The reason this function is deprecated, if any. + */ + deprecated = async (): Promise => { + if (this._deprecated) { + return this._deprecated + } + + const ctx = this._ctx.select( + "deprecated", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * A doc string for the function, if any. + */ + description = async (): Promise => { + if (this._description) { + return this._description + } + + const ctx = this._ctx.select( + "description", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The name of the function. + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The type returned by the function. + */ + returnType = (): TypeDef => { + + const ctx = this._ctx.select( + "returnType", + ) + return new TypeDef(ctx) + } + + /** + * The location of this function declaration. + */ + sourceMap = (): SourceMap => { + + const ctx = this._ctx.select( + "sourceMap", + ) + return new SourceMap(ctx) + } + + /** + * If this function is provided by a module, the name of the module. Unset otherwise. + */ + sourceModuleName = async (): Promise => { + if (this._sourceModuleName) { + return this._sourceModuleName + } + + const ctx = this._ctx.select( + "sourceModuleName", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Returns the function with the provided argument + * @param name The name of the argument + * @param typeDef The type of the argument + * @param opts.description A doc string for the argument, if any + * @param opts.defaultValue A default value to use for this argument if not explicitly set by the caller, if any + * @param opts.defaultPath If the argument is a Directory or File type, default to load path from context directory, relative to root directory. + * @param opts.ignore Patterns to ignore when loading the contextual argument value. + * @param opts.sourceMap The source map for the argument definition. + * @param opts.deprecated If deprecated, the reason or migration path. + */ + withArg = (name: string, typeDef: TypeDef, opts?: FunctionWithArgOpts): Function_ => { + + const ctx = this._ctx.select( + "withArg", + { name, typeDef, ...opts }, + ) + return new Function_(ctx) + } + + /** + * Returns the function updated to use the provided cache policy. + * @param policy The cache policy to use. + * @param opts.timeToLive The TTL for the cache policy, if applicable. Provided as a duration string, e.g. "5m", "1h30s". + */ + withCachePolicy = (policy: FunctionCachePolicy, opts?: FunctionWithCachePolicyOpts): Function_ => { + const metadata = { + policy: { is_enum: true, value_to_name: FunctionCachePolicyValueToName }, + } + + + const ctx = this._ctx.select( + "withCachePolicy", + { policy, ...opts, __metadata: metadata }, + ) + return new Function_(ctx) + } + + /** + * Returns the function with a flag indicating it's a check. + */ + withCheck = (): Function_ => { + + const ctx = this._ctx.select( + "withCheck", + ) + return new Function_(ctx) + } + + /** + * Returns the function with the provided deprecation reason. + * @param opts.reason Reason or migration path describing the deprecation. + */ + withDeprecated = (opts?: FunctionWithDeprecatedOpts): Function_ => { + + const ctx = this._ctx.select( + "withDeprecated", + { ...opts }, + ) + return new Function_(ctx) + } + + /** + * Returns the function with the given doc string. + * @param description The doc string to set. + */ + withDescription = (description: string): Function_ => { + + const ctx = this._ctx.select( + "withDescription", + { description }, + ) + return new Function_(ctx) + } + + /** + * Returns the function with a flag indicating it's a generator. + */ + withGenerator = (): Function_ => { + + const ctx = this._ctx.select( + "withGenerator", + ) + return new Function_(ctx) + } + + /** + * Returns the function with the given source map. + * @param sourceMap The source map for the function definition. + */ + withSourceMap = (sourceMap: SourceMap): Function_ => { + + const ctx = this._ctx.select( + "withSourceMap", + { sourceMap }, + ) + return new Function_(ctx) + } + + /** + * Returns the function with a flag indicating it returns a service for dagger up. + */ + withUp = (): Function_ => { + + const ctx = this._ctx.select( + "withUp", + ) + return new Function_(ctx) + } + + /** + * Call the provided function with current Function. + * + * This is useful for reusability and readability by not breaking the calling chain. + */ + with = (arg: (param: Function_) => Function_) => { + return arg(this) + } +} + +/** + * An argument accepted by a function. + * + * This is a specification for an argument at function definition time, not an argument passed at function call time. + */ +export class FunctionArg extends BaseClient { + private readonly _id?: ID = undefined + private readonly _defaultAddress?: string = undefined + private readonly _defaultPath?: string = undefined + private readonly _defaultValue?: JSON = undefined + private readonly _deprecated?: string = undefined + private readonly _description?: string = undefined + private readonly _name?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _defaultAddress?: string, + _defaultPath?: string, + _defaultValue?: JSON, + _deprecated?: string, + _description?: string, + _name?: string, + ) { + super(ctx) + + this._id = _id + this._defaultAddress = _defaultAddress + this._defaultPath = _defaultPath + this._defaultValue = _defaultValue + this._deprecated = _deprecated + this._description = _description + this._name = _name + } + + /** + * A unique identifier for this FunctionArg. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Only applies to arguments of type Container. If the argument is not set, load it from the given address (e.g. alpine:latest) + */ + defaultAddress = async (): Promise => { + if (this._defaultAddress) { + return this._defaultAddress + } + + const ctx = this._ctx.select( + "defaultAddress", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Only applies to arguments of type File or Directory. If the argument is not set, load it from the given path in the context directory + */ + defaultPath = async (): Promise => { + if (this._defaultPath) { + return this._defaultPath + } + + const ctx = this._ctx.select( + "defaultPath", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * A default value to use for this argument when not explicitly set by the caller, if any. + */ + defaultValue = async (): Promise => { + if (this._defaultValue) { + return this._defaultValue + } + + const ctx = this._ctx.select( + "defaultValue", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The reason this function is deprecated, if any. + */ + deprecated = async (): Promise => { + if (this._deprecated) { + return this._deprecated + } + + const ctx = this._ctx.select( + "deprecated", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * A doc string for the argument, if any. + */ + description = async (): Promise => { + if (this._description) { + return this._description + } + + const ctx = this._ctx.select( + "description", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Only applies to arguments of type Directory. The ignore patterns are applied to the input directory, and matching entries are filtered out, in a cache-efficient manner. + */ + ignore = async (): Promise => { + const ctx = this._ctx.select( + "ignore", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The name of the argument in lowerCamelCase format. + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The location of this arg declaration. + */ + sourceMap = (): SourceMap => { + + const ctx = this._ctx.select( + "sourceMap", + ) + return new SourceMap(ctx) + } + + /** + * The type of the argument. + */ + typeDef = (): TypeDef => { + + const ctx = this._ctx.select( + "typeDef", + ) + return new TypeDef(ctx) + } +} + + + +/** + * An active function call. + */ +export class FunctionCall extends BaseClient { + private readonly _id?: ID = undefined + private readonly _name?: string = undefined + private readonly _parent?: JSON = undefined + private readonly _parentName?: string = undefined + private readonly _returnError?: Void = undefined + private readonly _returnValue?: Void = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _name?: string, + _parent?: JSON, + _parentName?: string, + _returnError?: Void, + _returnValue?: Void, + ) { + super(ctx) + + this._id = _id + this._name = _name + this._parent = _parent + this._parentName = _parentName + this._returnError = _returnError + this._returnValue = _returnValue + } + + /** + * A unique identifier for this FunctionCall. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The argument values the function is being invoked with. + */ + inputArgs = async (): Promise => { + type inputArgs = { + id: ID + } + + const ctx = this._ctx.select( + "inputArgs", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new FunctionCallArgValue(ctx.copy().selectNode(r.id, "FunctionCallArgValue"))) + } + + /** + * The name of the function being called. + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The value of the parent object of the function being called. If the function is top-level to the module, this is always an empty object. + */ + parent = async (): Promise => { + if (this._parent) { + return this._parent + } + + const ctx = this._ctx.select( + "parent", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The name of the parent object of the function being called. If the function is top-level to the module, this is the name of the module. + */ + parentName = async (): Promise => { + if (this._parentName) { + return this._parentName + } + + const ctx = this._ctx.select( + "parentName", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Return an error from the function. + * @param error The error to return. + */ + returnError = async (error: Error): Promise => { + if (this._returnError) { + return + } + + const ctx = this._ctx.select( + "returnError", + { error}, + ) + + await ctx.execute() + + + } + + /** + * Set the return value of the function call to the provided value. + * @param value JSON serialization of the return value. + */ + returnValue = async (value: JSON): Promise => { + if (this._returnValue) { + return + } + + const ctx = this._ctx.select( + "returnValue", + { value}, + ) + + await ctx.execute() + + + } +} + +/** + * A value passed as a named argument to a function call. + */ +export class FunctionCallArgValue extends BaseClient { + private readonly _id?: ID = undefined + private readonly _name?: string = undefined + private readonly _value?: JSON = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _name?: string, + _value?: JSON, + ) { + super(ctx) + + this._id = _id + this._name = _name + this._value = _value + } + + /** + * A unique identifier for this FunctionCallArgValue. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The name of the argument. + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The value of the argument represented as a JSON serialized string. + */ + value = async (): Promise => { + if (this._value) { + return this._value + } + + const ctx = this._ctx.select( + "value", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * The result of running an SDK's codegen. + */ +export class GeneratedCode extends BaseClient { + private readonly _id?: ID = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + ) { + super(ctx) + + this._id = _id + } + + /** + * A unique identifier for this GeneratedCode. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The directory containing the generated code. + */ + code = (): Directory => { + + const ctx = this._ctx.select( + "code", + ) + return new Directory(ctx) + } + + /** + * List of paths to mark generated in version control (i.e. .gitattributes). + */ + vcsGeneratedPaths = async (): Promise => { + const ctx = this._ctx.select( + "vcsGeneratedPaths", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * List of paths to ignore in version control (i.e. .gitignore). + */ + vcsIgnoredPaths = async (): Promise => { + const ctx = this._ctx.select( + "vcsIgnoredPaths", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Set the list of paths to mark generated in version control. + */ + withVCSGeneratedPaths = (paths: string[]): GeneratedCode => { + + const ctx = this._ctx.select( + "withVCSGeneratedPaths", + { paths }, + ) + return new GeneratedCode(ctx) + } + + /** + * Set the list of paths to ignore in version control. + */ + withVCSIgnoredPaths = (paths: string[]): GeneratedCode => { + + const ctx = this._ctx.select( + "withVCSIgnoredPaths", + { paths }, + ) + return new GeneratedCode(ctx) + } + + /** + * Call the provided function with current GeneratedCode. + * + * This is useful for reusability and readability by not breaking the calling chain. + */ + with = (arg: (param: GeneratedCode) => GeneratedCode) => { + return arg(this) + } +} + + +export class Generator extends BaseClient { + private readonly _id?: ID = undefined + private readonly _completed?: boolean = undefined + private readonly _description?: string = undefined + private readonly _isEmpty?: boolean = undefined + private readonly _name?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _completed?: boolean, + _description?: string, + _isEmpty?: boolean, + _name?: string, + ) { + super(ctx) + + this._id = _id + this._completed = _completed + this._description = _description + this._isEmpty = _isEmpty + this._name = _name + } + + /** + * A unique identifier for this Generator. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The generated changeset from the last run + */ + changes = (): Changeset => { + + const ctx = this._ctx.select( + "changes", + ) + return new Changeset(ctx) + } + + /** + * Whether the generator complete + */ + completed = async (): Promise => { + if (this._completed) { + return this._completed + } + + const ctx = this._ctx.select( + "completed", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Return the description of the generator + */ + description = async (): Promise => { + if (this._description) { + return this._description + } + + const ctx = this._ctx.select( + "description", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Whether changeset from the last generator run is empty or not + */ + isEmpty = async (): Promise => { + if (this._isEmpty) { + return this._isEmpty + } + + const ctx = this._ctx.select( + "isEmpty", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Return the fully qualified name of the generator + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The original module in which the generator has been defined + */ + originalModule = (): Module_ => { + + const ctx = this._ctx.select( + "originalModule", + ) + return new Module_(ctx) + } + + /** + * The path of the generator within its module + */ + path = async (): Promise => { + const ctx = this._ctx.select( + "path", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Execute the generator + */ + run = (): Generator => { + + const ctx = this._ctx.select( + "run", + ) + return new Generator(ctx) + } + + /** + * Call the provided function with current Generator. + * + * This is useful for reusability and readability by not breaking the calling chain. + */ + with = (arg: (param: Generator) => Generator) => { + return arg(this) + } +} + + +export class GeneratorGroup extends BaseClient { + private readonly _id?: ID = undefined + private readonly _isEmpty?: boolean = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _isEmpty?: boolean, + ) { + super(ctx) + + this._id = _id + this._isEmpty = _isEmpty + } + + /** + * A unique identifier for this GeneratorGroup. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The combined changes from the last run of the generators + * + * If any conflict occurs, for instance if the same file is modified by multiple generators, or if a file is both modified and deleted, an error is raised and the merge of the changesets will failed. + * + * Set 'continueOnConflicts' flag to force to merge the changes in a 'last write wins' strategy. + * @param opts.onConflict Strategy to apply on conflicts between generators + */ + changes = (opts?: GeneratorGroupChangesOpts): Changeset => { + const metadata = { + onConflict: { is_enum: true, value_to_name: ChangesetsMergeConflictValueToName }, + } + + + const ctx = this._ctx.select( + "changes", + { ...opts, __metadata: metadata }, + ) + return new Changeset(ctx) + } + + /** + * Whether the generated changeset from the last run is empty or not + */ + isEmpty = async (): Promise => { + if (this._isEmpty) { + return this._isEmpty + } + + const ctx = this._ctx.select( + "isEmpty", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Return a list of individual generators and their details + */ + list = async (): Promise => { + type list = { + id: ID + } + + const ctx = this._ctx.select( + "list", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new Generator(ctx.copy().selectNode(r.id, "Generator"))) + } + + /** + * Load failures tolerated while collecting the generators. + * + * Empty unless a workspace module could not be loaded during an unscoped 'dagger generate' (no selector), where load failures are tolerated so the modules that do load still generate. Each entry is a human-readable error message. An explicit selector keeps failing hard instead. + */ + loadFailures = async (): Promise => { + const ctx = this._ctx.select( + "loadFailures", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Execute all selected generators + */ + run = (): GeneratorGroup => { + + const ctx = this._ctx.select( + "run", + ) + return new GeneratorGroup(ctx) + } + + /** + * Call the provided function with current GeneratorGroup. + * + * This is useful for reusability and readability by not breaking the calling chain. + */ + with = (arg: (param: GeneratorGroup) => GeneratorGroup) => { + return arg(this) + } +} + +/** + * A git ref (tag, branch, or commit). + */ +export class GitRef extends BaseClient { + private readonly _id?: ID = undefined + private readonly _commit?: string = undefined + private readonly _ref?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _commit?: string, + _ref?: string, + ) { + super(ctx) + + this._id = _id + this._commit = _commit + this._ref = _ref + } + + /** + * A unique identifier for this GitRef. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Creates a synthetic workspace from this git ref. + * @param opts.cwd Current working directory inside the workspace root. Defaults to the workspace root. + */ + asWorkspace = (opts?: GitRefAsWorkspaceOpts): Workspace => { + + const ctx = this._ctx.select( + "asWorkspace", + { ...opts }, + ) + return new Workspace(ctx) + } + + /** + * The resolved commit id at this ref. + */ + commit = async (): Promise => { + if (this._commit) { + return this._commit + } + + const ctx = this._ctx.select( + "commit", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Find the best common ancestor between this ref and another ref. + * @param other The other ref to compare against. + */ + commonAncestor = (other: GitRef): GitRef => { + + const ctx = this._ctx.select( + "commonAncestor", + { other }, + ) + return new GitRef(ctx) + } + + /** + * The resolved ref name at this ref. + */ + ref = async (): Promise => { + if (this._ref) { + return this._ref + } + + const ctx = this._ctx.select( + "ref", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The filesystem tree at this ref. + * @param opts.discardGitDir Set to true to discard .git directory. + * @param opts.depth The depth of the tree to fetch. + * @param opts.includeTags Set to true to populate tag refs in the local checkout .git. + */ + tree = (opts?: GitRefTreeOpts): Directory => { + + const ctx = this._ctx.select( + "tree", + { ...opts }, + ) + return new Directory(ctx) + } + + /** + * Call the provided function with current GitRef. + * + * This is useful for reusability and readability by not breaking the calling chain. + */ + with = (arg: (param: GitRef) => GitRef) => { + return arg(this) + } +} + +/** + * A git repository. + */ +export class GitRepository extends BaseClient { + private readonly _id?: ID = undefined + private readonly _url?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _url?: string, + ) { + super(ctx) + + this._id = _id + this._url = _url + } + + /** + * A unique identifier for this GitRepository. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Creates a synthetic workspace from this git repository. + * @param opts.cwd Current working directory inside the workspace root. Defaults to the workspace root. + */ + asWorkspace = (opts?: GitRepositoryAsWorkspaceOpts): Workspace => { + + const ctx = this._ctx.select( + "asWorkspace", + { ...opts }, + ) + return new Workspace(ctx) + } + + /** + * Returns details of a branch. + * @param name Branch's name (e.g., "main"). + */ + branch = (name: string): GitRef => { + + const ctx = this._ctx.select( + "branch", + { name }, + ) + return new GitRef(ctx) + } + + /** + * branches that match any of the given glob patterns. + * @param opts.patterns Glob patterns (e.g., "refs/tags/v*"). + */ + branches = async ( + opts?: GitRepositoryBranchesOpts): Promise => { + const ctx = this._ctx.select( + "branches", + { ...opts}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Returns details of a commit. + * @param id Identifier of the commit (e.g., "b6315d8f2810962c601af73f86831f6866ea798b"). + */ + commit = (id: string): GitRef => { + + const ctx = this._ctx.select( + "commit", + { id }, + ) + return new GitRef(ctx) + } + + /** + * Returns details for HEAD. + */ + head = (): GitRef => { + + const ctx = this._ctx.select( + "head", + ) + return new GitRef(ctx) + } + + /** + * Returns details for the latest semver tag. + */ + latestVersion = (): GitRef => { + + const ctx = this._ctx.select( + "latestVersion", + ) + return new GitRef(ctx) + } + + /** + * Returns details of a ref. + * @param name Ref's name (can be a commit identifier, a tag name, a branch name, or a fully-qualified ref). + */ + ref = (name: string): GitRef => { + + const ctx = this._ctx.select( + "ref", + { name }, + ) + return new GitRef(ctx) + } + + /** + * Returns details of a tag. + * @param name Tag's name (e.g., "v0.3.9"). + */ + tag = (name: string): GitRef => { + + const ctx = this._ctx.select( + "tag", + { name }, + ) + return new GitRef(ctx) + } + + /** + * tags that match any of the given glob patterns. + * @param opts.patterns Glob patterns (e.g., "refs/tags/v*"). + */ + tags = async ( + opts?: GitRepositoryTagsOpts): Promise => { + const ctx = this._ctx.select( + "tags", + { ...opts}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Returns the changeset of uncommitted changes in the git repository. + */ + uncommitted = (): Changeset => { + + const ctx = this._ctx.select( + "uncommitted", + ) + return new Changeset(ctx) + } + + /** + * The URL of the git repository. + */ + url = async (): Promise => { + if (this._url) { + return this._url + } + + const ctx = this._ctx.select( + "url", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * An internal persistent HTTP state. + */ +export class HTTPState extends BaseClient { + private readonly _id?: ID = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + ) { + super(ctx) + + this._id = _id + } + + /** + * A unique identifier for this HTTPState. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * Image healthcheck configuration. + */ +export class HealthcheckConfig extends BaseClient { + private readonly _id?: ID = undefined + private readonly _interval?: string = undefined + private readonly _retries?: number = undefined + private readonly _shell?: boolean = undefined + private readonly _startInterval?: string = undefined + private readonly _startPeriod?: string = undefined + private readonly _timeout?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _interval?: string, + _retries?: number, + _shell?: boolean, + _startInterval?: string, + _startPeriod?: string, + _timeout?: string, + ) { + super(ctx) + + this._id = _id + this._interval = _interval + this._retries = _retries + this._shell = _shell + this._startInterval = _startInterval + this._startPeriod = _startPeriod + this._timeout = _timeout + } + + /** + * A unique identifier for this HealthcheckConfig. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Healthcheck command arguments. + */ + args = async (): Promise => { + const ctx = this._ctx.select( + "args", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Interval between running healthcheck. Example:30s + */ + interval = async (): Promise => { + if (this._interval) { + return this._interval + } + + const ctx = this._ctx.select( + "interval", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The maximum number of consecutive failures before the container is marked as unhealthy. Example:3 + */ + retries = async (): Promise => { + if (this._retries) { + return this._retries + } + + const ctx = this._ctx.select( + "retries", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Healthcheck command is a shell command. + */ + shell = async (): Promise => { + if (this._shell) { + return this._shell + } + + const ctx = this._ctx.select( + "shell", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * StartInterval configures the duration between checks during the startup phase. Example:5s + */ + startInterval = async (): Promise => { + if (this._startInterval) { + return this._startInterval + } + + const ctx = this._ctx.select( + "startInterval", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * StartPeriod allows for failures during this initial startup period which do not count towards maximum number of retries. Example:0s + */ + startPeriod = async (): Promise => { + if (this._startPeriod) { + return this._startPeriod + } + + const ctx = this._ctx.select( + "startPeriod", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Healthcheck timeout. Example:3s + */ + timeout = async (): Promise => { + if (this._timeout) { + return this._timeout + } + + const ctx = this._ctx.select( + "timeout", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * Information about the host environment. + */ +export class Host extends BaseClient { + private readonly _id?: ID = undefined + private readonly _findUp?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _findUp?: string, + ) { + super(ctx) + + this._id = _id + this._findUp = _findUp + } + + /** + * A unique identifier for this Host. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Accesses a container image on the host. + * @param name Name of the image to access. + */ + containerImage = (name: string): Container => { + + const ctx = this._ctx.select( + "containerImage", + { name }, + ) + return new Container(ctx) + } + + /** + * Accesses a directory on the host. + * @param path Location of the directory to access (e.g., "."). + * @param opts.exclude Exclude artifacts that match the given pattern (e.g., ["node_modules/", ".git*"]). + * @param opts.include Include only artifacts that match the given pattern (e.g., ["app/", "package.*"]). + * @param opts.noCache If true, the directory will always be reloaded from the host. + * @param opts.gitignore Apply .gitignore filter rules inside the directory + */ + directory = (path: string, opts?: HostDirectoryOpts): Directory => { + + const ctx = this._ctx.select( + "directory", + { path, ...opts }, + ) + return new Directory(ctx) + } + + /** + * Accesses a file on the host. + * @param path Location of the file to retrieve (e.g., "README.md"). + * @param opts.noCache If true, the file will always be reloaded from the host. + */ + file = (path: string, opts?: HostFileOpts): File => { + + const ctx = this._ctx.select( + "file", + { path, ...opts }, + ) + return new File(ctx) + } + + /** + * Search for a file or directory by walking up the tree from system workdir. Return its relative path. If no match, return null + * @param name name of the file or directory to search for + */ + findUp = async (name: string, + opts?: HostFindUpOpts): Promise => { + if (this._findUp) { + return this._findUp + } + + const ctx = this._ctx.select( + "findUp", + { name, ...opts}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Creates a service that forwards traffic to a specified address via the host. + * @param ports Ports to expose via the service, forwarding through the host network. + * + * If a port's frontend is unspecified or 0, it defaults to the same as the backend port. + * + * An empty set of ports is not valid; an error will be returned. + * @param opts.host Upstream host to forward traffic to. + */ + service = (ports: PortForward[], opts?: HostServiceOpts): Service => { + + const ctx = this._ctx.select( + "service", + { ports, ...opts }, + ) + return new Service(ctx) + } + + /** + * Creates a tunnel that forwards traffic from the host to a service. + * @param service Service to send traffic from the tunnel. + * @param opts.native Map each service port to the same port on the host, as if the service were running natively. + * + * Note: enabling may result in port conflicts. + * @param opts.ports Configure explicit port forwarding rules for the tunnel. + * + * If a port's frontend is unspecified or 0, a random port will be chosen by the host. + * + * If no ports are given, all of the service's ports are forwarded. If native is true, each port maps to the same port on the host. If native is false, each port maps to a random port chosen by the host. + * + * If ports are given and native is true, the ports are additive. + */ + tunnel = (service: Service, opts?: HostTunnelOpts): Service => { + + const ctx = this._ctx.select( + "tunnel", + { service, ...opts }, + ) + return new Service(ctx) + } + + /** + * Accesses a Unix socket on the host. + * @param path Location of the Unix socket (e.g., "/var/run/docker.sock"). + */ + unixSocket = (path: string): Socket => { + + const ctx = this._ctx.select( + "unixSocket", + { path }, + ) + return new Socket(ctx) + } +} + + + + + + + +/** + * A graphql input type, which is essentially just a group of named args. + * This is currently only used to represent pre-existing usage of graphql input types + * in the core API. It is not used by user modules and shouldn't ever be as user + * module accept input objects via their id rather than graphql input types. + */ +export class InputTypeDef extends BaseClient { + private readonly _id?: ID = undefined + private readonly _name?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _name?: string, + ) { + super(ctx) + + this._id = _id + this._name = _name + } + + /** + * A unique identifier for this InputTypeDef. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Static fields defined on this input object, if any. + */ + fields = async (): Promise => { + type fields = { + id: ID + } + + const ctx = this._ctx.select( + "fields", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new FieldTypeDef(ctx.copy().selectNode(r.id, "FieldTypeDef"))) + } + + /** + * The name of the input object. + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + + + +/** + * A definition of a custom interface defined in a Module. + */ +export class InterfaceTypeDef extends BaseClient { + private readonly _id?: ID = undefined + private readonly _description?: string = undefined + private readonly _name?: string = undefined + private readonly _sourceModuleName?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _description?: string, + _name?: string, + _sourceModuleName?: string, + ) { + super(ctx) + + this._id = _id + this._description = _description + this._name = _name + this._sourceModuleName = _sourceModuleName + } + + /** + * A unique identifier for this InterfaceTypeDef. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The doc string for the interface, if any. + */ + description = async (): Promise => { + if (this._description) { + return this._description + } + + const ctx = this._ctx.select( + "description", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Functions defined on this interface, if any. + */ + functions = async (): Promise => { + type functions = { + id: ID + } + + const ctx = this._ctx.select( + "functions", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new Function_(ctx.copy().selectNode(r.id, "Function"))) + } + + /** + * The name of the interface. + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The location of this interface declaration. + */ + sourceMap = (): SourceMap => { + + const ctx = this._ctx.select( + "sourceMap", + ) + return new SourceMap(ctx) + } + + /** + * If this InterfaceTypeDef is associated with a Module, the name of the module. Unset otherwise. + */ + sourceModuleName = async (): Promise => { + if (this._sourceModuleName) { + return this._sourceModuleName + } + + const ctx = this._ctx.select( + "sourceModuleName", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + + + + +export class JSONValue extends BaseClient { + private readonly _id?: ID = undefined + private readonly _asBoolean?: boolean = undefined + private readonly _asInteger?: number = undefined + private readonly _asString?: string = undefined + private readonly _contents?: JSON = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _asBoolean?: boolean, + _asInteger?: number, + _asString?: string, + _contents?: JSON, + ) { + super(ctx) + + this._id = _id + this._asBoolean = _asBoolean + this._asInteger = _asInteger + this._asString = _asString + this._contents = _contents + } + + /** + * A unique identifier for this JSONValue. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Decode an array from json + */ + asArray = async (): Promise => { + type asArray = { + id: ID + } + + const ctx = this._ctx.select( + "asArray", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new JSONValue(ctx.copy().selectNode(r.id, "JSONValue"))) + } + + /** + * Decode a boolean from json + */ + asBoolean = async (): Promise => { + if (this._asBoolean) { + return this._asBoolean + } + + const ctx = this._ctx.select( + "asBoolean", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Decode an integer from json + */ + asInteger = async (): Promise => { + if (this._asInteger) { + return this._asInteger + } + + const ctx = this._ctx.select( + "asInteger", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Decode a string from json + */ + asString = async (): Promise => { + if (this._asString) { + return this._asString + } + + const ctx = this._ctx.select( + "asString", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Return the value encoded as json + * @param opts.pretty Pretty-print + * @param opts.indent Optional line prefix + */ + contents = async ( + opts?: JSONValueContentsOpts): Promise => { + if (this._contents) { + return this._contents + } + + const ctx = this._ctx.select( + "contents", + { ...opts}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Lookup the field at the given path, and return its value. + * @param path Path of the field to lookup, encoded as an array of field names + */ + field = (path: string[]): JSONValue => { + + const ctx = this._ctx.select( + "field", + { path }, + ) + return new JSONValue(ctx) + } + + /** + * List fields of the encoded object + */ + fields = async (): Promise => { + const ctx = this._ctx.select( + "fields", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Encode a boolean to json + * @param value New boolean value + */ + newBoolean = (value: boolean): JSONValue => { + + const ctx = this._ctx.select( + "newBoolean", + { value }, + ) + return new JSONValue(ctx) + } + + /** + * Encode an integer to json + * @param value New integer value + */ + newInteger = (value: number): JSONValue => { + + const ctx = this._ctx.select( + "newInteger", + { value }, + ) + return new JSONValue(ctx) + } + + /** + * Encode a string to json + * @param value New string value + */ + newString = (value: string): JSONValue => { + + const ctx = this._ctx.select( + "newString", + { value }, + ) + return new JSONValue(ctx) + } + + /** + * Return a new json value, decoded from the given content + * @param contents New JSON-encoded contents + */ + withContents = (contents: JSON): JSONValue => { + + const ctx = this._ctx.select( + "withContents", + { contents }, + ) + return new JSONValue(ctx) + } + + /** + * Set a new field at the given path + * @param path Path of the field to set, encoded as an array of field names + * @param value The new value of the field + */ + withField = (path: string[], value: JSONValue): JSONValue => { + + const ctx = this._ctx.select( + "withField", + { path, value }, + ) + return new JSONValue(ctx) + } + + /** + * Call the provided function with current JSONValue. + * + * This is useful for reusability and readability by not breaking the calling chain. + */ + with = (arg: (param: JSONValue) => JSONValue) => { + return arg(this) + } +} + +/** + * A conversation with a large language model (LLM): queue prompts, expose tools, and step the model until it completes its turn. + */ +export class LLM extends BaseClient { + private readonly _id?: ID = undefined + private readonly _contextWindow?: number = undefined + private readonly _hasPending?: boolean = undefined + private readonly _lastReply?: string = undefined + private readonly _model?: string = undefined + private readonly _portableID?: ID = undefined + private readonly _provider?: string = undefined + private readonly _replay?: ID = undefined + private readonly _sync?: ID = undefined + private readonly _tools?: string = undefined + private readonly _transcript?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _contextWindow?: number, + _hasPending?: boolean, + _lastReply?: string, + _model?: string, + _portableID?: ID, + _provider?: string, + _replay?: ID, + _sync?: ID, + _tools?: string, + _transcript?: string, + ) { + super(ctx) + + this._id = _id + this._contextWindow = _contextWindow + this._hasPending = _hasPending + this._lastReply = _lastReply + this._model = _model + this._portableID = _portableID + this._provider = _provider + this._replay = _replay + this._sync = _sync + this._tools = _tools + this._transcript = _transcript + } + + /** + * A unique identifier for this LLM. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * returns the type of the current state + */ + bindResult = (name: string): Binding => { + + const ctx = this._ctx.select( + "bindResult", + { name }, + ) + return new Binding(ctx) + } + + /** + * The model's total context window in tokens, or null if unknown (e.g. a local or uncatalogued model). + */ + contextWindow = async (): Promise => { + if (this._contextWindow) { + return this._contextWindow + } + + const ctx = this._ctx.select( + "contextWindow", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * return the LLM's current environment + */ + env = (): Env => { + + const ctx = this._ctx.select( + "env", + ) + return new Env(ctx) + } + + /** + * Fork the conversation, so that otherwise-identical follow-ups evaluate independently instead of deduplicating to a single cached result. + * @param label A label distinguishing this fork from its siblings, e.g. "attempt-2" when retrying a flaky evaluation. + */ + fork = (label: string): LLM => { + + const ctx = this._ctx.select( + "fork", + { label }, + ) + return new LLM(ctx) + } + + /** + * Report whether anything is queued to send to the model: an unsent prompt or unevaluated tool results. When true, another step will do work; when false, the turn is complete. + */ + hasPending = async (): Promise => { + if (this._hasPending) { + return this._hasPending + } + + const ctx = this._ctx.select( + "hasPending", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The text of the model's most recent reply. + */ + lastReply = async (): Promise => { + if (this._lastReply) { + return this._lastReply + } + + const ctx = this._ctx.select( + "lastReply", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Send the queued prompt and step the model against the available tools, until it ends its turn: a reply with no tool calls and nothing left queued. + * @param opts.maxSteps Cap the number of steps. The loop fails if the cap is reached before the model ends its turn. + * @param opts.maxTokens Cap the model's output tokens on each step. Defaults to the model's maximum. + */ + loop = (opts?: LLMLoopOpts): LLM => { + + const ctx = this._ctx.select( + "loop", + { ...opts }, + ) + return new LLM(ctx) + } + + /** + * The full message history, as structured messages. + */ + messages = async (): Promise => { + type messages = { + id: ID + } + + const ctx = this._ctx.select( + "messages", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new LLMMessage(ctx.copy().selectNode(r.id, "LLMMessage"))) + } + + /** + * The model the conversation is running against, after resolving any configured default. + */ + model = async (): Promise => { + if (this._model) { + return this._model + } + + const ctx = this._ctx.select( + "model", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * A portable, self-contained ID for the conversation that node() can resolve in any session. Unlike id, which may return an engine-local runtime handle valid only within the current session, this returns the recipe form suitable for persisting and later restoring the conversation. + */ + portableID = async (): Promise => { + if (this._portableID) { + return this._portableID + } + + const ctx = this._ctx.select( + "portableID", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The provider serving the model, e.g. "anthropic", "openai", "google", or "local". + */ + provider = async (): Promise => { + if (this._provider) { + return this._provider + } + + const ctx = this._ctx.select( + "provider", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Re-emit telemetry spans for the full message history, so a loaded conversation displays in the TUI. + */ + replay = async (): Promise => { + const ctx = this._ctx.select( + "replay", + ) + + const response: Awaited = await ctx.execute() + + + return new LLM(ctx.copy().selectNode(response, "LLM")) + } + + /** + * Advance the conversation by a single step: send the queued prompt or tool results to the model, evaluate any tool calls it makes, and queue their results. Use loop to step until the model ends its turn. + * @param opts.maxTokens Cap the model's output tokens for this step. Defaults to the model's maximum. + */ + step = (opts?: LLMStepOpts): LLM => { + + const ctx = this._ctx.select( + "step", + { ...opts }, + ) + return new LLM(ctx) + } + + /** + * Force evaluation of the conversation's pending operations (prompts, steps, loops) in the engine. + */ + sync = async (): Promise => { + const ctx = this._ctx.select( + "sync", + ) + + const response: Awaited = await ctx.execute() + + + return new LLM(ctx.copy().selectNode(response, "LLM")) + } + + /** + * The cumulative token usage, summed across every API call in the conversation. + */ + tokenUsage = (): LLMTokenUsage => { + + const ctx = this._ctx.select( + "tokenUsage", + ) + return new LLMTokenUsage(ctx) + } + + /** + * Render documentation for the tools currently exposed to the model. + */ + tools = async (): Promise => { + if (this._tools) { + return this._tools + } + + const ctx = this._ctx.select( + "tools", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The message history rendered as a plain-text transcript, suitable for feeding back to an LLM (e.g. for summarization). + */ + transcript = async (): Promise => { + if (this._transcript) { + return this._transcript + } + + const ctx = this._ctx.select( + "transcript", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Return a new LLM with the specified function no longer exposed as a tool + * @param typeName The type name whose function will be blocked + * @param function The function to block + * + * Will be converted to lowerCamelCase if necessary. + */ + withBlockedFunction = (typeName: string, function_: string): LLM => { + + const ctx = this._ctx.select( + "withBlockedFunction", + { typeName, + function:function_ }, + ) + return new LLM(ctx) + } + + /** + * allow the LLM to interact with an environment via MCP + */ + withEnv = (env: Env): LLM => { + + const ctx = this._ctx.select( + "withEnv", + { env }, + ) + return new LLM(ctx) + } + + /** + * Add an external MCP server to the LLM + * @param name The name of the MCP server + * @param service The MCP service to run and communicate with over stdio + */ + withMCPServer = (name: string, service: Service): LLM => { + + const ctx = this._ctx.select( + "withMCPServer", + { name, service }, + ) + return new LLM(ctx) + } + + /** + * Change the model for the rest of the conversation. The message history is preserved; the new model takes effect on the next step. + * @param model The model to use, e.g. "claude-sonnet-4-5" or "gpt-5.4". + * @param opts.provider The provider serving the model, e.g. "openai". Overrides the provider otherwise inferred from the model name — useful when the name matches no known pattern (e.g. a fine-tune), or matches the wrong one. + */ + withModel = (model: string, opts?: LLMWithModelOpts): LLM => { + + const ctx = this._ctx.select( + "withModel", + { model, ...opts }, + ) + return new LLM(ctx) + } + + /** + * Track an object so the LLM can reference it in subsequent tool calls. + * @param tag Arbitrary string tag for the object, typically in TypeName#Number format + * @param object The object to track, as a generic ID + */ + withObject = (tag: string, object: ID): LLM => { + + const ctx = this._ctx.select( + "withObject", + { tag, object }, + ) + return new LLM(ctx) + } + + /** + * Queue a user prompt, to be sent to the model on the next step or loop. + * @param prompt The prompt to send + */ + withPrompt = (prompt: string): LLM => { + + const ctx = this._ctx.select( + "withPrompt", + { prompt }, + ) + return new LLM(ctx) + } + + /** + * Queue a file's contents as a user prompt, like withPrompt. + * @param file The file to read the prompt from + */ + withPromptFile = (file: File): LLM => { + + const ctx = this._ctx.select( + "withPromptFile", + { file }, + ) + return new LLM(ctx) + } + + /** + * Append an assistant response to the message history without calling the model, e.g. to reconstruct a conversation from another source. + * @param content The response content + * @param opts.inputTokens Uncached input tokens sent + * @param opts.outputTokens Tokens received from the model, including text and tool calls + * @param opts.cachedTokenReads Cached input tokens read + * @param opts.cachedTokenWrites Cached input tokens written + * @param opts.totalTokens Total tokens consumed by this response + */ + withResponse = (content: LLMContentBlockInput[], opts?: LLMWithResponseOpts): LLM => { + + const ctx = this._ctx.select( + "withResponse", + { content, ...opts }, + ) + return new LLM(ctx) + } + + /** + * Use a static set of tools for method calls, e.g. for MCP clients that do not support dynamic tool registration + */ + withStaticTools = (): LLM => { + + const ctx = this._ctx.select( + "withStaticTools", + ) + return new LLM(ctx) + } + + /** + * Add a system prompt, instructing the model across the whole conversation. + * @param prompt The system prompt to send + */ + withSystemPrompt = (prompt: string): LLM => { + + const ctx = this._ctx.select( + "withSystemPrompt", + { prompt }, + ) + return new LLM(ctx) + } + + /** + * Append the result of a tool call to the message history. + * @param callId The ID of the tool call this result responds to + * @param content The content returned by the tool + * @param errored Whether the tool call resulted in an error + */ + withToolResult = (callId: string, content: string, errored: boolean): LLM => { + + const ctx = this._ctx.select( + "withToolResult", + { callId, content, errored }, + ) + return new LLM(ctx) + } + + /** + * Disable the default system prompt + */ + withoutDefaultSystemPrompt = (): LLM => { + + const ctx = this._ctx.select( + "withoutDefaultSystemPrompt", + ) + return new LLM(ctx) + } + + /** + * Clear the message history, keeping only the system prompts. + */ + withoutMessageHistory = (): LLM => { + + const ctx = this._ctx.select( + "withoutMessageHistory", + ) + return new LLM(ctx) + } + + /** + * Clear the user-added system prompts, keeping only the default system prompt. + */ + withoutSystemPrompts = (): LLM => { + + const ctx = this._ctx.select( + "withoutSystemPrompts", + ) + return new LLM(ctx) + } + + /** + * Call the provided function with current LLM. + * + * This is useful for reusability and readability by not breaking the calling chain. + */ + with = (arg: (param: LLM) => LLM) => { + return arg(this) + } +} + +/** + * A single piece of content within an LLM message. + */ +export class LLMContentBlock extends BaseClient { + private readonly _id?: ID = undefined + private readonly _arguments?: JSON = undefined + private readonly _callId?: string = undefined + private readonly _errored?: boolean = undefined + private readonly _kind?: LLMContentBlockKind = undefined + private readonly _signature?: string = undefined + private readonly _text?: string = undefined + private readonly _toolName?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _arguments?: JSON, + _callId?: string, + _errored?: boolean, + _kind?: LLMContentBlockKind, + _signature?: string, + _text?: string, + _toolName?: string, + ) { + super(ctx) + + this._id = _id + this._arguments = _arguments + this._callId = _callId + this._errored = _errored + this._kind = _kind + this._signature = _signature + this._text = _text + this._toolName = _toolName + } + + /** + * A unique identifier for this LLMContentBlock. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The arguments passed to the tool, JSON-encoded (for TOOL_CALL kind). + */ + arguments = async (): Promise => { + if (this._arguments) { + return this._arguments + } + + const ctx = this._ctx.select( + "arguments", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The unique ID of a tool call (for TOOL_CALL or TOOL_RESULT kinds). + */ + callId = async (): Promise => { + if (this._callId) { + return this._callId + } + + const ctx = this._ctx.select( + "callId", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Whether the tool call resulted in an error (for TOOL_RESULT kind). + */ + errored = async (): Promise => { + if (this._errored) { + return this._errored + } + + const ctx = this._ctx.select( + "errored", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The kind of content block, which determines the other populated fields. + */ + kind = async (): Promise => { + if (this._kind) { + return this._kind + } + + const ctx = this._ctx.select( + "kind", + ) + + const response: Awaited = await ctx.execute() + + return LLMContentBlockKindNameToValue(response) + } + + /** + * Provider-specific opaque data (e.g. Anthropic thinking signature). Preserve it when reconstructing a conversation. + */ + signature = async (): Promise => { + if (this._signature) { + return this._signature + } + + const ctx = this._ctx.select( + "signature", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Text content (for TEXT, THINKING, or TOOL_RESULT kinds). + */ + text = async (): Promise => { + if (this._text) { + return this._text + } + + const ctx = this._ctx.select( + "text", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The name of the tool called (for TOOL_CALL kind). + */ + toolName = async (): Promise => { + if (this._toolName) { + return this._toolName + } + + const ctx = this._ctx.select( + "toolName", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + + + + + +/** + * A single message in an LLM conversation. + */ +export class LLMMessage extends BaseClient { + private readonly _id?: ID = undefined + private readonly _role?: LLMMessageRole = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _role?: LLMMessageRole, + ) { + super(ctx) + + this._id = _id + this._role = _role + } + + /** + * A unique identifier for this LLMMessage. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The message's content blocks, in the order the model produced them. + */ + content = async (): Promise => { + type content = { + id: ID + } + + const ctx = this._ctx.select( + "content", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new LLMContentBlock(ctx.copy().selectNode(r.id, "LLMContentBlock"))) + } + + /** + * The role that produced this message. + */ + role = async (): Promise => { + if (this._role) { + return this._role + } + + const ctx = this._ctx.select( + "role", + ) + + const response: Awaited = await ctx.execute() + + return LLMMessageRoleNameToValue(response) + } + + /** + * Token usage reported by the provider for the API call that produced this message; all zeros except on assistant responses. + */ + tokenUsage = (): LLMTokenUsage => { + + const ctx = this._ctx.select( + "tokenUsage", + ) + return new LLMTokenUsage(ctx) + } +} + + + +/** + * A count of tokens consumed by LLM API calls. + */ +export class LLMTokenUsage extends BaseClient { + private readonly _id?: ID = undefined + private readonly _cachedTokenReads?: number = undefined + private readonly _cachedTokenWrites?: number = undefined + private readonly _inputTokens?: number = undefined + private readonly _outputTokens?: number = undefined + private readonly _totalTokens?: number = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _cachedTokenReads?: number, + _cachedTokenWrites?: number, + _inputTokens?: number, + _outputTokens?: number, + _totalTokens?: number, + ) { + super(ctx) + + this._id = _id + this._cachedTokenReads = _cachedTokenReads + this._cachedTokenWrites = _cachedTokenWrites + this._inputTokens = _inputTokens + this._outputTokens = _outputTokens + this._totalTokens = _totalTokens + } + + /** + * A unique identifier for this LLMTokenUsage. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Input tokens served from the provider's prompt cache. + */ + cachedTokenReads = async (): Promise => { + if (this._cachedTokenReads) { + return this._cachedTokenReads + } + + const ctx = this._ctx.select( + "cachedTokenReads", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Input tokens written to the provider's prompt cache. + */ + cachedTokenWrites = async (): Promise => { + if (this._cachedTokenWrites) { + return this._cachedTokenWrites + } + + const ctx = this._ctx.select( + "cachedTokenWrites", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Uncached input tokens sent to the model. + */ + inputTokens = async (): Promise => { + if (this._inputTokens) { + return this._inputTokens + } + + const ctx = this._ctx.select( + "inputTokens", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Tokens received from the model, including text and tool calls. + */ + outputTokens = async (): Promise => { + if (this._outputTokens) { + return this._outputTokens + } + + const ctx = this._ctx.select( + "outputTokens", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Total tokens consumed, as reported by the provider. + */ + totalTokens = async (): Promise => { + if (this._totalTokens) { + return this._totalTokens + } + + const ctx = this._ctx.select( + "totalTokens", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * A simple key value object that represents a label. + */ +export class Label extends BaseClient { + private readonly _id?: ID = undefined + private readonly _name?: string = undefined + private readonly _value?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _name?: string, + _value?: string, + ) { + super(ctx) + + this._id = _id + this._name = _name + this._value = _value + } + + /** + * A unique identifier for this Label. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The label name. + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The label value. + */ + value = async (): Promise => { + if (this._value) { + return this._value + } + + const ctx = this._ctx.select( + "value", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * A definition of a list type in a Module. + */ +export class ListTypeDef extends BaseClient { + private readonly _id?: ID = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + ) { + super(ctx) + + this._id = _id + } + + /** + * A unique identifier for this ListTypeDef. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The type of the elements in the list. + */ + elementTypeDef = (): TypeDef => { + + const ctx = this._ctx.select( + "elementTypeDef", + ) + return new TypeDef(ctx) + } +} + +/** + * A Dagger module. + */ +export class Module_ extends BaseClient { + private readonly _id?: ID = undefined + private readonly _description?: string = undefined + private readonly _name?: string = undefined + private readonly _serve?: Void = undefined + private readonly _sync?: ID = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _description?: string, + _name?: string, + _serve?: Void, + _sync?: ID, + ) { + super(ctx) + + this._id = _id + this._description = _description + this._name = _name + this._serve = _serve + this._sync = _sync + } + + /** + * A unique identifier for this Module. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Return the check defined by the module with the given name. Must match to exactly one check. + * @param name The name of the check to retrieve + * @experimental + */ + check = (name: string): Check => { + + const ctx = this._ctx.select( + "check", + { name }, + ) + return new Check(ctx) + } + + /** + * Return all checks defined by the module + * @param opts.include Only include checks matching the specified patterns + * @param opts.noGenerate When true, only return annotated check functions; exclude generate-as-checks + * @experimental + */ + checks = (opts?: ModuleChecksOpts): CheckGroup => { + + const ctx = this._ctx.select( + "checks", + { ...opts }, + ) + return new CheckGroup(ctx) + } + + /** + * The dependencies of the module. + */ + dependencies = async (): Promise => { + type dependencies = { + id: ID + } + + const ctx = this._ctx.select( + "dependencies", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new Module_(ctx.copy().selectNode(r.id, "Module"))) + } + + /** + * The doc string of the module, if any + */ + description = async (): Promise => { + if (this._description) { + return this._description + } + + const ctx = this._ctx.select( + "description", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Enumerations served by this module. + */ + enums = async (): Promise => { + type enums = { + id: ID + } + + const ctx = this._ctx.select( + "enums", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new TypeDef(ctx.copy().selectNode(r.id, "TypeDef"))) + } + + /** + * The generated files and directories made on top of the module source's context directory. + */ + generatedContextDirectory = (): Directory => { + + const ctx = this._ctx.select( + "generatedContextDirectory", + ) + return new Directory(ctx) + } + + /** + * Return the generator defined by the module with the given name. Must match to exactly one generator. + * @param name The name of the generator to retrieve + * @experimental + */ + generator = (name: string): Generator => { + + const ctx = this._ctx.select( + "generator", + { name }, + ) + return new Generator(ctx) + } + + /** + * Return all generators defined by the module + * @param opts.include Only include generators matching the specified patterns + * @experimental + */ + generators = (opts?: ModuleGeneratorsOpts): GeneratorGroup => { + + const ctx = this._ctx.select( + "generators", + { ...opts }, + ) + return new GeneratorGroup(ctx) + } + + /** + * Interfaces served by this module. + */ + interfaces = async (): Promise => { + type interfaces = { + id: ID + } + + const ctx = this._ctx.select( + "interfaces", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new TypeDef(ctx.copy().selectNode(r.id, "TypeDef"))) + } + + /** + * The introspection schema JSON file for this module. + * + * This file represents the schema visible to the module's source code, including all core types and those from the dependencies. + * + * Note: this is in the context of a module, so some core types may be hidden. + */ + introspectionSchemaJSON = (): File => { + + const ctx = this._ctx.select( + "introspectionSchemaJSON", + ) + return new File(ctx) + } + + /** + * The name of the module + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Objects served by this module. + */ + objects = async (): Promise => { + type objects = { + id: ID + } + + const ctx = this._ctx.select( + "objects", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new TypeDef(ctx.copy().selectNode(r.id, "TypeDef"))) + } + + /** + * The container that runs the module's entrypoint. It will fail to execute if the module doesn't compile. + */ + runtime = (): Container => { + + const ctx = this._ctx.select( + "runtime", + ) + return new Container(ctx) + } + + /** + * The SDK config used by this module. + */ + sdk = (): SDKConfig => { + + const ctx = this._ctx.select( + "sdk", + ) + return new SDKConfig(ctx) + } + + /** + * Serve a module's API in the current session. + * + * Note: this can only be called once per session. In the future, it could return a stream or service to remove the side effect. + * @param opts.includeDependencies Expose the dependencies of this module to the client + * @param opts.entrypoint Install the module as the entrypoint, promoting its main-object methods onto the Query root + */ + serve = async ( + opts?: ModuleServeOpts): Promise => { + if (this._serve) { + return + } + + const ctx = this._ctx.select( + "serve", + { ...opts}, + ) + + await ctx.execute() + + + } + + /** + * Return all services defined by the module + * @param opts.include Only include services matching the specified patterns + * @experimental + */ + services = (opts?: ModuleServicesOpts): UpGroup => { + + const ctx = this._ctx.select( + "services", + { ...opts }, + ) + return new UpGroup(ctx) + } + + /** + * The source for the module. + */ + source = (): ModuleSource => { + + const ctx = this._ctx.select( + "source", + ) + return new ModuleSource(ctx) + } + + /** + * Forces evaluation of the module, including any loading into the engine and associated validation. + */ + sync = async (): Promise => { + const ctx = this._ctx.select( + "sync", + ) + + const response: Awaited = await ctx.execute() + + + return new Module_(ctx.copy().selectNode(response, "Module")) + } + + /** + * User-defined default values, loaded from local .env files. + */ + userDefaults = (): EnvFile => { + + const ctx = this._ctx.select( + "userDefaults", + ) + return new EnvFile(ctx) + } + + /** + * Retrieves the module with the given description + * @param description The description to set + */ + withDescription = (description: string): Module_ => { + + const ctx = this._ctx.select( + "withDescription", + { description }, + ) + return new Module_(ctx) + } + + /** + * This module plus the given Enum type and associated values + */ + withEnum = (enum_: TypeDef): Module_ => { + + const ctx = this._ctx.select( + "withEnum", + { + enum:enum_ }, + ) + return new Module_(ctx) + } + + /** + * This module plus the given Interface type and associated functions + */ + withInterface = (iface: TypeDef): Module_ => { + + const ctx = this._ctx.select( + "withInterface", + { iface }, + ) + return new Module_(ctx) + } + + /** + * This module plus the given Object type and associated functions. + */ + withObject = (object: TypeDef): Module_ => { + + const ctx = this._ctx.select( + "withObject", + { object }, + ) + return new Module_(ctx) + } + + /** + * Call the provided function with current Module. + * + * This is useful for reusability and readability by not breaking the calling chain. + */ + with = (arg: (param: Module_) => Module_) => { + return arg(this) + } +} + +/** + * The client generated for the module. + */ +export class ModuleConfigClient extends BaseClient { + private readonly _id?: ID = undefined + private readonly _directory?: string = undefined + private readonly _generator?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _directory?: string, + _generator?: string, + ) { + super(ctx) + + this._id = _id + this._directory = _directory + this._generator = _generator + } + + /** + * A unique identifier for this ModuleConfigClient. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The directory the client is generated in. + */ + directory = async (): Promise => { + if (this._directory) { + return this._directory + } + + const ctx = this._ctx.select( + "directory", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The generator to use + */ + generator = async (): Promise => { + if (this._generator) { + return this._generator + } + + const ctx = this._ctx.select( + "generator", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * The source needed to load and run a module, along with any metadata about the source such as versions/urls/etc. + */ +export class ModuleSource extends BaseClient { + private readonly _id?: ID = undefined + private readonly _asString?: string = undefined + private readonly _cloneRef?: string = undefined + private readonly _commit?: string = undefined + private readonly _configExists?: boolean = undefined + private readonly _digest?: string = undefined + private readonly _engineVersion?: string = undefined + private readonly _htmlRepoURL?: string = undefined + private readonly _htmlURL?: string = undefined + private readonly _kind?: ModuleSourceKind = undefined + private readonly _localContextDirectoryPath?: string = undefined + private readonly _moduleName?: string = undefined + private readonly _moduleOriginalName?: string = undefined + private readonly _originalSubpath?: string = undefined + private readonly _pin?: string = undefined + private readonly _repoRootPath?: string = undefined + private readonly _sourceRootSubpath?: string = undefined + private readonly _sourceSubpath?: string = undefined + private readonly _sync?: ID = undefined + private readonly _version?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _asString?: string, + _cloneRef?: string, + _commit?: string, + _configExists?: boolean, + _digest?: string, + _engineVersion?: string, + _htmlRepoURL?: string, + _htmlURL?: string, + _kind?: ModuleSourceKind, + _localContextDirectoryPath?: string, + _moduleName?: string, + _moduleOriginalName?: string, + _originalSubpath?: string, + _pin?: string, + _repoRootPath?: string, + _sourceRootSubpath?: string, + _sourceSubpath?: string, + _sync?: ID, + _version?: string, + ) { + super(ctx) + + this._id = _id + this._asString = _asString + this._cloneRef = _cloneRef + this._commit = _commit + this._configExists = _configExists + this._digest = _digest + this._engineVersion = _engineVersion + this._htmlRepoURL = _htmlRepoURL + this._htmlURL = _htmlURL + this._kind = _kind + this._localContextDirectoryPath = _localContextDirectoryPath + this._moduleName = _moduleName + this._moduleOriginalName = _moduleOriginalName + this._originalSubpath = _originalSubpath + this._pin = _pin + this._repoRootPath = _repoRootPath + this._sourceRootSubpath = _sourceRootSubpath + this._sourceSubpath = _sourceSubpath + this._sync = _sync + this._version = _version + } + + /** + * A unique identifier for this ModuleSource. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Load the source as a module. If this is a local source, the parent directory must have been provided during module source creation + */ + asModule = (): Module_ => { + + const ctx = this._ctx.select( + "asModule", + ) + return new Module_(ctx) + } + + /** + * A human readable ref string representation of this module source. + */ + asString = async (): Promise => { + if (this._asString) { + return this._asString + } + + const ctx = this._ctx.select( + "asString", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The blueprint referenced by the module source. + * @deprecated Legacy dagger.json field. Generic module loading no longer honors it; use workspace modules in dagger.toml instead. + */ + blueprint = (): ModuleSource => { + + const ctx = this._ctx.select( + "blueprint", + ) + return new ModuleSource(ctx) + } + + /** + * The client-facing introspection schema JSON file for this module source. + * + * This is the schema consumed by client codegen: unlike introspectionSchemaJSON (the module-facing schema), it hides no core types and installs this module (reached via dag.) so a generated client can bind it. The module's dependencies are excluded: a client is generated for a single module plus core, not its dependency graph. + */ + clientSchemaIntrospectionJSON = (): File => { + + const ctx = this._ctx.select( + "clientSchemaIntrospectionJSON", + ) + return new File(ctx) + } + + /** + * The ref to clone the root of the git repo from. Only valid for git sources. + */ + cloneRef = async (): Promise => { + if (this._cloneRef) { + return this._cloneRef + } + + const ctx = this._ctx.select( + "cloneRef", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The resolved commit of the git repo this source points to. + */ + commit = async (): Promise => { + if (this._commit) { + return this._commit + } + + const ctx = this._ctx.select( + "commit", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The clients generated for the module. + */ + configClients = async (): Promise => { + type configClients = { + id: ID + } + + const ctx = this._ctx.select( + "configClients", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new ModuleConfigClient(ctx.copy().selectNode(r.id, "ModuleConfigClient"))) + } + + /** + * Whether an existing module config file was found. + */ + configExists = async (): Promise => { + if (this._configExists) { + return this._configExists + } + + const ctx = this._ctx.select( + "configExists", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The full directory loaded for the module source, including the source code as a subdirectory. + */ + contextDirectory = (): Directory => { + + const ctx = this._ctx.select( + "contextDirectory", + ) + return new Directory(ctx) + } + + /** + * The dependencies of the module source. + */ + dependencies = async (): Promise => { + type dependencies = { + id: ID + } + + const ctx = this._ctx.select( + "dependencies", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new ModuleSource(ctx.copy().selectNode(r.id, "ModuleSource"))) + } + + /** + * A content-hash of the module source. Module sources with the same digest will output the same generated context and convert into the same module instance. + */ + digest = async (): Promise => { + if (this._digest) { + return this._digest + } + + const ctx = this._ctx.select( + "digest", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The directory containing the module configuration and source code (source code may be in a subdir). + * @param path A subpath from the source directory to select. + */ + directory = (path: string): Directory => { + + const ctx = this._ctx.select( + "directory", + { path }, + ) + return new Directory(ctx) + } + + /** + * The engine version of the module. + */ + engineVersion = async (): Promise => { + if (this._engineVersion) { + return this._engineVersion + } + + const ctx = this._ctx.select( + "engineVersion", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Generate this module's transitive local dependency closure and return the staged changes as a single changeset against the unstaged workspace root. + * + * Each local dependency is generated by its own SDK against a workspace scoped to it, carrying the dependency's own already-generated dependencies. Remote (git) dependencies are assumed committed and skipped. Overlay the result onto the workspace before generating this module; it is not this module's own generated code. + * @param workspace The workspace to generate the local dependencies against. + */ + generateLocalDependencies = (workspace: Workspace): Changeset => { + + const ctx = this._ctx.select( + "generateLocalDependencies", + { workspace }, + ) + return new Changeset(ctx) + } + + /** + * The generated files and directories made on top of the module source's context directory, returned as a Changeset. + */ + generatedContextChangeset = (): Changeset => { + + const ctx = this._ctx.select( + "generatedContextChangeset", + ) + return new Changeset(ctx) + } + + /** + * The generated files and directories made on top of the module source's context directory. + */ + generatedContextDirectory = (): Directory => { + + const ctx = this._ctx.select( + "generatedContextDirectory", + ) + return new Directory(ctx) + } + + /** + * The URL to access the web view of the repository (e.g., GitHub, GitLab, Bitbucket). + */ + htmlRepoURL = async (): Promise => { + if (this._htmlRepoURL) { + return this._htmlRepoURL + } + + const ctx = this._ctx.select( + "htmlRepoURL", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The URL to the source's git repo in a web browser. Only valid for git sources. + */ + htmlURL = async (): Promise => { + if (this._htmlURL) { + return this._htmlURL + } + + const ctx = this._ctx.select( + "htmlURL", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The introspection schema JSON file for this module source. + * + * This file represents the schema visible to the module's source code, including all core types and those from the dependencies. + * + * Note: this is in the context of a module, so some core types may be hidden. + */ + introspectionSchemaJSON = (): File => { + + const ctx = this._ctx.select( + "introspectionSchemaJSON", + ) + return new File(ctx) + } + + /** + * The kind of module source (currently local, git or dir). + */ + kind = async (): Promise => { + if (this._kind) { + return this._kind + } + + const ctx = this._ctx.select( + "kind", + ) + + const response: Awaited = await ctx.execute() + + return ModuleSourceKindNameToValue(response) + } + + /** + * The full absolute path to the context directory on the caller's host filesystem that this module source is loaded from. Only valid for local module sources. + */ + localContextDirectoryPath = async (): Promise => { + if (this._localContextDirectoryPath) { + return this._localContextDirectoryPath + } + + const ctx = this._ctx.select( + "localContextDirectoryPath", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The name of the module, including any setting via the withName API. + */ + moduleName = async (): Promise => { + if (this._moduleName) { + return this._moduleName + } + + const ctx = this._ctx.select( + "moduleName", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The original name of the module as read from the module config file (or set for the first time with the withName API). + */ + moduleOriginalName = async (): Promise => { + if (this._moduleOriginalName) { + return this._moduleOriginalName + } + + const ctx = this._ctx.select( + "moduleOriginalName", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The original subpath used when instantiating this module source, relative to the context directory. + */ + originalSubpath = async (): Promise => { + if (this._originalSubpath) { + return this._originalSubpath + } + + const ctx = this._ctx.select( + "originalSubpath", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The pinned version of this module source. + */ + pin = async (): Promise => { + if (this._pin) { + return this._pin + } + + const ctx = this._ctx.select( + "pin", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The import path corresponding to the root of the git repo this source points to. Only valid for git sources. + */ + repoRootPath = async (): Promise => { + if (this._repoRootPath) { + return this._repoRootPath + } + + const ctx = this._ctx.select( + "repoRootPath", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The SDK configuration of the module. + */ + sdk = (): SDKConfig => { + + const ctx = this._ctx.select( + "sdk", + ) + return new SDKConfig(ctx) + } + + /** + * The path, relative to the context directory, that contains the module config. + */ + sourceRootSubpath = async (): Promise => { + if (this._sourceRootSubpath) { + return this._sourceRootSubpath + } + + const ctx = this._ctx.select( + "sourceRootSubpath", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The path to the directory containing the module's source code, relative to the context directory. + */ + sourceSubpath = async (): Promise => { + if (this._sourceSubpath) { + return this._sourceSubpath + } + + const ctx = this._ctx.select( + "sourceSubpath", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Forces evaluation of the module source, including any loading into the engine and associated validation. + */ + sync = async (): Promise => { + const ctx = this._ctx.select( + "sync", + ) + + const response: Awaited = await ctx.execute() + + + return new ModuleSource(ctx.copy().selectNode(response, "ModuleSource")) + } + + /** + * The toolchains referenced by the module source. + * @deprecated Legacy dagger.json field. Generic module loading no longer honors it; use workspace modules in dagger.toml instead. + */ + toolchains = async (): Promise => { + type toolchains = { + id: ID + } + + const ctx = this._ctx.select( + "toolchains", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new ModuleSource(ctx.copy().selectNode(r.id, "ModuleSource"))) + } + + /** + * The module's dagger.json with any in-memory edits from with* APIs applied, as a diff relative to the source's context directory. + * + * Unlike generatedContextDirectory, this does not run codegen and does not validate the engine version against the running engine, so it can be used to declare an engine requirement newer than the running engine. Loading or serving such a module still fails at moduleSource.asModule. + */ + updatedConfigDirectory = (): Directory => { + + const ctx = this._ctx.select( + "updatedConfigDirectory", + ) + return new Directory(ctx) + } + + /** + * User-defined defaults read from local .env files + */ + userDefaults = (): EnvFile => { + + const ctx = this._ctx.select( + "userDefaults", + ) + return new EnvFile(ctx) + } + + /** + * The specified version of the git repo this source points to. + */ + version = async (): Promise => { + if (this._version) { + return this._version + } + + const ctx = this._ctx.select( + "version", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Set a blueprint for the module source. + * @param blueprint The blueprint module to set. + * @deprecated Legacy dagger.json field. Generic module loading no longer honors it; use workspace modules in `dagger.toml` instead. + */ + withBlueprint = (blueprint: ModuleSource): ModuleSource => { + + const ctx = this._ctx.select( + "withBlueprint", + { blueprint }, + ) + return new ModuleSource(ctx) + } + + /** + * Update the module source with a new client to generate. + * @param generator The generator to use + * @param outputDir The output directory for the generated client. + */ + withClient = (generator: string, outputDir: string): ModuleSource => { + + const ctx = this._ctx.select( + "withClient", + { generator, outputDir }, + ) + return new ModuleSource(ctx) + } + + /** + * Append the provided dependencies to the module source's dependency list. + * @param dependencies The dependencies to append. + */ + withDependencies = (dependencies: ModuleSource[]): ModuleSource => { + + const ctx = this._ctx.select( + "withDependencies", + { dependencies }, + ) + return new ModuleSource(ctx) + } + + /** + * Upgrade the engine version of the module to the given value. + * @param version The engine version to upgrade to. + */ + withEngineVersion = (version: string): ModuleSource => { + + const ctx = this._ctx.select( + "withEngineVersion", + { version }, + ) + return new ModuleSource(ctx) + } + + /** + * Enable the experimental features for the module source. + * @param features The experimental features to enable. + */ + withExperimentalFeatures = (features: ModuleSourceExperimentalFeature[]): ModuleSource => { + + const ctx = this._ctx.select( + "withExperimentalFeatures", + { features }, + ) + return new ModuleSource(ctx) + } + + /** + * Update the module source with additional include patterns for files+directories from its context that are required for building it + * @param patterns The new additional include patterns. + */ + withIncludes = (patterns: string[]): ModuleSource => { + + const ctx = this._ctx.select( + "withIncludes", + { patterns }, + ) + return new ModuleSource(ctx) + } + + /** + * Update the module source with a new name. + * @param name The name to set. + */ + withName = (name: string): ModuleSource => { + + const ctx = this._ctx.select( + "withName", + { name }, + ) + return new ModuleSource(ctx) + } + + /** + * Update the module source with a new SDK. + * @param source The SDK source to set. + */ + withSDK = (source: string): ModuleSource => { + + const ctx = this._ctx.select( + "withSDK", + { source }, + ) + return new ModuleSource(ctx) + } + + /** + * Update the module source with a new source subpath. + * @param path The path to set as the source subpath. Must be relative to the module source's source root directory. + */ + withSourceSubpath = (path: string): ModuleSource => { + + const ctx = this._ctx.select( + "withSourceSubpath", + { path }, + ) + return new ModuleSource(ctx) + } + + /** + * Add toolchains to the module source. + * @param toolchains The toolchain modules to add. + * @deprecated Legacy dagger.json field. Generic module loading no longer honors it; use workspace modules in `dagger.toml` instead. + */ + withToolchains = (toolchains: ModuleSource[]): ModuleSource => { + + const ctx = this._ctx.select( + "withToolchains", + { toolchains }, + ) + return new ModuleSource(ctx) + } + + /** + * Update the blueprint module to the latest version. + * @deprecated Legacy dagger.json field. Generic module loading no longer honors it; use workspace modules in `dagger.toml` instead. + */ + withUpdateBlueprint = (): ModuleSource => { + + const ctx = this._ctx.select( + "withUpdateBlueprint", + ) + return new ModuleSource(ctx) + } + + /** + * Update one or more module dependencies. + * @param dependencies The dependencies to update. + */ + withUpdateDependencies = (dependencies: string[]): ModuleSource => { + + const ctx = this._ctx.select( + "withUpdateDependencies", + { dependencies }, + ) + return new ModuleSource(ctx) + } + + /** + * Update one or more toolchains. + * @param toolchains The toolchains to update. + * @deprecated Legacy dagger.json field. Generic module loading no longer honors it; use workspace modules in `dagger.toml` instead. + */ + withUpdateToolchains = (toolchains: string[]): ModuleSource => { + + const ctx = this._ctx.select( + "withUpdateToolchains", + { toolchains }, + ) + return new ModuleSource(ctx) + } + + /** + * Update one or more clients. + * @param clients The clients to update + */ + withUpdatedClients = (clients: string[]): ModuleSource => { + + const ctx = this._ctx.select( + "withUpdatedClients", + { clients }, + ) + return new ModuleSource(ctx) + } + + /** + * Remove the current blueprint from the module source. + * @deprecated Legacy dagger.json field. Generic module loading no longer honors it; use workspace modules in `dagger.toml` instead. + */ + withoutBlueprint = (): ModuleSource => { + + const ctx = this._ctx.select( + "withoutBlueprint", + ) + return new ModuleSource(ctx) + } + + /** + * Remove a client from the module source. + * @param path The path of the client to remove. + */ + withoutClient = (path: string): ModuleSource => { + + const ctx = this._ctx.select( + "withoutClient", + { path }, + ) + return new ModuleSource(ctx) + } + + /** + * Remove the provided dependencies from the module source's dependency list. + * @param dependencies The dependencies to remove. + */ + withoutDependencies = (dependencies: string[]): ModuleSource => { + + const ctx = this._ctx.select( + "withoutDependencies", + { dependencies }, + ) + return new ModuleSource(ctx) + } + + /** + * Disable experimental features for the module source. + * @param features The experimental features to disable. + */ + withoutExperimentalFeatures = (features: ModuleSourceExperimentalFeature[]): ModuleSource => { + + const ctx = this._ctx.select( + "withoutExperimentalFeatures", + { features }, + ) + return new ModuleSource(ctx) + } + + /** + * Remove the provided toolchains from the module source. + * @param toolchains The toolchains to remove. + * @deprecated Legacy dagger.json field. Generic module loading no longer honors it; use workspace modules in `dagger.toml` instead. + */ + withoutToolchains = (toolchains: string[]): ModuleSource => { + + const ctx = this._ctx.select( + "withoutToolchains", + { toolchains }, + ) + return new ModuleSource(ctx) + } + + /** + * Call the provided function with current ModuleSource. + * + * This is useful for reusability and readability by not breaking the calling chain. + */ + with = (arg: (param: ModuleSource) => ModuleSource) => { + return arg(this) + } +} + + + + + + + +/** + * An object with a globally unique ID. + */ +export interface Node { + id(): Promise +} + +export class _NodeClient extends BaseClient { + private readonly _id?: ID = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + ) { + super(ctx) + + this._id = _id + } + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * A definition of a custom object defined in a Module. + */ +export class ObjectTypeDef extends BaseClient { + private readonly _id?: ID = undefined + private readonly _deprecated?: string = undefined + private readonly _description?: string = undefined + private readonly _name?: string = undefined + private readonly _sourceModuleName?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _deprecated?: string, + _description?: string, + _name?: string, + _sourceModuleName?: string, + ) { + super(ctx) + + this._id = _id + this._deprecated = _deprecated + this._description = _description + this._name = _name + this._sourceModuleName = _sourceModuleName + } + + /** + * A unique identifier for this ObjectTypeDef. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The function used to construct new instances of this object, if any. + */ + constructor_ = (): Function_ => { + + const ctx = this._ctx.select( + "constructor", + ) + return new Function_(ctx) + } + + /** + * The reason this enum member is deprecated, if any. + */ + deprecated = async (): Promise => { + if (this._deprecated) { + return this._deprecated + } + + const ctx = this._ctx.select( + "deprecated", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The doc string for the object, if any. + */ + description = async (): Promise => { + if (this._description) { + return this._description + } + + const ctx = this._ctx.select( + "description", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Static fields defined on this object, if any. + */ + fields = async (): Promise => { + type fields = { + id: ID + } + + const ctx = this._ctx.select( + "fields", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new FieldTypeDef(ctx.copy().selectNode(r.id, "FieldTypeDef"))) + } + + /** + * Functions defined on this object, if any. + */ + functions = async (): Promise => { + type functions = { + id: ID + } + + const ctx = this._ctx.select( + "functions", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new Function_(ctx.copy().selectNode(r.id, "Function"))) + } + + /** + * The name of the object. + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The location of this object declaration. + */ + sourceMap = (): SourceMap => { + + const ctx = this._ctx.select( + "sourceMap", + ) + return new SourceMap(ctx) + } + + /** + * If this ObjectTypeDef is associated with a Module, the name of the module. Unset otherwise. + */ + sourceModuleName = async (): Promise => { + if (this._sourceModuleName) { + return this._sourceModuleName + } + + const ctx = this._ctx.select( + "sourceModuleName", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + + + + + +/** + * A port exposed by a container. + */ +export class Port extends BaseClient { + private readonly _id?: ID = undefined + private readonly _description?: string = undefined + private readonly _experimentalSkipHealthcheck?: boolean = undefined + private readonly _port?: number = undefined + private readonly _protocol?: NetworkProtocol = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _description?: string, + _experimentalSkipHealthcheck?: boolean, + _port?: number, + _protocol?: NetworkProtocol, + ) { + super(ctx) + + this._id = _id + this._description = _description + this._experimentalSkipHealthcheck = _experimentalSkipHealthcheck + this._port = _port + this._protocol = _protocol + } + + /** + * A unique identifier for this Port. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The port description. + */ + description = async (): Promise => { + if (this._description) { + return this._description + } + + const ctx = this._ctx.select( + "description", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Skip the health check when run as a service. + */ + experimentalSkipHealthcheck = async (): Promise => { + if (this._experimentalSkipHealthcheck) { + return this._experimentalSkipHealthcheck + } + + const ctx = this._ctx.select( + "experimentalSkipHealthcheck", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The port number. + */ + port = async (): Promise => { + if (this._port) { + return this._port + } + + const ctx = this._ctx.select( + "port", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The transport layer protocol. + */ + protocol = async (): Promise => { + if (this._protocol) { + return this._protocol + } + + const ctx = this._ctx.select( + "protocol", + ) + + const response: Awaited = await ctx.execute() + + return NetworkProtocolNameToValue(response) + } +} + + + +/** + * The root of the DAG. + */ +export class Client extends BaseClient { + private readonly _id?: ID = undefined + private readonly _defaultPlatform?: Platform = undefined + private readonly _version?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _defaultPlatform?: Platform, + _version?: string, + ) { + super(ctx) + + this._id = _id + this._defaultPlatform = _defaultPlatform + this._version = _version + } + + /** + * Get the Raw GraphQL client. + */ + public getGQLClient() { + return this._ctx.getGQLClient() + } + + /** + * A unique identifier for this Query. + */ + id = async (): Promise => { + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * initialize an address to load directories, containers, secrets or other object types. + */ + address = (value: string): Address => { + + const ctx = this._ctx.select( + "address", + { value }, + ) + return new Address(ctx) + } + + /** + * Constructs a cache volume for a given cache key. + * @param key A string identifier to target this cache volume (e.g., "modules-cache"). + * @param opts.source Identifier of the directory to use as the cache volume's root. + * @param opts.sharing Sharing mode of the cache volume. + * @param opts.owner A user:group to set for the cache volume root. + * + * The user and group can either be an ID (1000:1000) or a name (foo:bar). + * + * If the group is omitted, it defaults to the same as the user. + */ + cacheVolume = (key: string, opts?: ClientCacheVolumeOpts): CacheVolume => { + const metadata = { + sharing: { is_enum: true, value_to_name: CacheSharingModeValueToName }, + } + + + const ctx = this._ctx.select( + "cacheVolume", + { key, ...opts, __metadata: metadata }, + ) + return new CacheVolume(ctx) + } + + /** + * Creates an empty changeset + */ + changeset = (): Changeset => { + + const ctx = this._ctx.select( + "changeset", + ) + return new Changeset(ctx) + } + + /** + * Dagger Cloud configuration and state + */ + cloud = (): Cloud => { + + const ctx = this._ctx.select( + "cloud", + ) + return new Cloud(ctx) + } + + /** + * Creates a scratch container, with no image or metadata. + * + * To pull an image, follow up with the "from" function. + * @param opts.platform Platform to initialize the container with. Defaults to the native platform of the current engine + */ + container = (opts?: ClientContainerOpts): Container => { + + const ctx = this._ctx.select( + "container", + { ...opts }, + ) + return new Container(ctx) + } + + /** + * Returns the current environment + * + * When called from a function invoked via an LLM tool call, this will be the LLM's current environment, including any modifications made through calling tools. Env values returned by functions become the new environment for subsequent calls, and Changeset values returned by functions are applied to the environment's workspace. + * + * When called from a module function outside of an LLM, this returns an Env with the current module installed, and with the current module's source directory as its workspace. + * @experimental + */ + currentEnv = (): Env => { + + const ctx = this._ctx.select( + "currentEnv", + ) + return new Env(ctx) + } + + /** + * The FunctionCall context that the SDK caller is currently executing in. + * + * If the caller is not currently executing in a function, this will return an error. + */ + currentFunctionCall = (): FunctionCall => { + + const ctx = this._ctx.select( + "currentFunctionCall", + ) + return new FunctionCall(ctx) + } + + /** + * The module currently being served in the session, if any. + */ + currentModule = (): CurrentModule => { + + const ctx = this._ctx.select( + "currentModule", + ) + return new CurrentModule(ctx) + } + + /** + * The TypeDef representations of the objects currently being served in the session. + * @param opts.returnAllTypes Return the full referenced typedef closure instead of only top-level served typedefs. + * @param opts.hideCore Strip core API functions from the Query type, leaving only module-sourced functions (constructors, entrypoint proxies, etc.). + * + * Core types (Container, Directory, etc.) are kept so return types and method chaining still work. + */ + currentTypeDefs = async ( + opts?: ClientCurrentTypeDefsOpts): Promise => { + type currentTypeDefs = { + id: ID + } + + const ctx = this._ctx.select( + "currentTypeDefs", + { ...opts}, + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new TypeDef(ctx.copy().selectNode(r.id, "TypeDef"))) + } + + /** + * Detect and return the current workspace. + * @experimental + */ + currentWorkspace = (): Workspace => { + + const ctx = this._ctx.select( + "currentWorkspace", + ) + return new Workspace(ctx) + } + + /** + * The default platform of the engine. + */ + defaultPlatform = async (): Promise => { + const ctx = this._ctx.select( + "defaultPlatform", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Creates an empty directory. + */ + directory = (): Directory => { + + const ctx = this._ctx.select( + "directory", + ) + return new Directory(ctx) + } + + /** + * The Dagger engine container configuration and state + */ + engine = (): Engine => { + + const ctx = this._ctx.select( + "engine", + ) + return new Engine(ctx) + } + + /** + * Initializes a new environment + * @param opts.privileged Give the environment the same privileges as the caller: core API including host access, current module, and dependencies + * @param opts.writable Allow new outputs to be declared and saved in the environment + * @experimental + */ + env = (opts?: ClientEnvOpts): Env => { + + const ctx = this._ctx.select( + "env", + { ...opts }, + ) + return new Env(ctx) + } + + /** + * Initialize an environment file + * @param opts.expand Replace "${VAR}" or "$VAR" with the value of other vars + */ + envFile = (opts?: ClientEnvFileOpts): EnvFile => { + + const ctx = this._ctx.select( + "envFile", + { ...opts }, + ) + return new EnvFile(ctx) + } + + /** + * Create a new error. + * @param message A brief description of the error. + */ + error = (message: string): Error => { + + const ctx = this._ctx.select( + "error", + { message }, + ) + return new Error(ctx) + } + + /** + * Creates a file with the specified contents. + * @param name Name of the new file. Example: "foo.txt" + * @param contents Contents of the new file. Example: "Hello world!" + * @param opts.permissions Permissions of the new file. Example: 0600 + */ + file = (name: string, contents: string, opts?: ClientFileOpts): File => { + + const ctx = this._ctx.select( + "file", + { name, contents, ...opts }, + ) + return new File(ctx) + } + + /** + * Creates a function. + * @param name Name of the function, in its original format from the implementation language. + * @param returnType Return type of the function. + */ + function_ = (name: string, returnType: TypeDef): Function_ => { + + const ctx = this._ctx.select( + "function", + { name, returnType }, + ) + return new Function_(ctx) + } + + /** + * Create a code generation result, given a directory containing the generated code. + */ + generatedCode = (code: Directory): GeneratedCode => { + + const ctx = this._ctx.select( + "generatedCode", + { code }, + ) + return new GeneratedCode(ctx) + } + + /** + * Queries a Git repository. + * @param url URL of the git repository. + * + * Can be formatted as `https://{host}/{owner}/{repo}`, `git@{host}:{owner}/{repo}`. + * + * Suffix ".git" is optional. + * @param opts.keepGitDir DEPRECATED: Set to true to keep .git directory. + * @param opts.sshKnownHosts Set SSH known hosts + * @param opts.sshAuthSocket Set SSH auth socket + * @param opts.httpAuthUsername Username used to populate the password during basic HTTP Authorization + * @param opts.httpAuthToken Secret used to populate the password during basic HTTP Authorization + * @param opts.httpAuthHeader Secret used to populate the Authorization HTTP header + * @param opts.experimentalServiceHost A service which must be started before the repo is fetched. + */ + git = (url: string, opts?: ClientGitOpts): GitRepository => { + + const ctx = this._ctx.select( + "git", + { url, ...opts }, + ) + return new GitRepository(ctx) + } + + /** + * Queries the host environment. + */ + host = (): Host => { + + const ctx = this._ctx.select( + "host", + ) + return new Host(ctx) + } + + /** + * Returns a file containing an http remote url content. + * @param url HTTP url to get the content from (e.g., "https://docs.dagger.io"). + * @param opts.name File name to use for the file. Defaults to the last part of the URL. + * @param opts.permissions Permissions to set on the file. + * @param opts.checksum Expected digest of the downloaded content (e.g., "sha256:..."). + * @param opts.authHeader Secret used to populate the Authorization HTTP header + * @param opts.experimentalServiceHost A service which must be started before the URL is fetched. + */ + http = (url: string, opts?: ClientHttpOpts): File => { + + const ctx = this._ctx.select( + "http", + { url, ...opts }, + ) + return new File(ctx) + } + + /** + * Initialize a JSON value + */ + json = (): JSONValue => { + + const ctx = this._ctx.select( + "json", + ) + return new JSONValue(ctx) + } + + /** + * Initialize a new LLM conversation. + * @param opts.model The model to converse with, e.g. "claude-sonnet-4-5" or "gpt-5.4". Defaults to the configured default model. + * @param opts.provider The provider serving the model, e.g. "openai". Overrides the provider otherwise inferred from the model name — useful when the name matches no known pattern (e.g. a fine-tune), or matches the wrong one. + * @experimental + */ + llm = (opts?: ClientLLMOpts): LLM => { + + const ctx = this._ctx.select( + "llm", + { ...opts }, + ) + return new LLM(ctx) + } + + /** + * Create a new module. + */ + module_ = (): Module_ => { + + const ctx = this._ctx.select( + "module", + ) + return new Module_(ctx) + } + + /** + * Create a new module source instance from a source ref string + * @param refString The string ref representation of the module source + * @param opts.refPin The pinned version of the module source + * @param opts.disableFindUp If true, do not attempt to find a module config file in a parent directory of the provided path. Only relevant for local module sources. + * @param opts.allowNotExists If true, do not error out if the provided ref string is a local path and does not exist yet. Useful when initializing new modules in directories that don't exist yet. + * @param opts.requireKind If set, error out if the ref string is not of the provided requireKind. + */ + moduleSource = (refString: string, opts?: ClientModuleSourceOpts): ModuleSource => { + const metadata = { + requireKind: { is_enum: true, value_to_name: ModuleSourceKindValueToName }, + } + + + const ctx = this._ctx.select( + "moduleSource", + { refString, ...opts, __metadata: metadata }, + ) + return new ModuleSource(ctx) + } + + /** + * Load any object by its ID. + */ + node = (id: ID): Node => { + + const ctx = this._ctx.select( + "node", + { id }, + ) + return new _NodeClient(ctx) + } + + /** + * Load a GraphQL introspection schema for merging. + * @param json The introspection schema JSON to load. + */ + schema = (json: JSON): Schema => { + + const ctx = this._ctx.select( + "schema", + { json }, + ) + return new Schema(ctx) + } + + /** + * Creates a new secret. + * @param uri The URI of the secret store + * @param opts.cacheKey If set, the given string will be used as the cache key for this secret. This means that any secrets with the same cache key will be considered equivalent in terms of cache lookups, even if they have different URIs or plaintext values. + * + * For example, two secrets with the same cache key provided as secret env vars to other wise equivalent containers will result in the container withExecs hitting the cache for each other. + * + * If not set, the cache key for the secret will be derived from its plaintext value as looked up when the secret is constructed. + */ + secret = (uri: string, opts?: ClientSecretOpts): Secret => { + + const ctx = this._ctx.select( + "secret", + { uri, ...opts }, + ) + return new Secret(ctx) + } + + /** + * Sets a secret given a user defined name to its plaintext and returns the secret. + * + * The plaintext value is limited to a size of 128000 bytes. + * @param name The user defined name for this secret + * @param plaintext The plaintext of the secret + */ + setSecret = (name: string, plaintext: string): Secret => { + + const ctx = this._ctx.select( + "setSecret", + { name, plaintext }, + ) + return new Secret(ctx) + } + + /** + * Creates source map metadata. + * @param filename The filename from the module source. + * @param line The line number within the filename. + * @param column The column number within the line. + */ + sourceMap = (filename: string, line: number, column: number): SourceMap => { + + const ctx = this._ctx.select( + "sourceMap", + { filename, line, column }, + ) + return new SourceMap(ctx) + } + + /** + * Constructs an SSHFS volume. + * @param endpoint SSHFS endpoint URL in the form sshfs://user@host[:port]/absolute/path. + * @param privateKey Private key secret used to authenticate to the remote host. + * @param opts.knownHosts known_hosts material used to verify the remote host key. Required unless insecureSkipHostKeyCheck is true. + * @param opts.cacheKey Optional cache equivalence key. If set, volumes with the same cacheKey may be considered equivalent for cache lookups, still subject to their resource dependencies. + * @param opts.insecureSkipHostKeyCheck Disable SSH host key verification. This is insecure and must be explicitly opted into. + * @param opts.experimentalServiceHost Service to use as the SSHFS network endpoint while verifying the original host key. + */ + sshfsVolume = (endpoint: string, privateKey: Secret, opts?: ClientSshfsVolumeOpts): Volume => { + + const ctx = this._ctx.select( + "sshfsVolume", + { endpoint, privateKey, ...opts }, + ) + return new Volume(ctx) + } + + /** + * Create a new TypeDef. + */ + typeDef = (): TypeDef => { + + const ctx = this._ctx.select( + "typeDef", + ) + return new TypeDef(ctx) + } + + /** + * Get the current Dagger Engine version. + */ + version = async (): Promise => { + const ctx = this._ctx.select( + "version", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + + + +/** + * An internal persistent bare git mirror. + */ +export class RemoteGitMirror extends BaseClient { + private readonly _id?: ID = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + ) { + super(ctx) + + this._id = _id + } + + /** + * A unique identifier for this RemoteGitMirror. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + + + +/** + * The SDK config of the module. + */ +export class SDKConfig extends BaseClient { + private readonly _id?: ID = undefined + private readonly _debug?: boolean = undefined + private readonly _source?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _debug?: boolean, + _source?: string, + ) { + super(ctx) + + this._id = _id + this._debug = _debug + this._source = _source + } + + /** + * A unique identifier for this SDKConfig. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Whether to start the SDK runtime in debug mode with an interactive terminal. + */ + debug = async (): Promise => { + if (this._debug) { + return this._debug + } + + const ctx = this._ctx.select( + "debug", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Source of the SDK. Either a name of a builtin SDK or a module source ref string pointing to the SDK's implementation. + */ + source = async (): Promise => { + if (this._source) { + return this._source + } + + const ctx = this._ctx.select( + "source", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * A definition of a custom scalar defined in a Module. + */ +export class ScalarTypeDef extends BaseClient { + private readonly _id?: ID = undefined + private readonly _description?: string = undefined + private readonly _name?: string = undefined + private readonly _sourceModuleName?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _description?: string, + _name?: string, + _sourceModuleName?: string, + ) { + super(ctx) + + this._id = _id + this._description = _description + this._name = _name + this._sourceModuleName = _sourceModuleName + } + + /** + * A unique identifier for this ScalarTypeDef. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * A doc string for the scalar, if any. + */ + description = async (): Promise => { + if (this._description) { + return this._description + } + + const ctx = this._ctx.select( + "description", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The name of the scalar. + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * If this ScalarTypeDef is associated with a Module, the name of the module. Unset otherwise. + */ + sourceModuleName = async (): Promise => { + if (this._sourceModuleName) { + return this._sourceModuleName + } + + const ctx = this._ctx.select( + "sourceModuleName", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * A GraphQL introspection schema that can be inspected and merged. + */ +export class Schema extends BaseClient { + private readonly _id?: ID = undefined + private readonly _contents?: JSON = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _contents?: JSON, + ) { + super(ctx) + + this._id = _id + this._contents = _contents + } + + /** + * A unique identifier for this Schema. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Serialize the schema back to introspection JSON. + */ + contents = async (): Promise => { + if (this._contents) { + return this._contents + } + + const ctx = this._ctx.select( + "contents", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Merge a module's introspection-shaped type definitions into the schema, returning the combined schema. + * @param moduleTypes Introspection JSON describing the types the module defines. Object, interface and enum types are appended to the schema, and a constructor field for the module is added to the Query type. + * @param moduleName The name of the module whose types are being merged. Used to stamp the @sourceMap directive and to derive the module's constructor field. + */ + merge = (moduleTypes: JSON, moduleName: string): Schema => { + + const ctx = this._ctx.select( + "merge", + { moduleTypes, moduleName }, + ) + return new Schema(ctx) + } + + /** + * Call the provided function with current Schema. + * + * This is useful for reusability and readability by not breaking the calling chain. + */ + with = (arg: (param: Schema) => Schema) => { + return arg(this) + } +} + + +export class SearchResult extends BaseClient { + private readonly _id?: ID = undefined + private readonly _absoluteOffset?: number = undefined + private readonly _filePath?: string = undefined + private readonly _lineNumber?: number = undefined + private readonly _matchedLines?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _absoluteOffset?: number, + _filePath?: string, + _lineNumber?: number, + _matchedLines?: string, + ) { + super(ctx) + + this._id = _id + this._absoluteOffset = _absoluteOffset + this._filePath = _filePath + this._lineNumber = _lineNumber + this._matchedLines = _matchedLines + } + + /** + * A unique identifier for this SearchResult. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The byte offset of this line within the file. + */ + absoluteOffset = async (): Promise => { + if (this._absoluteOffset) { + return this._absoluteOffset + } + + const ctx = this._ctx.select( + "absoluteOffset", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The path to the file that matched. + */ + filePath = async (): Promise => { + if (this._filePath) { + return this._filePath + } + + const ctx = this._ctx.select( + "filePath", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The first line that matched. + */ + lineNumber = async (): Promise => { + if (this._lineNumber) { + return this._lineNumber + } + + const ctx = this._ctx.select( + "lineNumber", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The line content that matched. + */ + matchedLines = async (): Promise => { + if (this._matchedLines) { + return this._matchedLines + } + + const ctx = this._ctx.select( + "matchedLines", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Sub-match positions and content within the matched lines. + */ + submatches = async (): Promise => { + type submatches = { + id: ID + } + + const ctx = this._ctx.select( + "submatches", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new SearchSubmatch(ctx.copy().selectNode(r.id, "SearchSubmatch"))) + } +} + + +export class SearchSubmatch extends BaseClient { + private readonly _id?: ID = undefined + private readonly _end?: number = undefined + private readonly _start?: number = undefined + private readonly _text?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _end?: number, + _start?: number, + _text?: string, + ) { + super(ctx) + + this._id = _id + this._end = _end + this._start = _start + this._text = _text + } + + /** + * A unique identifier for this SearchSubmatch. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The match's end offset within the matched lines. + */ + end = async (): Promise => { + if (this._end) { + return this._end + } + + const ctx = this._ctx.select( + "end", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The match's start offset within the matched lines. + */ + start = async (): Promise => { + if (this._start) { + return this._start + } + + const ctx = this._ctx.select( + "start", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The matched text. + */ + text = async (): Promise => { + if (this._text) { + return this._text + } + + const ctx = this._ctx.select( + "text", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * A reference to a secret value, which can be handled more safely than the value itself. + */ +export class Secret extends BaseClient { + private readonly _id?: ID = undefined + private readonly _name?: string = undefined + private readonly _plaintext?: string = undefined + private readonly _uri?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _name?: string, + _plaintext?: string, + _uri?: string, + ) { + super(ctx) + + this._id = _id + this._name = _name + this._plaintext = _plaintext + this._uri = _uri + } + + /** + * A unique identifier for this Secret. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The name of this secret. + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The value of this secret. + */ + plaintext = async (): Promise => { + if (this._plaintext) { + return this._plaintext + } + + const ctx = this._ctx.select( + "plaintext", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The URI of this secret. + */ + uri = async (): Promise => { + if (this._uri) { + return this._uri + } + + const ctx = this._ctx.select( + "uri", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * A content-addressed service providing TCP connectivity. + */ +export class Service extends BaseClient { + private readonly _id?: ID = undefined + private readonly _endpoint?: string = undefined + private readonly _hostname?: string = undefined + private readonly _start?: ID = undefined + private readonly _stop?: ID = undefined + private readonly _sync?: ID = undefined + private readonly _up?: Void = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _endpoint?: string, + _hostname?: string, + _start?: ID, + _stop?: ID, + _sync?: ID, + _up?: Void, + ) { + super(ctx) + + this._id = _id + this._endpoint = _endpoint + this._hostname = _hostname + this._start = _start + this._stop = _stop + this._sync = _sync + this._up = _up + } + + /** + * A unique identifier for this Service. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Retrieves an endpoint that clients can use to reach this container. + * + * If no port is specified, the first exposed port is used. If none exist an error is returned. + * + * If a scheme is specified, a URL is returned. Otherwise, a host:port pair is returned. + * @param opts.port The exposed port number for the endpoint + * @param opts.scheme Return a URL with the given scheme, eg. http for http:// + */ + endpoint = async ( + opts?: ServiceEndpointOpts): Promise => { + if (this._endpoint) { + return this._endpoint + } + + const ctx = this._ctx.select( + "endpoint", + { ...opts}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Retrieves a hostname which can be used by clients to reach this container. + */ + hostname = async (): Promise => { + if (this._hostname) { + return this._hostname + } + + const ctx = this._ctx.select( + "hostname", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Retrieves the list of ports provided by the service. + */ + ports = async (): Promise => { + type ports = { + id: ID + } + + const ctx = this._ctx.select( + "ports", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new Port(ctx.copy().selectNode(r.id, "Port"))) + } + + /** + * Start the service and wait for its health checks to succeed. + * + * Services bound to a Container do not need to be manually started. + */ + start = async (): Promise => { + const ctx = this._ctx.select( + "start", + ) + + const response: Awaited = await ctx.execute() + + + return new Service(ctx.copy().selectNode(response, "Service")) + } + + /** + * Stop the service. + * @param opts.kill Immediately kill the service without waiting for a graceful exit + */ + stop = async ( + opts?: ServiceStopOpts): Promise => { + const ctx = this._ctx.select( + "stop", + { ...opts}, + ) + + const response: Awaited = await ctx.execute() + + + return new Service(ctx.copy().selectNode(response, "Service")) + } + + /** + * Forces evaluation of the pipeline in the engine. + */ + sync = async (): Promise => { + const ctx = this._ctx.select( + "sync", + ) + + const response: Awaited = await ctx.execute() + + + return new Service(ctx.copy().selectNode(response, "Service")) + } + terminal = (opts?: ServiceTerminalOpts): Service => { + + const ctx = this._ctx.select( + "terminal", + { ...opts }, + ) + return new Service(ctx) + } + + /** + * Creates a tunnel that forwards traffic from the caller's network to this service. + * @param opts.ports List of frontend/backend port mappings to forward. + * + * Frontend is the port accepting traffic on the host, backend is the service port. + * @param opts.random Bind each tunnel port to a random port on the host. + */ + up = async ( + opts?: ServiceUpOpts): Promise => { + if (this._up) { + return + } + + const ctx = this._ctx.select( + "up", + { ...opts}, + ) + + await ctx.execute() + + + } + + /** + * Configures a hostname which can be used by clients within the session to reach this container. + * @param hostname The hostname to use. + */ + withHostname = (hostname: string): Service => { + + const ctx = this._ctx.select( + "withHostname", + { hostname }, + ) + return new Service(ctx) + } + + /** + * Call the provided function with current Service. + * + * This is useful for reusability and readability by not breaking the calling chain. + */ + with = (arg: (param: Service) => Service) => { + return arg(this) + } +} + +/** + * A Unix or TCP/IP socket that can be mounted into a container. + */ +export class Socket extends BaseClient { + private readonly _id?: ID = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + ) { + super(ctx) + + this._id = _id + } + + /** + * A unique identifier for this Socket. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * Source location information. + */ +export class SourceMap extends BaseClient { + private readonly _id?: ID = undefined + private readonly _column?: number = undefined + private readonly _filename?: string = undefined + private readonly _line?: number = undefined + private readonly _module?: string = undefined + private readonly _url?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _column?: number, + _filename?: string, + _line?: number, + _module?: string, + _url?: string, + ) { + super(ctx) + + this._id = _id + this._column = _column + this._filename = _filename + this._line = _line + this._module = _module + this._url = _url + } + + /** + * A unique identifier for this SourceMap. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The column number within the line. + */ + column = async (): Promise => { + if (this._column) { + return this._column + } + + const ctx = this._ctx.select( + "column", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The filename from the module source. + */ + filename = async (): Promise => { + if (this._filename) { + return this._filename + } + + const ctx = this._ctx.select( + "filename", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The line number within the filename. + */ + line = async (): Promise => { + if (this._line) { + return this._line + } + + const ctx = this._ctx.select( + "line", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The module dependency this was declared in. + */ + module_ = async (): Promise => { + if (this._module) { + return this._module + } + + const ctx = this._ctx.select( + "module", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The URL to the file, if any. This can be used to link to the source map in the browser. + */ + url = async (): Promise => { + if (this._url) { + return this._url + } + + const ctx = this._ctx.select( + "url", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * A file or directory status object. + */ +export class Stat extends BaseClient { + private readonly _id?: ID = undefined + private readonly _fileType?: FileType = undefined + private readonly _name?: string = undefined + private readonly _permissions?: number = undefined + private readonly _size?: number = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _fileType?: FileType, + _name?: string, + _permissions?: number, + _size?: number, + ) { + super(ctx) + + this._id = _id + this._fileType = _fileType + this._name = _name + this._permissions = _permissions + this._size = _size + } + + /** + * A unique identifier for this Stat. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * file type + */ + fileType = async (): Promise => { + if (this._fileType) { + return this._fileType + } + + const ctx = this._ctx.select( + "fileType", + ) + + const response: Awaited = await ctx.execute() + + return FileTypeNameToValue(response) + } + + /** + * file name + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * permission bits + */ + permissions = async (): Promise => { + if (this._permissions) { + return this._permissions + } + + const ctx = this._ctx.select( + "permissions", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * file size + */ + size = async (): Promise => { + if (this._size) { + return this._size + } + + const ctx = this._ctx.select( + "size", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + + + +/** + * An object that can be force-evaluated. + * + * Calling sync ensures that the object's entire dependency DAG has been evaluated, returning the object's ID once complete. + */ +export interface Syncer { + id(): Promise + sync(): Promise +} + +export class _SyncerClient extends BaseClient { + private readonly _id?: ID = undefined + private readonly _sync?: ID = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _sync?: ID, + ) { + super(ctx) + + this._id = _id + this._sync = _sync + } + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + sync = async (): Promise => { + const ctx = this._ctx.select( + "sync", + ) + + const response: Awaited = await ctx.execute() + + + return new _SyncerClient(ctx.copy().selectNode(response, "Syncer")) + } +} + +/** + * An interactive terminal that clients can connect to. + */ +export class Terminal extends BaseClient { + private readonly _id?: ID = undefined + private readonly _sync?: ID = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _sync?: ID, + ) { + super(ctx) + + this._id = _id + this._sync = _sync + } + + /** + * A unique identifier for this Terminal. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Forces evaluation of the pipeline in the engine. + * + * It doesn't run the default command if no exec has been set. + */ + sync = async (): Promise => { + const ctx = this._ctx.select( + "sync", + ) + + const response: Awaited = await ctx.execute() + + + return new Terminal(ctx.copy().selectNode(response, "Terminal")) + } +} + +/** + * A definition of a parameter or return type in a Module. + */ +export class TypeDef extends BaseClient { + private readonly _id?: ID = undefined + private readonly _kind?: TypeDefKind = undefined + private readonly _name?: string = undefined + private readonly _optional?: boolean = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _kind?: TypeDefKind, + _name?: string, + _optional?: boolean, + ) { + super(ctx) + + this._id = _id + this._kind = _kind + this._name = _name + this._optional = _optional + } + + /** + * A unique identifier for this TypeDef. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * If kind is ENUM, the enum-specific type definition. If kind is not ENUM, this will be null. + */ + asEnum = (): EnumTypeDef => { + + const ctx = this._ctx.select( + "asEnum", + ) + return new EnumTypeDef(ctx) + } + + /** + * If kind is INPUT, the input-specific type definition. If kind is not INPUT, this will be null. + */ + asInput = (): InputTypeDef => { + + const ctx = this._ctx.select( + "asInput", + ) + return new InputTypeDef(ctx) + } + + /** + * If kind is INTERFACE, the interface-specific type definition. If kind is not INTERFACE, this will be null. + */ + asInterface = (): InterfaceTypeDef => { + + const ctx = this._ctx.select( + "asInterface", + ) + return new InterfaceTypeDef(ctx) + } + + /** + * If kind is LIST, the list-specific type definition. If kind is not LIST, this will be null. + */ + asList = (): ListTypeDef => { + + const ctx = this._ctx.select( + "asList", + ) + return new ListTypeDef(ctx) + } + + /** + * If kind is OBJECT, the object-specific type definition. If kind is not OBJECT, this will be null. + */ + asObject = (): ObjectTypeDef => { + + const ctx = this._ctx.select( + "asObject", + ) + return new ObjectTypeDef(ctx) + } + + /** + * If kind is SCALAR, the scalar-specific type definition. If kind is not SCALAR, this will be null. + */ + asScalar = (): ScalarTypeDef => { + + const ctx = this._ctx.select( + "asScalar", + ) + return new ScalarTypeDef(ctx) + } + + /** + * The kind of type this is (e.g. primitive, list, object). + */ + kind = async (): Promise => { + if (this._kind) { + return this._kind + } + + const ctx = this._ctx.select( + "kind", + ) + + const response: Awaited = await ctx.execute() + + return TypeDefKindNameToValue(response) + } + + /** + * The canonical non-optional name of the type. + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Whether this type can be set to null. Defaults to false. + */ + optional = async (): Promise => { + if (this._optional) { + return this._optional + } + + const ctx = this._ctx.select( + "optional", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Adds a function for constructing a new instance of an Object TypeDef, failing if the type is not an object. + */ + withConstructor = (function_: Function_): TypeDef => { + + const ctx = this._ctx.select( + "withConstructor", + { + function:function_ }, + ) + return new TypeDef(ctx) + } + + /** + * Returns a TypeDef of kind Enum with the provided name. + * + * Note that an enum's values may be omitted if the intent is only to refer to an enum. This is how functions are able to return their own, or any other circular reference. + * @param name The name of the enum + * @param opts.description A doc string for the enum, if any + * @param opts.sourceMap The source map for the enum definition. + */ + withEnum = (name: string, opts?: TypeDefWithEnumOpts): TypeDef => { + + const ctx = this._ctx.select( + "withEnum", + { name, ...opts }, + ) + return new TypeDef(ctx) + } + + /** + * Adds a static value for an Enum TypeDef, failing if the type is not an enum. + * @param name The name of the member in the enum + * @param opts.value The value of the member in the enum + * @param opts.description A doc string for the member, if any + * @param opts.sourceMap The source map for the enum member definition. + * @param opts.deprecated If deprecated, the reason or migration path. + */ + withEnumMember = (name: string, opts?: TypeDefWithEnumMemberOpts): TypeDef => { + + const ctx = this._ctx.select( + "withEnumMember", + { name, ...opts }, + ) + return new TypeDef(ctx) + } + + /** + * Adds a static value for an Enum TypeDef, failing if the type is not an enum. + * @param value The name of the value in the enum + * @param opts.description A doc string for the value, if any + * @param opts.sourceMap The source map for the enum value definition. + * @param opts.deprecated If deprecated, the reason or migration path. + * @deprecated Use withEnumMember instead + */ + withEnumValue = (value: string, opts?: TypeDefWithEnumValueOpts): TypeDef => { + + const ctx = this._ctx.select( + "withEnumValue", + { value, ...opts }, + ) + return new TypeDef(ctx) + } + + /** + * Adds a static field for an Object TypeDef, failing if the type is not an object. + * @param name The name of the field in the object + * @param typeDef The type of the field + * @param opts.description A doc string for the field, if any + * @param opts.sourceMap The source map for the field definition. + * @param opts.deprecated If deprecated, the reason or migration path. + */ + withField = (name: string, typeDef: TypeDef, opts?: TypeDefWithFieldOpts): TypeDef => { + + const ctx = this._ctx.select( + "withField", + { name, typeDef, ...opts }, + ) + return new TypeDef(ctx) + } + + /** + * Adds a function for an Object or Interface TypeDef, failing if the type is not one of those kinds. + */ + withFunction = (function_: Function_): TypeDef => { + + const ctx = this._ctx.select( + "withFunction", + { + function:function_ }, + ) + return new TypeDef(ctx) + } + + /** + * Returns a TypeDef of kind Interface with the provided name. + */ + withInterface = (name: string, opts?: TypeDefWithInterfaceOpts): TypeDef => { + + const ctx = this._ctx.select( + "withInterface", + { name, ...opts }, + ) + return new TypeDef(ctx) + } + + /** + * Sets the kind of the type. + */ + withKind = (kind: TypeDefKind): TypeDef => { + const metadata = { + kind: { is_enum: true, value_to_name: TypeDefKindValueToName }, + } + + + const ctx = this._ctx.select( + "withKind", + { kind, __metadata: metadata }, + ) + return new TypeDef(ctx) + } + + /** + * Returns a TypeDef of kind List with the provided type for its elements. + */ + withListOf = (elementType: TypeDef): TypeDef => { + + const ctx = this._ctx.select( + "withListOf", + { elementType }, + ) + return new TypeDef(ctx) + } + + /** + * Returns a TypeDef of kind Object with the provided name. + * + * Note that an object's fields and functions may be omitted if the intent is only to refer to an object. This is how functions are able to return their own object, or any other circular reference. + */ + withObject = (name: string, opts?: TypeDefWithObjectOpts): TypeDef => { + + const ctx = this._ctx.select( + "withObject", + { name, ...opts }, + ) + return new TypeDef(ctx) + } + + /** + * Sets whether this type can be set to null. + */ + withOptional = (optional: boolean): TypeDef => { + + const ctx = this._ctx.select( + "withOptional", + { optional }, + ) + return new TypeDef(ctx) + } + + /** + * Returns a TypeDef of kind Scalar with the provided name. + */ + withScalar = (name: string, opts?: TypeDefWithScalarOpts): TypeDef => { + + const ctx = this._ctx.select( + "withScalar", + { name, ...opts }, + ) + return new TypeDef(ctx) + } + + /** + * Call the provided function with current TypeDef. + * + * This is useful for reusability and readability by not breaking the calling chain. + */ + with = (arg: (param: TypeDef) => TypeDef) => { + return arg(this) + } +} + + + + +export class Up extends BaseClient { + private readonly _id?: ID = undefined + private readonly _description?: string = undefined + private readonly _name?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _description?: string, + _name?: string, + ) { + super(ctx) + + this._id = _id + this._description = _description + this._name = _name + } + + /** + * A unique identifier for this Up. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The description of the service + */ + description = async (): Promise => { + if (this._description) { + return this._description + } + + const ctx = this._ctx.select( + "description", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Return the fully qualified name of the service + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The original module in which the service has been defined + */ + originalModule = (): Module_ => { + + const ctx = this._ctx.select( + "originalModule", + ) + return new Module_(ctx) + } + + /** + * The path of the service within its module + */ + path = async (): Promise => { + const ctx = this._ctx.select( + "path", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Execute the service function + */ + run = (): Up => { + + const ctx = this._ctx.select( + "run", + ) + return new Up(ctx) + } + + /** + * Call the provided function with current Up. + * + * This is useful for reusability and readability by not breaking the calling chain. + */ + with = (arg: (param: Up) => Up) => { + return arg(this) + } +} + + +export class UpGroup extends BaseClient { + private readonly _id?: ID = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + ) { + super(ctx) + + this._id = _id + } + + /** + * A unique identifier for this UpGroup. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Return a list of individual services and their details + */ + list = async (): Promise => { + type list = { + id: ID + } + + const ctx = this._ctx.select( + "list", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new Up(ctx.copy().selectNode(r.id, "Up"))) + } + + /** + * Execute all selected service functions + */ + run = (): UpGroup => { + + const ctx = this._ctx.select( + "run", + ) + return new UpGroup(ctx) + } + + /** + * Call the provided function with current UpGroup. + * + * This is useful for reusability and readability by not breaking the calling chain. + */ + with = (arg: (param: UpGroup) => UpGroup) => { + return arg(this) + } +} + + + +/** + * A filesystem volume that can be mounted into containers. + */ +export class Volume extends BaseClient { + private readonly _id?: ID = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + ) { + super(ctx) + + this._id = _id + } + + /** + * A unique identifier for this Volume. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * A Dagger workspace detected from the current working directory or constructed from a Directory. + */ +export class Workspace extends BaseClient { + private readonly _id?: ID = undefined + private readonly _address?: string = undefined + private readonly _configFile?: string = undefined + private readonly _configRead?: string = undefined + private readonly _cwd?: string = undefined + private readonly _export?: Void = undefined + private readonly _findUp?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _address?: string, + _configFile?: string, + _configRead?: string, + _cwd?: string, + _export?: Void, + _findUp?: string, + ) { + super(ctx) + + this._id = _id + this._address = _address + this._configFile = _configFile + this._configRead = _configRead + this._cwd = _cwd + this._export = _export + this._findUp = _findUp + } + + /** + * A unique identifier for this Workspace. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Canonical Dagger address of the workspace location, or an opaque identity for synthetic workspaces. + */ + address = async (): Promise => { + if (this._address) { + return this._address + } + + const ctx = this._ctx.select( + "address", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Return this workspace's pending overlay changes. + */ + changes = (): Changeset => { + + const ctx = this._ctx.select( + "changes", + ) + return new Changeset(ctx) + } + + /** + * Return all checks from modules loaded in the workspace. + * @param opts.include Only include checks matching the specified patterns + * @param opts.skip Skip checks matching the specified patterns + * @param opts.noGenerate When true, only return annotated check functions; exclude generate-as-checks + * @param opts.onlyGenerate When true, only return generate-as-checks; exclude annotated check functions + */ + checks = (opts?: WorkspaceChecksOpts): CheckGroup => { + + const ctx = this._ctx.select( + "checks", + { ...opts }, + ) + return new CheckGroup(ctx) + } + + /** + * Selected native workspace config file relative to the workspace cwd, if any. + */ + configFile = async (): Promise => { + if (this._configFile) { + return this._configFile + } + + const ctx = this._ctx.select( + "configFile", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Read a configuration value from dagger.toml. + * + * If key is empty, returns the full config. + * + * If key points to a scalar, returns the value. + * + * If key points to a table, returns flattened dotted-key output. + * @param opts.key Dotted key path (e.g. modules.greeter.source). Empty for full config. + */ + configRead = async ( + opts?: WorkspaceConfigReadOpts): Promise => { + if (this._configRead) { + return this._configRead + } + + const ctx = this._ctx.select( + "configRead", + { ...opts}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Current location within the workspace root. + * + * The workspace root is returned as "/". + * + * Relative paths in workspace APIs resolve from here. + */ + cwd = async (): Promise => { + if (this._cwd) { + return this._cwd + } + + const ctx = this._ctx.select( + "cwd", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Returns a Directory from the workspace. + * + * Relative paths resolve from the workspace cwd. Absolute paths resolve from the workspace root. + * @param path Location of the directory to retrieve. Relative paths (e.g., "src") resolve from the workspace cwd; absolute paths (e.g., "/src") resolve from the workspace root. + * @param opts.exclude Exclude artifacts that match the given pattern (e.g., ["node_modules/", ".git*"]). + * @param opts.include Include only artifacts that match the given pattern (e.g., ["app/", "package.*"]). + * @param opts.gitignore Apply .gitignore filter rules inside the directory. + */ + directory = (path: string, opts?: WorkspaceDirectoryOpts): Directory => { + + const ctx = this._ctx.select( + "directory", + { path, ...opts }, + ) + return new Directory(ctx) + } + + /** + * List named environments defined in the workspace configuration. + */ + envList = async (): Promise => { + const ctx = this._ctx.select( + "envList", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Write this workspace's pending changes to its local Git workspace. + */ + export = async (): Promise => { + if (this._export) { + return + } + + const ctx = this._ctx.select( + "export", + ) + + await ctx.execute() + + + } + + /** + * Returns a File from the workspace. + * + * Relative paths resolve from the workspace cwd. Absolute paths resolve from the workspace root. + * @param path Location of the file to retrieve. Relative paths (e.g., "go.mod") resolve from the workspace cwd; absolute paths (e.g., "/go.mod") resolve from the workspace root. + */ + file = (path: string): File => { + + const ctx = this._ctx.select( + "file", + { path }, + ) + return new File(ctx) + } + + /** + * Search for a file or directory by walking up from the start path within the workspace. + * + * Returns the absolute workspace path if found, or null if not found. + * + * Relative start paths resolve from the workspace cwd. + * + * The search stops at the workspace root and will not traverse above it. + * @param name The name of the file or directory to search for. + * @param opts.from Path to start the search from. Relative paths resolve from the workspace cwd; absolute paths resolve from the workspace root. + */ + findUp = async (name: string, + opts?: WorkspaceFindUpOpts): Promise => { + if (this._findUp) { + return this._findUp + } + + const ctx = this._ctx.select( + "findUp", + { name, ...opts}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Return all generators from modules loaded in the workspace. + * @param opts.include Only include generators matching the specified patterns + */ + generators = (opts?: WorkspaceGeneratorsOpts): GeneratorGroup => { + + const ctx = this._ctx.select( + "generators", + { ...opts }, + ) + return new GeneratorGroup(ctx) + } + + /** + * Git state for this workspace. Errors if the workspace is not in a git repository. + */ + git = (): WorkspaceGit => { + + const ctx = this._ctx.select( + "git", + ) + return new WorkspaceGit(ctx) + } + + /** + * Returns a list of files and directories that match the given pattern. + * + * Patterns match paths relative to the workspace root. + * @param pattern Pattern to match (e.g., "*.md"). + */ + glob = async (pattern: string): Promise => { + const ctx = this._ctx.select( + "glob", + { pattern}, + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Plan the explicit migration needed for the current workspace. + * + * The returned plan has an empty changeset and no steps when no migration is needed. + */ + migrate = (): WorkspaceMigration => { + + const ctx = this._ctx.select( + "migrate", + ) + return new WorkspaceMigration(ctx) + } + + /** + * Return a module defined in the workspace configuration. + * @param name Module name to inspect. + */ + module_ = (name: string): WorkspaceModule => { + + const ctx = this._ctx.select( + "module", + { name }, + ) + return new WorkspaceModule(ctx) + } + + /** + * Load a module source from a path within the workspace. + * + * Relative paths (e.g., "foo") resolve from the workspace cwd; absolute paths (e.g., "/foo") resolve from the workspace root. + * + * Fails if the path does not point to an initialized module. + * @param path Location of the module source to load, relative to the workspace cwd or absolute from the workspace root. + */ + moduleSource = (path: string): ModuleSource => { + + const ctx = this._ctx.select( + "moduleSource", + { path }, + ) + return new ModuleSource(ctx) + } + + /** + * List modules defined in the workspace configuration. + */ + modules = async (): Promise => { + type modules = { + id: ID + } + + const ctx = this._ctx.select( + "modules", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new WorkspaceModule(ctx.copy().selectNode(r.id, "WorkspaceModule"))) + } + + /** + * An installed SDK, by name. + * @param name SDK name to look up. + */ + sdk = (name: string): WorkspaceSDK => { + + const ctx = this._ctx.select( + "sdk", + { name }, + ) + return new WorkspaceSDK(ctx) + } + + /** + * Installed SDKs. + */ + sdks = async (): Promise => { + type sdks = { + id: ID + } + + const ctx = this._ctx.select( + "sdks", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new WorkspaceSDK(ctx.copy().selectNode(r.id, "WorkspaceSDK"))) + } + + /** + * Searches for content matching the given regular expression or literal string. + * + * Uses Rust regex syntax; escape literal ., [, ], {, }, | with backslashes. + * + * Runs ripgrep on the client host, falling back to grep if unavailable. + * @param opts.paths Directory or file paths to search + * @param opts.globs Glob patterns to match (e.g., "*.md") + * @param opts.pattern The text to match. + * @param opts.literal Interpret the pattern as a literal string instead of a regular expression. + * @param opts.multiline Enable searching across multiple lines. + * @param opts.dotall Allow the . pattern to match newlines in multiline mode. + * @param opts.insensitive Enable case-insensitive matching. + * @param opts.skipIgnored Honor .gitignore, .ignore, and .rgignore files. + * @param opts.skipHidden Skip hidden files (files starting with .). + * @param opts.filesOnly Only return matching files, not lines and content + * @param opts.limit Limit the number of results to return + */ + search = async ( + opts?: WorkspaceSearchOpts): Promise => { + type search = { + id: ID + } + + const ctx = this._ctx.select( + "search", + { ...opts}, + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new SearchResult(ctx.copy().selectNode(r.id, "SearchResult"))) + } + + /** + * Return all services from modules loaded in the workspace. + * @param opts.include Only include services matching the specified patterns + */ + services = (opts?: WorkspaceServicesOpts): UpGroup => { + + const ctx = this._ctx.select( + "services", + { ...opts }, + ) + return new UpGroup(ctx) + } + + /** + * Return this workspace with a changeset applied, without mutating the source. + * @param changes Changes to apply. + */ + withChanges = (changes: Changeset): Workspace => { + + const ctx = this._ctx.select( + "withChanges", + { changes }, + ) + return new Workspace(ctx) + } + + /** + * Return this workspace with a named config environment created. + * @param name Environment name. + * @param opts.here Write to the workspace config directory at the workspace cwd. + */ + withConfigEnv = (name: string, opts?: WorkspaceWithConfigEnvOpts): Workspace => { + + const ctx = this._ctx.select( + "withConfigEnv", + { name, ...opts }, + ) + return new Workspace(ctx) + } + + /** + * Return this workspace with a configuration value written. + * @param key Dotted key path. + * @param value Value to set. Bools, integers, and comma-separated arrays are auto-detected. + * @param opts.values List value to set. Elements are stored verbatim, with no auto-detection. Mutually exclusive with value. + * @param opts.here Write to the workspace config directory at the workspace cwd. + */ + withConfigValue = (key: string, value: string, opts?: WorkspaceWithConfigValueOpts): Workspace => { + + const ctx = this._ctx.select( + "withConfigValue", + { key, value, ...opts }, + ) + return new Workspace(ctx) + } + + /** + * Return this workspace with a generated API client initialized. + * @param path Workspace-relative output directory for the generated client. + * @param sdk Workspace SDK name or module entry name to use. + * @param module Workspace-relative path or canonical ref for the module the client binds to. + * @param opts.args SDK-specific init arguments. + * @param opts.here Write to the workspace config directory at the workspace cwd. + */ + withInitClient = (path: string, sdk: string, module_: string, opts?: WorkspaceWithInitClientOpts): Workspace => { + + const ctx = this._ctx.select( + "withInitClient", + { path, sdk, + module:module_, ...opts }, + ) + return new Workspace(ctx) + } + + /** + * Return this workspace with a new module initialized. + * @param name Name of the new module. + * @param sdk Workspace SDK name or module entry name to use. + * @param opts.path Workspace-relative path for the new module. + * @param opts.source Source subpath within the new module. + * @param opts.include Additional include patterns for the module. + * @param opts.args SDK-specific init arguments. + * @param opts.here Write to the workspace config directory at the workspace cwd. + */ + withInitModule = (name: string, sdk: string, opts?: WorkspaceWithInitModuleOpts): Workspace => { + + const ctx = this._ctx.select( + "withInitModule", + { name, sdk, ...opts }, + ) + return new Workspace(ctx) + } + + /** + * Return this workspace with a module installed in its config. + * @param ref Module reference to install. + * @param opts.name Override name for the installed module entry. + * @param opts.here Write to the workspace config directory at the workspace cwd. + */ + withModule = (ref: string, opts?: WorkspaceWithModuleOpts): Workspace => { + + const ctx = this._ctx.select( + "withModule", + { ref, ...opts }, + ) + return new Workspace(ctx) + } + + /** + * Return this workspace with a directory added, without mutating the source. + * @param path Path of the added directory. Relative paths resolve from the workspace cwd. + * @param source Directory to add. + */ + withNewDirectory = (path: string, source: Directory): Workspace => { + + const ctx = this._ctx.select( + "withNewDirectory", + { path, source }, + ) + return new Workspace(ctx) + } + + /** + * Return this workspace with a new or replaced file, without mutating the source. + * @param path Path of the new file. Relative paths resolve from the workspace cwd. + * @param contents Contents of the new file. + * @param opts.permissions Permissions of the new file. + */ + withNewFile = (path: string, contents: string, opts?: WorkspaceWithNewFileOpts): Workspace => { + + const ctx = this._ctx.select( + "withNewFile", + { path, contents, ...opts }, + ) + return new Workspace(ctx) + } + + /** + * Return this workspace with an SDK installed in its config. + * @param ref SDK module reference to install. + * @param opts.name Override name for the installed SDK entry. + * @param opts.here Write to the workspace config directory at the workspace cwd. + * @param opts.asSdkName User-facing SDK name to persist under `[modules..as-sdk] name = ...`. + */ + withSDK = (ref: string, opts?: WorkspaceWithSdkOpts): Workspace => { + + const ctx = this._ctx.select( + "withSDK", + { ref, ...opts }, + ) + return new Workspace(ctx) + } + + /** + * Return this workspace with refreshed lockfile state. + */ + withUpdatedLock = (): Workspace => { + + const ctx = this._ctx.select( + "withUpdatedLock", + ) + return new Workspace(ctx) + } + + /** + * Return this workspace with its working directory pointed at the given workspace-relative path. + * @param path Workspace-relative path to use as the working directory. + */ + withWorkdir = (path: string): Workspace => { + + const ctx = this._ctx.select( + "withWorkdir", + { path }, + ) + return new Workspace(ctx) + } + + /** + * Return this workspace with a named config environment removed. + * @param name Environment name. + * @param opts.here Write to the workspace config directory at the workspace cwd. + */ + withoutConfigEnv = (name: string, opts?: WorkspaceWithoutConfigEnvOpts): Workspace => { + + const ctx = this._ctx.select( + "withoutConfigEnv", + { name, ...opts }, + ) + return new Workspace(ctx) + } + + /** + * Return this workspace with a configuration value removed. + * + * Errors when the key is not currently set. + * @param key Dotted key path (e.g. modules.greeter.settings.greeting). + * @param opts.here Write to the workspace config directory at the workspace cwd. + */ + withoutConfigValue = (key: string, opts?: WorkspaceWithoutConfigValueOpts): Workspace => { + + const ctx = this._ctx.select( + "withoutConfigValue", + { key, ...opts }, + ) + return new Workspace(ctx) + } + + /** + * Return this workspace with a module removed from its config. + * @param name Name of the installed module entry to remove. + * @param opts.here Write to the workspace config directory at the workspace cwd. + */ + withoutModule = (name: string, opts?: WorkspaceWithoutModuleOpts): Workspace => { + + const ctx = this._ctx.select( + "withoutModule", + { name, ...opts }, + ) + return new Workspace(ctx) + } + + /** + * Return this workspace with an SDK removed from its config. + * @param name Name of the installed SDK entry to remove. + * @param opts.here Write to the workspace config directory at the workspace cwd. + */ + withoutSDK = (name: string, opts?: WorkspaceWithoutSdkOpts): Workspace => { + + const ctx = this._ctx.select( + "withoutSDK", + { name, ...opts }, + ) + return new Workspace(ctx) + } + + /** + * Call the provided function with current Workspace. + * + * This is useful for reusability and readability by not breaking the calling chain. + */ + with = (arg: (param: Workspace) => Workspace) => { + return arg(this) + } +} + +/** + * Local git state for a workspace. + */ +export class WorkspaceGit extends BaseClient { + private readonly _id?: ID = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + ) { + super(ctx) + + this._id = _id + } + + /** + * A unique identifier for this WorkspaceGit. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The checked-out HEAD of this workspace. + */ + head = (): GitRef => { + + const ctx = this._ctx.select( + "head", + ) + return new GitRef(ctx) + } + + /** + * Uncommitted changes in this workspace, using the same rules as GitRepository.uncommitted. + */ + uncommitted = (): Changeset => { + + const ctx = this._ctx.select( + "uncommitted", + ) + return new Changeset(ctx) + } +} + +/** + * A planned workspace migration. + */ +export class WorkspaceMigration extends BaseClient { + private readonly _id?: ID = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + ) { + super(ctx) + + this._id = _id + } + + /** + * A unique identifier for this WorkspaceMigration. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Filesystem changes for the full migration plan. + */ + changes = (): Changeset => { + + const ctx = this._ctx.select( + "changes", + ) + return new Changeset(ctx) + } + + /** + * Logical migration steps, each identified by a stable code. + */ + steps = async (): Promise => { + type steps = { + id: ID + } + + const ctx = this._ctx.select( + "steps", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new WorkspaceMigrationStep(ctx.copy().selectNode(r.id, "WorkspaceMigrationStep"))) + } +} + +/** + * A single logical part of a workspace migration. + */ +export class WorkspaceMigrationStep extends BaseClient { + private readonly _id?: ID = undefined + private readonly _code?: string = undefined + private readonly _description?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _code?: string, + _description?: string, + ) { + super(ctx) + + this._id = _id + this._code = _code + this._description = _description + } + + /** + * A unique identifier for this WorkspaceMigrationStep. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Filesystem changes for this step. + */ + changes = (): Changeset => { + + const ctx = this._ctx.select( + "changes", + ) + return new Changeset(ctx) + } + + /** + * Stable code identifying this logical migration step. + */ + code = async (): Promise => { + if (this._code) { + return this._code + } + + const ctx = this._ctx.select( + "code", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Generic summary of this step's purpose and impact. + */ + description = async (): Promise => { + if (this._description) { + return this._description + } + + const ctx = this._ctx.select( + "description", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Non-fatal warnings raised while planning this step. + */ + warnings = async (): Promise => { + const ctx = this._ctx.select( + "warnings", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * A module entry in the workspace configuration. + */ +export class WorkspaceModule extends BaseClient { + private readonly _id?: ID = undefined + private readonly _entrypoint?: boolean = undefined + private readonly _name?: string = undefined + private readonly _source?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _entrypoint?: boolean, + _name?: string, + _source?: string, + ) { + super(ctx) + + this._id = _id + this._entrypoint = _entrypoint + this._name = _name + this._source = _source + } + + /** + * A unique identifier for this WorkspaceModule. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Whether the module is the workspace entrypoint (functions aliased to Query root). + */ + entrypoint = async (): Promise => { + if (this._entrypoint) { + return this._entrypoint + } + + const ctx = this._ctx.select( + "entrypoint", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The module name. + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * List constructor-backed settings for this module. + */ + settings = async (): Promise => { + type settings = { + id: ID + } + + const ctx = this._ctx.select( + "settings", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new WorkspaceModuleSetting(ctx.copy().selectNode(r.id, "WorkspaceModuleSetting"))) + } + + /** + * The module source path. + */ + source = async (): Promise => { + if (this._source) { + return this._source + } + + const ctx = this._ctx.select( + "source", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * A constructor-backed module setting. + */ +export class WorkspaceModuleSetting extends BaseClient { + private readonly _id?: ID = undefined + private readonly _description?: string = undefined + private readonly _isList?: boolean = undefined + private readonly _key?: string = undefined + private readonly _value?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _description?: string, + _isList?: boolean, + _key?: string, + _value?: string, + ) { + super(ctx) + + this._id = _id + this._description = _description + this._isList = _isList + this._key = _key + this._value = _value + } + + /** + * A unique identifier for this WorkspaceModuleSetting. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The constructor argument description. + */ + description = async (): Promise => { + if (this._description) { + return this._description + } + + const ctx = this._ctx.select( + "description", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Whether the setting accepts a list of values. + */ + isList = async (): Promise => { + if (this._isList) { + return this._isList + } + + const ctx = this._ctx.select( + "isList", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The setting key. + */ + key = async (): Promise => { + if (this._key) { + return this._key + } + + const ctx = this._ctx.select( + "key", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The configured value after applying the selected workspace environment, or empty when unset. + */ + value = async (): Promise => { + if (this._value) { + return this._value + } + + const ctx = this._ctx.select( + "value", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + +/** + * An installed SDK: a module marked for scaffolding other modules and clients. + */ +export class WorkspaceSDK extends BaseClient { + private readonly _id?: ID = undefined + private readonly _name?: string = undefined + private readonly _ref?: string = undefined + + /** + * Constructor is used for internal usage only, do not create object from it. + */ + constructor( + ctx?: Context, + _id?: ID, + _name?: string, + _ref?: string, + ) { + super(ctx) + + this._id = _id + this._name = _name + this._ref = _ref + } + + /** + * A unique identifier for this WorkspaceSDK. + */ + id = async (): Promise => { + if (this._id) { + return this._id + } + + const ctx = this._ctx.select( + "id", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * Clients generated with this SDK. + */ + clients = async (): Promise => { + type clients = { + id: ID + } + + const ctx = this._ctx.select( + "clients", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new WorkspaceModule(ctx.copy().selectNode(r.id, "WorkspaceModule"))) + } + + /** + * Modules authored with this SDK. + */ + modules = async (): Promise => { + type modules = { + id: ID + } + + const ctx = this._ctx.select( + "modules", + ).select("id") + + const response: Awaited = await ctx.execute() + + + return response.map((r) => new WorkspaceModule(ctx.copy().selectNode(r.id, "WorkspaceModule"))) + } + + /** + * The user-facing SDK name. + */ + name = async (): Promise => { + if (this._name) { + return this._name + } + + const ctx = this._ctx.select( + "name", + ) + + const response: Awaited = await ctx.execute() + + + return response + } + + /** + * The module reference this SDK was installed from. + */ + ref = async (): Promise => { + if (this._ref) { + return this._ref + } + + const ctx = this._ctx.select( + "ref", + ) + + const response: Awaited = await ctx.execute() + + + return response + } +} + + +export const dag = new Client() + +