Skip to content

Commit

Permalink
fix: Support --url arg in NextJs, SvelteKit and Sourcemaps wizards (
Browse files Browse the repository at this point in the history
…#331)

Reintroduce support for the `--url` (`-u`) arg in the new `clack`-based wizards (Next, Sveltekit, Sourcemaps). 

This enables users to optionally specify a url when starting the wizard via the command line:

```sh
npx @sentry/wizard@latest -u https://sentry.mydomain.com -i sourcemaps
```
  • Loading branch information
Lms24 committed Jul 5, 2023
1 parent 684e300 commit 3f1c146
Show file tree
Hide file tree
Showing 11 changed files with 128 additions and 69 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## Unreleased

- feat: Open browser when logging in (sourcemaps, sveltekit, nextjs) (#328)
- fix: Support `--url` arg in NextJs, SvelteKit and Sourcemaps wizards (#331)
- fix: Update minimum Node version to Node 14 (#332)

## 3.4.0
Expand Down
59 changes: 41 additions & 18 deletions bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { runNextjsWizard } from './src/nextjs/nextjs-wizard';
import { runSourcemapsWizard } from './src/sourcemaps/sourcemaps-wizard';
import { runSvelteKitWizard } from './src/sveltekit/sveltekit-wizard';
import { withTelemetry } from './src/telemetry';
import { WizardOptions } from './src/utils/types';
export * from './lib/Setup';

// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
Expand Down Expand Up @@ -44,7 +45,7 @@ const argv = require('yargs')
})
.option('u', {
alias: 'url',
default: DEFAULT_URL,
default: undefined,
describe: 'The url to your Sentry installation\nenv: SENTRY_WIZARD_URL',
})
.option('s', {
Expand All @@ -63,22 +64,44 @@ const argv = require('yargs')
describe: 'A promo code that will be applied during signup',
}).argv;

if (argv.i === 'nextjs') {
// eslint-disable-next-line no-console
runNextjsWizard({ promoCode: argv['promo-code'] }).catch(console.error);
} else if (argv.i === 'sveltekit') {
// eslint-disable-next-line no-console
runSvelteKitWizard({ promoCode: argv['promo-code'] }).catch(console.error);
} else if (argv.i === 'sourcemaps') {
withTelemetry(
{
enabled: !argv['disable-telemetry'],
integration: 'sourcemaps',
},
() => runSourcemapsWizard({ promoCode: argv['promo-code'] }),
// Collect argv options that are relevant for the new wizard
// flows based on `clack`
const wizardOptions: WizardOptions = {
url: argv.u as string | undefined,

Check warning on line 70 in bin.ts

View workflow job for this annotation

GitHub Actions / Lint

Unsafe member access .u on an `any` value
promoCode: argv['promo-code'] as string | undefined,

Check warning on line 71 in bin.ts

View workflow job for this annotation

GitHub Actions / Lint

Unsafe member access ['promo-code'] on an `any` value
};

switch (argv.i) {

Check warning on line 74 in bin.ts

View workflow job for this annotation

GitHub Actions / Lint

Unsafe member access .i on an `any` value
case 'nextjs':
// eslint-disable-next-line no-console
runNextjsWizard(wizardOptions).catch(console.error);
break;
case 'sveltekit':
// eslint-disable-next-line no-console
).catch(console.error);
} else {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
run(argv);
runSvelteKitWizard(wizardOptions).catch(console.error);
break;
case 'sourcemaps':
withTelemetry(
{
enabled: !argv['disable-telemetry'],

Check warning on line 86 in bin.ts

View workflow job for this annotation

GitHub Actions / Lint

Unsafe member access ['disable-telemetry'] on an `any` value
integration: 'sourcemaps',
},
() => runSourcemapsWizard(wizardOptions),
// eslint-disable-next-line no-console
).catch(console.error);
break;
default:
runOldWizard();
}

function runOldWizard() {
// For the `clack`-based wizard flows, we don't want a default url value
// For backwards-compatibility with the other flows, we fill it in here
const argvWithUrlDefaults = {

Check warning on line 100 in bin.ts

View workflow job for this annotation

GitHub Actions / Lint

Unsafe assignment of an `any` value
...argv,
url: argv.url || DEFAULT_URL,

Check warning on line 102 in bin.ts

View workflow job for this annotation

GitHub Actions / Lint

Unsafe assignment of an `any` value

Check warning on line 102 in bin.ts

View workflow job for this annotation

GitHub Actions / Lint

Unsafe member access .url on an `any` value
u: argv.u || DEFAULT_URL,

Check warning on line 103 in bin.ts

View workflow job for this annotation

GitHub Actions / Lint

Unsafe assignment of an `any` value

Check warning on line 103 in bin.ts

View workflow job for this annotation

GitHub Actions / Lint

Unsafe member access .u on an `any` value
};

void run(argvWithUrlDefaults);
}
8 changes: 4 additions & 4 deletions lib/Steps/ChooseIntegration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import { getIntegrationChoices, Integration } from '../Constants';
import { BaseStep } from './BaseStep';
import { Cordova } from './Integrations/Cordova';
import { Electron } from './Integrations/Electron';
import { NextJs } from './Integrations/NextJs';
import { NextJsShim } from './Integrations/NextJsShim';
import { ReactNative } from './Integrations/ReactNative';
import { SourceMapsShim } from './Integrations/SourceMapsShim';
import { SvelteKit } from './Integrations/SvelteKit';
import { SvelteKitShim } from './Integrations/SvelteKitShim';

let projectPackage: any = {};

Expand Down Expand Up @@ -40,10 +40,10 @@ export class ChooseIntegration extends BaseStep {
integration = new Electron(this._argv);
break;
case Integration.nextjs:
integration = new NextJs(this._argv);
integration = new NextJsShim(this._argv);
break;
case Integration.sveltekit:
integration = new SvelteKit(this._argv);
integration = new SvelteKitShim(this._argv);
break;
case Integration.sourcemaps:
integration = new SourceMapsShim(this._argv);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ import { BaseIntegration } from './BaseIntegration';
* This class just redirects to the new `nextjs-wizard.ts` flow
* for anyone calling the wizard without the '-i nextjs' flag.
*/
export class NextJs extends BaseIntegration {
export class NextJsShim extends BaseIntegration {
public constructor(protected _argv: Args) {
super(_argv);
}

public async emit(_answers: Answers): Promise<Answers> {
await runNextjsWizard({ promoCode: this._argv.promoCode });
await runNextjsWizard({
promoCode: this._argv.promoCode,
url: this._argv.url,
});
return {};
}

Expand Down
5 changes: 4 additions & 1 deletion lib/Steps/Integrations/SourceMapsShim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ export class SourceMapsShim extends BaseIntegration {
}

public async emit(_answers: Answers): Promise<Answers> {
await runSourcemapsWizard({ promoCode: this._argv.promoCode });
await runSourcemapsWizard({
promoCode: this._argv.promoCode,
url: this._argv.url,
});
return {};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ import { BaseIntegration } from './BaseIntegration';
* This class just redirects to the new `sveltekit-wizard.ts` flow
* for anyone calling the wizard without the '-i sveltekit' flag.
*/
export class SvelteKit extends BaseIntegration {
export class SvelteKitShim extends BaseIntegration {
public constructor(protected _argv: Args) {
super(_argv);
}

public async emit(_answers: Answers): Promise<Answers> {
await runSvelteKitWizard({ promoCode: this._argv.promoCode });
await runSvelteKitWizard({
promoCode: this._argv.promoCode,
url: this._argv.url,
});
return {};
}

Expand Down
11 changes: 3 additions & 8 deletions src/nextjs/nextjs-wizard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
installPackage,
printWelcome,
} from '../utils/clack-utils';
import { WizardOptions } from '../utils/types';
import {
getNextjsConfigCjsAppendix,
getNextjsConfigCjsTemplate,
Expand All @@ -31,14 +32,8 @@ import {
getSentryExamplePageContents,
} from './templates';

interface NextjsWizardOptions {
promoCode?: string;
}

// eslint-disable-next-line complexity
export async function runNextjsWizard(
options: NextjsWizardOptions,
): Promise<void> {
export async function runNextjsWizard(options: WizardOptions): Promise<void> {
printWelcome({
wizardName: 'Sentry Next.js Wizard',
promoCode: options.promoCode,
Expand All @@ -49,7 +44,7 @@ export async function runNextjsWizard(
const packageJson = await getPackageDotJson();
await ensurePackageIsInstalled(packageJson, 'next', 'Next.js');

const { url: sentryUrl, selfHosted } = await askForSelfHosted();
const { url: sentryUrl, selfHosted } = await askForSelfHosted(options.url);

const { projects, apiKeys } = await askForWizardLogin({
promoCode: options.promoCode,
Expand Down
9 changes: 3 additions & 6 deletions src/sourcemaps/sourcemaps-wizard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@ import { configureWebPackPlugin } from './tools/webpack';
import { configureTscSourcemapGenerationFlow } from './tools/tsc';
import { configureRollupPlugin } from './tools/rollup';
import { configureEsbuildPlugin } from './tools/esbuild';

interface SourceMapsWizardOptions {
promoCode?: string;
}
import { WizardOptions } from '../utils/types';

type SupportedTools =
| 'webpack'
Expand All @@ -33,7 +30,7 @@ type SupportedTools =
| 'sentry-cli';

export async function runSourcemapsWizard(
options: SourceMapsWizardOptions,
options: WizardOptions,
): Promise<void> {
printWelcome({
wizardName: 'Sentry Source Maps Upload Configuration Wizard',
Expand All @@ -44,7 +41,7 @@ export async function runSourcemapsWizard(

await confirmContinueEvenThoughNoGitRepo();

const { url: sentryUrl, selfHosted } = await askForSelfHosted();
const { url: sentryUrl, selfHosted } = await askForSelfHosted(options.url);

const { projects, apiKeys } = await askForWizardLogin({
promoCode: options.promoCode,
Expand Down
9 changes: 3 additions & 6 deletions src/sveltekit/sveltekit-wizard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,14 @@ import {
installPackage,
printWelcome,
} from '../utils/clack-utils';
import { WizardOptions } from '../utils/types';
import { createExamplePage } from './sdk-example';
import { createOrMergeSvelteKitFiles, loadSvelteConfig } from './sdk-setup';

import { setupCLIConfig } from './sentry-cli-setup';

interface SvelteKitWizardOptions {
promoCode?: string;
}

export async function runSvelteKitWizard(
options: SvelteKitWizardOptions,
options: WizardOptions,
): Promise<void> {
printWelcome({
wizardName: 'Sentry SvelteKit Wizard',
Expand All @@ -35,7 +32,7 @@ export async function runSvelteKitWizard(
const packageJson = await getPackageDotJson();
await ensurePackageIsInstalled(packageJson, '@sveltejs/kit', 'Sveltekit');

const { url: sentryUrl, selfHosted } = await askForSelfHosted();
const { url: sentryUrl, selfHosted } = await askForSelfHosted(options.url);

const { projects, apiKeys } = await askForWizardLogin({
promoCode: options.promoCode,
Expand Down
68 changes: 46 additions & 22 deletions src/utils/clack-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,34 +315,55 @@ export async function installPackage({
);
}

export async function askForSelfHosted(): Promise<{
/**
* Asks users if they are using SaaS or self-hosted Sentry and returns the validated URL.
*
* If users started the wizard with a --url arg, that URL is used as the default and we skip
* the self-hosted question. However, the passed url is still validated and in case it's
* invalid, users are asked to enter a new one until it is valid.
*
* @param urlFromArgs the url passed via the --url arg
*/
export async function askForSelfHosted(urlFromArgs?: string): Promise<{
url: string;
selfHosted: boolean;
}> {
const choice: 'saas' | 'self-hosted' | symbol = await 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' },
],
}),
);
if (!urlFromArgs) {
const choice: 'saas' | 'self-hosted' | symbol = await 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',
},
],
}),
);

if (choice === 'saas') {
Sentry.setTag('url', SAAS_URL);
Sentry.setTag('self-hosted', false);
return { url: SAAS_URL, selfHosted: false };
if (choice === 'saas') {
Sentry.setTag('url', SAAS_URL);
Sentry.setTag('self-hosted', false);
return { url: SAAS_URL, selfHosted: false };
}
}

let validUrl: string | undefined;
let tmpUrlFromArgs = urlFromArgs;

while (validUrl === undefined) {
const url = await abortIfCancelled(
clack.text({
message: 'Please enter the URL of your self-hosted Sentry instance.',
placeholder: 'https://sentry.io/',
}),
);
const url =
tmpUrlFromArgs ||
(await abortIfCancelled(
clack.text({
message: `Please enter the URL of your ${
urlFromArgs ? '' : 'self-hosted '
}Sentry instance.`,
placeholder: 'https://sentry.io/',
}),
));
tmpUrlFromArgs = undefined;

try {
validUrl = new URL(url).toString();
Expand All @@ -353,13 +374,16 @@ export async function askForSelfHosted(): Promise<{
}
} catch {
clack.log.error(
'Please enter a valid URL. (It should look something like "http://sentry.mydomain.com/")',
'Please enter a valid URL. (It should look something like "https://sentry.mydomain.com/")',
);
}
}

const isSelfHostedUrl = new URL(validUrl).host !== new URL(SAAS_URL).host;

Sentry.setTag('url', validUrl);
Sentry.setTag('self-hosted', true);
Sentry.setTag('self-hosted', isSelfHostedUrl);

return { url: validUrl, selfHosted: true };
}

Expand Down
13 changes: 13 additions & 0 deletions src/utils/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export type WizardOptions = {
/**
* The promo code to use while signing up for Sentry.
* This can be passed via the --promo-code arg.
*/
promoCode?: string;

/**
* The url of the Sentry instance to use.
* This can be passed via the `-u` or `--url` arg.
*/
url?: string;
};

0 comments on commit 3f1c146

Please sign in to comment.