Skip to content

Commit

Permalink
Add javascript types for AST (#129)
Browse files Browse the repository at this point in the history
  • Loading branch information
wilmveel authored Nov 21, 2023
1 parent 427a003 commit 73c2f9d
Show file tree
Hide file tree
Showing 3 changed files with 213 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/compiler/lib/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ repositories {
kotlin {
js {
nodejs()
generateTypeScriptDefinitions()
binaries.library()
compilations["main"].packageJson {
customField("name", "@flock/wirespec")
Expand All @@ -34,6 +35,7 @@ kotlin {
dependencies {
implementation(project(":src:compiler:cli"))
implementation(project(":src:compiler:core"))
implementation(project(":src:openapi"))
}
}
val jsMain by getting {
Expand Down
196 changes: 195 additions & 1 deletion src/compiler/lib/src/jsMain/kotlin/Ast.kt
Original file line number Diff line number Diff line change
@@ -1,3 +1,197 @@
import community.flock.wirespec.compiler.core.parse.nodes.Endpoint
import community.flock.wirespec.compiler.core.parse.nodes.Enum
import community.flock.wirespec.compiler.core.parse.nodes.Node
import community.flock.wirespec.compiler.core.parse.nodes.Refined
import community.flock.wirespec.compiler.core.parse.nodes.Type

@ExperimentalJsExport
internal fun List<Node>.produce(): Array<WsNode> = map {
when (it) {
is Type -> WsType(it.name, it.shape.produce())
is Endpoint -> WsEndpoint(
name = it.name,
method = it.method.produce(),
path= it.path.produce(),
query= it.query.produce(),
headers= it.headers.produce(),
cookies= it.cookies.produce(),
requests= it.requests.produce(),
responses= it.responses.produce(),

)
is Enum -> WsEnum(it.name, it.entries.toTypedArray())
is Refined -> WsRefined(it.name, it.validator.value)
}
}.toTypedArray()

private fun Type.Shape.produce() = WsShape(
value.map { it.produce() }.toTypedArray()
)

@ExperimentalJsExport
private fun List<Endpoint.Segment>.produce(): Array<WsSegment> = map{when(it){
is Endpoint.Segment.Literal -> WsLiteral(it.value)
is Endpoint.Segment.Param -> WsParam(it.identifier.produce(), it.reference.produce())
}}.toTypedArray()

@ExperimentalJsExport
private fun Type.Shape.Field.produce() = WsField(identifier.produce(), reference.produce(), isNullable)

@ExperimentalJsExport
private fun List<Type.Shape.Field>.produce() = map{it.produce()}.toTypedArray()

@ExperimentalJsExport
private fun Type.Shape.Field.Identifier.produce() = WsIdentifier(this.value)

@ExperimentalJsExport
private fun Type.Shape.Field.Reference.produce() = when(this){
is Type.Shape.Field.Reference.Any -> WsAny(isIterable, isMap)
is Type.Shape.Field.Reference.Custom -> WsCustom(value, isIterable, isMap)
is Type.Shape.Field.Reference.Primitive -> WsPrimitive(type.produce(), isIterable, isMap)
}

@ExperimentalJsExport
private fun Type.Shape.Field.Reference.Primitive.Type.produce() = when(this){
Type.Shape.Field.Reference.Primitive.Type.String -> WsPrimitiveType.String
Type.Shape.Field.Reference.Primitive.Type.Integer -> WsPrimitiveType.Integer
Type.Shape.Field.Reference.Primitive.Type.Number -> WsPrimitiveType.Number
Type.Shape.Field.Reference.Primitive.Type.Boolean -> WsPrimitiveType.Boolean
}

@ExperimentalJsExport
private fun Endpoint.Method.produce() = when (this){
Endpoint.Method.GET -> WsMethod.GET
Endpoint.Method.POST -> WsMethod.POST
Endpoint.Method.PUT -> WsMethod.PUT
Endpoint.Method.DELETE -> WsMethod.DELETE
Endpoint.Method.OPTIONS -> WsMethod.OPTIONS
Endpoint.Method.HEAD -> WsMethod.HEAD
Endpoint.Method.PATCH -> WsMethod.PATCH
Endpoint.Method.TRACE -> WsMethod.TRACE
}

@ExperimentalJsExport
private fun Endpoint.Content.produce() = WsContent(type, reference.produce(), isNullable)

@ExperimentalJsExport
private fun Endpoint.Request.produce() = WsRequest(content?.produce())

@ExperimentalJsExport
private fun List<Endpoint.Request>.produce() = map{it.produce()}.toTypedArray()


@ExperimentalJsExport
private fun Endpoint.Response.produce() = WsResponse(status, content?.produce())

@ExperimentalJsExport
private fun List<Endpoint.Response>.produce() = map{it.produce()}.toTypedArray()
@JsExport
@ExperimentalJsExport
sealed interface WsNode

@JsExport
@ExperimentalJsExport
data class WsType(val name: String, val shape: WsShape) : WsNode

@JsExport
@ExperimentalJsExport
data class WsShape(val value: Array<WsField>)


@JsExport
@ExperimentalJsExport
data class WsEndpoint(
val name: String,
val method: WsMethod,
val path: Array<WsSegment>,
val query: Array<WsField>,
val headers: Array<WsField>,
val cookies: Array<WsField>,
val requests: Array<WsRequest>,
val responses: Array<WsResponse>
) : WsNode

@JsExport
@ExperimentalJsExport
data class WsEnum(val name: String, val entries: Array<String>) : WsNode

@JsExport
@ExperimentalJsExport
data class WsRefined(val name: String, val validator: String) : WsNode

@JsExport
@ExperimentalJsExport
enum class WsMethod { GET, POST, PUT, DELETE, OPTIONS, HEAD, PATCH, TRACE }

@JsExport
@ExperimentalJsExport
sealed interface WsSegment

@JsExport
@ExperimentalJsExport
data class WsLiteral(val value: String) : WsSegment
@JsExport
@ExperimentalJsExport
data class WsParam(
val identifier: WsIdentifier,
val reference: WsReference
) : WsSegment


@JsExport
@ExperimentalJsExport
data class Shape(val value: Array<WsField>)

@JsExport
@ExperimentalJsExport
data class WsField(val identifier: WsIdentifier, val reference: WsReference, val isNullable: Boolean) {

}

@JsExport
@ExperimentalJsExport
data class WsIdentifier(val value: String)

@JsExport
@ExperimentalJsExport
sealed interface WsReference {
val isIterable: Boolean
val isMap: Boolean


}

@JsExport
@ExperimentalJsExport
data class WsAny(override val isIterable: Boolean, override val isMap: Boolean = false) : WsReference
@JsExport
@ExperimentalJsExport
data class WsCustom(
val value: String,
override val isIterable: Boolean,
override val isMap: Boolean = false
) : WsReference

@JsExport
@ExperimentalJsExport
data class WsPrimitive(
val type: WsPrimitiveType,
override val isIterable: Boolean,
override val isMap: Boolean = false
) : WsReference

@JsExport
@ExperimentalJsExport
enum class WsPrimitiveType { String, Integer, Number, Boolean }

@JsExport
@ExperimentalJsExport
data class WsRequest(val content: WsContent?)

@JsExport
@ExperimentalJsExport
data class WsResponse(val status: String, val content: WsContent?)

@JsExport
@ExperimentalJsExport
class Ast(val value: Array<String>)
data class WsContent(val type: String, val reference: WsReference, val isNullable: Boolean = false)
17 changes: 16 additions & 1 deletion src/compiler/lib/src/jsMain/kotlin/Compiler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import community.flock.wirespec.compiler.core.emit.WirespecEmitter
import community.flock.wirespec.compiler.core.parse.Parser
import community.flock.wirespec.compiler.core.tokenize.tokenize
import community.flock.wirespec.compiler.utils.Logger
import community.flock.wirespec.openapi.v2.OpenApiParser as OpenApiParserV2
import community.flock.wirespec.openapi.v3.OpenApiParser as OpenApiParserV3

@JsExport
@ExperimentalJsExport
Expand All @@ -17,7 +19,6 @@ abstract class Compiler {

fun parse(source: String) = Wirespec.tokenize(source)
.let { Parser(logger).parse(it) }
.let { Ast(arrayOf()) }

companion object {
protected val logger = object : Logger() {}
Expand Down Expand Up @@ -53,3 +54,17 @@ class WsToWirespec : Compiler() {
private val wirespecEmitter = WirespecEmitter(logger)
}
}

@JsExport
@ExperimentalJsExport
class OpenApiV2 {
fun parse(source: String):Array<WsNode> = OpenApiParserV2.parse(source).produce()

}

@JsExport
@ExperimentalJsExport
class OpenApiV3 {
fun parse(source: String):Array<WsNode> = OpenApiParserV3.parse(source).produce()

}

0 comments on commit 73c2f9d

Please sign in to comment.