<commit_before>/**
 * Copyright Ortus Solutions, Corp, All rights reserved
 * www.ortussolutions.com
 * ---
 * The DSL Service
 */
component accessors="true" singleton {

	// DI
	property name="wirebox"       inject="wirebox";
	property name="log"           inject="logbox:logger:{this}";
	property name="moduleService" inject="coldbox:moduleService";
	property name="templateCache" inject="cachebox:template";

	/**
	 * Storage for API Definitions
	 */
	property name="APIDefinitions" type="struct";

	/**
	 * Flag that tell us if the underlying application leverages session scope
	 */
	property name="sessionsEnabled" type="boolean";

	/**
	 * The relax module's settings
	 */
	property name="settings" type="struct";

	/**
	 * Constructor
	 * @settings The relax module settings needed
	 * @settings.inject coldbox:moduleSettings:relax
	 */
	function init( required settings ){
		variables.settings        = arguments.settings;
		variables.APIDefinitions  = {};
		variables.sessionsEnabled = arguments.settings.sessionsEnabled;

		return this;
	}

	/**
	 * Get a listing of all the APIs in the resources folder
	 */
	query function listAPIs(){
		var apiListing = directoryList(
			variables.settings.APILocationExpanded,
			false,
			"query",
			"",
			"asc"
		);

		if ( moduleService.isModuleRegistered( "cbswagger" ) ) {
			var definition = wirebox
				.getInstance( "RoutesParser@cbswagger" )
				.createDocFromRoutes()
				.getDocument();

			if ( !len( definition[ "info" ][ "title" ] ) ) {
				definition[ "info" ][ "title" ] = "cbSwagger";
			}

			var row = queryAddRow( apiListing );
			querySetCell( apiListing, "name", "cbswagger", row );
			querySetCell( apiListing, "type", "cbswagger", row );
			querySetCell(
				apiListing,
				"attributes",
				serializeJSON( definition[ "info" ] ),
				row
			);
		}

		return apiListing;
	}

	/**
	 * Get an API definition
	 * @name The name of the API to get.
	 */
	function getAPI( required name ){
		return variables.APIDefinitions[ arguments.name ];
	}

	/**
	 * Get the loaded API representation
	 */
	function getLoadedAPI(){
		var apiName = getLoadedAPIName();

		// lazy load API if not in scope
		if ( !structKeyExists( variables.APIDefinitions, apiName ) ) {
			loadAPI( apiName );
		}
		// return it.
		return variables.APIDefinitions[ apiName ];
	}

	/**
	 * Get the loaded API name
	 */
	string function getLoadedAPIName(){
		if ( !getSessionsEnabled() ) {
			return getDefaultAPIName();
		}

		return ( structKeyExists( session, "relax-api" ) ? session[ "relax-api" ] : "" );
	}

	/**
	 * Get the name of the default API
	 */
	string function getDefaultAPIName(){
		return getSettings().defaultAPI;
	}

	/**
	 * Checks if an API is loaded or not, usually by checking the user's data
	 */
	boolean function isLoadedAPI(){
		return ( len( getLoadedAPIName() ) ? true : false );
	}

	/**
	 * Clears user data
	 */
	APIService function clearUserData(){
		if ( !getSessionsEnabled() ) return this;

		structDelete( session, "relax-api" );
		return this;
	}

	/**
	 * Load an API into the service and get its representation. This can be a Relax.cfc or a Relax.json representation.
	 * @name The API to load
	 */
	function loadAPI( required name ){
		var APIDirectory = variables.settings.APILocationExpanded & "/" & arguments.name & "/";

		// determine if we have a legacy DSL configuration
		if ( fileExists( APIDirectory & "Relax.cfc" ) ) {
			var dataCFC = createObject( "component", variables.settings.APILocation & ".#arguments.name#.Relax" );
		} else if ( fileExists( variables.settings.APILocationExpanded & "/#arguments.name#/Relax.json" ) ) {
			var dataCFC = deserializeJSON( fileRead( APIDirectory & "Relax.json" ) );
		}

		// If we have a configure() then call it
		if ( !isNull( dataCFC ) && structKeyExists( dataCFC, "configure" ) ) {
			processConfiguration( dataCFC );
		}

		// Process Legacy Definitions
		if ( !isNull( dataCFC ) && isLegacyAPI( dataCFC ) ) {
			/**
			 * Legacy RelaxDSL API Checks
			 * @deprecated 	v3.0.0
			 * @eol			v4.0.0
			 **/
			loadDSLAPI( dataCFC );
			// Store the definitions
			variables.APIDefinitions[ arguments.name ] = getWirebox()
				.getInstance( "DSLTranslator@relax" )
				.translate( dataCFC );
		}
		// Open API Definitions
		else {
			if ( !isNull( dataCFC ) && structKeyExists( dataCFC.relax, "definition" ) ) {
				variables.APIDefinitions[ arguments.name ] = loadOpenAPI( APIDirectory & dataCFC.relax.definition );
			} else if ( isNull( dataCFC ) ) {
				var mimeExtensions = [
					"json",
					"json.cfm",
					"yaml",
					"yaml.cfm"
				];
				// perform our naming convention type checks checks
				for ( var ext in mimeExtensions ) {
					if ( fileExists( APIDirectory & arguments.name & "." & ext ) ) {
						variables.APIDefinitions[ arguments.name ] = loadOpenAPI(
							APIDirectory & arguments.name & "." & ext
						);
						break;
					}
				}
			}
		}

		// Store user's selection
		if ( getSessionsEnabled() ) {
			session[ "relax-api" ] = arguments.name;
		}

		return variables.APIDefinitions[ arguments.name ];
	}

	/**
	 * Process a relax configure method by injecting our Document.cfc methods first
	 * @dataCFC The data CFC to process
	 */
	APIService function processConfiguration( required dataCFC ){
		// create language object
		var dsl = getWirebox().getInstance( "RelaxDSL@relax" );

		// decorate and mixin methods.
		dataCFC.injectMixin = variables.injectMixin;

		for ( var key in dsl ) {
			// only inject methods/properties that do not exist
			if ( !structKeyExists( dataCFC, key ) ) {
				// check if a UDF
				if ( isCustomFunction( dsl[ key ] ) ) {
					dataCFC.injectMixin( key, dsl[ key ] );
				}
				// else a property injection
				else {<commit_msg>Fix for loading swagger via url (/relax/api/cbswagger)<commit_after>/**
 * Copyright Ortus Solutions, Corp, All rights reserved
 * www.ortussolutions.com
 * ---
 * The DSL Service
 */
component accessors="true" singleton {

	// DI
	property name="wirebox"       inject="wirebox";
	property name="log"           inject="logbox:logger:{this}";
	property name="moduleService" inject="coldbox:moduleService";
	property name="templateCache" inject="cachebox:template";

	/**
	 * Storage for API Definitions
	 */
	property name="APIDefinitions" type="struct";

	/**
	 * Flag that tell us if the underlying application leverages session scope
	 */
	property name="sessionsEnabled" type="boolean";

	/**
	 * The relax module's settings
	 */
	property name="settings" type="struct";

	/**
	 * Constructor
	 * @settings The relax module settings needed
	 * @settings.inject coldbox:moduleSettings:relax
	 */
	function init( required settings ){
		variables.settings        = arguments.settings;
		variables.APIDefinitions  = {};
		variables.sessionsEnabled = arguments.settings.sessionsEnabled;

		return this;
	}

	/**
	 * Get a listing of all the APIs in the resources folder
	 */
	query function listAPIs(){
		var apiListing = directoryList(
			variables.settings.APILocationExpanded,
			false,
			"query",
			"",
			"asc"
		);

		if ( moduleService.isModuleRegistered( "cbswagger" ) ) {
			var definition = wirebox
				.getInstance( "RoutesParser@cbswagger" )
				.createDocFromRoutes()
				.getDocument();

			if ( !len( definition[ "info" ][ "title" ] ) ) {
				definition[ "info" ][ "title" ] = "cbSwagger";
			}

			var row = queryAddRow( apiListing );
			querySetCell( apiListing, "name", "cbswagger", row );
			querySetCell( apiListing, "type", "cbswagger", row );
			querySetCell(
				apiListing,
				"attributes",
				serializeJSON( definition[ "info" ] ),
				row
			);
		}

		return apiListing;
	}

	/**
	 * Get an API definition
	 * @name The name of the API to get.
	 */
	function getAPI( required name ){
		return variables.APIDefinitions[ arguments.name ];
	}

	/**
	 * Get the loaded API representation
	 */
	function getLoadedAPI(){
		var apiName = getLoadedAPIName();

		// lazy load API if not in scope
		if ( !structKeyExists( variables.APIDefinitions, apiName ) ) {
			loadAPI( apiName );
		}
		// return it.
		return variables.APIDefinitions[ apiName ];
	}

	/**
	 * Get the loaded API name
	 */
	string function getLoadedAPIName(){
		if ( !getSessionsEnabled() ) {
			return getDefaultAPIName();
		}

		return ( structKeyExists( session, "relax-api" ) ? session[ "relax-api" ] : "" );
	}

	/**
	 * Get the name of the default API
	 */
	string function getDefaultAPIName(){
		return getSettings().defaultAPI;
	}

	/**
	 * Checks if an API is loaded or not, usually by checking the user's data
	 */
	boolean function isLoadedAPI(){
		return ( len( getLoadedAPIName() ) ? true : false );
	}

	/**
	 * Clears user data
	 */
	APIService function clearUserData(){
		if ( !getSessionsEnabled() ) return this;

		structDelete( session, "relax-api" );
		return this;
	}

	/**
	 * Load an API into the service and get its representation. This can be a Relax.cfc or a Relax.json representation.
	 * @name The API to load
	 */
	function loadAPI( required name ){
        if ( arguments.name == "cbswagger" ) {
            variables.APIDefinitions[ arguments.name ] = wirebox.getInstance( "RoutesParser@cbswagger" )
                .createDocFromRoutes()
                .getNormalizedDocument();
        } else {
            var APIDirectory = variables.settings.APILocationExpanded & "/" & arguments.name & "/";

            // determine if we have a legacy DSL configuration
            if ( fileExists( APIDirectory & "Relax.cfc" ) ) {
                var dataCFC = createObject( "component", variables.settings.APILocation & ".#arguments.name#.Relax" );
            } else if ( fileExists( variables.settings.APILocationExpanded & "/#arguments.name#/Relax.json" ) ) {
                var dataCFC = deserializeJSON( fileRead( APIDirectory & "Relax.json" ) );
            }

            // If we have a configure() then call it
            if ( !isNull( dataCFC ) && structKeyExists( dataCFC, "configure" ) ) {
                processConfiguration( dataCFC );
            }

            // Process Legacy Definitions
            if ( !isNull( dataCFC ) && isLegacyAPI( dataCFC ) ) {
                /**
                 * Legacy RelaxDSL API Checks
                 * @deprecated 	v3.0.0
                 * @eol			v4.0.0
                 **/
                loadDSLAPI( dataCFC );
                // Store the definitions
                variables.APIDefinitions[ arguments.name ] = getWirebox()
                    .getInstance( "DSLTranslator@relax" )
                    .translate( dataCFC );
            }
            // Open API Definitions
            else {
                if ( !isNull( dataCFC ) && structKeyExists( dataCFC.relax, "definition" ) ) {
                    variables.APIDefinitions[ arguments.name ] = loadOpenAPI( APIDirectory & dataCFC.relax.definition );
                } else if ( isNull( dataCFC ) ) {
                    var mimeExtensions = [
                        "json",
                        "json.cfm",
                        "yaml",
                        "yaml.cfm"
                    ];
                    // perform our naming convention type checks checks
                    for ( var ext in mimeExtensions ) {
                        if ( fileExists( APIDirectory & arguments.name & "." & ext ) ) {
                            variables.APIDefinitions[ arguments.name ] = loadOpenAPI(
                                APIDirectory & arguments.name & "." & ext
                            );
                            break;
                        }
                    }
                }
            }
        }

		// Store user's selection
		if ( getSessionsEnabled() ) {
			session[ "relax-api" ] = arguments.name;
		}

		return variables.APIDefinitions[ arguments.name ];
	}

	/**
	 * Process a relax configure method by injecting our Document.cfc methods first
	 * @dataCFC The data CFC to process
	 */
	APIService function processConfiguration( required dataCFC ){
		// create language object
		var dsl = getWirebox().getInstance( "RelaxDSL@relax" );

		// decorate and mixin methods.
		dataCFC.injectMixin = variables.injectMixin;

		for ( var key in dsl ) {
			// only inject methods/properties that do not exist
			if ( !structKeyExists( dataCFC, key ) ) {
				// check if a UDF
				if ( isCustomFunction( dsl[ key ] ) ) {
					dataCFC.injectMixin( key, dsl[ key ] );
				}
				// else a property injection
				else {
{'fraction_non_alphanumeric': 0.11988398324202384, 'fraction_numerical': 0.0009668063164679343, 'mean_word_length': 2.521418439716312, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3586120', 'n_tokens_mistral': 4191, 'n_tokens_neox': 3646, 'n_words': 988}