import * as express from 'express' ; import { join as pathJoin } from 'path' ; import { readFile as fsReadFile } from 'fs/promises' ; import { IDataObject } from 'n8n-workflow' ; import * as config from '../config' ; import { Db , ICredentialsDb , IPackageVersions } from '.' ; import { Like } from 'typeorm' ; import { WorkflowEntity } from './databases/entities/WorkflowEntity' ; let versionCache ; export returns { string } export function getBaseUrl ( ) { const protocol = config . get ( 'protocol' ) ; const host = config . get ( 'host' ) ; const port = config . get ( 'port' ) ; const path = config . get ( 'path' ) ; if ( ( protocol === 'http' && port === 80 ) || ( protocol === 'https' && port === 443 ) ) { return `${ protocol }://${ host }${ path }` ; } return `${ protocol }://${ host }:${ port }${ path }` ; } export param { express . Request } req returns { ( string | undefined ) } export function getSessionId ( req ) { return req . headers . sessionid as string | undefined ; } export returns { Promise < IPackageVersions > } export async function getVersions ( ) { if ( versionCache !== undefined ) { return versionCache ; } const packageFile = await fsReadFile ( pathJoin ( __dirname , '../../package.json' ) , 'utf8' ) ; const packageData = JSON . parse ( packageFile ) ; versionCache = { cli : packageData . version , } ; return versionCache ; } param { string } configKey param { IDataObject } configSchema returns { IDataObject } function extractSchemaForKey ( configKey , configSchema ) { const configKeyParts = configKey . split ( '.' ) ; for ( const key of configKeyParts ) { if ( configSchema [ key ] === undefined ) { throw new Error ( `Key "${ key }" of ConfigKey "${ configKey }" does not exist` ) ; } else if ( ( configSchema [ key ] ! as IDataObject ) . _cvtProperties === undefined ) { configSchema = configSchema [ key ] as IDataObject ; } else { configSchema = ( configSchema [ key ] as IDataObject ) . _cvtProperties as IDataObject ; } } return configSchema ; } export param { string } configKey returns { ( Promise < string | boolean | number | undefined > ) } export async function getConfigValue ( configKey ) { const configSchema = config . getSchema ( ) ; const currentSchema = extractSchemaForKey ( configKey , configSchema . _cvtProperties as IDataObject ) ; if ( currentSchema . env === undefined ) { return config . get ( configKey ) ; } const fileEnvironmentVariable = process . env [ `${ currentSchema . env }_FILE` ] ; if ( fileEnvironmentVariable === undefined ) { return config . get ( configKey ) ; } let data ; try { data = await fsReadFile ( fileEnvironmentVariable , 'utf8' ) ; } catch ( error ) { if ( error . code === 'ENOENT' ) { throw new Error ( `The file "${ fileEnvironmentVariable }" could not be found.` ) ; } throw error ; } return data ; } /**
 * Generate a unique name for a workflow or credentials entity.
 *
 * - If the name does not yet exist, it returns the requested name.
 * - If the name already exists once, it returns the requested name suffixed with 2.
 * - If the name already exists more than once with suffixes, it looks for the max suffix
 * and returns the requested name with max suffix + 1.
 */ export async function generateUniqueName ( requestedName , entityType ) { const findConditions = { select : [ 'name' as const ] , where : { name : Like ( `${ requestedName }%` ) , } , } ; const found = entityType === 'workflow' ? await Db . collections . Workflow ! . find ( findConditions ) : await Db . collections . Credentials ! . find ( findConditions ) ; if ( found . length === 0 ) { return { name : requestedName } ; } const maxSuffix = found . reduce ( ( acc , { name } ) => { const parts = name . split ( `${ requestedName } ` ) ; if ( parts . length > 2 ) return acc ; const suffix = Number ( parts [ 1 ] ) ; if ( ! isNaN ( suffix ) && Math . ceil ( suffix ) > acc ) { acc = Math . ceil ( suffix ) ; } return acc ; } , 0 ) ; if ( maxSuffix === 0 ) { return { name : `${ requestedName } 2` } ; } return { name : `${ requestedName } ${ maxSuffix + 1 }` } ; }