Skip to content

Conversation

@JPeer264
Copy link
Member

@JPeer264 JPeer264 commented Nov 26, 2025

(closes #2617)
(closes CLI-142)

This PR migrates all JavaScript files in the lib/ directory to native TypeScript, removing the need for JSDoc type annotations and improving type safety.

Main Changes

  • Converted all .js files to .ts with proper TypeScript syntax
  • Changed module system from CommonJS to ES6 modules for better TypeScript interoperability
  • Updated exports to use ES6 export syntax instead of module.exports
  • All types are now exported as named exports for better type inference and IDE support
  • OptionsSchema is now a union to satisfy SOURCEMAPS_OPTIONS, as this one didn't had the required param
  • The exports of lib/releases/options has changed its name

Breaking Changes

Module Exports

  • Before: module.exports = SentryCli; (CommonJS)
  • After: export class SentryCli { ... } (ES6 named export)

We could have maintained backwards compatibility with export = SentryCli;. The only problem were the types which needed to be exported as well. With ES6 named exports, we can now export all types alongside the class.

Internal Improvements

Simplified Release constructor

  • Before: new Releases({ ...this.options, configFile }) - configFile was merged into options
  • After: new Releases(this.options, configFile) - two separate parameters

With 2 parameters it's easier to maintain and makes the separation of concerns clearer.

@JPeer264 JPeer264 self-assigned this Nov 26, 2025
@JPeer264 JPeer264 requested review from a team as code owners November 26, 2025 16:02
@JPeer264 JPeer264 requested review from nicohrubec and removed request for a team November 26, 2025 16:02
@JPeer264 JPeer264 added the v3.0 Breaking changes to include in version 3.0.0 of Sentry CLI label Nov 26, 2025
@JPeer264 JPeer264 changed the title feat: move javascript files to native typescript feat: Move javascript files to native typescript Nov 26, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Nov 26, 2025

Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against 0f60c1c

@JPeer264 JPeer264 force-pushed the jp/move-to-native-typescript branch from 15c05f5 to a8e7f1f Compare November 26, 2025 16:33
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: rejectOnError always rejects after resolving

When live is 'rejectOnError' and the command succeeds with exit code 0, the code resolves with 'success (live mode)' but then immediately continues to execute the reject statement because there's no return or else. This causes the promise to be settled twice and creates incorrect behavior where successful commands trigger rejection logic.

lib/helper.ts#L342-L348

sentry-cli/lib/helper.ts

Lines 342 to 348 in a8e7f1f

pid.on('exit', (exitCode) => {
if (live === 'rejectOnError') {
if (exitCode === 0) {
resolve('success (live mode)');
}
reject(new Error(`Command ${args.join(' ')} failed with exit code ${exitCode}`));
}

Fix in Cursor Fix in Web


* @param options More options to pass to the CLI
*/
constructor(configFile, options) {
constructor(public configFile: string | null, public options: SentryCliOptions) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: SentryCli constructor breaks backwards compatibility

The constructor declares both configFile and options as required parameters without default values, but existing code calls new SentryCli() with no arguments. The original JavaScript version allowed both parameters to be optional. This breaks backwards compatibility beyond just the import syntax change documented in the CHANGELOG.

Fix in Cursor Fix in Web

@JPeer264 JPeer264 force-pushed the jp/move-to-native-typescript branch from a8e7f1f to d5414fc Compare November 26, 2025 16:45
* @param {OptionsSchema} [schema] An options schema required by the command.
* @param {object} [options] An options object according to the schema.
* @returns {string[]} An arguments array that can be passed via command line.
* @param command The literal name of the command.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Undefined paramName used in non-boolean types

When OptionsSchema entries have only invertedParam without param, the paramName variable becomes undefined. For non-boolean types like string or number, line 237 concatenates undefined into the arguments array, creating invalid command-line arguments. This case needs proper handling to skip entries without a param for non-boolean types.

Fix in Cursor Fix in Web

Copy link
Member

@andreiborza andreiborza left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM although I think we should rethink breaking the default export if avoidable. It makes migration slightly more annoying for little benefit to the user and I'm not sure it's worth the change, but your call.

@JPeer264
Copy link
Member Author

JPeer264 commented Dec 1, 2025

It makes migration slightly more annoying for little benefit to the user and I'm not sure it's worth the change, but your call.

Yes it is a change that the user has to do. The problem however, is that with tsc alone it'd be hard to support ESM & CJS in the future easily. Changing the export seems to be the least harmful.

Just for the record those are the 3 options we have (maybe I miss someone):

  1. Change the export to a named export (current) (this would work in CJS and ESM OOTB, but requires one change)
  2. Change the export to a default export (that would require CJS users to add .default)
  3. Use export = for backwards compatibility. With that we can't export additional types, which would defeat the purpose of having TypeScript (I think this one would also not work in ESM)

For point 2, we could theoretically add module.exports in the buildstep - but I guess tsc does not support that one.

Comment on lines +44 to 50
* @param options More options to pass to the CLI
*/
constructor(configFile, options) {
constructor(public configFile: string | null, public options: SentryCliOptions) {
if (typeof configFile === 'string') {
this.configFile = configFile;
}
this.options = options || { silent: false };

This comment was marked as outdated.

Copy link
Member

@andreiborza andreiborza left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right... fair enough then. I was thinking about our main repo, but totally different build system. I guess with that LGTM!

We just need to make sure we migrate all our repos correctly, few I can think of off of the top of my head:

Copy link
Member

@szokeasaurusrex szokeasaurusrex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only briefly checked this since @andreiborza already approved, but lgtm!

type: 'boolean',
},
};
} satisfies OptionsSchema;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] please fix the missing newline

Suggested change
} satisfies OptionsSchema;
} satisfies OptionsSchema;

I should probably enable pre-commit to auto fix these

@linear
Copy link

linear bot commented Dec 3, 2025

@szokeasaurusrex
Copy link
Member

@JPeer264 is this PR ready to be added to my stack? I can take care of merging conflicts

@JPeer264
Copy link
Member Author

JPeer264 commented Dec 4, 2025

yes it is ready

@szokeasaurusrex szokeasaurusrex force-pushed the jp/move-to-native-typescript branch from f1119df to 36bbead Compare December 10, 2025 13:31
@szokeasaurusrex szokeasaurusrex changed the base branch from jp/drop-node to graphite-base/2989 December 10, 2025 13:32
@szokeasaurusrex szokeasaurusrex changed the base branch from graphite-base/2989 to szokeasaurusrex/debugId December 10, 2025 13:32
if (typeof configFile === 'string') {
this.configFile = configFile;
}
this.options = options || { silent: false };

This comment was marked as outdated.

@szokeasaurusrex szokeasaurusrex removed request for a team and nicohrubec December 10, 2025 13:36
@szokeasaurusrex szokeasaurusrex force-pushed the jp/move-to-native-typescript branch from 36bbead to 60bb5c0 Compare December 10, 2025 13:41
Comment on lines +46 to +51
constructor(public configFile: string | null, public options: SentryCliOptions) {
if (typeof configFile === 'string') {
this.configFile = configFile;
}
this.options = options || { silent: false };
this.releases = new Releases({ ...this.options, configFile });
this.releases = new Releases(this.options, configFile);

This comment was marked as outdated.

Comment on lines +291 to +297
async function execute(
args: string[],
live: boolean,
silent: boolean,
configFile: string | undefined,
config: SentryCliOptions = {}
): Promise<string> {

This comment was marked as outdated.

Comment on lines +44 to +51
* @param options More options to pass to the CLI
*/
constructor(configFile, options) {
constructor(public configFile: string | null, public options: SentryCliOptions) {
if (typeof configFile === 'string') {
this.configFile = configFile;
}
this.options = options || { silent: false };
this.releases = new Releases({ ...this.options, configFile });
this.releases = new Releases(this.options, configFile);

This comment was marked as outdated.

szokeasaurusrex pushed a commit that referenced this pull request Dec 11, 2025
(closes #2617)
(closes [CLI-142](https://linear.app/getsentry/issue/CLI-142/use-typescript-to-generate-type-declarations))

This PR migrates all JavaScript files in the `lib/` directory to native TypeScript, removing the need for JSDoc type annotations and improving type safety.

### Main Changes

- Converted all `.js` files to `.ts` with proper TypeScript syntax
- Changed module system from CommonJS to ES6 modules for better TypeScript interoperability
- Updated exports to use ES6 `export` syntax instead of `module.exports`
- All types are now exported as named exports for better type inference and IDE support
- `OptionsSchema` is now a union to satisfy `SOURCEMAPS_OPTIONS`, as this one didn't had the required `param`
- The exports of `lib/releases/options` has changed its name

### Breaking Changes

**Module Exports**
- **Before**: `module.exports = SentryCli;` (CommonJS)
- **After**: `export class SentryCli { ... }` (ES6 named export)

We could have maintained backwards compatibility with `export = SentryCli;`. The only problem were the types which needed to be exported as well. With ES6 named exports, we can now export all types alongside the class.

### Internal Improvements

Simplified `Release` constructor
- **Before**: `new Releases({ ...this.options, configFile })` - configFile was merged into options
- **After**: `new Releases(this.options, configFile)` - two separate parameters

With 2 parameters it's easier to maintain and makes the separation of concerns clearer.
@szokeasaurusrex szokeasaurusrex force-pushed the jp/move-to-native-typescript branch from 2c953fe to 98e6185 Compare December 11, 2025 16:10
@szokeasaurusrex szokeasaurusrex force-pushed the jp/move-to-native-typescript branch from 98e6185 to 6b32ed2 Compare December 11, 2025 16:25
@szokeasaurusrex szokeasaurusrex force-pushed the jp/move-to-native-typescript branch from 6b32ed2 to 3679dc2 Compare December 11, 2025 17:20
(closes #2617)
(closes [CLI-142](https://linear.app/getsentry/issue/CLI-142/use-typescript-to-generate-type-declarations))

This PR migrates all JavaScript files in the `lib/` directory to native TypeScript, removing the need for JSDoc type annotations and improving type safety.

### Main Changes

- Converted all `.js` files to `.ts` with proper TypeScript syntax
- Changed module system from CommonJS to ES6 modules for better TypeScript interoperability
- Updated exports to use ES6 `export` syntax instead of `module.exports`
- All types are now exported as named exports for better type inference and IDE support
- `OptionsSchema` is now a union to satisfy `SOURCEMAPS_OPTIONS`, as this one didn't had the required `param`
- The exports of `lib/releases/options` has changed its name

### Breaking Changes

**Module Exports**
- **Before**: `module.exports = SentryCli;` (CommonJS)
- **After**: `export class SentryCli { ... }` (ES6 named export)

We could have maintained backwards compatibility with `export = SentryCli;`. The only problem were the types which needed to be exported as well. With ES6 named exports, we can now export all types alongside the class.

### Internal Improvements

Simplified `Release` constructor
- **Before**: `new Releases({ ...this.options, configFile })` - configFile was merged into options
- **After**: `new Releases(this.options, configFile)` - two separate parameters

With 2 parameters it's easier to maintain and makes the separation of concerns clearer.
@szokeasaurusrex szokeasaurusrex force-pushed the jp/move-to-native-typescript branch from 3679dc2 to 0f60c1c Compare December 12, 2025 12:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v3.0 Breaking changes to include in version 3.0.0 of Sentry CLI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants