<commit_before>var up = require('url');
var path = require('path');

var yaml = require('js-yaml');
var xml = require('jgexml/json2xml.js');
var jptr = require('jgexml/jpath.js');
var recurseotron = require('openapi_optimise/common.js');
var circular = require('openapi_optimise/circular.js');
var sampler = require('openapi-sampler');
var dot = require('dot');
dot.templateSettings.strip = false;
dot.templateSettings.varname = 'data';
var templates;

var circles = [];

// could change these to be regexes...
var xmlContentTypes = ['application/xml','text/xml','image/svg+xml','application/rss+xml','application/rdf+xml','application/atom+xml','application/mathml+xml','application/hal+xml'];
var jsonContentTypes = ['application/json','text/json','application/hal+json','application/ld+json','application/json-patch+json'];
var yamlContentTypes = ['application/x-yaml','text/x-yaml'];

/* originally from https://github.com/for-GET/know-your-http-well/blob/master/json/status-codes.json */
/* "Unlicensed", public domain */
var statusCodes = require('./statusCodes.json');

function clone(obj){
    return JSON.parse(JSON.stringify(obj));
}

/**
* function to reformat swagger paths object into an iodocs-style resources object, tags-first
*/
function convertSwagger(source){
    var apiInfo = clone(source,false);
    apiInfo.resources = {};
    for (var p in apiInfo.paths) {
        for (var m in apiInfo.paths[p]) {
            if (m != 'parameters') {
                var sMethod = apiInfo.paths[p][m];
                var ioMethod = {};
                ioMethod.path = p;
                ioMethod.op = m;
                var sMethodUniqueName = (sMethod.operationId ? sMethod.operationId : m+'_'+p).split('/').join('_');
                sMethodUniqueName = sMethodUniqueName.split(' ').join('_'); // TODO {, } and : ?
                var tagName = 'Default';
                if (sMethod.tags && sMethod.tags.length>0) {
                    tagName = sMethod.tags[0];
                }
                if (!apiInfo.resources[tagName]) {
                    apiInfo.resources[tagName] = {};
                    if (apiInfo.tags) {
                        for (var t in apiInfo.tags) {
                            var tag = apiInfo.tags[t];
                            if (tag.name == tagName) {
                                apiInfo.resources[tagName].description = tag.description;
                                apiInfo.resources[tagName].externalDocs = tag.externalDocs;
                            }
                        }
                    }
                }
                if (!apiInfo.resources[tagName].methods) apiInfo.resources[tagName].methods = {};
                apiInfo.resources[tagName].methods[sMethodUniqueName] = ioMethod;
            }
        }
    }
    delete apiInfo.paths; // to keep size down
    delete apiInfo.definitions; // ditto
    return apiInfo;
}

function dereference(obj,swagger){
    if (obj["$ref"]) {
		obj = jptr.jptr(swagger,obj["$ref"]);
	}
    var changes = 1;
    while (changes>0) {
        changes = 0;
        recurseotron.recurse(obj,{},function(obj,state) {
            if ((state.key === '$ref') && (typeof obj === 'string') && (!circular.isCircular(circles, obj))) {
				state.parents[state.parents.length-2][state.keys[state.keys.length-2]] = jptr.jptr(swagger,obj);
                delete state.parent["$ref"];
                changes++;
            }
        });
    }
    return obj;
}

function doContentType(types,targets){
    for (var type in types) {
		for (var target of targets) {
			if (types[type] === target) return true;
		}
    }
    return false;
}

function languageCheck(language,language_tabs,mutate){
    var lcLang = language.toLowerCase();
    if (lcLang === 'c#') lcLang = 'csharp';
    if (lcLang === 'c++') lcLang = 'cpp';
    for (var l in language_tabs){
        var target = language_tabs[l];
        if (typeof target === 'object') {
            if (Object.keys(target)[0] === lcLang) {
                return lcLang;
            }
        }
        else {
            if (target === lcLang) return lcLang;
        }
    }
    if (mutate) {
        var newLang = {};
        newLang[lcLang] = language;
        language_tabs.push(newLang);
        return lcLang;
    }
    return false;
}

