Skip to content

feat(tls.createSecureContext): introduce #156

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 33 commits into
base: main
Choose a base branch
from

Conversation

0hmX
Copy link

@0hmX 0hmX commented Aug 3, 2025

closes: #123

Copy link
Member

@AugustinMauroy AugustinMauroy left a comment

Choose a reason for hiding this comment

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

Minor thing

Copy link
Contributor

@brunocroh brunocroh left a comment

Choose a reason for hiding this comment

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

You did a great job on that, thank you for your awesome contribution!

I have some comments on a few points, feel free to share your opinion if you don't agree with something.

And just one more thing: could you please check if you ran node --run pre-commit? I think there are some Biome rules that aren't applied.

Copy link
Member

@AugustinMauroy AugustinMauroy left a comment

Choose a reason for hiding this comment

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

LGMT ! Thanks for you first contribution.
If you have any feedback about DX on this project let's me know. And if you have any feedback about codemod CLI/platform I'm going to transfer it to them

@AugustinMauroy AugustinMauroy requested a review from a team August 6, 2025 08:32
@AugustinMauroy
Copy link
Member

fro windows failing use https://nodejs.org/api/os.html#oseol instead of \n

@AugustinMauroy
Copy link
Member

we also have few utility you should use it to simplify

@brunocroh
Copy link
Contributor

I do not have a Windows machine to run the test, but I have updated as suggested, so could we give this another run cc: @AugustinMauroy @brunocroh

We have a CI to test these changes on Windows as well. Soon, a maintainer will enable it to run on your PR.

Copy link
Member

@JakobJingleheimer JakobJingleheimer left a comment

Choose a reason for hiding this comment

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

Thanks for this! I'll try to review the rest tonight.

@@ -0,0 +1,21 @@
schema_version: "1.0"
name: "@nodejs/crypto-create-credentials"
Copy link
Member

Choose a reason for hiding this comment

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

I think the name should be createCredentials-to-createSecureContext

Copy link
Contributor

Choose a reason for hiding this comment

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

Hey Jacob, I had a quick thought about naming:

In the other codemod-recipes, we’ve been using kebab case and lowercase, with the folder name and package.json matching.

I assumed this was because npm packages typically follow this convention and are case-insensitive. I was just thinking it might help avoid potential issues with OS differences (case-sensitive vs case-insensitive) and make it a bit easier for users to search for or use the codemod.

I’m still pretty new to the project, so there’s a good chance I might be missing some context, if this has already been discussed or decided, feel free to let me know. 🙂 Cheers!

I test it now, and codemod usage is case-sensitive

Screenshot 2025-08-11 at 16 47 30

Copy link
Member

Choose a reason for hiding this comment

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

oh, sure whatever. all minuscule is fine if something requires it. it was more about the $old-to-$new :)

Comment on lines 172 to 173
const newImportModule = 'node:tls';
const newImportFunction = 'createSecureContext';
Copy link
Member

Choose a reason for hiding this comment

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

Nit: these can be declared in the root scope to avoid re-declaring them each time (they're constant and immutable).

Copy link
Member

@JakobJingleheimer JakobJingleheimer left a comment

Choose a reason for hiding this comment

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

Looks like good test cases :)

Regarding cases handled, what about import expressions const { createCredentials } = await import('node:crypto') and variants like const createCredentials = (await import('node:crypto')).then((m) => m.createCredentials)?

I think that is needed in order to say the deprecation is handled.

endPos: statement.range().end.index,
insertedText: `${os.EOL}${newImportStatement}`,
};
localEdits.push(newEdit);
Copy link
Member

Choose a reason for hiding this comment

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

