Exemplo n.º 1
0
        public static string GenerateGlueCode(TypescriptGenerationOptions opts, IEnumerable <Type> types)
        {
            var ctx  = new TypescriptTypeMapping(opts);
            var code = new TypescriptCodeBuilder();

            var ctor   = new List <string>();
            var fields = new List <string>();


            foreach (var type in types)
            {
                var proxyClassName = "CoreRpcProxyFor" + type.Name;
                var proxyFieldName = opts.ApiFieldNamingPolicy(type);
                code.BeginClass(proxyClassName);
                code.AppendLines(
                    $"private parent: {opts.ClassName};",
                    $"constructor (parent: {opts.ClassName}){{this.parent = parent;}}"
                    );
                var target = opts.TargetNameExtractor.GetTargetName(type);
                foreach (var m in type.GetMethods())
                {
                    if (m.DeclaringType == typeof(System.Object))
                    {
                        continue;
                    }
                    var sig = Convert.ToBase64String(opts.Binder.GetMethodSignature(m));


                    code.BeginMethod(opts.ApiMethodNamingPolicy(m.Name));
                    var names = new List <string>();
                    foreach (var p in m.GetParameters())
                    {
                        code.AppendMethodParameter(p.Name, ctx.MapType(p.ParameterType));
                        names.Add(p.Name);
                    }
                    var returnType = m.ReturnType;
                    if (returnType == typeof(Task))
                    {
                        returnType = typeof(void);
                    }
                    else if (returnType.IsConstructedGenericType &&
                             returnType.GetGenericTypeDefinition() == typeof(Task <>))
                    {
                        returnType = returnType.GetGenericArguments()[0];
                    }
                    var returnTypeName = ctx.MapType(returnType);
                    code.AppendMethodReturnValueAndBeginBody("Promise<" + returnTypeName + ">");

                    var req =
                        $"{{Target: '{target}', MethodSignature: '{sig}', Arguments: [{string.Join(",", names)}] }}";
                    code.AppendLine($"return this.parent.send<{returnTypeName}>({req});");
                    code.End();
                }
                code.End();
                fields.Add($"{proxyFieldName} : " + proxyClassName + ";");
                ctor.Add($"this.{proxyFieldName} = new {proxyClassName}(this);");
            }

            var resultFieldName    = "Result";
            var exceptionFieldName = "Exception";


            code.BeginClass(opts.ClassName);
            code.AppendLines(
                "private baseUrl: string;",
                "private fetch: (url: string, init: RequestInit) => Promise<Response>;",

                "constructor(baseUrl : string, customFetch?: (url: string, init: RequestInit) => Promise<Response>) {",
                "this.baseUrl = baseUrl;",
                "if(customFetch) this.fetch = customFetch; else this.fetch =  (r, i) => fetch(r, i);"
                );
            code.AppendLines(ctor.ToArray());
            code.AppendLine("}");


            code.AppendLines(
                "public send<T>(request: any) : Promise<T>{",
                "return this.fetch(this.baseUrl, {method: 'post', body: JSON.stringify(request)})",
                "    .then(response => {",
                "        if (!response.ok)",
                "            throw new Error(response.statusText);",
                "         return response.json();",
                "    }).then(jr => {",
                $"        const r = <{{{resultFieldName}?: T, {exceptionFieldName}?: string}}>jr;",
                $"        if(r.{exceptionFieldName}) throw r.{exceptionFieldName};",
                $"        return r.{resultFieldName}!;",
                "    });",
                "}"
                );
            code.AppendLines(fields.ToArray());
            code.End();

            return((ctx + "\n" + code).Replace("\r\n", "\n"));
        }