serverless/lib/cli/resolve-configuration-path.js
2024-05-29 11:51:04 -04:00

79 lines
2.5 KiB
JavaScript

import ensurePlainObject from 'type/plain-object/ensure.js'
import ensureString from 'type/string/ensure.js'
import path from 'path'
import fsp from 'fs/promises'
import ServerlessError from '../serverless-error.js'
import fileExists from '../utils/fs/file-exists.js'
import resolveInput from './resolve-input.js'
const supportedExtensions = new Set([
'yml',
'yaml',
'json',
'js',
'mjs',
'cjs',
'ts',
])
export default async (options = {}) => {
if (!options) options = {}
const cliOptions =
ensurePlainObject(options.options, { isOptional: true }) ||
resolveInput().options
const cwd = path.resolve(
ensureString(options.cwd, { isOptional: true }) || process.cwd(),
)
const customConfigName = cliOptions.config
if (customConfigName) {
const customConfigPath = path.resolve(cwd, customConfigName)
if (!supportedExtensions.has(path.extname(customConfigPath).slice(1))) {
throw new ServerlessError(
'Invalid "--config" value: Unsupported file extension ' +
`(expected one of: ${Array.from(supportedExtensions).join(', ')}`,
'INVALID_SERVICE_CONFIG_PATH',
)
}
const stats = await (async () => {
try {
return await fsp.stat(customConfigPath)
} catch (error) {
if (error.code === 'ENOENT') {
throw new ServerlessError(
`'Invalid "--config" value: Cannot find "${customConfigName}" in service folder`,
'INVALID_SERVICE_CONFIG_PATH',
)
}
throw new ServerlessError(
`Invalid "--config" value: "${customConfigName}" is not accessible: ${error.stack}`,
'INVALID_SERVICE_CONFIG_PATH',
)
}
})()
if (!stats.isFile()) {
throw new ServerlessError(
`Invalid "--config" value: "${customConfigName}" is not a file`,
'INVALID_SERVICE_CONFIG_PATH',
)
}
if (cwd !== path.dirname(customConfigPath)) {
throw new ServerlessError(
'Service configuration is expected to be placed in a root of a service (working directory). All paths, function handlers in a configuration are resolved against service directory.\n',
'NESTED_CUSTOM_CONFIGURATION_PATH',
)
}
return customConfigPath
}
for (const extension of supportedExtensions) {
const eventualServiceConfigPath = path.resolve(
cwd,
`serverless.${extension}`,
)
if (await fileExists(eventualServiceConfigPath))
return eventualServiceConfigPath
}
return null
}