diff --git a/templates/README.md b/templates/README.md new file mode 100644 index 0000000..4ce7c52 --- /dev/null +++ b/templates/README.md @@ -0,0 +1,64 @@ +## Swagger / OpenAPI 2 and OpenAPI 3 template parameters + +Note that properties of OpenAPI objects will be in OpenAPI 3.0 form, as +Swagger / OpenAPI 2.0 definitions are converted automatically. + +### Code templates + +* `method` - the HTTP method of the operation (in lower-case) +* `methodUpper` - the HTTP method of the operation (in upper-case) +* `url` - the full URL of the operation (including protocol and host) +* `consumes[]` - an array of MIME-types the operation consumes +* `produces[]` - an array of MIME-types the operation produces +* `operation` - the current operation object +* `operationId` - the current operation id +* `opName` - the operationId if set, otherwise the method + path +* `tags[]` - the full list of tags applying to the operation +* `security` - the security definitions applying to the operation +* `resource` - the current tag/path object +* `parameters[]` - an array of parameters for the operation (see below) +* `queryString` - an example queryString, urlEncoded +* `requiredQueryString` - an example queryString for `required:true` parameters +* `queryParameters[]` - a subset of `parameters` that are `in:query` +* `requiredParameters[]` - a subset of `queryParameters` that are `required:true` +* `headerParameters[]` - a subset of `parameters` that are `in:header` +* `allHeaders[]` - a concatenation of `headerParameters` and pseudo-parameters `Accept` and `Content-Type`, and optionally `Authorization` (the latter has an `isAuth` boolean property set true so it can be omitted in templates if desired + +### Parameter template + +* `parameters[]` - an array of [parameters](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#parameterObject), including the following pseudo-properties + * `shortDesc` - a truncated version of the parameter description + * `safeType` - a computed version of the parameter type, including Body and schema names + * `originalType` - the original type of the parameter + * `exampleValues` - an object containing examples for use in code-templates + * `json` - example values in JSON compatible syntax + * `object` - example values in raw object form (unquoted strings etc) + * `depth` - a zero-based indicator of the depth of expanded request body parameters +* `enums[]` - an array of (parameter)name/value pairs + +### Responses template + +* `responses[]` - an array of [responses](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#responseObject), including `status` and `meaning` properties + +### Authentication template + +* `authenticationStr` - a simple string of methods (and scopes where appropriate) +* `securityDefinitions[]` - an array of applicable [securityDefinitions](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#securityRequirementObject) + +### Schema Property template + +* `schemaProperties[]` - an array of + * `name` + * `type` + * `required` + * `description` +* `enums[]` - an array of (schema property)name/value pairs + +### Common to all templates + +* `openapi` - the top-level OpenAPI / Swagger document +* `header` - the front-matter of the Slate/Shins markdown document +* `host` - the (computed) host of the API +* `protocol` - the default/first protocol of the API +* `baseUrl` - the (computed) baseUrl of the API (including protocol and host) +* `widdershins` - the contents of widdershins `package.json` diff --git a/templates/authentication.def b/templates/authentication.def new file mode 100644 index 0000000..6b039e5 --- /dev/null +++ b/templates/authentication.def @@ -0,0 +1,5 @@ + + diff --git a/templates/authentication_none.def b/templates/authentication_none.def new file mode 100644 index 0000000..ddb19cf --- /dev/null +++ b/templates/authentication_none.def @@ -0,0 +1,3 @@ + diff --git a/templates/callbacks.def b/templates/callbacks.def new file mode 100644 index 0000000..77873e3 --- /dev/null +++ b/templates/callbacks.def @@ -0,0 +1,38 @@ +{{? typeof data.operation.callbacks === 'object'}} + +### Callbacks + +{{ data.operationStack.push(data.operation); }} + +{{ for (var c of Object.keys(data.operation.callbacks)) { }} + +#### {{=c}} + +{{ var callback = data.operation.callbacks && data.operation.callbacks[c]; }} + +{{ for (var e in callback) { }} +{{ if (!e.startsWith('x-widdershins-')) { }} + +**{{=e}}** + +{{ var exp = callback[e]; }} + +{{ for (var m in exp) { }} + +{{ data.operation = exp[m]; }} +{{ data.method.operation = data.operation; }} + +{{= data.templates.operation(data) }} + +{{ } /* of methods */ }} + +{{ } /* of expressions */ }} + +{{ } /* of if */ }} + +{{ } /* of callbacks */ }} + +{{ data.operation = data.operationStack.pop(); }} +{{ data.method.operation = data.operation; }} + +{{?}} diff --git a/templates/code_csharp.dot b/templates/code_csharp.dot new file mode 100644 index 0000000..39597ad --- /dev/null +++ b/templates/code_csharp.dot @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; + +/// <> +/// Example of Http Client +/// <> +public class HttpExample +{ + private HttpClient Client { get; set; } + + /// <> + /// Setup http client + /// <> + public HttpExample() + { + Client = new HttpClient(); + } + {{? data.methodUpper == "GET"}} + /// Make a dummy request + public async Task MakeGetRequest() + { + string url = "{{=data.url}}"; + var result = await GetAsync(url); + } + + /// Performs a GET Request + public async Task GetAsync(string url) + { + //Start the request + HttpResponseMessage response = await Client.GetAsync(url); + + //Validate result + response.EnsureSuccessStatusCode(); + + }{{? }} + {{? data.methodUpper == "POST"}} + /// Make a dummy request + public async Task MakePostRequest() + { + string url = "{{=data.url}}"; + {{? data.bodyParameter.refName !== undefined }} + string json = @"{{=data.bodyParameter.exampleValues.json.replace(new RegExp('"', "g"), '""')}}"; + {{=data.bodyParameter.refName}} content = JsonConvert.DeserializeObject(json); + await PostAsync(content, url); + {{? }} + {{? data.bodyParameter.refName === undefined }} + await PostAsync(null, url); + {{? }} + } + + /// Performs a POST Request + public async Task PostAsync({{=data.bodyParameter.refName}} content, string url) + { + //Serialize Object + StringContent jsonContent = SerializeObject(content); + + //Execute POST request + HttpResponseMessage response = await Client.PostAsync(url, jsonContent); + }{{? }} + {{? data.methodUpper == "PUT"}} + /// Make a dummy request + public async Task MakePutRequest() + { + int id = 1; + string url = "{{=data.url}}"; + + {{? data.bodyParameter.refName !== undefined }} + string json = @"{{=data.bodyParameter.exampleValues.json.replace(new RegExp('"', "g"), '""')}}"; + {{=data.bodyParameter.refName}} content = JsonConvert.DeserializeObject(json); + var result = await PutAsync(id, content, url); + {{? }} + {{? data.bodyParameter.refName === undefined }} + var result = await PutAsync(id, null, url); + {{? }} + } + + /// Performs a PUT Request + public async Task PutAsync(int id, {{=data.bodyParameter.refName}} content, string url) + { + //Serialize Object + StringContent jsonContent = SerializeObject(content); + + //Execute PUT request + HttpResponseMessage response = await Client.PutAsync(url + $"/{id}", jsonContent); + + //Return response + return await DeserializeObject(response); + }{{? }} + {{? data.methodUpper == "DELETE"}} + /// Make a dummy request + public async Task MakeDeleteRequest() + { + int id = 1; + string url = "{{=data.url}}"; + + await DeleteAsync(id, url); + } + + /// Performs a DELETE Request + public async Task DeleteAsync(int id, string url) + { + //Execute DELETE request + HttpResponseMessage response = await Client.DeleteAsync(url + $"/{id}"); + + //Return response + await DeserializeObject(response); + }{{? }} + {{? data.methodUpper == "POST" || data.methodUpper == "PUT"}} + /// Serialize an object to Json + private StringContent SerializeObject({{=data.bodyParameter.refName}} content) + { + //Serialize Object + string jsonObject = JsonConvert.SerializeObject(content); + + //Create Json UTF8 String Content + return new StringContent(jsonObject, Encoding.UTF8, "application/json"); + } + {{? }} + /// Deserialize object from request response + private async Task DeserializeObject(HttpResponseMessage response) + { + //Read body + string responseBody = await response.Content.ReadAsStringAsync(); + + //Deserialize Body to object + var result = JsonConvert.DeserializeObject(responseBody); + } +} diff --git a/templates/code_go.dot b/templates/code_go.dot new file mode 100644 index 0000000..0f5a33f --- /dev/null +++ b/templates/code_go.dot @@ -0,0 +1,21 @@ +package main + +import ( + "bytes" + "net/http" +) + +func main() { +{{?data.allHeaders.length}} + headers := map[string][]string{ + {{~data.allHeaders :p:index}}"{{=p.name}}": []string{"{{=p.exampleValues.object}}"},{{?index < data.allHeaders.length-1}} + {{?}}{{~}} + }{{?}} + + data := bytes.NewBuffer([]byte{jsonReq}) + req, err := http.NewRequest("{{=data.methodUpper}}", "{{=data.url}}", data) + req.Header = headers + + client := &http.Client{} + resp, err := client.Do(req) +} \ No newline at end of file diff --git a/templates/code_http.dot b/templates/code_http.dot new file mode 100644 index 0000000..74b0333 --- /dev/null +++ b/templates/code_http.dot @@ -0,0 +1,7 @@ +{{=data.methodUpper}} {{=data.url}}{{=data.requiredQueryString}} HTTP/1.1 +{{? data.host}}Host: {{=data.host}}{{?}} +{{?data.consumes.length}}Content-Type: {{=data.consumes[0]}} +{{?}}{{?data.produces.length}}Accept: {{=data.produces[0]}}{{?}} +{{?data.headerParameters.length}}{{~ data.headerParameters :p:index}}{{=p.name}}: {{=p.exampleValues.object}} +{{~}} +{{?}} diff --git a/templates/code_java.dot b/templates/code_java.dot new file mode 100644 index 0000000..8d61d00 --- /dev/null +++ b/templates/code_java.dot @@ -0,0 +1,13 @@ +URL obj = new URL("{{=data.url}}{{=data.requiredQueryString}}"); +HttpURLConnection con = (HttpURLConnection) obj.openConnection(); +con.setRequestMethod("{{=data.methodUpper}}"); +int responseCode = con.getResponseCode(); +BufferedReader in = new BufferedReader( + new InputStreamReader(con.getInputStream())); +String inputLine; +StringBuffer response = new StringBuffer(); +while ((inputLine = in.readLine()) != null) { + response.append(inputLine); +} +in.close(); +System.out.println(response.toString()); diff --git a/templates/code_javascript.dot b/templates/code_javascript.dot new file mode 100644 index 0000000..32b74f4 --- /dev/null +++ b/templates/code_javascript.dot @@ -0,0 +1,9 @@ +{{?data.bodyParameter.present}}const inputBody = '{{=data.bodyParameter.exampleValues.json}}';{{?}}{{?data.allHeaders.length}}const headers = { +{{~data.allHeaders :p:index}} '{{=p.name}}':{{=p.exampleValues.json}}{{?index < data.allHeaders.length-1}},{{?}} +{{~}}}; +{{?}} +const response = await fetch('{{=data.url}}{{=data.requiredQueryString}}', { + method: '{{=data.methodUpper}}'{{?data.bodyParameter.present || data.allHeaders.length}},{{?}}{{?data.bodyParameter.present}} body: inputBody{{?}}{{? data.bodyParameter.present && data.allHeaders.length}},{{?}}{{?data.allHeaders.length}} headers: headers{{?}} +}) + +const body = await response.json() \ No newline at end of file diff --git a/templates/code_jquery.dot b/templates/code_jquery.dot new file mode 100644 index 0000000..06d2641 --- /dev/null +++ b/templates/code_jquery.dot @@ -0,0 +1,14 @@ +{{?data.allHeaders.length}}var headers = { +{{~data.allHeaders :p:index}} '{{=p.name}}':{{=p.exampleValues.json}}{{?index < data.allHeaders.length-1}},{{?}} +{{~}} +}; +{{?}} +$.ajax({ + url: '{{=data.url}}', + method: '{{=data.method.verb}}', +{{?data.requiredQueryString}} data: '{{=data.requiredQueryString}}',{{?}} +{{?data.allHeaders.length}} headers: headers,{{?}} + success: function(data) { + console.log(JSON.stringify(data)); + } +}) diff --git a/templates/code_nodejs.dot b/templates/code_nodejs.dot new file mode 100644 index 0000000..876d4bf --- /dev/null +++ b/templates/code_nodejs.dot @@ -0,0 +1,17 @@ +const fetch = require('node-fetch'); +{{?data.bodyParameter.present}}const inputBody = {{=data.bodyParameter.exampleValues.json}};{{?}} +{{?data.allHeaders.length}}const headers = { +{{~data.allHeaders :p:index}} '{{=p.name}}':{{=p.exampleValues.json}}{{?index < data.allHeaders.length-1}},{{?}} +{{~}}}; +{{?}} +fetch('{{=data.url}}{{=data.requiredQueryString}}', +{ + method: '{{=data.methodUpper}}'{{?data.bodyParameter.present || data.allHeaders.length}},{{?}} +{{?data.bodyParameter.present}} body: JSON.stringify(inputBody){{?}}{{? data.bodyParameter.present && data.allHeaders.length}},{{?}} +{{?data.allHeaders.length}} headers: headers{{?}} +}) +.then(function(res) { + return res.json(); +}).then(function(body) { + console.log(body); +}); diff --git a/templates/code_php.dot b/templates/code_php.dot new file mode 100644 index 0000000..5802466 --- /dev/null +++ b/templates/code_php.dot @@ -0,0 +1,28 @@ + '{{=p.exampleValues.object}}', +{{?index < data.allHeaders.length-1}} {{?}}{{~}});{{?}} + +$client = new \GuzzleHttp\Client(); + +// Define array of request body. +$request_body = array(); + +try { + $response = $client->request('{{=data.methodUpper}}','{{=data.url}}', array( + 'headers' => $headers, + 'json' => $request_body, + ) + ); + print_r($response->getBody()->getContents()); + } + catch (\GuzzleHttp\Exception\BadResponseException $e) { + // handle exception or api errors. + print_r($e->getMessage()); + } + + // ... diff --git a/templates/code_python.dot b/templates/code_python.dot new file mode 100644 index 0000000..1282b61 --- /dev/null +++ b/templates/code_python.dot @@ -0,0 +1,8 @@ +import requests +{{?data.allHeaders.length}}headers = { +{{~data.allHeaders :p:index}} '{{=p.name}}': {{=p.exampleValues.json}}{{?index < data.allHeaders.length-1}},{{?}} +{{~}}} +{{?}} +r = requests.{{=data.method.verb}}('{{=data.url}}'{{? data.requiredParameters.length}}, params={ +{{~ data.requiredParameters :p:index}} '{{=p.name}}': {{=p.exampleValues.json}}{{? data.requiredParameters.length-1 != index }},{{?}}{{~}} +}{{?}}{{?data.allHeaders.length}}, headers = headers{{?}}) \ No newline at end of file diff --git a/templates/code_ruby.dot b/templates/code_ruby.dot new file mode 100644 index 0000000..172219d --- /dev/null +++ b/templates/code_ruby.dot @@ -0,0 +1,14 @@ +require 'rest-client' +require 'json' + +{{?data.allHeaders.length}}headers = { +{{~data.allHeaders :p:index}} '{{=p.name}}' => {{=p.exampleValues.json}}{{?index < data.allHeaders.length-1}},{{?}} +{{~}}}{{?}} + +result = RestClient.{{=data.method.verb}} '{{=data.url}}', + params: { + {{~ data.requiredParameters :p:index}}'{{=p.name}}' => '{{=p.safeType}}'{{? data.requiredParameters.length-1 != index }},{{?}} +{{~}}}{{? data.allHeaders.length}}, headers: headers +{{?}} + +p JSON.parse(result) diff --git a/templates/code_shell.dot b/templates/code_shell.dot new file mode 100644 index 0000000..9934692 --- /dev/null +++ b/templates/code_shell.dot @@ -0,0 +1,3 @@ +curl -X {{=data.methodUpper}} {{=data.url}}{{=data.requiredQueryString}}{{?data.allHeaders.length}} \{{?}} +{{~data.allHeaders :p:index}} -H '{{=p.name}}: {{=p.exampleValues.object}}'{{?index < data.allHeaders.length-1}} \{{?}} +{{~}} diff --git a/templates/debug.def b/templates/debug.def new file mode 100644 index 0000000..04fcf8f --- /dev/null +++ b/templates/debug.def @@ -0,0 +1 @@ +{{= data.utils.inspect(data) }} diff --git a/templates/discovery.def b/templates/discovery.def new file mode 100644 index 0000000..4755a7b --- /dev/null +++ b/templates/discovery.def @@ -0,0 +1,11 @@ + diff --git a/templates/footer.def b/templates/footer.def new file mode 100644 index 0000000..139597f --- /dev/null +++ b/templates/footer.def @@ -0,0 +1,2 @@ + + diff --git a/templates/links.def b/templates/links.def new file mode 100644 index 0000000..990e130 --- /dev/null +++ b/templates/links.def @@ -0,0 +1,18 @@ +{{? data.response.links }} + +#### Links + +{{ for (var l in data.response.links) { }} +{{ var link = data.response.links[l]; }} + +**{{=l}}** => {{?link.operationId}}{{=link.operationId}}{{??}}{{=link.operationRef}}{{?}} + +{{? link.parameters }} +|Parameter|Expression| +|---|---| +{{for (var p in link.parameters) { }}|{{=p}}|{{=link.parameters[p]}}|{{ } }} +{{?}} + +{{ } /* of links */ }} + +{{?}} diff --git a/templates/main.dot b/templates/main.dot new file mode 100644 index 0000000..2c3a218 --- /dev/null +++ b/templates/main.dot @@ -0,0 +1,138 @@ +{{= data.tags.section }} + +# Endpoints + +> Scroll down for {{? data.header.language_tabs.length}}code samples, {{?}}example requests and responses.{{? data.header.language_tabs.length}} Select a language for code samples from the tabs above or the mobile navigation menu.{{?}} + +{{? data.api.info && data.api.info.description}}{{=data.api.info.description}}{{?}} + +{{? data.api.servers }} +Base URLs: +{{~data.api.servers :s}} +* {{=s.url}} +{{ for(var v in s.variables) { }} + * **{{=v}}** - {{=s.variables[v].description||''}} Default: {{=s.variables[v].default}} +{{? s.variables[v].enum}} +{{~ s.variables[v].enum :e}} + * {{= e}} +{{~}} +{{?}} +{{ } }} +{{~}} +{{?}} + +{{? data.api.info && data.api.info.termsOfService}}Terms of service{{?}} +{{? data.api.info && data.api.info.contact}}{{? data.api.info.contact.email}}Email: {{=data.api.info.contact.name || 'Support'}} {{?}}{{? data.api.info.contact.url}}Web: {{= data.api.info.contact.name || 'Support'}} {{?}}{{?}} +{{? data.api.info && data.api.info.license}}{{? data.api.info.license.url}}License: {{=data.api.info.license.name}}{{??}} License: {{=data.api.info.license.name}}{{?}}{{?}} +{{= data.tags.endSection }} + +{{? data.api.components && data.api.components.securitySchemes }} +{{#def.security}} +{{?}} + +{{= data.tags.section }} + + +{{ for (var r in data.resources) { }} +{{ data.resource = data.resources[r]; }} + +### {{= r}} + +{{? data.resource.description }}{{= data.resource.description}}{{?}} + +{{? data.resource.externalDocs}} +{{=data.resource.externalDocs.description||'External documentation'}} +{{?}} + +{{ for (var m in data.resource.methods) { }} +{{ data.operationUniqueName = m; }} +{{ data.method = data.resource.methods[m]; }} +{{ data.operationUniqueSlug = data.method.slug; }} +{{ data.operation = data.method.operation; }} + +{{= data.templates.operation(data) }} +{{ } /* of methods */ }} + +{{= data.tags.endSection }} +{{ } /* of resources */ }} + +{{? data.api.components && data.api.components.schemas }} +{{= data.tags.section }} + +## Schemas + +{{ for (var s in data.components.schemas) { }} +{{ var origSchema = data.components.schemas[s]; }} +{{ var schema = data.api.components.schemas[s]; }} + +{{= data.tags.section }} + +### {{= s}} + +{{? data.options.yaml }} +```yaml +{{=data.utils.yaml.stringify(data.utils.getSample(schema,data.options,{quiet:true},data.api))}} +{{??}} +```json +{{=data.utils.safejson(data.utils.getSample(schema,data.options,{quiet:true},data.api),null,2)}}{{?}} +``` + +{{ var enums = []; }} +{{ var blocks = data.utils.schemaToArray(origSchema,-1,{trim:true,join:true},data); }} +{{ for (var block of blocks) { + for (var p of block.rows) { + if (p.schema && p.schema.enum) { + for (var e of p.schema.enum) { + enums.push({name:p.name,value:e}); + } + } + } + } +}} + +{{~ blocks :block}} +{{? block.title }}{{= block.title}}{{= '\n\n'}}{{?}} +{{? block.externalDocs}} +{{=block.externalDocs.description||'External documentation'}} +{{?}} + +{{? block===blocks[0] }} +{{= data.tags.section }} + +**Properties** +{{?}} + +{{? block.rows.length}}|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---|{{?}} +{{~ block.rows :p}}|{{=p.displayName}}|{{=p.safeType}}|{{=p.required}}|{{=p.restrictions||'none'}}|{{=p.description||'none'}}| +{{~}} +{{~}} +{{? (blocks[0].rows.length === 0) && (blocks.length === 1) }} +*None* +{{?}} + +{{? enums.length > 0 }} +{{= data.tags.section }} + +**Enumerated Values** + +|Property|Value| +|---|---| +{{~ enums :e}}|{{=e.name}}|{{=data.utils.toPrimitive(e.value)}}| +{{~}} + +{{= data.tags.endSection }} +{{?}} + +{{= data.tags.endSection }} +{{= data.tags.endSection }} + +{{ } /* of schemas */ }} + +{{?}} + +{{#def.footer}} + +{{? data.options.discovery}} +{{#def.discovery}} +{{?}} diff --git a/templates/operation.dot b/templates/operation.dot new file mode 100644 index 0000000..cfd5b63 --- /dev/null +++ b/templates/operation.dot @@ -0,0 +1,49 @@ +{{= data.tags.section }} + +{{ data.methodUpper = data.method.verb.toUpperCase(); }} +{{ data.url = data.utils.slashes(data.baseUrl + data.method.path); }} +{{ data.parameters = data.operation.parameters; }} +{{ data.enums = []; }} +{{ data.utils.fakeProdCons(data); }} +{{ data.utils.fakeBodyParameter(data); }} +{{ data.utils.mergePathParameters(data); }} +{{ data.utils.getParameters(data); }} + +#### {{= data.methodUpper}} {{=data.method.path}} + +{{? data.operation.summary && !data.options.tocSummary}}*{{= data.operation.summary }}*{{?}} + +{{? data.operation.description}}{{= data.operation.description }}{{?}} + +{{? data.options.codeSamples || data.operation["x-code-samples"] }} + +{{= data.utils.getCodeSamples(data) }} +{{?}} + +{{? data.operation.requestBody}} +

