|
| 1 | +import { parseTemplate } from 'url-template' |
| 2 | +import { stringify } from 'javascript-stringify' |
| 3 | + |
| 4 | +import type { CodeSample, Operation } from '../rest/types' |
| 5 | + |
| 6 | +/* |
| 7 | + Generates a curl example |
| 8 | +
|
| 9 | + For example: |
| 10 | + curl \ |
| 11 | + -X POST \ |
| 12 | + -H "Accept: application/vnd.github.v3+json" \ |
| 13 | + https://{hostname}/api/v3/repos/OWNER/REPO/deployments \ |
| 14 | + -d '{"ref":"topic-branch","payload":"{ \"deploy\": \"migrate\" }","description":"Deploy request from hubot"}' |
| 15 | +*/ |
| 16 | +export function getShellExample(operation: Operation, codeSample: CodeSample) { |
| 17 | + // This allows us to display custom media types like application/sarif+json |
| 18 | + const defaultAcceptHeader = codeSample?.response?.contentType?.includes('+json') |
| 19 | + ? codeSample.response.contentType |
| 20 | + : 'application/vnd.github.v3+json' |
| 21 | + |
| 22 | + const requestPath = codeSample?.request?.parameters |
| 23 | + ? parseTemplate(operation.requestPath).expand(codeSample.request.parameters) |
| 24 | + : operation.requestPath |
| 25 | + |
| 26 | + let requestBodyParams = '' |
| 27 | + if (codeSample?.request?.bodyParameters) { |
| 28 | + requestBodyParams = `-d '${JSON.stringify(codeSample.request.bodyParameters)}'` |
| 29 | + |
| 30 | + // If the content type is application/x-www-form-urlencoded the format of |
| 31 | + // the shell example is --data-urlencode param1=value1 --data-urlencode param2=value2 |
| 32 | + // For example, this operation: |
| 33 | + // https://docs.github.com/en/enterprise/rest/reference/enterprise-admin#enable-or-disable-maintenance-mode |
| 34 | + if (codeSample.request.contentType === 'application/x-www-form-urlencoded') { |
| 35 | + requestBodyParams = '' |
| 36 | + const paramNames = Object.keys(codeSample.request.bodyParameters) |
| 37 | + paramNames.forEach((elem) => { |
| 38 | + requestBodyParams = `${requestBodyParams} --data-urlencode ${elem}=${codeSample.request.bodyParameters[elem]}` |
| 39 | + }) |
| 40 | + } |
| 41 | + } |
| 42 | + |
| 43 | + const args = [ |
| 44 | + operation.verb !== 'get' && `-X ${operation.verb.toUpperCase()}`, |
| 45 | + `-H "Accept: ${defaultAcceptHeader}"`, |
| 46 | + `${operation.serverUrl}${requestPath}`, |
| 47 | + requestBodyParams, |
| 48 | + ].filter(Boolean) |
| 49 | + return `curl \\\n ${args.join(' \\\n ')}` |
| 50 | +} |
| 51 | + |
| 52 | +/* |
| 53 | + Generates a GitHub CLI example |
| 54 | +
|
| 55 | + For example: |
| 56 | + gh api \ |
| 57 | + -X POST \ |
| 58 | + -H "Accept: application/vnd.github.v3+json" \ |
| 59 | + /repos/OWNER/REPO/deployments \ |
| 60 | + -fref,topic-branch=0,payload,{ "deploy": "migrate" }=1,description,Deploy request from hubot=2 |
| 61 | +*/ |
| 62 | +export function getGHExample(operation: Operation, codeSample: CodeSample) { |
| 63 | + const defaultAcceptHeader = codeSample?.response?.contentType?.includes('+json') |
| 64 | + ? codeSample.response.contentType |
| 65 | + : 'application/vnd.github.v3+json' |
| 66 | + const hostname = operation.serverUrl !== 'https://api.github.com' ? '--hostname HOSTNAME' : '' |
| 67 | + |
| 68 | + const requestPath = codeSample?.request?.parameters |
| 69 | + ? parseTemplate(operation.requestPath).expand(codeSample.request.parameters) |
| 70 | + : operation.requestPath |
| 71 | + |
| 72 | + let requestBodyParams = '' |
| 73 | + if (codeSample?.request?.bodyParameters) { |
| 74 | + const bodyParamValues = Object.values(codeSample.request.bodyParameters) |
| 75 | + // GitHub CLI does not support sending Objects and arrays using the -F or |
| 76 | + // -f flags. That support may be added in the future. It is possible to |
| 77 | + // use gh api --input to take a JSON object from standard input |
| 78 | + // constructed by jq and piped to gh api. However, we'll hold off on adding |
| 79 | + // that complexity for now. |
| 80 | + if (bodyParamValues.some((elem) => typeof elem === 'object')) { |
| 81 | + return undefined |
| 82 | + } |
| 83 | + requestBodyParams = Object.keys(codeSample.request.bodyParameters) |
| 84 | + .map((key) => { |
| 85 | + if (typeof codeSample.request.bodyParameters[key] === 'string') { |
| 86 | + return `-f ${key}='${codeSample.request.bodyParameters[key]}'` |
| 87 | + } else { |
| 88 | + return `-F ${key}=${codeSample.request.bodyParameters[key]}` |
| 89 | + } |
| 90 | + }) |
| 91 | + .join(' ') |
| 92 | + } |
| 93 | + const args = [ |
| 94 | + operation.verb !== 'get' && `--method ${operation.verb.toUpperCase()}`, |
| 95 | + `-H "Accept: ${defaultAcceptHeader}"`, |
| 96 | + hostname, |
| 97 | + requestPath, |
| 98 | + requestBodyParams, |
| 99 | + ].filter(Boolean) |
| 100 | + return `gh api \\\n ${args.join(' \\\n ')}` |
| 101 | +} |
| 102 | + |
| 103 | +/* |
| 104 | + Generates an octokit.js example |
| 105 | +
|
| 106 | + For example: |
| 107 | + await octokit.request('POST /repos/{owner}/{repo}/deployments'{ |
| 108 | + "owner": "OWNER", |
| 109 | + "repo": "REPO", |
| 110 | + "ref": "topic-branch", |
| 111 | + "payload": "{ \"deploy\": \"migrate\" }", |
| 112 | + "description": "Deploy request from hubot" |
| 113 | + }) |
| 114 | +
|
| 115 | +*/ |
| 116 | +export function getJSExample(operation: Operation, codeSample: CodeSample) { |
| 117 | + const parameters = codeSample.request |
| 118 | + ? { ...codeSample.request.parameters, ...codeSample.request.bodyParameters } |
| 119 | + : {} |
| 120 | + return `await octokit.request('${operation.verb.toUpperCase()} ${ |
| 121 | + operation.requestPath |
| 122 | + }', ${stringify(parameters, null, 2)})` |
| 123 | +} |
0 commit comments