From 93f7964d944abe63ab67c6a90a638411a9ba9f97 Mon Sep 17 00:00:00 2001 From: Joseph Bester Date: Tue, 14 Mar 2023 12:33:58 -0400 Subject: [PATCH] Add more output patterns (tags, component schemas) Adds the posibility to generate files for individual openapi tags or schema components. --- lib/generator.js | 146 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) diff --git a/lib/generator.js b/lib/generator.js index e98e442..d151478 100644 --- a/lib/generator.js +++ b/lib/generator.js @@ -149,6 +149,129 @@ const generateOperationFiles = config => new Promise((resolve, reject) => { }); }); + +/** + * Generates a file for every tag. + * + * @param config + * @param tag + * @param tag_name + * @returns {Promise} + */ +const generateTagFile = (config, tag, tag_name) => new Promise((resolve, reject) => { + fs.readFile(path.join(config.root, config.file_name), 'utf8', (err, data) => { + if (err) return reject(err); + const subdir = config.root.replace(new RegExp(`${config.templates_dir}[/]?`),''); + const new_filename = config.file_name.replace('$$tag$$', tag_name).replace(/.hbs$/, '').replace(/ /g, '_'); + const target_file = path.resolve(config.target_dir, subdir, new_filename); + const template = Handlebars.compile(data.toString()); + const content = template({ + openbrace: '{', + closebrace: '}' , + tag_name: tag_name.replace(/[}{]/g, ''), + tag: tag, + openapi: config.data.openapi + }); + + fs.writeFile(target_file, content, 'utf8', (err) => { + if (err) return reject(err); + resolve(); + }); + }); +}); + + +/** + * Generates all the files for each tag by iterating over the tags. + * + * @param {Object} config Configuration options + * @returns {Promise} + */ +const generateTagFiles = config => new Promise((resolve, reject) => { + const files = {}; + if (config.data.openapi.tags) { + _.each(config.data.openapi.tags, (tag, tagIndex) => { + const tag_name = tag.name + if (files[tag_name] === undefined) { + files[tag_name] = []; + } + + files[tag_name] = { + tag: tag + }; + + Promise.all( + _.map(files, (tag, tag_name) => generateTagFile(config, tag, tag_name)) + ).then(resolve).catch(reject); + resolve(); + }); + } else { + resolve(); + } +}); + + +/** + * Generates a file for component schema + * + * @param config + * @param schema + * @param schema_name + * @returns {Promise} + */ +const generateSchemaFile = (config, schema, schema_name) => new Promise((resolve, reject) => { + fs.readFile(path.join(config.root, config.file_name), 'utf8', (err, data) => { + if (err) return reject(err); + const subdir = config.root.replace(new RegExp(`${config.templates_dir}[/]?`),''); + const new_filename = config.file_name.replace('$$schema$$', schema_name).replace(/.hbs$/, '').replace(/ /g, '_'); + const target_file = path.resolve(config.target_dir, subdir, new_filename); + const template = Handlebars.compile(data.toString()); + const content = template({ + openbrace: '{', + closebrace: '}' , + schema_name: schema_name.replace(/[}{]/g, ''), + schema: schema, + openapi: config.data.openapi + }); + + fs.writeFile(target_file, content, 'utf8', (err) => { + if (err) return reject(err); + resolve(); + }); + }); +}); + + +/** + * Generates all the files for each schema by iterating over the component schemas. + * + * @param {Object} config Configuration options + * @returns {Promise} + */ +const generateSchemaFiles = config => new Promise((resolve, reject) => { + const files = {}; + if (config.data.openapi.components.schemas) { + _.each(config.data.openapi.components.schemas, (schema, schemaIndex) => { + console.log(`Generating for ${schema.title}`); + const schema_name = schema.title + if (files[schema_name] === undefined) { + files[schema_name] = []; + } + + files[schema_name] = { + schema: schema + }; + }); + + Promise.all( + _.map(files, (schema, schema_name) => generateSchemaFile(config, schema, schema_name)) + ).then(resolve).catch(reject); + resolve(); + } else { + resolve(); + } +}); + /** * Generates the directory structure. * @@ -182,6 +305,29 @@ const generateDirectoryStructure = config => new Promise((resolve, reject) => { }); const template_path = path.relative(templates_dir, path.resolve(root, stats.name)); fs.unlink(path.resolve(target_dir, template_path), next); + } else if (stats.name.includes('$$tag$$')) { + // this file should be handled for each in openapi.tags + await generateTagFiles({ + root, + templates_dir, + target_dir, + data: config, + file_name: stats.name + }); + const template_path = path.relative(templates_dir, path.resolve(root, stats.name)); + fs.unlink(path.resolve(target_dir, template_path), next); + } else if (stats.name.includes('$$schema$$')) { + // this file should be handled for each in openapi.components.schemas + console.log("Creating schemas doc"); + await generateSchemaFiles({ + root, + templates_dir, + target_dir, + data: config, + file_name: stats.name + }); + const template_path = path.relative(templates_dir, path.resolve(root, stats.name)); + fs.unlink(path.resolve(target_dir, template_path), next); } else { const file_path = path.relative(templates_dir, path.resolve(root, stats.name)); if (!file_path.startsWith(`${PARTIALS_DIRNAME}${path.sep}`) && !file_path.startsWith(`${HELPERS_DIRNAME}${path.sep}`)) {