mirror of
https://github.com/serverless/serverless.git
synced 2026-01-18 14:58:43 +00:00
191 lines
6.0 KiB
JavaScript
191 lines
6.0 KiB
JavaScript
'use strict';
|
|
|
|
module.exports = async () => {
|
|
const cliArgs = new Set(process.argv.slice(2));
|
|
|
|
// Unconditionally favor "serverless" for version check
|
|
if (cliArgs.has('--version')) return 'serverless';
|
|
if (cliArgs.has('-v')) return 'serverless';
|
|
|
|
// Unconditionally favor "@serverless/components" when component specific command or flag
|
|
const componentsCommands = new Set(['registry', 'init', 'publish']);
|
|
if (componentsCommands.has(process.argv[2])) return '@serverless/components';
|
|
if (cliArgs.has('--help-components')) return '@serverless/components';
|
|
if (cliArgs.has('--target')) return '@serverless/components';
|
|
|
|
// Detect eventual component configuration
|
|
const fsp = require('fs').promises;
|
|
if (
|
|
(
|
|
await Promise.all(
|
|
['yml', 'yaml', 'json'].map(async (extension) => {
|
|
try {
|
|
await fsp.access(`serverless.component.${extension}`);
|
|
return true;
|
|
} catch {
|
|
return false;
|
|
}
|
|
})
|
|
)
|
|
).some(Boolean)
|
|
) {
|
|
return '@serverless/components';
|
|
}
|
|
|
|
// Detect eventual service configuration
|
|
const configurationExtension =
|
|
(
|
|
await Promise.all(
|
|
['yml', 'yaml', 'json', 'js', 'ts'].map(async (extension) => {
|
|
try {
|
|
await fsp.access(`serverless.${extension}`);
|
|
return extension;
|
|
} catch {
|
|
return null;
|
|
}
|
|
})
|
|
)
|
|
).find(Boolean) || null;
|
|
|
|
if (configurationExtension) {
|
|
// Found top level service configuration, recognize CLI by content
|
|
|
|
const resolveByObjectConfiguration = (configuration) => {
|
|
if (configuration.provider) return 'serverless';
|
|
if (configuration.component) return '@serverless/components';
|
|
for (const value of Object.values(configuration)) {
|
|
if (value.component) return '@serverless/cli';
|
|
}
|
|
return 'serverless';
|
|
};
|
|
switch (configurationExtension) {
|
|
case 'yml':
|
|
case 'yaml': {
|
|
const content = await fsp.readFile(`serverless.${configurationExtension}`, 'utf8');
|
|
if (content.search(/(?:^|\n)provider\s*:/) !== -1) return 'serverless';
|
|
if (content.search(/(?:^|\n)component\s*:/) !== -1) return '@serverless/components';
|
|
if (content.search(/\n\s+component\s*:/) !== -1) return '@serverless/cli';
|
|
return 'serverless';
|
|
}
|
|
case 'json': {
|
|
const configuration = (() => {
|
|
try {
|
|
return require(`${process.cwd()}/serverless.json`);
|
|
} catch {
|
|
return null;
|
|
}
|
|
})();
|
|
if (!configuration) return 'serverless';
|
|
return resolveByObjectConfiguration(configuration);
|
|
}
|
|
case 'js': {
|
|
const configuration = (() => {
|
|
try {
|
|
return require(`${process.cwd()}/serverless.js`);
|
|
} catch {
|
|
return null;
|
|
}
|
|
})();
|
|
if (!configuration) return 'serverless';
|
|
if (typeof configuration === 'function') return '@serverless/cli';
|
|
return resolveByObjectConfiguration(configuration);
|
|
}
|
|
case 'ts':
|
|
return 'serverless';
|
|
default:
|
|
throw new Error(`Unrecognized extension "${configurationExtension}"`);
|
|
}
|
|
}
|
|
|
|
// No top level service configuration
|
|
const isChinaUser = (() => {
|
|
if (process.env.SLS_GEO_LOCATION) return process.env.SLS_GEO_LOCATION === 'cn';
|
|
return new Intl.DateTimeFormat('en', { timeZoneName: 'long' })
|
|
.format()
|
|
.includes('China Standard Time');
|
|
})();
|
|
|
|
// If "sls" or "sls deploy" command and in China, force "@serverless/components"
|
|
if (
|
|
(process.argv.length === 2 || process.argv[2] === 'deploy') &&
|
|
(isChinaUser || process.env.SERVERLESS_PLATFORM_VENDOR === 'tencent')
|
|
) {
|
|
return '@serverless/components';
|
|
}
|
|
|
|
// Detect eventual component template
|
|
const nestedTemplateKeywords = new Set([
|
|
'deploy',
|
|
'remove',
|
|
'info',
|
|
'help',
|
|
'--help',
|
|
'dev',
|
|
'logs',
|
|
'invoke',
|
|
'credentials',
|
|
]);
|
|
if (!nestedTemplateKeywords.has(process.argv[2])) return 'serverless';
|
|
|
|
const path = require('path');
|
|
const detectSubServiceType = async (subDirname) => {
|
|
const subConfigurationExtension =
|
|
(
|
|
await Promise.all(
|
|
['yml', 'yaml', 'json', 'js'].map(async (extension) => {
|
|
try {
|
|
await fsp.access(path.resolve(subDirname, `serverless.${extension}`));
|
|
return extension;
|
|
} catch {
|
|
return null;
|
|
}
|
|
})
|
|
)
|
|
).find(Boolean) || null;
|
|
if (!subConfigurationExtension) return null;
|
|
switch (subConfigurationExtension) {
|
|
case 'yml':
|
|
case 'yaml': {
|
|
const content = await fsp.readFile(
|
|
path.resolve(subDirname, `serverless.${subConfigurationExtension}`),
|
|
'utf8'
|
|
);
|
|
if (content.search(/(?:^|\n)component\s*:/) !== -1) return '@serverless/components';
|
|
return 'other';
|
|
}
|
|
case 'json': {
|
|
const configuration = (() => {
|
|
try {
|
|
return require(`${path.resolve(subDirname)}/serverless.json`);
|
|
} catch {
|
|
return null;
|
|
}
|
|
})();
|
|
return configuration && configuration.component ? '@serverless/components' : 'other';
|
|
}
|
|
case 'js': {
|
|
const configuration = (() => {
|
|
try {
|
|
return require(`${path.resolve(subDirname)}/serverless.js`);
|
|
} catch {
|
|
return null;
|
|
}
|
|
})();
|
|
return configuration && configuration.component ? '@serverless/components' : 'other';
|
|
}
|
|
default:
|
|
throw new Error(`Unrecognized extension "${subConfigurationExtension}"`);
|
|
}
|
|
};
|
|
let hasComponent = false;
|
|
for (const subDirname of await fsp.readdir('.')) {
|
|
const stats = await fsp.lstat(subDirname);
|
|
if (!stats.isDirectory()) continue;
|
|
const subServiceType = await detectSubServiceType(subDirname);
|
|
if (!subServiceType) continue;
|
|
if (subServiceType === '@serverless/components') hasComponent = true;
|
|
else return 'serverless';
|
|
}
|
|
return hasComponent ? '@serverless/components' : 'serverless';
|
|
};
|