@sentry/wizard
Version:
Sentry wizard helping you to configure your project
211 lines (210 loc) • 10.1 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>;
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;
export declare function confirmContinueIfNoOrDirtyGitRepo(): Promise<void>;
export declare function isInGitRepo(): boolean;
export declare function getUncommittedOrUntrackedFiles(): string[];
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>;
/**
* 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, }: {
/** 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;
}): Promise<{
packageManager?: PackageManager;
}>;
export declare function addSentryCliConfig({ authToken, org, project, url }: CliSetupConfigContent, setupConfig?: CliSetupConfig): Promise<void>;
export declare function addDotEnvSentryBuildPluginFile(authToken: string): Promise<void>;
export declare function runPrettierIfInstalled(): 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>;
export declare function getPackageManager(): 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-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-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>;
/**
* 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(filename: string, codeSnippet: string, hint?: string): 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 {};