@o3r/schematics
Version:
Schematics module of the Otter framework
160 lines • 7.05 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.isOtterTag = void 0;
exports.getAvailableModules = getAvailableModules;
exports.getAvailableModulesWithLatestPackage = getAvailableModulesWithLatestPackage;
exports.formatModuleDescription = formatModuleDescription;
const tslib_1 = require("tslib");
const node_child_process_1 = require("node:child_process");
const fs = tslib_1.__importStar(require("node:fs"));
const node_https_1 = require("node:https");
const node_os_1 = require("node:os");
const path = tslib_1.__importStar(require("node:path"));
const node_util_1 = require("node:util");
const chalk = tslib_1.__importStar(require("chalk"));
const semver_1 = require("semver");
const index_1 = require("../utility/index");
const package_version_1 = require("../utility/package-version");
const modules_constants_1 = require("./modules-constants");
const DEFAULT_NPM_REGISTRY = 'registry.npmjs.org';
async function promiseGetRequest(url) {
const res = await new Promise((resolve, reject) => (0, node_https_1.get)(url, resolve)
.on('error', (err) => reject(err)));
return new Promise((resolve, reject) => {
const data = [];
res.on('data', (chunk) => data.push(chunk));
res.on('end', () => resolve(JSON.parse(Buffer.concat(data).toString())));
res.on('error', reject);
});
}
/**
* Execute NPM search command if not run with other client
* @param search search text
* @param packageManagerOptions
* @param logger
*/
async function npmSearchExec(search, packageManagerOptions, logger) {
const manager = (0, index_1.getPackageManager)(packageManagerOptions);
switch (manager) {
case 'npm': {
const remoteModulesPromise = (0, node_util_1.promisify)(node_child_process_1.execFile)('npm', ['search', search, '--json']);
try {
const results = JSON.parse((await remoteModulesPromise).stdout);
return results
.reduce((acc, pck) => {
acc.objects.push({ package: pck });
return acc;
}, { objects: [] });
}
catch {
return undefined;
}
}
case 'yarn': {
logger?.warn('The Yarn Package Manager is not supported, the Rest API will be used (the registry configuration will be ignored)');
return undefined;
}
default: {
logger?.warn('Not supported Package Manager, the Rest API will be used');
return undefined;
}
}
}
/**
* Determine if the given keyword is an Otter tag
* @param keyword Keyword to identify
* @param expect tag expected for the Otter keyword
*/
const isOtterTag = (keyword, expect) => {
const isTag = typeof keyword === 'string' && keyword.startsWith(modules_constants_1.OTTER_MODULE_PREFIX);
return (isTag && expect && keyword === `${modules_constants_1.OTTER_MODULE_PREFIX}${expect}`) || isTag;
};
exports.isOtterTag = isOtterTag;
/**
* Get Available Otter modules on NPMjs.org
* @param keyword Keyword to search for Otter modules
* @param scopeWhitelist List of whitelisted scopes
* @param options
*/
async function getAvailableModules(keyword, scopeWhitelist, options) {
const search = `keywords:${keyword}`;
const npmRegistry = options?.npmRegistryToFetch || DEFAULT_NPM_REGISTRY;
const registry = await npmSearchExec(search) || await promiseGetRequest(`https://${npmRegistry}/-/v1/search?text=${search}&size=250`);
let packages = registry.objects
.filter((pck) => pck.package?.scope && scopeWhitelist.includes(pck.package?.scope))
.map((pck) => pck.package);
if (options?.onlyNotInstalled) {
packages = packages
.filter((pck) => {
try {
require.resolve(path.posix.join(pck.name, 'package.json'));
return false;
}
catch {
return true;
}
});
}
return packages;
}
/**
* Get Available Otter modules on NPMjs.org and get latest package information
* Similar to {@link getAvailableModules} with additional calls to retrieve all the package's information
* @param keyword Keyword to search for Otter modules
* @param options
*/
async function getAvailableModulesWithLatestPackage(keyword = modules_constants_1.OTTER_MODULE_KEYWORD, options) {
const scopeWhitelist = options.scopeWhitelist || modules_constants_1.OTTER_MODULE_SUPPORTED_SCOPES;
const packages = await getAvailableModules(keyword, scopeWhitelist, options);
const npmRegistry = options?.npmRegistryToFetch || DEFAULT_NPM_REGISTRY;
return Promise.all(packages
.map(async (pck) => {
try {
const pckInfo = await promiseGetRequest(`https://${npmRegistry}/${pck.name}/latest`);
return {
...pck,
package: pckInfo
};
}
catch {
options.logger?.debug(`Failed to retrieve information for ${pck.name}`);
return pck;
}
}));
}
/**
* Format a module description to be displayed in the terminal
* @param npmPackage Npm Package to display
* @param runner runner according to the context
* @param keywordTags Mapping of the NPM package Keywords and a displayed tag
* @param logger Logger to use to report package read failure (as debug message)
*/
function formatModuleDescription(npmPackage, runner = 'npx', keywordTags = {}, logger) {
let otterVersion;
const otterCorePackageName = '@o3r/core';
const otterCoreRange = npmPackage.package?.peerDependencies?.[otterCorePackageName];
if (npmPackage.package) {
try {
const otterCorePackage = (0, package_version_1.findClosestPackageJson)(require.resolve(otterCorePackageName));
if (otterCorePackage) {
const { version } = JSON.parse(fs.readFileSync(otterCorePackage, { encoding: 'utf8' }));
otterVersion = version;
}
}
catch {
logger?.debug('Fail to find local Otter installation');
}
}
const flags = npmPackage.keywords
?.filter((key) => (0, exports.isOtterTag)(key) && key !== modules_constants_1.OTTER_MODULE_KEYWORD)
.map((key) => keywordTags[key] || key.replace(modules_constants_1.OTTER_MODULE_PREFIX, '')) || [];
const outdatedWarning = otterVersion && otterCoreRange && !(0, semver_1.satisfies)(otterVersion, otterCoreRange) ? ' ' + chalk.yellow(`(outdated, supporting ${otterCoreRange})`) : '';
const lines = [
chalk.bold(`${runner} ng add ${chalk.cyan(npmPackage.name)}`) + outdatedWarning,
chalk.italic(npmPackage.description || '<no description>'),
...(npmPackage.links?.npm ? [chalk.italic.grey(`(details on ${npmPackage.links.npm})`)] : []),
...(flags.length > 0 ? [`Tags: ${flags.map((flag) => chalk.cyan(flag)).join(', ')}`] : [])
];
return lines.join(node_os_1.EOL);
}
//# sourceMappingURL=modules-helpers.js.map