// Code generated by 'just lsp-generate'. DO NOT EDIT.
package lsp

var hoverMap = map[string]map[string]string{
	"//ftl:cron": {
			"go": "\n# Cron\n\nA cron job is an Empty verb that will be called on a schedule. The syntax is described [here](https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/utilities/crontab.html).\n\nYou can also use a shorthand syntax for the cron job, supporting seconds (`s`), minutes (`m`), hours (`h`), and specific days of the week (e.g. `Mon`).\n\n## Examples\n\nThe following function will be called hourly:\n\n\n\n```go\n//ftl:cron 0 * * * *\nfunc Hourly(ctx context.Context) error {\n  // ...\n}\n```\n\n\nEvery 12 hours, starting at UTC midnight:\n\n\n```go\n//ftl:cron 12h\nfunc TwiceADay(ctx context.Context) error {\n  // ...\n}\n```\n\n\nEvery Monday at UTC midnight:\n\n\n```go\n//ftl:cron Mon\nfunc Mondays(ctx context.Context) error {\n  // ...\n}\n```\n\n\n",
			"java": "\n# Cron\n\nA cron job is an Empty verb that will be called on a schedule. The syntax is described [here](https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/utilities/crontab.html).\n\nYou can also use a shorthand syntax for the cron job, supporting seconds (`s`), minutes (`m`), hours (`h`), and specific days of the week (e.g. `Mon`).\n\n## Examples\n\nThe following function will be called hourly:\n\n\n\n```java\nimport xyz.block.ftl.Cron;\n\nclass MyCron {\n    @Cron(\"0 * * * *\")\n    void hourly() {\n        \n    }\n}\n```\n\n\nEvery 12 hours, starting at UTC midnight:\n\n\n```java\nimport xyz.block.ftl.Cron;\n\nclass MyCron {\n    @Cron(\"12h\")\n    void twiceADay() {\n        \n    }\n}\n```\n\n\nEvery Monday at UTC midnight:\n\n\n```java\nimport xyz.block.ftl.Cron;\n\nclass MyCron {\n    @Cron(\"Mon\")\n    void mondays() {\n        \n    }\n}\n```\n\n\n",
			"kotlin": "\n# Cron\n\nA cron job is an Empty verb that will be called on a schedule. The syntax is described [here](https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/utilities/crontab.html).\n\nYou can also use a shorthand syntax for the cron job, supporting seconds (`s`), minutes (`m`), hours (`h`), and specific days of the week (e.g. `Mon`).\n\n## Examples\n\nThe following function will be called hourly:\n\n\n\n```kotlin\nimport xyz.block.ftl.Cron\n\n@Cron(\"0 * * * *\")\nfun hourly() {\n    \n}\n```\n\n\nEvery 12 hours, starting at UTC midnight:\n\n\n```kotlin\nimport xyz.block.ftl.Cron\n\n@Cron(\"12h\")\nfun twiceADay() {\n    \n}\n```\n\n\nEvery Monday at UTC midnight:\n\n\n```kotlin\nimport xyz.block.ftl.Cron\n\n@Cron(\"Mon\")\nfun mondays() {\n    \n}\n```\n\n\n",
			"schema": "\n```schema\nmodule example {\n  verb hourly(Unit) Unit\n    +cron \"0 * * * *\"\n}\n```\n\n\nEvery 12 hours, starting at UTC midnight:\n\n\n```schema\nmodule example {\n  verb twiceADay(Unit) Unit\n    +cron \"12h\"\n}\n```\n\n\nEvery Monday at UTC midnight:\n\n\n```schema\nmodule example {\n  verb mondays(Unit) Unit\n    +cron \"Mon\"\n}\n```\n\n\n",
	},
	"//ftl:enum": {
			"go": "## Type enums (sum types)\n\n[Sum types](https://en.wikipedia.org/wiki/Tagged_union) are supported by FTL's type system.\n\n\nSum types aren't directly supported by Go, however they can be approximated with the use of [sealed interfaces](https://blog.chewxy.com/2018/03/18/golang-interfaces/):\n\n```go\n//ftl:enum\ntype Animal interface { animal() }\n\ntype Cat struct {}\nfunc (Cat) animal() {}\n\ntype Dog struct {}\nfunc (Dog) animal() {}\n```\n\n## Value enums\n\nA value enum is an enumerated set of string or integer values.\n\n\n```go\n//ftl:enum\ntype Colour string\n\nconst (\n  Red   Colour = \"red\"\n  Green Colour = \"green\"\n  Blue  Colour = \"blue\"\n)\n\n//ftl:enum\ntype Status int\n\nconst (\n  Active   Status = 1\n  Inactive Status = 0\n  Pending  Status = 2\n)\n```\n\n\n",
			"java": "## Type enums (sum types)\n\n[Sum types](https://en.wikipedia.org/wiki/Tagged_union) are supported by FTL's type system.\n\n\n> TODO\n\n## Value enums\n\nA value enum is an enumerated set of string or integer values.\n\n\n```java\n@Enum\npublic enum Colour {\n  Red(\"red\"),\n  Green(\"green\"),\n  Blue(\"blue\");\n\n  private final String value;\n\n  Colour(String value) {\n    this.value = value;\n  }\n}\n\n@Enum\npublic enum Status {\n  Active(1),\n  Inactive(0),\n  Pending(2);\n\n  private final int value;\n\n  Status(int value) {\n    this.value = value;\n  }\n}\n```\n\n\n",
			"kotlin": "## Type enums (sum types)\n\n[Sum types](https://en.wikipedia.org/wiki/Tagged_union) are supported by FTL's type system.\n\n\nSum types aren't directly supported by Kotlin, however they can be approximated with the use of [sealed interfaces](https://kotlinlang.org/docs/sealed-classes.html):\n\n```kotlin\n@Enum\nsealed interface Animal\n\n@EnumHolder\nclass Cat() : Animal\n\n@EnumHolder\nclass Dog() : Animal\n```\n\n## Value enums\n\nA value enum is an enumerated set of string or integer values.\n\n\n```kotlin\n@Enum\npublic enum class Colour(\n  public final val `value`: String,\n) {\n  Red(\"red\"),\n  Green(\"green\"),\n  Blue(\"blue\"),\n  ;\n}\n\n@Enum\npublic enum class Status(\n  public final val `value`: Int,\n) {\n  Active(1),\n  Inactive(0),\n  Pending(2),\n  ;\n}\n```\n\n\n",
			"schema": "\nIn the FTL schema, sum types (type enums) are represented as a union of types:\n\n```schema\nmodule example {\n  data Cat {}\n  \n  data Dog {}\n  \n  enum Animal {\n    Cat example.Cat\n    Dog example.Dog\n  }\n}\n```\n\nWhen used in other types or verbs, the sum type can be referenced directly:\n\n```schema\nmodule example {\n  verb processAnimal(example.Animal) Unit\n}\n```\n\n## Value enums\n\nA value enum is an enumerated set of string or integer values.\n\n\nIn the FTL schema, value enums are represented as an enum with string or integer values:\n\n```schema\nmodule example {\n  enum Colour: String {\n    Red = \"red\"\n    Green = \"green\"\n    Blue = \"blue\"\n  }\n  \n  enum Status: Int {\n    Active = 1\n    Inactive = 0\n    Pending = 2\n  }\n}\n```\n\n\n",
	},
	"//ftl:ingress": {
			"go": "\n# HTTP Ingress\n\nHTTP ingress is different depending on the language you are using. The following sections describe how to define HTTP ingress in each language.\n\n\n\nVerbs annotated with `ftl:ingress` will be exposed via HTTP (`http` is the default ingress type). These endpoints will then be available on one of our default `ingress` ports (local development defaults to `http://localhost:8891`).\n\nThe following will be available at `http://localhost:8891/http/users/123/posts?postId=456`.\n\n```go\ntype GetRequestPathParams struct {\n\tUserID string `json:\"userId\"`\n}\n\ntype GetRequestQueryParams struct {\n\tPostID string `json:\"postId\"`\n}\n\ntype GetResponse struct {\n\tMessage string `json:\"msg\"`\n}\n\n//ftl:ingress GET /http/users/{userId}/posts\nfunc Get(ctx context.Context, req builtin.HttpRequest[ftl.Unit, GetRequestPathParams, GetRequestQueryParams]) (builtin.HttpResponse[GetResponse, ErrorResponse], error) {\n  // ...\n}\n```\n\nBecause the example above only has a single path parameter it can be simplified by just using a scalar such as `string` or `int64` as the path parameter type:\n\n```go\n//ftl:ingress GET /http/users/{userId}/posts\nfunc Get(ctx context.Context, req builtin.HttpRequest[ftl.Unit, int64, GetRequestQueryParams]) (builtin.HttpResponse[GetResponse, ErrorResponse], error) {\n  // ...\n}\n```\n\n:::info\n\nThe `req` and `resp` types of HTTP `ingress` [verbs](../reference/verbs) must be `builtin.HttpRequest` and `builtin.HttpResponse` respectively. These types provide the necessary fields for HTTP `ingress` (`headers`, `statusCode`, etc.)\n\n:::\n\nKey points:\n\n- `ingress` verbs will be automatically exported by default.\n\n### Field mapping\n\nThe `HttpRequest` request object takes 3 type parameters, the body, the path parameters and the query parameters.\n\nGiven the following request verb:\n\n```go\ntype PostBody struct{\n\tTitle string               `json:\"title\"`\n\tContent string             `json:\"content\"`\n\tTag ftl.Option[string]     `json:\"tag\"`\n}\ntype PostPathParams struct {\n\tUserID string             `json:\"userId\"`\n\tPostID string             `json:\"postId\"`\n}\n\ntype PostQueryParams struct {\n\tPublish boolean `json:\"publish\"`\n}\n\n//ftl:ingress http PUT /users/{userId}/posts/{postId}\nfunc Get(ctx context.Context, req builtin.HttpRequest[PostBody, PostPathParams, PostQueryParams]) (builtin.HttpResponse[GetResponse, string], error) {\n\treturn builtin.HttpResponse[GetResponse, string]{\n\t\tHeaders: map[string][]string{\"Get\": {\"Header from FTL\"}},\n\t\tBody: ftl.Some(GetResponse{\n\t\t\tMessage: fmt.Sprintf(\"UserID: %s, PostID: %s, Tag: %s\", req.pathParameters.UserID, req.pathParameters.PostID, req.Body.Tag.Default(\"none\")),\n\t\t}),\n\t}, nil\n}\n```\n\nThe rules for how each element is mapped are slightly different, as they have a different structure:\n\n- The body is mapped directly to the body of the request, generally as a JSON object. Scalars are also supported, as well as []byte to get the raw body. If they type is `any` then it will be assumed to be JSON and mapped to the appropriate types based on the JSON structure.\n- The path parameters can be mapped directly to an object with field names corresponding to the name of the path parameter. If there is only a single path parameter it can be injected directly as a scalar. They can also be injected as a `map[string]string`.\n- The path parameters can also be mapped directly to an object with field names corresponding to the name of the path parameter. They can also be injected directly as a `map[string]string`, or `map[string][]string` for multiple values.\n\n### Optional fields\n\nOptional fields are represented by the `ftl.Option` type. The `Option` type is a wrapper around the actual type and can be `Some` or `None`. In the example above, the `Tag` field is optional.\n\n```sh\ncurl -i http://localhost:8891/users/123/posts/456\n```\n\nBecause the `tag` query parameter is not provided, the response will be:\n\n```json\n{\n  \"msg\": \"UserID: 123, PostID: 456, Tag: none\"\n}\n```\n\n### Casing\n\nField names use lowerCamelCase by default. You can override this by using the `json` tag.\n\n### SumTypes\n\nGiven the following request verb:\n\n```go\n//ftl:enum export\ntype SumType interface {\n\ttag()\n}\n\ntype A string\n\nfunc (A) tag() {}\n\ntype B []string\n\nfunc (B) tag() {}\n\n//ftl:ingress http POST /typeenum\nfunc TypeEnum(ctx context.Context, req builtin.HttpRequest[SumType, ftl.Unit, ftl.Unit]) (builtin.HttpResponse[SumType, string], error) {\n\treturn builtin.HttpResponse[SumType, string]{Body: ftl.Some(req.Body)}, nil\n}\n```\n\nThe following curl request will map the `SumType` name and value to the `req.Body`:\n\n```sh\ncurl -X POST \"http://localhost:8891/typeenum\" \\\n     -H \"Content-Type: application/json\" \\\n     --data '{\"name\": \"A\", \"value\": \"sample\"}'\n```\n\nThe response will be:\n\n```json\n{\n  \"name\": \"A\",\n  \"value\": \"sample\"\n}\n```\n\n### Encoding query params as JSON\n\nComplex query params can also be encoded as JSON using the `@json` query parameter. For example:\n\n> `{\"tag\":\"ftl\"}` url-encoded is `%7B%22tag%22%3A%22ftl%22%7D`\n\n```bash\ncurl -i http://localhost:8891/users/123/posts/456?@json=%7B%22tag%22%3A%22ftl%22%7D\n```\n\n\n",
			"java": "\n# HTTP Ingress\n\nHTTP ingress is different depending on the language you are using. The following sections describe how to define HTTP ingress in each language.\n\n\n\nJVM Languages use the `JAX-RS` annotations to define HTTP endpoints. The following example shows how to define an HTTP endpoint in Java. As the underling implementation is based on [Quarkus](https://quarkus.io)\nit is also possible to use the [Quarkus extensions to the JAX-RS annotations](https://quarkus.io/guides/rest#accessing-request-parameters).\n\nIn general the difference between the Quarkus annotation and the standard JAX-RS ones is that the Quarkus parameters infer the parameter name from the method parameter name, while the JAX-RS ones require the parameter name to be explicitly defined.\n\n```java\nimport java.util.List;\n\nimport jakarta.ws.rs.DELETE;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.PUT;\nimport jakarta.ws.rs.Path;\n\nimport jakarta.ws.rs.QueryParam; // JAX-RS annotation to get the query parameter\nimport org.jboss.resteasy.reactive.RestPath; // Quarkus annotation to get the path parameter\n\n@Path(\"/\")\npublic class TestHTTP {\n\n    @GET\n    @Path(\"/http/users/{userId}/posts\")\n    public String get(@RestPath String userId, @QueryParam(\"postId\") String post) {\n        //...\n    }\n\n}\n```\n\nUnder the hood these HTTP invocations are being mapped to verbs that take a `builtin.HttpRequest` and return a `builtin.HttpResponse`. This is not exposed directly to the user, but is instead mapped directly to `JAX-RS` annotations.\n\n\n",
			"kotlin": "\n# HTTP Ingress\n\nHTTP ingress is different depending on the language you are using. The following sections describe how to define HTTP ingress in each language.\n\n\n\nKotlin uses the `JAX-RS` annotations to define HTTP endpoints. The following example shows how to define an HTTP endpoint in Kotlin. As the underling implementation is based on [Quarkus](https://quarkus.io)\nit is also possible to use the [Quarkus extensions to the JAX-RS annotations](https://quarkus.io/guides/rest#accessing-request-parameters).\n\nIn general the difference between the Quarkus annotation and the standard JAX-RS ones is that the Quarkus parameters infer the parameter name from the method parameter name, while the JAX-RS ones require the parameter name to be explicitly defined.\n\n```kotlin\nimport java.util.List\n\nimport jakarta.ws.rs.DELETE\nimport jakarta.ws.rs.GET\nimport jakarta.ws.rs.POST\nimport jakarta.ws.rs.PUT\nimport jakarta.ws.rs.Path\n\nimport jakarta.ws.rs.QueryParam // JAX-RS annotation to get the query parameter\nimport org.jboss.resteasy.reactive.RestPath // Quarkus annotation to get the path parameter\n\n@Path(\"/\")\npublic class TestHTTP {\n\n    @GET\n    @Path(\"/http/users/{userId}/posts\")\n    fun get(@RestPath userId: String,@QueryParam(\"postId\") post: String) : String {\n        //...\n    }\n\n}\n```\n\nUnder the hood these HTTP invocations are being mapped to verbs that take a `builtin.HttpRequest` and return a `builtin.HttpResponse`. This is not exposed directly to the user, but is instead mapped directly to `JAX-RS` annotations.\n\n\n",
			"schema": "\nIn the FTL schema, HTTP ingress is represented by the `+ingress` annotation on verbs:\n\n```schema\nmodule example {\n  data GetRequestPathParams {\n    userId String\n  }\n  \n  data GetRequestQueryParams {\n    postId String\n  }\n  \n  data GetResponse {\n    message String\n  }\n  \n  data ErrorResponse {\n    error String\n  }\n  \n  // HTTP GET endpoint\n  verb get(builtin.HttpRequest<Unit, example.GetRequestPathParams, example.GetRequestQueryParams>) builtin.HttpResponse<example.GetResponse, example.ErrorResponse>\n    +ingress http GET /http/users/{userId}/posts\n}\n```\n\nThe `+ingress` annotation specifies:\n1. The ingress type (http)\n2. The HTTP method (GET, PUT, POST, DELETE, etc.)\n3. The path pattern with path parameters in curly braces\n\nHTTP ingress verbs always use the `builtin.HttpRequest` and `builtin.HttpResponse` types, which provide the necessary structure for HTTP requests and responses.\n\n\n",
	},
	"//ftl:retry": {
			"go": "\n# Retries\n\nSome FTL features allow specifying a retry policy via a language-specific directive. Retries back off exponentially until the maximum is reached.\n\n\n\nThe directive has the following syntax:\n\n```go\n//ftl:retry [<attempts=10>] <min-backoff> [<max-backoff=1hr>] [catch <catchVerb>]\n```\n\nFor example, the following function will retry up to 10 times, with a delay of 5s, 10s, 20s, 40s, 60s, 60s, etc.\n\n```go\n//ftl:retry 10 5s 1m\nfunc Process(ctx context.Context, in Invoice) error {\n  // ...\n}\n```\n\n### PubSub Subscribers\n\nSubscribers can have a retry policy. For example:\n\n```go\n//ftl:retry 5 1s catch recoverPaymentProcessing\nfunc ProcessPayment(ctx context.Context, payment Payment) error {\n...\n}\n```\n\n### Catching\n\nAfter all retries have failed, a catch verb can be used to safely recover.\n\nThese catch verbs have a request type of `builtin.CatchRequest<Req>` and no response type. If a catch verb returns an error, it will be retried until it succeeds so it is important to handle errors carefully.\n\n```go\n//ftl:retry 5 1s catch recoverPaymentProcessing\nfunc ProcessPayment(ctx context.Context, payment Payment) error {\n...\n}\n\n//ftl:verb\nfunc RecoverPaymentProcessing(ctx context.Context, request builtin.CatchRequest[Payment]) error {\n// safely handle final failure of the payment\n}\n```\n\n\n",
			"java": "\n# Retries\n\nSome FTL features allow specifying a retry policy via a language-specific directive. Retries back off exponentially until the maximum is reached.\n\n\n\nThe directive has the following syntax:\n\n```java\n@Retry(attempts = 10, minBackoff = \"5s\", maxBackoff = \"1h\", catchVerb = \"<catchVerb>\", catchModule = \"<catchModule>\")\n```\n\nFor example, the following function will retry up to 10 times, with a delay of 5s, 10s, 20s, 40s, 60s, 60s, etc.\n\n```java\n@Retry(count = 10, minBackoff = \"5s\", maxBackoff = \"1m\")\npublic void process(Invoice in) {\n    // ... \n}\n```\n\n### PubSub Subscribers\n\nSubscribers can have a retry policy. For example:\n\n```java\n@Subscription(topic = \"example\", name = \"exampleSubscription\")\n@SubscriptionOptions(from = FromOffset.LATEST)\n@Retry(count = 5, minBackoff = \"1s\", catchVerb = \"recoverPaymentProcessing\")\npublic void processPayment(Payment payment) {\n    // ... \n}\n```\n\n### Catching\n\nAfter all retries have failed, a catch verb can be used to safely recover.\n\nThese catch verbs have a request type of `CatchRequest<Req>` and no response type. If a catch verb returns an error, it will be retried until it succeeds so it is important to handle errors carefully.\n\n```java\n@Retry(count = 5, minBackoff = \"1s\", catchVerb = \"recoverPaymentProcessing\")\npublic void processPayment(Payment payment) {\n    // ... \n}\n\n@Verb\npublic void recoverPaymentProcessing(CatchRequest<Payment> req) {\n    // safely handle final failure of the payment\n}\n```\n\n\n",
			"kotlin": "\n# Retries\n\nSome FTL features allow specifying a retry policy via a language-specific directive. Retries back off exponentially until the maximum is reached.\n\n\n\nThe directive has the following syntax:\n\n```kotlin\n@Retry(attempts = 10, minBackoff = \"5s\", maxBackoff = \"1h\", catchVerb = \"<catchVerb>\", catchModule = \"<catchModule>\")\n```\n\nFor example, the following function will retry up to 10 times, with a delay of 5s, 10s, 20s, 40s, 60s, 60s, etc.\n\n```kotlin\n@Retry(count = 10, minBackoff = \"5s\", maxBackoff = \"1m\")\nfun process(inv: Invoice) {\n    // ... \n}\n```\n\n### PubSub Subscribers\n\nSubscribers can have a retry policy. For example:\n\n```kotlin\n@Subscription(topic = \"example\", name = \"exampleSubscription\")\n@SubscriptionOptions(from = FromOffset.LATEST)\n@Retry(count = 5, minBackoff = \"1s\", catchVerb = \"recoverPaymentProcessing\")\nfun processPayment(payment: Payment) {\n    // ... \n}\n```\n\n### Catching\n\nAfter all retries have failed, a catch verb can be used to safely recover.\n\nThese catch verbs have a request type of `CatchRequest<Req>` and no response type. If a catch verb returns an error, it will be retried until it succeeds so it is important to handle errors carefully.\n\n```kotlin\n@Retry(count = 5, minBackoff = \"1s\", catchVerb = \"recoverPaymentProcessing\")\nfun processPayment(payment: Payment) {\n    // ... \n}\n\n@Verb\nfun recoverPaymentProcessing(req: CatchRequest<Payment>) {\n    // safely handle final failure of the payment\n}\n```\n\n\n",
			"schema": "\nIn the FTL schema, retry policies are represented by the `+retry` annotation on verbs:\n\n```schema\nmodule example {\n  data Invoice {}\n  \n  verb process(example.Invoice) Unit\n    +retry attempts=10 min=5s max=1m\n  \n  data Payment {}\n  \n  verb processPayment(example.Payment) Unit\n    +subscribe example.payments from=latest\n    +retry attempts=5 min=1s catch=example.recoverPaymentProcessing\n  \n  verb recoverPaymentProcessing(builtin.CatchRequest<example.Payment>) Unit\n}\n```\n\nThe `+retry` annotation specifies the retry policy with parameters for attempts, minimum and maximum backoff, and an optional catch verb.\n\n\n",
	},
	"//ftl:subscribe": {
			"go": "\n# PubSub\n\nFTL has first-class support for PubSub, modelled on the concepts of topics (where events are sent) and subscribers (a verb which consumes events). Subscribers are, as you would expect, sinks. Each subscriber is a cursor over the topic it is associated with. Each topic may have multiple subscriptions. Each published event has an at least once delivery guarantee for each subscription.\n\nA topic can be exported to allow other modules to subscribe to it. Subscriptions are always private to their module.\n\nWhen a subscription is first created in an environment, it can start consuming from the beginning of the topic or only consume events published afterwards.\n\nTopics allow configuring the number of partitions and how each event should be mapped to a partition, allowing for greater throughput. Subscriptions will consume in order within each partition. There are cases where a small amount of progress on a subscription will be lost, so subscriptions should be able to handle receiving some events that have already been consumed.\n\n\n## Declaring a Topic\n\nHere's how to declare a simple topic with a single partition:\n\n\n```go\npackage payments\n\nimport (\n  \"github.com/block/ftl/go-runtime/ftl\"\n)\n\n// Define an event type\ntype Invoice struct {\n  InvoiceNo string\n}\n\n//ftl:topic partitions=1\ntype Invoices = ftl.TopicHandle[Invoice, ftl.SinglePartitionMap[Invoice]]\n```\n\nNote that the name of the topic as represented in the FTL schema is the lower camel case version of the type name.\n\nThe `Invoices` type is a handle to the topic. It is a generic type that takes two arguments: the event type and the partition map type. The partition map type is used to map events to partitions.\n\nTo export a topic, add `export` to the directive like this:\n```go\n//ftl:topic export partitions=1\n```\n\n\n## Multi-Partition Topics\n\nFor topics that require multiple partitions, you'll need to implement a partition mapper:\n\n\n```go\npackage payments\n\nimport (\n  \"github.com/block/ftl/go-runtime/ftl\"\n)\n\n// Define an event type\ntype Invoice struct {\n  InvoiceNo string\n}\n\ntype PartitionMapper struct{}\n\nvar _ ftl.TopicPartitionMap[PubSubEvent] = PartitionMapper{}\n\nfunc (PartitionMapper) PartitionKey(event PubSubEvent) string {\n\treturn event.Time.String()\n}\n\n//ftl:topic partitions=10\ntype Invoices = ftl.TopicHandle[Invoice, PartitionMapper]\n```\n\n\n## Publishing Events\n\nEvents can be published to a topic by injecting the topic into a verb:\n\n\n```go\n//ftl:verb\nfunc PublishInvoice(ctx context.Context, topic Invoices) error {\n   topic.Publish(ctx, Invoice{...})\n   // ...\n}\n```\n\n\n## Subscribing to Topics\n\nHere's how to subscribe to topics:\n\n\n```go\n// Configure initial event consumption with either from=beginning or from=latest\n//\n//ftl:subscribe payments.invoices from=beginning\nfunc SendInvoiceEmail(ctx context.Context, in Invoice) error {\n  // ...\n}\n```\n\n\n",
			"java": "\n# PubSub\n\nFTL has first-class support for PubSub, modelled on the concepts of topics (where events are sent) and subscribers (a verb which consumes events). Subscribers are, as you would expect, sinks. Each subscriber is a cursor over the topic it is associated with. Each topic may have multiple subscriptions. Each published event has an at least once delivery guarantee for each subscription.\n\nA topic can be exported to allow other modules to subscribe to it. Subscriptions are always private to their module.\n\nWhen a subscription is first created in an environment, it can start consuming from the beginning of the topic or only consume events published afterwards.\n\nTopics allow configuring the number of partitions and how each event should be mapped to a partition, allowing for greater throughput. Subscriptions will consume in order within each partition. There are cases where a small amount of progress on a subscription will be lost, so subscriptions should be able to handle receiving some events that have already been consumed.\n\n\n## Declaring a Topic\n\nHere's how to declare a simple topic with a single partition:\n\n\n```java\nimport xyz.block.ftl.Export;\nimport xyz.block.ftl.SinglePartitionMapper;\nimport xyz.block.ftl.Topic;\nimport xyz.block.ftl.WriteableTopic;\n\n// Define the event type for the topic\nrecord Invoice(String invoiceNo) {\n}\n\n// Add @Export if you want other modules to be able to consume from this topic\n@Topic(name = \"invoices\", partitions = 1)\ninterface InvoicesTopic extends WriteableTopic<Invoice, SinglePartitionMapper> {\n}\n```\n\n\n## Multi-Partition Topics\n\nFor topics that require multiple partitions, you'll need to implement a partition mapper:\n\n\n```java\nimport xyz.block.ftl.Export;\nimport xyz.block.ftl.Topic;\nimport xyz.block.ftl.TopicPartitionMapper;\nimport xyz.block.ftl.WriteableTopic;\n\n// Define the event type for the topic\nrecord Invoice(String invoiceNo) {\n}\n\n// PartitionMapper maps each to a partition in the topic\nclass PartitionMapper implements TopicPartitionMapper<Invoice> {\n    public String getPartitionKey(Invoice invoice) {\n        return invoice.invoiceNo();\n    }\n}\n\n// Add @Export if you want other modules to be able to consum from this topic\n@Topic(name = \"invoices\", partitions = 8)\ninterface InvoicesTopic extends WriteableTopic<Invoice, PartitionMapper> {\n}\n```\n\n\n## Publishing Events\n\nEvents can be published to a topic by injecting the topic into a verb:\n\n\n```java\n@Verb\nvoid publishInvoice(InvoiceRequest request, InvoicesTopic topic) throws Exception {\n    topic.publish(new Invoice(request.invoiceNo()));\n}\n```\n\n\n## Subscribing to Topics\n\nHere's how to subscribe to topics:\n\n\n```java\n// if subscribing from another module, import the event and topic\nimport ftl.othermodule.Invoice;\nimport ftl.othermodule.InvoicesTopic;\n\nimport xyz.block.ftl.FromOffset;\nimport xyz.block.ftl.Subscription;\n\nclass Subscriber {\n    @Subscription(topic = InvoicesTopic.class, from = FromOffset.LATEST)\n    public void consumeInvoice(Invoice event) {\n        // ...\n    }\n}\n```\n\nIf you are subscribing to a topic from another module, FTL will generate a topic class for you so you can subscribe to it. This generated\ntopic cannot be published to, only subscribed to:\n\n```java\n@Topic(name=\"invoices\", module=\"publisher\")\ninterface InvoicesTopic extends ConsumableTopic<Invoice> {}\n```\n\n\n",
			"kotlin": "\n# PubSub\n\nFTL has first-class support for PubSub, modelled on the concepts of topics (where events are sent) and subscribers (a verb which consumes events). Subscribers are, as you would expect, sinks. Each subscriber is a cursor over the topic it is associated with. Each topic may have multiple subscriptions. Each published event has an at least once delivery guarantee for each subscription.\n\nA topic can be exported to allow other modules to subscribe to it. Subscriptions are always private to their module.\n\nWhen a subscription is first created in an environment, it can start consuming from the beginning of the topic or only consume events published afterwards.\n\nTopics allow configuring the number of partitions and how each event should be mapped to a partition, allowing for greater throughput. Subscriptions will consume in order within each partition. There are cases where a small amount of progress on a subscription will be lost, so subscriptions should be able to handle receiving some events that have already been consumed.\n\n\n## Declaring a Topic\n\nHere's how to declare a simple topic with a single partition:\n\n\n```kotlin\nimport xyz.block.ftl.Export;\nimport xyz.block.ftl.SinglePartitionMapper\nimport xyz.block.ftl.Topic\nimport xyz.block.ftl.WriteableTopic\n\n// Define the event type for the topic\ndata class Invoice(val invoiceNo: String)\n\n// Add @Export if you want other modules to be able to consume from this topic\n@Topic(name = \"invoices\", partitions = 1)\ninternal interface InvoicesTopic : WriteableTopic<Invoice, SinglePartitionMapper>\n```\n\n\n## Multi-Partition Topics\n\nFor topics that require multiple partitions, you'll need to implement a partition mapper:\n\n\n```kotlin\nimport xyz.block.ftl.Export;\nimport xyz.block.ftl.SinglePartitionMapper\nimport xyz.block.ftl.Topic\nimport xyz.block.ftl.TopicPartitionMapper\nimport xyz.block.ftl.WriteableTopic\n\n// Define the event type for the topic\ndata class Invoice(val invoiceNo: String)\n\n// PartitionMapper maps each to a partition in the topic\nclass PartitionMapper : TopicPartitionMapper<Invoice> {\n    override fun getPartitionKey(invoice: Invoice): String {\n        return invoice.invoiceNo\n    }\n}\n\n// Add @Export if you want other modules to be able to consume from this topic\n@Topic(name = \"invoices\", partitions = 8)\ninternal interface InvoicesTopic : WriteableTopic<Invoice, PartitionMapper>\n```\n\n\n## Publishing Events\n\nEvents can be published to a topic by injecting the topic into a verb:\n\n\n```kotlin\n@Verb\nfun publishInvoice(request: InvoiceRequest, topic: InvoicesTopic) {\n    topic.publish(Invoice(request.invoiceNo))\n}\n```\n\n\n## Subscribing to Topics\n\nHere's how to subscribe to topics:\n\n\n```kotlin\n// if subscribing from another module, import the event and topic\nimport ftl.publisher.Invoice\nimport ftl.publisher.InvoicesTopic\n\nimport xyz.block.ftl.FromOffset\nimport xyz.block.ftl.Subscription\n\n@Subscription(topic = InvoicesTopic::class, from = FromOffset.LATEST)\nfun consumeInvoice(event: Invoice) {\n    // ...\n}\n```\n\nIf you are subscribing to a topic from another module, FTL will generate a topic class for you so you can subscribe to it. This generated\ntopic cannot be published to, only subscribed to:\n\n```kotlin\n@Topic(name=\"invoices\", module=\"publisher\")\ninternal interface InvoicesTopic : ConsumableTopic<Invoice>\n```\n\n\n",
			"schema": "\n```schema\nmodule payments {\n  // The Invoice data type that will be published to the topic\n  data Invoice {\n    invoiceNo String\n  }\n\n  // A topic with a single partition\n  topic invoices payments.Invoice\n}\n```\n\n\n## Multi-Partition Topics\n\nFor topics that require multiple partitions, you'll need to implement a partition mapper:\n\n\n```schema\nmodule payments {\n  // The Invoice data type that will be published to the topic\n  data Invoice {\n    invoiceNo String\n  }\n\n  // A topic with multiple partitions (8 or 10 depending on language)\n  // The partition key is determined by the mapper implementation\n  topic invoices payments.Invoice\n    +partitions 8\n}\n```\n\n\n## Publishing Events\n\nEvents can be published to a topic by injecting the topic into a verb:\n\n\n```schema\nmodule payments {\n  data InvoiceRequest {\n    invoiceNo String\n  }\n  \n  data Invoice {\n    invoiceNo String\n  }\n  \n  topic invoices payments.Invoice\n  \n  // A verb that publishes to the invoices topic\n  verb publishInvoice(payments.InvoiceRequest) Unit\n    +publish payments.invoices\n}\n```\n\n\n## Subscribing to Topics\n\nHere's how to subscribe to topics:\n\n\n```schema\nmodule payments {\n  data InvoiceRequest {\n    invoiceNo String\n  }\n  \n  data Invoice {\n    invoiceNo String\n  }\n  \n  topic invoices payments.Invoice\n  \n  // A verb that subscribes to the invoices topic\n  verb sendInvoiceEmail(payments.Invoice) Unit\n    +subscribe payments.invoices from=beginning\n}\n\n// In another module\nmodule emailer {\n  // A verb that subscribes to the invoices topic from another module\n  verb consumeInvoice(payments.Invoice) Unit\n    +subscribe payments.invoices from=latest\n}\n```\n\n\n",
	},
	"//ftl:topic": {
			"go": "\n# PubSub\n\nFTL has first-class support for PubSub, modelled on the concepts of topics (where events are sent) and subscribers (a verb which consumes events). Subscribers are, as you would expect, sinks. Each subscriber is a cursor over the topic it is associated with. Each topic may have multiple subscriptions. Each published event has an at least once delivery guarantee for each subscription.\n\nA topic can be exported to allow other modules to subscribe to it. Subscriptions are always private to their module.\n\nWhen a subscription is first created in an environment, it can start consuming from the beginning of the topic or only consume events published afterwards.\n\nTopics allow configuring the number of partitions and how each event should be mapped to a partition, allowing for greater throughput. Subscriptions will consume in order within each partition. There are cases where a small amount of progress on a subscription will be lost, so subscriptions should be able to handle receiving some events that have already been consumed.\n\n\n## Declaring a Topic\n\nHere's how to declare a simple topic with a single partition:\n\n\n```go\npackage payments\n\nimport (\n  \"github.com/block/ftl/go-runtime/ftl\"\n)\n\n// Define an event type\ntype Invoice struct {\n  InvoiceNo string\n}\n\n//ftl:topic partitions=1\ntype Invoices = ftl.TopicHandle[Invoice, ftl.SinglePartitionMap[Invoice]]\n```\n\nNote that the name of the topic as represented in the FTL schema is the lower camel case version of the type name.\n\nThe `Invoices` type is a handle to the topic. It is a generic type that takes two arguments: the event type and the partition map type. The partition map type is used to map events to partitions.\n\nTo export a topic, add `export` to the directive like this:\n```go\n//ftl:topic export partitions=1\n```\n\n\n## Multi-Partition Topics\n\nFor topics that require multiple partitions, you'll need to implement a partition mapper:\n\n\n```go\npackage payments\n\nimport (\n  \"github.com/block/ftl/go-runtime/ftl\"\n)\n\n// Define an event type\ntype Invoice struct {\n  InvoiceNo string\n}\n\ntype PartitionMapper struct{}\n\nvar _ ftl.TopicPartitionMap[PubSubEvent] = PartitionMapper{}\n\nfunc (PartitionMapper) PartitionKey(event PubSubEvent) string {\n\treturn event.Time.String()\n}\n\n//ftl:topic partitions=10\ntype Invoices = ftl.TopicHandle[Invoice, PartitionMapper]\n```\n\n\n## Publishing Events\n\nEvents can be published to a topic by injecting the topic into a verb:\n\n\n```go\n//ftl:verb\nfunc PublishInvoice(ctx context.Context, topic Invoices) error {\n   topic.Publish(ctx, Invoice{...})\n   // ...\n}\n```\n\n\n## Subscribing to Topics\n\nHere's how to subscribe to topics:\n\n\n```go\n// Configure initial event consumption with either from=beginning or from=latest\n//\n//ftl:subscribe payments.invoices from=beginning\nfunc SendInvoiceEmail(ctx context.Context, in Invoice) error {\n  // ...\n}\n```\n\n\n",
			"java": "\n# PubSub\n\nFTL has first-class support for PubSub, modelled on the concepts of topics (where events are sent) and subscribers (a verb which consumes events). Subscribers are, as you would expect, sinks. Each subscriber is a cursor over the topic it is associated with. Each topic may have multiple subscriptions. Each published event has an at least once delivery guarantee for each subscription.\n\nA topic can be exported to allow other modules to subscribe to it. Subscriptions are always private to their module.\n\nWhen a subscription is first created in an environment, it can start consuming from the beginning of the topic or only consume events published afterwards.\n\nTopics allow configuring the number of partitions and how each event should be mapped to a partition, allowing for greater throughput. Subscriptions will consume in order within each partition. There are cases where a small amount of progress on a subscription will be lost, so subscriptions should be able to handle receiving some events that have already been consumed.\n\n\n## Declaring a Topic\n\nHere's how to declare a simple topic with a single partition:\n\n\n```java\nimport xyz.block.ftl.Export;\nimport xyz.block.ftl.SinglePartitionMapper;\nimport xyz.block.ftl.Topic;\nimport xyz.block.ftl.WriteableTopic;\n\n// Define the event type for the topic\nrecord Invoice(String invoiceNo) {\n}\n\n// Add @Export if you want other modules to be able to consume from this topic\n@Topic(name = \"invoices\", partitions = 1)\ninterface InvoicesTopic extends WriteableTopic<Invoice, SinglePartitionMapper> {\n}\n```\n\n\n## Multi-Partition Topics\n\nFor topics that require multiple partitions, you'll need to implement a partition mapper:\n\n\n```java\nimport xyz.block.ftl.Export;\nimport xyz.block.ftl.Topic;\nimport xyz.block.ftl.TopicPartitionMapper;\nimport xyz.block.ftl.WriteableTopic;\n\n// Define the event type for the topic\nrecord Invoice(String invoiceNo) {\n}\n\n// PartitionMapper maps each to a partition in the topic\nclass PartitionMapper implements TopicPartitionMapper<Invoice> {\n    public String getPartitionKey(Invoice invoice) {\n        return invoice.invoiceNo();\n    }\n}\n\n// Add @Export if you want other modules to be able to consum from this topic\n@Topic(name = \"invoices\", partitions = 8)\ninterface InvoicesTopic extends WriteableTopic<Invoice, PartitionMapper> {\n}\n```\n\n\n## Publishing Events\n\nEvents can be published to a topic by injecting the topic into a verb:\n\n\n```java\n@Verb\nvoid publishInvoice(InvoiceRequest request, InvoicesTopic topic) throws Exception {\n    topic.publish(new Invoice(request.invoiceNo()));\n}\n```\n\n\n## Subscribing to Topics\n\nHere's how to subscribe to topics:\n\n\n```java\n// if subscribing from another module, import the event and topic\nimport ftl.othermodule.Invoice;\nimport ftl.othermodule.InvoicesTopic;\n\nimport xyz.block.ftl.FromOffset;\nimport xyz.block.ftl.Subscription;\n\nclass Subscriber {\n    @Subscription(topic = InvoicesTopic.class, from = FromOffset.LATEST)\n    public void consumeInvoice(Invoice event) {\n        // ...\n    }\n}\n```\n\nIf you are subscribing to a topic from another module, FTL will generate a topic class for you so you can subscribe to it. This generated\ntopic cannot be published to, only subscribed to:\n\n```java\n@Topic(name=\"invoices\", module=\"publisher\")\ninterface InvoicesTopic extends ConsumableTopic<Invoice> {}\n```\n\n\n",
			"kotlin": "\n# PubSub\n\nFTL has first-class support for PubSub, modelled on the concepts of topics (where events are sent) and subscribers (a verb which consumes events). Subscribers are, as you would expect, sinks. Each subscriber is a cursor over the topic it is associated with. Each topic may have multiple subscriptions. Each published event has an at least once delivery guarantee for each subscription.\n\nA topic can be exported to allow other modules to subscribe to it. Subscriptions are always private to their module.\n\nWhen a subscription is first created in an environment, it can start consuming from the beginning of the topic or only consume events published afterwards.\n\nTopics allow configuring the number of partitions and how each event should be mapped to a partition, allowing for greater throughput. Subscriptions will consume in order within each partition. There are cases where a small amount of progress on a subscription will be lost, so subscriptions should be able to handle receiving some events that have already been consumed.\n\n\n## Declaring a Topic\n\nHere's how to declare a simple topic with a single partition:\n\n\n```kotlin\nimport xyz.block.ftl.Export;\nimport xyz.block.ftl.SinglePartitionMapper\nimport xyz.block.ftl.Topic\nimport xyz.block.ftl.WriteableTopic\n\n// Define the event type for the topic\ndata class Invoice(val invoiceNo: String)\n\n// Add @Export if you want other modules to be able to consume from this topic\n@Topic(name = \"invoices\", partitions = 1)\ninternal interface InvoicesTopic : WriteableTopic<Invoice, SinglePartitionMapper>\n```\n\n\n## Multi-Partition Topics\n\nFor topics that require multiple partitions, you'll need to implement a partition mapper:\n\n\n```kotlin\nimport xyz.block.ftl.Export;\nimport xyz.block.ftl.SinglePartitionMapper\nimport xyz.block.ftl.Topic\nimport xyz.block.ftl.TopicPartitionMapper\nimport xyz.block.ftl.WriteableTopic\n\n// Define the event type for the topic\ndata class Invoice(val invoiceNo: String)\n\n// PartitionMapper maps each to a partition in the topic\nclass PartitionMapper : TopicPartitionMapper<Invoice> {\n    override fun getPartitionKey(invoice: Invoice): String {\n        return invoice.invoiceNo\n    }\n}\n\n// Add @Export if you want other modules to be able to consume from this topic\n@Topic(name = \"invoices\", partitions = 8)\ninternal interface InvoicesTopic : WriteableTopic<Invoice, PartitionMapper>\n```\n\n\n## Publishing Events\n\nEvents can be published to a topic by injecting the topic into a verb:\n\n\n```kotlin\n@Verb\nfun publishInvoice(request: InvoiceRequest, topic: InvoicesTopic) {\n    topic.publish(Invoice(request.invoiceNo))\n}\n```\n\n\n## Subscribing to Topics\n\nHere's how to subscribe to topics:\n\n\n```kotlin\n// if subscribing from another module, import the event and topic\nimport ftl.publisher.Invoice\nimport ftl.publisher.InvoicesTopic\n\nimport xyz.block.ftl.FromOffset\nimport xyz.block.ftl.Subscription\n\n@Subscription(topic = InvoicesTopic::class, from = FromOffset.LATEST)\nfun consumeInvoice(event: Invoice) {\n    // ...\n}\n```\n\nIf you are subscribing to a topic from another module, FTL will generate a topic class for you so you can subscribe to it. This generated\ntopic cannot be published to, only subscribed to:\n\n```kotlin\n@Topic(name=\"invoices\", module=\"publisher\")\ninternal interface InvoicesTopic : ConsumableTopic<Invoice>\n```\n\n\n",
			"schema": "\n```schema\nmodule payments {\n  // The Invoice data type that will be published to the topic\n  data Invoice {\n    invoiceNo String\n  }\n\n  // A topic with a single partition\n  topic invoices payments.Invoice\n}\n```\n\n\n## Multi-Partition Topics\n\nFor topics that require multiple partitions, you'll need to implement a partition mapper:\n\n\n```schema\nmodule payments {\n  // The Invoice data type that will be published to the topic\n  data Invoice {\n    invoiceNo String\n  }\n\n  // A topic with multiple partitions (8 or 10 depending on language)\n  // The partition key is determined by the mapper implementation\n  topic invoices payments.Invoice\n    +partitions 8\n}\n```\n\n\n## Publishing Events\n\nEvents can be published to a topic by injecting the topic into a verb:\n\n\n```schema\nmodule payments {\n  data InvoiceRequest {\n    invoiceNo String\n  }\n  \n  data Invoice {\n    invoiceNo String\n  }\n  \n  topic invoices payments.Invoice\n  \n  // A verb that publishes to the invoices topic\n  verb publishInvoice(payments.InvoiceRequest) Unit\n    +publish payments.invoices\n}\n```\n\n\n## Subscribing to Topics\n\nHere's how to subscribe to topics:\n\n\n```schema\nmodule payments {\n  data InvoiceRequest {\n    invoiceNo String\n  }\n  \n  data Invoice {\n    invoiceNo String\n  }\n  \n  topic invoices payments.Invoice\n  \n  // A verb that subscribes to the invoices topic\n  verb sendInvoiceEmail(payments.Invoice) Unit\n    +subscribe payments.invoices from=beginning\n}\n\n// In another module\nmodule emailer {\n  // A verb that subscribes to the invoices topic from another module\n  verb consumeInvoice(payments.Invoice) Unit\n    +subscribe payments.invoices from=latest\n}\n```\n\n\n",
	},
	"//ftl:typealias": {
			"go": "## Type aliases\n\nA type alias is an alternate name for an existing type. It can be declared like so:\n\n\n```go\n//ftl:typealias\ntype UserID string\n```\n\n\nType aliases are useful for making code more readable and type-safe by giving meaningful names to types that represent specific concepts in your domain.\n\n",
			"java": "## Type aliases\n\nA type alias is an alternate name for an existing type. It can be declared like so:\n\n\n```java\n// Java does not support type aliases directly\n// Use a wrapper class instead\npublic class UserID {\n    private final String value;\n\n    public UserID(String value) {\n        this.value = value;\n    }\n\n    public String getValue() {\n        return value;\n    }\n}\n```\n\n\nType aliases are useful for making code more readable and type-safe by giving meaningful names to types that represent specific concepts in your domain.\n\n",
			"kotlin": "## Type aliases\n\nA type alias is an alternate name for an existing type. It can be declared like so:\n\n\n```kotlin\ntypealias UserID = String\n```\n\n\nType aliases are useful for making code more readable and type-safe by giving meaningful names to types that represent specific concepts in your domain.\n\n",
			"schema": "\nIn the FTL schema, type aliases are defined using the `typealias` keyword:\n\n```schema\nmodule example {\n  typealias UserID String\n}\n```\n\nType aliases can be used in data structures:\n\n```schema\nmodule example {\n  typealias UserID String\n  \n  typealias UserMap Map<String, example.User>\n  \n  data User {\n    id example.UserID\n    name String\n  }\n}\n```\n\n\nType aliases are useful for making code more readable and type-safe by giving meaningful names to types that represent specific concepts in your domain.\n\n",
	},
	"//ftl:verb": {
			"go": "\n# Verbs\n\n## Defining Verbs\n\n\n\nTo declare a Verb, write a normal Go function with the following signature, annotated with the Go [comment directive](https://tip.golang.org/doc/comment#syntax) `//ftl:verb`:\n\n```go\n//ftl:verb\nfunc F(context.Context, In) (Out, error) { }\n```\n\neg.\n\n```go\ntype EchoRequest struct {}\n\ntype EchoResponse struct {}\n\n//ftl:verb\nfunc Echo(ctx context.Context, in EchoRequest) (EchoResponse, error) {\n  // ...\n}\n```\n\n\nBy default verbs are only visible to other verbs in the same module (see [visibility](./visibility) for more information).\n\n## Calling Verbs\n\n\nTo call a verb, import the module's verb client (`{ModuleName}.{VerbName}Client`), add it to your verb's signature, then invoke it as a function. eg.\n\n```go\n//ftl:verb\nfunc Echo(ctx context.Context, in EchoRequest, tc time.TimeClient) (EchoResponse, error) {\n    out, err := tc(ctx, TimeRequest{...})\n}\n```\n\nVerb clients are generated by FTL. If the callee verb belongs to the same module as the caller, you must build the\nmodule first (with callee verb defined) in order to generate its client for use by the caller. Local verb clients are\navailable in the generated `types.ftl.go` file as `{VerbName}Client`.\n\n\n",
			"java": "\n# Verbs\n\n## Defining Verbs\n\n\n\nTo declare a Verb, write a normal Java method with the following signature, annotated with the `@Verb` annotation:\n\n```java\n@Verb\npublic Output f(Input input) { }\n```\n\neg.\n\n```java\nimport xyz.block.ftl.Verb;\n\nclass EchoRequest {}\n\nclass EchoResponse {}\n\npublic class EchoClass {\n    @Verb\n    public EchoResponse echo(EchoRequest request) {\n        // ...\n    }\n}\n```\n\n\nBy default verbs are only visible to other verbs in the same module (see [visibility](./visibility) for more information).\n\n## Calling Verbs\n\n\nTo call a verb, import the module's verb client, add it to your verb's signature, then call it. eg.\n\n```java\nimport ftl.time.TimeClient;\nimport xyz.block.ftl.Verb;\n\npublic class EchoClass {\n    @Verb\n    public EchoResponse echo(EchoRequest request, TimeClient time) {\n        TimeResponse response = time.call();\n        // ...\n    }\n}\n```\n\nVerb clients are generated by FTL. If the callee verb belongs to the same module as the caller, you must manually define your\nown client:\n\n```java\npublic interface TimeClient {\n    @VerbClient\n    TimeResponse time();\n}\n```\n\n\n",
			"kotlin": "\n# Verbs\n\n## Defining Verbs\n\n\n\nTo declare a Verb, write a normal Kotlin function with the following signature, annotated with the Kotlin [annotation](https://kotlinlang.org/docs/annotations.html) `@Verb`:\n\n```kotlin\n@Verb\nfun F(In): Out { }\n```\n\neg.\n\n```kotlin\ndata class EchoRequest\ndata class EchoResponse\n\n@Verb\nfun echo(request: EchoRequest): EchoResponse {\n  // ...\n}\n```\n\n\nBy default verbs are only visible to other verbs in the same module (see [visibility](./visibility) for more information).\n\n## Calling Verbs\n\n\nTo call a verb, import the module's verb client, add it to your verb's signature, then `call()` it. eg.\n\n```kotlin\nimport ftl.time.TimeClient\nimport xyz.block.ftl.Verb\n\n@Verb\nfun echo(req: EchoRequest, time: TimeClient): EchoResponse {\n  val response = time.call()\n  // ...\n}\n\nval response = time.call()\n```\n\nVerb clients are generated by FTL. If the callee verb belongs to the same module as the caller, you must manually define your\nown client:\n\n```kotlin\ninterface TimeClient {\n    @VerbClient\n    fun time(): TimeResponse\n}\n```\n\n\n",
			"schema": "\nIn the FTL schema, verbs are declared with their input and output types:\n\n```schema\nmodule example {\n  data EchoRequest {}\n  \n  data EchoResponse {}\n  \n  verb echo(example.EchoRequest) example.EchoResponse\n}\n```\n\nVerbs can be exported to make them callable from other modules:\n\n```schema\nmodule example {\n  export verb echo(example.EchoRequest) example.EchoResponse\n}\n```\n\n\nBy default verbs are only visible to other verbs in the same module (see [visibility](./visibility) for more information).\n\n## Calling Verbs\n\n\nIn the FTL schema, verb calls are represented by the `+calls` annotation:\n\n```schema\nmodule echo {\n  data EchoRequest {}\n  \n  data EchoResponse {}\n  \n  verb echo(example.EchoRequest) example.EchoResponse\n    +calls time.time\n}\n\nmodule time {\n  data TimeRequest {}\n  \n  data TimeResponse {\n    time Time\n  }\n  \n  export verb time(time.TimeRequest) time.TimeResponse\n}\n```\n\nThe `+calls` annotation indicates that the verb calls another verb, in this case the `time` verb from the `time` module.\n\n\n",
	},
	"@Config": {
			"go": "\n# Secrets and Configuration\n\n## Configuration\n\nConfiguration values are named, typed values. They are managed by the `ftl config` command-line.\n\n\n\nTo declare a configuration value use the following syntax:\n\n```go\n// Simple string configuration\ntype ApiUrl = ftl.Config[string]\n\n// Type-safe configuration\ntype DefaultUser = ftl.Config[Username]\n```\n\nNote that the name of the configuration value as represented in the FTL schema is the lower camel case version of the type name (e.g., `ApiUrl` becomes `apiUrl`).\n\nConfiguration values can be injected into FTL methods, such as //ftl:verb, HTTP ingress, Cron etc. To inject a configuration value, use the following syntax:\n\n```go\n//ftl:verb\nfunc Hello(ctx context.Context, req Request, defaultUser DefaultUser) error {\n    username := defaultUser.Get(ctx)\n    // ...\n}\n```\n\n\n## Secrets\n\nSecrets are encrypted, named, typed values. They are managed by the `ftl secret` command-line.\n\n\nDeclare a secret with the following:\n\n```go\n// Simple string secret\ntype ApiToken = ftl.Secret[string]\n\n// Type-safe secret\ntype ApiKey = ftl.Secret[Credentials]\n```\n\nLike configuration values, the name of the secret as represented in the FTL schema is the lower camel case version of the type name (e.g., `ApiToken` becomes `apiToken`).\n\nSecrets can be injected into FTL methods, such as //ftl:verb, HTTP ingress, Cron etc. To inject a secret value, use the following syntax:\n\n```go\n//ftl:verb\nfunc CallApi(ctx context.Context, req Request, apiKey ApiKey) error {\n    credentials := apiKey.Get(ctx)\n    // ...\n}\n```\n\n\n## Transforming secrets/configuration\n\nOften, raw secret/configuration values aren't directly useful. For example, raw credentials might be used to create an API client. For those situations `ftl.Map()` can be used to transform a configuration or secret value into another type:\n\n```go\nvar client = ftl.Map(ftl.Secret[Credentials](\"credentials\"),\n                     func(ctx context.Context, creds Credentials) (*api.Client, error) {\n    return api.NewClient(creds)\n})\n```\n\nThis is not currently supported in Kotlin or Java. \n\n",
			"java": "\n# Secrets and Configuration\n\n## Configuration\n\nConfiguration values are named, typed values. They are managed by the `ftl config` command-line.\n\n\n\nConfiguration values can be injected into FTL methods, such as `@Verb`, HTTP ingress, Cron etc. To inject a configuration value, use the following syntax:\n\n```java\n@Export\n@Verb\nHelloResponse hello(HelloRequest helloRequest, @Config(\"defaultUser\") String defaultUser)  {\n    return new HelloResponse(\"Hello, \" + defaultUser);\n}\n```\n\n\n## Secrets\n\nSecrets are encrypted, named, typed values. They are managed by the `ftl secret` command-line.\n\n\nSecrets can be injected into FTL methods, such as `@Verb`, HTTP ingress, Cron etc. To inject a secret value, use the following syntax:\n\n```java\n@Export\n@Verb\nHelloResponse hello(HelloRequest helloRequest, @Secret(\"apiKey\") String apiKey)  {\n    return new HelloResponse(\"Hello, \" + api.call(apiKey));\n}\n```\n\n\n## Transforming secrets/configuration\n\nOften, raw secret/configuration values aren't directly useful. For example, raw credentials might be used to create an API client. For those situations `ftl.Map()` can be used to transform a configuration or secret value into another type:\n\n```go\nvar client = ftl.Map(ftl.Secret[Credentials](\"credentials\"),\n                     func(ctx context.Context, creds Credentials) (*api.Client, error) {\n    return api.NewClient(creds)\n})\n```\n\nThis is not currently supported in Kotlin or Java. \n\n",
			"kotlin": "\n# Secrets and Configuration\n\n## Configuration\n\nConfiguration values are named, typed values. They are managed by the `ftl config` command-line.\n\n\n\nConfiguration values can be injected into FTL methods, such as `@Verb`, HTTP ingress, Cron etc. To inject a configuration value, use the following syntax:\n\n```kotlin\n@Export\n@Verb\nfun hello(helloRequest: HelloRequest, @Config(\"defaultUser\") defaultUser: String): HelloResponse {\n    return HelloResponse(\"Hello, $defaultUser\")\n}\n```\n\n\n## Secrets\n\nSecrets are encrypted, named, typed values. They are managed by the `ftl secret` command-line.\n\n\nSecrets can be injected into FTL methods, such as `@Verb`, HTTP ingress, Cron etc. To inject a secret value, use the following syntax:\n\n```kotlin\n@Export\n@Verb\nfun hello(helloRequest: HelloRequest, @Secret(\"apiKey\") apiKey: String): HelloResponse {\n    return HelloResponse(\"Hello, ${api.call(apiKey)}\")\n}\n```\n\n\n## Transforming secrets/configuration\n\nOften, raw secret/configuration values aren't directly useful. For example, raw credentials might be used to create an API client. For those situations `ftl.Map()` can be used to transform a configuration or secret value into another type:\n\n```go\nvar client = ftl.Map(ftl.Secret[Credentials](\"credentials\"),\n                     func(ctx context.Context, creds Credentials) (*api.Client, error) {\n    return api.NewClient(creds)\n})\n```\n\nThis is not currently supported in Kotlin or Java. \n\n",
			"schema": "\nIn the FTL schema, configuration values are declared as follows:\n\n```schema\nmodule example {\n  config defaultUser String\n  \n  verb hello(Unit) String\n    +config example.defaultUser\n}\n```\n\nConfiguration values have a name, a type, and can be injected into verbs using the `+config` annotation.\n\n## Secrets\n\nSecrets are encrypted, named, typed values. They are managed by the `ftl secret` command-line.\n\n\nIn the FTL schema, secrets are declared as follows:\n\n```schema\nmodule example {\n  // Secret declaration\n  secret apiToken String\n  secret apiKey example.Credentials\n  \n  // Using a secret in a verb\n  verb callApi(example.Request) Unit\n    +secret apiKey\n}\n```\n\nSecrets have a name, a type, and can be injected into verbs using the `+secret` annotation.\n\n## Transforming secrets/configuration\n\nOften, raw secret/configuration values aren't directly useful. For example, raw credentials might be used to create an API client. For those situations `ftl.Map()` can be used to transform a configuration or secret value into another type:\n\n```go\nvar client = ftl.Map(ftl.Secret[Credentials](\"credentials\"),\n                     func(ctx context.Context, creds Credentials) (*api.Client, error) {\n    return api.NewClient(creds)\n})\n```\n\nThis is not currently supported in Kotlin or Java. \n\n",
	},
	"@Cron": {
			"go": "\n# Cron\n\nA cron job is an Empty verb that will be called on a schedule. The syntax is described [here](https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/utilities/crontab.html).\n\nYou can also use a shorthand syntax for the cron job, supporting seconds (`s`), minutes (`m`), hours (`h`), and specific days of the week (e.g. `Mon`).\n\n## Examples\n\nThe following function will be called hourly:\n\n\n\n```go\n//ftl:cron 0 * * * *\nfunc Hourly(ctx context.Context) error {\n  // ...\n}\n```\n\n\nEvery 12 hours, starting at UTC midnight:\n\n\n```go\n//ftl:cron 12h\nfunc TwiceADay(ctx context.Context) error {\n  // ...\n}\n```\n\n\nEvery Monday at UTC midnight:\n\n\n```go\n//ftl:cron Mon\nfunc Mondays(ctx context.Context) error {\n  // ...\n}\n```\n\n\n",
			"java": "\n# Cron\n\nA cron job is an Empty verb that will be called on a schedule. The syntax is described [here](https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/utilities/crontab.html).\n\nYou can also use a shorthand syntax for the cron job, supporting seconds (`s`), minutes (`m`), hours (`h`), and specific days of the week (e.g. `Mon`).\n\n## Examples\n\nThe following function will be called hourly:\n\n\n\n```java\nimport xyz.block.ftl.Cron;\n\nclass MyCron {\n    @Cron(\"0 * * * *\")\n    void hourly() {\n        \n    }\n}\n```\n\n\nEvery 12 hours, starting at UTC midnight:\n\n\n```java\nimport xyz.block.ftl.Cron;\n\nclass MyCron {\n    @Cron(\"12h\")\n    void twiceADay() {\n        \n    }\n}\n```\n\n\nEvery Monday at UTC midnight:\n\n\n```java\nimport xyz.block.ftl.Cron;\n\nclass MyCron {\n    @Cron(\"Mon\")\n    void mondays() {\n        \n    }\n}\n```\n\n\n",
			"kotlin": "\n# Cron\n\nA cron job is an Empty verb that will be called on a schedule. The syntax is described [here](https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/utilities/crontab.html).\n\nYou can also use a shorthand syntax for the cron job, supporting seconds (`s`), minutes (`m`), hours (`h`), and specific days of the week (e.g. `Mon`).\n\n## Examples\n\nThe following function will be called hourly:\n\n\n\n```kotlin\nimport xyz.block.ftl.Cron\n\n@Cron(\"0 * * * *\")\nfun hourly() {\n    \n}\n```\n\n\nEvery 12 hours, starting at UTC midnight:\n\n\n```kotlin\nimport xyz.block.ftl.Cron\n\n@Cron(\"12h\")\nfun twiceADay() {\n    \n}\n```\n\n\nEvery Monday at UTC midnight:\n\n\n```kotlin\nimport xyz.block.ftl.Cron\n\n@Cron(\"Mon\")\nfun mondays() {\n    \n}\n```\n\n\n",
			"schema": "\n```schema\nmodule example {\n  verb hourly(Unit) Unit\n    +cron \"0 * * * *\"\n}\n```\n\n\nEvery 12 hours, starting at UTC midnight:\n\n\n```schema\nmodule example {\n  verb twiceADay(Unit) Unit\n    +cron \"12h\"\n}\n```\n\n\nEvery Monday at UTC midnight:\n\n\n```schema\nmodule example {\n  verb mondays(Unit) Unit\n    +cron \"Mon\"\n}\n```\n\n\n",
	},
	"@DELETE": {
			"go": "\n# HTTP Ingress\n\nHTTP ingress is different depending on the language you are using. The following sections describe how to define HTTP ingress in each language.\n\n\n\nVerbs annotated with `ftl:ingress` will be exposed via HTTP (`http` is the default ingress type). These endpoints will then be available on one of our default `ingress` ports (local development defaults to `http://localhost:8891`).\n\nThe following will be available at `http://localhost:8891/http/users/123/posts?postId=456`.\n\n```go\ntype GetRequestPathParams struct {\n\tUserID string `json:\"userId\"`\n}\n\ntype GetRequestQueryParams struct {\n\tPostID string `json:\"postId\"`\n}\n\ntype GetResponse struct {\n\tMessage string `json:\"msg\"`\n}\n\n//ftl:ingress GET /http/users/{userId}/posts\nfunc Get(ctx context.Context, req builtin.HttpRequest[ftl.Unit, GetRequestPathParams, GetRequestQueryParams]) (builtin.HttpResponse[GetResponse, ErrorResponse], error) {\n  // ...\n}\n```\n\nBecause the example above only has a single path parameter it can be simplified by just using a scalar such as `string` or `int64` as the path parameter type:\n\n```go\n//ftl:ingress GET /http/users/{userId}/posts\nfunc Get(ctx context.Context, req builtin.HttpRequest[ftl.Unit, int64, GetRequestQueryParams]) (builtin.HttpResponse[GetResponse, ErrorResponse], error) {\n  // ...\n}\n```\n\n:::info\n\nThe `req` and `resp` types of HTTP `ingress` [verbs](../reference/verbs) must be `builtin.HttpRequest` and `builtin.HttpResponse` respectively. These types provide the necessary fields for HTTP `ingress` (`headers`, `statusCode`, etc.)\n\n:::\n\nKey points:\n\n- `ingress` verbs will be automatically exported by default.\n\n### Field mapping\n\nThe `HttpRequest` request object takes 3 type parameters, the body, the path parameters and the query parameters.\n\nGiven the following request verb:\n\n```go\ntype PostBody struct{\n\tTitle string               `json:\"title\"`\n\tContent string             `json:\"content\"`\n\tTag ftl.Option[string]     `json:\"tag\"`\n}\ntype PostPathParams struct {\n\tUserID string             `json:\"userId\"`\n\tPostID string             `json:\"postId\"`\n}\n\ntype PostQueryParams struct {\n\tPublish boolean `json:\"publish\"`\n}\n\n//ftl:ingress http PUT /users/{userId}/posts/{postId}\nfunc Get(ctx context.Context, req builtin.HttpRequest[PostBody, PostPathParams, PostQueryParams]) (builtin.HttpResponse[GetResponse, string], error) {\n\treturn builtin.HttpResponse[GetResponse, string]{\n\t\tHeaders: map[string][]string{\"Get\": {\"Header from FTL\"}},\n\t\tBody: ftl.Some(GetResponse{\n\t\t\tMessage: fmt.Sprintf(\"UserID: %s, PostID: %s, Tag: %s\", req.pathParameters.UserID, req.pathParameters.PostID, req.Body.Tag.Default(\"none\")),\n\t\t}),\n\t}, nil\n}\n```\n\nThe rules for how each element is mapped are slightly different, as they have a different structure:\n\n- The body is mapped directly to the body of the request, generally as a JSON object. Scalars are also supported, as well as []byte to get the raw body. If they type is `any` then it will be assumed to be JSON and mapped to the appropriate types based on the JSON structure.\n- The path parameters can be mapped directly to an object with field names corresponding to the name of the path parameter. If there is only a single path parameter it can be injected directly as a scalar. They can also be injected as a `map[string]string`.\n- The path parameters can also be mapped directly to an object with field names corresponding to the name of the path parameter. They can also be injected directly as a `map[string]string`, or `map[string][]string` for multiple values.\n\n### Optional fields\n\nOptional fields are represented by the `ftl.Option` type. The `Option` type is a wrapper around the actual type and can be `Some` or `None`. In the example above, the `Tag` field is optional.\n\n```sh\ncurl -i http://localhost:8891/users/123/posts/456\n```\n\nBecause the `tag` query parameter is not provided, the response will be:\n\n```json\n{\n  \"msg\": \"UserID: 123, PostID: 456, Tag: none\"\n}\n```\n\n### Casing\n\nField names use lowerCamelCase by default. You can override this by using the `json` tag.\n\n### SumTypes\n\nGiven the following request verb:\n\n```go\n//ftl:enum export\ntype SumType interface {\n\ttag()\n}\n\ntype A string\n\nfunc (A) tag() {}\n\ntype B []string\n\nfunc (B) tag() {}\n\n//ftl:ingress http POST /typeenum\nfunc TypeEnum(ctx context.Context, req builtin.HttpRequest[SumType, ftl.Unit, ftl.Unit]) (builtin.HttpResponse[SumType, string], error) {\n\treturn builtin.HttpResponse[SumType, string]{Body: ftl.Some(req.Body)}, nil\n}\n```\n\nThe following curl request will map the `SumType` name and value to the `req.Body`:\n\n```sh\ncurl -X POST \"http://localhost:8891/typeenum\" \\\n     -H \"Content-Type: application/json\" \\\n     --data '{\"name\": \"A\", \"value\": \"sample\"}'\n```\n\nThe response will be:\n\n```json\n{\n  \"name\": \"A\",\n  \"value\": \"sample\"\n}\n```\n\n### Encoding query params as JSON\n\nComplex query params can also be encoded as JSON using the `@json` query parameter. For example:\n\n> `{\"tag\":\"ftl\"}` url-encoded is `%7B%22tag%22%3A%22ftl%22%7D`\n\n```bash\ncurl -i http://localhost:8891/users/123/posts/456?@json=%7B%22tag%22%3A%22ftl%22%7D\n```\n\n\n",
			"java": "\n# HTTP Ingress\n\nHTTP ingress is different depending on the language you are using. The following sections describe how to define HTTP ingress in each language.\n\n\n\nJVM Languages use the `JAX-RS` annotations to define HTTP endpoints. The following example shows how to define an HTTP endpoint in Java. As the underling implementation is based on [Quarkus](https://quarkus.io)\nit is also possible to use the [Quarkus extensions to the JAX-RS annotations](https://quarkus.io/guides/rest#accessing-request-parameters).\n\nIn general the difference between the Quarkus annotation and the standard JAX-RS ones is that the Quarkus parameters infer the parameter name from the method parameter name, while the JAX-RS ones require the parameter name to be explicitly defined.\n\n```java\nimport java.util.List;\n\nimport jakarta.ws.rs.DELETE;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.PUT;\nimport jakarta.ws.rs.Path;\n\nimport jakarta.ws.rs.QueryParam; // JAX-RS annotation to get the query parameter\nimport org.jboss.resteasy.reactive.RestPath; // Quarkus annotation to get the path parameter\n\n@Path(\"/\")\npublic class TestHTTP {\n\n    @GET\n    @Path(\"/http/users/{userId}/posts\")\n    public String get(@RestPath String userId, @QueryParam(\"postId\") String post) {\n        //...\n    }\n\n}\n```\n\nUnder the hood these HTTP invocations are being mapped to verbs that take a `builtin.HttpRequest` and return a `builtin.HttpResponse`. This is not exposed directly to the user, but is instead mapped directly to `JAX-RS` annotations.\n\n\n",
			"kotlin": "\n# HTTP Ingress\n\nHTTP ingress is different depending on the language you are using. The following sections describe how to define HTTP ingress in each language.\n\n\n\nKotlin uses the `JAX-RS` annotations to define HTTP endpoints. The following example shows how to define an HTTP endpoint in Kotlin. As the underling implementation is based on [Quarkus](https://quarkus.io)\nit is also possible to use the [Quarkus extensions to the JAX-RS annotations](https://quarkus.io/guides/rest#accessing-request-parameters).\n\nIn general the difference between the Quarkus annotation and the standard JAX-RS ones is that the Quarkus parameters infer the parameter name from the method parameter name, while the JAX-RS ones require the parameter name to be explicitly defined.\n\n```kotlin\nimport java.util.List\n\nimport jakarta.ws.rs.DELETE\nimport jakarta.ws.rs.GET\nimport jakarta.ws.rs.POST\nimport jakarta.ws.rs.PUT\nimport jakarta.ws.rs.Path\n\nimport jakarta.ws.rs.QueryParam // JAX-RS annotation to get the query parameter\nimport org.jboss.resteasy.reactive.RestPath // Quarkus annotation to get the path parameter\n\n@Path(\"/\")\npublic class TestHTTP {\n\n    @GET\n    @Path(\"/http/users/{userId}/posts\")\n    fun get(@RestPath userId: String,@QueryParam(\"postId\") post: String) : String {\n        //...\n    }\n\n}\n```\n\nUnder the hood these HTTP invocations are being mapped to verbs that take a `builtin.HttpRequest` and return a `builtin.HttpResponse`. This is not exposed directly to the user, but is instead mapped directly to `JAX-RS` annotations.\n\n\n",
			"schema": "\nIn the FTL schema, HTTP ingress is represented by the `+ingress` annotation on verbs:\n\n```schema\nmodule example {\n  data GetRequestPathParams {\n    userId String\n  }\n  \n  data GetRequestQueryParams {\n    postId String\n  }\n  \n  data GetResponse {\n    message String\n  }\n  \n  data ErrorResponse {\n    error String\n  }\n  \n  // HTTP GET endpoint\n  verb get(builtin.HttpRequest<Unit, example.GetRequestPathParams, example.GetRequestQueryParams>) builtin.HttpResponse<example.GetResponse, example.ErrorResponse>\n    +ingress http GET /http/users/{userId}/posts\n}\n```\n\nThe `+ingress` annotation specifies:\n1. The ingress type (http)\n2. The HTTP method (GET, PUT, POST, DELETE, etc.)\n3. The path pattern with path parameters in curly braces\n\nHTTP ingress verbs always use the `builtin.HttpRequest` and `builtin.HttpResponse` types, which provide the necessary structure for HTTP requests and responses.\n\n\n",
	},
	"@Enum": {
			"go": "## Type enums (sum types)\n\n[Sum types](https://en.wikipedia.org/wiki/Tagged_union) are supported by FTL's type system.\n\n\nSum types aren't directly supported by Go, however they can be approximated with the use of [sealed interfaces](https://blog.chewxy.com/2018/03/18/golang-interfaces/):\n\n```go\n//ftl:enum\ntype Animal interface { animal() }\n\ntype Cat struct {}\nfunc (Cat) animal() {}\n\ntype Dog struct {}\nfunc (Dog) animal() {}\n```\n\n## Value enums\n\nA value enum is an enumerated set of string or integer values.\n\n\n```go\n//ftl:enum\ntype Colour string\n\nconst (\n  Red   Colour = \"red\"\n  Green Colour = \"green\"\n  Blue  Colour = \"blue\"\n)\n\n//ftl:enum\ntype Status int\n\nconst (\n  Active   Status = 1\n  Inactive Status = 0\n  Pending  Status = 2\n)\n```\n\n\n",
			"java": "## Type enums (sum types)\n\n[Sum types](https://en.wikipedia.org/wiki/Tagged_union) are supported by FTL's type system.\n\n\n> TODO\n\n## Value enums\n\nA value enum is an enumerated set of string or integer values.\n\n\n```java\n@Enum\npublic enum Colour {\n  Red(\"red\"),\n  Green(\"green\"),\n  Blue(\"blue\");\n\n  private final String value;\n\n  Colour(String value) {\n    this.value = value;\n  }\n}\n\n@Enum\npublic enum Status {\n  Active(1),\n  Inactive(0),\n  Pending(2);\n\n  private final int value;\n\n  Status(int value) {\n    this.value = value;\n  }\n}\n```\n\n\n",
			"kotlin": "## Type enums (sum types)\n\n[Sum types](https://en.wikipedia.org/wiki/Tagged_union) are supported by FTL's type system.\n\n\nSum types aren't directly supported by Kotlin, however they can be approximated with the use of [sealed interfaces](https://kotlinlang.org/docs/sealed-classes.html):\n\n```kotlin\n@Enum\nsealed interface Animal\n\n@EnumHolder\nclass Cat() : Animal\n\n@EnumHolder\nclass Dog() : Animal\n```\n\n## Value enums\n\nA value enum is an enumerated set of string or integer values.\n\n\n```kotlin\n@Enum\npublic enum class Colour(\n  public final val `value`: String,\n) {\n  Red(\"red\"),\n  Green(\"green\"),\n  Blue(\"blue\"),\n  ;\n}\n\n@Enum\npublic enum class Status(\n  public final val `value`: Int,\n) {\n  Active(1),\n  Inactive(0),\n  Pending(2),\n  ;\n}\n```\n\n\n",
			"schema": "\nIn the FTL schema, sum types (type enums) are represented as a union of types:\n\n```schema\nmodule example {\n  data Cat {}\n  \n  data Dog {}\n  \n  enum Animal {\n    Cat example.Cat\n    Dog example.Dog\n  }\n}\n```\n\nWhen used in other types or verbs, the sum type can be referenced directly:\n\n```schema\nmodule example {\n  verb processAnimal(example.Animal) Unit\n}\n```\n\n## Value enums\n\nA value enum is an enumerated set of string or integer values.\n\n\nIn the FTL schema, value enums are represented as an enum with string or integer values:\n\n```schema\nmodule example {\n  enum Colour: String {\n    Red = \"red\"\n    Green = \"green\"\n    Blue = \"blue\"\n  }\n  \n  enum Status: Int {\n    Active = 1\n    Inactive = 0\n    Pending = 2\n  }\n}\n```\n\n\n",
	},
	"@Export": {
			"go": "\n# Visibility\n\nBy default all declarations in FTL are visible only to the module they're declared in. The implicit visibility of types is that of the first verb or other declaration that references it.\n\n## Exporting declarations\n\nExporting a declaration makes it accessible to other modules. Some declarations that are entirely local to a module, such as secrets/config, cannot be exported.\n\nTypes that are transitively referenced by an exported declaration will be automatically exported unless they were already defined but unexported. In this case, an error will be raised and the type must be explicitly exported.\n\n\n\nThe following table describes the go directives used to export the corresponding declaration:\n\n| Symbol        | Export syntax            |\n| ------------- | ------------------------ |\n| Verb          | `//ftl:verb export`      |\n| Data          | `//ftl:data export`      |\n| Enum/Sum type | `//ftl:enum export`      |\n| Typealias     | `//ftl:typealias export` |\n| Topic         | `//ftl:export` [^1]      |\n\n```go\n//ftl:verb export\nfunc Verb(ctx context.Context, in In) (Out, error)\n\n//ftl:typealias export\ntype UserID string\n```\n\n[^1]: By default, topics do not require any annotations as the declaration itself is sufficient.\n\n\n",
			"java": "\n# Visibility\n\nBy default all declarations in FTL are visible only to the module they're declared in. The implicit visibility of types is that of the first verb or other declaration that references it.\n\n## Exporting declarations\n\nExporting a declaration makes it accessible to other modules. Some declarations that are entirely local to a module, such as secrets/config, cannot be exported.\n\nTypes that are transitively referenced by an exported declaration will be automatically exported unless they were already defined but unexported. In this case, an error will be raised and the type must be explicitly exported.\n\n\n\nFor Java the `@Export` annotation can be used to export a declaration:\n\n```java\n@Verb\n@Export\nTimeResponse time()  {\n    // ...\n}\n```\n\n\n",
			"kotlin": "\n# Visibility\n\nBy default all declarations in FTL are visible only to the module they're declared in. The implicit visibility of types is that of the first verb or other declaration that references it.\n\n## Exporting declarations\n\nExporting a declaration makes it accessible to other modules. Some declarations that are entirely local to a module, such as secrets/config, cannot be exported.\n\nTypes that are transitively referenced by an exported declaration will be automatically exported unless they were already defined but unexported. In this case, an error will be raised and the type must be explicitly exported.\n\n\n\nFor Kotlin the `@Export` annotation can be used to export a declaration:\n\n```kotlin\n@Verb\n@Export\nfun time(): TimeResponse {\n    // ...\n}\n```\n\n\n",
			"schema": "\nIn the FTL schema, exported declarations are prefixed with the `export` keyword:\n\n```schema\nmodule example {\n  export data TimeResponse {\n    time Time\n  }\n  \n  export verb time(Unit) example.TimeResponse\n  \n  export topic events example.Event\n  \n  export typealias UserID String\n}\n```\n\nNon-exported declarations are visible only within their module:\n\n```schema\nmodule example {\n  data InternalConfig {\n    setting String\n  }\n  \n  verb internalProcess(example.InternalConfig) Unit\n}\n```\n\n\n",
	},
	"@GET": {
			"go": "\n# HTTP Ingress\n\nHTTP ingress is different depending on the language you are using. The following sections describe how to define HTTP ingress in each language.\n\n\n\nVerbs annotated with `ftl:ingress` will be exposed via HTTP (`http` is the default ingress type). These endpoints will then be available on one of our default `ingress` ports (local development defaults to `http://localhost:8891`).\n\nThe following will be available at `http://localhost:8891/http/users/123/posts?postId=456`.\n\n```go\ntype GetRequestPathParams struct {\n\tUserID string `json:\"userId\"`\n}\n\ntype GetRequestQueryParams struct {\n\tPostID string `json:\"postId\"`\n}\n\ntype GetResponse struct {\n\tMessage string `json:\"msg\"`\n}\n\n//ftl:ingress GET /http/users/{userId}/posts\nfunc Get(ctx context.Context, req builtin.HttpRequest[ftl.Unit, GetRequestPathParams, GetRequestQueryParams]) (builtin.HttpResponse[GetResponse, ErrorResponse], error) {\n  // ...\n}\n```\n\nBecause the example above only has a single path parameter it can be simplified by just using a scalar such as `string` or `int64` as the path parameter type:\n\n```go\n//ftl:ingress GET /http/users/{userId}/posts\nfunc Get(ctx context.Context, req builtin.HttpRequest[ftl.Unit, int64, GetRequestQueryParams]) (builtin.HttpResponse[GetResponse, ErrorResponse], error) {\n  // ...\n}\n```\n\n:::info\n\nThe `req` and `resp` types of HTTP `ingress` [verbs](../reference/verbs) must be `builtin.HttpRequest` and `builtin.HttpResponse` respectively. These types provide the necessary fields for HTTP `ingress` (`headers`, `statusCode`, etc.)\n\n:::\n\nKey points:\n\n- `ingress` verbs will be automatically exported by default.\n\n### Field mapping\n\nThe `HttpRequest` request object takes 3 type parameters, the body, the path parameters and the query parameters.\n\nGiven the following request verb:\n\n```go\ntype PostBody struct{\n\tTitle string               `json:\"title\"`\n\tContent string             `json:\"content\"`\n\tTag ftl.Option[string]     `json:\"tag\"`\n}\ntype PostPathParams struct {\n\tUserID string             `json:\"userId\"`\n\tPostID string             `json:\"postId\"`\n}\n\ntype PostQueryParams struct {\n\tPublish boolean `json:\"publish\"`\n}\n\n//ftl:ingress http PUT /users/{userId}/posts/{postId}\nfunc Get(ctx context.Context, req builtin.HttpRequest[PostBody, PostPathParams, PostQueryParams]) (builtin.HttpResponse[GetResponse, string], error) {\n\treturn builtin.HttpResponse[GetResponse, string]{\n\t\tHeaders: map[string][]string{\"Get\": {\"Header from FTL\"}},\n\t\tBody: ftl.Some(GetResponse{\n\t\t\tMessage: fmt.Sprintf(\"UserID: %s, PostID: %s, Tag: %s\", req.pathParameters.UserID, req.pathParameters.PostID, req.Body.Tag.Default(\"none\")),\n\t\t}),\n\t}, nil\n}\n```\n\nThe rules for how each element is mapped are slightly different, as they have a different structure:\n\n- The body is mapped directly to the body of the request, generally as a JSON object. Scalars are also supported, as well as []byte to get the raw body. If they type is `any` then it will be assumed to be JSON and mapped to the appropriate types based on the JSON structure.\n- The path parameters can be mapped directly to an object with field names corresponding to the name of the path parameter. If there is only a single path parameter it can be injected directly as a scalar. They can also be injected as a `map[string]string`.\n- The path parameters can also be mapped directly to an object with field names corresponding to the name of the path parameter. They can also be injected directly as a `map[string]string`, or `map[string][]string` for multiple values.\n\n### Optional fields\n\nOptional fields are represented by the `ftl.Option` type. The `Option` type is a wrapper around the actual type and can be `Some` or `None`. In the example above, the `Tag` field is optional.\n\n```sh\ncurl -i http://localhost:8891/users/123/posts/456\n```\n\nBecause the `tag` query parameter is not provided, the response will be:\n\n```json\n{\n  \"msg\": \"UserID: 123, PostID: 456, Tag: none\"\n}\n```\n\n### Casing\n\nField names use lowerCamelCase by default. You can override this by using the `json` tag.\n\n### SumTypes\n\nGiven the following request verb:\n\n```go\n//ftl:enum export\ntype SumType interface {\n\ttag()\n}\n\ntype A string\n\nfunc (A) tag() {}\n\ntype B []string\n\nfunc (B) tag() {}\n\n//ftl:ingress http POST /typeenum\nfunc TypeEnum(ctx context.Context, req builtin.HttpRequest[SumType, ftl.Unit, ftl.Unit]) (builtin.HttpResponse[SumType, string], error) {\n\treturn builtin.HttpResponse[SumType, string]{Body: ftl.Some(req.Body)}, nil\n}\n```\n\nThe following curl request will map the `SumType` name and value to the `req.Body`:\n\n```sh\ncurl -X POST \"http://localhost:8891/typeenum\" \\\n     -H \"Content-Type: application/json\" \\\n     --data '{\"name\": \"A\", \"value\": \"sample\"}'\n```\n\nThe response will be:\n\n```json\n{\n  \"name\": \"A\",\n  \"value\": \"sample\"\n}\n```\n\n### Encoding query params as JSON\n\nComplex query params can also be encoded as JSON using the `@json` query parameter. For example:\n\n> `{\"tag\":\"ftl\"}` url-encoded is `%7B%22tag%22%3A%22ftl%22%7D`\n\n```bash\ncurl -i http://localhost:8891/users/123/posts/456?@json=%7B%22tag%22%3A%22ftl%22%7D\n```\n\n\n",
			"java": "\n# HTTP Ingress\n\nHTTP ingress is different depending on the language you are using. The following sections describe how to define HTTP ingress in each language.\n\n\n\nJVM Languages use the `JAX-RS` annotations to define HTTP endpoints. The following example shows how to define an HTTP endpoint in Java. As the underling implementation is based on [Quarkus](https://quarkus.io)\nit is also possible to use the [Quarkus extensions to the JAX-RS annotations](https://quarkus.io/guides/rest#accessing-request-parameters).\n\nIn general the difference between the Quarkus annotation and the standard JAX-RS ones is that the Quarkus parameters infer the parameter name from the method parameter name, while the JAX-RS ones require the parameter name to be explicitly defined.\n\n```java\nimport java.util.List;\n\nimport jakarta.ws.rs.DELETE;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.PUT;\nimport jakarta.ws.rs.Path;\n\nimport jakarta.ws.rs.QueryParam; // JAX-RS annotation to get the query parameter\nimport org.jboss.resteasy.reactive.RestPath; // Quarkus annotation to get the path parameter\n\n@Path(\"/\")\npublic class TestHTTP {\n\n    @GET\n    @Path(\"/http/users/{userId}/posts\")\n    public String get(@RestPath String userId, @QueryParam(\"postId\") String post) {\n        //...\n    }\n\n}\n```\n\nUnder the hood these HTTP invocations are being mapped to verbs that take a `builtin.HttpRequest` and return a `builtin.HttpResponse`. This is not exposed directly to the user, but is instead mapped directly to `JAX-RS` annotations.\n\n\n",
			"kotlin": "\n# HTTP Ingress\n\nHTTP ingress is different depending on the language you are using. The following sections describe how to define HTTP ingress in each language.\n\n\n\nKotlin uses the `JAX-RS` annotations to define HTTP endpoints. The following example shows how to define an HTTP endpoint in Kotlin. As the underling implementation is based on [Quarkus](https://quarkus.io)\nit is also possible to use the [Quarkus extensions to the JAX-RS annotations](https://quarkus.io/guides/rest#accessing-request-parameters).\n\nIn general the difference between the Quarkus annotation and the standard JAX-RS ones is that the Quarkus parameters infer the parameter name from the method parameter name, while the JAX-RS ones require the parameter name to be explicitly defined.\n\n```kotlin\nimport java.util.List\n\nimport jakarta.ws.rs.DELETE\nimport jakarta.ws.rs.GET\nimport jakarta.ws.rs.POST\nimport jakarta.ws.rs.PUT\nimport jakarta.ws.rs.Path\n\nimport jakarta.ws.rs.QueryParam // JAX-RS annotation to get the query parameter\nimport org.jboss.resteasy.reactive.RestPath // Quarkus annotation to get the path parameter\n\n@Path(\"/\")\npublic class TestHTTP {\n\n    @GET\n    @Path(\"/http/users/{userId}/posts\")\n    fun get(@RestPath userId: String,@QueryParam(\"postId\") post: String) : String {\n        //...\n    }\n\n}\n```\n\nUnder the hood these HTTP invocations are being mapped to verbs that take a `builtin.HttpRequest` and return a `builtin.HttpResponse`. This is not exposed directly to the user, but is instead mapped directly to `JAX-RS` annotations.\n\n\n",
			"schema": "\nIn the FTL schema, HTTP ingress is represented by the `+ingress` annotation on verbs:\n\n```schema\nmodule example {\n  data GetRequestPathParams {\n    userId String\n  }\n  \n  data GetRequestQueryParams {\n    postId String\n  }\n  \n  data GetResponse {\n    message String\n  }\n  \n  data ErrorResponse {\n    error String\n  }\n  \n  // HTTP GET endpoint\n  verb get(builtin.HttpRequest<Unit, example.GetRequestPathParams, example.GetRequestQueryParams>) builtin.HttpResponse<example.GetResponse, example.ErrorResponse>\n    +ingress http GET /http/users/{userId}/posts\n}\n```\n\nThe `+ingress` annotation specifies:\n1. The ingress type (http)\n2. The HTTP method (GET, PUT, POST, DELETE, etc.)\n3. The path pattern with path parameters in curly braces\n\nHTTP ingress verbs always use the `builtin.HttpRequest` and `builtin.HttpResponse` types, which provide the necessary structure for HTTP requests and responses.\n\n\n",
	},
	"@POST": {
			"go": "\n# HTTP Ingress\n\nHTTP ingress is different depending on the language you are using. The following sections describe how to define HTTP ingress in each language.\n\n\n\nVerbs annotated with `ftl:ingress` will be exposed via HTTP (`http` is the default ingress type). These endpoints will then be available on one of our default `ingress` ports (local development defaults to `http://localhost:8891`).\n\nThe following will be available at `http://localhost:8891/http/users/123/posts?postId=456`.\n\n```go\ntype GetRequestPathParams struct {\n\tUserID string `json:\"userId\"`\n}\n\ntype GetRequestQueryParams struct {\n\tPostID string `json:\"postId\"`\n}\n\ntype GetResponse struct {\n\tMessage string `json:\"msg\"`\n}\n\n//ftl:ingress GET /http/users/{userId}/posts\nfunc Get(ctx context.Context, req builtin.HttpRequest[ftl.Unit, GetRequestPathParams, GetRequestQueryParams]) (builtin.HttpResponse[GetResponse, ErrorResponse], error) {\n  // ...\n}\n```\n\nBecause the example above only has a single path parameter it can be simplified by just using a scalar such as `string` or `int64` as the path parameter type:\n\n```go\n//ftl:ingress GET /http/users/{userId}/posts\nfunc Get(ctx context.Context, req builtin.HttpRequest[ftl.Unit, int64, GetRequestQueryParams]) (builtin.HttpResponse[GetResponse, ErrorResponse], error) {\n  // ...\n}\n```\n\n:::info\n\nThe `req` and `resp` types of HTTP `ingress` [verbs](../reference/verbs) must be `builtin.HttpRequest` and `builtin.HttpResponse` respectively. These types provide the necessary fields for HTTP `ingress` (`headers`, `statusCode`, etc.)\n\n:::\n\nKey points:\n\n- `ingress` verbs will be automatically exported by default.\n\n### Field mapping\n\nThe `HttpRequest` request object takes 3 type parameters, the body, the path parameters and the query parameters.\n\nGiven the following request verb:\n\n```go\ntype PostBody struct{\n\tTitle string               `json:\"title\"`\n\tContent string             `json:\"content\"`\n\tTag ftl.Option[string]     `json:\"tag\"`\n}\ntype PostPathParams struct {\n\tUserID string             `json:\"userId\"`\n\tPostID string             `json:\"postId\"`\n}\n\ntype PostQueryParams struct {\n\tPublish boolean `json:\"publish\"`\n}\n\n//ftl:ingress http PUT /users/{userId}/posts/{postId}\nfunc Get(ctx context.Context, req builtin.HttpRequest[PostBody, PostPathParams, PostQueryParams]) (builtin.HttpResponse[GetResponse, string], error) {\n\treturn builtin.HttpResponse[GetResponse, string]{\n\t\tHeaders: map[string][]string{\"Get\": {\"Header from FTL\"}},\n\t\tBody: ftl.Some(GetResponse{\n\t\t\tMessage: fmt.Sprintf(\"UserID: %s, PostID: %s, Tag: %s\", req.pathParameters.UserID, req.pathParameters.PostID, req.Body.Tag.Default(\"none\")),\n\t\t}),\n\t}, nil\n}\n```\n\nThe rules for how each element is mapped are slightly different, as they have a different structure:\n\n- The body is mapped directly to the body of the request, generally as a JSON object. Scalars are also supported, as well as []byte to get the raw body. If they type is `any` then it will be assumed to be JSON and mapped to the appropriate types based on the JSON structure.\n- The path parameters can be mapped directly to an object with field names corresponding to the name of the path parameter. If there is only a single path parameter it can be injected directly as a scalar. They can also be injected as a `map[string]string`.\n- The path parameters can also be mapped directly to an object with field names corresponding to the name of the path parameter. They can also be injected directly as a `map[string]string`, or `map[string][]string` for multiple values.\n\n### Optional fields\n\nOptional fields are represented by the `ftl.Option` type. The `Option` type is a wrapper around the actual type and can be `Some` or `None`. In the example above, the `Tag` field is optional.\n\n```sh\ncurl -i http://localhost:8891/users/123/posts/456\n```\n\nBecause the `tag` query parameter is not provided, the response will be:\n\n```json\n{\n  \"msg\": \"UserID: 123, PostID: 456, Tag: none\"\n}\n```\n\n### Casing\n\nField names use lowerCamelCase by default. You can override this by using the `json` tag.\n\n### SumTypes\n\nGiven the following request verb:\n\n```go\n//ftl:enum export\ntype SumType interface {\n\ttag()\n}\n\ntype A string\n\nfunc (A) tag() {}\n\ntype B []string\n\nfunc (B) tag() {}\n\n//ftl:ingress http POST /typeenum\nfunc TypeEnum(ctx context.Context, req builtin.HttpRequest[SumType, ftl.Unit, ftl.Unit]) (builtin.HttpResponse[SumType, string], error) {\n\treturn builtin.HttpResponse[SumType, string]{Body: ftl.Some(req.Body)}, nil\n}\n```\n\nThe following curl request will map the `SumType` name and value to the `req.Body`:\n\n```sh\ncurl -X POST \"http://localhost:8891/typeenum\" \\\n     -H \"Content-Type: application/json\" \\\n     --data '{\"name\": \"A\", \"value\": \"sample\"}'\n```\n\nThe response will be:\n\n```json\n{\n  \"name\": \"A\",\n  \"value\": \"sample\"\n}\n```\n\n### Encoding query params as JSON\n\nComplex query params can also be encoded as JSON using the `@json` query parameter. For example:\n\n> `{\"tag\":\"ftl\"}` url-encoded is `%7B%22tag%22%3A%22ftl%22%7D`\n\n```bash\ncurl -i http://localhost:8891/users/123/posts/456?@json=%7B%22tag%22%3A%22ftl%22%7D\n```\n\n\n",
			"java": "\n# HTTP Ingress\n\nHTTP ingress is different depending on the language you are using. The following sections describe how to define HTTP ingress in each language.\n\n\n\nJVM Languages use the `JAX-RS` annotations to define HTTP endpoints. The following example shows how to define an HTTP endpoint in Java. As the underling implementation is based on [Quarkus](https://quarkus.io)\nit is also possible to use the [Quarkus extensions to the JAX-RS annotations](https://quarkus.io/guides/rest#accessing-request-parameters).\n\nIn general the difference between the Quarkus annotation and the standard JAX-RS ones is that the Quarkus parameters infer the parameter name from the method parameter name, while the JAX-RS ones require the parameter name to be explicitly defined.\n\n```java\nimport java.util.List;\n\nimport jakarta.ws.rs.DELETE;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.PUT;\nimport jakarta.ws.rs.Path;\n\nimport jakarta.ws.rs.QueryParam; // JAX-RS annotation to get the query parameter\nimport org.jboss.resteasy.reactive.RestPath; // Quarkus annotation to get the path parameter\n\n@Path(\"/\")\npublic class TestHTTP {\n\n    @GET\n    @Path(\"/http/users/{userId}/posts\")\n    public String get(@RestPath String userId, @QueryParam(\"postId\") String post) {\n        //...\n    }\n\n}\n```\n\nUnder the hood these HTTP invocations are being mapped to verbs that take a `builtin.HttpRequest` and return a `builtin.HttpResponse`. This is not exposed directly to the user, but is instead mapped directly to `JAX-RS` annotations.\n\n\n",
			"kotlin": "\n# HTTP Ingress\n\nHTTP ingress is different depending on the language you are using. The following sections describe how to define HTTP ingress in each language.\n\n\n\nKotlin uses the `JAX-RS` annotations to define HTTP endpoints. The following example shows how to define an HTTP endpoint in Kotlin. As the underling implementation is based on [Quarkus](https://quarkus.io)\nit is also possible to use the [Quarkus extensions to the JAX-RS annotations](https://quarkus.io/guides/rest#accessing-request-parameters).\n\nIn general the difference between the Quarkus annotation and the standard JAX-RS ones is that the Quarkus parameters infer the parameter name from the method parameter name, while the JAX-RS ones require the parameter name to be explicitly defined.\n\n```kotlin\nimport java.util.List\n\nimport jakarta.ws.rs.DELETE\nimport jakarta.ws.rs.GET\nimport jakarta.ws.rs.POST\nimport jakarta.ws.rs.PUT\nimport jakarta.ws.rs.Path\n\nimport jakarta.ws.rs.QueryParam // JAX-RS annotation to get the query parameter\nimport org.jboss.resteasy.reactive.RestPath // Quarkus annotation to get the path parameter\n\n@Path(\"/\")\npublic class TestHTTP {\n\n    @GET\n    @Path(\"/http/users/{userId}/posts\")\n    fun get(@RestPath userId: String,@QueryParam(\"postId\") post: String) : String {\n        //...\n    }\n\n}\n```\n\nUnder the hood these HTTP invocations are being mapped to verbs that take a `builtin.HttpRequest` and return a `builtin.HttpResponse`. This is not exposed directly to the user, but is instead mapped directly to `JAX-RS` annotations.\n\n\n",
			"schema": "\nIn the FTL schema, HTTP ingress is represented by the `+ingress` annotation on verbs:\n\n```schema\nmodule example {\n  data GetRequestPathParams {\n    userId String\n  }\n  \n  data GetRequestQueryParams {\n    postId String\n  }\n  \n  data GetResponse {\n    message String\n  }\n  \n  data ErrorResponse {\n    error String\n  }\n  \n  // HTTP GET endpoint\n  verb get(builtin.HttpRequest<Unit, example.GetRequestPathParams, example.GetRequestQueryParams>) builtin.HttpResponse<example.GetResponse, example.ErrorResponse>\n    +ingress http GET /http/users/{userId}/posts\n}\n```\n\nThe `+ingress` annotation specifies:\n1. The ingress type (http)\n2. The HTTP method (GET, PUT, POST, DELETE, etc.)\n3. The path pattern with path parameters in curly braces\n\nHTTP ingress verbs always use the `builtin.HttpRequest` and `builtin.HttpResponse` types, which provide the necessary structure for HTTP requests and responses.\n\n\n",
	},
	"@PUT": {
			"go": "\n# HTTP Ingress\n\nHTTP ingress is different depending on the language you are using. The following sections describe how to define HTTP ingress in each language.\n\n\n\nVerbs annotated with `ftl:ingress` will be exposed via HTTP (`http` is the default ingress type). These endpoints will then be available on one of our default `ingress` ports (local development defaults to `http://localhost:8891`).\n\nThe following will be available at `http://localhost:8891/http/users/123/posts?postId=456`.\n\n```go\ntype GetRequestPathParams struct {\n\tUserID string `json:\"userId\"`\n}\n\ntype GetRequestQueryParams struct {\n\tPostID string `json:\"postId\"`\n}\n\ntype GetResponse struct {\n\tMessage string `json:\"msg\"`\n}\n\n//ftl:ingress GET /http/users/{userId}/posts\nfunc Get(ctx context.Context, req builtin.HttpRequest[ftl.Unit, GetRequestPathParams, GetRequestQueryParams]) (builtin.HttpResponse[GetResponse, ErrorResponse], error) {\n  // ...\n}\n```\n\nBecause the example above only has a single path parameter it can be simplified by just using a scalar such as `string` or `int64` as the path parameter type:\n\n```go\n//ftl:ingress GET /http/users/{userId}/posts\nfunc Get(ctx context.Context, req builtin.HttpRequest[ftl.Unit, int64, GetRequestQueryParams]) (builtin.HttpResponse[GetResponse, ErrorResponse], error) {\n  // ...\n}\n```\n\n:::info\n\nThe `req` and `resp` types of HTTP `ingress` [verbs](../reference/verbs) must be `builtin.HttpRequest` and `builtin.HttpResponse` respectively. These types provide the necessary fields for HTTP `ingress` (`headers`, `statusCode`, etc.)\n\n:::\n\nKey points:\n\n- `ingress` verbs will be automatically exported by default.\n\n### Field mapping\n\nThe `HttpRequest` request object takes 3 type parameters, the body, the path parameters and the query parameters.\n\nGiven the following request verb:\n\n```go\ntype PostBody struct{\n\tTitle string               `json:\"title\"`\n\tContent string             `json:\"content\"`\n\tTag ftl.Option[string]     `json:\"tag\"`\n}\ntype PostPathParams struct {\n\tUserID string             `json:\"userId\"`\n\tPostID string             `json:\"postId\"`\n}\n\ntype PostQueryParams struct {\n\tPublish boolean `json:\"publish\"`\n}\n\n//ftl:ingress http PUT /users/{userId}/posts/{postId}\nfunc Get(ctx context.Context, req builtin.HttpRequest[PostBody, PostPathParams, PostQueryParams]) (builtin.HttpResponse[GetResponse, string], error) {\n\treturn builtin.HttpResponse[GetResponse, string]{\n\t\tHeaders: map[string][]string{\"Get\": {\"Header from FTL\"}},\n\t\tBody: ftl.Some(GetResponse{\n\t\t\tMessage: fmt.Sprintf(\"UserID: %s, PostID: %s, Tag: %s\", req.pathParameters.UserID, req.pathParameters.PostID, req.Body.Tag.Default(\"none\")),\n\t\t}),\n\t}, nil\n}\n```\n\nThe rules for how each element is mapped are slightly different, as they have a different structure:\n\n- The body is mapped directly to the body of the request, generally as a JSON object. Scalars are also supported, as well as []byte to get the raw body. If they type is `any` then it will be assumed to be JSON and mapped to the appropriate types based on the JSON structure.\n- The path parameters can be mapped directly to an object with field names corresponding to the name of the path parameter. If there is only a single path parameter it can be injected directly as a scalar. They can also be injected as a `map[string]string`.\n- The path parameters can also be mapped directly to an object with field names corresponding to the name of the path parameter. They can also be injected directly as a `map[string]string`, or `map[string][]string` for multiple values.\n\n### Optional fields\n\nOptional fields are represented by the `ftl.Option` type. The `Option` type is a wrapper around the actual type and can be `Some` or `None`. In the example above, the `Tag` field is optional.\n\n```sh\ncurl -i http://localhost:8891/users/123/posts/456\n```\n\nBecause the `tag` query parameter is not provided, the response will be:\n\n```json\n{\n  \"msg\": \"UserID: 123, PostID: 456, Tag: none\"\n}\n```\n\n### Casing\n\nField names use lowerCamelCase by default. You can override this by using the `json` tag.\n\n### SumTypes\n\nGiven the following request verb:\n\n```go\n//ftl:enum export\ntype SumType interface {\n\ttag()\n}\n\ntype A string\n\nfunc (A) tag() {}\n\ntype B []string\n\nfunc (B) tag() {}\n\n//ftl:ingress http POST /typeenum\nfunc TypeEnum(ctx context.Context, req builtin.HttpRequest[SumType, ftl.Unit, ftl.Unit]) (builtin.HttpResponse[SumType, string], error) {\n\treturn builtin.HttpResponse[SumType, string]{Body: ftl.Some(req.Body)}, nil\n}\n```\n\nThe following curl request will map the `SumType` name and value to the `req.Body`:\n\n```sh\ncurl -X POST \"http://localhost:8891/typeenum\" \\\n     -H \"Content-Type: application/json\" \\\n     --data '{\"name\": \"A\", \"value\": \"sample\"}'\n```\n\nThe response will be:\n\n```json\n{\n  \"name\": \"A\",\n  \"value\": \"sample\"\n}\n```\n\n### Encoding query params as JSON\n\nComplex query params can also be encoded as JSON using the `@json` query parameter. For example:\n\n> `{\"tag\":\"ftl\"}` url-encoded is `%7B%22tag%22%3A%22ftl%22%7D`\n\n```bash\ncurl -i http://localhost:8891/users/123/posts/456?@json=%7B%22tag%22%3A%22ftl%22%7D\n```\n\n\n",
			"java": "\n# HTTP Ingress\n\nHTTP ingress is different depending on the language you are using. The following sections describe how to define HTTP ingress in each language.\n\n\n\nJVM Languages use the `JAX-RS` annotations to define HTTP endpoints. The following example shows how to define an HTTP endpoint in Java. As the underling implementation is based on [Quarkus](https://quarkus.io)\nit is also possible to use the [Quarkus extensions to the JAX-RS annotations](https://quarkus.io/guides/rest#accessing-request-parameters).\n\nIn general the difference between the Quarkus annotation and the standard JAX-RS ones is that the Quarkus parameters infer the parameter name from the method parameter name, while the JAX-RS ones require the parameter name to be explicitly defined.\n\n```java\nimport java.util.List;\n\nimport jakarta.ws.rs.DELETE;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.PUT;\nimport jakarta.ws.rs.Path;\n\nimport jakarta.ws.rs.QueryParam; // JAX-RS annotation to get the query parameter\nimport org.jboss.resteasy.reactive.RestPath; // Quarkus annotation to get the path parameter\n\n@Path(\"/\")\npublic class TestHTTP {\n\n    @GET\n    @Path(\"/http/users/{userId}/posts\")\n    public String get(@RestPath String userId, @QueryParam(\"postId\") String post) {\n        //...\n    }\n\n}\n```\n\nUnder the hood these HTTP invocations are being mapped to verbs that take a `builtin.HttpRequest` and return a `builtin.HttpResponse`. This is not exposed directly to the user, but is instead mapped directly to `JAX-RS` annotations.\n\n\n",
			"kotlin": "\n# HTTP Ingress\n\nHTTP ingress is different depending on the language you are using. The following sections describe how to define HTTP ingress in each language.\n\n\n\nKotlin uses the `JAX-RS` annotations to define HTTP endpoints. The following example shows how to define an HTTP endpoint in Kotlin. As the underling implementation is based on [Quarkus](https://quarkus.io)\nit is also possible to use the [Quarkus extensions to the JAX-RS annotations](https://quarkus.io/guides/rest#accessing-request-parameters).\n\nIn general the difference between the Quarkus annotation and the standard JAX-RS ones is that the Quarkus parameters infer the parameter name from the method parameter name, while the JAX-RS ones require the parameter name to be explicitly defined.\n\n```kotlin\nimport java.util.List\n\nimport jakarta.ws.rs.DELETE\nimport jakarta.ws.rs.GET\nimport jakarta.ws.rs.POST\nimport jakarta.ws.rs.PUT\nimport jakarta.ws.rs.Path\n\nimport jakarta.ws.rs.QueryParam // JAX-RS annotation to get the query parameter\nimport org.jboss.resteasy.reactive.RestPath // Quarkus annotation to get the path parameter\n\n@Path(\"/\")\npublic class TestHTTP {\n\n    @GET\n    @Path(\"/http/users/{userId}/posts\")\n    fun get(@RestPath userId: String,@QueryParam(\"postId\") post: String) : String {\n        //...\n    }\n\n}\n```\n\nUnder the hood these HTTP invocations are being mapped to verbs that take a `builtin.HttpRequest` and return a `builtin.HttpResponse`. This is not exposed directly to the user, but is instead mapped directly to `JAX-RS` annotations.\n\n\n",
			"schema": "\nIn the FTL schema, HTTP ingress is represented by the `+ingress` annotation on verbs:\n\n```schema\nmodule example {\n  data GetRequestPathParams {\n    userId String\n  }\n  \n  data GetRequestQueryParams {\n    postId String\n  }\n  \n  data GetResponse {\n    message String\n  }\n  \n  data ErrorResponse {\n    error String\n  }\n  \n  // HTTP GET endpoint\n  verb get(builtin.HttpRequest<Unit, example.GetRequestPathParams, example.GetRequestQueryParams>) builtin.HttpResponse<example.GetResponse, example.ErrorResponse>\n    +ingress http GET /http/users/{userId}/posts\n}\n```\n\nThe `+ingress` annotation specifies:\n1. The ingress type (http)\n2. The HTTP method (GET, PUT, POST, DELETE, etc.)\n3. The path pattern with path parameters in curly braces\n\nHTTP ingress verbs always use the `builtin.HttpRequest` and `builtin.HttpResponse` types, which provide the necessary structure for HTTP requests and responses.\n\n\n",
	},
	"@Path": {
			"go": "\n# HTTP Ingress\n\nHTTP ingress is different depending on the language you are using. The following sections describe how to define HTTP ingress in each language.\n\n\n\nVerbs annotated with `ftl:ingress` will be exposed via HTTP (`http` is the default ingress type). These endpoints will then be available on one of our default `ingress` ports (local development defaults to `http://localhost:8891`).\n\nThe following will be available at `http://localhost:8891/http/users/123/posts?postId=456`.\n\n```go\ntype GetRequestPathParams struct {\n\tUserID string `json:\"userId\"`\n}\n\ntype GetRequestQueryParams struct {\n\tPostID string `json:\"postId\"`\n}\n\ntype GetResponse struct {\n\tMessage string `json:\"msg\"`\n}\n\n//ftl:ingress GET /http/users/{userId}/posts\nfunc Get(ctx context.Context, req builtin.HttpRequest[ftl.Unit, GetRequestPathParams, GetRequestQueryParams]) (builtin.HttpResponse[GetResponse, ErrorResponse], error) {\n  // ...\n}\n```\n\nBecause the example above only has a single path parameter it can be simplified by just using a scalar such as `string` or `int64` as the path parameter type:\n\n```go\n//ftl:ingress GET /http/users/{userId}/posts\nfunc Get(ctx context.Context, req builtin.HttpRequest[ftl.Unit, int64, GetRequestQueryParams]) (builtin.HttpResponse[GetResponse, ErrorResponse], error) {\n  // ...\n}\n```\n\n:::info\n\nThe `req` and `resp` types of HTTP `ingress` [verbs](../reference/verbs) must be `builtin.HttpRequest` and `builtin.HttpResponse` respectively. These types provide the necessary fields for HTTP `ingress` (`headers`, `statusCode`, etc.)\n\n:::\n\nKey points:\n\n- `ingress` verbs will be automatically exported by default.\n\n### Field mapping\n\nThe `HttpRequest` request object takes 3 type parameters, the body, the path parameters and the query parameters.\n\nGiven the following request verb:\n\n```go\ntype PostBody struct{\n\tTitle string               `json:\"title\"`\n\tContent string             `json:\"content\"`\n\tTag ftl.Option[string]     `json:\"tag\"`\n}\ntype PostPathParams struct {\n\tUserID string             `json:\"userId\"`\n\tPostID string             `json:\"postId\"`\n}\n\ntype PostQueryParams struct {\n\tPublish boolean `json:\"publish\"`\n}\n\n//ftl:ingress http PUT /users/{userId}/posts/{postId}\nfunc Get(ctx context.Context, req builtin.HttpRequest[PostBody, PostPathParams, PostQueryParams]) (builtin.HttpResponse[GetResponse, string], error) {\n\treturn builtin.HttpResponse[GetResponse, string]{\n\t\tHeaders: map[string][]string{\"Get\": {\"Header from FTL\"}},\n\t\tBody: ftl.Some(GetResponse{\n\t\t\tMessage: fmt.Sprintf(\"UserID: %s, PostID: %s, Tag: %s\", req.pathParameters.UserID, req.pathParameters.PostID, req.Body.Tag.Default(\"none\")),\n\t\t}),\n\t}, nil\n}\n```\n\nThe rules for how each element is mapped are slightly different, as they have a different structure:\n\n- The body is mapped directly to the body of the request, generally as a JSON object. Scalars are also supported, as well as []byte to get the raw body. If they type is `any` then it will be assumed to be JSON and mapped to the appropriate types based on the JSON structure.\n- The path parameters can be mapped directly to an object with field names corresponding to the name of the path parameter. If there is only a single path parameter it can be injected directly as a scalar. They can also be injected as a `map[string]string`.\n- The path parameters can also be mapped directly to an object with field names corresponding to the name of the path parameter. They can also be injected directly as a `map[string]string`, or `map[string][]string` for multiple values.\n\n### Optional fields\n\nOptional fields are represented by the `ftl.Option` type. The `Option` type is a wrapper around the actual type and can be `Some` or `None`. In the example above, the `Tag` field is optional.\n\n```sh\ncurl -i http://localhost:8891/users/123/posts/456\n```\n\nBecause the `tag` query parameter is not provided, the response will be:\n\n```json\n{\n  \"msg\": \"UserID: 123, PostID: 456, Tag: none\"\n}\n```\n\n### Casing\n\nField names use lowerCamelCase by default. You can override this by using the `json` tag.\n\n### SumTypes\n\nGiven the following request verb:\n\n```go\n//ftl:enum export\ntype SumType interface {\n\ttag()\n}\n\ntype A string\n\nfunc (A) tag() {}\n\ntype B []string\n\nfunc (B) tag() {}\n\n//ftl:ingress http POST /typeenum\nfunc TypeEnum(ctx context.Context, req builtin.HttpRequest[SumType, ftl.Unit, ftl.Unit]) (builtin.HttpResponse[SumType, string], error) {\n\treturn builtin.HttpResponse[SumType, string]{Body: ftl.Some(req.Body)}, nil\n}\n```\n\nThe following curl request will map the `SumType` name and value to the `req.Body`:\n\n```sh\ncurl -X POST \"http://localhost:8891/typeenum\" \\\n     -H \"Content-Type: application/json\" \\\n     --data '{\"name\": \"A\", \"value\": \"sample\"}'\n```\n\nThe response will be:\n\n```json\n{\n  \"name\": \"A\",\n  \"value\": \"sample\"\n}\n```\n\n### Encoding query params as JSON\n\nComplex query params can also be encoded as JSON using the `@json` query parameter. For example:\n\n> `{\"tag\":\"ftl\"}` url-encoded is `%7B%22tag%22%3A%22ftl%22%7D`\n\n```bash\ncurl -i http://localhost:8891/users/123/posts/456?@json=%7B%22tag%22%3A%22ftl%22%7D\n```\n\n\n",
			"java": "\n# HTTP Ingress\n\nHTTP ingress is different depending on the language you are using. The following sections describe how to define HTTP ingress in each language.\n\n\n\nJVM Languages use the `JAX-RS` annotations to define HTTP endpoints. The following example shows how to define an HTTP endpoint in Java. As the underling implementation is based on [Quarkus](https://quarkus.io)\nit is also possible to use the [Quarkus extensions to the JAX-RS annotations](https://quarkus.io/guides/rest#accessing-request-parameters).\n\nIn general the difference between the Quarkus annotation and the standard JAX-RS ones is that the Quarkus parameters infer the parameter name from the method parameter name, while the JAX-RS ones require the parameter name to be explicitly defined.\n\n```java\nimport java.util.List;\n\nimport jakarta.ws.rs.DELETE;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.PUT;\nimport jakarta.ws.rs.Path;\n\nimport jakarta.ws.rs.QueryParam; // JAX-RS annotation to get the query parameter\nimport org.jboss.resteasy.reactive.RestPath; // Quarkus annotation to get the path parameter\n\n@Path(\"/\")\npublic class TestHTTP {\n\n    @GET\n    @Path(\"/http/users/{userId}/posts\")\n    public String get(@RestPath String userId, @QueryParam(\"postId\") String post) {\n        //...\n    }\n\n}\n```\n\nUnder the hood these HTTP invocations are being mapped to verbs that take a `builtin.HttpRequest` and return a `builtin.HttpResponse`. This is not exposed directly to the user, but is instead mapped directly to `JAX-RS` annotations.\n\n\n",
			"kotlin": "\n# HTTP Ingress\n\nHTTP ingress is different depending on the language you are using. The following sections describe how to define HTTP ingress in each language.\n\n\n\nKotlin uses the `JAX-RS` annotations to define HTTP endpoints. The following example shows how to define an HTTP endpoint in Kotlin. As the underling implementation is based on [Quarkus](https://quarkus.io)\nit is also possible to use the [Quarkus extensions to the JAX-RS annotations](https://quarkus.io/guides/rest#accessing-request-parameters).\n\nIn general the difference between the Quarkus annotation and the standard JAX-RS ones is that the Quarkus parameters infer the parameter name from the method parameter name, while the JAX-RS ones require the parameter name to be explicitly defined.\n\n```kotlin\nimport java.util.List\n\nimport jakarta.ws.rs.DELETE\nimport jakarta.ws.rs.GET\nimport jakarta.ws.rs.POST\nimport jakarta.ws.rs.PUT\nimport jakarta.ws.rs.Path\n\nimport jakarta.ws.rs.QueryParam // JAX-RS annotation to get the query parameter\nimport org.jboss.resteasy.reactive.RestPath // Quarkus annotation to get the path parameter\n\n@Path(\"/\")\npublic class TestHTTP {\n\n    @GET\n    @Path(\"/http/users/{userId}/posts\")\n    fun get(@RestPath userId: String,@QueryParam(\"postId\") post: String) : String {\n        //...\n    }\n\n}\n```\n\nUnder the hood these HTTP invocations are being mapped to verbs that take a `builtin.HttpRequest` and return a `builtin.HttpResponse`. This is not exposed directly to the user, but is instead mapped directly to `JAX-RS` annotations.\n\n\n",
			"schema": "\nIn the FTL schema, HTTP ingress is represented by the `+ingress` annotation on verbs:\n\n```schema\nmodule example {\n  data GetRequestPathParams {\n    userId String\n  }\n  \n  data GetRequestQueryParams {\n    postId String\n  }\n  \n  data GetResponse {\n    message String\n  }\n  \n  data ErrorResponse {\n    error String\n  }\n  \n  // HTTP GET endpoint\n  verb get(builtin.HttpRequest<Unit, example.GetRequestPathParams, example.GetRequestQueryParams>) builtin.HttpResponse<example.GetResponse, example.ErrorResponse>\n    +ingress http GET /http/users/{userId}/posts\n}\n```\n\nThe `+ingress` annotation specifies:\n1. The ingress type (http)\n2. The HTTP method (GET, PUT, POST, DELETE, etc.)\n3. The path pattern with path parameters in curly braces\n\nHTTP ingress verbs always use the `builtin.HttpRequest` and `builtin.HttpResponse` types, which provide the necessary structure for HTTP requests and responses.\n\n\n",
	},
	"@QueryParam": {
			"go": "\n# HTTP Ingress\n\nHTTP ingress is different depending on the language you are using. The following sections describe how to define HTTP ingress in each language.\n\n\n\nVerbs annotated with `ftl:ingress` will be exposed via HTTP (`http` is the default ingress type). These endpoints will then be available on one of our default `ingress` ports (local development defaults to `http://localhost:8891`).\n\nThe following will be available at `http://localhost:8891/http/users/123/posts?postId=456`.\n\n```go\ntype GetRequestPathParams struct {\n\tUserID string `json:\"userId\"`\n}\n\ntype GetRequestQueryParams struct {\n\tPostID string `json:\"postId\"`\n}\n\ntype GetResponse struct {\n\tMessage string `json:\"msg\"`\n}\n\n//ftl:ingress GET /http/users/{userId}/posts\nfunc Get(ctx context.Context, req builtin.HttpRequest[ftl.Unit, GetRequestPathParams, GetRequestQueryParams]) (builtin.HttpResponse[GetResponse, ErrorResponse], error) {\n  // ...\n}\n```\n\nBecause the example above only has a single path parameter it can be simplified by just using a scalar such as `string` or `int64` as the path parameter type:\n\n```go\n//ftl:ingress GET /http/users/{userId}/posts\nfunc Get(ctx context.Context, req builtin.HttpRequest[ftl.Unit, int64, GetRequestQueryParams]) (builtin.HttpResponse[GetResponse, ErrorResponse], error) {\n  // ...\n}\n```\n\n:::info\n\nThe `req` and `resp` types of HTTP `ingress` [verbs](../reference/verbs) must be `builtin.HttpRequest` and `builtin.HttpResponse` respectively. These types provide the necessary fields for HTTP `ingress` (`headers`, `statusCode`, etc.)\n\n:::\n\nKey points:\n\n- `ingress` verbs will be automatically exported by default.\n\n### Field mapping\n\nThe `HttpRequest` request object takes 3 type parameters, the body, the path parameters and the query parameters.\n\nGiven the following request verb:\n\n```go\ntype PostBody struct{\n\tTitle string               `json:\"title\"`\n\tContent string             `json:\"content\"`\n\tTag ftl.Option[string]     `json:\"tag\"`\n}\ntype PostPathParams struct {\n\tUserID string             `json:\"userId\"`\n\tPostID string             `json:\"postId\"`\n}\n\ntype PostQueryParams struct {\n\tPublish boolean `json:\"publish\"`\n}\n\n//ftl:ingress http PUT /users/{userId}/posts/{postId}\nfunc Get(ctx context.Context, req builtin.HttpRequest[PostBody, PostPathParams, PostQueryParams]) (builtin.HttpResponse[GetResponse, string], error) {\n\treturn builtin.HttpResponse[GetResponse, string]{\n\t\tHeaders: map[string][]string{\"Get\": {\"Header from FTL\"}},\n\t\tBody: ftl.Some(GetResponse{\n\t\t\tMessage: fmt.Sprintf(\"UserID: %s, PostID: %s, Tag: %s\", req.pathParameters.UserID, req.pathParameters.PostID, req.Body.Tag.Default(\"none\")),\n\t\t}),\n\t}, nil\n}\n```\n\nThe rules for how each element is mapped are slightly different, as they have a different structure:\n\n- The body is mapped directly to the body of the request, generally as a JSON object. Scalars are also supported, as well as []byte to get the raw body. If they type is `any` then it will be assumed to be JSON and mapped to the appropriate types based on the JSON structure.\n- The path parameters can be mapped directly to an object with field names corresponding to the name of the path parameter. If there is only a single path parameter it can be injected directly as a scalar. They can also be injected as a `map[string]string`.\n- The path parameters can also be mapped directly to an object with field names corresponding to the name of the path parameter. They can also be injected directly as a `map[string]string`, or `map[string][]string` for multiple values.\n\n### Optional fields\n\nOptional fields are represented by the `ftl.Option` type. The `Option` type is a wrapper around the actual type and can be `Some` or `None`. In the example above, the `Tag` field is optional.\n\n```sh\ncurl -i http://localhost:8891/users/123/posts/456\n```\n\nBecause the `tag` query parameter is not provided, the response will be:\n\n```json\n{\n  \"msg\": \"UserID: 123, PostID: 456, Tag: none\"\n}\n```\n\n### Casing\n\nField names use lowerCamelCase by default. You can override this by using the `json` tag.\n\n### SumTypes\n\nGiven the following request verb:\n\n```go\n//ftl:enum export\ntype SumType interface {\n\ttag()\n}\n\ntype A string\n\nfunc (A) tag() {}\n\ntype B []string\n\nfunc (B) tag() {}\n\n//ftl:ingress http POST /typeenum\nfunc TypeEnum(ctx context.Context, req builtin.HttpRequest[SumType, ftl.Unit, ftl.Unit]) (builtin.HttpResponse[SumType, string], error) {\n\treturn builtin.HttpResponse[SumType, string]{Body: ftl.Some(req.Body)}, nil\n}\n```\n\nThe following curl request will map the `SumType` name and value to the `req.Body`:\n\n```sh\ncurl -X POST \"http://localhost:8891/typeenum\" \\\n     -H \"Content-Type: application/json\" \\\n     --data '{\"name\": \"A\", \"value\": \"sample\"}'\n```\n\nThe response will be:\n\n```json\n{\n  \"name\": \"A\",\n  \"value\": \"sample\"\n}\n```\n\n### Encoding query params as JSON\n\nComplex query params can also be encoded as JSON using the `@json` query parameter. For example:\n\n> `{\"tag\":\"ftl\"}` url-encoded is `%7B%22tag%22%3A%22ftl%22%7D`\n\n```bash\ncurl -i http://localhost:8891/users/123/posts/456?@json=%7B%22tag%22%3A%22ftl%22%7D\n```\n\n\n",
			"java": "\n# HTTP Ingress\n\nHTTP ingress is different depending on the language you are using. The following sections describe how to define HTTP ingress in each language.\n\n\n\nJVM Languages use the `JAX-RS` annotations to define HTTP endpoints. The following example shows how to define an HTTP endpoint in Java. As the underling implementation is based on [Quarkus](https://quarkus.io)\nit is also possible to use the [Quarkus extensions to the JAX-RS annotations](https://quarkus.io/guides/rest#accessing-request-parameters).\n\nIn general the difference between the Quarkus annotation and the standard JAX-RS ones is that the Quarkus parameters infer the parameter name from the method parameter name, while the JAX-RS ones require the parameter name to be explicitly defined.\n\n```java\nimport java.util.List;\n\nimport jakarta.ws.rs.DELETE;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.PUT;\nimport jakarta.ws.rs.Path;\n\nimport jakarta.ws.rs.QueryParam; // JAX-RS annotation to get the query parameter\nimport org.jboss.resteasy.reactive.RestPath; // Quarkus annotation to get the path parameter\n\n@Path(\"/\")\npublic class TestHTTP {\n\n    @GET\n    @Path(\"/http/users/{userId}/posts\")\n    public String get(@RestPath String userId, @QueryParam(\"postId\") String post) {\n        //...\n    }\n\n}\n```\n\nUnder the hood these HTTP invocations are being mapped to verbs that take a `builtin.HttpRequest` and return a `builtin.HttpResponse`. This is not exposed directly to the user, but is instead mapped directly to `JAX-RS` annotations.\n\n\n",
			"kotlin": "\n# HTTP Ingress\n\nHTTP ingress is different depending on the language you are using. The following sections describe how to define HTTP ingress in each language.\n\n\n\nKotlin uses the `JAX-RS` annotations to define HTTP endpoints. The following example shows how to define an HTTP endpoint in Kotlin. As the underling implementation is based on [Quarkus](https://quarkus.io)\nit is also possible to use the [Quarkus extensions to the JAX-RS annotations](https://quarkus.io/guides/rest#accessing-request-parameters).\n\nIn general the difference between the Quarkus annotation and the standard JAX-RS ones is that the Quarkus parameters infer the parameter name from the method parameter name, while the JAX-RS ones require the parameter name to be explicitly defined.\n\n```kotlin\nimport java.util.List\n\nimport jakarta.ws.rs.DELETE\nimport jakarta.ws.rs.GET\nimport jakarta.ws.rs.POST\nimport jakarta.ws.rs.PUT\nimport jakarta.ws.rs.Path\n\nimport jakarta.ws.rs.QueryParam // JAX-RS annotation to get the query parameter\nimport org.jboss.resteasy.reactive.RestPath // Quarkus annotation to get the path parameter\n\n@Path(\"/\")\npublic class TestHTTP {\n\n    @GET\n    @Path(\"/http/users/{userId}/posts\")\n    fun get(@RestPath userId: String,@QueryParam(\"postId\") post: String) : String {\n        //...\n    }\n\n}\n```\n\nUnder the hood these HTTP invocations are being mapped to verbs that take a `builtin.HttpRequest` and return a `builtin.HttpResponse`. This is not exposed directly to the user, but is instead mapped directly to `JAX-RS` annotations.\n\n\n",
			"schema": "\nIn the FTL schema, HTTP ingress is represented by the `+ingress` annotation on verbs:\n\n```schema\nmodule example {\n  data GetRequestPathParams {\n    userId String\n  }\n  \n  data GetRequestQueryParams {\n    postId String\n  }\n  \n  data GetResponse {\n    message String\n  }\n  \n  data ErrorResponse {\n    error String\n  }\n  \n  // HTTP GET endpoint\n  verb get(builtin.HttpRequest<Unit, example.GetRequestPathParams, example.GetRequestQueryParams>) builtin.HttpResponse<example.GetResponse, example.ErrorResponse>\n    +ingress http GET /http/users/{userId}/posts\n}\n```\n\nThe `+ingress` annotation specifies:\n1. The ingress type (http)\n2. The HTTP method (GET, PUT, POST, DELETE, etc.)\n3. The path pattern with path parameters in curly braces\n\nHTTP ingress verbs always use the `builtin.HttpRequest` and `builtin.HttpResponse` types, which provide the necessary structure for HTTP requests and responses.\n\n\n",
	},
	"@RestPath": {
			"go": "\n# HTTP Ingress\n\nHTTP ingress is different depending on the language you are using. The following sections describe how to define HTTP ingress in each language.\n\n\n\nVerbs annotated with `ftl:ingress` will be exposed via HTTP (`http` is the default ingress type). These endpoints will then be available on one of our default `ingress` ports (local development defaults to `http://localhost:8891`).\n\nThe following will be available at `http://localhost:8891/http/users/123/posts?postId=456`.\n\n```go\ntype GetRequestPathParams struct {\n\tUserID string `json:\"userId\"`\n}\n\ntype GetRequestQueryParams struct {\n\tPostID string `json:\"postId\"`\n}\n\ntype GetResponse struct {\n\tMessage string `json:\"msg\"`\n}\n\n//ftl:ingress GET /http/users/{userId}/posts\nfunc Get(ctx context.Context, req builtin.HttpRequest[ftl.Unit, GetRequestPathParams, GetRequestQueryParams]) (builtin.HttpResponse[GetResponse, ErrorResponse], error) {\n  // ...\n}\n```\n\nBecause the example above only has a single path parameter it can be simplified by just using a scalar such as `string` or `int64` as the path parameter type:\n\n```go\n//ftl:ingress GET /http/users/{userId}/posts\nfunc Get(ctx context.Context, req builtin.HttpRequest[ftl.Unit, int64, GetRequestQueryParams]) (builtin.HttpResponse[GetResponse, ErrorResponse], error) {\n  // ...\n}\n```\n\n:::info\n\nThe `req` and `resp` types of HTTP `ingress` [verbs](../reference/verbs) must be `builtin.HttpRequest` and `builtin.HttpResponse` respectively. These types provide the necessary fields for HTTP `ingress` (`headers`, `statusCode`, etc.)\n\n:::\n\nKey points:\n\n- `ingress` verbs will be automatically exported by default.\n\n### Field mapping\n\nThe `HttpRequest` request object takes 3 type parameters, the body, the path parameters and the query parameters.\n\nGiven the following request verb:\n\n```go\ntype PostBody struct{\n\tTitle string               `json:\"title\"`\n\tContent string             `json:\"content\"`\n\tTag ftl.Option[string]     `json:\"tag\"`\n}\ntype PostPathParams struct {\n\tUserID string             `json:\"userId\"`\n\tPostID string             `json:\"postId\"`\n}\n\ntype PostQueryParams struct {\n\tPublish boolean `json:\"publish\"`\n}\n\n//ftl:ingress http PUT /users/{userId}/posts/{postId}\nfunc Get(ctx context.Context, req builtin.HttpRequest[PostBody, PostPathParams, PostQueryParams]) (builtin.HttpResponse[GetResponse, string], error) {\n\treturn builtin.HttpResponse[GetResponse, string]{\n\t\tHeaders: map[string][]string{\"Get\": {\"Header from FTL\"}},\n\t\tBody: ftl.Some(GetResponse{\n\t\t\tMessage: fmt.Sprintf(\"UserID: %s, PostID: %s, Tag: %s\", req.pathParameters.UserID, req.pathParameters.PostID, req.Body.Tag.Default(\"none\")),\n\t\t}),\n\t}, nil\n}\n```\n\nThe rules for how each element is mapped are slightly different, as they have a different structure:\n\n- The body is mapped directly to the body of the request, generally as a JSON object. Scalars are also supported, as well as []byte to get the raw body. If they type is `any` then it will be assumed to be JSON and mapped to the appropriate types based on the JSON structure.\n- The path parameters can be mapped directly to an object with field names corresponding to the name of the path parameter. If there is only a single path parameter it can be injected directly as a scalar. They can also be injected as a `map[string]string`.\n- The path parameters can also be mapped directly to an object with field names corresponding to the name of the path parameter. They can also be injected directly as a `map[string]string`, or `map[string][]string` for multiple values.\n\n### Optional fields\n\nOptional fields are represented by the `ftl.Option` type. The `Option` type is a wrapper around the actual type and can be `Some` or `None`. In the example above, the `Tag` field is optional.\n\n```sh\ncurl -i http://localhost:8891/users/123/posts/456\n```\n\nBecause the `tag` query parameter is not provided, the response will be:\n\n```json\n{\n  \"msg\": \"UserID: 123, PostID: 456, Tag: none\"\n}\n```\n\n### Casing\n\nField names use lowerCamelCase by default. You can override this by using the `json` tag.\n\n### SumTypes\n\nGiven the following request verb:\n\n```go\n//ftl:enum export\ntype SumType interface {\n\ttag()\n}\n\ntype A string\n\nfunc (A) tag() {}\n\ntype B []string\n\nfunc (B) tag() {}\n\n//ftl:ingress http POST /typeenum\nfunc TypeEnum(ctx context.Context, req builtin.HttpRequest[SumType, ftl.Unit, ftl.Unit]) (builtin.HttpResponse[SumType, string], error) {\n\treturn builtin.HttpResponse[SumType, string]{Body: ftl.Some(req.Body)}, nil\n}\n```\n\nThe following curl request will map the `SumType` name and value to the `req.Body`:\n\n```sh\ncurl -X POST \"http://localhost:8891/typeenum\" \\\n     -H \"Content-Type: application/json\" \\\n     --data '{\"name\": \"A\", \"value\": \"sample\"}'\n```\n\nThe response will be:\n\n```json\n{\n  \"name\": \"A\",\n  \"value\": \"sample\"\n}\n```\n\n### Encoding query params as JSON\n\nComplex query params can also be encoded as JSON using the `@json` query parameter. For example:\n\n> `{\"tag\":\"ftl\"}` url-encoded is `%7B%22tag%22%3A%22ftl%22%7D`\n\n```bash\ncurl -i http://localhost:8891/users/123/posts/456?@json=%7B%22tag%22%3A%22ftl%22%7D\n```\n\n\n",
			"java": "\n# HTTP Ingress\n\nHTTP ingress is different depending on the language you are using. The following sections describe how to define HTTP ingress in each language.\n\n\n\nJVM Languages use the `JAX-RS` annotations to define HTTP endpoints. The following example shows how to define an HTTP endpoint in Java. As the underling implementation is based on [Quarkus](https://quarkus.io)\nit is also possible to use the [Quarkus extensions to the JAX-RS annotations](https://quarkus.io/guides/rest#accessing-request-parameters).\n\nIn general the difference between the Quarkus annotation and the standard JAX-RS ones is that the Quarkus parameters infer the parameter name from the method parameter name, while the JAX-RS ones require the parameter name to be explicitly defined.\n\n```java\nimport java.util.List;\n\nimport jakarta.ws.rs.DELETE;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.PUT;\nimport jakarta.ws.rs.Path;\n\nimport jakarta.ws.rs.QueryParam; // JAX-RS annotation to get the query parameter\nimport org.jboss.resteasy.reactive.RestPath; // Quarkus annotation to get the path parameter\n\n@Path(\"/\")\npublic class TestHTTP {\n\n    @GET\n    @Path(\"/http/users/{userId}/posts\")\n    public String get(@RestPath String userId, @QueryParam(\"postId\") String post) {\n        //...\n    }\n\n}\n```\n\nUnder the hood these HTTP invocations are being mapped to verbs that take a `builtin.HttpRequest` and return a `builtin.HttpResponse`. This is not exposed directly to the user, but is instead mapped directly to `JAX-RS` annotations.\n\n\n",
			"kotlin": "\n# HTTP Ingress\n\nHTTP ingress is different depending on the language you are using. The following sections describe how to define HTTP ingress in each language.\n\n\n\nKotlin uses the `JAX-RS` annotations to define HTTP endpoints. The following example shows how to define an HTTP endpoint in Kotlin. As the underling implementation is based on [Quarkus](https://quarkus.io)\nit is also possible to use the [Quarkus extensions to the JAX-RS annotations](https://quarkus.io/guides/rest#accessing-request-parameters).\n\nIn general the difference between the Quarkus annotation and the standard JAX-RS ones is that the Quarkus parameters infer the parameter name from the method parameter name, while the JAX-RS ones require the parameter name to be explicitly defined.\n\n```kotlin\nimport java.util.List\n\nimport jakarta.ws.rs.DELETE\nimport jakarta.ws.rs.GET\nimport jakarta.ws.rs.POST\nimport jakarta.ws.rs.PUT\nimport jakarta.ws.rs.Path\n\nimport jakarta.ws.rs.QueryParam // JAX-RS annotation to get the query parameter\nimport org.jboss.resteasy.reactive.RestPath // Quarkus annotation to get the path parameter\n\n@Path(\"/\")\npublic class TestHTTP {\n\n    @GET\n    @Path(\"/http/users/{userId}/posts\")\n    fun get(@RestPath userId: String,@QueryParam(\"postId\") post: String) : String {\n        //...\n    }\n\n}\n```\n\nUnder the hood these HTTP invocations are being mapped to verbs that take a `builtin.HttpRequest` and return a `builtin.HttpResponse`. This is not exposed directly to the user, but is instead mapped directly to `JAX-RS` annotations.\n\n\n",
			"schema": "\nIn the FTL schema, HTTP ingress is represented by the `+ingress` annotation on verbs:\n\n```schema\nmodule example {\n  data GetRequestPathParams {\n    userId String\n  }\n  \n  data GetRequestQueryParams {\n    postId String\n  }\n  \n  data GetResponse {\n    message String\n  }\n  \n  data ErrorResponse {\n    error String\n  }\n  \n  // HTTP GET endpoint\n  verb get(builtin.HttpRequest<Unit, example.GetRequestPathParams, example.GetRequestQueryParams>) builtin.HttpResponse<example.GetResponse, example.ErrorResponse>\n    +ingress http GET /http/users/{userId}/posts\n}\n```\n\nThe `+ingress` annotation specifies:\n1. The ingress type (http)\n2. The HTTP method (GET, PUT, POST, DELETE, etc.)\n3. The path pattern with path parameters in curly braces\n\nHTTP ingress verbs always use the `builtin.HttpRequest` and `builtin.HttpResponse` types, which provide the necessary structure for HTTP requests and responses.\n\n\n",
	},
	"@Retry": {
			"go": "\n# Retries\n\nSome FTL features allow specifying a retry policy via a language-specific directive. Retries back off exponentially until the maximum is reached.\n\n\n\nThe directive has the following syntax:\n\n```go\n//ftl:retry [<attempts=10>] <min-backoff> [<max-backoff=1hr>] [catch <catchVerb>]\n```\n\nFor example, the following function will retry up to 10 times, with a delay of 5s, 10s, 20s, 40s, 60s, 60s, etc.\n\n```go\n//ftl:retry 10 5s 1m\nfunc Process(ctx context.Context, in Invoice) error {\n  // ...\n}\n```\n\n### PubSub Subscribers\n\nSubscribers can have a retry policy. For example:\n\n```go\n//ftl:retry 5 1s catch recoverPaymentProcessing\nfunc ProcessPayment(ctx context.Context, payment Payment) error {\n...\n}\n```\n\n### Catching\n\nAfter all retries have failed, a catch verb can be used to safely recover.\n\nThese catch verbs have a request type of `builtin.CatchRequest<Req>` and no response type. If a catch verb returns an error, it will be retried until it succeeds so it is important to handle errors carefully.\n\n```go\n//ftl:retry 5 1s catch recoverPaymentProcessing\nfunc ProcessPayment(ctx context.Context, payment Payment) error {\n...\n}\n\n//ftl:verb\nfunc RecoverPaymentProcessing(ctx context.Context, request builtin.CatchRequest[Payment]) error {\n// safely handle final failure of the payment\n}\n```\n\n\n",
			"java": "\n# Retries\n\nSome FTL features allow specifying a retry policy via a language-specific directive. Retries back off exponentially until the maximum is reached.\n\n\n\nThe directive has the following syntax:\n\n```java\n@Retry(attempts = 10, minBackoff = \"5s\", maxBackoff = \"1h\", catchVerb = \"<catchVerb>\", catchModule = \"<catchModule>\")\n```\n\nFor example, the following function will retry up to 10 times, with a delay of 5s, 10s, 20s, 40s, 60s, 60s, etc.\n\n```java\n@Retry(count = 10, minBackoff = \"5s\", maxBackoff = \"1m\")\npublic void process(Invoice in) {\n    // ... \n}\n```\n\n### PubSub Subscribers\n\nSubscribers can have a retry policy. For example:\n\n```java\n@Subscription(topic = \"example\", name = \"exampleSubscription\")\n@SubscriptionOptions(from = FromOffset.LATEST)\n@Retry(count = 5, minBackoff = \"1s\", catchVerb = \"recoverPaymentProcessing\")\npublic void processPayment(Payment payment) {\n    // ... \n}\n```\n\n### Catching\n\nAfter all retries have failed, a catch verb can be used to safely recover.\n\nThese catch verbs have a request type of `CatchRequest<Req>` and no response type. If a catch verb returns an error, it will be retried until it succeeds so it is important to handle errors carefully.\n\n```java\n@Retry(count = 5, minBackoff = \"1s\", catchVerb = \"recoverPaymentProcessing\")\npublic void processPayment(Payment payment) {\n    // ... \n}\n\n@Verb\npublic void recoverPaymentProcessing(CatchRequest<Payment> req) {\n    // safely handle final failure of the payment\n}\n```\n\n\n",
			"kotlin": "\n# Retries\n\nSome FTL features allow specifying a retry policy via a language-specific directive. Retries back off exponentially until the maximum is reached.\n\n\n\nThe directive has the following syntax:\n\n```kotlin\n@Retry(attempts = 10, minBackoff = \"5s\", maxBackoff = \"1h\", catchVerb = \"<catchVerb>\", catchModule = \"<catchModule>\")\n```\n\nFor example, the following function will retry up to 10 times, with a delay of 5s, 10s, 20s, 40s, 60s, 60s, etc.\n\n```kotlin\n@Retry(count = 10, minBackoff = \"5s\", maxBackoff = \"1m\")\nfun process(inv: Invoice) {\n    // ... \n}\n```\n\n### PubSub Subscribers\n\nSubscribers can have a retry policy. For example:\n\n```kotlin\n@Subscription(topic = \"example\", name = \"exampleSubscription\")\n@SubscriptionOptions(from = FromOffset.LATEST)\n@Retry(count = 5, minBackoff = \"1s\", catchVerb = \"recoverPaymentProcessing\")\nfun processPayment(payment: Payment) {\n    // ... \n}\n```\n\n### Catching\n\nAfter all retries have failed, a catch verb can be used to safely recover.\n\nThese catch verbs have a request type of `CatchRequest<Req>` and no response type. If a catch verb returns an error, it will be retried until it succeeds so it is important to handle errors carefully.\n\n```kotlin\n@Retry(count = 5, minBackoff = \"1s\", catchVerb = \"recoverPaymentProcessing\")\nfun processPayment(payment: Payment) {\n    // ... \n}\n\n@Verb\nfun recoverPaymentProcessing(req: CatchRequest<Payment>) {\n    // safely handle final failure of the payment\n}\n```\n\n\n",
			"schema": "\nIn the FTL schema, retry policies are represented by the `+retry` annotation on verbs:\n\n```schema\nmodule example {\n  data Invoice {}\n  \n  verb process(example.Invoice) Unit\n    +retry attempts=10 min=5s max=1m\n  \n  data Payment {}\n  \n  verb processPayment(example.Payment) Unit\n    +subscribe example.payments from=latest\n    +retry attempts=5 min=1s catch=example.recoverPaymentProcessing\n  \n  verb recoverPaymentProcessing(builtin.CatchRequest<example.Payment>) Unit\n}\n```\n\nThe `+retry` annotation specifies the retry policy with parameters for attempts, minimum and maximum backoff, and an optional catch verb.\n\n\n",
	},
	"@SQLDatasource": {
			"go": "\n# Databases\n\nFTL has support for Postgresql and MySQL databases, including support for automatic provisioning and migrations. \n\n\n\nYour database is automatically declared by following a specific directory structure for your SQL files. No additional configuration is needed - just create the directory structure and FTL will handle the rest. See the [Creating a New Database](#creating-a-new-database) section for CLI shortcuts.\n\n\n## Creating a New Database\n\nTo create a new database with the required directory structure, you can use the `ftl postgres new` or `ftl mysql new` command. The format of the command is:\n\n```bash\nftl <engine> new <module>.<datasource>\n```\n\nWhere:\n- `<engine>` is either `mysql` or `postgres`\n- `<module>.<datasource>` is the qualified name of the datasource (module name can be omitted if in a single module directory)\n\nFor example:\n```bash\nftl mysql new mymodule.mydb    # Create a MySQL database named \"mydb\" in module \"mymodule\"\nftl postgres new mydb          # Create a PostgreSQL database named \"mydb\" in the current module\n```\n\nThis command will:\n1. Create the appropriate directory structure\n2. Create an initial migration file in the `schema` directory\n\n## SQL File Structure\n\nIn order to be discoverable by FTL, the SQL files in your project must follow a specific directory structure. FTL supports two database engines, declared via the directory hierarchy as either `mysql` or `postgres`:\n\n\nFor Go projects, SQL files must be located in:\n```\ndb/\n  ├── mysql/           # must be exactly \"mysql\" or \"postgres\"\n  │   └── mydb/        # database name\n  │       ├── schema/  # contains migration files\n  │       └── queries/ # contains query files\n```\n\nThe presence of a `schema` directory under your database name automatically declares the database in FTL.\n\n\n### Schema Directory\n\nThe `schema` directory contains all your database migration `.sql` files. These files are used to create and modify your database schema.\n\n### Queries Directory\n\nThe `queries` directory contains `.sql` files with any SQL queries you would like generated as FTL verbs for use in your module. These queries must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/). FTL will automatically lift these queries into the module schema and provide a type-safe client to execute each query.\n\nFind more information in the [Using Generated Query Clients](#using-generated-query-clients) section below.\n\n## Provisioning\n\nFTL includes support for automatically provisioning databases. The actual backing implementation is\nextensible, and presently we include support for both local development provisioning using docker,\nand cloud formations based provisioning for AWS deployments. When using `ftl dev` a docker container\nwill automatically be spun up for each datasource that has been defined, and FTL will automatically\nhandle configuration. The same applies when deploying to an AWS cluster with cloud formations\nprovisioning setup.\n\n## Migrations\n\nFTL includes support for automatically running migrations on databases. This is provided by [dbmate](https://github.com/amacneil/dbmate). \n\nTo create additional migrations you can use the `ftl postgres new migration` or `ftl mysql new migration` command. The format of the command is `ftl <engine> new migration <module>.<datasource> <migration-name>`.\n\nThe module name can be omitted if the current working directory only contains a single module.\n\nE.g. to create a new migration called `init` for the `testdb` datasource in the `mysql` module you would run `ftl mysql new migration mysql.testdb init`.\n\nWhen the modules are provisioned FTL will automatically run these migrations for you. \n\n## Connecting with your DB\n\nThere are two supported ways to interact with your database in FTL: using the generated database handle to perform raw queries, or using generated query clients.\n\n### Using the Generated Database Handle\n\n\nOnce you've declared a database, FTL automatically generates a database handle that provides direct access to the underlying connection. You can use this to execute raw SQL queries (where `MydbHandle` is the generated handle type for the `mydb` datasource):\n\n```go\n//ftl:verb export\nfunc Query(ctx context.Context, db MydbHandle) ([]string, error) {\n\trows, err := db.QueryContext(ctx, \"SELECT data FROM requests\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer rows.Close()\n\tvar items []string\n\tfor rows.Next() {\n\t\tvar i string\n\t\tif err := rows.Scan(&i); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\titems = append(items, i)\n\t}\n\tif err := rows.Close(); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := rows.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn items, nil\n}\n```\n\n\n### Using Generated Query Clients\n\nFor better type safety and maintainability, FTL can automatically generate type-safe query clients from SQL files in your `queries` directory. Your SQL files must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/) to specify the type of query and its parameters. For example:\n\n```sql\n-- name: GetUser :one\nSELECT id, name, email\nFROM users\nWHERE id = $1;\n\n-- name: ListUsers :many\nSELECT id, name, email\nFROM users\nORDER BY name;\n\n-- name: CreateUser :exec\nINSERT INTO users (name, email)\nVALUES ($1, $2);\n```\n\nThese queries will be automatically converted into FTL verbs with corresponding generated clients that you can inject into your verbs just like any other verb client. For example:\n\n\n```go\n//ftl:verb export\nfunc GetEmail(ctx context.Context, id int, query GetUserClient) (string, error) {\n\tresult, err := query(ctx, id)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn result.Email, nil\n}\n```\n\n\n## Transactions\n\nFTL provides transaction support through verb annotations. When a verb is marked as transactional, FTL will automatically manage the transaction boundaries - beginning the transaction when the verb is called, committing if the verb completes successfully, and rolling back if any errors occur during execution.\n\n\nTo mark a verb as transactional, use the `//ftl:transaction` comment directive:\n\n```go\ntype CreateUserRequest struct {\n    Name  string\n    Email string\n}\n\n//ftl:transaction\nfunc CreateUser(ctx context.Context, req CreateUserRequest, db MydbHandle, createAddress CreateAddressClient) error {\n    // All database operations within this verb will be executed in a single transaction\n    result, err := db.Get(ctx).Exec(\"INSERT INTO users (name, email) VALUES ($1, $2)\", req.Name, req.Email)\n    if err != nil {\n        return err // Transaction will be rolled back\n    }\n    \n    userId, err := result.LastInsertId()\n    if err != nil {\n        return err // Transaction will be rolled back\n    }\n    \n    // createAddress is a generated query client from a SQL file in queries/\n    err = createAddress(ctx, AddressRequest{UserId: userId})\n    if err != nil {\n        return err // Transaction will be rolled back\n    }\n    \n    return nil // Transaction will be committed\n}\n```\n\n\n### Transaction Rules and Limitations\n\nWhen using transactions, FTL enforces the following restrictions:\n\n1. **Database Usage**: Transaction verbs must use at least one database resource (either through a database handle or SQL query clients). FTL infers which database to open the transaction against based on these usages.\n\n2. **Single Database**: FTL only supports transactions against a single database. Two-phase commits across multiple databases are not supported.\n\n3. **No Nesting**: Transaction verbs cannot be nested. This means you cannot inject another transaction verb's client as a resource within a transaction verb.\n\n4. **Module Scope**: Transaction verbs can only call other verbs within the same module. Calls to external verbs from other modules are not allowed within a transaction.\n\n5. **Automatic Management**: Transaction boundaries are automatically managed by FTL:\n   - The transaction begins when the verb is called\n   - The transaction commits if the verb completes successfully\n   - The transaction rolls back if any errors occur during execution\n\n",
			"java": "\n# Databases\n\nFTL has support for Postgresql and MySQL databases, including support for automatic provisioning and migrations. \n\n\n\nYour database is automatically declared by following a specific directory structure for your SQL files. No additional configuration is needed - just create the directory structure and FTL will handle the rest. See the [Creating a New Database](#creating-a-new-database) section for CLI shortcuts.\n\n\n## Creating a New Database\n\nTo create a new database with the required directory structure, you can use the `ftl postgres new` or `ftl mysql new` command. The format of the command is:\n\n```bash\nftl <engine> new <module>.<datasource>\n```\n\nWhere:\n- `<engine>` is either `mysql` or `postgres`\n- `<module>.<datasource>` is the qualified name of the datasource (module name can be omitted if in a single module directory)\n\nFor example:\n```bash\nftl mysql new mymodule.mydb    # Create a MySQL database named \"mydb\" in module \"mymodule\"\nftl postgres new mydb          # Create a PostgreSQL database named \"mydb\" in the current module\n```\n\nThis command will:\n1. Create the appropriate directory structure\n2. Create an initial migration file in the `schema` directory\n\n## SQL File Structure\n\nIn order to be discoverable by FTL, the SQL files in your project must follow a specific directory structure. FTL supports two database engines, declared via the directory hierarchy as either `mysql` or `postgres`:\n\n\nFor Java projects, SQL files must be located in:\n```\nsrc/main/resources/\n  └── db/\n      ├── mysql/           # must be exactly \"mysql\" or \"postgres\"\n      │   └── mydb/        # database name\n      │       ├── schema/  # contains migration files\n      │       └── queries/ # contains query files\n```\n\nThe presence of a `schema` directory under your database name automatically declares the database in FTL.\n\n\n### Schema Directory\n\nThe `schema` directory contains all your database migration `.sql` files. These files are used to create and modify your database schema.\n\n### Queries Directory\n\nThe `queries` directory contains `.sql` files with any SQL queries you would like generated as FTL verbs for use in your module. These queries must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/). FTL will automatically lift these queries into the module schema and provide a type-safe client to execute each query.\n\nFind more information in the [Using Generated Query Clients](#using-generated-query-clients) section below.\n\n## Provisioning\n\nFTL includes support for automatically provisioning databases. The actual backing implementation is\nextensible, and presently we include support for both local development provisioning using docker,\nand cloud formations based provisioning for AWS deployments. When using `ftl dev` a docker container\nwill automatically be spun up for each datasource that has been defined, and FTL will automatically\nhandle configuration. The same applies when deploying to an AWS cluster with cloud formations\nprovisioning setup.\n\n## Migrations\n\nFTL includes support for automatically running migrations on databases. This is provided by [dbmate](https://github.com/amacneil/dbmate). \n\nTo create additional migrations you can use the `ftl postgres new migration` or `ftl mysql new migration` command. The format of the command is `ftl <engine> new migration <module>.<datasource> <migration-name>`.\n\nThe module name can be omitted if the current working directory only contains a single module.\n\nE.g. to create a new migration called `init` for the `testdb` datasource in the `mysql` module you would run `ftl mysql new migration mysql.testdb init`.\n\nWhen the modules are provisioned FTL will automatically run these migrations for you. \n\n## Connecting with your DB\n\nThere are two supported ways to interact with your database in FTL: using the generated database handle to perform raw queries, or using generated query clients.\n\n### Using the Generated Database Handle\n\n\t\n\tTBD\n\n\n### Using Generated Query Clients\n\nFor better type safety and maintainability, FTL can automatically generate type-safe query clients from SQL files in your `queries` directory. Your SQL files must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/) to specify the type of query and its parameters. For example:\n\n```sql\n-- name: GetUser :one\nSELECT id, name, email\nFROM users\nWHERE id = $1;\n\n-- name: ListUsers :many\nSELECT id, name, email\nFROM users\nORDER BY name;\n\n-- name: CreateUser :exec\nINSERT INTO users (name, email)\nVALUES ($1, $2);\n```\n\nThese queries will be automatically converted into FTL verbs with corresponding generated clients that you can inject into your verbs just like any other verb client. For example:\n\n\t\n```java\n@Verb\npublic String getEmail(int id, GetUserClient query) {\n    UserResult result = query.getUser(id);\n    return result.getEmail();\n}\n```\n\n\n## Transactions\n\nFTL provides transaction support through verb annotations. When a verb is marked as transactional, FTL will automatically manage the transaction boundaries - beginning the transaction when the verb is called, committing if the verb completes successfully, and rolling back if any errors occur during execution.\n\n\nTo mark a verb as transactional, use the `@Transactional` annotation:\n\n```java\npublic class CreateUserRequest {\n    private String name;\n    private String email;\n}\n\npublic class UserService {\n    @Transactional\n    public void createUser(\n        CreateUserRequest request,\n        CreateAddressClient createAddress  // Generated query client\n    ) { \n        // createAddress is a generated query client from a SQL file in queries/\n        createAddress.createAddress(new AddressRequest(userId));\n        // Transaction commits if we reach here without errors\n        // Any errors will cause automatic rollback\n    }\n}\n```\n\n\n### Transaction Rules and Limitations\n\nWhen using transactions, FTL enforces the following restrictions:\n\n1. **Database Usage**: Transaction verbs must use at least one database resource (either through a database handle or SQL query clients). FTL infers which database to open the transaction against based on these usages.\n\n2. **Single Database**: FTL only supports transactions against a single database. Two-phase commits across multiple databases are not supported.\n\n3. **No Nesting**: Transaction verbs cannot be nested. This means you cannot inject another transaction verb's client as a resource within a transaction verb.\n\n4. **Module Scope**: Transaction verbs can only call other verbs within the same module. Calls to external verbs from other modules are not allowed within a transaction.\n\n5. **Automatic Management**: Transaction boundaries are automatically managed by FTL:\n   - The transaction begins when the verb is called\n   - The transaction commits if the verb completes successfully\n   - The transaction rolls back if any errors occur during execution\n\n",
			"kotlin": "\n# Databases\n\nFTL has support for Postgresql and MySQL databases, including support for automatic provisioning and migrations. \n\n\n\nYour database is automatically declared by following a specific directory structure for your SQL files. No additional configuration is needed - just create the directory structure and FTL will handle the rest. See the [Creating a New Database](#creating-a-new-database) section for CLI shortcuts.\n\n\n## Creating a New Database\n\nTo create a new database with the required directory structure, you can use the `ftl postgres new` or `ftl mysql new` command. The format of the command is:\n\n```bash\nftl <engine> new <module>.<datasource>\n```\n\nWhere:\n- `<engine>` is either `mysql` or `postgres`\n- `<module>.<datasource>` is the qualified name of the datasource (module name can be omitted if in a single module directory)\n\nFor example:\n```bash\nftl mysql new mymodule.mydb    # Create a MySQL database named \"mydb\" in module \"mymodule\"\nftl postgres new mydb          # Create a PostgreSQL database named \"mydb\" in the current module\n```\n\nThis command will:\n1. Create the appropriate directory structure\n2. Create an initial migration file in the `schema` directory\n\n## SQL File Structure\n\nIn order to be discoverable by FTL, the SQL files in your project must follow a specific directory structure. FTL supports two database engines, declared via the directory hierarchy as either `mysql` or `postgres`:\n\n\nFor Kotlin projects, SQL files must be located in:\n```\nsrc/main/resources/\n  └── db/\n      ├── mysql/           # must be exactly \"mysql\" or \"postgres\"\n      │   └── mydb/        # database name\n      │       ├── schema/  # contains migration files\n      │       └── queries/ # contains query files\n```\n\nThe presence of a `schema` directory under your database name automatically declares the database in FTL.\n\n\n### Schema Directory\n\nThe `schema` directory contains all your database migration `.sql` files. These files are used to create and modify your database schema.\n\n### Queries Directory\n\nThe `queries` directory contains `.sql` files with any SQL queries you would like generated as FTL verbs for use in your module. These queries must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/). FTL will automatically lift these queries into the module schema and provide a type-safe client to execute each query.\n\nFind more information in the [Using Generated Query Clients](#using-generated-query-clients) section below.\n\n## Provisioning\n\nFTL includes support for automatically provisioning databases. The actual backing implementation is\nextensible, and presently we include support for both local development provisioning using docker,\nand cloud formations based provisioning for AWS deployments. When using `ftl dev` a docker container\nwill automatically be spun up for each datasource that has been defined, and FTL will automatically\nhandle configuration. The same applies when deploying to an AWS cluster with cloud formations\nprovisioning setup.\n\n## Migrations\n\nFTL includes support for automatically running migrations on databases. This is provided by [dbmate](https://github.com/amacneil/dbmate). \n\nTo create additional migrations you can use the `ftl postgres new migration` or `ftl mysql new migration` command. The format of the command is `ftl <engine> new migration <module>.<datasource> <migration-name>`.\n\nThe module name can be omitted if the current working directory only contains a single module.\n\nE.g. to create a new migration called `init` for the `testdb` datasource in the `mysql` module you would run `ftl mysql new migration mysql.testdb init`.\n\nWhen the modules are provisioned FTL will automatically run these migrations for you. \n\n## Connecting with your DB\n\nThere are two supported ways to interact with your database in FTL: using the generated database handle to perform raw queries, or using generated query clients.\n\n### Using the Generated Database Handle\n\n\n\tTBD\n\n\n### Using Generated Query Clients\n\nFor better type safety and maintainability, FTL can automatically generate type-safe query clients from SQL files in your `queries` directory. Your SQL files must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/) to specify the type of query and its parameters. For example:\n\n```sql\n-- name: GetUser :one\nSELECT id, name, email\nFROM users\nWHERE id = $1;\n\n-- name: ListUsers :many\nSELECT id, name, email\nFROM users\nORDER BY name;\n\n-- name: CreateUser :exec\nINSERT INTO users (name, email)\nVALUES ($1, $2);\n```\n\nThese queries will be automatically converted into FTL verbs with corresponding generated clients that you can inject into your verbs just like any other verb client. For example:\n\n\n```kotlin\n@Verb\nfun getEmail(id: Int, query: GetUserClient): String {\n    val result = query.getUser(id)\n    return result.email\n}\n```\n\n\n## Transactions\n\nFTL provides transaction support through verb annotations. When a verb is marked as transactional, FTL will automatically manage the transaction boundaries - beginning the transaction when the verb is called, committing if the verb completes successfully, and rolling back if any errors occur during execution.\n\n\nTo mark a verb as transactional, use the `@Transactional` annotation:\n\n```kotlin\ndata class CreateUserRequest(\n    val name: String,\n    val email: String\n)\n\n@Transactional\nfun createUser(\n    request: CreateUserRequest,\n    createAddress: CreateAddressClient // Generated query client\n): Unit {    \n    // createAddress is a generated query client from a SQL file in queries/\n    createAddress.createAddress(AddressRequest(userId = userId))\n    // Transaction commits if we reach here without errors\n    // Any errors will cause automatic rollback\n}\n```\n\n\n### Transaction Rules and Limitations\n\nWhen using transactions, FTL enforces the following restrictions:\n\n1. **Database Usage**: Transaction verbs must use at least one database resource (either through a database handle or SQL query clients). FTL infers which database to open the transaction against based on these usages.\n\n2. **Single Database**: FTL only supports transactions against a single database. Two-phase commits across multiple databases are not supported.\n\n3. **No Nesting**: Transaction verbs cannot be nested. This means you cannot inject another transaction verb's client as a resource within a transaction verb.\n\n4. **Module Scope**: Transaction verbs can only call other verbs within the same module. Calls to external verbs from other modules are not allowed within a transaction.\n\n5. **Automatic Management**: Transaction boundaries are automatically managed by FTL:\n   - The transaction begins when the verb is called\n   - The transaction commits if the verb completes successfully\n   - The transaction rolls back if any errors occur during execution\n\n",
			"schema": "\nIn the FTL schema, databases are represented using the `database` keyword with the engine type and name:\n\n```schema\nmodule example {\n  // Database declaration\n  database postgres testdb  \n    +migration sha256:59b989063b6de57a1b6867e8ad7915109c9b8632616118c6ef23e4439cf17f8e\n  \n  // Data structures for database operations\n  data CreateUserParams {\n    name String\n    email String\n  }\n  \n  data UserResult {\n    id Int +sql column \"users\".\"id\"\n    name String +sql column \"users\".\"name\"\n    email String +sql column \"users\".\"email\"\n  }\n  \n  // Query that returns a single row\n  verb getUser(Int) example.UserResult\n    +database calls example.testdb\n    +sql query one \"SELECT id, name, email FROM users WHERE id = ?\"\n  \n  // Query that returns multiple rows\n  verb listUsers(Unit) [example.UserResult]\n    +database calls example.testdb\n    +sql query many \"SELECT id, name, email FROM users ORDER BY name\"\n  \n  // Query that performs an action but doesn't return data\n  verb createUser(example.CreateUserParams) Unit\n    +database calls example.testdb\n    +sql query exec \"INSERT INTO users (name, email) VALUES (?, ?)\"\n  \n  // Custom verb that uses a database query\n  export verb getUserEmail(Int) String\n}\n```\n\nThe schema representation includes:\n1. A `database` declaration with the engine type (`postgres` or `mysql`) and database name\n2. The `+migration` annotation with a SHA256 hash of the migration files\n3. Data structures with `+sql column` annotations mapping to database columns\n4. Verb declarations with `+database calls` and `+sql query` annotations specifying the query type and SQL statement\n\n\n## Creating a New Database\n\nTo create a new database with the required directory structure, you can use the `ftl postgres new` or `ftl mysql new` command. The format of the command is:\n\n```bash\nftl <engine> new <module>.<datasource>\n```\n\nWhere:\n- `<engine>` is either `mysql` or `postgres`\n- `<module>.<datasource>` is the qualified name of the datasource (module name can be omitted if in a single module directory)\n\nFor example:\n```bash\nftl mysql new mymodule.mydb    # Create a MySQL database named \"mydb\" in module \"mymodule\"\nftl postgres new mydb          # Create a PostgreSQL database named \"mydb\" in the current module\n```\n\nThis command will:\n1. Create the appropriate directory structure\n2. Create an initial migration file in the `schema` directory\n\n## SQL File Structure\n\nIn order to be discoverable by FTL, the SQL files in your project must follow a specific directory structure. FTL supports two database engines, declared via the directory hierarchy as either `mysql` or `postgres`:\n\n\n### Schema Directory\n\nThe `schema` directory contains all your database migration `.sql` files. These files are used to create and modify your database schema.\n\n### Queries Directory\n\nThe `queries` directory contains `.sql` files with any SQL queries you would like generated as FTL verbs for use in your module. These queries must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/). FTL will automatically lift these queries into the module schema and provide a type-safe client to execute each query.\n\nFind more information in the [Using Generated Query Clients](#using-generated-query-clients) section below.\n\n## Provisioning\n\nFTL includes support for automatically provisioning databases. The actual backing implementation is\nextensible, and presently we include support for both local development provisioning using docker,\nand cloud formations based provisioning for AWS deployments. When using `ftl dev` a docker container\nwill automatically be spun up for each datasource that has been defined, and FTL will automatically\nhandle configuration. The same applies when deploying to an AWS cluster with cloud formations\nprovisioning setup.\n\n## Migrations\n\nFTL includes support for automatically running migrations on databases. This is provided by [dbmate](https://github.com/amacneil/dbmate). \n\nTo create additional migrations you can use the `ftl postgres new migration` or `ftl mysql new migration` command. The format of the command is `ftl <engine> new migration <module>.<datasource> <migration-name>`.\n\nThe module name can be omitted if the current working directory only contains a single module.\n\nE.g. to create a new migration called `init` for the `testdb` datasource in the `mysql` module you would run `ftl mysql new migration mysql.testdb init`.\n\nWhen the modules are provisioned FTL will automatically run these migrations for you. \n\n## Connecting with your DB\n\nThere are two supported ways to interact with your database in FTL: using the generated database handle to perform raw queries, or using generated query clients.\n\n### Using the Generated Database Handle\n\n\nIn the FTL schema, the database handle is represented by the `+database calls` annotation on verbs:\n\n```schema\nmodule example {\n  // Database declaration\n  database postgres mydb\n    +migration sha256:59b989063b6de57a1b6867e8ad7915109c9b8632616118c6ef23e4439cf17f8e\n  \n  // Verb that uses the database handle directly\n  export verb query(Unit) [String]\n    +database calls example.mydb\n}\n```\n\nWhen you use a database handle in your code, you're directly accessing the underlying database connection. The FTL compiler automatically generates the appropriate handle type based on the database declaration.\n\n\n### Using Generated Query Clients\n\nFor better type safety and maintainability, FTL can automatically generate type-safe query clients from SQL files in your `queries` directory. Your SQL files must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/) to specify the type of query and its parameters. For example:\n\n```sql\n-- name: GetUser :one\nSELECT id, name, email\nFROM users\nWHERE id = $1;\n\n-- name: ListUsers :many\nSELECT id, name, email\nFROM users\nORDER BY name;\n\n-- name: CreateUser :exec\nINSERT INTO users (name, email)\nVALUES ($1, $2);\n```\n\nThese queries will be automatically converted into FTL verbs with corresponding generated clients that you can inject into your verbs just like any other verb client. For example:\n\n\nIn the FTL schema, the generated query clients are represented as verbs with the `+database calls` and `+sql query` annotations:\n\n```schema\nmodule example {\n  // Database declaration\n  database postgres testdb\n    +migration sha256:59b989063b6de57a1b6867e8ad7915109c9b8632616118c6ef23e4439cf17f8e\n  \n  // Data structures for query results and parameters\n  data UserResult {\n    id Int +sql column \"users\".\"id\"\n    name String +sql column \"users\".\"name\"\n    email String +sql column \"users\".\"email\"\n  }\n  \n  data CreateUserParams {\n    name String\n    email String\n  }\n  \n  // Query that returns a single row\n  verb getUser(Int) example.UserResult\n    +database calls example.testdb\n    +sql query one \"SELECT id, name, email FROM users WHERE id = ?\"\n  \n  // Query that returns multiple rows\n  verb listUsers(Unit) [example.UserResult]\n    +database calls example.testdb\n    +sql query many \"SELECT id, name, email FROM users ORDER BY name\"\n  \n  // Query that performs an action but doesn't return data\n  verb createUser(example.CreateUserParams) Unit\n    +database calls example.testdb\n    +sql query exec \"INSERT INTO users (name, email) VALUES (?, ?)\"\n  \n  // Custom verb that uses the generated query client\n  export verb getUserEmail(Int) String\n    +calls example.getUser\n}\n```\n\nWhen you use a generated query client in your code, you're calling a verb that has been automatically generated from your SQL query. FTL handles the mapping between your SQL queries and the generated verbs.\n\n\n## Transactions\n\nFTL provides transaction support through verb annotations. When a verb is marked as transactional, FTL will automatically manage the transaction boundaries - beginning the transaction when the verb is called, committing if the verb completes successfully, and rolling back if any errors occur during execution.\n\n\nIn the FTL schema, transaction verbs are represented with the `+transaction` annotation:\n\n```schema\nmodule example {\n  // Database declaration\n  database postgres mydb\n    +migration sha256:59b989063b6de57a1b6867e8ad7915109c9b8632616118c6ef23e4439cf17f8e\n  \n  data CreateUserRequest {\n    name String\n    email String\n  }\n  \n  data AddressRequest {\n    userId Int +sql column \"addresses\".\"id\"\n    street String +sql column \"addresses\".\"street\"\n    city String +sql column \"addresses\".\"city\"\n  }\n  \n  // Generated query client from SQL file\n  verb createAddress(example.AddressRequest) Unit\n    +database calls example.mydb\n    +sql query exec \"INSERT INTO addresses (user_id, street, city) VALUES (?, ?, ?)\"\n  \n  // Transaction verb that uses both direct database access and a generated query client\n  verb createUser(example.CreateUserRequest) Unit\n    +transaction\n    +database calls example.mydb\n    +calls example.createAddress\n}\n```\n\n\n### Transaction Rules and Limitations\n\nWhen using transactions, FTL enforces the following restrictions:\n\n1. **Database Usage**: Transaction verbs must use at least one database resource (either through a database handle or SQL query clients). FTL infers which database to open the transaction against based on these usages.\n\n2. **Single Database**: FTL only supports transactions against a single database. Two-phase commits across multiple databases are not supported.\n\n3. **No Nesting**: Transaction verbs cannot be nested. This means you cannot inject another transaction verb's client as a resource within a transaction verb.\n\n4. **Module Scope**: Transaction verbs can only call other verbs within the same module. Calls to external verbs from other modules are not allowed within a transaction.\n\n5. **Automatic Management**: Transaction boundaries are automatically managed by FTL:\n   - The transaction begins when the verb is called\n   - The transaction commits if the verb completes successfully\n   - The transaction rolls back if any errors occur during execution\n\n",
	},
	"@Secret": {
			"go": "\n# Secrets and Configuration\n\n## Configuration\n\nConfiguration values are named, typed values. They are managed by the `ftl config` command-line.\n\n\n\nTo declare a configuration value use the following syntax:\n\n```go\n// Simple string configuration\ntype ApiUrl = ftl.Config[string]\n\n// Type-safe configuration\ntype DefaultUser = ftl.Config[Username]\n```\n\nNote that the name of the configuration value as represented in the FTL schema is the lower camel case version of the type name (e.g., `ApiUrl` becomes `apiUrl`).\n\nConfiguration values can be injected into FTL methods, such as //ftl:verb, HTTP ingress, Cron etc. To inject a configuration value, use the following syntax:\n\n```go\n//ftl:verb\nfunc Hello(ctx context.Context, req Request, defaultUser DefaultUser) error {\n    username := defaultUser.Get(ctx)\n    // ...\n}\n```\n\n\n## Secrets\n\nSecrets are encrypted, named, typed values. They are managed by the `ftl secret` command-line.\n\n\nDeclare a secret with the following:\n\n```go\n// Simple string secret\ntype ApiToken = ftl.Secret[string]\n\n// Type-safe secret\ntype ApiKey = ftl.Secret[Credentials]\n```\n\nLike configuration values, the name of the secret as represented in the FTL schema is the lower camel case version of the type name (e.g., `ApiToken` becomes `apiToken`).\n\nSecrets can be injected into FTL methods, such as //ftl:verb, HTTP ingress, Cron etc. To inject a secret value, use the following syntax:\n\n```go\n//ftl:verb\nfunc CallApi(ctx context.Context, req Request, apiKey ApiKey) error {\n    credentials := apiKey.Get(ctx)\n    // ...\n}\n```\n\n\n## Transforming secrets/configuration\n\nOften, raw secret/configuration values aren't directly useful. For example, raw credentials might be used to create an API client. For those situations `ftl.Map()` can be used to transform a configuration or secret value into another type:\n\n```go\nvar client = ftl.Map(ftl.Secret[Credentials](\"credentials\"),\n                     func(ctx context.Context, creds Credentials) (*api.Client, error) {\n    return api.NewClient(creds)\n})\n```\n\nThis is not currently supported in Kotlin or Java. \n\n",
			"java": "\n# Secrets and Configuration\n\n## Configuration\n\nConfiguration values are named, typed values. They are managed by the `ftl config` command-line.\n\n\n\nConfiguration values can be injected into FTL methods, such as `@Verb`, HTTP ingress, Cron etc. To inject a configuration value, use the following syntax:\n\n```java\n@Export\n@Verb\nHelloResponse hello(HelloRequest helloRequest, @Config(\"defaultUser\") String defaultUser)  {\n    return new HelloResponse(\"Hello, \" + defaultUser);\n}\n```\n\n\n## Secrets\n\nSecrets are encrypted, named, typed values. They are managed by the `ftl secret` command-line.\n\n\nSecrets can be injected into FTL methods, such as `@Verb`, HTTP ingress, Cron etc. To inject a secret value, use the following syntax:\n\n```java\n@Export\n@Verb\nHelloResponse hello(HelloRequest helloRequest, @Secret(\"apiKey\") String apiKey)  {\n    return new HelloResponse(\"Hello, \" + api.call(apiKey));\n}\n```\n\n\n## Transforming secrets/configuration\n\nOften, raw secret/configuration values aren't directly useful. For example, raw credentials might be used to create an API client. For those situations `ftl.Map()` can be used to transform a configuration or secret value into another type:\n\n```go\nvar client = ftl.Map(ftl.Secret[Credentials](\"credentials\"),\n                     func(ctx context.Context, creds Credentials) (*api.Client, error) {\n    return api.NewClient(creds)\n})\n```\n\nThis is not currently supported in Kotlin or Java. \n\n",
			"kotlin": "\n# Secrets and Configuration\n\n## Configuration\n\nConfiguration values are named, typed values. They are managed by the `ftl config` command-line.\n\n\n\nConfiguration values can be injected into FTL methods, such as `@Verb`, HTTP ingress, Cron etc. To inject a configuration value, use the following syntax:\n\n```kotlin\n@Export\n@Verb\nfun hello(helloRequest: HelloRequest, @Config(\"defaultUser\") defaultUser: String): HelloResponse {\n    return HelloResponse(\"Hello, $defaultUser\")\n}\n```\n\n\n## Secrets\n\nSecrets are encrypted, named, typed values. They are managed by the `ftl secret` command-line.\n\n\nSecrets can be injected into FTL methods, such as `@Verb`, HTTP ingress, Cron etc. To inject a secret value, use the following syntax:\n\n```kotlin\n@Export\n@Verb\nfun hello(helloRequest: HelloRequest, @Secret(\"apiKey\") apiKey: String): HelloResponse {\n    return HelloResponse(\"Hello, ${api.call(apiKey)}\")\n}\n```\n\n\n## Transforming secrets/configuration\n\nOften, raw secret/configuration values aren't directly useful. For example, raw credentials might be used to create an API client. For those situations `ftl.Map()` can be used to transform a configuration or secret value into another type:\n\n```go\nvar client = ftl.Map(ftl.Secret[Credentials](\"credentials\"),\n                     func(ctx context.Context, creds Credentials) (*api.Client, error) {\n    return api.NewClient(creds)\n})\n```\n\nThis is not currently supported in Kotlin or Java. \n\n",
			"schema": "\nIn the FTL schema, configuration values are declared as follows:\n\n```schema\nmodule example {\n  config defaultUser String\n  \n  verb hello(Unit) String\n    +config example.defaultUser\n}\n```\n\nConfiguration values have a name, a type, and can be injected into verbs using the `+config` annotation.\n\n## Secrets\n\nSecrets are encrypted, named, typed values. They are managed by the `ftl secret` command-line.\n\n\nIn the FTL schema, secrets are declared as follows:\n\n```schema\nmodule example {\n  // Secret declaration\n  secret apiToken String\n  secret apiKey example.Credentials\n  \n  // Using a secret in a verb\n  verb callApi(example.Request) Unit\n    +secret apiKey\n}\n```\n\nSecrets have a name, a type, and can be injected into verbs using the `+secret` annotation.\n\n## Transforming secrets/configuration\n\nOften, raw secret/configuration values aren't directly useful. For example, raw credentials might be used to create an API client. For those situations `ftl.Map()` can be used to transform a configuration or secret value into another type:\n\n```go\nvar client = ftl.Map(ftl.Secret[Credentials](\"credentials\"),\n                     func(ctx context.Context, creds Credentials) (*api.Client, error) {\n    return api.NewClient(creds)\n})\n```\n\nThis is not currently supported in Kotlin or Java. \n\n",
	},
	"@Subscription": {
			"go": "\n# PubSub\n\nFTL has first-class support for PubSub, modelled on the concepts of topics (where events are sent) and subscribers (a verb which consumes events). Subscribers are, as you would expect, sinks. Each subscriber is a cursor over the topic it is associated with. Each topic may have multiple subscriptions. Each published event has an at least once delivery guarantee for each subscription.\n\nA topic can be exported to allow other modules to subscribe to it. Subscriptions are always private to their module.\n\nWhen a subscription is first created in an environment, it can start consuming from the beginning of the topic or only consume events published afterwards.\n\nTopics allow configuring the number of partitions and how each event should be mapped to a partition, allowing for greater throughput. Subscriptions will consume in order within each partition. There are cases where a small amount of progress on a subscription will be lost, so subscriptions should be able to handle receiving some events that have already been consumed.\n\n\n## Declaring a Topic\n\nHere's how to declare a simple topic with a single partition:\n\n\n```go\npackage payments\n\nimport (\n  \"github.com/block/ftl/go-runtime/ftl\"\n)\n\n// Define an event type\ntype Invoice struct {\n  InvoiceNo string\n}\n\n//ftl:topic partitions=1\ntype Invoices = ftl.TopicHandle[Invoice, ftl.SinglePartitionMap[Invoice]]\n```\n\nNote that the name of the topic as represented in the FTL schema is the lower camel case version of the type name.\n\nThe `Invoices` type is a handle to the topic. It is a generic type that takes two arguments: the event type and the partition map type. The partition map type is used to map events to partitions.\n\nTo export a topic, add `export` to the directive like this:\n```go\n//ftl:topic export partitions=1\n```\n\n\n## Multi-Partition Topics\n\nFor topics that require multiple partitions, you'll need to implement a partition mapper:\n\n\n```go\npackage payments\n\nimport (\n  \"github.com/block/ftl/go-runtime/ftl\"\n)\n\n// Define an event type\ntype Invoice struct {\n  InvoiceNo string\n}\n\ntype PartitionMapper struct{}\n\nvar _ ftl.TopicPartitionMap[PubSubEvent] = PartitionMapper{}\n\nfunc (PartitionMapper) PartitionKey(event PubSubEvent) string {\n\treturn event.Time.String()\n}\n\n//ftl:topic partitions=10\ntype Invoices = ftl.TopicHandle[Invoice, PartitionMapper]\n```\n\n\n## Publishing Events\n\nEvents can be published to a topic by injecting the topic into a verb:\n\n\n```go\n//ftl:verb\nfunc PublishInvoice(ctx context.Context, topic Invoices) error {\n   topic.Publish(ctx, Invoice{...})\n   // ...\n}\n```\n\n\n## Subscribing to Topics\n\nHere's how to subscribe to topics:\n\n\n```go\n// Configure initial event consumption with either from=beginning or from=latest\n//\n//ftl:subscribe payments.invoices from=beginning\nfunc SendInvoiceEmail(ctx context.Context, in Invoice) error {\n  // ...\n}\n```\n\n\n",
			"java": "\n# PubSub\n\nFTL has first-class support for PubSub, modelled on the concepts of topics (where events are sent) and subscribers (a verb which consumes events). Subscribers are, as you would expect, sinks. Each subscriber is a cursor over the topic it is associated with. Each topic may have multiple subscriptions. Each published event has an at least once delivery guarantee for each subscription.\n\nA topic can be exported to allow other modules to subscribe to it. Subscriptions are always private to their module.\n\nWhen a subscription is first created in an environment, it can start consuming from the beginning of the topic or only consume events published afterwards.\n\nTopics allow configuring the number of partitions and how each event should be mapped to a partition, allowing for greater throughput. Subscriptions will consume in order within each partition. There are cases where a small amount of progress on a subscription will be lost, so subscriptions should be able to handle receiving some events that have already been consumed.\n\n\n## Declaring a Topic\n\nHere's how to declare a simple topic with a single partition:\n\n\n```java\nimport xyz.block.ftl.Export;\nimport xyz.block.ftl.SinglePartitionMapper;\nimport xyz.block.ftl.Topic;\nimport xyz.block.ftl.WriteableTopic;\n\n// Define the event type for the topic\nrecord Invoice(String invoiceNo) {\n}\n\n// Add @Export if you want other modules to be able to consume from this topic\n@Topic(name = \"invoices\", partitions = 1)\ninterface InvoicesTopic extends WriteableTopic<Invoice, SinglePartitionMapper> {\n}\n```\n\n\n## Multi-Partition Topics\n\nFor topics that require multiple partitions, you'll need to implement a partition mapper:\n\n\n```java\nimport xyz.block.ftl.Export;\nimport xyz.block.ftl.Topic;\nimport xyz.block.ftl.TopicPartitionMapper;\nimport xyz.block.ftl.WriteableTopic;\n\n// Define the event type for the topic\nrecord Invoice(String invoiceNo) {\n}\n\n// PartitionMapper maps each to a partition in the topic\nclass PartitionMapper implements TopicPartitionMapper<Invoice> {\n    public String getPartitionKey(Invoice invoice) {\n        return invoice.invoiceNo();\n    }\n}\n\n// Add @Export if you want other modules to be able to consum from this topic\n@Topic(name = \"invoices\", partitions = 8)\ninterface InvoicesTopic extends WriteableTopic<Invoice, PartitionMapper> {\n}\n```\n\n\n## Publishing Events\n\nEvents can be published to a topic by injecting the topic into a verb:\n\n\n```java\n@Verb\nvoid publishInvoice(InvoiceRequest request, InvoicesTopic topic) throws Exception {\n    topic.publish(new Invoice(request.invoiceNo()));\n}\n```\n\n\n## Subscribing to Topics\n\nHere's how to subscribe to topics:\n\n\n```java\n// if subscribing from another module, import the event and topic\nimport ftl.othermodule.Invoice;\nimport ftl.othermodule.InvoicesTopic;\n\nimport xyz.block.ftl.FromOffset;\nimport xyz.block.ftl.Subscription;\n\nclass Subscriber {\n    @Subscription(topic = InvoicesTopic.class, from = FromOffset.LATEST)\n    public void consumeInvoice(Invoice event) {\n        // ...\n    }\n}\n```\n\nIf you are subscribing to a topic from another module, FTL will generate a topic class for you so you can subscribe to it. This generated\ntopic cannot be published to, only subscribed to:\n\n```java\n@Topic(name=\"invoices\", module=\"publisher\")\ninterface InvoicesTopic extends ConsumableTopic<Invoice> {}\n```\n\n\n",
			"kotlin": "\n# PubSub\n\nFTL has first-class support for PubSub, modelled on the concepts of topics (where events are sent) and subscribers (a verb which consumes events). Subscribers are, as you would expect, sinks. Each subscriber is a cursor over the topic it is associated with. Each topic may have multiple subscriptions. Each published event has an at least once delivery guarantee for each subscription.\n\nA topic can be exported to allow other modules to subscribe to it. Subscriptions are always private to their module.\n\nWhen a subscription is first created in an environment, it can start consuming from the beginning of the topic or only consume events published afterwards.\n\nTopics allow configuring the number of partitions and how each event should be mapped to a partition, allowing for greater throughput. Subscriptions will consume in order within each partition. There are cases where a small amount of progress on a subscription will be lost, so subscriptions should be able to handle receiving some events that have already been consumed.\n\n\n## Declaring a Topic\n\nHere's how to declare a simple topic with a single partition:\n\n\n```kotlin\nimport xyz.block.ftl.Export;\nimport xyz.block.ftl.SinglePartitionMapper\nimport xyz.block.ftl.Topic\nimport xyz.block.ftl.WriteableTopic\n\n// Define the event type for the topic\ndata class Invoice(val invoiceNo: String)\n\n// Add @Export if you want other modules to be able to consume from this topic\n@Topic(name = \"invoices\", partitions = 1)\ninternal interface InvoicesTopic : WriteableTopic<Invoice, SinglePartitionMapper>\n```\n\n\n## Multi-Partition Topics\n\nFor topics that require multiple partitions, you'll need to implement a partition mapper:\n\n\n```kotlin\nimport xyz.block.ftl.Export;\nimport xyz.block.ftl.SinglePartitionMapper\nimport xyz.block.ftl.Topic\nimport xyz.block.ftl.TopicPartitionMapper\nimport xyz.block.ftl.WriteableTopic\n\n// Define the event type for the topic\ndata class Invoice(val invoiceNo: String)\n\n// PartitionMapper maps each to a partition in the topic\nclass PartitionMapper : TopicPartitionMapper<Invoice> {\n    override fun getPartitionKey(invoice: Invoice): String {\n        return invoice.invoiceNo\n    }\n}\n\n// Add @Export if you want other modules to be able to consume from this topic\n@Topic(name = \"invoices\", partitions = 8)\ninternal interface InvoicesTopic : WriteableTopic<Invoice, PartitionMapper>\n```\n\n\n## Publishing Events\n\nEvents can be published to a topic by injecting the topic into a verb:\n\n\n```kotlin\n@Verb\nfun publishInvoice(request: InvoiceRequest, topic: InvoicesTopic) {\n    topic.publish(Invoice(request.invoiceNo))\n}\n```\n\n\n## Subscribing to Topics\n\nHere's how to subscribe to topics:\n\n\n```kotlin\n// if subscribing from another module, import the event and topic\nimport ftl.publisher.Invoice\nimport ftl.publisher.InvoicesTopic\n\nimport xyz.block.ftl.FromOffset\nimport xyz.block.ftl.Subscription\n\n@Subscription(topic = InvoicesTopic::class, from = FromOffset.LATEST)\nfun consumeInvoice(event: Invoice) {\n    // ...\n}\n```\n\nIf you are subscribing to a topic from another module, FTL will generate a topic class for you so you can subscribe to it. This generated\ntopic cannot be published to, only subscribed to:\n\n```kotlin\n@Topic(name=\"invoices\", module=\"publisher\")\ninternal interface InvoicesTopic : ConsumableTopic<Invoice>\n```\n\n\n",
			"schema": "\n```schema\nmodule payments {\n  // The Invoice data type that will be published to the topic\n  data Invoice {\n    invoiceNo String\n  }\n\n  // A topic with a single partition\n  topic invoices payments.Invoice\n}\n```\n\n\n## Multi-Partition Topics\n\nFor topics that require multiple partitions, you'll need to implement a partition mapper:\n\n\n```schema\nmodule payments {\n  // The Invoice data type that will be published to the topic\n  data Invoice {\n    invoiceNo String\n  }\n\n  // A topic with multiple partitions (8 or 10 depending on language)\n  // The partition key is determined by the mapper implementation\n  topic invoices payments.Invoice\n    +partitions 8\n}\n```\n\n\n## Publishing Events\n\nEvents can be published to a topic by injecting the topic into a verb:\n\n\n```schema\nmodule payments {\n  data InvoiceRequest {\n    invoiceNo String\n  }\n  \n  data Invoice {\n    invoiceNo String\n  }\n  \n  topic invoices payments.Invoice\n  \n  // A verb that publishes to the invoices topic\n  verb publishInvoice(payments.InvoiceRequest) Unit\n    +publish payments.invoices\n}\n```\n\n\n## Subscribing to Topics\n\nHere's how to subscribe to topics:\n\n\n```schema\nmodule payments {\n  data InvoiceRequest {\n    invoiceNo String\n  }\n  \n  data Invoice {\n    invoiceNo String\n  }\n  \n  topic invoices payments.Invoice\n  \n  // A verb that subscribes to the invoices topic\n  verb sendInvoiceEmail(payments.Invoice) Unit\n    +subscribe payments.invoices from=beginning\n}\n\n// In another module\nmodule emailer {\n  // A verb that subscribes to the invoices topic from another module\n  verb consumeInvoice(payments.Invoice) Unit\n    +subscribe payments.invoices from=latest\n}\n```\n\n\n",
	},
	"@Topic": {
			"go": "\n# PubSub\n\nFTL has first-class support for PubSub, modelled on the concepts of topics (where events are sent) and subscribers (a verb which consumes events). Subscribers are, as you would expect, sinks. Each subscriber is a cursor over the topic it is associated with. Each topic may have multiple subscriptions. Each published event has an at least once delivery guarantee for each subscription.\n\nA topic can be exported to allow other modules to subscribe to it. Subscriptions are always private to their module.\n\nWhen a subscription is first created in an environment, it can start consuming from the beginning of the topic or only consume events published afterwards.\n\nTopics allow configuring the number of partitions and how each event should be mapped to a partition, allowing for greater throughput. Subscriptions will consume in order within each partition. There are cases where a small amount of progress on a subscription will be lost, so subscriptions should be able to handle receiving some events that have already been consumed.\n\n\n## Declaring a Topic\n\nHere's how to declare a simple topic with a single partition:\n\n\n```go\npackage payments\n\nimport (\n  \"github.com/block/ftl/go-runtime/ftl\"\n)\n\n// Define an event type\ntype Invoice struct {\n  InvoiceNo string\n}\n\n//ftl:topic partitions=1\ntype Invoices = ftl.TopicHandle[Invoice, ftl.SinglePartitionMap[Invoice]]\n```\n\nNote that the name of the topic as represented in the FTL schema is the lower camel case version of the type name.\n\nThe `Invoices` type is a handle to the topic. It is a generic type that takes two arguments: the event type and the partition map type. The partition map type is used to map events to partitions.\n\nTo export a topic, add `export` to the directive like this:\n```go\n//ftl:topic export partitions=1\n```\n\n\n## Multi-Partition Topics\n\nFor topics that require multiple partitions, you'll need to implement a partition mapper:\n\n\n```go\npackage payments\n\nimport (\n  \"github.com/block/ftl/go-runtime/ftl\"\n)\n\n// Define an event type\ntype Invoice struct {\n  InvoiceNo string\n}\n\ntype PartitionMapper struct{}\n\nvar _ ftl.TopicPartitionMap[PubSubEvent] = PartitionMapper{}\n\nfunc (PartitionMapper) PartitionKey(event PubSubEvent) string {\n\treturn event.Time.String()\n}\n\n//ftl:topic partitions=10\ntype Invoices = ftl.TopicHandle[Invoice, PartitionMapper]\n```\n\n\n## Publishing Events\n\nEvents can be published to a topic by injecting the topic into a verb:\n\n\n```go\n//ftl:verb\nfunc PublishInvoice(ctx context.Context, topic Invoices) error {\n   topic.Publish(ctx, Invoice{...})\n   // ...\n}\n```\n\n\n## Subscribing to Topics\n\nHere's how to subscribe to topics:\n\n\n```go\n// Configure initial event consumption with either from=beginning or from=latest\n//\n//ftl:subscribe payments.invoices from=beginning\nfunc SendInvoiceEmail(ctx context.Context, in Invoice) error {\n  // ...\n}\n```\n\n\n",
			"java": "\n# PubSub\n\nFTL has first-class support for PubSub, modelled on the concepts of topics (where events are sent) and subscribers (a verb which consumes events). Subscribers are, as you would expect, sinks. Each subscriber is a cursor over the topic it is associated with. Each topic may have multiple subscriptions. Each published event has an at least once delivery guarantee for each subscription.\n\nA topic can be exported to allow other modules to subscribe to it. Subscriptions are always private to their module.\n\nWhen a subscription is first created in an environment, it can start consuming from the beginning of the topic or only consume events published afterwards.\n\nTopics allow configuring the number of partitions and how each event should be mapped to a partition, allowing for greater throughput. Subscriptions will consume in order within each partition. There are cases where a small amount of progress on a subscription will be lost, so subscriptions should be able to handle receiving some events that have already been consumed.\n\n\n## Declaring a Topic\n\nHere's how to declare a simple topic with a single partition:\n\n\n```java\nimport xyz.block.ftl.Export;\nimport xyz.block.ftl.SinglePartitionMapper;\nimport xyz.block.ftl.Topic;\nimport xyz.block.ftl.WriteableTopic;\n\n// Define the event type for the topic\nrecord Invoice(String invoiceNo) {\n}\n\n// Add @Export if you want other modules to be able to consume from this topic\n@Topic(name = \"invoices\", partitions = 1)\ninterface InvoicesTopic extends WriteableTopic<Invoice, SinglePartitionMapper> {\n}\n```\n\n\n## Multi-Partition Topics\n\nFor topics that require multiple partitions, you'll need to implement a partition mapper:\n\n\n```java\nimport xyz.block.ftl.Export;\nimport xyz.block.ftl.Topic;\nimport xyz.block.ftl.TopicPartitionMapper;\nimport xyz.block.ftl.WriteableTopic;\n\n// Define the event type for the topic\nrecord Invoice(String invoiceNo) {\n}\n\n// PartitionMapper maps each to a partition in the topic\nclass PartitionMapper implements TopicPartitionMapper<Invoice> {\n    public String getPartitionKey(Invoice invoice) {\n        return invoice.invoiceNo();\n    }\n}\n\n// Add @Export if you want other modules to be able to consum from this topic\n@Topic(name = \"invoices\", partitions = 8)\ninterface InvoicesTopic extends WriteableTopic<Invoice, PartitionMapper> {\n}\n```\n\n\n## Publishing Events\n\nEvents can be published to a topic by injecting the topic into a verb:\n\n\n```java\n@Verb\nvoid publishInvoice(InvoiceRequest request, InvoicesTopic topic) throws Exception {\n    topic.publish(new Invoice(request.invoiceNo()));\n}\n```\n\n\n## Subscribing to Topics\n\nHere's how to subscribe to topics:\n\n\n```java\n// if subscribing from another module, import the event and topic\nimport ftl.othermodule.Invoice;\nimport ftl.othermodule.InvoicesTopic;\n\nimport xyz.block.ftl.FromOffset;\nimport xyz.block.ftl.Subscription;\n\nclass Subscriber {\n    @Subscription(topic = InvoicesTopic.class, from = FromOffset.LATEST)\n    public void consumeInvoice(Invoice event) {\n        // ...\n    }\n}\n```\n\nIf you are subscribing to a topic from another module, FTL will generate a topic class for you so you can subscribe to it. This generated\ntopic cannot be published to, only subscribed to:\n\n```java\n@Topic(name=\"invoices\", module=\"publisher\")\ninterface InvoicesTopic extends ConsumableTopic<Invoice> {}\n```\n\n\n",
			"kotlin": "\n# PubSub\n\nFTL has first-class support for PubSub, modelled on the concepts of topics (where events are sent) and subscribers (a verb which consumes events). Subscribers are, as you would expect, sinks. Each subscriber is a cursor over the topic it is associated with. Each topic may have multiple subscriptions. Each published event has an at least once delivery guarantee for each subscription.\n\nA topic can be exported to allow other modules to subscribe to it. Subscriptions are always private to their module.\n\nWhen a subscription is first created in an environment, it can start consuming from the beginning of the topic or only consume events published afterwards.\n\nTopics allow configuring the number of partitions and how each event should be mapped to a partition, allowing for greater throughput. Subscriptions will consume in order within each partition. There are cases where a small amount of progress on a subscription will be lost, so subscriptions should be able to handle receiving some events that have already been consumed.\n\n\n## Declaring a Topic\n\nHere's how to declare a simple topic with a single partition:\n\n\n```kotlin\nimport xyz.block.ftl.Export;\nimport xyz.block.ftl.SinglePartitionMapper\nimport xyz.block.ftl.Topic\nimport xyz.block.ftl.WriteableTopic\n\n// Define the event type for the topic\ndata class Invoice(val invoiceNo: String)\n\n// Add @Export if you want other modules to be able to consume from this topic\n@Topic(name = \"invoices\", partitions = 1)\ninternal interface InvoicesTopic : WriteableTopic<Invoice, SinglePartitionMapper>\n```\n\n\n## Multi-Partition Topics\n\nFor topics that require multiple partitions, you'll need to implement a partition mapper:\n\n\n```kotlin\nimport xyz.block.ftl.Export;\nimport xyz.block.ftl.SinglePartitionMapper\nimport xyz.block.ftl.Topic\nimport xyz.block.ftl.TopicPartitionMapper\nimport xyz.block.ftl.WriteableTopic\n\n// Define the event type for the topic\ndata class Invoice(val invoiceNo: String)\n\n// PartitionMapper maps each to a partition in the topic\nclass PartitionMapper : TopicPartitionMapper<Invoice> {\n    override fun getPartitionKey(invoice: Invoice): String {\n        return invoice.invoiceNo\n    }\n}\n\n// Add @Export if you want other modules to be able to consume from this topic\n@Topic(name = \"invoices\", partitions = 8)\ninternal interface InvoicesTopic : WriteableTopic<Invoice, PartitionMapper>\n```\n\n\n## Publishing Events\n\nEvents can be published to a topic by injecting the topic into a verb:\n\n\n```kotlin\n@Verb\nfun publishInvoice(request: InvoiceRequest, topic: InvoicesTopic) {\n    topic.publish(Invoice(request.invoiceNo))\n}\n```\n\n\n## Subscribing to Topics\n\nHere's how to subscribe to topics:\n\n\n```kotlin\n// if subscribing from another module, import the event and topic\nimport ftl.publisher.Invoice\nimport ftl.publisher.InvoicesTopic\n\nimport xyz.block.ftl.FromOffset\nimport xyz.block.ftl.Subscription\n\n@Subscription(topic = InvoicesTopic::class, from = FromOffset.LATEST)\nfun consumeInvoice(event: Invoice) {\n    // ...\n}\n```\n\nIf you are subscribing to a topic from another module, FTL will generate a topic class for you so you can subscribe to it. This generated\ntopic cannot be published to, only subscribed to:\n\n```kotlin\n@Topic(name=\"invoices\", module=\"publisher\")\ninternal interface InvoicesTopic : ConsumableTopic<Invoice>\n```\n\n\n",
			"schema": "\n```schema\nmodule payments {\n  // The Invoice data type that will be published to the topic\n  data Invoice {\n    invoiceNo String\n  }\n\n  // A topic with a single partition\n  topic invoices payments.Invoice\n}\n```\n\n\n## Multi-Partition Topics\n\nFor topics that require multiple partitions, you'll need to implement a partition mapper:\n\n\n```schema\nmodule payments {\n  // The Invoice data type that will be published to the topic\n  data Invoice {\n    invoiceNo String\n  }\n\n  // A topic with multiple partitions (8 or 10 depending on language)\n  // The partition key is determined by the mapper implementation\n  topic invoices payments.Invoice\n    +partitions 8\n}\n```\n\n\n## Publishing Events\n\nEvents can be published to a topic by injecting the topic into a verb:\n\n\n```schema\nmodule payments {\n  data InvoiceRequest {\n    invoiceNo String\n  }\n  \n  data Invoice {\n    invoiceNo String\n  }\n  \n  topic invoices payments.Invoice\n  \n  // A verb that publishes to the invoices topic\n  verb publishInvoice(payments.InvoiceRequest) Unit\n    +publish payments.invoices\n}\n```\n\n\n## Subscribing to Topics\n\nHere's how to subscribe to topics:\n\n\n```schema\nmodule payments {\n  data InvoiceRequest {\n    invoiceNo String\n  }\n  \n  data Invoice {\n    invoiceNo String\n  }\n  \n  topic invoices payments.Invoice\n  \n  // A verb that subscribes to the invoices topic\n  verb sendInvoiceEmail(payments.Invoice) Unit\n    +subscribe payments.invoices from=beginning\n}\n\n// In another module\nmodule emailer {\n  // A verb that subscribes to the invoices topic from another module\n  verb consumeInvoice(payments.Invoice) Unit\n    +subscribe payments.invoices from=latest\n}\n```\n\n\n",
	},
	"@TypeAlias": {
			"go": "## Type aliases\n\nA type alias is an alternate name for an existing type. It can be declared like so:\n\n\n```go\n//ftl:typealias\ntype UserID string\n```\n\n\nType aliases are useful for making code more readable and type-safe by giving meaningful names to types that represent specific concepts in your domain.\n\n",
			"java": "## Type aliases\n\nA type alias is an alternate name for an existing type. It can be declared like so:\n\n\n```java\n// Java does not support type aliases directly\n// Use a wrapper class instead\npublic class UserID {\n    private final String value;\n\n    public UserID(String value) {\n        this.value = value;\n    }\n\n    public String getValue() {\n        return value;\n    }\n}\n```\n\n\nType aliases are useful for making code more readable and type-safe by giving meaningful names to types that represent specific concepts in your domain.\n\n",
			"kotlin": "## Type aliases\n\nA type alias is an alternate name for an existing type. It can be declared like so:\n\n\n```kotlin\ntypealias UserID = String\n```\n\n\nType aliases are useful for making code more readable and type-safe by giving meaningful names to types that represent specific concepts in your domain.\n\n",
			"schema": "\nIn the FTL schema, type aliases are defined using the `typealias` keyword:\n\n```schema\nmodule example {\n  typealias UserID String\n}\n```\n\nType aliases can be used in data structures:\n\n```schema\nmodule example {\n  typealias UserID String\n  \n  typealias UserMap Map<String, example.User>\n  \n  data User {\n    id example.UserID\n    name String\n  }\n}\n```\n\n\nType aliases are useful for making code more readable and type-safe by giving meaningful names to types that represent specific concepts in your domain.\n\n",
	},
	"@Verb": {
			"go": "\n# Verbs\n\n## Defining Verbs\n\n\n\nTo declare a Verb, write a normal Go function with the following signature, annotated with the Go [comment directive](https://tip.golang.org/doc/comment#syntax) `//ftl:verb`:\n\n```go\n//ftl:verb\nfunc F(context.Context, In) (Out, error) { }\n```\n\neg.\n\n```go\ntype EchoRequest struct {}\n\ntype EchoResponse struct {}\n\n//ftl:verb\nfunc Echo(ctx context.Context, in EchoRequest) (EchoResponse, error) {\n  // ...\n}\n```\n\n\nBy default verbs are only visible to other verbs in the same module (see [visibility](./visibility) for more information).\n\n## Calling Verbs\n\n\nTo call a verb, import the module's verb client (`{ModuleName}.{VerbName}Client`), add it to your verb's signature, then invoke it as a function. eg.\n\n```go\n//ftl:verb\nfunc Echo(ctx context.Context, in EchoRequest, tc time.TimeClient) (EchoResponse, error) {\n    out, err := tc(ctx, TimeRequest{...})\n}\n```\n\nVerb clients are generated by FTL. If the callee verb belongs to the same module as the caller, you must build the\nmodule first (with callee verb defined) in order to generate its client for use by the caller. Local verb clients are\navailable in the generated `types.ftl.go` file as `{VerbName}Client`.\n\n\n",
			"java": "\n# Verbs\n\n## Defining Verbs\n\n\n\nTo declare a Verb, write a normal Java method with the following signature, annotated with the `@Verb` annotation:\n\n```java\n@Verb\npublic Output f(Input input) { }\n```\n\neg.\n\n```java\nimport xyz.block.ftl.Verb;\n\nclass EchoRequest {}\n\nclass EchoResponse {}\n\npublic class EchoClass {\n    @Verb\n    public EchoResponse echo(EchoRequest request) {\n        // ...\n    }\n}\n```\n\n\nBy default verbs are only visible to other verbs in the same module (see [visibility](./visibility) for more information).\n\n## Calling Verbs\n\n\nTo call a verb, import the module's verb client, add it to your verb's signature, then call it. eg.\n\n```java\nimport ftl.time.TimeClient;\nimport xyz.block.ftl.Verb;\n\npublic class EchoClass {\n    @Verb\n    public EchoResponse echo(EchoRequest request, TimeClient time) {\n        TimeResponse response = time.call();\n        // ...\n    }\n}\n```\n\nVerb clients are generated by FTL. If the callee verb belongs to the same module as the caller, you must manually define your\nown client:\n\n```java\npublic interface TimeClient {\n    @VerbClient\n    TimeResponse time();\n}\n```\n\n\n",
			"kotlin": "\n# Verbs\n\n## Defining Verbs\n\n\n\nTo declare a Verb, write a normal Kotlin function with the following signature, annotated with the Kotlin [annotation](https://kotlinlang.org/docs/annotations.html) `@Verb`:\n\n```kotlin\n@Verb\nfun F(In): Out { }\n```\n\neg.\n\n```kotlin\ndata class EchoRequest\ndata class EchoResponse\n\n@Verb\nfun echo(request: EchoRequest): EchoResponse {\n  // ...\n}\n```\n\n\nBy default verbs are only visible to other verbs in the same module (see [visibility](./visibility) for more information).\n\n## Calling Verbs\n\n\nTo call a verb, import the module's verb client, add it to your verb's signature, then `call()` it. eg.\n\n```kotlin\nimport ftl.time.TimeClient\nimport xyz.block.ftl.Verb\n\n@Verb\nfun echo(req: EchoRequest, time: TimeClient): EchoResponse {\n  val response = time.call()\n  // ...\n}\n\nval response = time.call()\n```\n\nVerb clients are generated by FTL. If the callee verb belongs to the same module as the caller, you must manually define your\nown client:\n\n```kotlin\ninterface TimeClient {\n    @VerbClient\n    fun time(): TimeResponse\n}\n```\n\n\n",
			"schema": "\nIn the FTL schema, verbs are declared with their input and output types:\n\n```schema\nmodule example {\n  data EchoRequest {}\n  \n  data EchoResponse {}\n  \n  verb echo(example.EchoRequest) example.EchoResponse\n}\n```\n\nVerbs can be exported to make them callable from other modules:\n\n```schema\nmodule example {\n  export verb echo(example.EchoRequest) example.EchoResponse\n}\n```\n\n\nBy default verbs are only visible to other verbs in the same module (see [visibility](./visibility) for more information).\n\n## Calling Verbs\n\n\nIn the FTL schema, verb calls are represented by the `+calls` annotation:\n\n```schema\nmodule echo {\n  data EchoRequest {}\n  \n  data EchoResponse {}\n  \n  verb echo(example.EchoRequest) example.EchoResponse\n    +calls time.time\n}\n\nmodule time {\n  data TimeRequest {}\n  \n  data TimeResponse {\n    time Time\n  }\n  \n  export verb time(time.TimeRequest) time.TimeResponse\n}\n```\n\nThe `+calls` annotation indicates that the verb calls another verb, in this case the `time` verb from the `time` module.\n\n\n",
	},
	"export": {
			"go": "\n# Visibility\n\nBy default all declarations in FTL are visible only to the module they're declared in. The implicit visibility of types is that of the first verb or other declaration that references it.\n\n## Exporting declarations\n\nExporting a declaration makes it accessible to other modules. Some declarations that are entirely local to a module, such as secrets/config, cannot be exported.\n\nTypes that are transitively referenced by an exported declaration will be automatically exported unless they were already defined but unexported. In this case, an error will be raised and the type must be explicitly exported.\n\n\n\nThe following table describes the go directives used to export the corresponding declaration:\n\n| Symbol        | Export syntax            |\n| ------------- | ------------------------ |\n| Verb          | `//ftl:verb export`      |\n| Data          | `//ftl:data export`      |\n| Enum/Sum type | `//ftl:enum export`      |\n| Typealias     | `//ftl:typealias export` |\n| Topic         | `//ftl:export` [^1]      |\n\n```go\n//ftl:verb export\nfunc Verb(ctx context.Context, in In) (Out, error)\n\n//ftl:typealias export\ntype UserID string\n```\n\n[^1]: By default, topics do not require any annotations as the declaration itself is sufficient.\n\n\n",
			"java": "\n# Visibility\n\nBy default all declarations in FTL are visible only to the module they're declared in. The implicit visibility of types is that of the first verb or other declaration that references it.\n\n## Exporting declarations\n\nExporting a declaration makes it accessible to other modules. Some declarations that are entirely local to a module, such as secrets/config, cannot be exported.\n\nTypes that are transitively referenced by an exported declaration will be automatically exported unless they were already defined but unexported. In this case, an error will be raised and the type must be explicitly exported.\n\n\n\nFor Java the `@Export` annotation can be used to export a declaration:\n\n```java\n@Verb\n@Export\nTimeResponse time()  {\n    // ...\n}\n```\n\n\n",
			"kotlin": "\n# Visibility\n\nBy default all declarations in FTL are visible only to the module they're declared in. The implicit visibility of types is that of the first verb or other declaration that references it.\n\n## Exporting declarations\n\nExporting a declaration makes it accessible to other modules. Some declarations that are entirely local to a module, such as secrets/config, cannot be exported.\n\nTypes that are transitively referenced by an exported declaration will be automatically exported unless they were already defined but unexported. In this case, an error will be raised and the type must be explicitly exported.\n\n\n\nFor Kotlin the `@Export` annotation can be used to export a declaration:\n\n```kotlin\n@Verb\n@Export\nfun time(): TimeResponse {\n    // ...\n}\n```\n\n\n",
			"schema": "\nIn the FTL schema, exported declarations are prefixed with the `export` keyword:\n\n```schema\nmodule example {\n  export data TimeResponse {\n    time Time\n  }\n  \n  export verb time(Unit) example.TimeResponse\n  \n  export topic events example.Event\n  \n  export typealias UserID String\n}\n```\n\nNon-exported declarations are visible only within their module:\n\n```schema\nmodule example {\n  data InternalConfig {\n    setting String\n  }\n  \n  verb internalProcess(example.InternalConfig) Unit\n}\n```\n\n\n",
	},
	"ftl.Config": {
			"go": "\n# Secrets and Configuration\n\n## Configuration\n\nConfiguration values are named, typed values. They are managed by the `ftl config` command-line.\n\n\n\nTo declare a configuration value use the following syntax:\n\n```go\n// Simple string configuration\ntype ApiUrl = ftl.Config[string]\n\n// Type-safe configuration\ntype DefaultUser = ftl.Config[Username]\n```\n\nNote that the name of the configuration value as represented in the FTL schema is the lower camel case version of the type name (e.g., `ApiUrl` becomes `apiUrl`).\n\nConfiguration values can be injected into FTL methods, such as //ftl:verb, HTTP ingress, Cron etc. To inject a configuration value, use the following syntax:\n\n```go\n//ftl:verb\nfunc Hello(ctx context.Context, req Request, defaultUser DefaultUser) error {\n    username := defaultUser.Get(ctx)\n    // ...\n}\n```\n\n\n## Secrets\n\nSecrets are encrypted, named, typed values. They are managed by the `ftl secret` command-line.\n\n\nDeclare a secret with the following:\n\n```go\n// Simple string secret\ntype ApiToken = ftl.Secret[string]\n\n// Type-safe secret\ntype ApiKey = ftl.Secret[Credentials]\n```\n\nLike configuration values, the name of the secret as represented in the FTL schema is the lower camel case version of the type name (e.g., `ApiToken` becomes `apiToken`).\n\nSecrets can be injected into FTL methods, such as //ftl:verb, HTTP ingress, Cron etc. To inject a secret value, use the following syntax:\n\n```go\n//ftl:verb\nfunc CallApi(ctx context.Context, req Request, apiKey ApiKey) error {\n    credentials := apiKey.Get(ctx)\n    // ...\n}\n```\n\n\n## Transforming secrets/configuration\n\nOften, raw secret/configuration values aren't directly useful. For example, raw credentials might be used to create an API client. For those situations `ftl.Map()` can be used to transform a configuration or secret value into another type:\n\n```go\nvar client = ftl.Map(ftl.Secret[Credentials](\"credentials\"),\n                     func(ctx context.Context, creds Credentials) (*api.Client, error) {\n    return api.NewClient(creds)\n})\n```\n\nThis is not currently supported in Kotlin or Java. \n\n",
			"java": "\n# Secrets and Configuration\n\n## Configuration\n\nConfiguration values are named, typed values. They are managed by the `ftl config` command-line.\n\n\n\nConfiguration values can be injected into FTL methods, such as `@Verb`, HTTP ingress, Cron etc. To inject a configuration value, use the following syntax:\n\n```java\n@Export\n@Verb\nHelloResponse hello(HelloRequest helloRequest, @Config(\"defaultUser\") String defaultUser)  {\n    return new HelloResponse(\"Hello, \" + defaultUser);\n}\n```\n\n\n## Secrets\n\nSecrets are encrypted, named, typed values. They are managed by the `ftl secret` command-line.\n\n\nSecrets can be injected into FTL methods, such as `@Verb`, HTTP ingress, Cron etc. To inject a secret value, use the following syntax:\n\n```java\n@Export\n@Verb\nHelloResponse hello(HelloRequest helloRequest, @Secret(\"apiKey\") String apiKey)  {\n    return new HelloResponse(\"Hello, \" + api.call(apiKey));\n}\n```\n\n\n## Transforming secrets/configuration\n\nOften, raw secret/configuration values aren't directly useful. For example, raw credentials might be used to create an API client. For those situations `ftl.Map()` can be used to transform a configuration or secret value into another type:\n\n```go\nvar client = ftl.Map(ftl.Secret[Credentials](\"credentials\"),\n                     func(ctx context.Context, creds Credentials) (*api.Client, error) {\n    return api.NewClient(creds)\n})\n```\n\nThis is not currently supported in Kotlin or Java. \n\n",
			"kotlin": "\n# Secrets and Configuration\n\n## Configuration\n\nConfiguration values are named, typed values. They are managed by the `ftl config` command-line.\n\n\n\nConfiguration values can be injected into FTL methods, such as `@Verb`, HTTP ingress, Cron etc. To inject a configuration value, use the following syntax:\n\n```kotlin\n@Export\n@Verb\nfun hello(helloRequest: HelloRequest, @Config(\"defaultUser\") defaultUser: String): HelloResponse {\n    return HelloResponse(\"Hello, $defaultUser\")\n}\n```\n\n\n## Secrets\n\nSecrets are encrypted, named, typed values. They are managed by the `ftl secret` command-line.\n\n\nSecrets can be injected into FTL methods, such as `@Verb`, HTTP ingress, Cron etc. To inject a secret value, use the following syntax:\n\n```kotlin\n@Export\n@Verb\nfun hello(helloRequest: HelloRequest, @Secret(\"apiKey\") apiKey: String): HelloResponse {\n    return HelloResponse(\"Hello, ${api.call(apiKey)}\")\n}\n```\n\n\n## Transforming secrets/configuration\n\nOften, raw secret/configuration values aren't directly useful. For example, raw credentials might be used to create an API client. For those situations `ftl.Map()` can be used to transform a configuration or secret value into another type:\n\n```go\nvar client = ftl.Map(ftl.Secret[Credentials](\"credentials\"),\n                     func(ctx context.Context, creds Credentials) (*api.Client, error) {\n    return api.NewClient(creds)\n})\n```\n\nThis is not currently supported in Kotlin or Java. \n\n",
			"schema": "\nIn the FTL schema, configuration values are declared as follows:\n\n```schema\nmodule example {\n  config defaultUser String\n  \n  verb hello(Unit) String\n    +config example.defaultUser\n}\n```\n\nConfiguration values have a name, a type, and can be injected into verbs using the `+config` annotation.\n\n## Secrets\n\nSecrets are encrypted, named, typed values. They are managed by the `ftl secret` command-line.\n\n\nIn the FTL schema, secrets are declared as follows:\n\n```schema\nmodule example {\n  // Secret declaration\n  secret apiToken String\n  secret apiKey example.Credentials\n  \n  // Using a secret in a verb\n  verb callApi(example.Request) Unit\n    +secret apiKey\n}\n```\n\nSecrets have a name, a type, and can be injected into verbs using the `+secret` annotation.\n\n## Transforming secrets/configuration\n\nOften, raw secret/configuration values aren't directly useful. For example, raw credentials might be used to create an API client. For those situations `ftl.Map()` can be used to transform a configuration or secret value into another type:\n\n```go\nvar client = ftl.Map(ftl.Secret[Credentials](\"credentials\"),\n                     func(ctx context.Context, creds Credentials) (*api.Client, error) {\n    return api.NewClient(creds)\n})\n```\n\nThis is not currently supported in Kotlin or Java. \n\n",
	},
	"ftl.DatabaseHandle": {
			"go": "\n# Databases\n\nFTL has support for Postgresql and MySQL databases, including support for automatic provisioning and migrations. \n\n\n\nYour database is automatically declared by following a specific directory structure for your SQL files. No additional configuration is needed - just create the directory structure and FTL will handle the rest. See the [Creating a New Database](#creating-a-new-database) section for CLI shortcuts.\n\n\n## Creating a New Database\n\nTo create a new database with the required directory structure, you can use the `ftl postgres new` or `ftl mysql new` command. The format of the command is:\n\n```bash\nftl <engine> new <module>.<datasource>\n```\n\nWhere:\n- `<engine>` is either `mysql` or `postgres`\n- `<module>.<datasource>` is the qualified name of the datasource (module name can be omitted if in a single module directory)\n\nFor example:\n```bash\nftl mysql new mymodule.mydb    # Create a MySQL database named \"mydb\" in module \"mymodule\"\nftl postgres new mydb          # Create a PostgreSQL database named \"mydb\" in the current module\n```\n\nThis command will:\n1. Create the appropriate directory structure\n2. Create an initial migration file in the `schema` directory\n\n## SQL File Structure\n\nIn order to be discoverable by FTL, the SQL files in your project must follow a specific directory structure. FTL supports two database engines, declared via the directory hierarchy as either `mysql` or `postgres`:\n\n\nFor Go projects, SQL files must be located in:\n```\ndb/\n  ├── mysql/           # must be exactly \"mysql\" or \"postgres\"\n  │   └── mydb/        # database name\n  │       ├── schema/  # contains migration files\n  │       └── queries/ # contains query files\n```\n\nThe presence of a `schema` directory under your database name automatically declares the database in FTL.\n\n\n### Schema Directory\n\nThe `schema` directory contains all your database migration `.sql` files. These files are used to create and modify your database schema.\n\n### Queries Directory\n\nThe `queries` directory contains `.sql` files with any SQL queries you would like generated as FTL verbs for use in your module. These queries must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/). FTL will automatically lift these queries into the module schema and provide a type-safe client to execute each query.\n\nFind more information in the [Using Generated Query Clients](#using-generated-query-clients) section below.\n\n## Provisioning\n\nFTL includes support for automatically provisioning databases. The actual backing implementation is\nextensible, and presently we include support for both local development provisioning using docker,\nand cloud formations based provisioning for AWS deployments. When using `ftl dev` a docker container\nwill automatically be spun up for each datasource that has been defined, and FTL will automatically\nhandle configuration. The same applies when deploying to an AWS cluster with cloud formations\nprovisioning setup.\n\n## Migrations\n\nFTL includes support for automatically running migrations on databases. This is provided by [dbmate](https://github.com/amacneil/dbmate). \n\nTo create additional migrations you can use the `ftl postgres new migration` or `ftl mysql new migration` command. The format of the command is `ftl <engine> new migration <module>.<datasource> <migration-name>`.\n\nThe module name can be omitted if the current working directory only contains a single module.\n\nE.g. to create a new migration called `init` for the `testdb` datasource in the `mysql` module you would run `ftl mysql new migration mysql.testdb init`.\n\nWhen the modules are provisioned FTL will automatically run these migrations for you. \n\n## Connecting with your DB\n\nThere are two supported ways to interact with your database in FTL: using the generated database handle to perform raw queries, or using generated query clients.\n\n### Using the Generated Database Handle\n\n\nOnce you've declared a database, FTL automatically generates a database handle that provides direct access to the underlying connection. You can use this to execute raw SQL queries (where `MydbHandle` is the generated handle type for the `mydb` datasource):\n\n```go\n//ftl:verb export\nfunc Query(ctx context.Context, db MydbHandle) ([]string, error) {\n\trows, err := db.QueryContext(ctx, \"SELECT data FROM requests\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer rows.Close()\n\tvar items []string\n\tfor rows.Next() {\n\t\tvar i string\n\t\tif err := rows.Scan(&i); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\titems = append(items, i)\n\t}\n\tif err := rows.Close(); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := rows.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn items, nil\n}\n```\n\n\n### Using Generated Query Clients\n\nFor better type safety and maintainability, FTL can automatically generate type-safe query clients from SQL files in your `queries` directory. Your SQL files must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/) to specify the type of query and its parameters. For example:\n\n```sql\n-- name: GetUser :one\nSELECT id, name, email\nFROM users\nWHERE id = $1;\n\n-- name: ListUsers :many\nSELECT id, name, email\nFROM users\nORDER BY name;\n\n-- name: CreateUser :exec\nINSERT INTO users (name, email)\nVALUES ($1, $2);\n```\n\nThese queries will be automatically converted into FTL verbs with corresponding generated clients that you can inject into your verbs just like any other verb client. For example:\n\n\n```go\n//ftl:verb export\nfunc GetEmail(ctx context.Context, id int, query GetUserClient) (string, error) {\n\tresult, err := query(ctx, id)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn result.Email, nil\n}\n```\n\n\n## Transactions\n\nFTL provides transaction support through verb annotations. When a verb is marked as transactional, FTL will automatically manage the transaction boundaries - beginning the transaction when the verb is called, committing if the verb completes successfully, and rolling back if any errors occur during execution.\n\n\nTo mark a verb as transactional, use the `//ftl:transaction` comment directive:\n\n```go\ntype CreateUserRequest struct {\n    Name  string\n    Email string\n}\n\n//ftl:transaction\nfunc CreateUser(ctx context.Context, req CreateUserRequest, db MydbHandle, createAddress CreateAddressClient) error {\n    // All database operations within this verb will be executed in a single transaction\n    result, err := db.Get(ctx).Exec(\"INSERT INTO users (name, email) VALUES ($1, $2)\", req.Name, req.Email)\n    if err != nil {\n        return err // Transaction will be rolled back\n    }\n    \n    userId, err := result.LastInsertId()\n    if err != nil {\n        return err // Transaction will be rolled back\n    }\n    \n    // createAddress is a generated query client from a SQL file in queries/\n    err = createAddress(ctx, AddressRequest{UserId: userId})\n    if err != nil {\n        return err // Transaction will be rolled back\n    }\n    \n    return nil // Transaction will be committed\n}\n```\n\n\n### Transaction Rules and Limitations\n\nWhen using transactions, FTL enforces the following restrictions:\n\n1. **Database Usage**: Transaction verbs must use at least one database resource (either through a database handle or SQL query clients). FTL infers which database to open the transaction against based on these usages.\n\n2. **Single Database**: FTL only supports transactions against a single database. Two-phase commits across multiple databases are not supported.\n\n3. **No Nesting**: Transaction verbs cannot be nested. This means you cannot inject another transaction verb's client as a resource within a transaction verb.\n\n4. **Module Scope**: Transaction verbs can only call other verbs within the same module. Calls to external verbs from other modules are not allowed within a transaction.\n\n5. **Automatic Management**: Transaction boundaries are automatically managed by FTL:\n   - The transaction begins when the verb is called\n   - The transaction commits if the verb completes successfully\n   - The transaction rolls back if any errors occur during execution\n\n",
			"java": "\n# Databases\n\nFTL has support for Postgresql and MySQL databases, including support for automatic provisioning and migrations. \n\n\n\nYour database is automatically declared by following a specific directory structure for your SQL files. No additional configuration is needed - just create the directory structure and FTL will handle the rest. See the [Creating a New Database](#creating-a-new-database) section for CLI shortcuts.\n\n\n## Creating a New Database\n\nTo create a new database with the required directory structure, you can use the `ftl postgres new` or `ftl mysql new` command. The format of the command is:\n\n```bash\nftl <engine> new <module>.<datasource>\n```\n\nWhere:\n- `<engine>` is either `mysql` or `postgres`\n- `<module>.<datasource>` is the qualified name of the datasource (module name can be omitted if in a single module directory)\n\nFor example:\n```bash\nftl mysql new mymodule.mydb    # Create a MySQL database named \"mydb\" in module \"mymodule\"\nftl postgres new mydb          # Create a PostgreSQL database named \"mydb\" in the current module\n```\n\nThis command will:\n1. Create the appropriate directory structure\n2. Create an initial migration file in the `schema` directory\n\n## SQL File Structure\n\nIn order to be discoverable by FTL, the SQL files in your project must follow a specific directory structure. FTL supports two database engines, declared via the directory hierarchy as either `mysql` or `postgres`:\n\n\nFor Java projects, SQL files must be located in:\n```\nsrc/main/resources/\n  └── db/\n      ├── mysql/           # must be exactly \"mysql\" or \"postgres\"\n      │   └── mydb/        # database name\n      │       ├── schema/  # contains migration files\n      │       └── queries/ # contains query files\n```\n\nThe presence of a `schema` directory under your database name automatically declares the database in FTL.\n\n\n### Schema Directory\n\nThe `schema` directory contains all your database migration `.sql` files. These files are used to create and modify your database schema.\n\n### Queries Directory\n\nThe `queries` directory contains `.sql` files with any SQL queries you would like generated as FTL verbs for use in your module. These queries must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/). FTL will automatically lift these queries into the module schema and provide a type-safe client to execute each query.\n\nFind more information in the [Using Generated Query Clients](#using-generated-query-clients) section below.\n\n## Provisioning\n\nFTL includes support for automatically provisioning databases. The actual backing implementation is\nextensible, and presently we include support for both local development provisioning using docker,\nand cloud formations based provisioning for AWS deployments. When using `ftl dev` a docker container\nwill automatically be spun up for each datasource that has been defined, and FTL will automatically\nhandle configuration. The same applies when deploying to an AWS cluster with cloud formations\nprovisioning setup.\n\n## Migrations\n\nFTL includes support for automatically running migrations on databases. This is provided by [dbmate](https://github.com/amacneil/dbmate). \n\nTo create additional migrations you can use the `ftl postgres new migration` or `ftl mysql new migration` command. The format of the command is `ftl <engine> new migration <module>.<datasource> <migration-name>`.\n\nThe module name can be omitted if the current working directory only contains a single module.\n\nE.g. to create a new migration called `init` for the `testdb` datasource in the `mysql` module you would run `ftl mysql new migration mysql.testdb init`.\n\nWhen the modules are provisioned FTL will automatically run these migrations for you. \n\n## Connecting with your DB\n\nThere are two supported ways to interact with your database in FTL: using the generated database handle to perform raw queries, or using generated query clients.\n\n### Using the Generated Database Handle\n\n\t\n\tTBD\n\n\n### Using Generated Query Clients\n\nFor better type safety and maintainability, FTL can automatically generate type-safe query clients from SQL files in your `queries` directory. Your SQL files must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/) to specify the type of query and its parameters. For example:\n\n```sql\n-- name: GetUser :one\nSELECT id, name, email\nFROM users\nWHERE id = $1;\n\n-- name: ListUsers :many\nSELECT id, name, email\nFROM users\nORDER BY name;\n\n-- name: CreateUser :exec\nINSERT INTO users (name, email)\nVALUES ($1, $2);\n```\n\nThese queries will be automatically converted into FTL verbs with corresponding generated clients that you can inject into your verbs just like any other verb client. For example:\n\n\t\n```java\n@Verb\npublic String getEmail(int id, GetUserClient query) {\n    UserResult result = query.getUser(id);\n    return result.getEmail();\n}\n```\n\n\n## Transactions\n\nFTL provides transaction support through verb annotations. When a verb is marked as transactional, FTL will automatically manage the transaction boundaries - beginning the transaction when the verb is called, committing if the verb completes successfully, and rolling back if any errors occur during execution.\n\n\nTo mark a verb as transactional, use the `@Transactional` annotation:\n\n```java\npublic class CreateUserRequest {\n    private String name;\n    private String email;\n}\n\npublic class UserService {\n    @Transactional\n    public void createUser(\n        CreateUserRequest request,\n        CreateAddressClient createAddress  // Generated query client\n    ) { \n        // createAddress is a generated query client from a SQL file in queries/\n        createAddress.createAddress(new AddressRequest(userId));\n        // Transaction commits if we reach here without errors\n        // Any errors will cause automatic rollback\n    }\n}\n```\n\n\n### Transaction Rules and Limitations\n\nWhen using transactions, FTL enforces the following restrictions:\n\n1. **Database Usage**: Transaction verbs must use at least one database resource (either through a database handle or SQL query clients). FTL infers which database to open the transaction against based on these usages.\n\n2. **Single Database**: FTL only supports transactions against a single database. Two-phase commits across multiple databases are not supported.\n\n3. **No Nesting**: Transaction verbs cannot be nested. This means you cannot inject another transaction verb's client as a resource within a transaction verb.\n\n4. **Module Scope**: Transaction verbs can only call other verbs within the same module. Calls to external verbs from other modules are not allowed within a transaction.\n\n5. **Automatic Management**: Transaction boundaries are automatically managed by FTL:\n   - The transaction begins when the verb is called\n   - The transaction commits if the verb completes successfully\n   - The transaction rolls back if any errors occur during execution\n\n",
			"kotlin": "\n# Databases\n\nFTL has support for Postgresql and MySQL databases, including support for automatic provisioning and migrations. \n\n\n\nYour database is automatically declared by following a specific directory structure for your SQL files. No additional configuration is needed - just create the directory structure and FTL will handle the rest. See the [Creating a New Database](#creating-a-new-database) section for CLI shortcuts.\n\n\n## Creating a New Database\n\nTo create a new database with the required directory structure, you can use the `ftl postgres new` or `ftl mysql new` command. The format of the command is:\n\n```bash\nftl <engine> new <module>.<datasource>\n```\n\nWhere:\n- `<engine>` is either `mysql` or `postgres`\n- `<module>.<datasource>` is the qualified name of the datasource (module name can be omitted if in a single module directory)\n\nFor example:\n```bash\nftl mysql new mymodule.mydb    # Create a MySQL database named \"mydb\" in module \"mymodule\"\nftl postgres new mydb          # Create a PostgreSQL database named \"mydb\" in the current module\n```\n\nThis command will:\n1. Create the appropriate directory structure\n2. Create an initial migration file in the `schema` directory\n\n## SQL File Structure\n\nIn order to be discoverable by FTL, the SQL files in your project must follow a specific directory structure. FTL supports two database engines, declared via the directory hierarchy as either `mysql` or `postgres`:\n\n\nFor Kotlin projects, SQL files must be located in:\n```\nsrc/main/resources/\n  └── db/\n      ├── mysql/           # must be exactly \"mysql\" or \"postgres\"\n      │   └── mydb/        # database name\n      │       ├── schema/  # contains migration files\n      │       └── queries/ # contains query files\n```\n\nThe presence of a `schema` directory under your database name automatically declares the database in FTL.\n\n\n### Schema Directory\n\nThe `schema` directory contains all your database migration `.sql` files. These files are used to create and modify your database schema.\n\n### Queries Directory\n\nThe `queries` directory contains `.sql` files with any SQL queries you would like generated as FTL verbs for use in your module. These queries must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/). FTL will automatically lift these queries into the module schema and provide a type-safe client to execute each query.\n\nFind more information in the [Using Generated Query Clients](#using-generated-query-clients) section below.\n\n## Provisioning\n\nFTL includes support for automatically provisioning databases. The actual backing implementation is\nextensible, and presently we include support for both local development provisioning using docker,\nand cloud formations based provisioning for AWS deployments. When using `ftl dev` a docker container\nwill automatically be spun up for each datasource that has been defined, and FTL will automatically\nhandle configuration. The same applies when deploying to an AWS cluster with cloud formations\nprovisioning setup.\n\n## Migrations\n\nFTL includes support for automatically running migrations on databases. This is provided by [dbmate](https://github.com/amacneil/dbmate). \n\nTo create additional migrations you can use the `ftl postgres new migration` or `ftl mysql new migration` command. The format of the command is `ftl <engine> new migration <module>.<datasource> <migration-name>`.\n\nThe module name can be omitted if the current working directory only contains a single module.\n\nE.g. to create a new migration called `init` for the `testdb` datasource in the `mysql` module you would run `ftl mysql new migration mysql.testdb init`.\n\nWhen the modules are provisioned FTL will automatically run these migrations for you. \n\n## Connecting with your DB\n\nThere are two supported ways to interact with your database in FTL: using the generated database handle to perform raw queries, or using generated query clients.\n\n### Using the Generated Database Handle\n\n\n\tTBD\n\n\n### Using Generated Query Clients\n\nFor better type safety and maintainability, FTL can automatically generate type-safe query clients from SQL files in your `queries` directory. Your SQL files must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/) to specify the type of query and its parameters. For example:\n\n```sql\n-- name: GetUser :one\nSELECT id, name, email\nFROM users\nWHERE id = $1;\n\n-- name: ListUsers :many\nSELECT id, name, email\nFROM users\nORDER BY name;\n\n-- name: CreateUser :exec\nINSERT INTO users (name, email)\nVALUES ($1, $2);\n```\n\nThese queries will be automatically converted into FTL verbs with corresponding generated clients that you can inject into your verbs just like any other verb client. For example:\n\n\n```kotlin\n@Verb\nfun getEmail(id: Int, query: GetUserClient): String {\n    val result = query.getUser(id)\n    return result.email\n}\n```\n\n\n## Transactions\n\nFTL provides transaction support through verb annotations. When a verb is marked as transactional, FTL will automatically manage the transaction boundaries - beginning the transaction when the verb is called, committing if the verb completes successfully, and rolling back if any errors occur during execution.\n\n\nTo mark a verb as transactional, use the `@Transactional` annotation:\n\n```kotlin\ndata class CreateUserRequest(\n    val name: String,\n    val email: String\n)\n\n@Transactional\nfun createUser(\n    request: CreateUserRequest,\n    createAddress: CreateAddressClient // Generated query client\n): Unit {    \n    // createAddress is a generated query client from a SQL file in queries/\n    createAddress.createAddress(AddressRequest(userId = userId))\n    // Transaction commits if we reach here without errors\n    // Any errors will cause automatic rollback\n}\n```\n\n\n### Transaction Rules and Limitations\n\nWhen using transactions, FTL enforces the following restrictions:\n\n1. **Database Usage**: Transaction verbs must use at least one database resource (either through a database handle or SQL query clients). FTL infers which database to open the transaction against based on these usages.\n\n2. **Single Database**: FTL only supports transactions against a single database. Two-phase commits across multiple databases are not supported.\n\n3. **No Nesting**: Transaction verbs cannot be nested. This means you cannot inject another transaction verb's client as a resource within a transaction verb.\n\n4. **Module Scope**: Transaction verbs can only call other verbs within the same module. Calls to external verbs from other modules are not allowed within a transaction.\n\n5. **Automatic Management**: Transaction boundaries are automatically managed by FTL:\n   - The transaction begins when the verb is called\n   - The transaction commits if the verb completes successfully\n   - The transaction rolls back if any errors occur during execution\n\n",
			"schema": "\nIn the FTL schema, databases are represented using the `database` keyword with the engine type and name:\n\n```schema\nmodule example {\n  // Database declaration\n  database postgres testdb  \n    +migration sha256:59b989063b6de57a1b6867e8ad7915109c9b8632616118c6ef23e4439cf17f8e\n  \n  // Data structures for database operations\n  data CreateUserParams {\n    name String\n    email String\n  }\n  \n  data UserResult {\n    id Int +sql column \"users\".\"id\"\n    name String +sql column \"users\".\"name\"\n    email String +sql column \"users\".\"email\"\n  }\n  \n  // Query that returns a single row\n  verb getUser(Int) example.UserResult\n    +database calls example.testdb\n    +sql query one \"SELECT id, name, email FROM users WHERE id = ?\"\n  \n  // Query that returns multiple rows\n  verb listUsers(Unit) [example.UserResult]\n    +database calls example.testdb\n    +sql query many \"SELECT id, name, email FROM users ORDER BY name\"\n  \n  // Query that performs an action but doesn't return data\n  verb createUser(example.CreateUserParams) Unit\n    +database calls example.testdb\n    +sql query exec \"INSERT INTO users (name, email) VALUES (?, ?)\"\n  \n  // Custom verb that uses a database query\n  export verb getUserEmail(Int) String\n}\n```\n\nThe schema representation includes:\n1. A `database` declaration with the engine type (`postgres` or `mysql`) and database name\n2. The `+migration` annotation with a SHA256 hash of the migration files\n3. Data structures with `+sql column` annotations mapping to database columns\n4. Verb declarations with `+database calls` and `+sql query` annotations specifying the query type and SQL statement\n\n\n## Creating a New Database\n\nTo create a new database with the required directory structure, you can use the `ftl postgres new` or `ftl mysql new` command. The format of the command is:\n\n```bash\nftl <engine> new <module>.<datasource>\n```\n\nWhere:\n- `<engine>` is either `mysql` or `postgres`\n- `<module>.<datasource>` is the qualified name of the datasource (module name can be omitted if in a single module directory)\n\nFor example:\n```bash\nftl mysql new mymodule.mydb    # Create a MySQL database named \"mydb\" in module \"mymodule\"\nftl postgres new mydb          # Create a PostgreSQL database named \"mydb\" in the current module\n```\n\nThis command will:\n1. Create the appropriate directory structure\n2. Create an initial migration file in the `schema` directory\n\n## SQL File Structure\n\nIn order to be discoverable by FTL, the SQL files in your project must follow a specific directory structure. FTL supports two database engines, declared via the directory hierarchy as either `mysql` or `postgres`:\n\n\n### Schema Directory\n\nThe `schema` directory contains all your database migration `.sql` files. These files are used to create and modify your database schema.\n\n### Queries Directory\n\nThe `queries` directory contains `.sql` files with any SQL queries you would like generated as FTL verbs for use in your module. These queries must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/). FTL will automatically lift these queries into the module schema and provide a type-safe client to execute each query.\n\nFind more information in the [Using Generated Query Clients](#using-generated-query-clients) section below.\n\n## Provisioning\n\nFTL includes support for automatically provisioning databases. The actual backing implementation is\nextensible, and presently we include support for both local development provisioning using docker,\nand cloud formations based provisioning for AWS deployments. When using `ftl dev` a docker container\nwill automatically be spun up for each datasource that has been defined, and FTL will automatically\nhandle configuration. The same applies when deploying to an AWS cluster with cloud formations\nprovisioning setup.\n\n## Migrations\n\nFTL includes support for automatically running migrations on databases. This is provided by [dbmate](https://github.com/amacneil/dbmate). \n\nTo create additional migrations you can use the `ftl postgres new migration` or `ftl mysql new migration` command. The format of the command is `ftl <engine> new migration <module>.<datasource> <migration-name>`.\n\nThe module name can be omitted if the current working directory only contains a single module.\n\nE.g. to create a new migration called `init` for the `testdb` datasource in the `mysql` module you would run `ftl mysql new migration mysql.testdb init`.\n\nWhen the modules are provisioned FTL will automatically run these migrations for you. \n\n## Connecting with your DB\n\nThere are two supported ways to interact with your database in FTL: using the generated database handle to perform raw queries, or using generated query clients.\n\n### Using the Generated Database Handle\n\n\nIn the FTL schema, the database handle is represented by the `+database calls` annotation on verbs:\n\n```schema\nmodule example {\n  // Database declaration\n  database postgres mydb\n    +migration sha256:59b989063b6de57a1b6867e8ad7915109c9b8632616118c6ef23e4439cf17f8e\n  \n  // Verb that uses the database handle directly\n  export verb query(Unit) [String]\n    +database calls example.mydb\n}\n```\n\nWhen you use a database handle in your code, you're directly accessing the underlying database connection. The FTL compiler automatically generates the appropriate handle type based on the database declaration.\n\n\n### Using Generated Query Clients\n\nFor better type safety and maintainability, FTL can automatically generate type-safe query clients from SQL files in your `queries` directory. Your SQL files must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/) to specify the type of query and its parameters. For example:\n\n```sql\n-- name: GetUser :one\nSELECT id, name, email\nFROM users\nWHERE id = $1;\n\n-- name: ListUsers :many\nSELECT id, name, email\nFROM users\nORDER BY name;\n\n-- name: CreateUser :exec\nINSERT INTO users (name, email)\nVALUES ($1, $2);\n```\n\nThese queries will be automatically converted into FTL verbs with corresponding generated clients that you can inject into your verbs just like any other verb client. For example:\n\n\nIn the FTL schema, the generated query clients are represented as verbs with the `+database calls` and `+sql query` annotations:\n\n```schema\nmodule example {\n  // Database declaration\n  database postgres testdb\n    +migration sha256:59b989063b6de57a1b6867e8ad7915109c9b8632616118c6ef23e4439cf17f8e\n  \n  // Data structures for query results and parameters\n  data UserResult {\n    id Int +sql column \"users\".\"id\"\n    name String +sql column \"users\".\"name\"\n    email String +sql column \"users\".\"email\"\n  }\n  \n  data CreateUserParams {\n    name String\n    email String\n  }\n  \n  // Query that returns a single row\n  verb getUser(Int) example.UserResult\n    +database calls example.testdb\n    +sql query one \"SELECT id, name, email FROM users WHERE id = ?\"\n  \n  // Query that returns multiple rows\n  verb listUsers(Unit) [example.UserResult]\n    +database calls example.testdb\n    +sql query many \"SELECT id, name, email FROM users ORDER BY name\"\n  \n  // Query that performs an action but doesn't return data\n  verb createUser(example.CreateUserParams) Unit\n    +database calls example.testdb\n    +sql query exec \"INSERT INTO users (name, email) VALUES (?, ?)\"\n  \n  // Custom verb that uses the generated query client\n  export verb getUserEmail(Int) String\n    +calls example.getUser\n}\n```\n\nWhen you use a generated query client in your code, you're calling a verb that has been automatically generated from your SQL query. FTL handles the mapping between your SQL queries and the generated verbs.\n\n\n## Transactions\n\nFTL provides transaction support through verb annotations. When a verb is marked as transactional, FTL will automatically manage the transaction boundaries - beginning the transaction when the verb is called, committing if the verb completes successfully, and rolling back if any errors occur during execution.\n\n\nIn the FTL schema, transaction verbs are represented with the `+transaction` annotation:\n\n```schema\nmodule example {\n  // Database declaration\n  database postgres mydb\n    +migration sha256:59b989063b6de57a1b6867e8ad7915109c9b8632616118c6ef23e4439cf17f8e\n  \n  data CreateUserRequest {\n    name String\n    email String\n  }\n  \n  data AddressRequest {\n    userId Int +sql column \"addresses\".\"id\"\n    street String +sql column \"addresses\".\"street\"\n    city String +sql column \"addresses\".\"city\"\n  }\n  \n  // Generated query client from SQL file\n  verb createAddress(example.AddressRequest) Unit\n    +database calls example.mydb\n    +sql query exec \"INSERT INTO addresses (user_id, street, city) VALUES (?, ?, ?)\"\n  \n  // Transaction verb that uses both direct database access and a generated query client\n  verb createUser(example.CreateUserRequest) Unit\n    +transaction\n    +database calls example.mydb\n    +calls example.createAddress\n}\n```\n\n\n### Transaction Rules and Limitations\n\nWhen using transactions, FTL enforces the following restrictions:\n\n1. **Database Usage**: Transaction verbs must use at least one database resource (either through a database handle or SQL query clients). FTL infers which database to open the transaction against based on these usages.\n\n2. **Single Database**: FTL only supports transactions against a single database. Two-phase commits across multiple databases are not supported.\n\n3. **No Nesting**: Transaction verbs cannot be nested. This means you cannot inject another transaction verb's client as a resource within a transaction verb.\n\n4. **Module Scope**: Transaction verbs can only call other verbs within the same module. Calls to external verbs from other modules are not allowed within a transaction.\n\n5. **Automatic Management**: Transaction boundaries are automatically managed by FTL:\n   - The transaction begins when the verb is called\n   - The transaction commits if the verb completes successfully\n   - The transaction rolls back if any errors occur during execution\n\n",
	},
	"ftl.DefaultMySQLDatabaseConfig": {
			"go": "\n# Databases\n\nFTL has support for Postgresql and MySQL databases, including support for automatic provisioning and migrations. \n\n\n\nYour database is automatically declared by following a specific directory structure for your SQL files. No additional configuration is needed - just create the directory structure and FTL will handle the rest. See the [Creating a New Database](#creating-a-new-database) section for CLI shortcuts.\n\n\n## Creating a New Database\n\nTo create a new database with the required directory structure, you can use the `ftl postgres new` or `ftl mysql new` command. The format of the command is:\n\n```bash\nftl <engine> new <module>.<datasource>\n```\n\nWhere:\n- `<engine>` is either `mysql` or `postgres`\n- `<module>.<datasource>` is the qualified name of the datasource (module name can be omitted if in a single module directory)\n\nFor example:\n```bash\nftl mysql new mymodule.mydb    # Create a MySQL database named \"mydb\" in module \"mymodule\"\nftl postgres new mydb          # Create a PostgreSQL database named \"mydb\" in the current module\n```\n\nThis command will:\n1. Create the appropriate directory structure\n2. Create an initial migration file in the `schema` directory\n\n## SQL File Structure\n\nIn order to be discoverable by FTL, the SQL files in your project must follow a specific directory structure. FTL supports two database engines, declared via the directory hierarchy as either `mysql` or `postgres`:\n\n\nFor Go projects, SQL files must be located in:\n```\ndb/\n  ├── mysql/           # must be exactly \"mysql\" or \"postgres\"\n  │   └── mydb/        # database name\n  │       ├── schema/  # contains migration files\n  │       └── queries/ # contains query files\n```\n\nThe presence of a `schema` directory under your database name automatically declares the database in FTL.\n\n\n### Schema Directory\n\nThe `schema` directory contains all your database migration `.sql` files. These files are used to create and modify your database schema.\n\n### Queries Directory\n\nThe `queries` directory contains `.sql` files with any SQL queries you would like generated as FTL verbs for use in your module. These queries must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/). FTL will automatically lift these queries into the module schema and provide a type-safe client to execute each query.\n\nFind more information in the [Using Generated Query Clients](#using-generated-query-clients) section below.\n\n## Provisioning\n\nFTL includes support for automatically provisioning databases. The actual backing implementation is\nextensible, and presently we include support for both local development provisioning using docker,\nand cloud formations based provisioning for AWS deployments. When using `ftl dev` a docker container\nwill automatically be spun up for each datasource that has been defined, and FTL will automatically\nhandle configuration. The same applies when deploying to an AWS cluster with cloud formations\nprovisioning setup.\n\n## Migrations\n\nFTL includes support for automatically running migrations on databases. This is provided by [dbmate](https://github.com/amacneil/dbmate). \n\nTo create additional migrations you can use the `ftl postgres new migration` or `ftl mysql new migration` command. The format of the command is `ftl <engine> new migration <module>.<datasource> <migration-name>`.\n\nThe module name can be omitted if the current working directory only contains a single module.\n\nE.g. to create a new migration called `init` for the `testdb` datasource in the `mysql` module you would run `ftl mysql new migration mysql.testdb init`.\n\nWhen the modules are provisioned FTL will automatically run these migrations for you. \n\n## Connecting with your DB\n\nThere are two supported ways to interact with your database in FTL: using the generated database handle to perform raw queries, or using generated query clients.\n\n### Using the Generated Database Handle\n\n\nOnce you've declared a database, FTL automatically generates a database handle that provides direct access to the underlying connection. You can use this to execute raw SQL queries (where `MydbHandle` is the generated handle type for the `mydb` datasource):\n\n```go\n//ftl:verb export\nfunc Query(ctx context.Context, db MydbHandle) ([]string, error) {\n\trows, err := db.QueryContext(ctx, \"SELECT data FROM requests\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer rows.Close()\n\tvar items []string\n\tfor rows.Next() {\n\t\tvar i string\n\t\tif err := rows.Scan(&i); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\titems = append(items, i)\n\t}\n\tif err := rows.Close(); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := rows.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn items, nil\n}\n```\n\n\n### Using Generated Query Clients\n\nFor better type safety and maintainability, FTL can automatically generate type-safe query clients from SQL files in your `queries` directory. Your SQL files must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/) to specify the type of query and its parameters. For example:\n\n```sql\n-- name: GetUser :one\nSELECT id, name, email\nFROM users\nWHERE id = $1;\n\n-- name: ListUsers :many\nSELECT id, name, email\nFROM users\nORDER BY name;\n\n-- name: CreateUser :exec\nINSERT INTO users (name, email)\nVALUES ($1, $2);\n```\n\nThese queries will be automatically converted into FTL verbs with corresponding generated clients that you can inject into your verbs just like any other verb client. For example:\n\n\n```go\n//ftl:verb export\nfunc GetEmail(ctx context.Context, id int, query GetUserClient) (string, error) {\n\tresult, err := query(ctx, id)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn result.Email, nil\n}\n```\n\n\n## Transactions\n\nFTL provides transaction support through verb annotations. When a verb is marked as transactional, FTL will automatically manage the transaction boundaries - beginning the transaction when the verb is called, committing if the verb completes successfully, and rolling back if any errors occur during execution.\n\n\nTo mark a verb as transactional, use the `//ftl:transaction` comment directive:\n\n```go\ntype CreateUserRequest struct {\n    Name  string\n    Email string\n}\n\n//ftl:transaction\nfunc CreateUser(ctx context.Context, req CreateUserRequest, db MydbHandle, createAddress CreateAddressClient) error {\n    // All database operations within this verb will be executed in a single transaction\n    result, err := db.Get(ctx).Exec(\"INSERT INTO users (name, email) VALUES ($1, $2)\", req.Name, req.Email)\n    if err != nil {\n        return err // Transaction will be rolled back\n    }\n    \n    userId, err := result.LastInsertId()\n    if err != nil {\n        return err // Transaction will be rolled back\n    }\n    \n    // createAddress is a generated query client from a SQL file in queries/\n    err = createAddress(ctx, AddressRequest{UserId: userId})\n    if err != nil {\n        return err // Transaction will be rolled back\n    }\n    \n    return nil // Transaction will be committed\n}\n```\n\n\n### Transaction Rules and Limitations\n\nWhen using transactions, FTL enforces the following restrictions:\n\n1. **Database Usage**: Transaction verbs must use at least one database resource (either through a database handle or SQL query clients). FTL infers which database to open the transaction against based on these usages.\n\n2. **Single Database**: FTL only supports transactions against a single database. Two-phase commits across multiple databases are not supported.\n\n3. **No Nesting**: Transaction verbs cannot be nested. This means you cannot inject another transaction verb's client as a resource within a transaction verb.\n\n4. **Module Scope**: Transaction verbs can only call other verbs within the same module. Calls to external verbs from other modules are not allowed within a transaction.\n\n5. **Automatic Management**: Transaction boundaries are automatically managed by FTL:\n   - The transaction begins when the verb is called\n   - The transaction commits if the verb completes successfully\n   - The transaction rolls back if any errors occur during execution\n\n",
			"java": "\n# Databases\n\nFTL has support for Postgresql and MySQL databases, including support for automatic provisioning and migrations. \n\n\n\nYour database is automatically declared by following a specific directory structure for your SQL files. No additional configuration is needed - just create the directory structure and FTL will handle the rest. See the [Creating a New Database](#creating-a-new-database) section for CLI shortcuts.\n\n\n## Creating a New Database\n\nTo create a new database with the required directory structure, you can use the `ftl postgres new` or `ftl mysql new` command. The format of the command is:\n\n```bash\nftl <engine> new <module>.<datasource>\n```\n\nWhere:\n- `<engine>` is either `mysql` or `postgres`\n- `<module>.<datasource>` is the qualified name of the datasource (module name can be omitted if in a single module directory)\n\nFor example:\n```bash\nftl mysql new mymodule.mydb    # Create a MySQL database named \"mydb\" in module \"mymodule\"\nftl postgres new mydb          # Create a PostgreSQL database named \"mydb\" in the current module\n```\n\nThis command will:\n1. Create the appropriate directory structure\n2. Create an initial migration file in the `schema` directory\n\n## SQL File Structure\n\nIn order to be discoverable by FTL, the SQL files in your project must follow a specific directory structure. FTL supports two database engines, declared via the directory hierarchy as either `mysql` or `postgres`:\n\n\nFor Java projects, SQL files must be located in:\n```\nsrc/main/resources/\n  └── db/\n      ├── mysql/           # must be exactly \"mysql\" or \"postgres\"\n      │   └── mydb/        # database name\n      │       ├── schema/  # contains migration files\n      │       └── queries/ # contains query files\n```\n\nThe presence of a `schema` directory under your database name automatically declares the database in FTL.\n\n\n### Schema Directory\n\nThe `schema` directory contains all your database migration `.sql` files. These files are used to create and modify your database schema.\n\n### Queries Directory\n\nThe `queries` directory contains `.sql` files with any SQL queries you would like generated as FTL verbs for use in your module. These queries must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/). FTL will automatically lift these queries into the module schema and provide a type-safe client to execute each query.\n\nFind more information in the [Using Generated Query Clients](#using-generated-query-clients) section below.\n\n## Provisioning\n\nFTL includes support for automatically provisioning databases. The actual backing implementation is\nextensible, and presently we include support for both local development provisioning using docker,\nand cloud formations based provisioning for AWS deployments. When using `ftl dev` a docker container\nwill automatically be spun up for each datasource that has been defined, and FTL will automatically\nhandle configuration. The same applies when deploying to an AWS cluster with cloud formations\nprovisioning setup.\n\n## Migrations\n\nFTL includes support for automatically running migrations on databases. This is provided by [dbmate](https://github.com/amacneil/dbmate). \n\nTo create additional migrations you can use the `ftl postgres new migration` or `ftl mysql new migration` command. The format of the command is `ftl <engine> new migration <module>.<datasource> <migration-name>`.\n\nThe module name can be omitted if the current working directory only contains a single module.\n\nE.g. to create a new migration called `init` for the `testdb` datasource in the `mysql` module you would run `ftl mysql new migration mysql.testdb init`.\n\nWhen the modules are provisioned FTL will automatically run these migrations for you. \n\n## Connecting with your DB\n\nThere are two supported ways to interact with your database in FTL: using the generated database handle to perform raw queries, or using generated query clients.\n\n### Using the Generated Database Handle\n\n\t\n\tTBD\n\n\n### Using Generated Query Clients\n\nFor better type safety and maintainability, FTL can automatically generate type-safe query clients from SQL files in your `queries` directory. Your SQL files must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/) to specify the type of query and its parameters. For example:\n\n```sql\n-- name: GetUser :one\nSELECT id, name, email\nFROM users\nWHERE id = $1;\n\n-- name: ListUsers :many\nSELECT id, name, email\nFROM users\nORDER BY name;\n\n-- name: CreateUser :exec\nINSERT INTO users (name, email)\nVALUES ($1, $2);\n```\n\nThese queries will be automatically converted into FTL verbs with corresponding generated clients that you can inject into your verbs just like any other verb client. For example:\n\n\t\n```java\n@Verb\npublic String getEmail(int id, GetUserClient query) {\n    UserResult result = query.getUser(id);\n    return result.getEmail();\n}\n```\n\n\n## Transactions\n\nFTL provides transaction support through verb annotations. When a verb is marked as transactional, FTL will automatically manage the transaction boundaries - beginning the transaction when the verb is called, committing if the verb completes successfully, and rolling back if any errors occur during execution.\n\n\nTo mark a verb as transactional, use the `@Transactional` annotation:\n\n```java\npublic class CreateUserRequest {\n    private String name;\n    private String email;\n}\n\npublic class UserService {\n    @Transactional\n    public void createUser(\n        CreateUserRequest request,\n        CreateAddressClient createAddress  // Generated query client\n    ) { \n        // createAddress is a generated query client from a SQL file in queries/\n        createAddress.createAddress(new AddressRequest(userId));\n        // Transaction commits if we reach here without errors\n        // Any errors will cause automatic rollback\n    }\n}\n```\n\n\n### Transaction Rules and Limitations\n\nWhen using transactions, FTL enforces the following restrictions:\n\n1. **Database Usage**: Transaction verbs must use at least one database resource (either through a database handle or SQL query clients). FTL infers which database to open the transaction against based on these usages.\n\n2. **Single Database**: FTL only supports transactions against a single database. Two-phase commits across multiple databases are not supported.\n\n3. **No Nesting**: Transaction verbs cannot be nested. This means you cannot inject another transaction verb's client as a resource within a transaction verb.\n\n4. **Module Scope**: Transaction verbs can only call other verbs within the same module. Calls to external verbs from other modules are not allowed within a transaction.\n\n5. **Automatic Management**: Transaction boundaries are automatically managed by FTL:\n   - The transaction begins when the verb is called\n   - The transaction commits if the verb completes successfully\n   - The transaction rolls back if any errors occur during execution\n\n",
			"kotlin": "\n# Databases\n\nFTL has support for Postgresql and MySQL databases, including support for automatic provisioning and migrations. \n\n\n\nYour database is automatically declared by following a specific directory structure for your SQL files. No additional configuration is needed - just create the directory structure and FTL will handle the rest. See the [Creating a New Database](#creating-a-new-database) section for CLI shortcuts.\n\n\n## Creating a New Database\n\nTo create a new database with the required directory structure, you can use the `ftl postgres new` or `ftl mysql new` command. The format of the command is:\n\n```bash\nftl <engine> new <module>.<datasource>\n```\n\nWhere:\n- `<engine>` is either `mysql` or `postgres`\n- `<module>.<datasource>` is the qualified name of the datasource (module name can be omitted if in a single module directory)\n\nFor example:\n```bash\nftl mysql new mymodule.mydb    # Create a MySQL database named \"mydb\" in module \"mymodule\"\nftl postgres new mydb          # Create a PostgreSQL database named \"mydb\" in the current module\n```\n\nThis command will:\n1. Create the appropriate directory structure\n2. Create an initial migration file in the `schema` directory\n\n## SQL File Structure\n\nIn order to be discoverable by FTL, the SQL files in your project must follow a specific directory structure. FTL supports two database engines, declared via the directory hierarchy as either `mysql` or `postgres`:\n\n\nFor Kotlin projects, SQL files must be located in:\n```\nsrc/main/resources/\n  └── db/\n      ├── mysql/           # must be exactly \"mysql\" or \"postgres\"\n      │   └── mydb/        # database name\n      │       ├── schema/  # contains migration files\n      │       └── queries/ # contains query files\n```\n\nThe presence of a `schema` directory under your database name automatically declares the database in FTL.\n\n\n### Schema Directory\n\nThe `schema` directory contains all your database migration `.sql` files. These files are used to create and modify your database schema.\n\n### Queries Directory\n\nThe `queries` directory contains `.sql` files with any SQL queries you would like generated as FTL verbs for use in your module. These queries must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/). FTL will automatically lift these queries into the module schema and provide a type-safe client to execute each query.\n\nFind more information in the [Using Generated Query Clients](#using-generated-query-clients) section below.\n\n## Provisioning\n\nFTL includes support for automatically provisioning databases. The actual backing implementation is\nextensible, and presently we include support for both local development provisioning using docker,\nand cloud formations based provisioning for AWS deployments. When using `ftl dev` a docker container\nwill automatically be spun up for each datasource that has been defined, and FTL will automatically\nhandle configuration. The same applies when deploying to an AWS cluster with cloud formations\nprovisioning setup.\n\n## Migrations\n\nFTL includes support for automatically running migrations on databases. This is provided by [dbmate](https://github.com/amacneil/dbmate). \n\nTo create additional migrations you can use the `ftl postgres new migration` or `ftl mysql new migration` command. The format of the command is `ftl <engine> new migration <module>.<datasource> <migration-name>`.\n\nThe module name can be omitted if the current working directory only contains a single module.\n\nE.g. to create a new migration called `init` for the `testdb` datasource in the `mysql` module you would run `ftl mysql new migration mysql.testdb init`.\n\nWhen the modules are provisioned FTL will automatically run these migrations for you. \n\n## Connecting with your DB\n\nThere are two supported ways to interact with your database in FTL: using the generated database handle to perform raw queries, or using generated query clients.\n\n### Using the Generated Database Handle\n\n\n\tTBD\n\n\n### Using Generated Query Clients\n\nFor better type safety and maintainability, FTL can automatically generate type-safe query clients from SQL files in your `queries` directory. Your SQL files must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/) to specify the type of query and its parameters. For example:\n\n```sql\n-- name: GetUser :one\nSELECT id, name, email\nFROM users\nWHERE id = $1;\n\n-- name: ListUsers :many\nSELECT id, name, email\nFROM users\nORDER BY name;\n\n-- name: CreateUser :exec\nINSERT INTO users (name, email)\nVALUES ($1, $2);\n```\n\nThese queries will be automatically converted into FTL verbs with corresponding generated clients that you can inject into your verbs just like any other verb client. For example:\n\n\n```kotlin\n@Verb\nfun getEmail(id: Int, query: GetUserClient): String {\n    val result = query.getUser(id)\n    return result.email\n}\n```\n\n\n## Transactions\n\nFTL provides transaction support through verb annotations. When a verb is marked as transactional, FTL will automatically manage the transaction boundaries - beginning the transaction when the verb is called, committing if the verb completes successfully, and rolling back if any errors occur during execution.\n\n\nTo mark a verb as transactional, use the `@Transactional` annotation:\n\n```kotlin\ndata class CreateUserRequest(\n    val name: String,\n    val email: String\n)\n\n@Transactional\nfun createUser(\n    request: CreateUserRequest,\n    createAddress: CreateAddressClient // Generated query client\n): Unit {    \n    // createAddress is a generated query client from a SQL file in queries/\n    createAddress.createAddress(AddressRequest(userId = userId))\n    // Transaction commits if we reach here without errors\n    // Any errors will cause automatic rollback\n}\n```\n\n\n### Transaction Rules and Limitations\n\nWhen using transactions, FTL enforces the following restrictions:\n\n1. **Database Usage**: Transaction verbs must use at least one database resource (either through a database handle or SQL query clients). FTL infers which database to open the transaction against based on these usages.\n\n2. **Single Database**: FTL only supports transactions against a single database. Two-phase commits across multiple databases are not supported.\n\n3. **No Nesting**: Transaction verbs cannot be nested. This means you cannot inject another transaction verb's client as a resource within a transaction verb.\n\n4. **Module Scope**: Transaction verbs can only call other verbs within the same module. Calls to external verbs from other modules are not allowed within a transaction.\n\n5. **Automatic Management**: Transaction boundaries are automatically managed by FTL:\n   - The transaction begins when the verb is called\n   - The transaction commits if the verb completes successfully\n   - The transaction rolls back if any errors occur during execution\n\n",
			"schema": "\nIn the FTL schema, databases are represented using the `database` keyword with the engine type and name:\n\n```schema\nmodule example {\n  // Database declaration\n  database postgres testdb  \n    +migration sha256:59b989063b6de57a1b6867e8ad7915109c9b8632616118c6ef23e4439cf17f8e\n  \n  // Data structures for database operations\n  data CreateUserParams {\n    name String\n    email String\n  }\n  \n  data UserResult {\n    id Int +sql column \"users\".\"id\"\n    name String +sql column \"users\".\"name\"\n    email String +sql column \"users\".\"email\"\n  }\n  \n  // Query that returns a single row\n  verb getUser(Int) example.UserResult\n    +database calls example.testdb\n    +sql query one \"SELECT id, name, email FROM users WHERE id = ?\"\n  \n  // Query that returns multiple rows\n  verb listUsers(Unit) [example.UserResult]\n    +database calls example.testdb\n    +sql query many \"SELECT id, name, email FROM users ORDER BY name\"\n  \n  // Query that performs an action but doesn't return data\n  verb createUser(example.CreateUserParams) Unit\n    +database calls example.testdb\n    +sql query exec \"INSERT INTO users (name, email) VALUES (?, ?)\"\n  \n  // Custom verb that uses a database query\n  export verb getUserEmail(Int) String\n}\n```\n\nThe schema representation includes:\n1. A `database` declaration with the engine type (`postgres` or `mysql`) and database name\n2. The `+migration` annotation with a SHA256 hash of the migration files\n3. Data structures with `+sql column` annotations mapping to database columns\n4. Verb declarations with `+database calls` and `+sql query` annotations specifying the query type and SQL statement\n\n\n## Creating a New Database\n\nTo create a new database with the required directory structure, you can use the `ftl postgres new` or `ftl mysql new` command. The format of the command is:\n\n```bash\nftl <engine> new <module>.<datasource>\n```\n\nWhere:\n- `<engine>` is either `mysql` or `postgres`\n- `<module>.<datasource>` is the qualified name of the datasource (module name can be omitted if in a single module directory)\n\nFor example:\n```bash\nftl mysql new mymodule.mydb    # Create a MySQL database named \"mydb\" in module \"mymodule\"\nftl postgres new mydb          # Create a PostgreSQL database named \"mydb\" in the current module\n```\n\nThis command will:\n1. Create the appropriate directory structure\n2. Create an initial migration file in the `schema` directory\n\n## SQL File Structure\n\nIn order to be discoverable by FTL, the SQL files in your project must follow a specific directory structure. FTL supports two database engines, declared via the directory hierarchy as either `mysql` or `postgres`:\n\n\n### Schema Directory\n\nThe `schema` directory contains all your database migration `.sql` files. These files are used to create and modify your database schema.\n\n### Queries Directory\n\nThe `queries` directory contains `.sql` files with any SQL queries you would like generated as FTL verbs for use in your module. These queries must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/). FTL will automatically lift these queries into the module schema and provide a type-safe client to execute each query.\n\nFind more information in the [Using Generated Query Clients](#using-generated-query-clients) section below.\n\n## Provisioning\n\nFTL includes support for automatically provisioning databases. The actual backing implementation is\nextensible, and presently we include support for both local development provisioning using docker,\nand cloud formations based provisioning for AWS deployments. When using `ftl dev` a docker container\nwill automatically be spun up for each datasource that has been defined, and FTL will automatically\nhandle configuration. The same applies when deploying to an AWS cluster with cloud formations\nprovisioning setup.\n\n## Migrations\n\nFTL includes support for automatically running migrations on databases. This is provided by [dbmate](https://github.com/amacneil/dbmate). \n\nTo create additional migrations you can use the `ftl postgres new migration` or `ftl mysql new migration` command. The format of the command is `ftl <engine> new migration <module>.<datasource> <migration-name>`.\n\nThe module name can be omitted if the current working directory only contains a single module.\n\nE.g. to create a new migration called `init` for the `testdb` datasource in the `mysql` module you would run `ftl mysql new migration mysql.testdb init`.\n\nWhen the modules are provisioned FTL will automatically run these migrations for you. \n\n## Connecting with your DB\n\nThere are two supported ways to interact with your database in FTL: using the generated database handle to perform raw queries, or using generated query clients.\n\n### Using the Generated Database Handle\n\n\nIn the FTL schema, the database handle is represented by the `+database calls` annotation on verbs:\n\n```schema\nmodule example {\n  // Database declaration\n  database postgres mydb\n    +migration sha256:59b989063b6de57a1b6867e8ad7915109c9b8632616118c6ef23e4439cf17f8e\n  \n  // Verb that uses the database handle directly\n  export verb query(Unit) [String]\n    +database calls example.mydb\n}\n```\n\nWhen you use a database handle in your code, you're directly accessing the underlying database connection. The FTL compiler automatically generates the appropriate handle type based on the database declaration.\n\n\n### Using Generated Query Clients\n\nFor better type safety and maintainability, FTL can automatically generate type-safe query clients from SQL files in your `queries` directory. Your SQL files must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/) to specify the type of query and its parameters. For example:\n\n```sql\n-- name: GetUser :one\nSELECT id, name, email\nFROM users\nWHERE id = $1;\n\n-- name: ListUsers :many\nSELECT id, name, email\nFROM users\nORDER BY name;\n\n-- name: CreateUser :exec\nINSERT INTO users (name, email)\nVALUES ($1, $2);\n```\n\nThese queries will be automatically converted into FTL verbs with corresponding generated clients that you can inject into your verbs just like any other verb client. For example:\n\n\nIn the FTL schema, the generated query clients are represented as verbs with the `+database calls` and `+sql query` annotations:\n\n```schema\nmodule example {\n  // Database declaration\n  database postgres testdb\n    +migration sha256:59b989063b6de57a1b6867e8ad7915109c9b8632616118c6ef23e4439cf17f8e\n  \n  // Data structures for query results and parameters\n  data UserResult {\n    id Int +sql column \"users\".\"id\"\n    name String +sql column \"users\".\"name\"\n    email String +sql column \"users\".\"email\"\n  }\n  \n  data CreateUserParams {\n    name String\n    email String\n  }\n  \n  // Query that returns a single row\n  verb getUser(Int) example.UserResult\n    +database calls example.testdb\n    +sql query one \"SELECT id, name, email FROM users WHERE id = ?\"\n  \n  // Query that returns multiple rows\n  verb listUsers(Unit) [example.UserResult]\n    +database calls example.testdb\n    +sql query many \"SELECT id, name, email FROM users ORDER BY name\"\n  \n  // Query that performs an action but doesn't return data\n  verb createUser(example.CreateUserParams) Unit\n    +database calls example.testdb\n    +sql query exec \"INSERT INTO users (name, email) VALUES (?, ?)\"\n  \n  // Custom verb that uses the generated query client\n  export verb getUserEmail(Int) String\n    +calls example.getUser\n}\n```\n\nWhen you use a generated query client in your code, you're calling a verb that has been automatically generated from your SQL query. FTL handles the mapping between your SQL queries and the generated verbs.\n\n\n## Transactions\n\nFTL provides transaction support through verb annotations. When a verb is marked as transactional, FTL will automatically manage the transaction boundaries - beginning the transaction when the verb is called, committing if the verb completes successfully, and rolling back if any errors occur during execution.\n\n\nIn the FTL schema, transaction verbs are represented with the `+transaction` annotation:\n\n```schema\nmodule example {\n  // Database declaration\n  database postgres mydb\n    +migration sha256:59b989063b6de57a1b6867e8ad7915109c9b8632616118c6ef23e4439cf17f8e\n  \n  data CreateUserRequest {\n    name String\n    email String\n  }\n  \n  data AddressRequest {\n    userId Int +sql column \"addresses\".\"id\"\n    street String +sql column \"addresses\".\"street\"\n    city String +sql column \"addresses\".\"city\"\n  }\n  \n  // Generated query client from SQL file\n  verb createAddress(example.AddressRequest) Unit\n    +database calls example.mydb\n    +sql query exec \"INSERT INTO addresses (user_id, street, city) VALUES (?, ?, ?)\"\n  \n  // Transaction verb that uses both direct database access and a generated query client\n  verb createUser(example.CreateUserRequest) Unit\n    +transaction\n    +database calls example.mydb\n    +calls example.createAddress\n}\n```\n\n\n### Transaction Rules and Limitations\n\nWhen using transactions, FTL enforces the following restrictions:\n\n1. **Database Usage**: Transaction verbs must use at least one database resource (either through a database handle or SQL query clients). FTL infers which database to open the transaction against based on these usages.\n\n2. **Single Database**: FTL only supports transactions against a single database. Two-phase commits across multiple databases are not supported.\n\n3. **No Nesting**: Transaction verbs cannot be nested. This means you cannot inject another transaction verb's client as a resource within a transaction verb.\n\n4. **Module Scope**: Transaction verbs can only call other verbs within the same module. Calls to external verbs from other modules are not allowed within a transaction.\n\n5. **Automatic Management**: Transaction boundaries are automatically managed by FTL:\n   - The transaction begins when the verb is called\n   - The transaction commits if the verb completes successfully\n   - The transaction rolls back if any errors occur during execution\n\n",
	},
	"ftl.PostgresDatabaseConfig": {
			"go": "\n# Databases\n\nFTL has support for Postgresql and MySQL databases, including support for automatic provisioning and migrations. \n\n\n\nYour database is automatically declared by following a specific directory structure for your SQL files. No additional configuration is needed - just create the directory structure and FTL will handle the rest. See the [Creating a New Database](#creating-a-new-database) section for CLI shortcuts.\n\n\n## Creating a New Database\n\nTo create a new database with the required directory structure, you can use the `ftl postgres new` or `ftl mysql new` command. The format of the command is:\n\n```bash\nftl <engine> new <module>.<datasource>\n```\n\nWhere:\n- `<engine>` is either `mysql` or `postgres`\n- `<module>.<datasource>` is the qualified name of the datasource (module name can be omitted if in a single module directory)\n\nFor example:\n```bash\nftl mysql new mymodule.mydb    # Create a MySQL database named \"mydb\" in module \"mymodule\"\nftl postgres new mydb          # Create a PostgreSQL database named \"mydb\" in the current module\n```\n\nThis command will:\n1. Create the appropriate directory structure\n2. Create an initial migration file in the `schema` directory\n\n## SQL File Structure\n\nIn order to be discoverable by FTL, the SQL files in your project must follow a specific directory structure. FTL supports two database engines, declared via the directory hierarchy as either `mysql` or `postgres`:\n\n\nFor Go projects, SQL files must be located in:\n```\ndb/\n  ├── mysql/           # must be exactly \"mysql\" or \"postgres\"\n  │   └── mydb/        # database name\n  │       ├── schema/  # contains migration files\n  │       └── queries/ # contains query files\n```\n\nThe presence of a `schema` directory under your database name automatically declares the database in FTL.\n\n\n### Schema Directory\n\nThe `schema` directory contains all your database migration `.sql` files. These files are used to create and modify your database schema.\n\n### Queries Directory\n\nThe `queries` directory contains `.sql` files with any SQL queries you would like generated as FTL verbs for use in your module. These queries must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/). FTL will automatically lift these queries into the module schema and provide a type-safe client to execute each query.\n\nFind more information in the [Using Generated Query Clients](#using-generated-query-clients) section below.\n\n## Provisioning\n\nFTL includes support for automatically provisioning databases. The actual backing implementation is\nextensible, and presently we include support for both local development provisioning using docker,\nand cloud formations based provisioning for AWS deployments. When using `ftl dev` a docker container\nwill automatically be spun up for each datasource that has been defined, and FTL will automatically\nhandle configuration. The same applies when deploying to an AWS cluster with cloud formations\nprovisioning setup.\n\n## Migrations\n\nFTL includes support for automatically running migrations on databases. This is provided by [dbmate](https://github.com/amacneil/dbmate). \n\nTo create additional migrations you can use the `ftl postgres new migration` or `ftl mysql new migration` command. The format of the command is `ftl <engine> new migration <module>.<datasource> <migration-name>`.\n\nThe module name can be omitted if the current working directory only contains a single module.\n\nE.g. to create a new migration called `init` for the `testdb` datasource in the `mysql` module you would run `ftl mysql new migration mysql.testdb init`.\n\nWhen the modules are provisioned FTL will automatically run these migrations for you. \n\n## Connecting with your DB\n\nThere are two supported ways to interact with your database in FTL: using the generated database handle to perform raw queries, or using generated query clients.\n\n### Using the Generated Database Handle\n\n\nOnce you've declared a database, FTL automatically generates a database handle that provides direct access to the underlying connection. You can use this to execute raw SQL queries (where `MydbHandle` is the generated handle type for the `mydb` datasource):\n\n```go\n//ftl:verb export\nfunc Query(ctx context.Context, db MydbHandle) ([]string, error) {\n\trows, err := db.QueryContext(ctx, \"SELECT data FROM requests\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer rows.Close()\n\tvar items []string\n\tfor rows.Next() {\n\t\tvar i string\n\t\tif err := rows.Scan(&i); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\titems = append(items, i)\n\t}\n\tif err := rows.Close(); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := rows.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn items, nil\n}\n```\n\n\n### Using Generated Query Clients\n\nFor better type safety and maintainability, FTL can automatically generate type-safe query clients from SQL files in your `queries` directory. Your SQL files must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/) to specify the type of query and its parameters. For example:\n\n```sql\n-- name: GetUser :one\nSELECT id, name, email\nFROM users\nWHERE id = $1;\n\n-- name: ListUsers :many\nSELECT id, name, email\nFROM users\nORDER BY name;\n\n-- name: CreateUser :exec\nINSERT INTO users (name, email)\nVALUES ($1, $2);\n```\n\nThese queries will be automatically converted into FTL verbs with corresponding generated clients that you can inject into your verbs just like any other verb client. For example:\n\n\n```go\n//ftl:verb export\nfunc GetEmail(ctx context.Context, id int, query GetUserClient) (string, error) {\n\tresult, err := query(ctx, id)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn result.Email, nil\n}\n```\n\n\n## Transactions\n\nFTL provides transaction support through verb annotations. When a verb is marked as transactional, FTL will automatically manage the transaction boundaries - beginning the transaction when the verb is called, committing if the verb completes successfully, and rolling back if any errors occur during execution.\n\n\nTo mark a verb as transactional, use the `//ftl:transaction` comment directive:\n\n```go\ntype CreateUserRequest struct {\n    Name  string\n    Email string\n}\n\n//ftl:transaction\nfunc CreateUser(ctx context.Context, req CreateUserRequest, db MydbHandle, createAddress CreateAddressClient) error {\n    // All database operations within this verb will be executed in a single transaction\n    result, err := db.Get(ctx).Exec(\"INSERT INTO users (name, email) VALUES ($1, $2)\", req.Name, req.Email)\n    if err != nil {\n        return err // Transaction will be rolled back\n    }\n    \n    userId, err := result.LastInsertId()\n    if err != nil {\n        return err // Transaction will be rolled back\n    }\n    \n    // createAddress is a generated query client from a SQL file in queries/\n    err = createAddress(ctx, AddressRequest{UserId: userId})\n    if err != nil {\n        return err // Transaction will be rolled back\n    }\n    \n    return nil // Transaction will be committed\n}\n```\n\n\n### Transaction Rules and Limitations\n\nWhen using transactions, FTL enforces the following restrictions:\n\n1. **Database Usage**: Transaction verbs must use at least one database resource (either through a database handle or SQL query clients). FTL infers which database to open the transaction against based on these usages.\n\n2. **Single Database**: FTL only supports transactions against a single database. Two-phase commits across multiple databases are not supported.\n\n3. **No Nesting**: Transaction verbs cannot be nested. This means you cannot inject another transaction verb's client as a resource within a transaction verb.\n\n4. **Module Scope**: Transaction verbs can only call other verbs within the same module. Calls to external verbs from other modules are not allowed within a transaction.\n\n5. **Automatic Management**: Transaction boundaries are automatically managed by FTL:\n   - The transaction begins when the verb is called\n   - The transaction commits if the verb completes successfully\n   - The transaction rolls back if any errors occur during execution\n\n",
			"java": "\n# Databases\n\nFTL has support for Postgresql and MySQL databases, including support for automatic provisioning and migrations. \n\n\n\nYour database is automatically declared by following a specific directory structure for your SQL files. No additional configuration is needed - just create the directory structure and FTL will handle the rest. See the [Creating a New Database](#creating-a-new-database) section for CLI shortcuts.\n\n\n## Creating a New Database\n\nTo create a new database with the required directory structure, you can use the `ftl postgres new` or `ftl mysql new` command. The format of the command is:\n\n```bash\nftl <engine> new <module>.<datasource>\n```\n\nWhere:\n- `<engine>` is either `mysql` or `postgres`\n- `<module>.<datasource>` is the qualified name of the datasource (module name can be omitted if in a single module directory)\n\nFor example:\n```bash\nftl mysql new mymodule.mydb    # Create a MySQL database named \"mydb\" in module \"mymodule\"\nftl postgres new mydb          # Create a PostgreSQL database named \"mydb\" in the current module\n```\n\nThis command will:\n1. Create the appropriate directory structure\n2. Create an initial migration file in the `schema` directory\n\n## SQL File Structure\n\nIn order to be discoverable by FTL, the SQL files in your project must follow a specific directory structure. FTL supports two database engines, declared via the directory hierarchy as either `mysql` or `postgres`:\n\n\nFor Java projects, SQL files must be located in:\n```\nsrc/main/resources/\n  └── db/\n      ├── mysql/           # must be exactly \"mysql\" or \"postgres\"\n      │   └── mydb/        # database name\n      │       ├── schema/  # contains migration files\n      │       └── queries/ # contains query files\n```\n\nThe presence of a `schema` directory under your database name automatically declares the database in FTL.\n\n\n### Schema Directory\n\nThe `schema` directory contains all your database migration `.sql` files. These files are used to create and modify your database schema.\n\n### Queries Directory\n\nThe `queries` directory contains `.sql` files with any SQL queries you would like generated as FTL verbs for use in your module. These queries must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/). FTL will automatically lift these queries into the module schema and provide a type-safe client to execute each query.\n\nFind more information in the [Using Generated Query Clients](#using-generated-query-clients) section below.\n\n## Provisioning\n\nFTL includes support for automatically provisioning databases. The actual backing implementation is\nextensible, and presently we include support for both local development provisioning using docker,\nand cloud formations based provisioning for AWS deployments. When using `ftl dev` a docker container\nwill automatically be spun up for each datasource that has been defined, and FTL will automatically\nhandle configuration. The same applies when deploying to an AWS cluster with cloud formations\nprovisioning setup.\n\n## Migrations\n\nFTL includes support for automatically running migrations on databases. This is provided by [dbmate](https://github.com/amacneil/dbmate). \n\nTo create additional migrations you can use the `ftl postgres new migration` or `ftl mysql new migration` command. The format of the command is `ftl <engine> new migration <module>.<datasource> <migration-name>`.\n\nThe module name can be omitted if the current working directory only contains a single module.\n\nE.g. to create a new migration called `init` for the `testdb` datasource in the `mysql` module you would run `ftl mysql new migration mysql.testdb init`.\n\nWhen the modules are provisioned FTL will automatically run these migrations for you. \n\n## Connecting with your DB\n\nThere are two supported ways to interact with your database in FTL: using the generated database handle to perform raw queries, or using generated query clients.\n\n### Using the Generated Database Handle\n\n\t\n\tTBD\n\n\n### Using Generated Query Clients\n\nFor better type safety and maintainability, FTL can automatically generate type-safe query clients from SQL files in your `queries` directory. Your SQL files must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/) to specify the type of query and its parameters. For example:\n\n```sql\n-- name: GetUser :one\nSELECT id, name, email\nFROM users\nWHERE id = $1;\n\n-- name: ListUsers :many\nSELECT id, name, email\nFROM users\nORDER BY name;\n\n-- name: CreateUser :exec\nINSERT INTO users (name, email)\nVALUES ($1, $2);\n```\n\nThese queries will be automatically converted into FTL verbs with corresponding generated clients that you can inject into your verbs just like any other verb client. For example:\n\n\t\n```java\n@Verb\npublic String getEmail(int id, GetUserClient query) {\n    UserResult result = query.getUser(id);\n    return result.getEmail();\n}\n```\n\n\n## Transactions\n\nFTL provides transaction support through verb annotations. When a verb is marked as transactional, FTL will automatically manage the transaction boundaries - beginning the transaction when the verb is called, committing if the verb completes successfully, and rolling back if any errors occur during execution.\n\n\nTo mark a verb as transactional, use the `@Transactional` annotation:\n\n```java\npublic class CreateUserRequest {\n    private String name;\n    private String email;\n}\n\npublic class UserService {\n    @Transactional\n    public void createUser(\n        CreateUserRequest request,\n        CreateAddressClient createAddress  // Generated query client\n    ) { \n        // createAddress is a generated query client from a SQL file in queries/\n        createAddress.createAddress(new AddressRequest(userId));\n        // Transaction commits if we reach here without errors\n        // Any errors will cause automatic rollback\n    }\n}\n```\n\n\n### Transaction Rules and Limitations\n\nWhen using transactions, FTL enforces the following restrictions:\n\n1. **Database Usage**: Transaction verbs must use at least one database resource (either through a database handle or SQL query clients). FTL infers which database to open the transaction against based on these usages.\n\n2. **Single Database**: FTL only supports transactions against a single database. Two-phase commits across multiple databases are not supported.\n\n3. **No Nesting**: Transaction verbs cannot be nested. This means you cannot inject another transaction verb's client as a resource within a transaction verb.\n\n4. **Module Scope**: Transaction verbs can only call other verbs within the same module. Calls to external verbs from other modules are not allowed within a transaction.\n\n5. **Automatic Management**: Transaction boundaries are automatically managed by FTL:\n   - The transaction begins when the verb is called\n   - The transaction commits if the verb completes successfully\n   - The transaction rolls back if any errors occur during execution\n\n",
			"kotlin": "\n# Databases\n\nFTL has support for Postgresql and MySQL databases, including support for automatic provisioning and migrations. \n\n\n\nYour database is automatically declared by following a specific directory structure for your SQL files. No additional configuration is needed - just create the directory structure and FTL will handle the rest. See the [Creating a New Database](#creating-a-new-database) section for CLI shortcuts.\n\n\n## Creating a New Database\n\nTo create a new database with the required directory structure, you can use the `ftl postgres new` or `ftl mysql new` command. The format of the command is:\n\n```bash\nftl <engine> new <module>.<datasource>\n```\n\nWhere:\n- `<engine>` is either `mysql` or `postgres`\n- `<module>.<datasource>` is the qualified name of the datasource (module name can be omitted if in a single module directory)\n\nFor example:\n```bash\nftl mysql new mymodule.mydb    # Create a MySQL database named \"mydb\" in module \"mymodule\"\nftl postgres new mydb          # Create a PostgreSQL database named \"mydb\" in the current module\n```\n\nThis command will:\n1. Create the appropriate directory structure\n2. Create an initial migration file in the `schema` directory\n\n## SQL File Structure\n\nIn order to be discoverable by FTL, the SQL files in your project must follow a specific directory structure. FTL supports two database engines, declared via the directory hierarchy as either `mysql` or `postgres`:\n\n\nFor Kotlin projects, SQL files must be located in:\n```\nsrc/main/resources/\n  └── db/\n      ├── mysql/           # must be exactly \"mysql\" or \"postgres\"\n      │   └── mydb/        # database name\n      │       ├── schema/  # contains migration files\n      │       └── queries/ # contains query files\n```\n\nThe presence of a `schema` directory under your database name automatically declares the database in FTL.\n\n\n### Schema Directory\n\nThe `schema` directory contains all your database migration `.sql` files. These files are used to create and modify your database schema.\n\n### Queries Directory\n\nThe `queries` directory contains `.sql` files with any SQL queries you would like generated as FTL verbs for use in your module. These queries must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/). FTL will automatically lift these queries into the module schema and provide a type-safe client to execute each query.\n\nFind more information in the [Using Generated Query Clients](#using-generated-query-clients) section below.\n\n## Provisioning\n\nFTL includes support for automatically provisioning databases. The actual backing implementation is\nextensible, and presently we include support for both local development provisioning using docker,\nand cloud formations based provisioning for AWS deployments. When using `ftl dev` a docker container\nwill automatically be spun up for each datasource that has been defined, and FTL will automatically\nhandle configuration. The same applies when deploying to an AWS cluster with cloud formations\nprovisioning setup.\n\n## Migrations\n\nFTL includes support for automatically running migrations on databases. This is provided by [dbmate](https://github.com/amacneil/dbmate). \n\nTo create additional migrations you can use the `ftl postgres new migration` or `ftl mysql new migration` command. The format of the command is `ftl <engine> new migration <module>.<datasource> <migration-name>`.\n\nThe module name can be omitted if the current working directory only contains a single module.\n\nE.g. to create a new migration called `init` for the `testdb` datasource in the `mysql` module you would run `ftl mysql new migration mysql.testdb init`.\n\nWhen the modules are provisioned FTL will automatically run these migrations for you. \n\n## Connecting with your DB\n\nThere are two supported ways to interact with your database in FTL: using the generated database handle to perform raw queries, or using generated query clients.\n\n### Using the Generated Database Handle\n\n\n\tTBD\n\n\n### Using Generated Query Clients\n\nFor better type safety and maintainability, FTL can automatically generate type-safe query clients from SQL files in your `queries` directory. Your SQL files must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/) to specify the type of query and its parameters. For example:\n\n```sql\n-- name: GetUser :one\nSELECT id, name, email\nFROM users\nWHERE id = $1;\n\n-- name: ListUsers :many\nSELECT id, name, email\nFROM users\nORDER BY name;\n\n-- name: CreateUser :exec\nINSERT INTO users (name, email)\nVALUES ($1, $2);\n```\n\nThese queries will be automatically converted into FTL verbs with corresponding generated clients that you can inject into your verbs just like any other verb client. For example:\n\n\n```kotlin\n@Verb\nfun getEmail(id: Int, query: GetUserClient): String {\n    val result = query.getUser(id)\n    return result.email\n}\n```\n\n\n## Transactions\n\nFTL provides transaction support through verb annotations. When a verb is marked as transactional, FTL will automatically manage the transaction boundaries - beginning the transaction when the verb is called, committing if the verb completes successfully, and rolling back if any errors occur during execution.\n\n\nTo mark a verb as transactional, use the `@Transactional` annotation:\n\n```kotlin\ndata class CreateUserRequest(\n    val name: String,\n    val email: String\n)\n\n@Transactional\nfun createUser(\n    request: CreateUserRequest,\n    createAddress: CreateAddressClient // Generated query client\n): Unit {    \n    // createAddress is a generated query client from a SQL file in queries/\n    createAddress.createAddress(AddressRequest(userId = userId))\n    // Transaction commits if we reach here without errors\n    // Any errors will cause automatic rollback\n}\n```\n\n\n### Transaction Rules and Limitations\n\nWhen using transactions, FTL enforces the following restrictions:\n\n1. **Database Usage**: Transaction verbs must use at least one database resource (either through a database handle or SQL query clients). FTL infers which database to open the transaction against based on these usages.\n\n2. **Single Database**: FTL only supports transactions against a single database. Two-phase commits across multiple databases are not supported.\n\n3. **No Nesting**: Transaction verbs cannot be nested. This means you cannot inject another transaction verb's client as a resource within a transaction verb.\n\n4. **Module Scope**: Transaction verbs can only call other verbs within the same module. Calls to external verbs from other modules are not allowed within a transaction.\n\n5. **Automatic Management**: Transaction boundaries are automatically managed by FTL:\n   - The transaction begins when the verb is called\n   - The transaction commits if the verb completes successfully\n   - The transaction rolls back if any errors occur during execution\n\n",
			"schema": "\nIn the FTL schema, databases are represented using the `database` keyword with the engine type and name:\n\n```schema\nmodule example {\n  // Database declaration\n  database postgres testdb  \n    +migration sha256:59b989063b6de57a1b6867e8ad7915109c9b8632616118c6ef23e4439cf17f8e\n  \n  // Data structures for database operations\n  data CreateUserParams {\n    name String\n    email String\n  }\n  \n  data UserResult {\n    id Int +sql column \"users\".\"id\"\n    name String +sql column \"users\".\"name\"\n    email String +sql column \"users\".\"email\"\n  }\n  \n  // Query that returns a single row\n  verb getUser(Int) example.UserResult\n    +database calls example.testdb\n    +sql query one \"SELECT id, name, email FROM users WHERE id = ?\"\n  \n  // Query that returns multiple rows\n  verb listUsers(Unit) [example.UserResult]\n    +database calls example.testdb\n    +sql query many \"SELECT id, name, email FROM users ORDER BY name\"\n  \n  // Query that performs an action but doesn't return data\n  verb createUser(example.CreateUserParams) Unit\n    +database calls example.testdb\n    +sql query exec \"INSERT INTO users (name, email) VALUES (?, ?)\"\n  \n  // Custom verb that uses a database query\n  export verb getUserEmail(Int) String\n}\n```\n\nThe schema representation includes:\n1. A `database` declaration with the engine type (`postgres` or `mysql`) and database name\n2. The `+migration` annotation with a SHA256 hash of the migration files\n3. Data structures with `+sql column` annotations mapping to database columns\n4. Verb declarations with `+database calls` and `+sql query` annotations specifying the query type and SQL statement\n\n\n## Creating a New Database\n\nTo create a new database with the required directory structure, you can use the `ftl postgres new` or `ftl mysql new` command. The format of the command is:\n\n```bash\nftl <engine> new <module>.<datasource>\n```\n\nWhere:\n- `<engine>` is either `mysql` or `postgres`\n- `<module>.<datasource>` is the qualified name of the datasource (module name can be omitted if in a single module directory)\n\nFor example:\n```bash\nftl mysql new mymodule.mydb    # Create a MySQL database named \"mydb\" in module \"mymodule\"\nftl postgres new mydb          # Create a PostgreSQL database named \"mydb\" in the current module\n```\n\nThis command will:\n1. Create the appropriate directory structure\n2. Create an initial migration file in the `schema` directory\n\n## SQL File Structure\n\nIn order to be discoverable by FTL, the SQL files in your project must follow a specific directory structure. FTL supports two database engines, declared via the directory hierarchy as either `mysql` or `postgres`:\n\n\n### Schema Directory\n\nThe `schema` directory contains all your database migration `.sql` files. These files are used to create and modify your database schema.\n\n### Queries Directory\n\nThe `queries` directory contains `.sql` files with any SQL queries you would like generated as FTL verbs for use in your module. These queries must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/). FTL will automatically lift these queries into the module schema and provide a type-safe client to execute each query.\n\nFind more information in the [Using Generated Query Clients](#using-generated-query-clients) section below.\n\n## Provisioning\n\nFTL includes support for automatically provisioning databases. The actual backing implementation is\nextensible, and presently we include support for both local development provisioning using docker,\nand cloud formations based provisioning for AWS deployments. When using `ftl dev` a docker container\nwill automatically be spun up for each datasource that has been defined, and FTL will automatically\nhandle configuration. The same applies when deploying to an AWS cluster with cloud formations\nprovisioning setup.\n\n## Migrations\n\nFTL includes support for automatically running migrations on databases. This is provided by [dbmate](https://github.com/amacneil/dbmate). \n\nTo create additional migrations you can use the `ftl postgres new migration` or `ftl mysql new migration` command. The format of the command is `ftl <engine> new migration <module>.<datasource> <migration-name>`.\n\nThe module name can be omitted if the current working directory only contains a single module.\n\nE.g. to create a new migration called `init` for the `testdb` datasource in the `mysql` module you would run `ftl mysql new migration mysql.testdb init`.\n\nWhen the modules are provisioned FTL will automatically run these migrations for you. \n\n## Connecting with your DB\n\nThere are two supported ways to interact with your database in FTL: using the generated database handle to perform raw queries, or using generated query clients.\n\n### Using the Generated Database Handle\n\n\nIn the FTL schema, the database handle is represented by the `+database calls` annotation on verbs:\n\n```schema\nmodule example {\n  // Database declaration\n  database postgres mydb\n    +migration sha256:59b989063b6de57a1b6867e8ad7915109c9b8632616118c6ef23e4439cf17f8e\n  \n  // Verb that uses the database handle directly\n  export verb query(Unit) [String]\n    +database calls example.mydb\n}\n```\n\nWhen you use a database handle in your code, you're directly accessing the underlying database connection. The FTL compiler automatically generates the appropriate handle type based on the database declaration.\n\n\n### Using Generated Query Clients\n\nFor better type safety and maintainability, FTL can automatically generate type-safe query clients from SQL files in your `queries` directory. Your SQL files must be annotated with [SQLC annotation syntax](https://docs.sqlc.dev/) to specify the type of query and its parameters. For example:\n\n```sql\n-- name: GetUser :one\nSELECT id, name, email\nFROM users\nWHERE id = $1;\n\n-- name: ListUsers :many\nSELECT id, name, email\nFROM users\nORDER BY name;\n\n-- name: CreateUser :exec\nINSERT INTO users (name, email)\nVALUES ($1, $2);\n```\n\nThese queries will be automatically converted into FTL verbs with corresponding generated clients that you can inject into your verbs just like any other verb client. For example:\n\n\nIn the FTL schema, the generated query clients are represented as verbs with the `+database calls` and `+sql query` annotations:\n\n```schema\nmodule example {\n  // Database declaration\n  database postgres testdb\n    +migration sha256:59b989063b6de57a1b6867e8ad7915109c9b8632616118c6ef23e4439cf17f8e\n  \n  // Data structures for query results and parameters\n  data UserResult {\n    id Int +sql column \"users\".\"id\"\n    name String +sql column \"users\".\"name\"\n    email String +sql column \"users\".\"email\"\n  }\n  \n  data CreateUserParams {\n    name String\n    email String\n  }\n  \n  // Query that returns a single row\n  verb getUser(Int) example.UserResult\n    +database calls example.testdb\n    +sql query one \"SELECT id, name, email FROM users WHERE id = ?\"\n  \n  // Query that returns multiple rows\n  verb listUsers(Unit) [example.UserResult]\n    +database calls example.testdb\n    +sql query many \"SELECT id, name, email FROM users ORDER BY name\"\n  \n  // Query that performs an action but doesn't return data\n  verb createUser(example.CreateUserParams) Unit\n    +database calls example.testdb\n    +sql query exec \"INSERT INTO users (name, email) VALUES (?, ?)\"\n  \n  // Custom verb that uses the generated query client\n  export verb getUserEmail(Int) String\n    +calls example.getUser\n}\n```\n\nWhen you use a generated query client in your code, you're calling a verb that has been automatically generated from your SQL query. FTL handles the mapping between your SQL queries and the generated verbs.\n\n\n## Transactions\n\nFTL provides transaction support through verb annotations. When a verb is marked as transactional, FTL will automatically manage the transaction boundaries - beginning the transaction when the verb is called, committing if the verb completes successfully, and rolling back if any errors occur during execution.\n\n\nIn the FTL schema, transaction verbs are represented with the `+transaction` annotation:\n\n```schema\nmodule example {\n  // Database declaration\n  database postgres mydb\n    +migration sha256:59b989063b6de57a1b6867e8ad7915109c9b8632616118c6ef23e4439cf17f8e\n  \n  data CreateUserRequest {\n    name String\n    email String\n  }\n  \n  data AddressRequest {\n    userId Int +sql column \"addresses\".\"id\"\n    street String +sql column \"addresses\".\"street\"\n    city String +sql column \"addresses\".\"city\"\n  }\n  \n  // Generated query client from SQL file\n  verb createAddress(example.AddressRequest) Unit\n    +database calls example.mydb\n    +sql query exec \"INSERT INTO addresses (user_id, street, city) VALUES (?, ?, ?)\"\n  \n  // Transaction verb that uses both direct database access and a generated query client\n  verb createUser(example.CreateUserRequest) Unit\n    +transaction\n    +database calls example.mydb\n    +calls example.createAddress\n}\n```\n\n\n### Transaction Rules and Limitations\n\nWhen using transactions, FTL enforces the following restrictions:\n\n1. **Database Usage**: Transaction verbs must use at least one database resource (either through a database handle or SQL query clients). FTL infers which database to open the transaction against based on these usages.\n\n2. **Single Database**: FTL only supports transactions against a single database. Two-phase commits across multiple databases are not supported.\n\n3. **No Nesting**: Transaction verbs cannot be nested. This means you cannot inject another transaction verb's client as a resource within a transaction verb.\n\n4. **Module Scope**: Transaction verbs can only call other verbs within the same module. Calls to external verbs from other modules are not allowed within a transaction.\n\n5. **Automatic Management**: Transaction boundaries are automatically managed by FTL:\n   - The transaction begins when the verb is called\n   - The transaction commits if the verb completes successfully\n   - The transaction rolls back if any errors occur during execution\n\n",
	},
	"ftl.Secret": {
			"go": "\n# Secrets and Configuration\n\n## Configuration\n\nConfiguration values are named, typed values. They are managed by the `ftl config` command-line.\n\n\n\nTo declare a configuration value use the following syntax:\n\n```go\n// Simple string configuration\ntype ApiUrl = ftl.Config[string]\n\n// Type-safe configuration\ntype DefaultUser = ftl.Config[Username]\n```\n\nNote that the name of the configuration value as represented in the FTL schema is the lower camel case version of the type name (e.g., `ApiUrl` becomes `apiUrl`).\n\nConfiguration values can be injected into FTL methods, such as //ftl:verb, HTTP ingress, Cron etc. To inject a configuration value, use the following syntax:\n\n```go\n//ftl:verb\nfunc Hello(ctx context.Context, req Request, defaultUser DefaultUser) error {\n    username := defaultUser.Get(ctx)\n    // ...\n}\n```\n\n\n## Secrets\n\nSecrets are encrypted, named, typed values. They are managed by the `ftl secret` command-line.\n\n\nDeclare a secret with the following:\n\n```go\n// Simple string secret\ntype ApiToken = ftl.Secret[string]\n\n// Type-safe secret\ntype ApiKey = ftl.Secret[Credentials]\n```\n\nLike configuration values, the name of the secret as represented in the FTL schema is the lower camel case version of the type name (e.g., `ApiToken` becomes `apiToken`).\n\nSecrets can be injected into FTL methods, such as //ftl:verb, HTTP ingress, Cron etc. To inject a secret value, use the following syntax:\n\n```go\n//ftl:verb\nfunc CallApi(ctx context.Context, req Request, apiKey ApiKey) error {\n    credentials := apiKey.Get(ctx)\n    // ...\n}\n```\n\n\n## Transforming secrets/configuration\n\nOften, raw secret/configuration values aren't directly useful. For example, raw credentials might be used to create an API client. For those situations `ftl.Map()` can be used to transform a configuration or secret value into another type:\n\n```go\nvar client = ftl.Map(ftl.Secret[Credentials](\"credentials\"),\n                     func(ctx context.Context, creds Credentials) (*api.Client, error) {\n    return api.NewClient(creds)\n})\n```\n\nThis is not currently supported in Kotlin or Java. \n\n",
			"java": "\n# Secrets and Configuration\n\n## Configuration\n\nConfiguration values are named, typed values. They are managed by the `ftl config` command-line.\n\n\n\nConfiguration values can be injected into FTL methods, such as `@Verb`, HTTP ingress, Cron etc. To inject a configuration value, use the following syntax:\n\n```java\n@Export\n@Verb\nHelloResponse hello(HelloRequest helloRequest, @Config(\"defaultUser\") String defaultUser)  {\n    return new HelloResponse(\"Hello, \" + defaultUser);\n}\n```\n\n\n## Secrets\n\nSecrets are encrypted, named, typed values. They are managed by the `ftl secret` command-line.\n\n\nSecrets can be injected into FTL methods, such as `@Verb`, HTTP ingress, Cron etc. To inject a secret value, use the following syntax:\n\n```java\n@Export\n@Verb\nHelloResponse hello(HelloRequest helloRequest, @Secret(\"apiKey\") String apiKey)  {\n    return new HelloResponse(\"Hello, \" + api.call(apiKey));\n}\n```\n\n\n## Transforming secrets/configuration\n\nOften, raw secret/configuration values aren't directly useful. For example, raw credentials might be used to create an API client. For those situations `ftl.Map()` can be used to transform a configuration or secret value into another type:\n\n```go\nvar client = ftl.Map(ftl.Secret[Credentials](\"credentials\"),\n                     func(ctx context.Context, creds Credentials) (*api.Client, error) {\n    return api.NewClient(creds)\n})\n```\n\nThis is not currently supported in Kotlin or Java. \n\n",
			"kotlin": "\n# Secrets and Configuration\n\n## Configuration\n\nConfiguration values are named, typed values. They are managed by the `ftl config` command-line.\n\n\n\nConfiguration values can be injected into FTL methods, such as `@Verb`, HTTP ingress, Cron etc. To inject a configuration value, use the following syntax:\n\n```kotlin\n@Export\n@Verb\nfun hello(helloRequest: HelloRequest, @Config(\"defaultUser\") defaultUser: String): HelloResponse {\n    return HelloResponse(\"Hello, $defaultUser\")\n}\n```\n\n\n## Secrets\n\nSecrets are encrypted, named, typed values. They are managed by the `ftl secret` command-line.\n\n\nSecrets can be injected into FTL methods, such as `@Verb`, HTTP ingress, Cron etc. To inject a secret value, use the following syntax:\n\n```kotlin\n@Export\n@Verb\nfun hello(helloRequest: HelloRequest, @Secret(\"apiKey\") apiKey: String): HelloResponse {\n    return HelloResponse(\"Hello, ${api.call(apiKey)}\")\n}\n```\n\n\n## Transforming secrets/configuration\n\nOften, raw secret/configuration values aren't directly useful. For example, raw credentials might be used to create an API client. For those situations `ftl.Map()` can be used to transform a configuration or secret value into another type:\n\n```go\nvar client = ftl.Map(ftl.Secret[Credentials](\"credentials\"),\n                     func(ctx context.Context, creds Credentials) (*api.Client, error) {\n    return api.NewClient(creds)\n})\n```\n\nThis is not currently supported in Kotlin or Java. \n\n",
			"schema": "\nIn the FTL schema, configuration values are declared as follows:\n\n```schema\nmodule example {\n  config defaultUser String\n  \n  verb hello(Unit) String\n    +config example.defaultUser\n}\n```\n\nConfiguration values have a name, a type, and can be injected into verbs using the `+config` annotation.\n\n## Secrets\n\nSecrets are encrypted, named, typed values. They are managed by the `ftl secret` command-line.\n\n\nIn the FTL schema, secrets are declared as follows:\n\n```schema\nmodule example {\n  // Secret declaration\n  secret apiToken String\n  secret apiKey example.Credentials\n  \n  // Using a secret in a verb\n  verb callApi(example.Request) Unit\n    +secret apiKey\n}\n```\n\nSecrets have a name, a type, and can be injected into verbs using the `+secret` annotation.\n\n## Transforming secrets/configuration\n\nOften, raw secret/configuration values aren't directly useful. For example, raw credentials might be used to create an API client. For those situations `ftl.Map()` can be used to transform a configuration or secret value into another type:\n\n```go\nvar client = ftl.Map(ftl.Secret[Credentials](\"credentials\"),\n                     func(ctx context.Context, creds Credentials) (*api.Client, error) {\n    return api.NewClient(creds)\n})\n```\n\nThis is not currently supported in Kotlin or Java. \n\n",
	},
}
