ts format (#302)

This commit is contained in:
Dima 2021-09-14 13:46:48 +03:00 committed by GitHub
parent 84141bbcc4
commit c4248640af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 111 additions and 117 deletions

View File

@ -14,7 +14,7 @@ object TypeScriptCommon {
case pt: ProductType => case pt: ProductType =>
"[" + pt.toList.map(typeToTs).mkString(", ") + "]" "[" + pt.toList.map(typeToTs).mkString(", ") + "]"
case st: StructType => case st: StructType =>
s"{${st.fields.map(typeToTs).toNel.map(kv => kv._1 + ":" + kv._2).toList.mkString(";")}}" s"{ ${st.fields.map(typeToTs).toNel.map(kv => kv._1 + ": " + kv._2).toList.mkString("; ")} }"
case st: ScalarType if ScalarType.number(st) => "number" case st: ScalarType if ScalarType.number(st) => "number"
case ScalarType.bool => "boolean" case ScalarType.bool => "boolean"
case ScalarType.string => "string" case ScalarType.string => "string"
@ -66,7 +66,7 @@ object TypeScriptCommon {
def argsCallToTs(at: ArrowType): List[String] = def argsCallToTs(at: ArrowType): List[String] =
FuncRes.arrowArgIndices(at).map(idx => s"args[$idx]") FuncRes.arrowArgIndices(at).map(idx => s"args[$idx]")
def callBackExprBody(at: ArrowType, callbackName: String): String = { def callBackExprBody(at: ArrowType, callbackName: String, leftSpace: Int): String = {
val arrowArgumentsToCallbackArgumentsList = val arrowArgumentsToCallbackArgumentsList =
at.domain.toList at.domain.toList
.zipWithIndex .zipWithIndex
@ -101,16 +101,16 @@ object TypeScriptCommon {
}) })
.mkString(",") .mkString(",")
s""" val left = " " * leftSpace
| const callParams = {
| ...req.particleContext, s"""${left}const callParams = {
| tetraplets: { |$left ...req.particleContext,
| ${tetraplets} |$left tetraplets: {
| }, |$left ${tetraplets}
| }; |$left },
| resp.retCode = ResultCodes.success; |$left};
| ${callCallbackStatementAndReturn} |${left}resp.retCode = ResultCodes.success;
|""".stripMargin |$left${callCallbackStatementAndReturn}""".stripMargin
} }
} }

View File

