@rockset/cli
Version:
Official Rockset CLI
154 lines (152 loc) • 6.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const _ = require("lodash");
const swagger = require("./swagger-generated.json");
const Handlebars = require("handlebars");
// Allow filesystem in this file because it is not invoked at runtime
// eslint-disable-next-line no-restricted-imports
const fs_1 = require("fs");
const p = require("path");
const YAML = require("yaml");
const docs_codegen_1 = require("./docs-codegen");
const helper_1 = require("@rockset/core/dist/helper");
const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);
const getTemplate = async () => {
const templateText = (await fs_1.promises.readFile(p.join(__dirname, 'apiTemplate.ts.handlebars'))).toString();
const template = Handlebars.compile(templateText);
return template;
};
const pp = (obj) => JSON.stringify(obj, null, 2);
function getBodySchema(bodyParams) {
var _a, _b;
if (bodyParams.length > 1) {
throw new Error('More than one body parameter');
}
else if (bodyParams.length === 1) {
const body = bodyParams[0];
const bodySchema = docs_codegen_1.renderSchema((_b = (_a = bodyParams[0].schema) === null || _a === void 0 ? void 0 : _a.$ref) !== null && _b !== void 0 ? _b : '');
const bodyRequired = body.required;
return helper_1.tuple(YAML.stringify(bodySchema), bodyRequired);
}
else {
return helper_1.tuple(undefined, false);
}
}
async function generate() {
try {
// Get the template
const template = await getTemplate();
const output = _.flatMap(swagger.paths, (path, endpoint) => _.map(path, (get, rawMethod) => {
var _a, _b;
const method = rawMethod.toUpperCase();
const tag = getTag(get);
const operation = get.operationId;
const apicall = `client.${tag}.${operation}.bind(client.${tag})`;
const rawRequestParams = (_a = get.parameters) !== null && _a !== void 0 ? _a : [];
const hasBody = rawRequestParams.some((x) => x.name.toLowerCase() === 'body');
const [bodyParams, urlParams] = _.partition(rawRequestParams, ({ schema, in: location }) => schema && location === 'body');
const [bodySchema, bodyRequired] = getBodySchema(bodyParams);
const parameters = urlParams.map(({ name, description }) => ({
name,
description,
required: true,
hidden: false,
}));
// These are the tags that we want to support load testing for
const loadTest = ['queryLambdas', 'queries', 'documents'].includes(tag);
const schemaTooLong = ((_b = bodySchema === null || bodySchema === void 0 ? void 0 : bodySchema.length) !== null && _b !== void 0 ? _b : 0) > 200;
const description = getDescription({
method,
endpoint,
hasBody,
get,
operation,
bodyRequired,
schemaTooLong,
bodySchema,
});
const examples = getExamples({
hasBody,
operation,
parameterNames: parameters.map((n) => n.name),
topic: tag,
bodyRequired,
schemaTooLong,
bodySchema,
});
const output = template({
apicall,
description,
args: pp(parameters),
endpoint,
method,
className: capitalize(operation),
loadTest,
bodyRequired,
bodySchema,
schemaTooLong,
examples: pp(examples),
});
return { topic: tag, filename: operation, value: output };
}));
output.forEach(async (out) => {
const d = p.join(p.dirname(__dirname), 'commands', 'api', out.topic);
await fs_1.promises.mkdir(d, { recursive: true });
return fs_1.promises.writeFile(p.join(d, `${out.filename}.ts`), out.value);
});
}
catch (error) {
console.log(error);
}
}
function getTag(get) {
return _.camelCase(get.tags[0])
.replace(/apiKey/, 'apikey')
.replace(/organizations/, 'orgs');
}
function getExamples({ hasBody, bodySchema, schemaTooLong, parameterNames, topic, operation, bodyRequired, }) {
const examples = [];
const egNoBody = `$ rockset api:${topic}:${operation} ${parameterNames
.map((x) => x.toUpperCase())
.join(' ')}`;
if (!bodyRequired) {
examples.push(egNoBody);
}
if (hasBody && !schemaTooLong) {
const egBody = `${egNoBody} --body body.yaml
$ cat body.yaml
${bodySchema}
`;
examples.push(egBody);
}
return examples;
}
const genChalkString = (cmd, str) => {
return `\${chalk.${cmd}(\`${str}\`)}`;
};
function getDescription({ method, endpoint, hasBody, get, operation, bodyRequired, schemaTooLong, bodySchema, }) {
const docsLink = genChalkString('underline', `https://docs.rockset.com/rest-api#${operation.toLowerCase()}`);
const exampleBody = hasBody
? schemaTooLong
? `The ${method} body request schema has been omitted because it is too long. Please view the documentation at ${docsLink} to see the example.
`
: `Example Body (YAML):
${bodySchema}
`
: '';
const bodyCallout = hasBody
? genChalkString('bold', `This endpoint ${bodyRequired ? 'REQUIRES' : 'optionally accepts'} a ${method} body. To specify a ${method} body, please pass a JSON or YAML file to the --body flag.
`)
: '';
return `${get.description.toLowerCase().trim().replace(/\.$/, '')}
Arguments to this command will be passed as URL parameters to ${genChalkString('bold', `${method}: ${endpoint}`)}
${bodyCallout}
${exampleBody}
Endpoint Reference
${method}: ${endpoint}
${get.summary}
${get.description}
More documentation at ${docsLink}`;
}
// Run!
generate().catch(console.error);