Skip to main content

Module Constructor

Sometimes it's convenient to have a special function for constructing the main module object. This can, for example, be a simple way to accept module-wide configuration.

Here is an example module with a constructor:

import { object, func } from "@dagger.io/dagger"

@object()
class MyModule {
greeting: string
name: string

constructor(greeting = "Hello", name = "World") {
this.greeting = greeting
this.name = name
}

@func()
message(): string {
return `${this.greeting} ${this.name}`
}
}

And here is an example call for this module:

dagger call --name=Foo message

The result will be:

Hello, Foo!
note

Dagger Modules have only one constructor. Constructors of custom types are not registered; they are constructed by the function that chains them.

Default values for complex types

If a Dagger Module constructor expects a Dagger core type (such as Container, Directory, Service etc.) as argument and you wish to assign a default value for this argument, it is necessary to use the ?? notation for this assignment. It is not possible to use the classic TypeScript notation for default arguments because the argument in this case is not a TypeScript primitive.

Here's is an example of a Dagger Module with a default constructor argument of type Container:

import { dag, Container, object, func, field } from "@dagger.io/dagger"

@object()
class MyModule {
@field()
ctr: Container

constructor(ctr?: Container) {
this.ctr = ctr ?? dag.container().from("alpine:3.14.0")
}

@func()
async version(): Promise<string> {
return await this.ctr
.withExec(["/bin/sh", "-c", "cat /etc/os-release | grep VERSION_ID"])
.stdout()
}
}

This default value can also be assigned directly in the field:

import { dag, Container, object, func, field } from "@dagger.io/dagger"

@object()
class MyModule {
@field()
ctr: Container = dag.container().from("alpine:3.14.0")

constructor(ctr?: Container) {
this.ctr = ctr ?? this.ctr
}

@func()
async version(): Promise<string> {
return await this.ctr
.withExec(["/bin/sh", "-c", "cat /etc/os-release | grep VERSION_ID"])
.stdout()
}
}
note

It is necessary to explicitly declare the type even when a default value is assigned, as the TypeScript SDK needs this information to extend the GraphQL schema correctly.

Here is an example call for this module:

dagger call version

The result will be:

VERSION_ID=3.14.0