initial commit to support yaml format
This commit is contained in:
Родитель
f7cf17e7c9
Коммит
ec0d891aec
|
@ -24,6 +24,12 @@ exports.builder = {
|
|||
'need to be transformed. If operationIds are not provided then the entire spec will be processed. ' +
|
||||
'Example: "StorageAccounts_Create, StorageAccounts_List, Usages_List".',
|
||||
string: true
|
||||
},
|
||||
y: {
|
||||
alias: 'inYaml',
|
||||
describe: 'A boolean flag when provided will indicate the tool to ' +
|
||||
'generate wireformat in a yaml doc. Default is a markdown doc.',
|
||||
boolean: true
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -33,12 +39,13 @@ exports.handler = function (argv) {
|
|||
let operationIds = argv.operationIds;
|
||||
let outDir = argv.outDir;
|
||||
let vOptions = {};
|
||||
let emitYaml = argv.inYaml;
|
||||
vOptions.consoleLogLevel = argv.logLevel;
|
||||
vOptions.logFilepath = argv.f;
|
||||
if (specPath.match(/.*composite.*/ig) !== null) {
|
||||
return validate.generateWireFormatInCompositeSpec(specPath, vOptions);
|
||||
return validate.generateWireFormatInCompositeSpec(specPath, outDir, emitYaml, vOptions);
|
||||
} else {
|
||||
return validate.generateWireFormat(specPath, outDir, operationIds, vOptions);
|
||||
return validate.generateWireFormat(specPath, outDir, emitYaml, operationIds, vOptions);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,9 +7,10 @@ const url = require('url'),
|
|||
|
||||
class HttpTemplate {
|
||||
|
||||
constructor(request, responses) {
|
||||
constructor(request, responses, emitYaml) {
|
||||
this.request = request;
|
||||
this.responses = responses;
|
||||
this.emitYaml = emitYaml || false;
|
||||
}
|
||||
|
||||
getHost() {
|
||||
|
@ -22,15 +23,16 @@ class HttpTemplate {
|
|||
|
||||
getRequestHeaders() {
|
||||
let result = ``;
|
||||
let padding = this.emitYaml ? ` ` : ``;
|
||||
if (this.request.body) {
|
||||
result += `Content-Length: ${JSON.stringify(this.request.body).length}\n`;
|
||||
result += `${padding}Content-Length: ${JSON.stringify(this.request.body).length}\n`;
|
||||
}
|
||||
if (this.request.headers) {
|
||||
let headers = Object.keys(this.request.headers);
|
||||
|
||||
for (let i = 0; i < headers.length; i++) {
|
||||
let headerName = headers[i];
|
||||
result += `${headerName}: ${this.request.headers[headerName]}`;
|
||||
result += `${padding}${headerName}: ${this.request.headers[headerName]}`;
|
||||
if (i !== headers.length - 1) {
|
||||
result += `\n`;
|
||||
}
|
||||
|
@ -41,15 +43,16 @@ class HttpTemplate {
|
|||
|
||||
getCurlRequestHeaders() {
|
||||
let result = ``;
|
||||
let padding = this.emitYaml ? ` ` : ``;
|
||||
if (this.request.body) {
|
||||
result += ` \n-H 'Content-Length: ${JSON.stringify(this.request.body).length}' \\`;
|
||||
result += `\n${padding}-H 'Content-Length: ${JSON.stringify(this.request.body).length}' \\`;
|
||||
}
|
||||
if (this.request.headers) {
|
||||
let headers = Object.keys(this.request.headers);
|
||||
|
||||
for (let i = 0; i < headers.length; i++) {
|
||||
let headerName = headers[i];
|
||||
result += `\n-H '${headerName}: ${this.request.headers[headerName]}' \\`;
|
||||
result += `\n${padding}-H '${headerName}: ${this.request.headers[headerName]}' \\`;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -63,18 +66,23 @@ class HttpTemplate {
|
|||
return body;
|
||||
}
|
||||
|
||||
//The format for request body in Curl has been inspired from the following links:
|
||||
// - https://stackoverflow.com/questions/34847981/curl-with-multiline-of-json
|
||||
// - https://ok-b.org/t/34847981/curl-with-multiline-of-json
|
||||
getCurlRequestBody() {
|
||||
let body = ``;
|
||||
let padding = this.emitYaml ? ` ` : ``;
|
||||
if (this.request && this.request.body !== null && this.request.body !== undefined) {
|
||||
body = `\n-d ${JSON.stringify(this.request.body, null, 2).split('\n').join(' \\\n')}`;
|
||||
body = `\n${padding}-d @- << EOF\n${padding}${JSON.stringify(this.request.body, null, 2).split(`\n`).join(`\n${padding}`)}\n${padding}EOF`;
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
getResponseHeaders(response) {
|
||||
let result = ``;
|
||||
let padding = this.emitYaml ? ` ` : ``;
|
||||
if (response.body) {
|
||||
result += `Content-Length: ${JSON.stringify(response.body).length}\n`;
|
||||
result += `${padding}Content-Length: ${JSON.stringify(response.body).length}\n`;
|
||||
}
|
||||
let gotContentType = false;
|
||||
if (response.headers) {
|
||||
|
@ -82,14 +90,14 @@ class HttpTemplate {
|
|||
for (let i = 0; i < headers.length; i++) {
|
||||
let headerName = headers[i];
|
||||
if (headerName.match(/^Content-Type$/ig) !== null) gotContentType = true;
|
||||
result += `${headerName}: ${response.headers[headerName]}`;
|
||||
result += `${padding}${headerName}: ${response.headers[headerName]}`;
|
||||
if (i !== headers.length - 1) {
|
||||
result += `\n`;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!gotContentType) {
|
||||
result += `Content-Type: application/json; charset=utf-8`
|
||||
result += `${padding}Content-Type: application/json; charset=utf-8`
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -103,7 +111,8 @@ class HttpTemplate {
|
|||
}
|
||||
|
||||
populateRequest() {
|
||||
let requestTemplate =
|
||||
let requestTemplate = ``;
|
||||
let requestTemplateMD =
|
||||
`## Request
|
||||
|
||||
\`\`\`http
|
||||
|
@ -117,13 +126,30 @@ ${this.getRequestBody()}
|
|||
\`\`\`\
|
||||
|
||||
`;
|
||||
|
||||
|
||||
let requestTemplateYAML =
|
||||
`#Request
|
||||
request: |
|
||||
${this.request.method} ${this.request.url} HTTP/1.1
|
||||
Authorization: Bearer <token>
|
||||
${this.getRequestHeaders()}
|
||||
host: ${this.getHost()}
|
||||
Connection: close
|
||||
|
||||
${this.getRequestBody()}
|
||||
`;
|
||||
|
||||
requestTemplate = this.emitYaml ? requestTemplateYAML : requestTemplateMD;
|
||||
return requestTemplate;
|
||||
}
|
||||
|
||||
populateResponse(response, responseType) {
|
||||
if (!responseType) responseType = 'Response';
|
||||
let responseGuid = uuid.v4();
|
||||
let responseTemplate = `
|
||||
let responseTemplate = ``;
|
||||
|
||||
let responseTemplateMD = `
|
||||
## ${responseType}
|
||||
|
||||
#### StatusCode: ${response.statusCode}
|
||||
|
@ -145,17 +171,48 @@ Connection: close
|
|||
${this.getResponseBody(response)}
|
||||
\`\`\`
|
||||
`;
|
||||
|
||||
|
||||
let responseTemplateYAML = `
|
||||
#${responseType}
|
||||
response:
|
||||
#${response.statusCode}
|
||||
${response.statusCode}: |
|
||||
HTTP 1.1 ${response.statusCode}
|
||||
Cache-Control: no-cache
|
||||
Pragma: no-cache
|
||||
Expires: -1
|
||||
x-ms-ratelimit-remaining-subscription-writes: 1199
|
||||
x-ms-request-id: ${responseGuid}
|
||||
x-ms-correlation-request-id: ${responseGuid}
|
||||
x-ms-routing-request-id: WESTUS2:${new Date().toISOString().replace(/(\W)/ig, '')}:${responseGuid}
|
||||
Strict-Transport-Security: max-age=31536000; includeSubDomains
|
||||
${this.getResponseHeaders(response)}
|
||||
Date: ${new Date().toUTCString()}
|
||||
Connection: close
|
||||
|
||||
${this.getResponseBody(response)}
|
||||
`;
|
||||
responseTemplate = this.emitYaml ? responseTemplateYAML : responseTemplateMD;
|
||||
return responseTemplate;
|
||||
}
|
||||
|
||||
populateCurl() {
|
||||
let template =
|
||||
let template = ``;
|
||||
let templateMD =
|
||||
`\n## Curl
|
||||
|
||||
\`\`\`bash
|
||||
curl -X ${this.request.method} '${this.request.url}' \\\n-H 'authorization: bearer <token>' \\${this.getCurlRequestHeaders()}${this.getCurlRequestBody()}
|
||||
\`\`\`
|
||||
`;
|
||||
|
||||
let templateYAML =
|
||||
`\n#Curl
|
||||
curl: |
|
||||
curl -X ${this.request.method} '${this.request.url}' \\\n -H 'authorization: bearer <token>' \\${this.getCurlRequestHeaders()}${this.getCurlRequestBody()}
|
||||
`;
|
||||
template = this.emitYaml ? templateYAML : templateMD;
|
||||
return template;
|
||||
}
|
||||
|
||||
|
|
|
@ -164,11 +164,11 @@ exports.resolveCompositeSpec = function resolveCompositeSpec(specPath, outputDir
|
|||
};
|
||||
|
||||
|
||||
exports.generateWireFormat = function generateWireFormat(specPath, outDir, operationIds, options) {
|
||||
exports.generateWireFormat = function generateWireFormat(specPath, outDir, emitYaml, operationIds, options) {
|
||||
if (!options) options = {};
|
||||
log.consoleLogLevel = options.consoleLogLevel || log.consoleLogLevel;
|
||||
log.filepath = options.logFilepath || log.filepath;
|
||||
let wfGenerator = new WireFormatGenerator(specPath, null, outDir);
|
||||
let wfGenerator = new WireFormatGenerator(specPath, null, outDir, emitYaml);
|
||||
return wfGenerator.initialize().then(function () {
|
||||
log.info(`Generating wire format request and responses for swagger spec: "${specPath}":\n`);
|
||||
wfGenerator.processOperations(operationIds);
|
||||
|
@ -179,7 +179,7 @@ exports.generateWireFormat = function generateWireFormat(specPath, outDir, opera
|
|||
});
|
||||
};
|
||||
|
||||
exports.generateWireFormatInCompositeSpec = function generateWireFormatInCompositeSpec(compositeSpecPath, outDir, options) {
|
||||
exports.generateWireFormatInCompositeSpec = function generateWireFormatInCompositeSpec(compositeSpecPath, outDir, emitYaml, options) {
|
||||
if (!options) options = {};
|
||||
log.consoleLogLevel = options.consoleLogLevel || log.consoleLogLevel;
|
||||
log.filepath = options.logFilepath || log.filepath;
|
||||
|
@ -187,7 +187,7 @@ exports.generateWireFormatInCompositeSpec = function generateWireFormatInComposi
|
|||
options.consoleLogLevel = log.consoleLogLevel;
|
||||
options.logFilepath = log.filepath;
|
||||
let promiseFactories = docs.map(function (doc) {
|
||||
return function () { return exports.generateWireFormat(doc, outDir, null, options); }
|
||||
return function () { return exports.generateWireFormat(doc, outDir, emitYaml, null, options); }
|
||||
});
|
||||
return utils.executePromisesSequentially(promiseFactories);
|
||||
}).catch(function (err) {
|
||||
|
|
|
@ -19,7 +19,7 @@ const ErrorCodes = Constants.ErrorCodes;
|
|||
|
||||
|
||||
class WireFormatGenerator {
|
||||
constructor(specPath, specInJson, wireFormatDir) {
|
||||
constructor(specPath, specInJson, wireFormatDir, emitYaml) {
|
||||
if (specPath === null || specPath === undefined || typeof specPath.valueOf() !== 'string' || !specPath.trim().length) {
|
||||
throw new Error('specPath is a required parameter of type string and it cannot be an empty string.')
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ class WireFormatGenerator {
|
|||
if (!fs.existsSync(this.wireFormatDir)) {
|
||||
fs.mkdirSync(this.wireFormatDir);
|
||||
}
|
||||
this.emitYaml = emitYaml || false;
|
||||
this.specInJson = specInJson;
|
||||
this.specResolver = null;
|
||||
this.swaggerApi = null;
|
||||
|
@ -248,9 +249,10 @@ class WireFormatGenerator {
|
|||
let sampleRequest = self.processRequest(operation, xmsExample.parameters);
|
||||
let sampleResponses = self.processXmsExampleResponses(operation, xmsExample.responses);
|
||||
let exampleFileName = path.basename(xmsExamples[scenario].filePath);
|
||||
let wireformatFileName = `${exampleFileName.substring(0, exampleFileName.indexOf(path.extname(exampleFileName)))}.md`;
|
||||
let wireformatFileName = `${exampleFileName.substring(0, exampleFileName.indexOf(path.extname(exampleFileName)))}.`;
|
||||
wireformatFileName += self.emitYaml ? 'yml' : 'md';
|
||||
let fileName = path.join(self.wireFormatDir, wireformatFileName);
|
||||
let httpTempl = new HttpTemplate(sampleRequest, sampleResponses);
|
||||
let httpTempl = new HttpTemplate(sampleRequest, sampleResponses, self.emitYaml);
|
||||
let sampleData = httpTempl.populate();
|
||||
fs.writeFileSync(fileName, sampleData, { encoding: 'utf8' });
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче