Skip to content

fix deprecation warnings in node 24#109

Open
ptandler wants to merge 21 commits into
deinsoftware:package-updatesfrom
ptandler:copilot/fix-deprecation-warnings-node24
Open

fix deprecation warnings in node 24#109
ptandler wants to merge 21 commits into
deinsoftware:package-updatesfrom
ptandler:copilot/fix-deprecation-warnings-node24

Conversation

@ptandler
Copy link
Copy Markdown

Closes #108

Copilot AI and others added 3 commits February 27, 2026 22:46
…ort via cmd /c

Co-authored-by: ptandler <934595+ptandler@users.noreply.github.com>
Co-authored-by: ptandler <934595+ptandler@users.noreply.github.com>
Comment thread src/helpers/cmds.ts Outdated
@equiman
Copy link
Copy Markdown
Member

equiman commented Apr 25, 2026

Have you tested these changes with previous Node.js versions? I'd like to confirm if they are backward compatible with older releases.

@equiman
Copy link
Copy Markdown
Member

equiman commented Apr 25, 2026

Hi! @ptandler

I’ve created a new branch including the required fixes and several package updates. You can find it here: https://github.com/deinsoftware/swpm/tree/package-updates

Please note that the recommended minimum version of Node.js for this branch is Node 20.

I would appreciate your help testing these changes. Please follow these steps:

  1. Switch to the branch:

    git fetch origin
    git checkout package-updates
    npm ci
  2. Uninstall the current global package:

    npm uninstall -g swpm
  3. Build and link the local version:
    From the project root, run:

    npm run build
    cd bin
    npm link

The swpm command will now be available for testing. Once you are finished, you can revert to the stable version by running this inside the bin folder:

npm unlink
npm install -g swpm

Please let me know if everything works as expected. If you encounter any errors, please provide any evidence or logs if possible.

Thanks for the help!

Reuse existing detectOs() from open.ts instead of maintaining
separate platform === 'win32' check in cmds.ts.
Add integration test that verifies swpm install works on all active
LTS node versions (18, 20, 22, 24). Versions are fetched dynamically
from nodejs.org API.

Create .tool-versions to pin current node version for the project.
Document findings from testing the upstream package-updates branch:
- detectOs refactor already included (improved version)
- Build and CLI commands work correctly
- 496/501 tests pass (5 timeout failures are environmental)
- Compatible with all active LTS Node versions (18, 20, 22, 24)
- Significant dependency updates (TypeScript 6, vitest 4, etc.)
- New swpm status command added
Set 120s per-test timeout since npm install under different node
versions can take longer than the default 5s, especially on first
run when mise needs to download and install the node binary.
…fix-deprecation-warnings-node24

# Conflicts:
#	package.json
#	src/helpers/cmds.ts
#	src/helpers/open.ts
@ptandler ptandler changed the base branch from main to package-updates April 30, 2026 12:39
@ptandler
Copy link
Copy Markdown
Author

Have you tested these changes with previous Node.js versions? I'd like to confirm if they are backward compatible with older releases.

I now tested with several node versions and did not detect any issue. I also created a test script for this src/node-versions.test.ts - which actually might be improved, but at least is does some basic checks. It uses the mise node version manager to test different node versions.

