234 lines
No EOL
7 KiB
JavaScript
234 lines
No EOL
7 KiB
JavaScript
// Libraries used
|
|
const axios = require('axios');
|
|
|
|
// BookStack API variables
|
|
// Uses values on the environment unless hardcoded
|
|
// To hardcode, add values to the empty strings in the below.
|
|
const bookStackConfig = {
|
|
base_url: '' || process.env.BS_URL,
|
|
token_id: '' || process.env.BS_TOKEN_ID,
|
|
token_secret: '' || process.env.BS_TOKEN_SECRET,
|
|
};
|
|
|
|
// Script Logic
|
|
////////////////
|
|
|
|
// Create an axios instance for our API
|
|
const api = axios.create({
|
|
baseURL: bookStackConfig.base_url.replace(/\/$/, '') + '/api/',
|
|
timeout: 5000,
|
|
headers: {'Authorization': `Token ${bookStackConfig.token_id}:${bookStackConfig.token_secret}`},
|
|
});
|
|
|
|
// Wrap the rest of our code in an async function, so we can await within.
|
|
(async function () {
|
|
|
|
// Get our default schema structure and look up to BookStack
|
|
// to get a JSON view of the BookStack docs.
|
|
const postmanSchema = getBaseCollectionSchema();
|
|
const {data: docs} = await api.get('/docs.json');
|
|
|
|
// Cycle over the endpoint categories within the API docs
|
|
for (const [category, endpoints] of Object.entries(docs)) {
|
|
// Create the schema for the postman collection, which represents
|
|
// a BookStack API category.
|
|
const postmanFolderSchema = {
|
|
name: category.toUpperCase(),
|
|
item: [],
|
|
};
|
|
|
|
// Cycle over the endpoints within the category
|
|
for (const endpoint of endpoints) {
|
|
postmanFolderSchema.item.push(getEndpointSchema(endpoint));
|
|
}
|
|
|
|
// Push our endpoint data into the postman collection
|
|
postmanSchema.item.push(postmanFolderSchema);
|
|
}
|
|
|
|
// Output the postman collection data to the command line
|
|
console.log(JSON.stringify(postmanSchema, null, 2));
|
|
|
|
})().catch(err => {
|
|
|
|
// Handle API errors
|
|
if (err.response) {
|
|
console.error(`Request failed with status ${err.response.status} [${err.response.statusText}]`);
|
|
return;
|
|
}
|
|
|
|
// Output all other errors
|
|
console.error(err)
|
|
});
|
|
|
|
|
|
/**
|
|
* Get the postman collection data for a specific endpoint.
|
|
* @param {Object} apiEndpoint
|
|
* @return {{request: {method, header: *[]}, response: *[], name: string}}
|
|
*/
|
|
function getEndpointSchema(apiEndpoint) {
|
|
// Create our base format for the postman schema for a single endpoint
|
|
const postmanEndpointSchema = {
|
|
name: `${apiEndpoint.name}`,
|
|
request: {
|
|
method: apiEndpoint.method,
|
|
header: [],
|
|
},
|
|
response: []
|
|
};
|
|
|
|
// Create the base format used to represent a URL
|
|
const url = {
|
|
raw: `{{BASE_URL}}/${apiEndpoint.uri}`,
|
|
host: ['{{BASE_URL}}'],
|
|
path: apiEndpoint.uri.split('/'),
|
|
query: []
|
|
};
|
|
|
|
// If a listing endpoint, add the standard list params,
|
|
// although we leave them disabled by default.
|
|
if (apiEndpoint.controller_method === 'list') {
|
|
url.query = [
|
|
{
|
|
"key": "count",
|
|
"value": "100",
|
|
"disabled": true
|
|
},
|
|
{
|
|
"key": "offset",
|
|
"value": "0",
|
|
"disabled": true
|
|
},
|
|
{
|
|
"key": "sort",
|
|
"value": "+name",
|
|
"disabled": true
|
|
},
|
|
{
|
|
"key": "filter[id]",
|
|
"value": "5",
|
|
"disabled": true
|
|
}
|
|
];
|
|
}
|
|
|
|
// Add the url to the request schema
|
|
postmanEndpointSchema.request.url = url;
|
|
|
|
// Build a description for the endpoint
|
|
// Formats the body parameters, if existing, to shown their validations.
|
|
const description = [apiEndpoint.description];
|
|
if (apiEndpoint.body_params) {
|
|
description.push('', '', 'Available body parameters:', '');
|
|
for (const [name, validations] of Object.entries(apiEndpoint.body_params)) {
|
|
description.push(`${name}: ${validations.join(' :: ')}`);
|
|
}
|
|
}
|
|
postmanEndpointSchema.request.description = description.join('\n');
|
|
|
|
// If we have an example request, push it as default body JSON data
|
|
if (apiEndpoint.example_request) {
|
|
postmanEndpointSchema.request.header.push({
|
|
"key": "Content-Type",
|
|
"value": "application/json"
|
|
});
|
|
postmanEndpointSchema.request.body = {
|
|
mode: "raw",
|
|
raw: apiEndpoint.example_request,
|
|
options: {
|
|
raw: {
|
|
language: 'json'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Push an example of a response if we have one
|
|
if (apiEndpoint.example_response) {
|
|
postmanEndpointSchema.response.push({
|
|
name: 'Example Response',
|
|
"status": "OK",
|
|
"code": 200,
|
|
"_postman_previewlanguage": "json",
|
|
header: [
|
|
{
|
|
"key": "Content-Type",
|
|
"value": "application/json"
|
|
},
|
|
],
|
|
body: apiEndpoint.example_response,
|
|
});
|
|
}
|
|
|
|
// Provide back the postman schema data
|
|
return postmanEndpointSchema;
|
|
}
|
|
|
|
/**
|
|
* Get the base Postman collection schema data structure.
|
|
* Contains auth data and variables.
|
|
* @return {{item: *[], auth: {apikey: [{type: string, value: string, key: string},{type: string, value: string, key: string}], type: string}, variable: [{type: string, value: string, key: string},{type: string, value: string, key: string},{type: string, value: string, key: string}], event: [{listen: string, script: {type: string, exec: string[]}},{listen: string, script: {type: string, exec: string[]}}], info: {schema: string, name: string}}}
|
|
*/
|
|
function getBaseCollectionSchema() {
|
|
return {
|
|
info: {
|
|
name: "BookStack REST API",
|
|
schema: "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
|
|
},
|
|
item: [
|
|
],
|
|
auth: {
|
|
type: "apikey",
|
|
apikey: [
|
|
{
|
|
key: "value",
|
|
value: "Token {{TOKEN_ID}}:{{TOKEN_SECRET}}",
|
|
type: "string"
|
|
},
|
|
{
|
|
key: "key",
|
|
value: "Authorization",
|
|
type: "string"
|
|
}
|
|
]
|
|
},
|
|
event: [
|
|
{
|
|
listen: "prerequest",
|
|
script: {
|
|
type: "text/javascript",
|
|
exec: [
|
|
""
|
|
]
|
|
}
|
|
},
|
|
{
|
|
listen: "test",
|
|
script: {
|
|
type: "text/javascript",
|
|
exec: [
|
|
""
|
|
]
|
|
}
|
|
}
|
|
],
|
|
variable: [
|
|
{
|
|
key: "TOKEN_ID",
|
|
value: "",
|
|
type: "default"
|
|
},
|
|
{
|
|
key: "TOKEN_SECRET",
|
|
value: "",
|
|
type: "default"
|
|
},
|
|
{
|
|
key: "BASE_URL",
|
|
value: "",
|
|
type: "default"
|
|
}
|
|
]
|
|
};
|
|
} |