mirror of
https://github.com/langgenius/dify.git
synced 2026-05-08 00:02:34 -04:00
130 lines
3.6 KiB
TypeScript
130 lines
3.6 KiB
TypeScript
import type { DotenvOptions } from 'c12'
|
|
import type { DevProxyCliOptions, DevProxyConfig, DevProxyConfigLoadOptions, DevProxyServerConfig, ResolvedDevProxyServerOptions } from './types'
|
|
import path from 'node:path'
|
|
import { loadConfig } from 'c12'
|
|
|
|
const DEFAULT_CONFIG_FILE = 'dev-proxy.config.ts'
|
|
const DEFAULT_PROXY_HOST = '127.0.0.1'
|
|
const DEFAULT_PROXY_PORT = 5001
|
|
|
|
const OPTION_NAME_TO_KEY = {
|
|
'--config': 'config',
|
|
'-c': 'config',
|
|
'--env-file': 'envFile',
|
|
'--host': 'host',
|
|
'--port': 'port',
|
|
} as const
|
|
|
|
type OptionName = keyof typeof OPTION_NAME_TO_KEY
|
|
|
|
const isOptionName = (value: string): value is OptionName => value in OPTION_NAME_TO_KEY
|
|
|
|
const requireOptionValue = (name: string, value?: string) => {
|
|
if (!value || value.startsWith('-'))
|
|
throw new Error(`Missing value for ${name}.`)
|
|
|
|
return value
|
|
}
|
|
|
|
export const parseDevProxyCliArgs = (argv: readonly string[]): DevProxyCliOptions => {
|
|
const options: DevProxyCliOptions = {}
|
|
|
|
for (let index = 0; index < argv.length; index += 1) {
|
|
const arg = argv[index]!
|
|
|
|
if (arg === '--')
|
|
continue
|
|
|
|
if (arg === '--help' || arg === '-h') {
|
|
options.help = true
|
|
continue
|
|
}
|
|
|
|
const [rawName, inlineValue] = arg.split('=', 2)
|
|
const name = rawName ?? ''
|
|
|
|
if (!name.startsWith('-'))
|
|
continue
|
|
|
|
if (!isOptionName(name))
|
|
throw new Error(`Unsupported dev proxy option "${name}".`)
|
|
|
|
const key = OPTION_NAME_TO_KEY[name]
|
|
options[key] = inlineValue ?? requireOptionValue(name, argv[index + 1])
|
|
|
|
if (inlineValue === undefined)
|
|
index += 1
|
|
}
|
|
|
|
return options
|
|
}
|
|
|
|
const resolvePort = (rawPort: string | number) => {
|
|
const port = Number(rawPort)
|
|
if (!Number.isInteger(port) || port < 1 || port > 65535)
|
|
throw new Error(`Invalid proxy port "${rawPort}". Expected an integer between 1 and 65535.`)
|
|
|
|
return port
|
|
}
|
|
|
|
export const resolveDevProxyServerOptions = (
|
|
serverConfig: DevProxyServerConfig = {},
|
|
cliOptions: DevProxyCliOptions = {},
|
|
): ResolvedDevProxyServerOptions => {
|
|
const configuredPort = cliOptions.port ?? serverConfig.port ?? DEFAULT_PROXY_PORT
|
|
|
|
return {
|
|
host: cliOptions.host || serverConfig.host || DEFAULT_PROXY_HOST,
|
|
port: resolvePort(configuredPort),
|
|
}
|
|
}
|
|
|
|
const isRecord = (value: unknown): value is Record<string, unknown> =>
|
|
typeof value === 'object' && value !== null
|
|
|
|
export function assertDevProxyConfig(config: unknown): asserts config is DevProxyConfig {
|
|
if (!isRecord(config))
|
|
throw new Error('Dev proxy config must export an object.')
|
|
|
|
if (!Array.isArray(config.routes))
|
|
throw new Error('Dev proxy config must include a routes array.')
|
|
}
|
|
|
|
const resolveDotenvOptions = (
|
|
envFile: DevProxyConfigLoadOptions['envFile'],
|
|
cwd: string,
|
|
): DotenvOptions | false => {
|
|
if (!envFile)
|
|
return false
|
|
|
|
const resolvedEnvFilePath = path.resolve(cwd, envFile)
|
|
return {
|
|
cwd: path.dirname(resolvedEnvFilePath),
|
|
fileName: path.basename(resolvedEnvFilePath),
|
|
interpolate: true,
|
|
}
|
|
}
|
|
|
|
export const loadDevProxyConfig = async (
|
|
configPath = DEFAULT_CONFIG_FILE,
|
|
cwd = process.cwd(),
|
|
options: DevProxyConfigLoadOptions = {},
|
|
): Promise<DevProxyConfig> => {
|
|
const resolvedConfigPath = path.resolve(cwd, configPath)
|
|
const parsedPath = path.parse(resolvedConfigPath)
|
|
const { config: loadedConfig } = await loadConfig({
|
|
configFile: parsedPath.name,
|
|
cwd: parsedPath.dir,
|
|
dotenv: resolveDotenvOptions(options.envFile, cwd),
|
|
envName: false,
|
|
globalRc: false,
|
|
packageJson: false,
|
|
rcFile: false,
|
|
})
|
|
|
|
assertDevProxyConfig(loadedConfig)
|
|
return loadedConfig
|
|
}
|
|
|
|
export const defineDevProxyConfig = (config: DevProxyConfig) => config
|