Comment thread package.json Outdated
Comment thread package-lock.json
Comment thread .tool-versions Outdated
Comment thread .editorconfig Outdated
Comment thread src/helpers/open.ts
spinnies.succeed(urlId)
exit(0)
} catch (error) {
await spinnies.fail(urlId)
Copy link
Copy Markdown
Member

@equiman equiman May 1, 2026

Choose a reason for hiding this comment

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

Should we keep the await on spinnies.fail(urlId)? I'm concerned that removing it might cause a race condition where the process exits before the failure state is fully rendered. Could you double-check if the UI still displays correctly before the termination?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

when committing, my sonar lint extension complained about this saying that spinnies.fail() does not return a Promise, so await has no effect and is misleading. Looking at the typing, sonar is right, so if the typing is correct, the await should not be necessary.

Comment thread src/helpers/open.ts
Comment thread src/helpers/open.ts Outdated
}
console.error(stripIndents`
${chalk.red.bold('Error')}: no compatible browser ${chalk.bold(`${!browserId ? browserId : ' '}`)}found.
${chalk.red.bold('Error')}: no compatible browser ${chalk.bold(`${browserId ?? ' '}`)}found.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The use of ?? is much cleaner than the previous ternary operator. However, if browserId is an empty string (""), it will skip the default space. Should we use browserId || ' ' instead to handle empty strings as well? Or are we certain browserId will only be null or undefined?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Ah, actually here I was a bit confused, as the original code ${!browserId ? browserId : ' '} would return the browserId if it is falsy. Not sure if this was intended.

And if the ID is an empty string, we have a space already before the ${}.

And now looking at the code once again, isn't `${!browserId ? browserId : ' '}` identical to !browserId ? browserId : ' '?

So maybe browserId || ' ' is a good choice 😄

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I looked at this part again: I actually assume that in case there is a browserId, that there should be a space appended, so I adjusted the code accordingly.

Comment thread src/node-versions.test.ts Outdated
@equiman
Copy link
Copy Markdown
Member

equiman commented May 1, 2026

@ptandler thanks a lot for your interest and all the help with these improvements! I've left a few comments to polish some details and ensure everything is solid. I'm looking forward to your feedback so we can merge these changes and release the official version as soon as possible. Great job

@ptandler
Copy link
Copy Markdown
Author

ptandler commented May 2, 2026

@ptandler thanks a lot for your interest and all the help with these improvements! I've left a few comments to polish some details and ensure everything is solid. I'm looking forward to your feedback so we can merge these changes and release the official version as soon as possible. Great job

Glad I can help 🙏

Feel free to adjust my suggestions as you prefer, so you don't need to wait until I respond ... which sometimes can take a bit ... ⏳ 😴

Comment thread src/helpers/open.ts
return version.includes('wsl') && version.includes('microsoft')
}

/** returns node platform and 'wsl' if running in wsl */
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the explanation. Following Clean Code principles, I'd prefer to remove these comments. The code should be self-explanatory enough that they aren't necessary. If the logic is too complex, let's look into refactoring it instead

Comment thread src/helpers/open.ts
/** returns node platform and 'wsl' if running in wsl */
export const detectOs = () => {
let os = platform().toLowerCase().replace(/\d/g, '')
let os = platform().toLowerCase().replaceAll(/\d/g, '')
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could you explain the reasoning behind switching from .replace(/\d/g, '') to .replaceAll(/\d/g, '')? Since the original regex already uses the global flag, both should behave the same way. Is there a specific benefit you're looking for?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

this was a recommendation from sonarlint and I try to fix issues that sonar mentions before committing:

Strings should use "replaceAll()" instead of "replace()" with global regex

typescript:S7781

This rule flags when String#replace() is used with a global regex pattern, or when String#replaceAll() is used with a global regex flag.

The String#replaceAll() method was introduced in ES2021 to provide a clearer and safer way to replace all occurrences of a pattern in a string.
When using String#replace() with a global regex, developers must remember to include the global flag (g) and properly escape special regex characters if the search pattern contains them. This can lead to bugs when special characters are not escaped correctly.
For example, if you want to replace all dots in a string, using string.replace(/./g, '') will actually replace all characters (since . matches any character in regex), not just literal dots. You would need string.replace(/./g, '') instead.
With String#replaceAll(), you can simply use string.replaceAll('.', '') which is both safer and more readable. The method name clearly indicates that all occurrences will be replaced.
When String#replaceAll() is used with a regex, the global flag is required, or a TypeError will be thrown.
What is the potential impact?
Using the wrong replacement method can lead to unexpected behavior:
Incorrect replacements when special regex characters are not properly escaped
Performance issues due to unnecessary regex compilation
Reduced code readability and maintainability
Potential security vulnerabilities if user input is used in regex patterns without proper escaping
How to fix?
Replace String#replace() with global regex with String#replaceAll() using a string literal when the pattern doesn’t need regex features.

@ptandler
Copy link
Copy Markdown
Author

@equiman you can have a look again now :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants