diff --git a/Bitfile b/Bitfile
index 65623631a9..18a13f3717 100644
--- a/Bitfile
+++ b/Bitfile
@@ -31,9 +31,6 @@ KT_RUNTIME_IN = kotlin-runtime/ftl-runtime/**/*.{kt,kts} pom.xml kotlin-runtime/
KT_RUNTIME_OUT = kotlin-runtime/ftl-runtime/target/ftl-runtime-1.0-SNAPSHOT.jar
KT_RUNTIME_RUNNER_TEMPLATE_OUT = build/template/ftl/jars/ftl-runtime.jar
-KT_GENERATOR_IN = kotlin-runtime/ftl-generator/**/*.{kt,kts} pom.xml kotlin-runtime/ftl-runtime/**/pom.xml %{KT_RUNTIME_OUT}
-KT_GENERATOR_OUT = kotlin-runtime/ftl-generator/target/ftl-generator-1.0-SNAPSHOT.jar
-
CLIENT_IN = frontend/src/**/*
CLIENT_OUT = frontend/dist/index.html
NPM_IN = frontend/package{,-lock}.json
@@ -119,12 +116,6 @@ kotlin-runtime/external-module-template.zip: kotlin-runtime/external-module-temp
mvn -B -pl :ftl-runtime install
+clean: mvn -B -pl :ftl-runtime clean
-%{KT_GENERATOR_OUT}: %{KT_GENERATOR_IN}
- build:
- mvn -B -N install
- mvn -B -pl :ftl-generator install
- +clean: mvn -B -pl :ftl-generator clean
-
%(dirname %{KT_RUNTIME_RUNNER_TEMPLATE_OUT})%:
build: install -m 0700 -d %{OUT}
diff --git a/examples/kotlin/pom.xml b/examples/kotlin/pom.xml
index 812e162f79..7cd8e9adc2 100644
--- a/examples/kotlin/pom.xml
+++ b/examples/kotlin/pom.xml
@@ -115,31 +115,6 @@
-
-
- org.codehaus.mojo
- exec-maven-plugin
- 3.0.0
-
-
- initialize
-
- exec
-
-
- java
-
- -jar
- target/dependency/ftl-generator.jar
- --endpoint=${ftlEndpoint}
- --dest=${project.build.directory}
- --module=${ftlModuleName}
- --module-client-suffix=ModuleClient
-
-
-
-
-
org.codehaus.mojo
diff --git a/kotlin-runtime/ftl-generator/pom.xml b/kotlin-runtime/ftl-generator/pom.xml
deleted file mode 100644
index 8db81a8dcb..0000000000
--- a/kotlin-runtime/ftl-generator/pom.xml
+++ /dev/null
@@ -1,155 +0,0 @@
-
-
- 4.0.0
-
-
- xyz.block
- ftl
- 1.0-SNAPSHOT
- ../../pom.xml
-
-
- ftl-generator
- jar
-
- ${project.groupId}:${project.artifactId}
-
-
- ${basedir}/../..
- false
-
-
-
-
- com.squareup
- kotlinpoet-jvm
- 1.16.0
-
-
- ${project.groupId}
- ftl-runtime
- ${project.version}
-
-
- com.github.ajalt.clikt
- clikt-jvm
- 4.2.2
-
-
- com.squareup.wire
- wire-runtime-jvm
-
-
- com.squareup.wire
- wire-grpc-server
-
-
- com.squareup.wire
- wire-grpc-client-jvm
-
-
- org.jetbrains.kotlin
- kotlin-stdlib
-
-
- io.grpc
- grpc-protobuf
-
-
- io.grpc
- grpc-stub
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-shade-plugin
-
-
- shade-jar
- package
-
- shade
-
-
- false
-
-
- xyz.block.ftl.generator.MainKt
-
-
- false
-
-
-
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
-
-
- kotlin-maven-plugin
- org.jetbrains.kotlin
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
-
-
- 11
-
-
-
-
- org.apache.maven.plugins
- maven-dependency-plugin
-
-
-
- org.codehaus.mojo
- exec-maven-plugin
-
-
- org.codehaus.mojo
- build-helper-maven-plugin
-
-
-
-
-
-
- release
-
-
-
- org.apache.maven.plugins
- maven-shade-plugin
-
-
- shade-jar
-
- true
-
-
-
-
-
- org.codehaus.mojo
- flatten-maven-plugin
-
-
- flatten
- package
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/kotlin-runtime/ftl-generator/src/main/kotlin/xyz/block/ftl/generator/FTLClient.kt b/kotlin-runtime/ftl-generator/src/main/kotlin/xyz/block/ftl/generator/FTLClient.kt
deleted file mode 100644
index 1e6dbd2099..0000000000
--- a/kotlin-runtime/ftl-generator/src/main/kotlin/xyz/block/ftl/generator/FTLClient.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-package xyz.block.ftl.generator
-
-import com.squareup.wire.GrpcClient
-import kotlinx.coroutines.channels.ReceiveChannel
-import kotlinx.coroutines.channels.SendChannel
-import okhttp3.OkHttpClient
-import okhttp3.Protocol
-import xyz.block.ftl.v1.ControllerServiceClient
-import xyz.block.ftl.v1.GetSchemaRequest
-import xyz.block.ftl.v1.PullSchemaRequest
-import xyz.block.ftl.v1.PullSchemaResponse
-import xyz.block.ftl.v1.schema.Schema
-import java.net.ConnectException
-import java.time.Duration
-
-internal class FTLClient(ftlEndpoint: String) {
- private var grpcClient: GrpcClient
- private lateinit var sendSchemaChannel: SendChannel
- private lateinit var receiveSchemaChannel: ReceiveChannel
-
- init {
- grpcClient = GrpcClient.Builder()
- .client(
- OkHttpClient.Builder()
- .readTimeout(Duration.ofSeconds(10))
- .writeTimeout(Duration.ofSeconds(10))
- .callTimeout(Duration.ofSeconds(10))
- .protocols(listOf(Protocol.H2_PRIOR_KNOWLEDGE))
- .addInterceptor { chain ->
- try {
- chain.proceed(chain.request())
- } catch (e: ConnectException) {
- throw ConnectException(
- "Unable to connect to FTL Controller at: $ftlEndpoint. Is it running?"
- )
- }
- }
- .build()
- )
- .baseUrl(ftlEndpoint)
- .build()
- }
-
- fun getSchema(): Schema? {
- val client = grpcClient.create(ControllerServiceClient::class)
- return client.GetSchema().executeBlocking(GetSchemaRequest()).schema
- }
-}
diff --git a/kotlin-runtime/ftl-generator/src/main/kotlin/xyz/block/ftl/generator/ModuleGenerator.kt b/kotlin-runtime/ftl-generator/src/main/kotlin/xyz/block/ftl/generator/ModuleGenerator.kt
deleted file mode 100644
index 9f33cf8784..0000000000
--- a/kotlin-runtime/ftl-generator/src/main/kotlin/xyz/block/ftl/generator/ModuleGenerator.kt
+++ /dev/null
@@ -1,238 +0,0 @@
-package xyz.block.ftl.generator
-
-import com.squareup.kotlinpoet.*
-import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
-import xyz.block.ftl.Context
-import xyz.block.ftl.HttpIngress
-import xyz.block.ftl.v1.schema.*
-import java.io.File
-import java.nio.file.Path
-import java.nio.file.attribute.PosixFilePermission
-import kotlin.io.path.createDirectories
-import kotlin.io.path.setPosixFilePermissions
-import kotlin.io.path.writeText
-
-class ModuleGenerator {
- fun run(schema: Schema, outputDirectory: File, module: String, moduleClientSuffix: String) {
- val fqOutputDir = outputDirectory.absolutePath
- prepareFtlRoot(fqOutputDir, module)
- val sourcesDest = File(fqOutputDir, "generated-sources")
- Path.of(sourcesDest.path).createDirectories()
- schema.modules.filter { it.name != module }.forEach {
- val file = generateModule(it, moduleClientSuffix)
- file.writeTo(sourcesDest)
-
- println("Generated module: ${fqOutputDir}/generated-sources/ftl/${it.name}/${file.name}.kt")
- }
- }
-
- internal fun generateModule(module: Module, moduleClientSuffix: String = DEFAULT_MODULE_CLIENT_SUFFIX): FileSpec {
- val namespace = "ftl.${module.name}"
- val filename = module.name.replaceFirstChar(Char::titlecase) + moduleClientSuffix
- val file = FileSpec.builder(namespace, filename)
- .addFileComment("Code generated by FTL-Generator, do not edit.")
-
- module.comments.let {
- file.addFileComment("\n")
- file.addFileComment(it.joinToString("\n"))
- }
-
- val emptyData = mutableSetOf()
- val types = module.decls.mapNotNull { it.data_ }
- types.forEach {
- if (namespace == "ftl.builtin" && it.name == "Empty") {
- file.addType(
- TypeSpec.classBuilder(it.name)
- .addKdoc(it.comments.joinToString("\n"))
- .build()
- )
- } else if (it.fields.isEmpty()) {
- emptyData.add("${namespace}.${it.name}")
- } else {
- file.addType(buildDataClass(it, namespace))
- }
- }
-
- val verbs = module.decls.mapNotNull { it.verb }
- verbs.forEach { file.addFunction(buildVerbFunction(namespace, emptyData, it)) }
-
- return file.build()
- }
-
- private fun buildDataClass(type: Data, namespace: String): TypeSpec {
- val dataClassBuilder = TypeSpec.classBuilder(type.name)
- .addModifiers(KModifier.DATA)
- .addTypeVariables(type.typeParameters.map { TypeVariableName(it.name) })
- .addKdoc(type.comments.joinToString("\n"))
-
- val dataConstructorBuilder = FunSpec.constructorBuilder()
- type.fields.forEach { field ->
- dataClassBuilder.addKdoc(field.comments.joinToString("\n"))
- field.type?.let { type ->
- var parameter = ParameterSpec
- .builder(field.name, getTypeClass(type, namespace))
- if (type.optional != null) {
- parameter = parameter.defaultValue("null")
- }
- dataConstructorBuilder.addParameter(parameter.build())
- dataClassBuilder.addProperty(
- PropertySpec.builder(field.name, getTypeClass(type, namespace)).initializer(field.name).let {
- if (field.jsonAlias != "") {
- it.addAnnotation(
- AnnotationSpec.builder(xyz.block.ftl.Json::class).addMember("%S", field.jsonAlias).build()
- )
- } else {
- it
- }
- }.build()
- )
- }
- }
-
- dataClassBuilder.primaryConstructor(dataConstructorBuilder.build())
-
- return dataClassBuilder.build()
- }
-
- private fun buildVerbFunction(namespace: String, emptyData: Set, verb: Verb): FunSpec {
- val verbFunBuilder =
- FunSpec.builder(verb.name)
- .addKdoc(verb.comments.joinToString("\n"))
- .addAnnotation(AnnotationSpec.builder(xyz.block.ftl.Verb::class).build())
- .addAnnotation(AnnotationSpec.builder(xyz.block.ftl.Ignore::class).build())
-
- verb.metadata.forEach { metadata ->
- metadata.ingress?.let {
- verbFunBuilder.addAnnotation(
- AnnotationSpec.builder(HttpIngress::class)
- .addMember("%T", ClassName("xyz.block.ftl.Method", it.method.replaceBefore(".", "")))
- .addMember("%S", ingressPathString(it.path))
- .build()
- )
- }
- }
-
- verbFunBuilder.addParameter("context", Context::class)
- val emptyDataRef = getTypeClass(Type(dataRef = DataRef(name = "Empty")), "ftl.builtin")
-
- verb.request?.let {
- verbFunBuilder.addParameter(
- "req",
- if (emptyData.contains("${namespace}.${it.dataRef?.name}")) {
- emptyDataRef
- } else {
- getTypeClass(it, namespace)
- }
- )
- }
-
- verb.response?.let {
- verbFunBuilder.returns(
- if (emptyData.contains("${namespace}.${it.dataRef?.name}")) {
- emptyDataRef
- } else {
- getTypeClass(it, namespace)
- }
- )
- }
-
- val message =
- "Verb stubs should not be called directly, instead use context.call(::${verb.name}, ...)"
- verbFunBuilder.addCode("""throw NotImplementedError(%S)""", message)
-
- return verbFunBuilder.build()
- }
-
- private fun ingressPathString(components: List): String {
- return "/" + components.joinToString("/") { component ->
- when {
- component.ingressPathLiteral != null -> component.ingressPathLiteral.text
- component.ingressPathParameter != null -> "{${component.ingressPathParameter.name}}"
- else -> throw IllegalArgumentException("Unknown ingress path component")
- }
- }
- }
-
- private fun getTypeClass(type: Type, namespace: String): TypeName {
- return when {
- type.int != null -> ClassName("kotlin", "Long")
- type.float != null -> ClassName("kotlin", "Float")
- type.string != null -> ClassName("kotlin", "String")
- type.bytes != null -> ClassName("kotlin", "ByteArray")
- type.bool != null -> ClassName("kotlin", "Boolean")
- type.time != null -> ClassName("java.time", "OffsetDateTime")
- type.unit != null -> ClassName("kotlin", "Unit")
- type.any != null -> ClassName("kotlin", "Any")
- type.array != null -> {
- val element = type.array?.element ?: throw IllegalArgumentException(
- "Missing element type in kotlin array generator"
- )
- val elementType = getTypeClass(element, namespace)
- val arrayList = ClassName("kotlin.collections", "ArrayList")
- arrayList.parameterizedBy(elementType)
- }
-
- type.map != null -> {
- val map = ClassName("kotlin.collections", "Map")
- val key =
- type.map?.key ?: throw IllegalArgumentException("Missing map key in kotlin map generator")
- val value = type.map?.value_ ?: throw IllegalArgumentException(
- "Missing map value in kotlin map generator"
- )
- map.parameterizedBy(getTypeClass(key, namespace), getTypeClass(value, namespace))
- }
-
- type.dataRef != null -> {
- val module = if (type.dataRef.module.isEmpty()) namespace else "ftl.${type.dataRef.module}"
- ClassName(module, type.dataRef.name).let { className ->
- if (type.dataRef.typeParameters.isNotEmpty()) {
- className.parameterizedBy(type.dataRef.typeParameters.map { getTypeClass(it, namespace) })
- } else {
- className
- }
- }
- }
-
- type.optional != null -> {
- val wrapped = type.optional.type ?: throw IllegalArgumentException(
- "Missing wrapped type in kotlin optional generator"
- )
- return getTypeClass(wrapped, namespace).copy(nullable = true)
- }
-
- else -> throw IllegalArgumentException("Unknown type in kotlin generator")
- }
- }
-
- private fun prepareFtlRoot(buildDir: String, module: String) {
- Path.of(buildDir).createDirectories()
-
- Path.of(buildDir, "detekt.yml").writeText(
- """
- SchemaExtractorRuleSet:
- ExtractSchemaRule:
- active: true
- output: ${buildDir}
- """.trimIndent()
- )
-
- val mainFile = Path.of(buildDir, "main")
- mainFile.writeText(
- """
- #!/bin/bash
- exec java -cp "classes:$(cat classpath.txt)" xyz.block.ftl.main.MainKt
- """.trimIndent(),
- )
- mainFile.setPosixFilePermissions(
- setOf(
- PosixFilePermission.OWNER_EXECUTE,
- PosixFilePermission.OWNER_READ,
- PosixFilePermission.OWNER_WRITE
- )
- )
- }
-
- companion object {
- const val DEFAULT_MODULE_CLIENT_SUFFIX = "Module"
- }
-}
diff --git a/kotlin-runtime/ftl-generator/src/main/kotlin/xyz/block/ftl/generator/main.kt b/kotlin-runtime/ftl-generator/src/main/kotlin/xyz/block/ftl/generator/main.kt
deleted file mode 100644
index feb9070097..0000000000
--- a/kotlin-runtime/ftl-generator/src/main/kotlin/xyz/block/ftl/generator/main.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-package xyz.block.ftl.generator
-
-import com.github.ajalt.clikt.core.CliktCommand
-import com.github.ajalt.clikt.parameters.options.default
-import com.github.ajalt.clikt.parameters.options.option
-import com.github.ajalt.clikt.parameters.options.required
-import xyz.block.ftl.generator.ModuleGenerator.Companion.DEFAULT_MODULE_CLIENT_SUFFIX
-import java.io.File
-
-class Main : CliktCommand() {
- val endpoint by option(help = "FTL endpoint.").required()
- val dest by option(help = "Destination directory for generated code.").required()
- val module by option(help = "The FTL module name we're working on.").required()
- val moduleClientSuffix by option(
- help = "The suffix appended to FTL-generated client classes for other modules in this cluster."
- ).default(DEFAULT_MODULE_CLIENT_SUFFIX)
-
- override fun run() {
- val client = FTLClient(endpoint)
- val schema = client.getSchema()!!
- val outputDirectory = File(dest)
- outputDirectory.deleteRecursively()
- val gen = ModuleGenerator()
- gen.run(schema, outputDirectory, module, moduleClientSuffix)
- }
-}
-
-fun main(args: Array) = Main().main(args)
diff --git a/kotlin-runtime/ftl-generator/src/test/kotlin/xyz/block/ftl/generator/ModuleGeneratorTest.kt b/kotlin-runtime/ftl-generator/src/test/kotlin/xyz/block/ftl/generator/ModuleGeneratorTest.kt
deleted file mode 100644
index d5c8655adb..0000000000
--- a/kotlin-runtime/ftl-generator/src/test/kotlin/xyz/block/ftl/generator/ModuleGeneratorTest.kt
+++ /dev/null
@@ -1,338 +0,0 @@
-package xyz.block.ftl.generator
-
-import org.junit.jupiter.api.BeforeEach
-import org.junit.jupiter.api.Test
-import xyz.block.ftl.v1.schema.*
-import xyz.block.ftl.v1.schema.Array
-import xyz.block.ftl.v1.schema.Float
-import xyz.block.ftl.v1.schema.Int
-import xyz.block.ftl.v1.schema.Map
-import xyz.block.ftl.v1.schema.String
-import kotlin.test.assertEquals
-
-class ModuleGeneratorTest {
- private lateinit var generator: ModuleGenerator
-
- @BeforeEach
- fun setUp() {
- generator = ModuleGenerator()
- }
-
- @Test
- fun `should generate basic module`() {
- val file = generator.generateModule(Module(name = "test"))
- val expected = """// Code generated by FTL-Generator, do not edit.
-//
-package ftl.test
-
-"""
- assertEquals(expected, file.toString())
- }
-
- @Test
- fun `should generate all Types`() {
- val decls = listOf(
- Decl(
- data_ = Data(
- name = "ParamTestData",
- typeParameters = listOf(TypeParameter(name = "T")),
- fields = listOf(
- Field(name = "t", type = Type(dataRef = DataRef(name = "T"))),
- )
- )
- ),
- Decl(
- data_ = Data(
- comments = listOf("Response comments"), name = "TestResponse",
- fields = listOf(
- Field(name = "int", type = Type(int = Int())),
- Field(name = "float", type = Type(float = Float())),
- Field(name = "string", type = Type(string = String())),
- Field(name = "bytes", type = Type(bytes = Bytes())),
- Field(name = "bool", type = Type(bool = Bool())),
- Field(name = "time", type = Type(time = Time())),
- Field(name = "optional", type = Type(optional = Optional(type = Type(string = String())))),
- Field(name = "array", type = Type(array = Array(element = Type(string = String())))),
- Field(
- name = "nestedArray", type = Type(
- array = Array(element = Type(array = Array(element = Type(string = String()))))
- )
- ),
- Field(
- name = "dataRefArray", type = Type(
- array = Array(element = Type(dataRef = DataRef(name = "TestRequest", module = "test")))
- )
- ),
- Field(
- name = "map",
- type = Type(map = Map(key = Type(string = String()), value_ = Type(int = Int())))
- ),
- Field(
- name = "nestedMap", type = Type(
- map = Map(
- key = Type(string = String()),
- value_ = Type(map = Map(key = Type(string = String()), value_ = Type(int = Int())))
- )
- )
- ),
- Field(name = "dataRef", type = Type(dataRef = DataRef(name = "TestRequest"))),
- Field(name = "externalDataRef", type = Type(dataRef = DataRef(module = "other", name = "TestRequest"))),
- Field(name = "any", type = Type(any = xyz.block.ftl.v1.schema.Any())),
- Field(
- name = "parameterizedDataRef", type = Type(
- dataRef = DataRef(
- name = "ParamTestData",
- typeParameters = listOf(Type(dataRef = DataRef(name = "T")))
- )
- )
- ),
- Field(name = "withAlias", type = Type(string = String()), jsonAlias = "a"),
- )
- )
- ),
- )
- val module = Module(name = "test", comments = listOf("Module comments"), decls = decls)
-
- val file = generator.generateModule(module)
- val expected = """// Code generated by FTL-Generator, do not edit.
-// Module comments
-package ftl.test
-
-import java.time.OffsetDateTime
-import kotlin.Any
-import kotlin.Boolean
-import kotlin.ByteArray
-import kotlin.Float
-import kotlin.Long
-import kotlin.String
-import kotlin.collections.ArrayList
-import kotlin.collections.Map
-import xyz.block.ftl.Json
-
-public data class ParamTestData(
- public val t: T,
-)
-
-/**
- * Response comments
- */
-public data class TestResponse(
- public val int: Long,
- public val float: Float,
- public val string: String,
- public val bytes: ByteArray,
- public val bool: Boolean,
- public val time: OffsetDateTime,
- public val optional: String? = null,
- public val array: ArrayList,
- public val nestedArray: ArrayList>,
- public val dataRefArray: ArrayList,
- public val map: Map,
- public val nestedMap: Map>,
- public val dataRef: TestRequest,
- public val externalDataRef: ftl.other.TestRequest,
- public val any: Any,
- public val parameterizedDataRef: ParamTestData,
- @Json("a")
- public val withAlias: String,
-)
-"""
- assertEquals(expected, file.toString())
- }
-
- @Test
- fun `should generate all Verbs`() {
- val decls = listOf(
- Decl(
- verb = Verb(
- name = "TestVerb",
- comments = listOf("TestVerb comments"),
- request = Type(dataRef = DataRef(name = "Empty", module = "builtin")),
- response = Type(dataRef = DataRef(name = "Empty", module = "builtin"))
- )
- ),
- Decl(
- verb = Verb(
- name = "TestIngressVerb",
- comments = listOf("TestIngressVerb comments"),
- request = Type(dataRef = DataRef(name = "Empty", module = "builtin")),
- response = Type(dataRef = DataRef(name = "Empty", module = "builtin")),
- metadata = listOf(
- Metadata(
- ingress = MetadataIngress(
- type = "http",
- path = listOf(IngressPathComponent(ingressPathLiteral = IngressPathLiteral(text = "test"))),
- method = "GET"
- )
- ),
- )
- )
- ),
- )
- val module = Module(name = "test", comments = listOf("Module comments"), decls = decls)
- val file = generator.generateModule(module)
- val expected = """// Code generated by FTL-Generator, do not edit.
-// Module comments
-package ftl.test
-
-import ftl.builtin.Empty
-import xyz.block.ftl.Context
-import xyz.block.ftl.HttpIngress
-import xyz.block.ftl.Ignore
-import xyz.block.ftl.Method.GET
-import xyz.block.ftl.Verb
-
-/**
- * TestVerb comments
- */
-@Verb
-@Ignore
-public fun TestVerb(context: Context, req: Empty): Empty = throw
- NotImplementedError("Verb stubs should not be called directly, instead use context.call(::TestVerb, ...)")
-
-/**
- * TestIngressVerb comments
- */
-@Verb
-@Ignore
-@HttpIngress(
- GET,
- "/test",
-)
-public fun TestIngressVerb(context: Context, req: Empty): Empty = throw
- NotImplementedError("Verb stubs should not be called directly, instead use context.call(::TestIngressVerb, ...)")
-"""
- assertEquals(expected, file.toString())
- }
-
- @Test
- fun `builtins are handled correctly`() {
- val decls = listOf(
- Decl(
- data_ = Data(
- comments = listOf("HTTP request structure used for HTTP ingress verbs."),
- name = "HttpRequest",
- fields = listOf(
- Field(name = "method", type = Type(string = String())),
- Field(name = "path", type = Type(string = String())),
- Field(
- name = "pathParameters",
- type = Type(map = Map(key = Type(string = String()), value_ = Type(string = String())))
- ),
- Field(
- name = "query",
- type = Type(
- map = Map(
- key = Type(string = String()),
- value_ = Type(array = Array(element = Type(string = String())))
- )
- )
- ),
- Field(
- name = "headers",
- type = Type(
- map = Map(
- key = Type(string = String()),
- value_ = Type(array = Array(element = Type(string = String())))
- )
- )
- ),
- Field(name = "body", type = Type(dataRef = DataRef(name = "Body")))
- ),
- typeParameters = listOf(TypeParameter(name = "Body"))
- )
- ),
- Decl(
- data_ = Data(
- comments = listOf("HTTP response structure used for HTTP ingress verbs."),
- name = "HttpResponse",
- fields = listOf(
- Field(name = "status", type = Type(int = Int())),
- Field(
- name = "headers",
- type = Type(
- map = Map(
- key = Type(string = String()),
- value_ = Type(array = Array(element = Type(string = String())))
- )
- )
- ),
- Field(name = "body", type = Type(dataRef = DataRef(name = "Body")))
- ),
- typeParameters = listOf(TypeParameter(name = "Body"))
- )
- ),
- Decl(data_ = Data(name = "Empty")),
- )
- val module = Module(name = "builtin", comments = listOf("Built-in types for FTL"), decls = decls)
- val file = generator.generateModule(module)
- val expected = """// Code generated by FTL-Generator, do not edit.
-// Built-in types for FTL
-package ftl.builtin
-
-import kotlin.Long
-import kotlin.String
-import kotlin.collections.ArrayList
-import kotlin.collections.Map
-
-/**
- * HTTP request structure used for HTTP ingress verbs.
- */
-public data class HttpRequest(
- public val method: String,
- public val path: String,
- public val pathParameters: Map,
- public val query: Map>,
- public val headers: Map>,
- public val body: Body,
-)
-
-/**
- * HTTP response structure used for HTTP ingress verbs.
- */
-public data class HttpResponse(
- public val status: Long,
- public val headers: Map>,
- public val body: Body,
-)
-
-public class Empty
-"""
- assertEquals(expected, file.toString())
- }
-
- @Test
- fun `generates empty data refs`() {
- val file = generator.generateModule(
- Module(
- name = "test",
- decls = listOf(
- Decl(data_ = Data(name = "EmptyRequest")),
- Decl(data_ = Data(name = "EmptyResponse")),
- Decl(
- verb = Verb(
- name = "EmptyVerb",
- request = Type(dataRef = DataRef(name = "EmptyRequest")),
- response = Type(dataRef = DataRef(name = "EmptyResponse"))
- )
- )
- )
- )
- )
- val expected = """// Code generated by FTL-Generator, do not edit.
-//
-package ftl.test
-
-import ftl.builtin.Empty
-import xyz.block.ftl.Context
-import xyz.block.ftl.Ignore
-import xyz.block.ftl.Verb
-
-@Verb
-@Ignore
-public fun EmptyVerb(context: Context, req: Empty): Empty = throw
- NotImplementedError("Verb stubs should not be called directly, instead use context.call(::EmptyVerb, ...)")
-"""
- assertEquals(expected, file.toString())
- }
-}
diff --git a/pom.xml b/pom.xml
index 2f050332f6..c30fd7e288 100644
--- a/pom.xml
+++ b/pom.xml
@@ -46,7 +46,6 @@
kotlin-runtime/ftl-runtime
- kotlin-runtime/ftl-generator
@@ -344,7 +343,6 @@
release
kotlin-runtime/ftl-runtime
- kotlin-runtime/ftl-generator