예제 #1
0
 protected void OutputInterface(TypeScriptWriter writer, ApiInterfaceDesc i)
 {
     writer.Write($"interface {getName(i.TsName)}");
     if (i.Extends.Any())
     {
         writer.Write(" extends ");
         writer.Write(i.Extends.Select(e => getNamespace(e.TsName) == getNamespace(i.TsName) ? getName(e.TsName) : e.TsName).Order().JoinString(", "));
     }
     writer.WriteLine(" {");
     using (writer.Indent())
     {
         foreach (var prop in i.Properties.OrderBy(p => p.TsName))
         {
             writer.WriteLine($"{prop.TsName}: {prop.TsType.GetTypeScript()};");
         }
     }
     writer.WriteLine("}");
 }
예제 #2
0
        protected void OutputService(TypeScriptWriter writer, ApiServiceDesc s)
        {
            _convertersUsedFrom = new HashSet <TypeConverter>();
            _convertersUsedTo   = new HashSet <TypeConverter>();
            writer.WriteLine($"export class {s.Name}Service extends ApiServiceBase {{");
            writer.WriteLine();
            using (writer.Indent())
            {
                writer.WriteLine("private _hostname: string;");
                writer.WriteLine();
                writer.WriteLine("public constructor(hostname: string) {");
                using (writer.Indent())
                {
                    writer.WriteLine("super();");
                    writer.WriteLine("this._hostname = (hostname.substr(-1) == '/') ? hostname : hostname + '/';");
                }
                writer.WriteLine("}");
                writer.WriteLine();
                foreach (var method in s.Methods.OrderBy(m => m.TsName))
                {
                    foreach (var httpMethod in method.HttpMethods.Order())
                    {
                        bool canDirectReturn = getConverter(method.TsReturnType) == null;
                        writer.Write($"public {(canDirectReturn ? "" : "async ")}{getMethodName(method, httpMethod)}(");
                        bool first = true;
                        foreach (var p in method.Parameters)
                        {
                            if (!first)
                            {
                                writer.Write(", ");
                            }
                            writer.Write($"{p.TsName}: {p.TsType.GetTypeScript()}");
                            first = false;
                        }
                        writer.WriteLine($"): {string.Format(ReturnTypeTemplate, method.TsReturnType.GetTypeScript())} {{");
                        using (writer.Indent())
                        {
                            var  url    = method.UrlPath;
                            bool first2 = true;
                            foreach (var p in method.Parameters.Where(p => p.Location == ParameterLocation.QueryString).OrderBy(p => p.TsName))
                            {
                                url   += (first2 ? '?' : '&') + p.TsName + "=${encodeURIComponent('' + " + p.TsName + ")}";
                                first2 = false;
                            }
                            writer.WriteLine($"let url = this._hostname + `{url}`;");

                            // Output parameter type conversions
                            foreach (var p in method.Parameters)
                            {
                                OutputTypeConversion(writer, p.TsName, p.TsType, toTypeScript: false);
                            }

                            // Build request body
                            var bodyParams = method.Parameters.Where(p => p.Location == ParameterLocation.RequestBody).OrderBy(p => p.TsName).ToList();
                            if (bodyParams.Count > 0 && httpMethod == "GET")
                            {
                                throw new InvalidOperationException($"GET requests must not have any body parameters. Offending parameter: {bodyParams[0].TsName}, method {method.Method.Name}, controller {s.Controller.FullName}");
                            }
                            if (bodyParams.Count > 1 && (method.BodyEncoding == BodyEncoding.Raw || method.BodyEncoding == BodyEncoding.Json))
                            {
                                throw new InvalidOperationException($"The body encoding for this method allows for at most one body parameter. Offending parameters: [{bodyParams.Select(p => p.TsName).JoinString(", ")}], method {method.Method.Name}, controller {s.Controller.FullName}");
                            }
                            var bodyCode = "";
                            if (bodyParams.Count > 0)
                            {
                                if (method.BodyEncoding == BodyEncoding.Raw)
                                {
                                    bodyCode = $", body: {bodyParams[0].TsName}";
                                }
                                else if (method.BodyEncoding == BodyEncoding.Json)
                                {
                                    bodyCode = $", body: JSON.stringify({bodyParams[0].TsName}), headers: {{ 'Content-Type': 'application/json' }}";
                                }
                                else if (method.BodyEncoding == BodyEncoding.FormUrlEncoded)
                                {
                                    writer.WriteLine("let __body = new URLSearchParams();");
                                    foreach (var bp in bodyParams)
                                    {
                                        writer.WriteLine($"__body.append('{bp.TsName}', '' + {bp.TsName});");
                                    }
                                    bodyCode = ", body: __body";
                                }
                                else if (method.BodyEncoding == BodyEncoding.MultipartFormData)
                                {
                                    writer.WriteLine("let __body = new FormData();");
                                    foreach (var bp in bodyParams)
                                    {
                                        writer.WriteLine($"__body.append('{bp.TsName}', '' + {bp.TsName});");
                                    }
                                    bodyCode = ", body: __body";
                                    throw new NotImplementedException("FormData encoding is not fully implemented."); // no support for file name, parameter is always stringified with no support for Blob
                                }
                                else
                                {
                                    throw new Exception($"Unexpected {nameof(method.BodyEncoding)}: {method.BodyEncoding}");
                                }
                            }

                            // Output call
                            var sendCookies = s.SendCookies == SendCookies.Always ? "include" : s.SendCookies == SendCookies.SameOriginOnly ? "same-origin" : s.SendCookies == SendCookies.Never ? "omit" : throw new Exception();
                            if (canDirectReturn)
                            {
                                writer.Write("return ");
                            }
                            else
                            {
                                writer.Write("let result = await ");
                            }
                            writer.WriteLine($"this.{httpMethod}<{method.TsReturnType.GetTypeScript()}>(url, {{ credentials: '{sendCookies}'{bodyCode} }});");

                            if (!canDirectReturn)
                            {
                                // Output return type conversion
                                OutputTypeConversion(writer, "result", method.TsReturnType, toTypeScript: true);

                                writer.WriteLine("return result;");
                            }
                        }
                        writer.WriteLine("}");
                        writer.WriteLine();
                    }
                }

                // Output type converters
                foreach (var tc in _typeConverters.Values.Where(c => c != null).OrderBy(c => c.ForType.GetHash()))
                {
                    if (_convertersUsedFrom.Contains(tc))
                    {
                        writer.WriteLine($"private {tc.FunctionName(toTypeScript: false)}(val: {tc.ForType.GetTypeScript()}): any {{");
                        using (writer.Indent())
                            tc.WriteFunctionBody(writer, false);
                        writer.WriteLine("}");
                        writer.WriteLine();
                    }
                    if (_convertersUsedTo.Contains(tc))
                    {
                        writer.WriteLine($"private {tc.FunctionName(toTypeScript: true)}(val: any): {tc.ForType.GetTypeScript()} {{");
                        using (writer.Indent())
                            tc.WriteFunctionBody(writer, true);
                        writer.WriteLine("}");
                        writer.WriteLine();
                    }
                }
            }
            writer.WriteLine("}");
        }