mirror of
https://github.com/serverless/serverless.git
synced 2025-12-08 19:46:03 +00:00
172 lines
4.6 KiB
JavaScript
172 lines
4.6 KiB
JavaScript
import path from 'path'
|
|
import fse from 'fs-extra'
|
|
import fsp from 'fs/promises'
|
|
import weakMemoizee from 'memoizee/weak.js'
|
|
import _ from 'lodash'
|
|
import resolveTmpdir from 'process-utils/tmpdir/index.js'
|
|
import ServerlessError from '../serverless-error.js'
|
|
import safeMoveFile from './fs/safe-move-file.js'
|
|
import utils from '@serverlessinc/sf-core/src/utils.js'
|
|
import healthStatusFilename from './health-status-filename.js'
|
|
|
|
const { log, style } = utils
|
|
const disabledDeprecationCodesByEnv = extractCodes(
|
|
process.env.SLS_DEPRECATION_DISABLE,
|
|
)
|
|
|
|
const notificationModeByEnv = process.env.SLS_DEPRECATION_NOTIFICATION_MODE
|
|
|
|
export const triggeredDeprecations = new Set()
|
|
const bufferedDeprecations = []
|
|
|
|
const deprecationLogger = log.get('deprecation')
|
|
|
|
function extractCodes(codesStr) {
|
|
if (!codesStr) {
|
|
return new Set()
|
|
}
|
|
return new Set(codesStr.split(','))
|
|
}
|
|
|
|
const resolveDisabledDeprecationsByService = weakMemoizee((serviceConfig) => {
|
|
let disabledDeprecations = []
|
|
if (typeof serviceConfig.disabledDeprecations === 'string') {
|
|
disabledDeprecations = [serviceConfig.disabledDeprecations]
|
|
} else {
|
|
disabledDeprecations = Array.from(serviceConfig.disabledDeprecations || [])
|
|
}
|
|
return new Set(disabledDeprecations)
|
|
})
|
|
|
|
const resolveMode = (serviceConfig) => {
|
|
switch (notificationModeByEnv) {
|
|
case 'error':
|
|
case 'warn':
|
|
return notificationModeByEnv
|
|
default:
|
|
}
|
|
const modeByConfig = _.get(serviceConfig, 'deprecationNotificationMode')
|
|
switch (modeByConfig) {
|
|
case 'error':
|
|
case 'warn':
|
|
return modeByConfig
|
|
default:
|
|
return defaultMode
|
|
}
|
|
}
|
|
|
|
function writeDeprecation(code, message) {
|
|
const messageLines = message.split('\n')
|
|
if (!code.startsWith('EXT_')) {
|
|
messageLines.push(
|
|
`More Info: https://www.serverless.com/framework/docs/deprecations/#${code}`,
|
|
)
|
|
}
|
|
log.warning(messageLines.join('\n'))
|
|
}
|
|
|
|
export default (code, message, { serviceConfig } = {}) => {
|
|
try {
|
|
if (
|
|
triggeredDeprecations.has(code) ||
|
|
disabledDeprecationCodesByEnv.has(code) ||
|
|
disabledDeprecationCodesByEnv.has('*')
|
|
) {
|
|
return
|
|
}
|
|
|
|
if (serviceConfig) {
|
|
const serviceDisabledCodes =
|
|
resolveDisabledDeprecationsByService(serviceConfig)
|
|
if (serviceDisabledCodes.has(code) || serviceDisabledCodes.has('*')) {
|
|
return
|
|
}
|
|
}
|
|
|
|
switch (resolveMode(serviceConfig)) {
|
|
case 'error':
|
|
throw new ServerlessError(
|
|
`${message}\n More Info: https://www.serverless.com/framework/docs/deprecations/#${code}`,
|
|
`REJECTED_DEPRECATION_${code}`,
|
|
)
|
|
case 'warn':
|
|
writeDeprecation(code, message)
|
|
return
|
|
default:
|
|
bufferedDeprecations.push({ message, code })
|
|
}
|
|
} finally {
|
|
triggeredDeprecations.add(code)
|
|
}
|
|
}
|
|
|
|
export const defaultMode = 'warn:summary'
|
|
|
|
export const printSummary = async () => {
|
|
if (!bufferedDeprecations.length) {
|
|
try {
|
|
await fsp.unlink(healthStatusFilename)
|
|
} catch {
|
|
// ignore
|
|
}
|
|
return
|
|
}
|
|
|
|
try {
|
|
const healthStatus = []
|
|
|
|
deprecationLogger.warning()
|
|
|
|
if (bufferedDeprecations.length === 1) {
|
|
healthStatus.push('1 deprecation triggered in the last command:', '')
|
|
deprecationLogger.warning(
|
|
style.aside(
|
|
"1 deprecation found: run 'serverless doctor' for more details",
|
|
),
|
|
)
|
|
} else {
|
|
healthStatus.push(
|
|
`${bufferedDeprecations.length} deprecations triggered in the last command:`,
|
|
'',
|
|
)
|
|
deprecationLogger.warning(
|
|
style.aside(
|
|
`${bufferedDeprecations.length} deprecations found: run 'serverless doctor' for more details`,
|
|
),
|
|
)
|
|
}
|
|
for (const { code, message } of bufferedDeprecations) {
|
|
healthStatus.push(message)
|
|
if (!code.startsWith('EXT_')) {
|
|
healthStatus.push(
|
|
style.aside(
|
|
`More info: https://serverless.com/framework/docs/deprecations/#${code}`,
|
|
),
|
|
)
|
|
}
|
|
}
|
|
|
|
const tmpHealthStatusFilename = path.resolve(
|
|
await resolveTmpdir(),
|
|
'health-status',
|
|
)
|
|
await Promise.all([
|
|
fse.ensureDir(path.dirname(healthStatusFilename)),
|
|
fsp.writeFile(tmpHealthStatusFilename, healthStatus.join('\n')),
|
|
])
|
|
try {
|
|
await safeMoveFile(tmpHealthStatusFilename, healthStatusFilename)
|
|
} catch (error) {
|
|
if (error.code === 'EACCES') {
|
|
log.error(
|
|
'Cannot store information on approached deprecation. Please ensure process has write access to the ~/.serverless directory',
|
|
)
|
|
} else {
|
|
throw error
|
|
}
|
|
}
|
|
} finally {
|
|
bufferedDeprecations.length = 0
|
|
}
|
|
}
|