public bool Render(TypeScriptModuleContext context, Fragment fragment, IndentedTextWriter writer) { if (!(fragment is ObjectFragment objectFragment)) { return(false); } if (objectFragment.Hints.TryGetValue("source-type", out var sourceType)) { writer.WriteIndentedLine($"// source: {sourceType}"); writer.WriteSeparatingLine(); } var genericSuffix = string.Join(", ", objectFragment.GenericArguments.Select(a => a.Name)); using (writer.WriteIndentedBlock(prefix: $"class {TS.Type(objectFragment.Name)}{(genericSuffix.Length > 0 ? $"<{genericSuffix}>" : "")} ")) { if (objectFragment.Constants.Any()) { foreach (var constant in objectFragment.Constants) { writer.WriteIndentedLine($"static readonly {TS.Field(constant.Name)}: {context.Resolve(constant.Type)} = {TS.Constant(constant.Value)};"); } writer.WriteSeparatingLine(); } foreach (var field in objectFragment.Fields) { writer.WriteIndentedLine($"{TS.Field(field.Name)}: {context.Resolve(field.Type)} = {context.ResolveDefaultValue(field.Type)};"); writer.WriteSeparatingLine(); } if (objectFragment.GenericArguments.Any()) { var genericParameters = $"<{string.Join(", ", objectFragment.GenericArguments.Select(a => a.Name))}>"; var factoryParameters = string.Join(", ", objectFragment.GenericArguments.Select(a => $"{a.Name}_factory: {{ create(source: any): {a.Name} }}")); using (writer.WriteIndentedBlock(prefix: $"static create{genericParameters}({factoryParameters}): {{ create: (source: any) => {TS.Type(objectFragment.Name)}{genericParameters} }} ")) { using (writer.WriteIndentedBlock(prefix: $"return ", suffix: ";")) { using (writer.WriteIndentedBlock(prefix: $"create: (source: any) => ")) { writer.WriteIndentedLine($"const result = new {TS.Type(objectFragment.Name)}{genericParameters}();"); foreach (var field in objectFragment.Fields) { writer.WriteIndentedLine($"result.{TS.Field(field.Name)} = {context.CreateExpression(field.Type, $"source.{TS.Field(field.Name)}")};"); } writer.WriteIndentedLine("return result;"); } } } } else { using (writer.WriteIndentedBlock(prefix: $"static create(source: any): {TS.Type(objectFragment.Name)} ")) { writer.WriteIndentedLine($"const result = new {TS.Type(objectFragment.Name)}();"); foreach (var field in objectFragment.Fields) { writer.WriteIndentedLine($"result.{TS.Field(field.Name)} = {context.CreateExpression(field.Type, $"source.{TS.Field(field.Name)}")};"); } writer.WriteIndentedLine("return result;"); } } } context.Export(objectFragment.Name, @default: true); return(true); }
public bool Render(TypeScriptModuleContext context, Fragment fragment, IndentedTextWriter writer) { if (!(fragment is ObjectFragment objectFragment)) { return(false); } if (objectFragment.Hints.TryGetValue("source-type", out var sourceType)) { writer.WriteIndentedLine($"// source: {sourceType}"); writer.WriteSeparatingLine(); } var genericSuffix = string.Join(", ", objectFragment.GenericArguments.Select(a => a.Name)); using (writer.WriteIndentedBlock(prefix: $"class {TS.Type(objectFragment.Name)}{(genericSuffix.Length > 0 ? $"<{genericSuffix}>" : "")} ")) { if (objectFragment.Constants.Any()) { foreach (var constant in objectFragment.Constants) { writer.WriteIndentedLine($"static readonly {TS.Field(constant.Name)}: {context.Resolve(constant.Type)} = {TS.Constant(constant.Value)};"); } writer.WriteSeparatingLine(); } foreach (var field in objectFragment.Fields) { context.Import("mobx", "observable"); writer.WriteIndentedLine("@observable.ref"); writer.WriteIndentedLine($"{TS.Field(field.Name)}: {context.Resolve(field.Type)} = {context.ResolveDefaultValue(field.Type)};"); writer.WriteSeparatingLine(); } if (objectFragment.GenericArguments.Any()) { var genericParameters = $"<{string.Join(", ", objectFragment.GenericArguments.Select(a => a.Name))}>"; var factoryParameters = string.Join(", ", objectFragment.GenericArguments.Select(a => $"{a.Name}_factory: {{ create(source: any): {a.Name} }}")); using (writer.WriteIndentedBlock(prefix: $"static create{genericParameters}({factoryParameters}): {{ create: (source: any) => {TS.Type(objectFragment.Name)}{genericParameters} }} ")) { using (writer.WriteIndentedBlock(prefix: $"return ", suffix: ";")) { using (writer.WriteIndentedBlock(prefix: $"create: (source: any) => ")) { writer.WriteIndentedLine($"const result = new {TS.Type(objectFragment.Name)}{genericParameters}();"); foreach (var field in objectFragment.Fields) { writer.WriteIndentedLine($"result.{TS.Field(field.Name)} = {context.CreateExpression(field.Type, $"source.{TS.Field(field.Name)}")};"); } writer.WriteIndentedLine("return result;"); } } } } else { using (writer.WriteIndentedBlock(prefix: $"static create(source: any): {TS.Type(objectFragment.Name)} ")) { writer.WriteIndentedLine($"const result = new {TS.Type(objectFragment.Name)}();"); foreach (var field in objectFragment.Fields) { writer.WriteIndentedLine($"result.{TS.Field(field.Name)} = {context.CreateExpression(field.Type, $"source.{TS.Field(field.Name)}")};"); } writer.WriteIndentedLine("return result;"); } } var hasValidation = objectFragment.Fields.Any(f => f.Hints.Any(h => h.Key.StartsWith("validation:"))); if (hasValidation) { using (writer.WriteIndentedBlock(prefix: $"static validation = ", suffix: ";")) { foreach (var field in objectFragment.Fields) { field.Hints.TryGetValue("validation:is-required", out var isRequired); field.Hints.TryGetValue("validation:min-length", out var minLength); field.Hints.TryGetValue("validation:max-length", out var maxLength); if (string.IsNullOrEmpty(isRequired) && string.IsNullOrEmpty(minLength) && string.IsNullOrEmpty(maxLength)) { continue; } using (writer.WriteIndentedBlock(prefix: $"{TS.Field(field.Name)}: ", suffix: ",")) { if (isRequired == "true") { writer.WriteIndentedLine("required: true,"); } if ((!string.IsNullOrEmpty(minLength) && minLength != "-1") || (!string.IsNullOrEmpty(maxLength) && maxLength != "-1")) { using (writer.WriteIndentedBlock(prefix: "length: ", suffix: ",")) { if (!string.IsNullOrEmpty(minLength) && minLength != "-1") { writer.WriteIndentedLine($"min: {minLength},"); } if (!string.IsNullOrEmpty(maxLength) && maxLength != "-1") { writer.WriteIndentedLine($"max: {maxLength},"); } } } } } } } } context.Export(objectFragment.Name, @default: true); return(true); }
public bool Render(TypeScriptModuleContext context, Fragment fragment, IndentedTextWriter writer) { if (!(fragment is ObjectFragment objectFragment)) { return(false); } if (objectFragment.Hints.TryGetValue("source-type", out var sourceType)) { writer.WriteIndentedLine($"// source: {sourceType}"); writer.WriteSeparatingLine(); } var genericSuffix = string.Join(", ", objectFragment.GenericArguments.Select(a => a.Name)); using (writer.WriteIndentedBlock(prefix: $"class {TS.Type(objectFragment.Name)}{(genericSuffix.Length > 0 ? $"<{genericSuffix}>" : "")} ")) { if (objectFragment.Constants.Any()) { foreach (var constant in objectFragment.Constants) { writer.WriteIndentedLine($"static readonly {TS.Field(constant.Name)}: {context.Resolve(constant.Type)} = {TS.Constant(constant.Value)};"); } writer.WriteSeparatingLine(); } if (objectFragment.Fields.Count > 0) { foreach (var field in objectFragment.Fields) { context.Import("mobx", "observable"); // this seem to be sometimes wrong? todo: investigate //if (field.Type.Kind == TypeKind.Array) if (field.Type.Module == null && field.Type.Name == "array") { writer.WriteIndentedLine("@observable.shallow"); } else { writer.WriteIndentedLine("@observable.ref"); } writer.WriteIndentedLine($"{TS.Field(field.Name)}: {context.Resolve(field.Type)} = {context.ResolveDefaultValue(field.Type)};"); writer.WriteSeparatingLine(); } if (objectFragment.GenericArguments.Any()) { var genericParameters = $"<{string.Join(", ", objectFragment.GenericArguments.Select(a => a.Name))}>"; var factoryParameters = string.Join(", ", objectFragment.GenericArguments.Select(a => $"{a.Name}_factory: {{ create(source: any): {a.Name} }}")); using (writer.WriteIndentedBlock(prefix: $"static create{genericParameters}({factoryParameters}): {{ create: (source: any) => {TS.Type(objectFragment.Name)}{genericParameters} }} ")) { using (writer.WriteIndentedBlock(prefix: $"return ", suffix: ";")) { using (writer.WriteIndentedBlock(prefix: $"create: (source: any) => ")) { writer.WriteIndentedLine($"const result = new {TS.Type(objectFragment.Name)}{genericParameters}();"); foreach (var field in objectFragment.Fields) { writer.WriteIndentedLine($"result.{TS.Field(field.Name)} = {context.CreateExpression(field.Type, $"source.{TS.Field(field.Name)}")};"); } writer.WriteIndentedLine("return result;"); } } } writer.WriteSeparatingLine(); using (writer.WriteIndentedBlock(prefix: $"static copy{genericParameters}(source: {TS.Type(objectFragment.Name)}{genericParameters}, destination: {TS.Type(objectFragment.Name)}{genericParameters}): void ")) { foreach (var field in objectFragment.Fields) { writer.WriteIndentedLine($"destination.{TS.Field(field.Name)} = source.{TS.Field(field.Name)};"); } } writer.WriteSeparatingLine(); using (writer.WriteIndentedBlock(prefix: $"static clone{genericParameters}(source: {TS.Type(objectFragment.Name)}{genericParameters}): {TS.Type(objectFragment.Name)}{genericParameters} ")) { writer.WriteIndentedLine($"const result = new {TS.Type(objectFragment.Name)}{genericParameters}();"); writer.WriteIndentedLine($"{TS.Type(objectFragment.Name)}.copy{genericParameters}(source, result);"); writer.WriteIndentedLine("return result;"); } } else { using (writer.WriteIndentedBlock(prefix: $"static create(source: any): {TS.Type(objectFragment.Name)} ")) { writer.WriteIndentedLine($"const result = new {TS.Type(objectFragment.Name)}();"); foreach (var field in objectFragment.Fields) { writer.WriteIndentedLine($"result.{TS.Field(field.Name)} = {context.CreateExpression(field.Type, $"source.{TS.Field(field.Name)}")};"); } writer.WriteIndentedLine("return result;"); } writer.WriteSeparatingLine(); using (writer.WriteIndentedBlock(prefix: $"static copy(source: {TS.Type(objectFragment.Name)}, destination: {TS.Type(objectFragment.Name)}): void ")) { foreach (var field in objectFragment.Fields) { writer.WriteIndentedLine($"destination.{TS.Field(field.Name)} = source.{TS.Field(field.Name)};"); } } writer.WriteSeparatingLine(); using (writer.WriteIndentedBlock(prefix: $"static clone(source: {TS.Type(objectFragment.Name)}): {TS.Type(objectFragment.Name)} ")) { writer.WriteIndentedLine($"const result = new {TS.Type(objectFragment.Name)}();"); writer.WriteIndentedLine($"{TS.Type(objectFragment.Name)}.copy(source, result);"); writer.WriteIndentedLine("return result;"); } } } } context.Export(objectFragment.Name, @default: true); return(true); }
public bool Render(TypeScriptModuleContext context, Fragment fragment, IndentedTextWriter writer) { if (!(fragment is ServiceFragment serviceFragment)) { return(false); } if (serviceFragment.Hints.TryGetValue("source-type", out var sourceType)) { writer.WriteIndentedLine($"// source: {sourceType}"); writer.WriteSeparatingLine(); } using (writer.WriteIndentedBlock(prefix: $"class {TS.Type(serviceFragment.Name)} ")) { if (serviceFragment.Constants.Any()) { foreach (var constant in serviceFragment.Constants) { writer.WriteIndentedLine($"static readonly {TS.Field(constant.Name)}: {context.Resolve(constant.Type)} = {TS.Constant(constant.Value)};"); } writer.WriteSeparatingLine(); } context.Import(Options.RpcClientModule, Options.RpcClientImport); using (writer.WriteIndentedBlock(prefix: $"constructor(client: {Options.RpcClientImport}) ")) { writer.WriteIndentedLine("this.client = client;"); } writer.WriteSeparatingLine(); writer.WriteIndentedLine($"private client: {Options.RpcClientImport};"); writer.WriteSeparatingLine(); foreach (var method in serviceFragment.Methods) { var rpcMethodName = method.Hints["jsonrpc-name"] ?? method.Name; var parameters = method.Parameters .Select(p => $"{TS.Parameter(p.Name)}: {context.Resolve(p.Type)}") .ToList(); using (writer.WriteIndentedBlock(prefix: $"async {TS.Method(method.Name)}Async({string.Join(", ", parameters)}): Promise<{context.Resolve(method.ReturnType)}> ")) { if (method.ReturnType.Name == "void") { writer.WriteIndentedLine($"await this.client.callAsync('{rpcMethodName}', {{ {string.Join(", ", method.Parameters.Select(p => p.Name))} }});"); } else { writer.WriteIndentedLine($"const result = await this.client.callAsync('{rpcMethodName}', {{ {string.Join(", ", method.Parameters.Select(p => p.Name))} }});"); writer.WriteIndentedLine($"return {context.CreateExpression(method.ReturnType, "result")};"); } } writer.WriteSeparatingLine(); } } writer.WriteSeparatingLine(); context.Export(serviceFragment.Name, @default: true); return(true); }
public bool Render(TypeScriptModuleContext context, Fragment fragment, IndentedTextWriter writer) { if (!(fragment is ServiceFragment serviceFragment)) { return(false); } if (serviceFragment.Hints.TryGetValue("source-type", out var sourceType)) { writer.WriteIndentedLine($"// source: {sourceType}"); writer.WriteSeparatingLine(); } var hasConstants = serviceFragment.Constants.Any(); var hasMethods = serviceFragment.Methods.Any(); var classDeclaration = $"class {TS.Type(serviceFragment.Name)} "; if (hasMethods) { context.Import("@stackino/due", "Tag"); writer.WriteIndentedLine($"const {TS.Type(serviceFragment.Name)}Tag = new Tag<{TS.Type(serviceFragment.Name)}>('{context.PackageContext.Package.Name} {TS.Type(serviceFragment.Name)}');"); writer.WriteSeparatingLine(); context.Export($"{TS.Type(serviceFragment.Name)}Tag"); context.Import("@stackino/due", "Injectable"); classDeclaration += "extends Injectable "; } using (writer.WriteIndentedBlock(prefix: classDeclaration)) { if (hasConstants) { foreach (var constant in serviceFragment.Constants) { writer.WriteIndentedLine($"static readonly {TS.Field(constant.Name)}: {context.Resolve(constant.Type)} = {TS.Constant(constant.Value)};"); } writer.WriteSeparatingLine(); } if (hasMethods) { context.Import("@stackino/due-plugin-odachirpcclient", "RpcClientTag"); writer.WriteIndentedLine("private readonly client = this.$dependency(RpcClientTag);"); writer.WriteSeparatingLine(); foreach (var method in serviceFragment.Methods) { var rpcMethodName = method.Hints["jsonrpc-name"] ?? method.Name; var parameters = method.Parameters .Select(p => $"{TS.Parameter(p.Name)}: {context.Resolve(p.Type)}") .ToList(); using (writer.WriteIndentedBlock(prefix: $"async {TS.Method(method.Name)}Async({string.Join(", ", parameters)}): Promise<{context.Resolve(method.ReturnType)}> ")) { if (method.ReturnType.Name == "void") { writer.WriteIndentedLine($"await this.client.callAsync({TS.String(rpcMethodName)}, {{ {string.Join(", ", method.Parameters.Select(p => p.Name))} }});"); } else { writer.WriteIndentedLine($"const result = await this.client.callAsync({TS.String(rpcMethodName)}, {{ {string.Join(", ", method.Parameters.Select(p => p.Name))} }});"); writer.WriteIndentedLine($"return {context.CreateExpression(method.ReturnType, "result")};"); } } writer.WriteSeparatingLine(); } } } writer.WriteSeparatingLine(); context.Export(serviceFragment.Name, @default: true); return(true); }