UNPKG

openapi-codegen

Version:
188 lines (166 loc) 8.2 kB
// @ts-check 'use strict'; const fs = require('fs'); const path = require('path'); const util = require('util'); const mkdirp = require('mkdirp'); const rimraf = require('rimraf'); const Hogan = require('hogan.js'); const clone = require('reftools/lib/clone.js').circularClone; // must preserve functions const adaptor = require('./adaptor.js'); const lambdas = require('./lambdas.js'); // allows other backends, such as a stream writer for .tar.gz files let ff = { readFileSync: fs.readFileSync, createFile: fs.writeFileSync, rimraf: rimraf, mkdirp: mkdirp }; function tpl(config, ...segments) { if (config.templateDir) { segments.splice(0,1); return path.join(config.templateDir, ...segments); } return path.join(__dirname, 'templates', ...segments) } function main(o, config, configName, callback) { let outputDir = config.outputDir || './out/'; let verbose = config.defaults.verbose; config.defaults.configName = configName; adaptor.transform(o, config.defaults, function(err, model) { if (config.generator) { model.generator = config.generator; } if (verbose) console.log('Processing lambdas '+Object.keys(lambdas)); Object.keys(lambdas).forEach(key => model[key] = lambdas[key]); if (config.generator && config.generator.lambdas) { for (let lambda in config.generator.lambdas) { if (verbose) console.log('Processing lambda '+lambda); model[lambda] = config.generator.lambdas[lambda]; } } for (let p in config.partials) { let partial = config.partials[p]; if (verbose) console.log('Processing partial '+partial); config.partials[p] = ff.readFileSync(tpl(config, configName, partial),'utf8'); } let actions = []; for (let t in config.transformations) { let tx = config.transformations[t]; if (tx.input) { if (verbose) console.log('Processing template ' + tx.input); tx.template = ff.readFileSync(tpl(config, configName, tx.input),'utf8'); } actions.push(tx); } const subDir = (config.defaults.flat ? '' : configName); if (verbose) console.log('Making/cleaning output directories'); ff.mkdirp.sync(path.join(outputDir,subDir)); ff.rimraf(path.join(outputDir,subDir)+'/*',function(){ if (config.directories) { for (let directory of config.directories) { ff.mkdirp.sync(path.join(outputDir,subDir,directory)); } } for (let action of actions) { if (verbose) console.log('Rendering '+action.output); let content; if (config.generator && config.generator.render) { content = config.generator.render(action.template, model, config.partials); } else { let template = Hogan.compile(action.template); content = template.render(model,config.partials); } ff.createFile(path.join(outputDir,subDir,action.output),content,'utf8'); } if (config.touch) { // may not now be necessary let touchTmp = Hogan.compile(config.touch); let touchList = touchTmp.render(model,config.partials); let files = touchList.split('\r').join('').split('\n'); for (let file of files) { file = file.trim(); if (file) { if (!fs.existsSync(path.join(outputDir,subDir,file))) { ff.createFile(path.join(outputDir,subDir,file),'','utf8'); } } } } // generate license by default if (typeof config.license === 'undefined') { config.license = true; } if (config.license) { const licenseType = config.apache ? 'LICENSE' : 'UNLICENSE'; ff.createFile(path.join(outputDir, subDir, 'LICENSE'), ff.readFileSync(tpl({}, '_common', licenseType), 'utf8'), 'utf8'); } let outer = model; if (config.perApi) { let toplevel = clone(model); delete toplevel.apiInfo; for (let pa of config.perApi) { let fnTemplate = Hogan.compile(pa.output); let template = Hogan.compile(ff.readFileSync(tpl(config, configName, pa.input), 'utf8')); for (let api of model.apiInfo.apis) { let cApi = Object.assign({},config.defaults,pa.defaults||{},toplevel,api); let filename = fnTemplate.render(cApi,config.partials); if (verbose) console.log('Rendering '+filename+' (dynamic:'+pa.input+')'); ff.createFile(path.join(outputDir,subDir,filename),template.render(cApi,config.partials),'utf8'); } } } if (config.perPath) { let toplevel = clone(model); delete toplevel.apiInfo; for (let pa of config.perPath) { let fnTemplate = Hogan.compile(pa.output); let template = Hogan.compile(ff.readFileSync(tpl(config, configName, pa.input), 'utf8')); for (let pat of model.apiInfo.paths) { let cPath = Object.assign({},config.defaults,pa.defaults||{},toplevel,pat); let filename = fnTemplate.render(cPath,config.partials); let dirname = path.dirname(filename); if (verbose) console.log('Rendering '+filename+' (dynamic:'+pa.input+')'); ff.mkdirp.sync(path.join(outputDir,subDir,dirname)); ff.createFile(path.join(outputDir,subDir,filename),template.render(cPath,config.partials),'utf8'); } } } if (config.perModel) { let cModels = clone(model.models); for (let pm of config.perModel) { let fnTemplate = Hogan.compile(pm.output); let template = Hogan.compile(ff.readFileSync(tpl(config, configName, pm.input), 'utf8')); for (let model of cModels) { outer.models = []; let effModel = Object.assign({},model,pm.defaults||{}); outer.models.push(effModel); let filename = fnTemplate.render(outer,config.partials); if (verbose) console.log('Rendering '+filename+' (dynamic:'+pm.input+')'); ff.createFile(path.join(outputDir,subDir,filename),template.render(outer,config.partials),'utf8'); } } } if (config.perOperation) { // now may not be necessary for (let po of config.perOperation) { for (let api of outer.apiInfo.apis) { let cOperations = clone(api.operations); let fnTemplate = Hogan.compile(po.output); let template = Hogan.compile(ff.readFileSync(tpl(config, configName, po.input), 'utf8')); for (let operation of cOperations.operation) { model.operations = []; model.operations.push(operation); let filename = fnTemplate.render(outer,config.partials); if (verbose) console.log('Rendering '+filename+' (dynamic:'+po.input+')'); ff.createFile(path.join(outputDir,subDir,filename),template.render(outer,config.partials),'utf8'); } } } } if (callback) callback(null,true); }); }); } module.exports = { fileFunctions: ff, main };