forked from bluesky-social/atproto
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add docs generator and improve http-routes.md generation (bluesky-soc…
- Loading branch information
Showing
31 changed files
with
2,895 additions
and
190 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"private": true, | ||
"scripts": { | ||
"build": "node scripts/gen.js" | ||
}, | ||
"dependencies": { | ||
"widdershins": "^4.0.1", | ||
"yaml": "^2.1.1" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
const widdershins = require('widdershins') | ||
const yaml = require('yaml') | ||
const fs = require('fs') | ||
const path = require('path') | ||
|
||
async function httpRoutes() { | ||
console.log('Converting http-routes.yml to .md') | ||
const yamlStr = fs.readFileSync( | ||
path.join(__dirname, '..', 'specs', 'http-routes.yml'), | ||
'utf8', | ||
) | ||
const md = await widdershins.convert(yaml.parse(yamlStr), { | ||
search: false, | ||
language_tabs: [], | ||
sample: false, | ||
user_templates: path.join(__dirname, 'http-routes-templates'), | ||
}) | ||
fs.writeFileSync( | ||
path.join(__dirname, '..', 'specs', 'http-routes.md'), | ||
stripFrontMatter(md), | ||
) | ||
} | ||
httpRoutes() | ||
// widdershins --search false --language_tabs false -o docs/specs/http-routes.md --raw docs/specs/http-routes.yml | ||
|
||
function stripFrontMatter(md) { | ||
const lines = md.split('\n') | ||
let numDashLines = 0 | ||
let i = 0 | ||
while (numDashLines < 2) { | ||
if (lines[i].trim() === '---') { | ||
numDashLines++ | ||
} | ||
i++ | ||
} | ||
return lines.slice(i).join('\n') | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<aside class="warning"> | ||
To perform this operation, you must be authenticated by means of one of the following methods: | ||
{{= data.utils.getAuthenticationStr(data) }} | ||
</aside> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<aside class="success"> | ||
This operation does not require authentication | ||
</aside> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; }} | ||
|
||
{{?}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
|
||
/// <<summary>> | ||
/// Example of Http Client | ||
/// <</summary>> | ||
public class HttpExample | ||
{ | ||
private HttpClient Client { get; set; } | ||
|
||
/// <<summary>> | ||
/// Setup http client | ||
/// <</summary>> | ||
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); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
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) | ||
// ... | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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}} | ||
{{~}} | ||
{{?}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{{?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: inputBody{{?}}{{? data.bodyParameter.present && data.allHeaders.length}},{{?}} | ||
{{?data.allHeaders.length}} headers: headers{{?}} | ||
}) | ||
.then(function(res) { | ||
return res.json(); | ||
}).then(function(body) { | ||
console.log(body); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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)); | ||
} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
}); |
Oops, something went wrong.