@ -12,7 +12,6 @@ case class TypeScriptFile(res: AquaRes) {
| |
|// Services |// Services
|${res.services.map(TypeScriptService(_)).map(_.generate).toList.mkString("\n\n")} |${res.services.map(TypeScriptService(_)).map(_.generate).toList.mkString("\n\n")}
|
|// Functions |// Functions
|${res.funcs.map(TypeScriptFunc(_)).map(_.generate).toList.mkString("\n\n")} |${res.funcs.map(TypeScriptFunc(_)).map(_.generate).toList.mkString("\n\n")}
|""".stripMargin |""".stripMargin

View File

@ -15,34 +15,32 @@ case class TypeScriptFunc(func: FuncRes) {
val respBody = func.returnType match { val respBody = func.returnType match {
case Some(x) => x match { case Some(x) => x match {
case OptionType(_) => case OptionType(_) =>
""" let [opt] = args; """ let [opt] = args;
| if (Array.isArray(opt)) { | if (Array.isArray(opt)) {
| if (opt.length === 0) { resolve(null); } | if (opt.length === 0) { resolve(null); }
| opt = opt[0]; | opt = opt[0];
| } | }
| return resolve(opt);""".stripMargin | return resolve(opt);""".stripMargin
case pt: ProductType => case pt: ProductType =>
val unwrapOpts = pt.toList.zipWithIndex.collect { case (OptionType(_), i) => val unwrapOpts = pt.toList.zipWithIndex.collect { case (OptionType(_), i) =>
s""" s""" if( Array.isArray(opt[$i])) {
| if(Array.isArray(opt[$i])) { | if (opt[$i].length === 0) { opt[$i] = null; }
| if (opt[$i].length === 0) { opt[$i] = null; } | else {opt[$i] = opt[$i][0]; }
| else {opt[$i] = opt[$i][0]; } | }""".stripMargin
| }""".stripMargin
}.mkString }.mkString
s""" let opt: any = args; s""" let opt: any = args;
|$unwrapOpts |$unwrapOpts
| return resolve(opt);""".stripMargin | return resolve(opt);""".stripMargin
case _ => case _ =>
""" const [res] = args; """ const [res] = args;
| resolve(res);""".stripMargin | resolve(res);""".stripMargin
} }
case None => "" case None => ""
} }
s"""h.onEvent('$callbackServiceId', '$respFuncName', (args) => { s""" h.onEvent('$callbackServiceId', '$respFuncName', (args) => {
| $respBody |$respBody
|}); | });""".stripMargin
|""".stripMargin
def generate: String = { def generate: String = {
@ -53,17 +51,16 @@ case class TypeScriptFunc(func: FuncRes) {
val setCallbacks = func.args.collect { // Product types are not handled val setCallbacks = func.args.collect { // Product types are not handled
case Arg(argName, OptionType(_)) => case Arg(argName, OptionType(_)) =>
s"""h.on('$dataServiceId', '$argName', () => {return ${fixupArgName(argName)} === null ? [] : [${fixupArgName(argName)}];});""" s""" h.on('$dataServiceId', '$argName', () => {return ${fixupArgName(argName)} === null ? [] : [${fixupArgName(argName)}];});"""
case Arg(argName, _: DataType) => case Arg(argName, _: DataType) =>
s"""h.on('$dataServiceId', '$argName', () => {return ${fixupArgName(argName)};});""" s""" h.on('$dataServiceId', '$argName', () => {return ${fixupArgName(argName)};});"""
case Arg(argName, at: ArrowType) => case Arg(argName, at: ArrowType) =>
s""" s""" h.use((req, resp, next) => {
| h.use((req, resp, next) => { | if(req.serviceId === '${conf.callbackService}' && req.fnName === '$argName') {
| if(req.serviceId === '${conf.callbackService}' && req.fnName === '$argName') { |${callBackExprBody(at, argName, 28)}
| ${callBackExprBody(at, argName)} | }
| } | next();
| next(); | });
| });
""".stripMargin """.stripMargin
} }
.mkString("\n") .mkString("\n")
@ -86,7 +83,7 @@ case class TypeScriptFunc(func: FuncRes) {
var funcTypeOverload1 = argsTypescript.mkString(", ") var funcTypeOverload1 = argsTypescript.mkString(", ")
var funcTypeOverload2 = ("peer: FluencePeer" :: argsTypescript).mkString(", ") var funcTypeOverload2 = ("peer: FluencePeer" :: argsTypescript).mkString(", ")
val argsLets = args.map(arg => s"let ${fixupArgName(arg.name)}: any;").mkString("\n") val argsLets = args.map(arg => s" let ${fixupArgName(arg.name)}: any;").mkString("\n")
val argsFormAssingment = args val argsFormAssingment = args
.map(arg => fixupArgName(arg.name)) .map(arg => fixupArgName(arg.name))
@ -96,60 +93,62 @@ case class TypeScriptFunc(func: FuncRes) {
// argument upnacking has two forms. // argument upnacking has two forms.
// One starting from the first (by index) argument, // One starting from the first (by index) argument,
// One starting from zero // One starting from zero
val argsAssignmentStartingFrom1 = argsFormAssingment.map((name, ix) => s"${name} = args[${ix + 1}];").mkString("\n") val argsAssignmentStartingFrom1 = argsFormAssingment.map((name, ix) => s" ${name} = args[${ix + 1}];").mkString("\n")
val argsAssignmentStartingFrom0 = argsFormAssingment.map((name, ix) => s"${name} = args[${ix}];").mkString("\n") val argsAssignmentStartingFrom0 = argsFormAssingment.map((name, ix) => s" ${name} = args[${ix}];").mkString("\n")
val funcTypeRes = s"Promise<$retTypeTs>" val funcTypeRes = s"Promise<$retTypeTs>"
val codeLeftSpace = " " * 20
s""" s"""
| export function ${func.funcName}(${funcTypeOverload1}) : ${funcTypeRes}; |export function ${func.funcName}(${funcTypeOverload1}) : ${funcTypeRes};
| export function ${func.funcName}(${funcTypeOverload2}) : ${funcTypeRes}; |export function ${func.funcName}(${funcTypeOverload2}) : ${funcTypeRes};
| export function ${func.funcName}(...args: any) { |export function ${func.funcName}(...args: any) {
| let peer: FluencePeer; | let peer: FluencePeer;
| ${argsLets} |${argsLets}
| let config: any; | let config: any;
| if (FluencePeer.isInstance(args[0])) { | if (FluencePeer.isInstance(args[0])) {
| peer = args[0]; | peer = args[0];
| ${argsAssignmentStartingFrom1} |${argsAssignmentStartingFrom1}
| } else { | } else {
| peer = Fluence.getPeer(); | peer = Fluence.getPeer();
| ${argsAssignmentStartingFrom0} |${argsAssignmentStartingFrom0}
| } | }
| |
| let request: RequestFlow; | let request: RequestFlow;
| const promise = new Promise<$retTypeTs>((resolve, reject) => { | const promise = new Promise<$retTypeTs>((resolve, reject) => {
| const r = new RequestFlowBuilder() | const r = new RequestFlowBuilder()
| .disableInjections() | .disableInjections()
| .withRawScript( | .withRawScript(`
| ` |${tsAir.show.linesIterator.map(codeLeftSpace + _).mkString("\n")}
| ${tsAir.show} | `,
| `, | )
| ) | .configHandler((h) => {
| .configHandler((h) => { | ${conf.relayVarName.fold("") { r =>
| ${conf.relayVarName.fold("") { r =>
s"""h.on('${conf.getDataService}', '$r', () => { s"""h.on('${conf.getDataService}', '$r', () => {
| return peer.getStatus().relayPeerId; | return peer.getStatus().relayPeerId;
| });""".stripMargin }} | });""".stripMargin }}
| $setCallbacks |$setCallbacks
| $returnCallback |$returnCallback
| h.onEvent('${conf.errorHandlingService}', '${conf.errorFuncName}', (args) => { | h.onEvent('${conf.errorHandlingService}', '${conf.errorFuncName}', (args) => {
| const [err] = args; | const [err] = args;
| reject(err); | reject(err);
| }); | });
| }) | })
| .handleScriptError(reject) | .handleScriptError(reject)
| .handleTimeout(() => { | .handleTimeout(() => {
| reject('Request timed out for ${func.funcName}'); | reject('Request timed out for ${func.funcName}');
| }) | })
| if(${configArgName} && ${configArgName}.ttl) { |
| r.withTTL(${configArgName}.ttl) | if (${configArgName} && ${configArgName}.ttl) {
| } | r.withTTL(${configArgName}.ttl)
| request = r.build(); | }
|
| request = r.build();
| }); | });
| peer.internals.initiateFlow(request!); | peer.internals.initiateFlow(request!);
| return ${returnVal}; | return ${returnVal};
|} |}""".stripMargin
""".stripMargin
} }
} }

View File

@ -11,11 +11,9 @@ case class TypeScriptService(srv: ServiceRes) {
import TypeScriptCommon._ import TypeScriptCommon._
def fnHandler(arrow: ArrowType, memberName: String) = { def fnHandler(arrow: ArrowType, memberName: String) = {
s""" s"""if (req.fnName === '${memberName}') {
| if (req.fnName === '${memberName}') { |${callBackExprBody(arrow, "service." + memberName, 12)}
| ${callBackExprBody(arrow, "service." + memberName)} }""".stripMargin
| }
""".stripMargin
} }
def generate: String = def generate: String =
@ -66,27 +64,25 @@ case class TypeScriptService(srv: ServiceRes) {
// This variable contain defines the list of lists where // This variable contain defines the list of lists where
// the outmost list describes the list of overloads // the outmost list describes the list of overloads
// and the innermost one defines the list of arguments in the overload // and the innermost one defines the list of arguments in the overload
val registerServiceArgs = registerServiceArgsSource. val registerServiceArgs = registerServiceArgsSource.map{ x =>
map(x => {
val args = x.mkString(", ") val args = x.mkString(", ")
s"export function ${registerName}(${args}): void;" s"export function ${registerName}(${args}): void;"
}) }
.mkString("\n"); .mkString("\n");
val defaultServiceIdBranch = srv.defaultId.fold("")(x => val defaultServiceIdBranch = srv.defaultId.fold("")(x =>
s""" s"""else {
| else { | serviceId = ${x}
| serviceId = ${x} | }""".stripMargin
|}""".stripMargin
) )
s""" s"""
| export interface ${serviceTypeName} { |export interface ${serviceTypeName} {
| ${fnDefs} | ${fnDefs}
| } |}
| |
| ${registerServiceArgs} |$registerServiceArgs
| export function ${registerName}(...args: any) { |export function ${registerName}(...args: any) {
| let peer: FluencePeer; | let peer: FluencePeer;
| let serviceId: any; | let serviceId: any;
| let service: any; | let service: any;
@ -115,16 +111,16 @@ case class TypeScriptService(srv: ServiceRes) {
| service = args[2]; | service = args[2];
| } | }
| |
| peer.internals.callServiceHandler.use((req, resp, next) => { | peer.internals.callServiceHandler.use((req, resp, next) => {
| if (req.serviceId !== serviceId) { | if (req.serviceId !== serviceId) {
| next(); | next();
| return; | return;
| } | }
| |
| ${fnHandlers} | ${fnHandlers}
| |
| next(); | next();
| }); | });
| } |}
""".stripMargin """.stripMargin
} }