diff --git a/package-lock.json b/package-lock.json index 0fa3862e..a59425a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -194,30 +194,30 @@ } }, "node_modules/@ast-grep/napi": { - "version": "0.39.7", - "resolved": "https://registry.npmjs.org/@ast-grep/napi/-/napi-0.39.7.tgz", - "integrity": "sha512-fkCG3cSc2LiLgUXCrx83uo+dxmoRTGXtc7xMxhLsjHt5JRyJcXznevg92yjEQlCusVm98WtT/urh3hh2/4NZVQ==", + "version": "0.39.9", + "resolved": "https://registry.npmjs.org/@ast-grep/napi/-/napi-0.39.9.tgz", + "integrity": "sha512-qtLLQq1a3isK0iaq0Drl7Qt4PqeyjTrpFxNdA/20O/jYkGiA/oJA8DLMn1bzczsfjlUohe4dg39bpeAqG02uvA==", "dev": true, "license": "MIT", "engines": { "node": ">= 10" }, "optionalDependencies": { - "@ast-grep/napi-darwin-arm64": "0.39.7", - "@ast-grep/napi-darwin-x64": "0.39.7", - "@ast-grep/napi-linux-arm64-gnu": "0.39.7", - "@ast-grep/napi-linux-arm64-musl": "0.39.7", - "@ast-grep/napi-linux-x64-gnu": "0.39.7", - "@ast-grep/napi-linux-x64-musl": "0.39.7", - "@ast-grep/napi-win32-arm64-msvc": "0.39.7", - "@ast-grep/napi-win32-ia32-msvc": "0.39.7", - "@ast-grep/napi-win32-x64-msvc": "0.39.7" + "@ast-grep/napi-darwin-arm64": "0.39.9", + "@ast-grep/napi-darwin-x64": "0.39.9", + "@ast-grep/napi-linux-arm64-gnu": "0.39.9", + "@ast-grep/napi-linux-arm64-musl": "0.39.9", + "@ast-grep/napi-linux-x64-gnu": "0.39.9", + "@ast-grep/napi-linux-x64-musl": "0.39.9", + "@ast-grep/napi-win32-arm64-msvc": "0.39.9", + "@ast-grep/napi-win32-ia32-msvc": "0.39.9", + "@ast-grep/napi-win32-x64-msvc": "0.39.9" } }, "node_modules/@ast-grep/napi-darwin-arm64": { - "version": "0.39.7", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-darwin-arm64/-/napi-darwin-arm64-0.39.7.tgz", - "integrity": "sha512-P02ZhbUOKq2wMwlswiWGfnsGDL1lzPSMCfqVnm9NuJoVtZ1IsEEncDcvQnJp997VQJ1MOlP3kzzCgZcpREBnfQ==", + "version": "0.39.9", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-darwin-arm64/-/napi-darwin-arm64-0.39.9.tgz", + "integrity": "sha512-0gdBC2oPBkIBsh89yUXxJeK37QYRbp1qNZVuRGizT666ljgCw+2NIxHeQGNjwWuI0+g3exrd8FyqD3gMixRx3w==", "cpu": [ "arm64" ], @@ -232,9 +232,9 @@ } }, "node_modules/@ast-grep/napi-darwin-x64": { - "version": "0.39.7", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-darwin-x64/-/napi-darwin-x64-0.39.7.tgz", - "integrity": "sha512-PXeMgv6RxVj06/8X9k2gljJf9rroCI9/MRmlEV9ktZkTtg9qjG6QKXiJ4AqDGem6i1Hm2H/2O1IMa6hAn8Uehw==", + "version": "0.39.9", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-darwin-x64/-/napi-darwin-x64-0.39.9.tgz", + "integrity": "sha512-7QuQNFwcVj71hDAMBErF+mVq2h92vUdHLKa/vq58HdRpix5G3DZqcTKoFjwhCNzc2wsNRAjV+BiIR01znQSxLA==", "cpu": [ "x64" ], @@ -249,9 +249,9 @@ } }, "node_modules/@ast-grep/napi-linux-arm64-gnu": { - "version": "0.39.7", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-arm64-gnu/-/napi-linux-arm64-gnu-0.39.7.tgz", - "integrity": "sha512-dTA10IoJPEQUVfOHrHUvpM0uEnhVatF90lY7OyRFbrgjqggiacjSmQUWxTOWmXNKt/jHZxLhlumXVd+W87VrOA==", + "version": "0.39.9", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-arm64-gnu/-/napi-linux-arm64-gnu-0.39.9.tgz", + "integrity": "sha512-qXTjhagRYkPyHNACEzGi5q26OMRdSvLRRqi799oZaSDf96Xj+8tcB5+tFlH0NpqaP84GsZoQ15SfDXeoP4qdmQ==", "cpu": [ "arm64" ], @@ -266,9 +266,9 @@ } }, "node_modules/@ast-grep/napi-linux-arm64-musl": { - "version": "0.39.7", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-arm64-musl/-/napi-linux-arm64-musl-0.39.7.tgz", - "integrity": "sha512-DAkLxVGZR5yrDCBNdPV+Eu0tKG3Zxm8Lhj1AQ2AOYFD6d/mbiTzufuyiXlqOJgmf53V5288j16JdxtcQJKJOtA==", + "version": "0.39.9", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-arm64-musl/-/napi-linux-arm64-musl-0.39.9.tgz", + "integrity": "sha512-U9KVohyburVGEWiiREFq+iTxdMdSbRyXL+yzCVvGPmLPW4Ca4zpX9Cret4jCJBp8dljSIK0C7txXAc7fM+6rag==", "cpu": [ "arm64" ], @@ -283,9 +283,9 @@ } }, "node_modules/@ast-grep/napi-linux-x64-gnu": { - "version": "0.39.7", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-x64-gnu/-/napi-linux-x64-gnu-0.39.7.tgz", - "integrity": "sha512-x0KKHwSqwinXEkSGOpb74HQ7v6paJPIssZhaJCO3ZPWe0U1VITqeHbukV85wpVz7VJPu5HztkKLIE7jVCRMHQw==", + "version": "0.39.9", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-x64-gnu/-/napi-linux-x64-gnu-0.39.9.tgz", + "integrity": "sha512-C5WwiNr/eE7lS0vl9bNdSXrsGIUAga2SaqV3G+ogVl9HeRU2jtGhv+3AgzGvYWj+PtnbtuZ2Nxkm10gEVPhv1A==", "cpu": [ "x64" ], @@ -300,9 +300,9 @@ } }, "node_modules/@ast-grep/napi-linux-x64-musl": { - "version": "0.39.7", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-x64-musl/-/napi-linux-x64-musl-0.39.7.tgz", - "integrity": "sha512-SXVWii/AWzME4HESkIvpm8yCqUdiGvwTAzq2f54PiL+12oodL3uFoA2ccpB5Vvq49e5C2OOeW0bkr8jzRure6A==", + "version": "0.39.9", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-x64-musl/-/napi-linux-x64-musl-0.39.9.tgz", + "integrity": "sha512-KutzZSMhHP3P43nQ+kNSbuiDaqkCcdqOcXLnq28MRvS+qwvW+01dJ8eWRlpMJC9vCJmaJAZfI7xkNSp74WkdxA==", "cpu": [ "x64" ], @@ -317,9 +317,9 @@ } }, "node_modules/@ast-grep/napi-win32-arm64-msvc": { - "version": "0.39.7", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-win32-arm64-msvc/-/napi-win32-arm64-msvc-0.39.7.tgz", - "integrity": "sha512-4w3wCgGOZADXnoS6zV9z2Qw2u+CxNSgjR7/6E69wb2dJ5nJOJXc2dingB3l1CZ2f1XOq5ag+PEtBINwvu0r2vA==", + "version": "0.39.9", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-win32-arm64-msvc/-/napi-win32-arm64-msvc-0.39.9.tgz", + "integrity": "sha512-S2kC6K9I7e70oMVn2FDICzVlz7SPZVWNCRKCBD+Dgy1OTn0byzmMLaGpjth3pqN93UCssEC03ooP3tuclS0JSA==", "cpu": [ "arm64" ], @@ -334,9 +334,9 @@ } }, "node_modules/@ast-grep/napi-win32-ia32-msvc": { - "version": "0.39.7", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-win32-ia32-msvc/-/napi-win32-ia32-msvc-0.39.7.tgz", - "integrity": "sha512-+CVjlvYbF4vYdltffG7dAmYAv4WBZPeBrsZfuXBe7+nNdM6MXrinT1uMX8nWKJMV8KA264xojlneyDsxSt2Ntw==", + "version": "0.39.9", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-win32-ia32-msvc/-/napi-win32-ia32-msvc-0.39.9.tgz", + "integrity": "sha512-n18Dqtc7O5q8ZM9gBNkvLd+ajdjLNraw4ZoIcHelI7TnTvh1m6zR3tUuHNxPhL+IJfdKx3ne7ATKlEeiSlMn4g==", "cpu": [ "ia32" ], @@ -351,9 +351,9 @@ } }, "node_modules/@ast-grep/napi-win32-x64-msvc": { - "version": "0.39.7", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-win32-x64-msvc/-/napi-win32-x64-msvc-0.39.7.tgz", - "integrity": "sha512-ZjfdsjcAmtg9TyTcTalqw9W+HyQH+C0Mx4rL6UieIEc2Z4tWqP/hTwOl9CJ4JPmRYsW6yKMIxjJPj9RF0mv4iA==", + "version": "0.39.9", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-win32-x64-msvc/-/napi-win32-x64-msvc-0.39.9.tgz", + "integrity": "sha512-YOF7mO+6nvyRtMC179u82Vr1qIGOmoE1yjwr4cmAf7DVNd+vs42y9tbQGYwLmVY8M3Hg1PviB8XX7FQKewuOGQ==", "cpu": [ "x64" ], @@ -1520,6 +1520,10 @@ "resolved": "recipes/node-url-to-whatwg-url", "link": true }, + "node_modules/@nodejs/process-assert-to-node-assert": { + "resolved": "recipes/process-assert-to-node-assert", + "link": true + }, "node_modules/@nodejs/process-main-module": { "resolved": "recipes/process-main-module", "link": true @@ -1772,6 +1776,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.0.tgz", "integrity": "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==", "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -1787,28 +1792,28 @@ } }, "node_modules/@typescript/native-preview": { - "version": "7.0.0-dev.20251104.1", - "resolved": "https://registry.npmjs.org/@typescript/native-preview/-/native-preview-7.0.0-dev.20251104.1.tgz", - "integrity": "sha512-jRyx4j67IHO5a512iE7LGT6wD5DgOmedG6nEQkMIRQGiwRnO3ntzk01PBpFXBoNwiBRfQk6PlFTcljkFQT5RbA==", + "version": "7.0.0-dev.20251107.1", + "resolved": "https://registry.npmjs.org/@typescript/native-preview/-/native-preview-7.0.0-dev.20251107.1.tgz", + "integrity": "sha512-oNrTZZIqZfxQKcKSNF6J/2V4URossXyIG63SZXixRMlXmhydjDxO/VgGxpgpTv6oMKpT/dJix1lvs2e3KX/0zQ==", "dev": true, "license": "Apache-2.0", "bin": { "tsgo": "bin/tsgo.js" }, "optionalDependencies": { - "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20251104.1", - "@typescript/native-preview-darwin-x64": "7.0.0-dev.20251104.1", - "@typescript/native-preview-linux-arm": "7.0.0-dev.20251104.1", - "@typescript/native-preview-linux-arm64": "7.0.0-dev.20251104.1", - "@typescript/native-preview-linux-x64": "7.0.0-dev.20251104.1", - "@typescript/native-preview-win32-arm64": "7.0.0-dev.20251104.1", - "@typescript/native-preview-win32-x64": "7.0.0-dev.20251104.1" + "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20251107.1", + "@typescript/native-preview-darwin-x64": "7.0.0-dev.20251107.1", + "@typescript/native-preview-linux-arm": "7.0.0-dev.20251107.1", + "@typescript/native-preview-linux-arm64": "7.0.0-dev.20251107.1", + "@typescript/native-preview-linux-x64": "7.0.0-dev.20251107.1", + "@typescript/native-preview-win32-arm64": "7.0.0-dev.20251107.1", + "@typescript/native-preview-win32-x64": "7.0.0-dev.20251107.1" } }, "node_modules/@typescript/native-preview-darwin-arm64": { - "version": "7.0.0-dev.20251104.1", - "resolved": "https://registry.npmjs.org/@typescript/native-preview-darwin-arm64/-/native-preview-darwin-arm64-7.0.0-dev.20251104.1.tgz", - "integrity": "sha512-4I/Xy2saFsrzfRhQ5H6gV2SwICvkS0PV5T+wWD0aKQTsffEFPtTBhUOTaTuzG1FpMMcdO5WC5qSUdIvqcIWD+Q==", + "version": "7.0.0-dev.20251107.1", + "resolved": "https://registry.npmjs.org/@typescript/native-preview-darwin-arm64/-/native-preview-darwin-arm64-7.0.0-dev.20251107.1.tgz", + "integrity": "sha512-+gb7AGD6sERUo3d0b4WYPNtJHHGxXiMKy7oVHxdN1dhhMhyhbpPbmL3lcS9ZK7z4/paJMpRzVoOOgIwTf3xY0g==", "cpu": [ "arm64" ], @@ -1820,9 +1825,9 @@ ] }, "node_modules/@typescript/native-preview-darwin-x64": { - "version": "7.0.0-dev.20251104.1", - "resolved": "https://registry.npmjs.org/@typescript/native-preview-darwin-x64/-/native-preview-darwin-x64-7.0.0-dev.20251104.1.tgz", - "integrity": "sha512-03ymJ3eg0z9soEmN0Mg8UZPqsG4TwAYPFQLvNT1D8+meGKgihsGgUb05bBYhnvaq0M3HcG7XUJac1molOTxUOA==", + "version": "7.0.0-dev.20251107.1", + "resolved": "https://registry.npmjs.org/@typescript/native-preview-darwin-x64/-/native-preview-darwin-x64-7.0.0-dev.20251107.1.tgz", + "integrity": "sha512-RyRbmdD3Bzglvc8TDr9PFd7O5HaFwiuY7pRMj3S+C2G1uWRVEndVxliHHK+G7kbgcO/oPnRZPV3q+l988OxSRg==", "cpu": [ "x64" ], @@ -1834,9 +1839,9 @@ ] }, "node_modules/@typescript/native-preview-linux-arm": { - "version": "7.0.0-dev.20251104.1", - "resolved": "https://registry.npmjs.org/@typescript/native-preview-linux-arm/-/native-preview-linux-arm-7.0.0-dev.20251104.1.tgz", - "integrity": "sha512-y+qu91VCz3bjI0m0d6hDCtmk+q2ToFd/Z3tjX1r8OyKgLQeetpdxpUrEZ+Y/uLZTfKXDfcv599IQI2Oma3vEiQ==", + "version": "7.0.0-dev.20251107.1", + "resolved": "https://registry.npmjs.org/@typescript/native-preview-linux-arm/-/native-preview-linux-arm-7.0.0-dev.20251107.1.tgz", + "integrity": "sha512-aCWp84B0VsgHOcZ6M8LmZuDFirVoqfOdB5l51h1onLqpNrui25I5g9D5COktdoB6BBWuYmnKjvIENo1EMUYZBg==", "cpu": [ "arm" ], @@ -1848,9 +1853,9 @@ ] }, "node_modules/@typescript/native-preview-linux-arm64": { - "version": "7.0.0-dev.20251104.1", - "resolved": "https://registry.npmjs.org/@typescript/native-preview-linux-arm64/-/native-preview-linux-arm64-7.0.0-dev.20251104.1.tgz", - "integrity": "sha512-UM1d8mqyGnkvP3Uvy1GDW+XBQM9Sgl7Up1vGUV0JempuXHPf9fhI8swSBBCyLVVTUAgzxp79q1EvM6ieTkm8VA==", + "version": "7.0.0-dev.20251107.1", + "resolved": "https://registry.npmjs.org/@typescript/native-preview-linux-arm64/-/native-preview-linux-arm64-7.0.0-dev.20251107.1.tgz", + "integrity": "sha512-9qGIKu0nvfk5jEpt1MS7vn8gYKPfkcPrm+bOUSpfinsKrQKSCI8rIx0Nn+IyP4aLpSrfIxd0hgOkuYJy7J2NzA==", "cpu": [ "arm64" ], @@ -1862,9 +1867,9 @@ ] }, "node_modules/@typescript/native-preview-linux-x64": { - "version": "7.0.0-dev.20251104.1", - "resolved": "https://registry.npmjs.org/@typescript/native-preview-linux-x64/-/native-preview-linux-x64-7.0.0-dev.20251104.1.tgz", - "integrity": "sha512-TJ2Xh+isYw49Yi/c5vffQROjUHf2UsiSX7VB+Vh3ywVhOC9mEnLGS9L3D5UZguAMiotz1BoqU66GqEge/lbI1A==", + "version": "7.0.0-dev.20251107.1", + "resolved": "https://registry.npmjs.org/@typescript/native-preview-linux-x64/-/native-preview-linux-x64-7.0.0-dev.20251107.1.tgz", + "integrity": "sha512-3KgYypYr6brGvKstYgDvfuksF7SQTYDoaL3gD7F0VwRtDw9ttMAq7lm66h4FwH/H1aK1mNj8Unua4yI6rQkXSA==", "cpu": [ "x64" ], @@ -1876,9 +1881,9 @@ ] }, "node_modules/@typescript/native-preview-win32-arm64": { - "version": "7.0.0-dev.20251104.1", - "resolved": "https://registry.npmjs.org/@typescript/native-preview-win32-arm64/-/native-preview-win32-arm64-7.0.0-dev.20251104.1.tgz", - "integrity": "sha512-DonN+wVOTeIwE72idHOqC2eXJ8pkpNI4DWAwA1DmepFI6TXeWln8yKEyak8yjguPVvvCrJEKvx4q26CVXfWThA==", + "version": "7.0.0-dev.20251107.1", + "resolved": "https://registry.npmjs.org/@typescript/native-preview-win32-arm64/-/native-preview-win32-arm64-7.0.0-dev.20251107.1.tgz", + "integrity": "sha512-oT9mY4huqEEG0zvwl68tlnKjv+7v59uH32FXT6ZHQtT6XOvHV2DZfdcouoAS035pnempXkXLIDJnnqRrSMQa8Q==", "cpu": [ "arm64" ], @@ -1890,9 +1895,9 @@ ] }, "node_modules/@typescript/native-preview-win32-x64": { - "version": "7.0.0-dev.20251104.1", - "resolved": "https://registry.npmjs.org/@typescript/native-preview-win32-x64/-/native-preview-win32-x64-7.0.0-dev.20251104.1.tgz", - "integrity": "sha512-kMhr8pCKcNBEl5+6q71MkBxMCukJNWQAg4WKsDDfrO5ImhAanHGkNfVD6g0nAPbRP3MjuXo1o4KwPdxyfHXUmg==", + "version": "7.0.0-dev.20251107.1", + "resolved": "https://registry.npmjs.org/@typescript/native-preview-win32-x64/-/native-preview-win32-x64-7.0.0-dev.20251107.1.tgz", + "integrity": "sha512-vXnu3tY2/5Zu1CzFaATZnzYijLt0mIxWNd12MDFFfk/5JcEBLHSibvnXinalyXviNbnfJIG8+gdbKrlbR3p89w==", "cpu": [ "x64" ], @@ -2025,9 +2030,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.8.24", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.24.tgz", - "integrity": "sha512-uUhTRDPXamakPyghwrUcjaGvvBqGrWvBHReoiULMIpOJVM9IYzQh83Xk2Onx5HlGI2o10NNCzcs9TG/S3TkwrQ==", + "version": "2.8.25", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.25.tgz", + "integrity": "sha512-2NovHVesVF5TXefsGX1yzx1xgr7+m9JQenvz6FQY3qd+YXkKkYiv+vTCc7OriP9mcDZpTC5mAOYN4ocd29+erA==", "license": "Apache-2.0", "bin": { "baseline-browser-mapping": "dist/cli.js" @@ -2149,9 +2154,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001753", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001753.tgz", - "integrity": "sha512-Bj5H35MD/ebaOV4iDLqPEtiliTN29qkGtEHCwawWn4cYm+bPJM2NsaP30vtZcnERClMzp52J4+aw2UNbK4o+zw==", + "version": "1.0.30001754", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001754.tgz", + "integrity": "sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==", "funding": [ { "type": "opencollective", @@ -2470,9 +2475,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.244", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.244.tgz", - "integrity": "sha512-OszpBN7xZX4vWMPJwB9illkN/znA8M36GQqQxi6MNy9axWxhOfJyZZJtSLQCpEFLHP2xK33BiWx9aIuIEXVCcw==", + "version": "1.5.248", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.248.tgz", + "integrity": "sha512-zsur2yunphlyAO4gIubdJEXCK6KOVvtpiuDfCIqbM9FjcnMYiyn0ICa3hWfPr0nc41zcLWobgy1iL7VvoOyA2Q==", "license": "ISC" }, "node_modules/emoji-regex": { @@ -2635,9 +2640,9 @@ } }, "node_modules/flow-parser": { - "version": "0.289.0", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.289.0.tgz", - "integrity": "sha512-w4sVnH6ddNAIxokoz0mGyiIIdzvqncFhAYW+RmkPbPSSTYozG6yhqAixzaWeBCQf2qqXJTlHkoKPnf/BAj8Ofw==", + "version": "0.290.0", + "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.290.0.tgz", + "integrity": "sha512-9qXeNyrHPIoRK23kX7HNp275RYMy2y1AWb37y86ZTH/2UvfrofBis18aBunzfTIXkRpeD0F/w/uAKFhLUpboqQ==", "license": "MIT", "engines": { "node": ">=0.4.0" @@ -4376,6 +4381,17 @@ "@codemod.com/jssg-types": "^1.0.3" } }, + "recipes/process-assert-to-node-assert": { + "name": "@nodejs/process-assert-to-node-assert", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@nodejs/codemod-utils": "*" + }, + "devDependencies": { + "@codemod.com/jssg-types": "^1.0.3" + } + }, "recipes/process-main-module": { "name": "@nodejs/process-main-module", "version": "1.0.1", diff --git a/recipes/process-assert-to-node-assert/README.md b/recipes/process-assert-to-node-assert/README.md new file mode 100644 index 00000000..cae74613 --- /dev/null +++ b/recipes/process-assert-to-node-assert/README.md @@ -0,0 +1,24 @@ +# `process.assert` to `node:assert` DEP0100 + +This recipe transforms the usage of `process.assert` to use `node:assert` module. + +See [DEP0100](https://nodejs.org/api/deprecations.html#DEP0100). + +## Example + +**Before:** + +```js +process.assert(condition, "Assertion failed"); +``` + +**After:** + +```js +import assert from "node:assert"; +assert(condition, "Assertion failed"); +``` + +## Additional Notes + +This codemod use [`fs` capability](https://docs.codemod.com/jssg/security) to read the `package.json` file and determine if the project is using ES modules or CommonJS. Based on this information, it adds the appropriate import statement for the `assert` module. diff --git a/recipes/process-assert-to-node-assert/codemod.yaml b/recipes/process-assert-to-node-assert/codemod.yaml new file mode 100644 index 00000000..ff21d993 --- /dev/null +++ b/recipes/process-assert-to-node-assert/codemod.yaml @@ -0,0 +1,25 @@ +schema_version: "1.0" +name: "@nodejs/process-assert-to-node-assert" +version: 1.0.0 +description: Handle DEP0100 via transforming `process.assert` to `node:assert`. +author: matheusmorett2 +license: MIT +workflow: workflow.yaml +category: migration + +targets: + languages: + - javascript + - typescript + +keywords: + - transformation + - migration + +registry: + access: public + visibility: public + +# https://docs.codemod.com/jssg/security#enabling-capabilities +capabilities: + - fs diff --git a/recipes/process-assert-to-node-assert/package.json b/recipes/process-assert-to-node-assert/package.json new file mode 100644 index 00000000..7d6999e0 --- /dev/null +++ b/recipes/process-assert-to-node-assert/package.json @@ -0,0 +1,24 @@ +{ + "name": "@nodejs/process-assert-to-node-assert", + "version": "1.0.0", + "description": "Handle DEP0100 via transforming `process.assert` to `node:assert`.", + "type": "module", + "scripts": { + "test": "npx codemod jssg test -l typescript --ignore-whitespace ./src/workflow.ts ./" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/nodejs/userland-migrations.git", + "directory": "recipes/process-assert-to-node-assert", + "bugs": "https://github.com/nodejs/userland-migrations/issues" + }, + "author": "matheusmorett2", + "license": "MIT", + "homepage": "https://github.com/nodejs/userland-migrations/blob/main/recipes/process-assert-to-node-assert/README.md", + "devDependencies": { + "@codemod.com/jssg-types": "^1.0.3" + }, + "dependencies": { + "@nodejs/codemod-utils": "*" + } +} diff --git a/recipes/process-assert-to-node-assert/src/workflow.ts b/recipes/process-assert-to-node-assert/src/workflow.ts new file mode 100644 index 00000000..14322159 --- /dev/null +++ b/recipes/process-assert-to-node-assert/src/workflow.ts @@ -0,0 +1,230 @@ +import { EOL } from 'node:os'; +import { readFileSync } from 'node:fs'; +import { join } from 'node:path'; +import { getNodeRequireCalls } from '@nodejs/codemod-utils/ast-grep/require-call'; +import { getNodeImportStatements } from '@nodejs/codemod-utils/ast-grep/import-statement'; +import { resolveBindingPath } from '@nodejs/codemod-utils/ast-grep/resolve-binding-path'; +import { removeBinding } from '@nodejs/codemod-utils/ast-grep/remove-binding'; +import { removeLines } from '@nodejs/codemod-utils/ast-grep/remove-lines'; +import type { + Edit, + Range, + Rule, + SgNode, + SgRoot, +} from '@codemod.com/jssg-types/main'; +import type JS from '@codemod.com/jssg-types/langs/javascript'; + +type ReplaceRule = { + importNode?: SgNode; + binding?: string; + rule: Rule; + replaceWith?: string; +}; + +/** + * Transform function that converts deprecated `process.assert` usage to the `node:assert` module. + * + * Handles: + * 1. Replaces `process.assert(...)` member expressions/calls with `assert(...)` or `assert.xxx` as appropriate. + * 2. Handles cases where `process` is imported/required under a different binding (resolves binding paths). + * 3. Removes the original `process` import/require when it's only used for `assert` and removes the import line when empty. + * 4. Adds `import assert from "node:assert";` or `const assert = require("node:assert");` at the top + * when the file does not already import/require `assert`. + * + * Steps: + * - Find all `process` import/require statements and resolve any binding for `assert`. + * - Replace call and member-expression usages that reference `process.assert` (or the resolved binding) with `assert`. + * - Remove or update the original import/require for `process` when it's no longer needed. + * - If `assert` is not already present, insert the appropriate `import` or `require` line depending on the module style. + * + * @param root - The AST root node provided by jssg for the file being transformed. + * @returns The transformed source code as a string, or `null` when no edits are required. + */ +export default function transform(root: SgRoot): string | null { + const rootNode = root.root(); + const edits: Edit[] = []; + const linesToRemove: Range[] = []; + const replaceRules: ReplaceRule[] = [ + { + rule: { + kind: 'member_expression', + pattern: 'process.assert', + }, + replaceWith: 'assert', + }, + ]; + + const processImportsToRemove = new Set>(); + + const requireCalls = getNodeRequireCalls(root, 'process'); + const importStatements = getNodeImportStatements(root, 'process'); + const allImports = [...requireCalls, ...importStatements]; + const processUsages = rootNode.findAll({ + rule: { + kind: 'member_expression', + has: { + kind: 'identifier', + pattern: 'process', + }, + }, + }); + + for (const processImport of allImports) { + const binding = resolveBindingPath(processImport, '$.assert'); + + if (binding) { + // Handle member expressions like nodeAssert.strictEqual + replaceRules.push({ + importNode: processImport, + binding, + rule: { + kind: 'member_expression', + has: { + kind: binding.includes('.') ? 'member_expression' : 'identifier', + pattern: binding, + }, + }, + replaceWith: 'assert', + }); + + // Handle standalone calls like nodeAssert(...) + replaceRules.push({ + importNode: processImport, + binding, + rule: { + kind: 'call_expression', + has: { + kind: 'identifier', + field: 'function', + pattern: binding, + }, + }, + replaceWith: 'assert', + }); + } + + let hasNonAssertUsage = false; + for (const usage of processUsages) { + const propertyNode = usage.field('property'); + if (propertyNode && propertyNode.text() !== 'assert') { + hasNonAssertUsage = true; + break; + } + } + + if (!hasNonAssertUsage && processUsages.length > 0) { + processImportsToRemove.add(processImport); + linesToRemove.push(processImport.range()); + } + } + + const processedImports = new Set>(); + + for (const replaceRule of replaceRules) { + const nodes = rootNode.findAll({ + rule: replaceRule.rule, + }); + + for (const node of nodes) { + if ( + replaceRule.importNode && + !processedImports.has(replaceRule.importNode) + ) { + if (!processImportsToRemove.has(replaceRule.importNode)) { + const removeBind = removeBinding( + replaceRule.importNode, + replaceRule.binding, + ); + + if (removeBind.edit) { + edits.push(removeBind.edit); + } + + if (removeBind.lineToRemove) { + linesToRemove.push(removeBind.lineToRemove); + } + } + processedImports.add(replaceRule.importNode); + } + + if ( + replaceRule.rule.kind === 'member_expression' && + replaceRule.binding + ) { + // Replace the object part of member expressions (e.g., nodeAssert.strictEqual -> assert.strictEqual) + const objectNode = node.field('object'); + + if (objectNode) { + edits.push(objectNode.replace('assert')); + } + } else if ( + replaceRule.rule.kind === 'call_expression' && + replaceRule.binding + ) { + // Replace the function identifier in call expressions (e.g., nodeAssert(...) -> assert(...)) + const functionNode = node.field('function'); + + if (functionNode) { + edits.push(functionNode.replace('assert')); + } + } else { + const replaceText = replaceRule.replaceWith || 'assert'; + edits.push(node.replace(replaceText)); + } + } + } + + let sourceCode = rootNode.commitEdits(edits); + + sourceCode = removeLines(sourceCode, linesToRemove); + + if (edits.length === 0 && linesToRemove) return sourceCode; + + const alreadyRequiringAssert = getNodeRequireCalls(root, 'assert'); + const alreadyImportingAssert = getNodeImportStatements(root, 'assert'); + + if (alreadyRequiringAssert.length || alreadyImportingAssert.length) + return sourceCode; + + const usingRequire = rootNode.find({ + rule: { + kind: 'call_expression', + has: { + kind: 'identifier', + field: 'function', + regex: 'require', + }, + }, + }); + const usingImport = rootNode.find({ + rule: { + kind: 'import_statement', + }, + }); + const filename = root.filename(); + const isCjsFile = filename.endsWith('.cjs'); + const isMjsFile = filename.endsWith('.mjs'); + + // Prefer adding an ES module import when the file already uses ESM syntax + // (contains `import` statements) or is an `.mjs` file. This avoids injecting a + // CommonJS `require` into an ES module source (even if the file references + // `createRequire`). + if (usingImport || isMjsFile) { + return `import assert from "node:assert";${EOL}${sourceCode}`; + } + + if (usingRequire || isCjsFile) { + return `const assert = require("node:assert");${EOL}${sourceCode}`; + } + + const packageJsonPath = join(process.cwd(), 'package.json'); + const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8')); + const isEsm = packageJson.type === 'module'; + + if (isEsm) { + return `import assert from "node:assert";${EOL}${sourceCode}`; + } + + return `const assert = require("node:assert");${EOL}${sourceCode}`; +} diff --git a/recipes/process-assert-to-node-assert/tests/expected/01-basic-global-process-assert.js b/recipes/process-assert-to-node-assert/tests/expected/01-basic-global-process-assert.js new file mode 100644 index 00000000..08f8977f --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/expected/01-basic-global-process-assert.js @@ -0,0 +1,3 @@ +import assert from "node:assert"; +assert(condition, "Basic assertion"); +assert.strictEqual(a, b, "Values should be equal"); diff --git a/recipes/process-assert-to-node-assert/tests/expected/02-basic-commonjs.cjs b/recipes/process-assert-to-node-assert/tests/expected/02-basic-commonjs.cjs new file mode 100644 index 00000000..3ae76b87 --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/expected/02-basic-commonjs.cjs @@ -0,0 +1,3 @@ +const assert = require("node:assert"); +assert(condition, "Basic assertion"); +assert.strictEqual(a, b, "Values should be equal"); diff --git a/recipes/process-assert-to-node-assert/tests/expected/03-esm-import-process.mjs b/recipes/process-assert-to-node-assert/tests/expected/03-esm-import-process.mjs new file mode 100644 index 00000000..18f54fdb --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/expected/03-esm-import-process.mjs @@ -0,0 +1,3 @@ +import assert from "node:assert"; +assert(value, "Process assertion"); +assert.strictEqual(obj1, obj2); diff --git a/recipes/process-assert-to-node-assert/tests/expected/04-mixed-process-usage.js b/recipes/process-assert-to-node-assert/tests/expected/04-mixed-process-usage.js new file mode 100644 index 00000000..4d46b15f --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/expected/04-mixed-process-usage.js @@ -0,0 +1,5 @@ +import assert from "node:assert"; +import process from "node:process"; +assert(value, "Process assertion"); +process.env.NODE_ENV = "test"; +console.log(process.pid); diff --git a/recipes/process-assert-to-node-assert/tests/expected/05-require-process.js b/recipes/process-assert-to-node-assert/tests/expected/05-require-process.js new file mode 100644 index 00000000..e54c017d --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/expected/05-require-process.js @@ -0,0 +1,3 @@ +const assert = require("node:assert"); +assert(value, "Process assertion"); +assert.throws(() => { throw new Error(); }); diff --git a/recipes/process-assert-to-node-assert/tests/expected/06-destructured-assert-only.js b/recipes/process-assert-to-node-assert/tests/expected/06-destructured-assert-only.js new file mode 100644 index 00000000..24569401 --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/expected/06-destructured-assert-only.js @@ -0,0 +1,3 @@ +import assert from "node:assert"; +assert(condition, "Assertion from destructured import"); +assert.throws(() => { throw new Error("test"); }); diff --git a/recipes/process-assert-to-node-assert/tests/expected/07-destructured-mixed-bindings.js b/recipes/process-assert-to-node-assert/tests/expected/07-destructured-mixed-bindings.js new file mode 100644 index 00000000..0aff0c40 --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/expected/07-destructured-mixed-bindings.js @@ -0,0 +1,4 @@ +import assert from "node:assert"; +import { env } from "node:process"; +assert(value, "Using destructured assert"); +console.log(env.NODE_ENV); diff --git a/recipes/process-assert-to-node-assert/tests/expected/08-aliased-destructured-assert.js b/recipes/process-assert-to-node-assert/tests/expected/08-aliased-destructured-assert.js new file mode 100644 index 00000000..cf8634e6 --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/expected/08-aliased-destructured-assert.js @@ -0,0 +1,3 @@ +import assert from "node:assert"; +assert(value, "Using aliased assert"); +assert.notStrictEqual(a, b); diff --git a/recipes/process-assert-to-node-assert/tests/expected/09-aliased-destructured-mixed.js b/recipes/process-assert-to-node-assert/tests/expected/09-aliased-destructured-mixed.js new file mode 100644 index 00000000..e1b0edd5 --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/expected/09-aliased-destructured-mixed.js @@ -0,0 +1,5 @@ +import assert from "node:assert"; +import { env } from "node:process"; +assert(value, "Using aliased assert"); +assert.strictEqual(a, b); +console.log(env.NODE_ENV); diff --git a/recipes/process-assert-to-node-assert/tests/expected/10-require-destructured.js b/recipes/process-assert-to-node-assert/tests/expected/10-require-destructured.js new file mode 100644 index 00000000..78b4324f --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/expected/10-require-destructured.js @@ -0,0 +1,3 @@ +const assert = require("node:assert"); +assert(value, "Destructured assert from require"); +assert.strictEqual(a, b, "Should be equal"); diff --git a/recipes/process-assert-to-node-assert/tests/expected/11-already-has-assert-import.js b/recipes/process-assert-to-node-assert/tests/expected/11-already-has-assert-import.js new file mode 100644 index 00000000..db459c1a --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/expected/11-already-has-assert-import.js @@ -0,0 +1,3 @@ +import assert from "node:assert"; +assert(value, "This should be transformed"); +assert.strictEqual(a, b, "This should remain unchanged"); diff --git a/recipes/process-assert-to-node-assert/tests/expected/12-already-has-assert-require.js b/recipes/process-assert-to-node-assert/tests/expected/12-already-has-assert-require.js new file mode 100644 index 00000000..a0f7c1b4 --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/expected/12-already-has-assert-require.js @@ -0,0 +1,3 @@ +const assert = require("node:assert"); +assert(value, "This should be transformed"); +assert.strictEqual(a, b, "This should remain unchanged"); diff --git a/recipes/process-assert-to-node-assert/tests/expected/13-no-process-assert.js b/recipes/process-assert-to-node-assert/tests/expected/13-no-process-assert.js new file mode 100644 index 00000000..d7717c73 --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/expected/13-no-process-assert.js @@ -0,0 +1,6 @@ +const config = { + port: 3000, + host: "localhost" +}; + +console.log("Server config:", config); diff --git a/recipes/process-assert-to-node-assert/tests/expected/14-nested-in-function.js b/recipes/process-assert-to-node-assert/tests/expected/14-nested-in-function.js new file mode 100644 index 00000000..92d74048 --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/expected/14-nested-in-function.js @@ -0,0 +1,10 @@ +import assert from "node:assert"; +function testFunction() { + assert(condition, "Assertion inside function"); + + if (someCondition) { + assert.deepStrictEqual(obj1, obj2, "Deep comparison"); + } + + return assert.ok(value) && true; +} diff --git a/recipes/process-assert-to-node-assert/tests/expected/15-multiple-assert-methods.js b/recipes/process-assert-to-node-assert/tests/expected/15-multiple-assert-methods.js new file mode 100644 index 00000000..5db73614 --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/expected/15-multiple-assert-methods.js @@ -0,0 +1,6 @@ +import assert from "node:assert"; +assert(condition); +assert.ok(value); +assert.strictEqual(a, b); +assert.notStrictEqual(a, c); +assert.throws(() => { throw new Error(); }); diff --git a/recipes/process-assert-to-node-assert/tests/expected/16-mixed-require-and-assert.js b/recipes/process-assert-to-node-assert/tests/expected/16-mixed-require-and-assert.js new file mode 100644 index 00000000..e0389c84 --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/expected/16-mixed-require-and-assert.js @@ -0,0 +1,9 @@ +const assert = require("node:assert"); +const fs = require("fs"); + +function readConfig(path) { + assert(fs.existsSync(path), "Config file must exist"); + const data = fs.readFileSync(path, "utf8"); + assert.ok(data.length > 0, "Config file cannot be empty"); + return JSON.parse(data); +} diff --git a/recipes/process-assert-to-node-assert/tests/expected/17-complex-nested-class.js b/recipes/process-assert-to-node-assert/tests/expected/17-complex-nested-class.js new file mode 100644 index 00000000..1cd40c48 --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/expected/17-complex-nested-class.js @@ -0,0 +1,19 @@ +import assert from "node:assert"; +class Validator { + static validate(data) { + assert(data, "Data is required"); + + try { + assert.strictEqual(typeof data, "object", "Data must be object"); + } catch (error) { + assert.fail("Validation failed"); + } + + const results = [1, 2, 3].map(item => { + assert.ok(item > 0, "Item must be positive"); + return item * 2; + }); + + return results; + } +} diff --git a/recipes/process-assert-to-node-assert/tests/input/01-basic-global-process-assert.js b/recipes/process-assert-to-node-assert/tests/input/01-basic-global-process-assert.js new file mode 100644 index 00000000..f96e309c --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/input/01-basic-global-process-assert.js @@ -0,0 +1,2 @@ +process.assert(condition, "Basic assertion"); +process.assert.strictEqual(a, b, "Values should be equal"); diff --git a/recipes/process-assert-to-node-assert/tests/input/02-basic-commonjs.cjs b/recipes/process-assert-to-node-assert/tests/input/02-basic-commonjs.cjs new file mode 100644 index 00000000..f96e309c --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/input/02-basic-commonjs.cjs @@ -0,0 +1,2 @@ +process.assert(condition, "Basic assertion"); +process.assert.strictEqual(a, b, "Values should be equal"); diff --git a/recipes/process-assert-to-node-assert/tests/input/03-esm-import-process.mjs b/recipes/process-assert-to-node-assert/tests/input/03-esm-import-process.mjs new file mode 100644 index 00000000..8137a947 --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/input/03-esm-import-process.mjs @@ -0,0 +1,3 @@ +import process from "node:process"; +process.assert(value, "Process assertion"); +process.assert.strictEqual(obj1, obj2); diff --git a/recipes/process-assert-to-node-assert/tests/input/04-mixed-process-usage.js b/recipes/process-assert-to-node-assert/tests/input/04-mixed-process-usage.js new file mode 100644 index 00000000..4c0286f3 --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/input/04-mixed-process-usage.js @@ -0,0 +1,4 @@ +import process from "node:process"; +process.assert(value, "Process assertion"); +process.env.NODE_ENV = "test"; +console.log(process.pid); diff --git a/recipes/process-assert-to-node-assert/tests/input/05-require-process.js b/recipes/process-assert-to-node-assert/tests/input/05-require-process.js new file mode 100644 index 00000000..8467b5b4 --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/input/05-require-process.js @@ -0,0 +1,3 @@ +const process = require("node:process"); +process.assert(value, "Process assertion"); +process.assert.throws(() => { throw new Error(); }); diff --git a/recipes/process-assert-to-node-assert/tests/input/06-destructured-assert-only.js b/recipes/process-assert-to-node-assert/tests/input/06-destructured-assert-only.js new file mode 100644 index 00000000..bfd159da --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/input/06-destructured-assert-only.js @@ -0,0 +1,3 @@ +import { assert } from "node:process"; +assert(condition, "Assertion from destructured import"); +assert.throws(() => { throw new Error("test"); }); diff --git a/recipes/process-assert-to-node-assert/tests/input/07-destructured-mixed-bindings.js b/recipes/process-assert-to-node-assert/tests/input/07-destructured-mixed-bindings.js new file mode 100644 index 00000000..dcb14937 --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/input/07-destructured-mixed-bindings.js @@ -0,0 +1,3 @@ +import { assert, env } from "node:process"; +assert(value, "Using destructured assert"); +console.log(env.NODE_ENV); diff --git a/recipes/process-assert-to-node-assert/tests/input/08-aliased-destructured-assert.js b/recipes/process-assert-to-node-assert/tests/input/08-aliased-destructured-assert.js new file mode 100644 index 00000000..3fe72101 --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/input/08-aliased-destructured-assert.js @@ -0,0 +1,3 @@ +import { assert as nodeAssert } from "node:process"; +nodeAssert(value, "Using aliased assert"); +nodeAssert.notStrictEqual(a, b); diff --git a/recipes/process-assert-to-node-assert/tests/input/09-aliased-destructured-mixed.js b/recipes/process-assert-to-node-assert/tests/input/09-aliased-destructured-mixed.js new file mode 100644 index 00000000..ee1ad631 --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/input/09-aliased-destructured-mixed.js @@ -0,0 +1,4 @@ +import { assert as nodeAssert, env } from "node:process"; +nodeAssert(value, "Using aliased assert"); +nodeAssert.strictEqual(a, b); +console.log(env.NODE_ENV); diff --git a/recipes/process-assert-to-node-assert/tests/input/10-require-destructured.js b/recipes/process-assert-to-node-assert/tests/input/10-require-destructured.js new file mode 100644 index 00000000..aeda6e77 --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/input/10-require-destructured.js @@ -0,0 +1,3 @@ +const { assert } = require("node:process"); +assert(value, "Destructured assert from require"); +assert.strictEqual(a, b, "Should be equal"); diff --git a/recipes/process-assert-to-node-assert/tests/input/11-already-has-assert-import.js b/recipes/process-assert-to-node-assert/tests/input/11-already-has-assert-import.js new file mode 100644 index 00000000..f1c2bd59 --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/input/11-already-has-assert-import.js @@ -0,0 +1,3 @@ +import assert from "node:assert"; +process.assert(value, "This should be transformed"); +assert.strictEqual(a, b, "This should remain unchanged"); diff --git a/recipes/process-assert-to-node-assert/tests/input/12-already-has-assert-require.js b/recipes/process-assert-to-node-assert/tests/input/12-already-has-assert-require.js new file mode 100644 index 00000000..3d98a928 --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/input/12-already-has-assert-require.js @@ -0,0 +1,3 @@ +const assert = require("node:assert"); +process.assert(value, "This should be transformed"); +assert.strictEqual(a, b, "This should remain unchanged"); diff --git a/recipes/process-assert-to-node-assert/tests/input/13-no-process-assert.js b/recipes/process-assert-to-node-assert/tests/input/13-no-process-assert.js new file mode 100644 index 00000000..d7717c73 --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/input/13-no-process-assert.js @@ -0,0 +1,6 @@ +const config = { + port: 3000, + host: "localhost" +}; + +console.log("Server config:", config); diff --git a/recipes/process-assert-to-node-assert/tests/input/14-nested-in-function.js b/recipes/process-assert-to-node-assert/tests/input/14-nested-in-function.js new file mode 100644 index 00000000..336d1695 --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/input/14-nested-in-function.js @@ -0,0 +1,9 @@ +function testFunction() { + process.assert(condition, "Assertion inside function"); + + if (someCondition) { + process.assert.deepStrictEqual(obj1, obj2, "Deep comparison"); + } + + return process.assert.ok(value) && true; +} diff --git a/recipes/process-assert-to-node-assert/tests/input/15-multiple-assert-methods.js b/recipes/process-assert-to-node-assert/tests/input/15-multiple-assert-methods.js new file mode 100644 index 00000000..086caef7 --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/input/15-multiple-assert-methods.js @@ -0,0 +1,5 @@ +process.assert(condition); +process.assert.ok(value); +process.assert.strictEqual(a, b); +process.assert.notStrictEqual(a, c); +process.assert.throws(() => { throw new Error(); }); diff --git a/recipes/process-assert-to-node-assert/tests/input/16-mixed-require-and-assert.js b/recipes/process-assert-to-node-assert/tests/input/16-mixed-require-and-assert.js new file mode 100644 index 00000000..34229dbf --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/input/16-mixed-require-and-assert.js @@ -0,0 +1,8 @@ +const fs = require("fs"); + +function readConfig(path) { + process.assert(fs.existsSync(path), "Config file must exist"); + const data = fs.readFileSync(path, "utf8"); + process.assert.ok(data.length > 0, "Config file cannot be empty"); + return JSON.parse(data); +} diff --git a/recipes/process-assert-to-node-assert/tests/input/17-complex-nested-class.js b/recipes/process-assert-to-node-assert/tests/input/17-complex-nested-class.js new file mode 100644 index 00000000..7306d2e7 --- /dev/null +++ b/recipes/process-assert-to-node-assert/tests/input/17-complex-nested-class.js @@ -0,0 +1,18 @@ +class Validator { + static validate(data) { + process.assert(data, "Data is required"); + + try { + process.assert.strictEqual(typeof data, "object", "Data must be object"); + } catch (error) { + process.assert.fail("Validation failed"); + } + + const results = [1, 2, 3].map(item => { + process.assert.ok(item > 0, "Item must be positive"); + return item * 2; + }); + + return results; + } +} diff --git a/recipes/process-assert-to-node-assert/workflow.yaml b/recipes/process-assert-to-node-assert/workflow.yaml new file mode 100644 index 00000000..7aa67a1d --- /dev/null +++ b/recipes/process-assert-to-node-assert/workflow.yaml @@ -0,0 +1,25 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/codemod-com/codemod/refs/heads/main/schemas/workflow.json + +version: "1" + +nodes: + - id: apply-transforms + name: Apply AST Transformations + type: automatic + steps: + - name: Handle DEP0100 via transforming `process.assert` to `node:assert`. + js-ast-grep: + js_file: src/workflow.ts + base_path: . + include: + - "**/*.cjs" + - "**/*.js" + - "**/*.jsx" + - "**/*.mjs" + - "**/*.cts" + - "**/*.mts" + - "**/*.ts" + - "**/*.tsx" + exclude: + - "**/node_modules/**" + language: typescript