vtex
Version:
The platform for e-commerce apps
116 lines (115 loc) • 6.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.isBillingApp = exports.hasErrorMessage = exports.isNotFoundError = exports.isForbiddenError = void 0;
const tslib_1 = require("tslib");
const utils_1 = require("../../api/modules/utils");
const chalk_1 = tslib_1.__importDefault(require("chalk"));
const Billing_1 = require("../../api/clients/IOClients/apps/Billing");
const Apps_1 = require("../../api/clients/IOClients/infra/Apps");
const logger_1 = tslib_1.__importDefault(require("../../api/logger"));
const manifest_1 = require("../../api/manifest");
const prompts_1 = require("../../api/modules/prompts");
const BillingMessages_1 = require("../../lib/constants/BillingMessages");
const featureFlagDecider_1 = require("../featureFlag/featureFlagDecider");
const SessionManager_1 = require("../../api/session/SessionManager");
const InstallStatus_1 = require("../../lib/constants/InstallStatus");
const installApp = (appName, termsOfUseAccepted, force) => Billing_1.Billing.createClient().installApp(appName, termsOfUseAccepted, force);
const legacyInstallApp = (descriptor) => Apps_1.createAppsClient().installApp(descriptor);
const isError = (errorCode) => (e) => { var _a; return ((_a = e === null || e === void 0 ? void 0 : e.response) === null || _a === void 0 ? void 0 : _a.status) === errorCode; };
exports.isForbiddenError = isError(403);
exports.isNotFoundError = isError(404);
exports.hasErrorMessage = (e) => { var _a, _b; return ((_b = (_a = e === null || e === void 0 ? void 0 : e.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.message) !== undefined; };
const logGraphQLErrorMessage = e => {
logger_1.default.error('Installation failed!');
logger_1.default.error(e.message);
};
const appStoreProductPage = (app) => {
const [appName] = app.split('@');
const [vendor, name] = appName.split('.');
return `https://apps.vtex.com/${vendor}-${name}/p`;
};
async function handleAppStoreContractNotFoundError(app) {
const appWebsite = appStoreProductPage(app);
logger_1.default.info(BillingMessages_1.BillingMessages.getAppForInstall(appWebsite));
const shouldOpenProductPage = await prompts_1.promptConfirm(BillingMessages_1.BillingMessages.shouldOpenPage(), true);
if (shouldOpenProductPage) {
featureFlagDecider_1.switchOpen(appWebsite, { wait: false });
}
}
exports.isBillingApp = (app) => {
const billingRegex = /^vtex\.billing(@.*)?$/;
return billingRegex.test(app);
};
function handleAccountNotSponsoredByVendorError(app) {
const { account } = SessionManager_1.SessionManager.getSingleton();
const vendor = utils_1.getVendorFromApp(app);
logger_1.default.error(BillingMessages_1.BillingMessages.accountNotSponsoredByVendorError(app, account, vendor));
}
const prepareInstall = async (appsList, force) => {
let exitWithError = false;
for (const app of appsList) {
manifest_1.ManifestValidator.validateApp(app);
try {
logger_1.default.debug('Starting to install app', app);
if (exports.isBillingApp(app)) {
// eslint-disable-next-line no-await-in-loop
await legacyInstallApp(app);
}
else {
// eslint-disable-next-line no-await-in-loop
const { code } = await installApp(app, true, force);
switch (code) {
case InstallStatus_1.InstallStatus.OWN_REGISTRY:
logger_1.default.debug('Installed from own registry');
break;
case InstallStatus_1.InstallStatus.PUBLIC_REGISTRY:
logger_1.default.debug('Installed from public registry');
break;
case InstallStatus_1.InstallStatus.PREVIOUS_PURCHASE:
logger_1.default.debug('Installed from previous purchase');
break;
case InstallStatus_1.InstallStatus.FREE:
logger_1.default.debug('Free app');
}
}
logger_1.default.info(`Installed app ${chalk_1.default.green(app)} successfully`);
}
catch (e) {
exitWithError = true;
if (exports.isNotFoundError(e)) {
logger_1.default.warn(`Billing app not found in current workspace. Please install it with ${chalk_1.default.green('vtex install vtex.billing')}`);
}
else if (exports.isForbiddenError(e)) {
logger_1.default.error(`You do not have permission to install apps. Please check your VTEX IO 'Install App' resource access in Account Management`);
}
else if (exports.hasErrorMessage(e)) {
logger_1.default.error(e.response.data.message);
}
else {
switch (e.message) {
case InstallStatus_1.InstallStatus.CONTRACT_NOT_FOUND:
// eslint-disable-next-line no-await-in-loop
await handleAppStoreContractNotFoundError(app);
break;
case InstallStatus_1.InstallStatus.ACCOUNT_NOT_SPONSORED:
handleAccountNotSponsoredByVendorError(app);
break;
default:
logGraphQLErrorMessage(e);
}
}
logger_1.default.warn(`The following app was not installed: ${app}`);
}
}
if (exitWithError)
process.exit(1);
};
exports.default = async (optionalApps, options) => {
const force = options.f || options.force;
const confirm = await utils_1.validateAppAction('install', optionalApps);
if (!confirm)
return;
const appsList = optionalApps.length > 0 ? optionalApps : [(await manifest_1.ManifestEditor.getManifestEditor()).appLocator];
logger_1.default.debug(`Installing app${appsList.length > 1 ? 's' : ''}: ${appsList.join(', ')}`);
return prepareInstall(appsList, force);
};