function parameterToSchema(param,swagger) {
	var schema = {};
	schema.type = 'object';
	schema.properties = {};
	var definition = {};
	if ((param.type == 'integer') || (param.type == 'string') || (param.type == 'array')
		|| (param.type == 'boolean') || (param.type == 'number')) {
		definition.type = param.type;
	}
	if (param.format == 'password') {
		definition.format = param.format;
	}
	if ((typeof param.default !== 'undefined') && (param.default != 'undefined')) {
		// bugfix for Trello spec in test cases, and for boolean:false
		definition.default = param.default;
	}
	if (typeof param.maximum !== 'undefined') definition.maximum = param.maximum;
	if (typeof param.minimum !== 'undefined') definition.minimum = param.minimum;
	if (typeof param.maxLength !== 'undefined') definition.maxLength = param.maxLength;
	if (typeof param.minLength !== 'undefined') definition.minLength = param.minLength;
	if (typeof param.maxItems !== 'undefined') definition.maxItems = param.maxItems;
	if (typeof param.minItems !== 'undefined') definition.minItems = param.minItems;
	if (param.pattern) definition.pattern = param.pattern;
	if (param.enum) definition.enum = param.enum;
	if (typeof param.multipleOf !== 'undefined') definition.multipleOf = param.multipleOf;
	if (typeof param.exclusiveMaximum !== 'undefined') definition.exclusiveMaximum = param.exclusiveMaximum;
	if (typeof param.exclusiveMinimum !== 'undefined') definition.exclusiveMinimum = param.exclusiveMinimum;
	if (typeof param.uniqueItems !== 'undefined') definition.uniqueItems = param.uniqueItems;

	if (param.schema) {
		definition = dereference(param.schema,swagger);
	}
	if (param.type == 'array') {
		definition.items = {};
		if (param.items && param.items.type) {
			definition.items.type = param.items.type;
			// do we need to repeat or recurse the min,max etc here?
		}
		if (param.items && param.items.schema) {
			definition.items.schema = dereference(param.items.schema,swagger);
		}
	}
	schema.properties[param.name] = definition;
	return schema;
}

