private async Task WriteClient(InterfaceManager interfacesToWrite, TextWriter writer) { foreach (var client in await clientGenerator.GetEndpointDefinitions()) { //Write injector if (client.IsEntryPoint) { writer.WriteLine($@" public class {client.Name}Injector {{ private string url; private IHttpClientFactory fetcher; private Task<{client.Name}{ResultClassSuffix}> instanceTask = default(Task<{client.Name}{ResultClassSuffix}>); public {client.Name}Injector(string url, IHttpClientFactory fetcher) {{ this.url = url; this.fetcher = fetcher; }} public Task<{client.Name}{ResultClassSuffix}> Load() {{ if (this.instanceTask == default(Task<{client.Name}{ResultClassSuffix}>)) {{ this.instanceTask = {client.Name}{ResultClassSuffix}.Load(this.url, this.fetcher); }} return this.instanceTask; }} }}"); } writer.WriteLine($@" public class {client.Name}{ResultClassSuffix} {{ private HalEndpointClient client;"); if (client.IsEntryPoint) { writer.WriteLine($@" public static async Task<{client.Name}{ResultClassSuffix}> Load(string url, IHttpClientFactory fetcher) {{ var result = await HalEndpointClient.Load(new HalLink(url, ""GET""), fetcher); return new {client.Name}{ResultClassSuffix}(result); }}"); } //Write accessor for data writer.WriteLine($@" public {client.Name}{ResultClassSuffix}(HalEndpointClient client) {{ this.client = client; }} private {client.Name} strongData = default({client.Name}); public {client.Name} Data {{ get {{ if(this.strongData == default({client.Name})) {{ this.strongData = this.client.GetData<{client.Name}>(); }} return this.strongData; }} }}"); //Write data interface if we haven't found it yet interfacesToWrite.Add(client.Schema); if (client.IsCollectionView) { WriteEmbedAccessor(writer, "items", "values", client.CollectionType); } //Write out any embedded properties foreach (var embedded in client.Schema.Properties.Where(i => i.Value.IsHalEmbedded())) { var embeddedItem = embedded.Value.Item; if (embeddedItem.HasReference) { var reference = embeddedItem.Reference; //Get the reference var def = client.Schema.Definitions.First(i => i.Value == reference); //Find reference in definitions, njsonschema will have the objects the same, so this is a valid way to look this up var typeHint = def.Key.Replace('\\', '/').Split('/').Last(); WriteEmbedAccessor(writer, embedded.Key, embedded.Key, typeHint); } } foreach (var link in client.Links) { String returnOpen = null; String returnClose = null; String linkReturnType = null; var linkRequestArg = ""; var loadFuncType = "Load"; //Only take a request or upload, prefer requests if (link.EndpointDoc.RequestSchema != null) { interfacesToWrite.Add(link.EndpointDoc.RequestSchema); if (link.EndpointDoc.RequestSchema.IsArray()) { linkRequestArg = $"IEnumerable<{link.EndpointDoc.RequestSchema.Title}> data"; } else { linkRequestArg = $"{link.EndpointDoc.RequestSchema.Title} data"; } } if (link.EndpointDoc.ResponseSchema != null) { if (link.EndpointDoc.ResponseSchema.IsRawResponse()) { linkReturnType = $"Task<RawEndpointResult>"; loadFuncType = "LoadRaw"; } else { interfacesToWrite.Add(link.EndpointDoc.ResponseSchema); linkReturnType = $"Task<{link.EndpointDoc.ResponseSchema.Title}{ResultClassSuffix}>"; returnOpen = $"new {link.EndpointDoc.ResponseSchema.Title}{ResultClassSuffix}("; returnClose = ")"; } } if (linkReturnType == null) { linkReturnType = VoidReturnType; } var loadFunc = "Link"; var inArgs = ""; var outArgs = ""; if (linkRequestArg != "") { inArgs += linkRequestArg; outArgs += ", data"; loadFunc = "LinkWithData"; } var funcName = link.Rel; if (link.Rel == "self") { //Self links make refresh functions, also clear in and out args funcName = "refresh"; inArgs = ""; outArgs = ""; loadFunc = "Link"; } var lowerFuncName = funcName.Substring(0, 1).ToLowerInvariant() + funcName.Substring(1); var upperFuncName = funcName.Substring(0, 1).ToUpperInvariant() + funcName.Substring(1); var fullLoadFunc = loadFuncType + loadFunc; if (!link.DocsOnly) { //Write link writer.Write($@" public async {linkReturnType} {upperFuncName}({inArgs}) {{ var result = await this.client.{fullLoadFunc}(""{link.Rel}""{outArgs});"); //If the returns are set return r, otherwise void out the promise so we don't leak on void functions if (returnOpen != null && returnClose != null) { writer.WriteLine($@" return {returnOpen}result{returnClose};"); } else if (linkReturnType == VoidReturnType) //Write a then that will hide the promise result and become void. { //Don't write anything for this } else //Returning the respose directly { writer.Write(@" return result;"); } writer.WriteLine($@" }} public bool Can{upperFuncName} {{ get {{ return this.client.HasLink(""{link.Rel}""); }} }} public HalLink LinkFor{upperFuncName} {{ get {{ return this.client.GetLink(""{link.Rel}""); }} }}"); } if (link.EndpointDoc.HasDocumentation) { //Write link docs writer.WriteLine($@" public async Task<HalEndpointDoc> Get{upperFuncName}Docs(HalEndpointDocQuery query = null) {{ var result = await this.client.LoadLinkDoc(""{link.Rel}"", query); return result.GetData<HalEndpointDoc>(); }} public bool Has{upperFuncName}Docs() {{ return this.client.HasLinkDoc(""{link.Rel}""); }}"); } } //Close class //Close class writer.WriteLine("}"); } }
private async Task WriteClient(InterfaceManager interfacesToWrite, TextWriter writer) { foreach (var client in await clientGenerator.GetEndpointDefinitions()) { //Write injector if (client.IsEntryPoint) { writer.WriteLine($@" class {client.Name}Injector {{ private $url; private $fetcher; private $instance = NULL; public function __construct(string $url, CurlHelper $fetcher) {{ $this->url = $url; $this->fetcher = $fetcher; }} public function load(): {client.Name}{ResultClassSuffix} {{ if ($this->instance === NULL) {{ $this->instance = {client.Name}{ResultClassSuffix}::Load($this->url, $this->fetcher); }} return $this->instance; }} }}"); } writer.WriteLine($@" class {client.Name}{ResultClassSuffix} {{ private $client;"); if (client.IsEntryPoint) { writer.WriteLine($@" public static function Load(string $url, CurlHelper $fetcher): {client.Name}{ResultClassSuffix} {{ $result = HalEndpointClient::Load($url, $fetcher); return new {client.Name}{ResultClassSuffix}($result); }}"); } //Write accessor for data writer.WriteLine($@" public function __construct(HalEndpointClient $client) {{ $this->client = $client; }} public function getData() {{ return $this->client->getData(); }}"); //Write data interface if we haven't found it yet interfacesToWrite.Add(client.Schema); if (client.IsCollectionView) { WriteEmbedAccessor(writer, "items", "values", client.CollectionType); } //Write out any embedded properties foreach (var embedded in client.Schema.Properties.Where(i => i.Value.IsHalEmbedded())) { var embeddedItem = embedded.Value.Item; if (embeddedItem.HasReference) { var reference = embeddedItem.Reference; //Get the reference var def = client.Schema.Definitions.First(i => i.Value == reference); //Find reference in definitions, njsonschema will have the objects the same, so this is a valid way to look this up var typeHint = def.Key.Replace('\\', '/').Split('/').Last(); WriteEmbedAccessor(writer, embedded.Key, embedded.Key, typeHint); } } foreach (var link in client.Links) { String returnOpen = null; String returnClose = null; String linkReturnType = null; var linkRequestArg = ""; var loadFuncType = "load"; //Only take a request or upload, prefer requests if (link.EndpointDoc.RequestSchema != null) { interfacesToWrite.Add(link.EndpointDoc.RequestSchema); linkRequestArg = $"$data"; } if (link.EndpointDoc.ResponseSchema != null) { if (link.EndpointDoc.ResponseSchema.IsRawResponse()) { linkReturnType = $""; loadFuncType = "loadRaw"; } else { interfacesToWrite.Add(link.EndpointDoc.ResponseSchema); linkReturnType = $": {link.EndpointDoc.ResponseSchema.Title}{ResultClassSuffix}"; returnOpen = $"new {link.EndpointDoc.ResponseSchema.Title}{ResultClassSuffix}("; returnClose = ")"; } } if (linkReturnType == null) { linkReturnType = VoidReturnType; } var loadFunc = "Link"; var inArgs = ""; var outArgs = ""; if (linkRequestArg != "") { inArgs += linkRequestArg; outArgs += ", $data"; loadFunc = "LinkWithData"; } var funcName = link.Rel; if (link.Rel == "self") { //Self links make refresh functions, also clear in and out args funcName = "refresh"; inArgs = ""; outArgs = ""; loadFunc = "Link"; } var lowerFuncName = funcName.Substring(0, 1).ToLowerInvariant() + funcName.Substring(1); var upperFuncName = funcName.Substring(0, 1).ToUpperInvariant() + funcName.Substring(1); var fullLoadFunc = loadFuncType + loadFunc; if (!link.DocsOnly) { //Write link writer.Write($@" public function {lowerFuncName}({inArgs}){linkReturnType} {{ $r = $this->client->{fullLoadFunc}(""{link.Rel}""{outArgs});"); //If the returns are set return r, otherwise void out the promise so we don't leak on void functions if (returnOpen != null && returnClose != null) { writer.Write($@" return {returnOpen}$r{returnClose};"); } writer.WriteLine($@" }} public function can{upperFuncName}(): bool {{ return $this->client->hasLink(""{link.Rel}""); }} public function linkFor{upperFuncName}() {{ return $this->client->getLink(""{link.Rel}""); }}"); } if (link.EndpointDoc.HasDocumentation) { //Write link docs writer.WriteLine($@" public function get{upperFuncName}Docs(HalEndpointDocQuery $query = NULL) {{ return $this->client->loadLinkDoc(""{link.Rel}"", $query)->getData(); }} public function has{upperFuncName}Docs(): bool {{ return $this->client->hasLinkDoc(""{link.Rel}""); }}"); } } //Close class writer.WriteLine("}"); } }
private async Task WriteClient(InterfaceManager interfacesToWrite, TextWriter writer) { foreach (var client in await clientGenerator.GetEndpointDefinitions()) { //Write injector if (client.IsEntryPoint) { writer.WriteLine($@" export class {client.Name}Injector {{ private instancePromise: Promise<{client.Name}{ResultClassSuffix}>; constructor(private url: string, private fetcher: Fetcher, private data?: any) {{}} public load(): Promise<{client.Name}{ResultClassSuffix}> {{ if (!this.instancePromise) {{ if (this.data) {{ this.instancePromise = Promise.resolve(new {client.Name}{ResultClassSuffix}(new hal.HalEndpointClient(this.data, this.fetcher))); }} else {{ this.instancePromise = {client.Name}{ResultClassSuffix}.Load(this.url, this.fetcher); }} }} return this.instancePromise; }} }}"); } writer.WriteLine($@" export class {client.Name}{ResultClassSuffix} {{ private client: hal.HalEndpointClient;"); if (client.IsEntryPoint) { writer.WriteLine($@" public static Load(url: string, fetcher: Fetcher): Promise<{client.Name}{ResultClassSuffix}> {{ return hal.HalEndpointClient.Load({{ href: url, method: ""GET"" }}, fetcher) .then(c => {{ return new {client.Name}{ResultClassSuffix}(c); }}); }}"); } //Write accessor for data writer.WriteLine($@" constructor(client: hal.HalEndpointClient) {{ this.client = client; }} private strongData: {client.Name} = undefined; public get data(): {client.Name} {{ this.strongData = this.strongData || this.client.GetData<{client.Name}>(); return this.strongData; }}"); //Write data interface if we haven't found it yet interfacesToWrite.Add(client.Schema); if (client.IsCollectionView) { WriteEmbedAccessor(writer, "items", "values", client.CollectionType); } //Write out any embedded properties foreach (var embedded in client.Schema.Properties.Where(i => i.Value.IsHalEmbedded())) { var embeddedItem = embedded.Value.Item; if (embeddedItem.HasReference) { var reference = embeddedItem.Reference; //Get the reference var def = client.Schema.Definitions.First(i => i.Value == reference); //Find reference in definitions, njsonschema will have the objects the same, so this is a valid way to look this up var typeHint = def.Key.Replace('\\', '/').Split('/').Last(); WriteEmbedAccessor(writer, embedded.Key, embedded.Key, typeHint); } } foreach (var link in client.Links) { String returnOpen = null; String returnClose = null; String linkReturnType = null; var linkRequestArg = ""; var loadFuncType = "Load"; //Only take a request or upload, prefer requests if (link.EndpointDoc.RequestSchema != null) { interfacesToWrite.Add(link.EndpointDoc.RequestSchema); linkRequestArg = $"data: {link.EndpointDoc.RequestSchema.Title}"; if (link.EndpointDoc.RequestSchema.IsArray()) { linkRequestArg += "[]"; } } if (link.EndpointDoc.ResponseSchema != null) { if (link.EndpointDoc.ResponseSchema.IsRawResponse()) { linkReturnType = $": Promise<Response>"; loadFuncType = "LoadRaw"; } else { interfacesToWrite.Add(link.EndpointDoc.ResponseSchema); linkReturnType = $": Promise<{link.EndpointDoc.ResponseSchema.Title}{ResultClassSuffix}>"; returnOpen = $"new {link.EndpointDoc.ResponseSchema.Title}{ResultClassSuffix}("; returnClose = ")"; } } if (linkReturnType == null) { linkReturnType = VoidReturnType; } var loadFunc = "Link"; var inArgs = ""; var outArgs = ""; if (linkRequestArg != "") { inArgs += linkRequestArg; outArgs += ", data"; loadFunc = "LinkWithData"; } var funcName = link.Rel; if (link.Rel == "self") { //Self links make refresh functions, also clear in and out args funcName = "refresh"; inArgs = ""; outArgs = ""; loadFunc = "Link"; } var lowerFuncName = funcName.Substring(0, 1).ToLowerInvariant() + funcName.Substring(1); var upperFuncName = funcName.Substring(0, 1).ToUpperInvariant() + funcName.Substring(1); var fullLoadFunc = loadFuncType + loadFunc; if (!link.DocsOnly) { //Write link writer.Write($@" public {lowerFuncName}({inArgs}){linkReturnType} {{ return this.client.{fullLoadFunc}(""{link.Rel}""{outArgs})"); //If the returns are set return r, otherwise void out the promise so we don't leak on void functions if (returnOpen != null && returnClose != null) { writer.WriteLine($@" .then(r => {{ return {returnOpen}r{returnClose}; }});"); } else if (linkReturnType == VoidReturnType) //Write a then that will hide the promise result and become void. { writer.Write(".then(hal.makeVoid);"); } else //Returning the respose directly { writer.Write(";"); } writer.WriteLine($@" }} public can{upperFuncName}(): boolean {{ return this.client.HasLink(""{link.Rel}""); }} public linkFor{upperFuncName}(): hal.HalLink {{ return this.client.GetLink(""{link.Rel}""); }}"); } if (link.EndpointDoc.HasDocumentation) { //Write link docs writer.WriteLine($@" public get{upperFuncName}Docs(query?: HalEndpointDocQuery): Promise<hal.HalEndpointDoc> {{ return this.client.LoadLinkDoc(""{link.Rel}"", query) .then(r => {{ return r.GetData<hal.HalEndpointDoc>(); }}); }} public has{upperFuncName}Docs(): boolean {{ return this.client.HasLinkDoc(""{link.Rel}""); }}"); } } //Close class writer.WriteLine("}"); } }