@sentry/wizard
Version:
Sentry wizard helping you to configure your project
619 lines • 33.3 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.hasPackageInstalled = exports.getPackageDotJson = exports.ensurePackageIsInstalled = exports.addDotEnvSentryBuildPluginFile = exports.addSentryCliRc = exports.askForSelfHosted = exports.installPackage = exports.askForProjectSelection = exports.askForWizardLogin = exports.confirmContinueEvenThoughNoGitRepo = exports.printWelcome = exports.abortIfCancelled = exports.abort = void 0;
// @ts-ignore - clack is ESM and TS complains about that. It works though
var clack = __importStar(require("@clack/prompts"));
var axios_1 = __importDefault(require("axios"));
var chalk_1 = __importDefault(require("chalk"));
var childProcess = __importStar(require("child_process"));
var fs = __importStar(require("fs"));
var path = __importStar(require("path"));
var timers_1 = require("timers");
var url_1 = require("url");
var util_1 = require("util");
var Sentry = __importStar(require("@sentry/node"));
var clack_custom_select_1 = require("./vendor/clack-custom-select");
var SAAS_URL = 'https://sentry.io/';
function abort(message, status) {
return __awaiter(this, void 0, void 0, function () {
var sentryHub, sentryTransaction, sentrySession;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
clack.outro(message !== null && message !== void 0 ? message : 'Wizard setup cancelled.');
sentryHub = Sentry.getCurrentHub();
sentryTransaction = sentryHub.getScope().getTransaction();
sentryTransaction === null || sentryTransaction === void 0 ? void 0 : sentryTransaction.setStatus('aborted');
sentryTransaction === null || sentryTransaction === void 0 ? void 0 : sentryTransaction.finish();
sentrySession = sentryHub.getScope().getSession();
if (sentrySession) {
sentrySession.status = status === 0 ? 'abnormal' : 'crashed';
sentryHub.captureSession(true);
}
return [4 /*yield*/, Sentry.flush(3000)];
case 1:
_a.sent();
return [2 /*return*/, process.exit(status !== null && status !== void 0 ? status : 1)];
}
});
});
}
exports.abort = abort;
function abortIfCancelled(input) {
return __awaiter(this, void 0, void 0, function () {
var _a, _b, sentryHub, sentryTransaction;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
_b = (_a = clack).isCancel;
return [4 /*yield*/, input];
case 1:
if (!_b.apply(_a, [_c.sent()])) return [3 /*break*/, 3];
clack.cancel('Wizard setup cancelled.');
sentryHub = Sentry.getCurrentHub();
sentryTransaction = sentryHub.getScope().getTransaction();
sentryTransaction === null || sentryTransaction === void 0 ? void 0 : sentryTransaction.setStatus('cancelled');
sentryTransaction === null || sentryTransaction === void 0 ? void 0 : sentryTransaction.finish();
sentryHub.captureSession(true);
return [4 /*yield*/, Sentry.flush(3000)];
case 2:
_c.sent();
process.exit(0);
return [3 /*break*/, 4];
case 3: return [2 /*return*/, input];
case 4: return [2 /*return*/];
}
});
});
}
exports.abortIfCancelled = abortIfCancelled;
function printWelcome(options) {
var wizardPackage = {};
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
wizardPackage = require(path.join(path.dirname(require.resolve('@sentry/wizard')), '..', 'package.json'));
}
catch (_a) {
// We don't need to have this
}
// eslint-disable-next-line no-console
console.log('');
clack.intro(chalk_1.default.inverse(" ".concat(options.wizardName, " ")));
var welcomeText = options.message ||
'This Wizard will help you to set up Sentry for your application.\nThank you for using Sentry :)';
if (options.promoCode) {
welcomeText += "\n\nUsing promo-code: ".concat(options.promoCode);
}
if (wizardPackage.version) {
welcomeText += "\n\nVersion: ".concat(wizardPackage.version);
}
clack.note(welcomeText);
}
exports.printWelcome = printWelcome;
function confirmContinueEvenThoughNoGitRepo() {
return __awaiter(this, void 0, void 0, function () {
var _a, continueWithoutGit;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_b.trys.push([0, 1, , 5]);
childProcess.execSync('git rev-parse --is-inside-work-tree', {
stdio: 'ignore',
});
return [3 /*break*/, 5];
case 1:
_a = _b.sent();
return [4 /*yield*/, abortIfCancelled(clack.confirm({
message: 'You are not inside a git repository. The wizard will create and update files. Do you still want to continue?',
}))];
case 2:
continueWithoutGit = _b.sent();
Sentry.setTag('continue-without-git', continueWithoutGit);
if (!!continueWithoutGit) return [3 /*break*/, 4];
return [4 /*yield*/, abort(undefined, 0)];
case 3:
_b.sent();
_b.label = 4;
case 4: return [3 /*break*/, 5];
case 5: return [2 /*return*/];
}
});
});
}
exports.confirmContinueEvenThoughNoGitRepo = confirmContinueEvenThoughNoGitRepo;
function askForWizardLogin(options) {
return __awaiter(this, void 0, void 0, function () {
var hasSentryAccount, wizardHash, _a, loginUrl, loginSpinner, data;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
Sentry.setTag('has-promo-code', !!options.promoCode);
return [4 /*yield*/, clack.confirm({
message: 'Do you already have a Sentry account?',
})];
case 1:
hasSentryAccount = _b.sent();
return [4 /*yield*/, abortIfCancelled(hasSentryAccount)];
case 2:
hasSentryAccount = _b.sent();
Sentry.setTag('already-has-sentry-account', hasSentryAccount);
_b.label = 3;
case 3:
_b.trys.push([3, 5, , 10]);
return [4 /*yield*/, axios_1.default.get("".concat(options.url, "api/0/wizard/"))];
case 4:
wizardHash = (_b.sent()).data.hash;
return [3 /*break*/, 10];
case 5:
_a = _b.sent();
if (!(options.url !== SAAS_URL)) return [3 /*break*/, 7];
clack.log.error('Loading Wizard failed. Did you provide the right URL?');
return [4 /*yield*/, abort(chalk_1.default.red('Please check your configuration and try again.\n\n Let us know if you think this is an issue with the wizard or Sentry: https://github.com/getsentry/sentry-wizard/issues'))];
case 6:
_b.sent();
return [3 /*break*/, 9];
case 7:
clack.log.error('Loading Wizard failed.');
return [4 /*yield*/, abort(chalk_1.default.red('Please try again in a few minutes and let us know if this issue persists: https://github.com/getsentry/sentry-wizard/issues'))];
case 8:
_b.sent();
_b.label = 9;
case 9: return [3 /*break*/, 10];
case 10:
loginUrl = new url_1.URL("".concat(options.url, "account/settings/wizard/").concat(wizardHash, "/"));
if (!hasSentryAccount) {
loginUrl.searchParams.set('signup', '1');
if (options.platform) {
loginUrl.searchParams.set('project_platform', options.platform);
}
}
if (options.promoCode) {
loginUrl.searchParams.set('code', options.promoCode);
}
clack.log.info("".concat(chalk_1.default.bold("Please open the following link in your browser to ".concat(hasSentryAccount ? 'log' : 'sign', " into Sentry:")), "\n\n").concat(chalk_1.default.cyan(loginUrl.toString())));
loginSpinner = clack.spinner();
loginSpinner.start('Waiting for you to click the link above 👆. Take your time.');
return [4 /*yield*/, new Promise(function (resolve) {
var pollingInterval = (0, timers_1.setInterval)(function () {
axios_1.default
.get("".concat(options.url, "api/0/wizard/").concat(wizardHash, "/"))
.then(function (result) {
resolve(result.data);
clearTimeout(timeout);
clearInterval(pollingInterval);
void axios_1.default.delete("".concat(options.url, "api/0/wizard/").concat(wizardHash, "/"));
})
.catch(function () {
// noop - just try again
});
}, 500);
var timeout = setTimeout(function () {
clearInterval(pollingInterval);
loginSpinner.stop('Login timed out. No worries - it happens to the best of us.');
Sentry.setTag('opened-wizard-link', false);
void abort('Please restart the Wizard and log in to complete the setup.');
}, 180000);
})];
case 11:
data = _b.sent();
loginSpinner.stop('Login complete.');
Sentry.setTag('opened-wizard-link', true);
return [2 /*return*/, data];
}
});
});
}
exports.askForWizardLogin = askForWizardLogin;
function askForProjectSelection(projects) {
return __awaiter(this, void 0, void 0, function () {
var selection;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, abortIfCancelled((0, clack_custom_select_1.windowedSelect)({
maxItems: 12,
message: 'Select your Sentry project.',
options: projects.map(function (project) {
return {
value: project,
label: "".concat(project.organization.slug, "/").concat(project.slug),
};
}),
}))];
case 1:
selection = _a.sent();
Sentry.setTag('project', selection.slug);
Sentry.setUser({ id: selection.organization.slug });
return [2 /*return*/, selection];
}
});
});
}
exports.askForProjectSelection = askForProjectSelection;
function installPackage(_a) {
var packageName = _a.packageName, alreadyInstalled = _a.alreadyInstalled;
return __awaiter(this, void 0, void 0, function () {
var shouldUpdatePackage, sdkInstallSpinner, packageManager, e_1;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
if (!alreadyInstalled) return [3 /*break*/, 2];
return [4 /*yield*/, abortIfCancelled(clack.confirm({
message: "The ".concat(chalk_1.default.bold.cyan(packageName), " package is already installed. Do you want to update it to the latest version?"),
}))];
case 1:
shouldUpdatePackage = _b.sent();
if (!shouldUpdatePackage) {
return [2 /*return*/];
}
_b.label = 2;
case 2:
sdkInstallSpinner = clack.spinner();
return [4 /*yield*/, getPackageManager()];
case 3:
packageManager = _b.sent();
sdkInstallSpinner.start("".concat(alreadyInstalled ? 'Updating' : 'Installing', " ").concat(chalk_1.default.bold.cyan(packageName), " with ").concat(chalk_1.default.bold(packageManager), "."));
_b.label = 4;
case 4:
_b.trys.push([4, 11, , 13]);
if (!(packageManager === 'yarn')) return [3 /*break*/, 6];
return [4 /*yield*/, (0, util_1.promisify)(childProcess.exec)("yarn add ".concat(packageName, "@latest"))];
case 5:
_b.sent();
return [3 /*break*/, 10];
case 6:
if (!(packageManager === 'pnpm')) return [3 /*break*/, 8];
return [4 /*yield*/, (0, util_1.promisify)(childProcess.exec)("pnpm add ".concat(packageName, "@latest"))];
case 7:
_b.sent();
return [3 /*break*/, 10];
case 8:
if (!(packageManager === 'npm')) return [3 /*break*/, 10];
return [4 /*yield*/, (0, util_1.promisify)(childProcess.exec)("npm install ".concat(packageName, "@latest"))];
case 9:
_b.sent();
_b.label = 10;
case 10: return [3 /*break*/, 13];
case 11:
e_1 = _b.sent();
sdkInstallSpinner.stop('Installation failed.');
clack.log.error("".concat(chalk_1.default.red('Encountered the following error during installation:'), "\n\n").concat(e_1, "\n\n").concat(chalk_1.default.dim('If you think this issue is caused by the Sentry wizard, let us know here:\nhttps://github.com/getsentry/sentry-wizard/issues')));
return [4 /*yield*/, abort()];
case 12:
_b.sent();
return [3 /*break*/, 13];
case 13:
sdkInstallSpinner.stop("".concat(alreadyInstalled ? 'Updated' : 'Installed', " ").concat(chalk_1.default.bold.cyan(packageName), " with ").concat(chalk_1.default.bold(packageManager), "."));
return [2 /*return*/];
}
});
});
}
exports.installPackage = installPackage;
function askForSelfHosted() {
return __awaiter(this, void 0, void 0, function () {
var choice, validUrl, url;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, abortIfCancelled(clack.select({
message: 'Are you using Sentry SaaS or self-hosted Sentry?',
options: [
{ value: 'saas', label: 'Sentry SaaS (sentry.io)' },
{ value: 'self-hosted', label: 'Self-hosted/on-premise/single-tenant' },
],
}))];
case 1:
choice = _a.sent();
if (choice === 'saas') {
Sentry.setTag('url', SAAS_URL);
Sentry.setTag('self-hosted', false);
return [2 /*return*/, { url: SAAS_URL, selfHosted: false }];
}
_a.label = 2;
case 2:
if (!(validUrl === undefined)) return [3 /*break*/, 4];
return [4 /*yield*/, abortIfCancelled(clack.text({
message: 'Please enter the URL of your self-hosted Sentry instance.',
placeholder: 'https://sentry.io/',
}))];
case 3:
url = _a.sent();
try {
validUrl = new url_1.URL(url).toString();
// We assume everywhere else that the URL ends in a slash
if (!validUrl.endsWith('/')) {
validUrl += '/';
}
}
catch (_b) {
clack.log.error('Please enter a valid URL. (It should look something like "http://sentry.mydomain.com/")');
}
return [3 /*break*/, 2];
case 4:
Sentry.setTag('url', validUrl);
Sentry.setTag('self-hosted', true);
return [2 /*return*/, { url: validUrl, selfHosted: true }];
}
});
});
}
exports.askForSelfHosted = askForSelfHosted;
function addSentryCliRc(authToken) {
return __awaiter(this, void 0, void 0, function () {
var clircExists, clircContents, likelyAlreadyHasAuthToken, _a, _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
clircExists = fs.existsSync(path.join(process.cwd(), '.sentryclirc'));
if (!clircExists) return [3 /*break*/, 5];
clircContents = fs.readFileSync(path.join(process.cwd(), '.sentryclirc'), 'utf8');
likelyAlreadyHasAuthToken = !!(clircContents.includes('[auth]') && clircContents.match(/token=./g));
if (!likelyAlreadyHasAuthToken) return [3 /*break*/, 1];
clack.log.warn("".concat(chalk_1.default.bold('.sentryclirc'), " already has auth token. Will not add one."));
return [3 /*break*/, 4];
case 1:
_c.trys.push([1, 3, , 4]);
return [4 /*yield*/, fs.promises.writeFile(path.join(process.cwd(), '.sentryclirc'), "".concat(clircContents, "\n[auth]\ntoken=").concat(authToken, "\n"), { encoding: 'utf8', flag: 'w' })];
case 2:
_c.sent();
clack.log.success("Added auth token to ".concat(chalk_1.default.bold('.sentryclirc'), " for you to test uploading source maps locally."));
return [3 /*break*/, 4];
case 3:
_a = _c.sent();
clack.log.warning("Failed to add auth token to ".concat(chalk_1.default.bold('.sentryclirc'), ". Uploading source maps during build will likely not work locally."));
return [3 /*break*/, 4];
case 4: return [3 /*break*/, 8];
case 5:
_c.trys.push([5, 7, , 8]);
return [4 /*yield*/, fs.promises.writeFile(path.join(process.cwd(), '.sentryclirc'), "[auth]\ntoken=".concat(authToken, "\n"), { encoding: 'utf8', flag: 'w' })];
case 6:
_c.sent();
clack.log.success("Created ".concat(chalk_1.default.bold('.sentryclirc'), " with auth token for you to test uploading source maps locally."));
return [3 /*break*/, 8];
case 7:
_b = _c.sent();
clack.log.warning("Failed to create ".concat(chalk_1.default.bold('.sentryclirc'), " with auth token. Uploading source maps during build will likely not work locally."));
return [3 /*break*/, 8];
case 8: return [4 /*yield*/, addAuthTokenFileToGitIgnore('.sentryclirc')];
case 9:
_c.sent();
return [2 /*return*/];
}
});
});
}
exports.addSentryCliRc = addSentryCliRc;
function addDotEnvSentryBuildPluginFile(authToken) {
return __awaiter(this, void 0, void 0, function () {
var DOT_ENV_FILE, envVarContent, dotEnvFilePath, dotEnvFileExists, dotEnvFileContent, hasAuthToken, _a, _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
DOT_ENV_FILE = '.env.sentry-build-plugin';
envVarContent = "# DO NOT commit this file to your repository!\n# The SENTRY_AUTH_TOKEN variable is picked up by the Sentry Build Plugin.\n# It's used for authentication when uploading source maps.\n# You can also set this env variable in your own `.env` files and remove this file.\nSENTRY_AUTH_TOKEN=\"".concat(authToken, "\"\n");
dotEnvFilePath = path.join(process.cwd(), DOT_ENV_FILE);
dotEnvFileExists = fs.existsSync(dotEnvFilePath);
if (!dotEnvFileExists) return [3 /*break*/, 5];
dotEnvFileContent = fs.readFileSync(dotEnvFilePath, 'utf8');
hasAuthToken = !!dotEnvFileContent.match(/^\s*SENTRY_AUTH_TOKEN\s*=/g);
if (!hasAuthToken) return [3 /*break*/, 1];
clack.log.warn("".concat(chalk_1.default.bold(DOT_ENV_FILE), " already has auth token. Will not add one."));
return [3 /*break*/, 4];
case 1:
_c.trys.push([1, 3, , 4]);
return [4 /*yield*/, fs.promises.writeFile(dotEnvFilePath, "".concat(dotEnvFileContent, "\n").concat(envVarContent), {
encoding: 'utf8',
flag: 'w',
})];
case 2:
_c.sent();
clack.log.success("Added auth token to ".concat(chalk_1.default.bold(DOT_ENV_FILE)));
return [3 /*break*/, 4];
case 3:
_a = _c.sent();
clack.log.warning("Failed to add auth token to ".concat(chalk_1.default.bold(DOT_ENV_FILE), ". Uploading source maps during build will likely not work locally."));
return [3 /*break*/, 4];
case 4: return [3 /*break*/, 8];
case 5:
_c.trys.push([5, 7, , 8]);
return [4 /*yield*/, fs.promises.writeFile(dotEnvFilePath, envVarContent, {
encoding: 'utf8',
flag: 'w',
})];
case 6:
_c.sent();
clack.log.success("Created ".concat(chalk_1.default.bold(DOT_ENV_FILE), " with auth token for you to test source map uploading locally."));
return [3 /*break*/, 8];
case 7:
_b = _c.sent();
clack.log.warning("Failed to create ".concat(chalk_1.default.bold(DOT_ENV_FILE), " with auth token. Uploading source maps during build will likely not work locally."));
return [3 /*break*/, 8];
case 8: return [4 /*yield*/, addAuthTokenFileToGitIgnore(DOT_ENV_FILE)];
case 9:
_c.sent();
return [2 /*return*/];
}
});
});
}
exports.addDotEnvSentryBuildPluginFile = addDotEnvSentryBuildPluginFile;
function addAuthTokenFileToGitIgnore(filename) {
return __awaiter(this, void 0, void 0, function () {
var _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_b.trys.push([0, 2, , 3]);
return [4 /*yield*/, fs.promises.appendFile(path.join(process.cwd(), '.gitignore'), "\n# Sentry Auth Token\n".concat(filename, "\n"), { encoding: 'utf8' })];
case 1:
_b.sent();
clack.log.success("Added ".concat(chalk_1.default.bold(filename), " to ").concat(chalk_1.default.bold('.gitignore'), "."));
return [3 /*break*/, 3];
case 2:
_a = _b.sent();
clack.log.error("Failed adding ".concat(chalk_1.default.bold(filename), " to ").concat(chalk_1.default.bold('.gitignore'), ". Please add it manually!"));
return [3 /*break*/, 3];
case 3: return [2 /*return*/];
}
});
});
}
function ensurePackageIsInstalled(packageJson, packageId, packageName) {
return __awaiter(this, void 0, void 0, function () {
var continueWithoutPackage;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!!hasPackageInstalled(packageId, packageJson)) return [3 /*break*/, 3];
return [4 /*yield*/, abortIfCancelled(clack.confirm({
message: "".concat(packageName, " does not seem to be installed. Do you still want to continue?"),
initialValue: false,
}))];
case 1:
continueWithoutPackage = _a.sent();
if (!!continueWithoutPackage) return [3 /*break*/, 3];
return [4 /*yield*/, abort(undefined, 0)];
case 2:
_a.sent();
_a.label = 3;
case 3: return [2 /*return*/];
}
});
});
}
exports.ensurePackageIsInstalled = ensurePackageIsInstalled;
function getPackageDotJson() {
return __awaiter(this, void 0, void 0, function () {
var packageJsonFileContents, packageJson, _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, fs.promises
.readFile(path.join(process.cwd(), 'package.json'), 'utf8')
.catch(function () {
clack.log.error('Could not find package.json. Make sure to run the wizard in the root of your app!');
return abort();
})];
case 1:
packageJsonFileContents = _b.sent();
packageJson = undefined;
_b.label = 2;
case 2:
_b.trys.push([2, 3, , 5]);
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
packageJson = JSON.parse(packageJsonFileContents);
return [3 /*break*/, 5];
case 3:
_a = _b.sent();
clack.log.error('Unable to parse your package.json. Make sure it has a valid format!');
return [4 /*yield*/, abort()];
case 4:
_b.sent();
return [3 /*break*/, 5];
case 5: return [2 /*return*/, packageJson || {}];
}
});
});
}
exports.getPackageDotJson = getPackageDotJson;
function hasPackageInstalled(packageName, packageJson) {
var _a, _b;
return (!!((_a = packageJson === null || packageJson === void 0 ? void 0 : packageJson.dependencies) === null || _a === void 0 ? void 0 : _a[packageName]) ||
!!((_b = packageJson === null || packageJson === void 0 ? void 0 : packageJson.devDependencies) === null || _b === void 0 ? void 0 : _b[packageName]));
}
exports.hasPackageInstalled = hasPackageInstalled;
function getPackageManager() {
return __awaiter(this, void 0, void 0, function () {
var detectedPackageManager, selectedPackageManager;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (fs.existsSync(path.join(process.cwd(), 'yarn.lock'))) {
detectedPackageManager = 'yarn';
}
else if (fs.existsSync(path.join(process.cwd(), 'package-lock.json'))) {
detectedPackageManager = 'npm';
}
else if (fs.existsSync(path.join(process.cwd(), 'pnpm-lock.yaml'))) {
detectedPackageManager = 'pnpm';
}
if (detectedPackageManager) {
return [2 /*return*/, detectedPackageManager];
}
return [4 /*yield*/, abortIfCancelled(clack.select({
message: 'Please select your package manager.',
options: [
{ value: 'npm', label: 'Npm' },
{ value: 'yarn', label: 'Yarn' },
{ value: 'pnpm', label: 'Pnpm' },
],
}))];
case 1:
selectedPackageManager = _a.sent();
Sentry.setTag('package-manager', selectedPackageManager);
return [2 /*return*/, selectedPackageManager];
}
});
});
}
//# sourceMappingURL=clack-utils.js.map