function convert(swagger,options) {

    var defaults = {};
    defaults.header = true;
    defaults.language_tabs = [{'shell': 'Shell'},{'http': 'HTTP'},{'javascript': 'JavaScript'},{'javascript--nodejs': 'Node.JS'},{'python': 'Python'},{'ruby': 'Ruby'},{'java': 'Java'}];
    defaults.codeSamples = true;
	defaults.theme = 'darkula';
	defaults.search = true;
	defaults.sample = true;
	defaults.discovery = false;
	defaults.includes = [];
	defaults.templateCallback = function(templateName,stage,data) { return data; };

	if (!options.codeSamples) defaults.language_tabs = [];

    options = Object.assign({},defaults,options);

    if (typeof templates === 'undefined') {<commit_msg>fix: check codeSamples flag AFTER merging user options<commit_after>var up = require('url');
var path = require('path');

var yaml = require('js-yaml');
var xml = require('jgexml/json2xml.js');
var jptr = require('jgexml/jpath.js');
var recurseotron = require('openapi_optimise/common.js');
var circular = require('openapi_optimise/circular.js');
var sampler = require('openapi-sampler');
var dot = require('dot');
dot.templateSettings.strip = false;
dot.templateSettings.varname = 'data';
var templates;

var circles = [];

// could change these to be regexes...
var xmlContentTypes = ['application/xml','text/xml','image/svg+xml','application/rss+xml','application/rdf+xml','application/atom+xml','application/mathml+xml','application/hal+xml'];
var jsonContentTypes = ['application/json','text/json','application/hal+json','application/ld+json','application/json-patch+json'];
var yamlContentTypes = ['application/x-yaml','text/x-yaml'];

/* originally from https://github.com/for-GET/know-your-http-well/blob/master/json/status-codes.json */
/* "Unlicensed", public domain */
var statusCodes = require('./statusCodes.json');

function clone(obj){
    return JSON.parse(JSON.stringify(obj));
}

/**
* function to reformat swagger paths object into an iodocs-style resources object, tags-first
*/
function convertSwagger(source){
    var apiInfo = clone(source,false);
    apiInfo.resources = {};
    for (var p in apiInfo.paths) {
        for (var m in apiInfo.paths[p]) {
            if (m != 'parameters') {
                var sMethod = apiInfo.paths[p][m];
                var ioMethod = {};
                ioMethod.path = p;
                ioMethod.op = m;
                var sMethodUniqueName = (sMethod.operationId ? sMethod.operationId : m+'_'+p).split('/').join('_');
                sMethodUniqueName = sMethodUniqueName.split(' ').join('_'); // TODO {, } and : ?
                var tagName = 'Default';
                if (sMethod.tags && sMethod.tags.length>0) {
                    tagName = sMethod.tags[0];
                }
                if (!apiInfo.resources[tagName]) {
                    apiInfo.resources[tagName] = {};
                    if (apiInfo.tags) {
                        for (var t in apiInfo.tags) {
                            var tag = apiInfo.tags[t];
                            if (tag.name == tagName) {
                                apiInfo.resources[tagName].description = tag.description;
                                apiInfo.resources[tagName].externalDocs = tag.externalDocs;
                            }
                        }
                    }
                }
                if (!apiInfo.resources[tagName].methods) apiInfo.resources[tagName].methods = {};
                apiInfo.resources[tagName].methods[sMethodUniqueName] = ioMethod;
            }
        }
    }
    delete apiInfo.paths; // to keep size down
    delete apiInfo.definitions; // ditto
    return apiInfo;
}

function dereference(obj,swagger){
    if (obj["$ref"]) {
		obj = jptr.jptr(swagger,obj["$ref"]);
	}
    var changes = 1;
    while (changes>0) {
        changes = 0;
        recurseotron.recurse(obj,{},function(obj,state) {
            if ((state.key === '$ref') && (typeof obj === 'string') && (!circular.isCircular(circles, obj))) {
				state.parents[state.parents.length-2][state.keys[state.keys.length-2]] = jptr.jptr(swagger,obj);
                delete state.parent["$ref"];
                changes++;
            }
        });
    }
    return obj;
}

function doContentType(types,targets){
    for (var type in types) {
		for (var target of targets) {
			if (types[type] === target) return true;
		}
    }
    return false;
}

function languageCheck(language,language_tabs,mutate){
    var lcLang = language.toLowerCase();
    if (lcLang === 'c#') lcLang = 'csharp';
    if (lcLang === 'c++') lcLang = 'cpp';
    for (var l in language_tabs){
        var target = language_tabs[l];
        if (typeof target === 'object') {
            if (Object.keys(target)[0] === lcLang) {
                return lcLang;
            }
        }
        else {
            if (target === lcLang) return lcLang;
        }
    }
    if (mutate) {
        var newLang = {};
        newLang[lcLang] = language;
        language_tabs.push(newLang);
        return lcLang;
    }
    return false;
}

function parameterToSchema(param,swagger) {
	var schema = {};
	schema.type = 'object';
	schema.properties = {};
	var definition = {};
	if ((param.type == 'integer') || (param.type == 'string') || (param.type == 'array')
		|| (param.type == 'boolean') || (param.type == 'number')) {
		definition.type = param.type;
	}
	if (param.format == 'password') {
		definition.format = param.format;
	}
	if ((typeof param.default !== 'undefined') && (param.default != 'undefined')) {
		// bugfix for Trello spec in test cases, and for boolean:false
		definition.default = param.default;
	}
	if (typeof param.maximum !== 'undefined') definition.maximum = param.maximum;
	if (typeof param.minimum !== 'undefined') definition.minimum = param.minimum;
	if (typeof param.maxLength !== 'undefined') definition.maxLength = param.maxLength;
	if (typeof param.minLength !== 'undefined') definition.minLength = param.minLength;
	if (typeof param.maxItems !== 'undefined') definition.maxItems = param.maxItems;
	if (typeof param.minItems !== 'undefined') definition.minItems = param.minItems;
	if (param.pattern) definition.pattern = param.pattern;
	if (param.enum) definition.enum = param.enum;
	if (typeof param.multipleOf !== 'undefined') definition.multipleOf = param.multipleOf;
	if (typeof param.exclusiveMaximum !== 'undefined') definition.exclusiveMaximum = param.exclusiveMaximum;
	if (typeof param.exclusiveMinimum !== 'undefined') definition.exclusiveMinimum = param.exclusiveMinimum;
	if (typeof param.uniqueItems !== 'undefined') definition.uniqueItems = param.uniqueItems;

	if (param.schema) {
		definition = dereference(param.schema,swagger);
	}
	if (param.type == 'array') {
		definition.items = {};
		if (param.items && param.items.type) {
			definition.items.type = param.items.type;
			// do we need to repeat or recurse the min,max etc here?
		}
		if (param.items && param.items.schema) {
			definition.items.schema = dereference(param.items.schema,swagger);
		}
	}
	schema.properties[param.name] = definition;
	return schema;
}

function convert(swagger,options) {

    var defaults = {};
    defaults.header = true;
    defaults.language_tabs = [{'shell': 'Shell'},{'http': 'HTTP'},{'javascript': 'JavaScript'},{'javascript--nodejs': 'Node.JS'},{'python': 'Python'},{'ruby': 'Ruby'},{'java': 'Java'}];
    defaults.codeSamples = true;
	defaults.theme = 'darkula';
	defaults.search = true;
	defaults.sample = true;
	defaults.discovery = false;
	defaults.includes = [];
	defaults.templateCallback = function(templateName,stage,data) { return data; };

    options = Object.assign({},defaults,options);

    if (!options.codeSamples) defaults.language_tabs = [];

    if (typeof templates === 'undefined') {
{'fraction_non_alphanumeric': 0.15565836298932384, 'fraction_numerical': 0.001281138790035587, 'mean_word_length': 2.869732855962545, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 26}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7597688', 'n_tokens_mistral': 4275, 'n_tokens_neox': 4127, 'n_words': 885}