nit: why not just write the value of newEdit into push? localEdits.push({…}) `newEdits isn't used elsewhere and isn't complicated.

Copy link
Member

Choose a reason for hiding this comment

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

Not necessarily a blocker, but this file has a lot more code than I expected. There are basically 3 things that need handling, 2 of which are mostly the same:

1.1 an import statement
1.2 a require statement
2 createCredentialscreateSecureContext

1.1 & 1.2 the detection is different, but the transformation is the same (the only part changing is mostly irrespective of cjs vs esm). So I would expect something like this pseudo-code:

type findDepExpressions = (ast): {
  node: ASTNode,
  type: 'import-dynamic' | 'import-static' | 'require',
};

const depExpHandlers = {
  require(n: ASTNode) {
    depExpCommonHandler(n);
    // Require-specific bits like namespacing
    return updatedNode;
  },
  'import-dynamic'(n: ASTNode) {
    depExpCommonHandler(n);
    // Dynamic-specific bits like thenable namespacing
    return updatedNode;
  },
  'import-static'(n: ASTNode) {
    depExpCommonHandler(n);
    // Static-specific bits like namespacing
    return updatedNode;
  },
};

for (const dS of findDepExpressions(ast)) edits.push(
  depExpHandlers[ds.type](ds.node),
);

Copy link
Author

Choose a reason for hiding this comment

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

I am open to the idea, but this will cause a significant refactor

Copy link
Member

Choose a reason for hiding this comment

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

Not necessarily a blocker, but this file has a lot more code than I expected. There are basically 3 things that need handling, 2 of which are mostly the same:

Also it's because it's doesn't use any utility.

@0hmX what do you think about using our utility to reduce the amount of code here ?

Copy link
Member

Choose a reason for hiding this comment

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

Niiiice

@AugustinMauroy
Copy link
Member

Looks like good test cases :)

Regarding cases handled, what about import expressions const { createCredentials } = await import('node:crypto') and variants like const createCredentials = (await import('node:crypto')).then((m) => m.createCredentials)?

I think that is needed in order to say the deprecation is handled.

BTW any of our publish codemod support dynamic import

@JakobJingleheimer
Copy link
Member

BTW any of our publish codemod support dynamic import

Sorry, is that a question or a statement? (Do you mean "all of our published codemods support dynamic import"?)

@AugustinMauroy
Copy link
Member

BTW any of our publish codemod support dynamic import

Sorry, is that a question or a statement? (Do you mean "all of our published codemods support dynamic import"?)

It's a fact ! So do we want to support that in general ?

@0hmX
Copy link
Author

0hmX commented Aug 12, 2025

Regarding cases handled, what about import expressions const { createCredentials } = await import('node:crypto') and variants like const createCredentials = (await import('node:crypto')).then((m) => m.createCredentials)?

I did not know we were handling this. I will add a test case for it.

@0hmX 0hmX force-pushed the crypto-createCredentials branch from 24f755d to d057380 Compare August 14, 2025 17:17
@0hmX
Copy link
Author

0hmX commented Aug 14, 2025

Okay, so I ended up rewriting the code, but it's now bigger than the previous version🫠. Yes, I am using the utilities. I added a few more test cases related to pair_pattern and import_specifier.

However, I couldn't get the logic to work for const createCredentials = (await import('node:crypto')).then((m) => m.createCredentials) because the getNodeImportCalls utility does not handle this case. I want to skip it, as adding the extra code would make the file too large.

@JakobJingleheimer
Copy link
Member

Okay, so I ended up rewriting the code, but it's now bigger than the previous version🫠. Yes, I am using the utilities. I added a few more test cases related to pair_pattern and import_specifier.

However, I couldn't get the logic to work for const createCredentials = (await import('node:crypto')).then((m) => m.createCredentials) because the getNodeImportCalls utility does not handle this case. I want to skip it, as adding the extra code would make the file too large.

Thanks! I'm sure it was a fair amount of work 😅 (that's why I said it wasn't necessarily a blocker)

Unfortunately you force-pushed, which wipes the review history. That means the entire PR has to get reviewed again instead of just the pieces recently changed (and that massively increases the effort & time needed to review the latest changes). I've updated the repo settings to now block force-pushing to prevent this happening again (you weren't the only one to do it), but FYI the next review will take me some time to get through now because of that force-push 😬

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feat: handle crypto.createCredentials() depreciation
5 participants