2 const axios = require('axios');
4 // BookStack API variables
5 // Uses values on the environment unless hardcoded
6 // To hardcode, add values to the empty strings in the below.
7 const bookStackConfig = {
8 base_url: '' || process.env.BS_URL,
9 token_id: '' || process.env.BS_TOKEN_ID,
10 token_secret: '' || process.env.BS_TOKEN_SECRET,
16 // Create an axios instance for our API
17 const api = axios.create({
18 baseURL: bookStackConfig.base_url.replace(/\/$/, '') + '/api/',
20 headers: {'Authorization': `Token ${bookStackConfig.token_id}:${bookStackConfig.token_secret}`},
23 // Wrap the rest of our code in an async function, so we can await within.
26 // Get our default schema structure and look up to BookStack
27 // to get a JSON view of the BookStack docs.
28 const postmanSchema = getBaseCollectionSchema();
29 const {data: docs} = await api.get('/docs.json');
31 // Cycle over the endpoint categories within the API docs
32 for (const [category, endpoints] of Object.entries(docs)) {
33 // Create the schema for the postman collection, which represents
34 // a BookStack API category.
35 const postmanFolderSchema = {
36 name: category.toUpperCase(),
40 // Cycle over the endpoints within the category
41 for (const endpoint of endpoints) {
42 postmanFolderSchema.item.push(getEndpointSchema(endpoint));
45 // Push our endpoint data into the postman collection
46 postmanSchema.item.push(postmanFolderSchema);
49 // Output the postman collection data to the command line
50 console.log(JSON.stringify(postmanSchema, null, 2));
56 console.error(`Request failed with status ${err.response.status} [${err.response.statusText}]`);
60 // Output all other errors
66 * Get the postman collection data for a specific endpoint.
67 * @param {Object} apiEndpoint
68 * @return {{request: {method, header: *[]}, response: *[], name: string}}
70 function getEndpointSchema(apiEndpoint) {
71 // Create our base format for the postman schema for a single endpoint
72 const postmanEndpointSchema = {
73 name: `${apiEndpoint.name}`,
75 method: apiEndpoint.method,
81 // Create the base format used to represent a URL
83 raw: `{{BASE_URL}}/${apiEndpoint.uri}`,
84 host: ['{{BASE_URL}}'],
85 path: apiEndpoint.uri.split('/'),
89 // If a listing endpoint, add the standard list params,
90 // although we leave them disabled by default.
91 if (apiEndpoint.controller_method === 'list') {
116 // Add the url to the request schema
117 postmanEndpointSchema.request.url = url;
119 // Build a description for the endpoint
120 // Formats the body parameters, if existing, to shown their validations.
121 const description = [apiEndpoint.description];
122 if (apiEndpoint.body_params) {
123 description.push('', '', 'Available body parameters:', '');
124 for (const [name, validations] of Object.entries(apiEndpoint.body_params)) {
125 description.push(`${name}: ${validations.join(' :: ')}`);
128 postmanEndpointSchema.request.description = description.join('\n');
130 // If we have an example request, push it as default body JSON data
131 if (apiEndpoint.example_request) {
132 postmanEndpointSchema.request.header.push({
133 "key": "Content-Type",
134 "value": "application/json"
136 postmanEndpointSchema.request.body = {
138 raw: apiEndpoint.example_request,
147 // Push an example of a response if we have one
148 if (apiEndpoint.example_response) {
149 postmanEndpointSchema.response.push({
150 name: 'Example Response',
153 "_postman_previewlanguage": "json",
156 "key": "Content-Type",
157 "value": "application/json"
160 body: apiEndpoint.example_response,
164 // Provide back the postman schema data
165 return postmanEndpointSchema;
169 * Get the base Postman collection schema data structure.
170 * Contains auth data and variables.
171 * @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}}}
173 function getBaseCollectionSchema() {
176 name: "BookStack REST API",
177 schema: "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
186 value: "Token {{TOKEN_ID}}:{{TOKEN_SECRET}}",
191 value: "Authorization",
198 listen: "prerequest",
200 type: "text/javascript",
209 type: "text/javascript",