Skip to content

Valet/Herd Preference + Smarter Detection #327

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: 1.x
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 82 additions & 40 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ function resolveLaravelPlugin(pluginConfig: Required<PluginConfig>): LaravelPlug
const env = loadEnv(mode, userConfig.envDir || process.cwd(), '')
const assetUrl = env.ASSET_URL ?? ''
const serverConfig = command === 'serve'
? (resolveDevelopmentEnvironmentServerConfig(pluginConfig.detectTls) ?? resolveEnvironmentServerConfig(env))
? (resolveDevelopmentEnvironmentServerConfig(pluginConfig.detectTls, env.LARAVEL_PREFER_DEVELOPMENT_ENVIRONMENT) ?? resolveEnvironmentServerConfig(env))
: undefined

ensureCommandShouldRunInEnvironment(command, env)
Expand Down Expand Up @@ -521,10 +521,36 @@ function resolveHostFromEnv(env: Record<string, string>): string|undefined
}
}

function resolveCertsInEnvironment(host: string|boolean|null, configPath: string): {
key: string,
cert: string,
resolvedHost: string,
configPath: string
}|undefined
{
const resolvedHost = host === true || host === null
? path.basename(process.cwd()) + '.' + resolveDevelopmentEnvironmentTld(configPath)
: host as string

const keyPath = path.resolve(configPath, 'Certificates', `${resolvedHost}.key`)
const certPath = path.resolve(configPath, 'Certificates', `${resolvedHost}.crt`)
const config = {
key: keyPath,
cert: certPath,
resolvedHost: resolvedHost,
configPath: configPath
}

if (! fs.existsSync(keyPath) || ! fs.existsSync(certPath)) {
return
}
return config
}

/**
* Resolve the Herd or Valet server config for the given host.
*/
function resolveDevelopmentEnvironmentServerConfig(host: string|boolean|null): {
function resolveDevelopmentEnvironmentServerConfig(host: string|boolean|null, prefer?: "herd"|"valet"|string): {
hmr?: { host: string }
host?: string,
https?: { cert: string, key: string }
Expand All @@ -533,37 +559,45 @@ function resolveDevelopmentEnvironmentServerConfig(host: string|boolean|null): {
return
}

const configPath = determineDevelopmentEnvironmentConfigPath();

if (typeof configPath === 'undefined' && host === null) {
return
}

if (typeof configPath === 'undefined') {
throw Error(`Unable to find the Herd or Valet configuration directory. Please check they are correctly installed.`)
const configsAvailable = determineDevelopmentEnvironmentConfigPath()
const candidateConfigs: string[] = []
if (configsAvailable.herd.length > 0 && configsAvailable.valet.length > 0) {
if (prefer === 'herd') {
candidateConfigs.push(...configsAvailable.herd)
} else if (prefer === 'valet') {
candidateConfigs.push(...configsAvailable.valet)
} else {
candidateConfigs.push(...configsAvailable.herd, ...configsAvailable.valet)
}
} else {
candidateConfigs.push(...configsAvailable.herd, ...configsAvailable.valet)
}

const resolvedHost = host === true || host === null
? path.basename(process.cwd()) + '.' + resolveDevelopmentEnvironmentTld(configPath)
: host
const configs = candidateConfigs.map(path => resolveCertsInEnvironment(host, path))

const keyPath = path.resolve(configPath, 'Certificates', `${resolvedHost}.key`)
const certPath = path.resolve(configPath, 'Certificates', `${resolvedHost}.crt`)
const resolvedConfig = configs.find(config => config !== undefined)

if (! fs.existsSync(keyPath) || ! fs.existsSync(certPath)) {
if (host === null) {
return
}
if (typeof resolvedConfig === 'undefined' && host === null) {
return
}

if (configPath === herdMacConfigPath() || configPath === herdWindowsConfigPath()) {
throw Error(`Unable to find certificate files for your host [${resolvedHost}] in the [${configPath}/Certificates] directory. Ensure you have secured the site via the Herd UI.`)
} else if (typeof host === 'string') {
throw Error(`Unable to find certificate files for your host [${resolvedHost}] in the [${configPath}/Certificates] directory. Ensure you have secured the site by running \`valet secure ${host}\`.`)
} else {
throw Error(`Unable to find certificate files for your host [${resolvedHost}] in the [${configPath}/Certificates] directory. Ensure you have secured the site by running \`valet secure\`.`)
if (typeof resolvedConfig === 'undefined') {
if (prefer !== undefined && configsAvailable.herd.length > 0 && configsAvailable.valet.length > 0) {
if (prefer == 'valet') {
throw Error(`Unable to find certificate files for your project in Valet. Ensure you have secured the site with Valet by running by running \`valet secure ${host}\`.`)
} else if (prefer == 'herd') {
throw Error(`Unable to find certificate files for your project in Herd. Ensure you have secured the site with the Herd UI.`)
} else {
throw Error(`Unable to find certificate files for your project in Valet and Herd. Ensure you have secured the site.`)
}
}
throw Error(`Unable to find the Herd or Valet configuration directory. Please check they are correctly installed.`)
}

const resolvedHost = resolvedConfig.resolvedHost
const keyPath = resolvedConfig.key
const certPath = resolvedConfig.cert

return {
hmr: { host: resolvedHost },
host: resolvedHost,
Expand All @@ -574,24 +608,32 @@ function resolveDevelopmentEnvironmentServerConfig(host: string|boolean|null): {
}
}

function resolveHerdConfigs(): string[]
{
return [
herdMacConfigPath(),
herdWindowsConfigPath(),
].filter(fs.existsSync)
}

function resolveValetConfigs(): string[]
{
return [
valetMacConfigPath(),
valetLinuxConfigPath(),
].filter(fs.existsSync);
}

/**
* Resolve the path to the Herd or Valet configuration directory.
*/
function determineDevelopmentEnvironmentConfigPath(): string|undefined {
if (fs.existsSync(herdMacConfigPath())) {
return herdMacConfigPath()
}

if (fs.existsSync(herdWindowsConfigPath())) {
return herdWindowsConfigPath()
}

if (fs.existsSync(valetMacConfigPath())) {
return valetMacConfigPath()
}

if (fs.existsSync(valetLinuxConfigPath())) {
return valetLinuxConfigPath()
function determineDevelopmentEnvironmentConfigPath(): {
herd: string[],
valet: string[]
} {
return {
herd: resolveHerdConfigs(),
valet: resolveValetConfigs(),
}
}

Expand Down