@sentry/wizard
Version:
Sentry wizard helping you to configure your project
263 lines (262 loc) • 12.2 kB
TypeScript
import { type PackageDotJson } from '../package-json';
import { type PackageManager } from '../package-manager';
import type { Feature, SentryProjectData, WizardOptions } from '../types';
export declare const SENTRY_DOT_ENV_FILE = ".env.sentry-build-plugin";
export declare const SENTRY_CLI_RC_FILE = ".sentryclirc";
export declare const SENTRY_PROPERTIES_FILE = "sentry.properties";
interface WizardProjectData {
apiKeys?: {
token?: string;
};
projects?: SentryProjectData[];
}
export interface CliSetupConfig {
filename: string;
name: string;
gitignore: boolean;
likelyAlreadyHasAuthToken(contents: string): boolean;
tokenContent(authToken: string): string;
likelyAlreadyHasOrgAndProject(contents: string): boolean;
orgAndProjContent(org: string, project: string): string;
likelyAlreadyHasUrl?(contents: string): boolean;
urlContent?(url: string): string;
}
export interface CliSetupConfigContent {
authToken: string;
org?: string;
project?: string;
url?: string;
}
export declare const rcCliSetupConfig: CliSetupConfig;
export declare const propertiesCliSetupConfig: Required<CliSetupConfig>;
/**
* Aborts the wizard and sets the Sentry transaction status to `cancelled` or `aborted`.
*
* @param message The message to display to the user.
* @param status The status to set on the Sentry transaction. Defaults to `1`.
*/
export declare function abort(message?: string, status?: number): Promise<never>;
export declare function abortIfCancelled<T>(input: T | Promise<T>): Promise<Exclude<T, symbol>>;
export declare function printWelcome(options: {
wizardName: string;
promoCode?: string;
message?: string;
telemetryEnabled?: boolean;
}): void;
/**
* Confirms if the user wants to continue with the wizard if the project is not a git repository.
*
* @param options.ignoreGitChanges If true, the wizard will not check if the project is a git repository.
* @param options.cwd The directory of the project. If undefined, the current process working directory will be used.
*/
export declare function confirmContinueIfNoOrDirtyGitRepo(options: {
ignoreGitChanges: boolean | undefined;
cwd: string | undefined;
}): Promise<void>;
export declare function askToInstallSentryCLI(): Promise<boolean>;
export declare function askForItemSelection(items: string[], message: string): Promise<{
value: string;
index: number;
}>;
export declare function confirmContinueIfPackageVersionNotSupported({ packageId, packageName, packageVersion, acceptableVersions, note, }: {
packageId: string;
packageName: string;
packageVersion: string;
acceptableVersions: string;
note?: string;
}): Promise<void>;
type InstallPackageOptions = {
/** The string that is passed to the package manager CLI as identifier to install (e.g. `@sentry/nextjs`, or `@sentry/nextjs@^8`) */
packageName: string;
alreadyInstalled: boolean;
askBeforeUpdating?: boolean;
/** Overrides what is shown in the installation logs in place of the `packageName` option. Useful if the `packageName` is ugly (e.g. `@sentry/nextjs@^8`) */
packageNameDisplayLabel?: string;
packageManager?: PackageManager;
/** Add force install flag to command to skip install precondition fails */
forceInstall?: boolean;
/** Install as a dev dependency (@default: false) */
devDependency?: boolean;
};
/**
* Installs or updates a package with the user's package manager.
*
* IMPORTANT: This function modifies the `package.json`! Be sure to re-read
* it if you make additional modifications to it after calling this function!
*/
export declare function installPackage({ packageName, alreadyInstalled, askBeforeUpdating, packageNameDisplayLabel, packageManager, forceInstall, devDependency, }: InstallPackageOptions): Promise<{
packageManager?: PackageManager;
}>;
export declare function addSentryCliConfig({ authToken, org, project, url }: CliSetupConfigContent, setupConfig?: CliSetupConfig): Promise<void>;
export declare function addDotEnvSentryBuildPluginFile(authToken: string): Promise<void>;
/**
* Runs prettier on the changed or untracked files in the project.
*
* @param options.cwd The directory of the project. If undefined, the current process working directory will be used.
*/
export declare function runPrettierIfInstalled(opts: {
cwd: string | undefined;
}): Promise<void>;
/**
* Checks if @param packageId is listed as a dependency in @param packageJson.
* If not, it will ask users if they want to continue without the package.
*
* Use this function to check if e.g. a the framework of the SDK is installed
*
* @param packageJson the package.json object
* @param packageId the npm name of the package
* @param packageName a human readable name of the package
*/
export declare function ensurePackageIsInstalled(packageJson: PackageDotJson, packageId: string, packageName: string): Promise<void>;
export declare function getPackageDotJson(): Promise<PackageDotJson>;
export declare function updatePackageDotJson(packageDotJson: PackageDotJson): Promise<void>;
/**
* Use this function to get the used JS Package manager.
*
* This function:
* - attempts to auto-detect the used package manager and return it
* - if unsuccessful, returns the passed fallback package manager
* - if no fallback is passed, it asks the user to select a package manager
*
* The result is cached on the first invocation to avoid asking the user multiple times.
*
* @param fallback the package manager to use if auto-detection fails and you don't want to
* ask the user. This is useful in cases where asking users would be too intrusive/low in value
* and where it's okay to fall back to a default package manager. Use this with caution.
*/
export declare function getPackageManager(fallback?: PackageManager): Promise<PackageManager>;
export declare function isUsingTypeScript(): boolean;
/**
* Checks if we already got project data from a previous wizard invocation.
* If yes, this data is returned.
* Otherwise, we start the login flow and ask the user to select a project.
*
* Use this function to get project data for the wizard.
*
* @param options wizard options
* @param platform the platform of the wizard
* @returns project data (org, project, token, url)
*/
export declare function getOrAskForProjectData(options: WizardOptions, platform?: 'javascript-angular' | 'javascript-nextjs' | 'javascript-nuxt' | 'javascript-remix' | 'javascript-sveltekit' | 'apple-ios' | 'android' | 'react-native' | 'flutter'): Promise<{
sentryUrl: string;
selfHosted: boolean;
selectedProject: SentryProjectData;
authToken: string;
}>;
/**
* Exported for testing
*/
export declare function askForWizardLogin(options: {
url: string;
promoCode?: string;
platform?: 'javascript-angular' | 'javascript-nextjs' | 'javascript-nuxt' | 'javascript-remix' | 'javascript-sveltekit' | 'apple-ios' | 'android' | 'react-native' | 'flutter';
orgSlug?: string;
projectSlug?: string;
comingFrom?: string;
}): Promise<WizardProjectData>;
/**
* Asks users if they have a config file for @param tool (e.g. Vite).
* If yes, asks users to specify the path to their config file.
*
* Use this helper function as a fallback mechanism if the lookup for
* a config file with its most usual location/name fails.
*
* @param toolName Name of the tool for which we're looking for the config file
* @param configFileName Name of the most common config file name (e.g. vite.config.js)
*
* @returns a user path to the config file or undefined if the user doesn't have a config file
*/
export declare function askForToolConfigPath(toolName: string, configFileName: string): Promise<string | undefined>;
type ShowCopyPasteInstructionsOptions = {
codeSnippet: string;
} & ({
filename: string;
hint?: string;
} | {
instructions: string;
});
/**
* Prints copy/paste-able instructions to the console.
* Afterwards asks the user if they added the code snippet to their file.
*
* While there's no point in providing a "no" answer here, it gives users time to fulfill the
* task before the wizard continues with additional steps.
*
* Use this function if you want to show users instructions on how to add/modify
* code in their file. This is helpful if automatic insertion failed or is not possible/feasible.
*
* @param filename the name of the file to which the code snippet should be applied.
* If a path is provided, only the filename will be used.
*
* @param codeSnippet the snippet to be printed. Use {@link makeCodeSnippet} to create the
* diff-like format for visually highlighting unchanged or modified lines of code.
*
* @param hint (optional) a hint to be printed after the main instruction to add
* the code from @param codeSnippet to their @param filename.
*
* More guidelines on copy/paste instructions:
* @see {@link https://develop.sentry.dev/sdk/setup-wizards/#copy--paste-snippets}
*
* TODO: refactor copy paste instructions across different wizards to use this function.
* this might require adding a custom message parameter to the function
*/
export declare function showCopyPasteInstructions(opts: ShowCopyPasteInstructionsOptions): Promise<void>;
/**
* Callback that exposes formatting helpers for a code snippet.
* @param unchanged - Formats text as old code.
* @param plus - Formats text as new code.
* @param minus - Formats text as removed code.
*/
type CodeSnippetFormatter = (unchanged: (txt: string) => string, plus: (txt: string) => string, minus: (txt: string) => string) => string;
/**
* Crafts a code snippet that can be used to e.g.
* - print copy/paste instructions to the console
* - create a new config file.
*
* @param colors set this to true if you want the final snippet to be colored.
* This is useful for printing the snippet to the console as part of copy/paste instructions.
*
* @param callback the callback that returns the formatted code snippet.
* It exposes takes the helper functions for marking code as unchanged, new or removed.
* These functions no-op if no special formatting should be applied
* and otherwise apply the appropriate formatting/coloring.
* (@see {@link CodeSnippetFormatter})
*
* @see {@link showCopyPasteInstructions} for the helper with which to display the snippet in the console.
*
* @returns a string containing the final, formatted code snippet.
*/
export declare function makeCodeSnippet(colors: boolean, callback: CodeSnippetFormatter): string;
/**
* Creates a new config file with the given @param filepath and @param codeSnippet.
*
* Use this function to create a new config file for users. This is useful
* when users answered that they don't yet have a config file for a tool.
*
* (This doesn't mean that they don't yet have some other way of configuring
* their tool but we can leave it up to them to figure out how to merge configs
* here.)
*
* @param filepath absolute path to the new config file
* @param codeSnippet the snippet to be inserted into the file
* @param moreInformation (optional) the message to be printed after the file was created
* For example, this can be a link to more information about configuring the tool.
*
* @returns true on success, false otherwise
*/
export declare function createNewConfigFile(filepath: string, codeSnippet: string, moreInformation?: string): Promise<boolean>;
export declare function askShouldCreateExamplePage(customRoute?: string): Promise<boolean>;
export declare function askShouldCreateExampleComponent(): Promise<boolean>;
export declare function featureSelectionPrompt<F extends ReadonlyArray<Feature>>(features: F): Promise<{
[key in F[number]['id']]: boolean;
}>;
export declare function askShouldInstallPackage(pkgName: string): Promise<boolean>;
export declare function askShouldAddPackageOverride(pkgName: string, pkgVersion: string): Promise<boolean>;
export declare function artifactsExist(relativePath: string): boolean;
export declare function askToRunBuildOrEnterPathOrProceed({ relativeArtifactPath, }: {
relativeArtifactPath: string;
}): Promise<{
validPath: boolean;
relativeArtifactPath?: string;
}>;
export {};