Body

+ +{{? data.bodyParameter.exampleValues.description }} +> {{= data.bodyParameter.exampleValues.description }} +{{?}} + +{{= data.utils.getBodyParameterExamples(data) }} +{{?}} + +{{? data.parameters && data.parameters.length }} +{{#def.parameters}} +{{?}} + +{{#def.responses}} + +{{#def.callbacks}} + +{{ data.security = data.operation.security ? data.operation.security : data.api.security; }} +{{? data.security && data.security.length }} +{{#def.authentication}} +{{??}} +{{#def.authentication_none}} +{{?}} + +
+{{= data.tags.endSection }} diff --git a/templates/parameters.def b/templates/parameters.def new file mode 100644 index 0000000..8df3b31 --- /dev/null +++ b/templates/parameters.def @@ -0,0 +1,40 @@ +{{= data.tags.section }} +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +{{~ data.parameters :p}}|{{=p.name}}|{{=p.in}}|{{=p.safeType}}|{{? p.required === true }}✔{{?? }} ❌ {{? }}|{{=p.shortDesc || 'none'}}| +{{~}} + +{{? data.longDescs }} +#### Detailed descriptions +{{~ data.parameters :p}}{{? p.shortDesc !== p.description}} +**{{=p.name}}**: {{=p.description}}{{?}} +{{~}} +{{?}} + +{{~ data.parameters :p}} + +{{? p.schema && p.schema.enum }} +{{~ p.schema.enum :e}} +{{ var entry = {}; entry.name = p.name; entry.value = e; data.enums.push(entry); }} +{{~}} +{{?}} + +{{? p.schema && p.schema.items && p.schema.items.enum }} +{{~ p.schema.items.enum :e}} +{{ var entry = {}; entry.name = p.name; entry.value = e; data.enums.push(entry); }} +{{~}} +{{?}} + +{{~}} + +{{? data.enums && data.enums.length }} +#### Enumerated Values + +|Parameter|Value| +|---|---| +{{~ data.enums :e}}|{{=e.name}}|{{=data.utils.toPrimitive(e.value)}}| +{{~}} +{{?}} +{{= data.tags.endSection }} diff --git a/templates/responses.def b/templates/responses.def new file mode 100644 index 0000000..6a9846b --- /dev/null +++ b/templates/responses.def @@ -0,0 +1,78 @@ +{{ data.responses = data.utils.getResponses(data); }} +{{ data.responseSchemas = false; }} +{{~ data.responses :response }} +{{ if (response.content) data.responseSchemas = true; }} +{{~}} + +{{? data.responseSchemas }} +

Responses

+ +{{= data.utils.getResponseExamples(data) }} +{{?}} + +{{= data.tags.section }} + +|Status|Meaning|Description|Schema| +|---|---|---|---| +{{~ data.responses :r}}|{{=r.status}}|{{=r.meaning}}|{{=r.description || 'none'}}|{{=r.schema}}| +{{~}} + +{{ data.responseSchemas = false; }} +{{~ data.responses :response }} +{{ if (response.content && !response.$ref && !data.utils.isPrimitive(response.type)) data.responseSchemas = true; }} +{{~}} +{{? data.responseSchemas }} +

Response Schema

+{{~ data.responses :response}} +{{? response.content && !response.$ref && !data.utils.isPrimitive(response.type)}} +{{? Object.keys(response.content).length }} +{{ var responseKey = Object.keys(response.content)[0]; }} +{{ var responseSchema = response.content[responseKey].schema; }} +{{ var enums = []; }} +{{ var blocks = data.utils.schemaToArray(responseSchema,0,{trim:true,join:true},data); }} +{{ for (var block of blocks) { + for (var p of block.rows) { + if (p.schema && p.schema.enum) { + for (var e of p.schema.enum) { + enums.push({name:p.name,value:e}); + } + } + } + } +}} + +{{? blocks[0].rows.length || blocks[0].title }} +Status Code **{{=response.status}}** + +{{~ blocks :block}} +{{? block.title }}*{{=block.title}}* +{{?}} +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +{{~block.rows :p}}|{{=p.displayName}}|{{=p.safeType}}|{{=p.required}}|{{=p.restrictions||'none'}}|{{=p.description||'none'}}| +{{~}} +{{~}} +{{?}} + + +{{?}} + +{{ data.response = response; }} +{{#def.links}} + +{{?}} +{{~}} +{{?}} + +{{ data.responseHeaders = data.utils.getResponseHeaders(data); }} +{{? data.responseHeaders.length }} + +### Response Headers + +|Status|Header|Type|Format|Description| +|---|---|---|---|---| +{{~ data.responseHeaders :h}}|{{=h.status}}|{{=h.header}}|{{=h.type}}|{{=h.format||''}}|{{=h.description||'none'}}| +{{~}} + +{{?}} +{{= data.tags.endSection }} diff --git a/templates/security.def b/templates/security.def new file mode 100644 index 0000000..2e83581 --- /dev/null +++ b/templates/security.def @@ -0,0 +1,31 @@ +{{= data.tags.section }} + +# Authentication + +{{ for (var s in data.api.components.securitySchemes) { }} +{{ var sd = data.api.components.securitySchemes[s]; }} +{{? sd.type == 'apiKey' }} +* API Key ({{=s}}) + - Parameter Name: **{{=sd.name}}**, in: {{=sd.in}}. {{=sd.description || ''}} +{{?}} +{{? sd.type == 'http'}} +- HTTP Authentication, scheme: {{=sd.scheme}}{{? sd.description }}
{{=sd.description}}{{?}} +{{?}} +{{? sd.type == 'oauth2'}} +- oAuth2 authentication. {{=sd.description || ''}} +{{ for (var f in sd.flows) { }} +{{ var flow = sd.flows[f]; }} + - Flow: {{=f}} +{{? flow.authorizationUrl}} - Authorization URL = [{{=flow.authorizationUrl}}]({{=flow.authorizationUrl}}){{?}} +{{? flow.tokenUrl}} - Token URL = [{{=flow.tokenUrl}}]({{=flow.tokenUrl}}){{?}} +{{? flow.scopes && Object.keys(flow.scopes).length}} +|Scope|Scope Description| +|---|---| +{{ for (var sc in flow.scopes) { }}|{{=sc}}|{{=data.utils.join(flow.scopes[sc])}}| +{{ } /* of scopes */ }} +{{?}} +{{ } /* of flows */ }} +{{?}} +{{ } /* of securitySchemes */ }} + +{{= data.tags.endSection }} diff --git a/templates/translations.dot b/templates/translations.dot new file mode 100644 index 0000000..b58e912 --- /dev/null +++ b/templates/translations.dot @@ -0,0 +1,19 @@ +{{ +data.translations.defaultTag = 'Default'; +data.translations.response = 'Response'; +data.translations.responseDefault = 'Default'; +data.translations.responseUnknown = 'Unknown'; +data.translations.schemaInline = 'Inline'; +data.translations.schemaNone = 'None'; +data.translations.externalDocs = 'External documentation'; +data.translations.secDefNone = 'None'; +data.translations.secDefScopes = 'Scopes'; +data.translations.anonymous = 'anonymous'; +data.translations.continued = 'continued'; +data.translations.indent = '»'; +data.translations.readOnly = 'read-only'; +data.translations.writeOnly = 'write-only'; +data.tags = {}; +data.tags.section = data.options.respec ? '
' : ''; +data.tags.endSection = data.options.respec ? '
' : ''; +}}