sugar-generate
Version:
Auto generate OAS 3.0 REST + GraphQL APIs (Node + MongoDB)
158 lines (150 loc) • 5.54 kB
JavaScript
const fs = require('fs');
const beautify = require('js-beautify').js;
module.exports = ({ schema, logging, destination, name }) => {
const action = 'get';
const { getSearchCode, uppercase, getValidationCode, sugarGenerated, extraParams, getSchemaQueryDefinitions } = require('../utils');
if (logging) console.log(` API => REST => GET ${name}`);
const controllerSubFolder = `${destination}/controller/${name}`;
const createFile = `${controllerSubFolder}/get.js`;
let code = [];
const top = [
sugarGenerated(),
`const ${uppercase(name)} = require("../../models/${uppercase(name)}");`,
// `const { userCanApiKey } = require('../../configs/config');`,
// `const userCan = require('../../user-can')(userCanApiKey);`,
];
let swagger = [
"/*",
`* @oas [get] /${name}s`,
`* summary: "get ${name}s"`,
`* tags: ["${name}"]`,
`* parameters: `,
`* - in: query`,
`* name: page`,
`* description: page`,
`* schema:`,
`* type: integer`,
`* - in: query`,
`* name: limit`,
`* description: The numbers of items to return`,
`* schema:`,
`* type: integer`,
`* - in: query`,
`* name: filters`,
`* description: Filters to search on specific 'columns'`,
`* style: deepObject`,
`* schema:`,
`* type: object`,
`* example: 'stringified array [{"column":{"title":"Name","field":"name","type":"…Sort":"asc","id":0}},"operator":"=","value":"1"}]'`,
`* - in: query`,
`* name: orderBy`,
`* style: deepObject`,
`* description: object containing how to sort the items`,
`* schema:`,
`* type: object`,
`* example: { "field": "asc", "test": -1, "field2": "desc" }`,
`* - in: query`,
`* name: select`,
`* description: object containing fields want to be returned`,
`* style: deepObject`,
`* schema:`,
`* type: object`,
`* example: { "first_name": 1 }`,
];
swagger = swagger.concat(getSchemaQueryDefinitions(schema.schema));
swagger = swagger.concat([
// `* requestBody:`,
// `* description: ${uppercase(name)} - **GET** `,
// `* required: true`,
// `* content:`,
// `* application/json:`,
// `* schema:`,
// `* $ref: '#/components/schemas/Extended${uppercase(name)}'`,
`* responses:`,
`* "200":`,
`* description: "get ${name}s"`,
`* schema:`,
`* type: "${uppercase(name)}"`,
"*/",
]);
const schemaKeys = Object.keys(schema.schema);
const paginateValidation = getValidationCode(schema.schema, name);
const extraKeys = Object.keys(extraParams);
const func = [
`module.exports = async (req, res) => {`,
` try {`,
` let { ${extraKeys.join(', ')}} = req.query;`,
` const { ${schemaKeys.join(', ')}} = req.query;`,
//` console.log('req query ', req.query);`,
` // The model query`,
` const find = {};`,
` let parsedFilters = null;`,
` // pagination object (search, sort, filter, etc);
const where = {};
if (filters && filters !== '[]') {
parsedFilters = JSON.parse(filters);
parsedFilters.forEach((f) => {
let regexValue = {};
if (f.column.type === 'boolean') {
regexValue = f.value === 'checked' ? true : false;
} else if (Array.isArray(f.value) && f.value.length > 0) {
if (f.column.type === 'string') {
regexValue = { $in: [] };
f.value.forEach((val) => {
regexValue.$in.push(val)
});
} else {
regexValue = { $or: [] };
f.value.forEach((val) => {
regexValue.$or.push({ $eq: val });
});
}
} else if (f.column.type === 'numeric' || f.column.type === 'number') {
regexValue = { $eq: f.value };
} else {
regexValue = { $regex: new RegExp(f.value, "ig")};
}
if (JSON.stringify(regexValue) !== '{}') find[f.column.field] = regexValue;
});
`,
` }`,
`
// search
if (search) {
${getSearchCode(schema)};
}
`,
];
const end = [
` `,
` } catch (e) {`,
` console.error('GET => ${name}', e);`,
` return res.status(500).json({ error: e.message ? e.message : e });`,
` }`,
`};`,
];
const permissions = [
// ``,
// `// @TODO Permissions`,
// `const permission = userCan('${action}', '${name}', { user: req.user, body: req.body, params: req.params, query: req.query });`,
// `if (!permission) throw new Error('Permission denied for userCan ${action} ${name}');`,
// ``
];
const safeArea = [
`// @TODO handle safe area. Should be idempotent.`,
``,
`// maybe with @sugar-safe-start`,
`// @sugar-safe-end`,
``
];
const save = [
`// save`,
// `console.log('find ', find);`,
// `console.log('where', where);`,
`const ${name} = await ${uppercase(name)}.paginate(find, where); // @TODO populate: '<model name>'`,
`return res.json({ ${name}s: ${name} });`
];
code = code.concat(top, swagger, func, paginateValidation, permissions, safeArea, save, end);
const pretty = beautify(code.join('\n'), { indent_size: 2, space_in_empty_paren: true });
fs.writeFileSync(createFile, pretty);
};