From 53ed809a967b84408e4d705c946cafa7f6751e92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Sun, 29 Jun 2025 21:13:40 +0200 Subject: [PATCH 01/14] Add a node-tests package --- package-lock.json | 121 ++++++++++++++++++++ package.json | 1 + packages/node-tests/.gitignore | 2 + packages/node-tests/package.json | 27 +++++ packages/node-tests/scripts/build-tests.mts | 21 ++++ packages/node-tests/scripts/copy-tests.mts | 65 +++++++++++ packages/node-tests/scripts/utils.mts | 20 ++++ 7 files changed, 257 insertions(+) create mode 100644 packages/node-tests/.gitignore create mode 100644 packages/node-tests/package.json create mode 100644 packages/node-tests/scripts/build-tests.mts create mode 100644 packages/node-tests/scripts/copy-tests.mts create mode 100644 packages/node-tests/scripts/utils.mts diff --git a/package-lock.json b/package-lock.json index e3d811c9..091d0268 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "packages/ferric", "packages/host", "packages/node-addon-examples", + "packages/node-tests", "packages/ferric-example" ], "devDependencies": { @@ -5895,6 +5896,10 @@ "resolved": "packages/node-addon-examples", "link": true }, + "node_modules/@react-native-node-api/node-tests": { + "resolved": "packages/node-tests", + "link": true + }, "node_modules/@react-native-node-api/test-app": { "resolved": "apps/test-app", "link": true @@ -8994,6 +8999,13 @@ "node": ">= 0.6" } }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true, + "license": "MIT" + }, "node_modules/fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -10966,6 +10978,13 @@ "node": ">=10" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true, + "license": "MIT" + }, "node_modules/mocha": { "version": "11.7.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.0.tgz", @@ -11236,6 +11255,19 @@ "node": ">=12.0.0" } }, + "node_modules/node-abi": { + "version": "3.75.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.75.0.tgz", + "integrity": "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/node-addon-api": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.4.0.tgz", @@ -11817,6 +11849,37 @@ "node": ">= 0.4" } }, + "node_modules/prebuildify": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/prebuildify/-/prebuildify-6.0.1.tgz", + "integrity": "sha512-8Y2oOOateom/s8dNBsGIcnm6AxPmLH4/nanQzL5lQMU+sC0CMhzARZHizwr36pUPLdvBnOkCNQzxg4djuFSgIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "mkdirp-classic": "^0.5.3", + "node-abi": "^3.3.0", + "npm-run-path": "^3.1.0", + "pump": "^3.0.0", + "tar-fs": "^2.1.0" + }, + "bin": { + "prebuildify": "bin.js" + } + }, + "node_modules/prebuildify/node_modules/npm-run-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz", + "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -11897,6 +11960,17 @@ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "license": "MIT" }, + "node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -13152,6 +13226,43 @@ "node": ">=10" } }, + "node_modules/tar-fs": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz", + "integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true, + "license": "ISC" + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/tar/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -15013,6 +15124,16 @@ "react-native-node-api-cmake": "*" } }, + "packages/node-tests": { + "name": "@react-native-node-api/node-tests", + "devDependencies": { + "cmake-js": "^7.3.1", + "cmake-rn": "*", + "gyp-to-cmake": "*", + "prebuildify": "^6.0.1", + "read-pkg": "^9.0.1" + } + }, "packages/react-native-node-api-cmake": { "version": "0.1.0", "extraneous": true, diff --git a/package.json b/package.json index c7ff7c2f..cac8f8d6 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "packages/ferric", "packages/host", "packages/node-addon-examples", + "packages/node-tests", "packages/ferric-example" ], "homepage": "https://github.com/callstackincubator/react-native-node-api#readme", diff --git a/packages/node-tests/.gitignore b/packages/node-tests/.gitignore new file mode 100644 index 00000000..88db8942 --- /dev/null +++ b/packages/node-tests/.gitignore @@ -0,0 +1,2 @@ +node/ +tests/ diff --git a/packages/node-tests/package.json b/packages/node-tests/package.json new file mode 100644 index 00000000..ab42c2ae --- /dev/null +++ b/packages/node-tests/package.json @@ -0,0 +1,27 @@ +{ + "name": "@react-native-node-api/node-tests", + "description": "Harness for running the Node.js tests from https://github.com/nodejs/node/tree/main/test", + "type": "commonjs", + "main": "dist/index.js", + "private": true, + "homepage": "https://github.com/callstackincubator/react-native-node-api", + "repository": { + "type": "git", + "url": "git+https://github.com/callstackincubator/react-native-node-api.git", + "directory": "packages/node-tests" + }, + "scripts": { + "copy-tests": "tsx scripts/copy-tests.mts", + "gyp-to-cmake": "gyp-to-cmake ./tests", + "build": "tsx scripts/build-tests.mts", + "copy-and-build": "npm run copy-tests && npm run gyp-to-cmake && npm run build", + "test": "npm run copy-and-build" + }, + "devDependencies": { + "cmake-js": "^7.3.1", + "cmake-rn": "*", + "gyp-to-cmake": "*", + "prebuildify": "^6.0.1", + "read-pkg": "^9.0.1" + } +} diff --git a/packages/node-tests/scripts/build-tests.mts b/packages/node-tests/scripts/build-tests.mts new file mode 100644 index 00000000..fcf08cbb --- /dev/null +++ b/packages/node-tests/scripts/build-tests.mts @@ -0,0 +1,21 @@ +import { execSync } from "node:child_process"; + +import { findCMakeProjects } from "./utils.mts"; + +const projectDirectories = findCMakeProjects(); + +for (const projectDirectory of projectDirectories) { + console.log( + `Running "cmake-rn" in ${projectDirectory} to build for React Native` + ); + execSync("cmake-rn --out-to-build", { + cwd: projectDirectory, + stdio: "inherit", + }); + console.log(`Running "cmake-js" in ${projectDirectory} to build for Node.js`); + execSync("cmake-js", { + cwd: projectDirectory, + stdio: "inherit", + }); + console.log(); +} diff --git a/packages/node-tests/scripts/copy-tests.mts b/packages/node-tests/scripts/copy-tests.mts new file mode 100644 index 00000000..057a9c3b --- /dev/null +++ b/packages/node-tests/scripts/copy-tests.mts @@ -0,0 +1,65 @@ +import fs from "node:fs"; +import path from "node:path"; +import cp from "node:child_process"; + +import { TESTS_DIR } from "./utils.mts"; + +const NODE_REPO_URL = "git@github.com:nodejs/node.git"; +const NODE_REPO_DIR = path.resolve(import.meta.dirname, "../node"); + +const ALLOW_LIST = [ + "js-native-api/common.h", + "js-native-api/common-inl.h", + "js-native-api/entry_point.h", + "js-native-api/2_function_arguments", +]; + +console.log("Copying files to", TESTS_DIR); + +// Clean up the destination directory before copying +// fs.rmSync(EXAMPLES_DIR, { recursive: true, force: true }); + +if (!fs.existsSync(NODE_REPO_DIR)) { + console.log( + "Sparse and shallow cloning Node.js repository to", + NODE_REPO_DIR + ); + + // Init a new git repository + cp.execFileSync("git", ["init", NODE_REPO_DIR], { + stdio: "inherit", + }); + // Set the remote origin to the Node.js repository + cp.execFileSync("git", ["remote", "add", "origin", NODE_REPO_URL], { + stdio: "inherit", + cwd: NODE_REPO_DIR, + }); + // Enable sparse checkout + cp.execFileSync("git", ["sparse-checkout", "set", "test/js-native-api"], { + stdio: "inherit", + cwd: NODE_REPO_DIR, + }); + // Pull the latest changes from the master branch + console.log("Pulling latest changes from Node.js repository..."); + cp.execFileSync("git", ["pull", "--depth=1", "origin", "main"], { + stdio: "inherit", + cwd: NODE_REPO_DIR, + }); +} +const SRC_DIR = path.join(NODE_REPO_DIR, "test"); +console.log("Copying files from", SRC_DIR); + +for (const src of ALLOW_LIST) { + const srcPath = path.join(SRC_DIR, src); + const destPath = path.join(TESTS_DIR, src); + + if (fs.existsSync(destPath)) { + console.warn( + `Destination path ${destPath} already exists - skipping copy of ${src}.` + ); + continue; + } + + console.log("Copying from", srcPath, "to", destPath); + fs.cpSync(srcPath, destPath, { recursive: true }); +} diff --git a/packages/node-tests/scripts/utils.mts b/packages/node-tests/scripts/utils.mts new file mode 100644 index 00000000..97e32b03 --- /dev/null +++ b/packages/node-tests/scripts/utils.mts @@ -0,0 +1,20 @@ +import { readdirSync, statSync } from "node:fs"; +import path from "node:path"; + +export const TESTS_DIR = path.resolve(import.meta.dirname, "../tests"); + +export function findCMakeProjects(dir = TESTS_DIR): string[] { + let results: string[] = []; + const files = readdirSync(dir); + + for (const file of files) { + const fullPath = path.join(dir, file); + if (statSync(fullPath).isDirectory()) { + results = results.concat(findCMakeProjects(fullPath)); + } else if (file === "CMakeLists.txt") { + results.push(dir); + } + } + + return results; +} From b5ec2bec099d1f824460e6074e564908409f9428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Mon, 14 Jul 2025 17:04:22 +0200 Subject: [PATCH 02/14] Rolldown WIP --- package-lock.json | 221 +++++++++++++++++++- packages/node-tests/package.json | 4 +- packages/node-tests/rolldown.config.mts | 15 ++ packages/node-tests/scripts/build-tests.mts | 3 +- packages/node-tests/scripts/copy-tests.mts | 4 + 5 files changed, 244 insertions(+), 3 deletions(-) create mode 100644 packages/node-tests/rolldown.config.mts diff --git a/package-lock.json b/package-lock.json index 091d0268..ea809eec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6239,6 +6239,184 @@ "node": ">=16.17" } }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0-beta.26", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-beta.26.tgz", + "integrity": "sha512-I73Ej+PVoCJiYQHpy45CHKkLgFqrYv9O1CUJs6TIav6f8f9WAVeN/k0YXrs0tgMO20AfsyEN8zenz2wprVWOYQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0-beta.26", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-beta.26.tgz", + "integrity": "sha512-IcXzfO2/9bnm6WfCNmGxBiD1kQQdA0pTjjGcjvglUub8H6RlEY0tz+IIQxUirsl/++84S0PkCuafAxZi8Am8fg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0-beta.26", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-beta.26.tgz", + "integrity": "sha512-foLJNqEFdvwFm2MXDFxgywxJMic+wovbpEyszlz5K/sUbN7sP2+NJ7MZAUMHuggiswB4Rt1HqRLYKy26zJev8g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0-beta.26", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-beta.26.tgz", + "integrity": "sha512-1BWDpLtujfZCvWAcfIamqHGWo2+VnPWvpZQR0DL5qNit6cu3FC0sRZ+bZzTUK0QWDTA7nUy5RR9fUTL2PQxH2g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0-beta.26", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-beta.26.tgz", + "integrity": "sha512-lg6DVwciFb7sIw0ONDHeLhRuFQl/wz+J26bxfVOVzVoQ7Zgl07gDklv7q96W7SRDAjlG/20flBOexdiPim/I3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0-beta.26", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-beta.26.tgz", + "integrity": "sha512-0X14trOBVtU13Y0XYeb8EvOvb3/TxJVOmalDakEID/UUX9qkvOmlU0fvoDVmsnhH6yx23bDlpmOj0f8V3BCgIw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.0-beta.26", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-beta.26.tgz", + "integrity": "sha512-stb8XloM+N3hSKUs6kS5tNqrlTGsCoYuh9emFZtTovfFzzdFYevgXoOdeGoXv9KkPh5B7MOMl4/7c+WaX46Opg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0-beta.26", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-beta.26.tgz", + "integrity": "sha512-5udEpAS5IUy2t74d/m40JUYyk3Ga8QXQDvK7eGqDDOwz8/7Piq0kCwmNuLnpSRiqbXNP8mnVlvtIcASJUEtRPA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0-beta.26", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-beta.26.tgz", + "integrity": "sha512-Is5tTdScXXQzslj7+jCFncPoRNARJ/+fYt/C9+Yx0QQ67/m8pGPLFoCzIKmJQZ8QHzOfq5ML4CQlMgBbCFlZqQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.10" + }, + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0-beta.26", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-beta.26.tgz", + "integrity": "sha512-bH+TB+/8Z/95cxGws0fH995HsbsopVYdGcuM1Z/Hnqe7KPLkhqkubsambHQYd1V/QNbLzAgJ0nMAFLyBrwFZZQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rolldown/binding-win32-ia32-msvc": { + "version": "1.0.0-beta.26", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.0.0-beta.26.tgz", + "integrity": "sha512-Nsg7ZzfwLHwKGneuNHEpqdBekmZA5pzVOuFx5R8EVyva8dg+sgtDHQRmiVSVYe25YYISNFXDSuHKwNhrWI4HWA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0-beta.26", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-beta.26.tgz", + "integrity": "sha512-NE5Btf10Fu3IbpHxrlRkgcO/d05iEpbIiP/XdMYW7Lc9BGSgE4f8njUHnM0V2XJKyXkC1fqv/uHSEw2dCNgzxQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.26", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.26.tgz", + "integrity": "sha512-r/5po89voz/QRPDmoErL10+hVuTAuz1SHvokx+yWBlOIPB5C41jC7QhLqq9kaebx/+EHyoV3z22/qBfX81Ns8A==", + "dev": true, + "license": "MIT" + }, "node_modules/@sideway/address": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", @@ -6822,6 +7000,16 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/ansis": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.1.0.tgz", + "integrity": "sha512-BGcItUBWSMRgOCe+SVZJ+S7yTRG0eGt9cXAHev72yuGcY23hnLA7Bky5L/xLyPINoSN95geovfBkqoTlNZYa7w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + } + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -12530,6 +12718,36 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rolldown": { + "version": "1.0.0-beta.26", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-beta.26.tgz", + "integrity": "sha512-2rad1JDFst/GD1J86RuqN1SIP8O8Xv4UbqNyKaVayXTjgF0D6HpvTnUZ1RQ6tANpZweGmq4v6Ay0uyRNEycFPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/runtime": "=0.76.0", + "@oxc-project/types": "=0.76.0", + "@rolldown/pluginutils": "1.0.0-beta.26", + "ansis": "^4.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "optionalDependencies": { + "@rolldown/binding-darwin-arm64": "1.0.0-beta.26", + "@rolldown/binding-darwin-x64": "1.0.0-beta.26", + "@rolldown/binding-freebsd-x64": "1.0.0-beta.26", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-beta.26", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.26", + "@rolldown/binding-linux-arm64-musl": "1.0.0-beta.26", + "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.26", + "@rolldown/binding-linux-x64-musl": "1.0.0-beta.26", + "@rolldown/binding-wasm32-wasi": "1.0.0-beta.26", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-beta.26", + "@rolldown/binding-win32-ia32-msvc": "1.0.0-beta.26", + "@rolldown/binding-win32-x64-msvc": "1.0.0-beta.26" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -15131,7 +15349,8 @@ "cmake-rn": "*", "gyp-to-cmake": "*", "prebuildify": "^6.0.1", - "read-pkg": "^9.0.1" + "read-pkg": "^9.0.1", + "rolldown": "1.0.0-beta.26" } }, "packages/react-native-node-api-cmake": { diff --git a/packages/node-tests/package.json b/packages/node-tests/package.json index ab42c2ae..b9303b40 100644 --- a/packages/node-tests/package.json +++ b/packages/node-tests/package.json @@ -14,6 +14,7 @@ "copy-tests": "tsx scripts/copy-tests.mts", "gyp-to-cmake": "gyp-to-cmake ./tests", "build": "tsx scripts/build-tests.mts", + "bundle": "rolldown -c rolldown.config.mts", "copy-and-build": "npm run copy-tests && npm run gyp-to-cmake && npm run build", "test": "npm run copy-and-build" }, @@ -22,6 +23,7 @@ "cmake-rn": "*", "gyp-to-cmake": "*", "prebuildify": "^6.0.1", - "read-pkg": "^9.0.1" + "read-pkg": "^9.0.1", + "rolldown": "1.0.0-beta.26" } } diff --git a/packages/node-tests/rolldown.config.mts b/packages/node-tests/rolldown.config.mts new file mode 100644 index 00000000..5afedb77 --- /dev/null +++ b/packages/node-tests/rolldown.config.mts @@ -0,0 +1,15 @@ +import { defineConfig } from "rolldown"; + +export default defineConfig([ + { + input: "tests/js-native-api/2_function_arguments/test.js", + output: { + file: "bundle.js", + }, + resolve: { + alias: { + "../../common": "yo.ts", + }, + }, + }, +]); diff --git a/packages/node-tests/scripts/build-tests.mts b/packages/node-tests/scripts/build-tests.mts index fcf08cbb..27bd9aae 100644 --- a/packages/node-tests/scripts/build-tests.mts +++ b/packages/node-tests/scripts/build-tests.mts @@ -8,10 +8,11 @@ for (const projectDirectory of projectDirectories) { console.log( `Running "cmake-rn" in ${projectDirectory} to build for React Native` ); - execSync("cmake-rn --out-to-build", { + execSync("cmake-rn", { cwd: projectDirectory, stdio: "inherit", }); + console.log(`Running "cmake-js" in ${projectDirectory} to build for Node.js`); execSync("cmake-js", { cwd: projectDirectory, diff --git a/packages/node-tests/scripts/copy-tests.mts b/packages/node-tests/scripts/copy-tests.mts index 057a9c3b..e1edd3c2 100644 --- a/packages/node-tests/scripts/copy-tests.mts +++ b/packages/node-tests/scripts/copy-tests.mts @@ -63,3 +63,7 @@ for (const src of ALLOW_LIST) { console.log("Copying from", srcPath, "to", destPath); fs.cpSync(srcPath, destPath, { recursive: true }); } + +if (!fs.existsSync(path.join(TESTS_DIR, "common.js"))) { + // TODO: Perform a symlink of a common.js file from src/common.js +} From afca0fd9ebceef008d6277a5371014dcc05b9edb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Thu, 24 Jul 2025 13:28:56 +0200 Subject: [PATCH 03/14] Build and bundle node test addons --- package-lock.json | 246 +++++++++++++----- packages/node-tests/common.ts | 1 + packages/node-tests/package.json | 9 +- packages/node-tests/rolldown.config.mts | 93 ++++++- packages/node-tests/scripts/build-tests.mts | 9 +- packages/node-tests/scripts/copy-tests.mts | 2 +- packages/node-tests/tsconfig.json | 7 + .../node-tests/tsconfig.node-scripts.json | 12 + packages/node-tests/tsconfig.tests.json | 12 + tsconfig.json | 3 +- 10 files changed, 311 insertions(+), 83 deletions(-) create mode 100644 packages/node-tests/common.ts create mode 100644 packages/node-tests/tsconfig.json create mode 100644 packages/node-tests/tsconfig.node-scripts.json create mode 100644 packages/node-tests/tsconfig.tests.json diff --git a/package-lock.json b/package-lock.json index ea809eec..a0c3d8df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6239,10 +6239,24 @@ "node": ">=16.17" } }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0-beta.29", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-beta.29.tgz", + "integrity": "sha512-pDv7gg59Gdy80eFmMkEqXEaoJi3Y9W/a9T3z9M4t8Ma8aVXNldvSy9UgtlX7AK7DPqF8tULnmIZ2Z3rvGMz/NQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.0.0-beta.26", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-beta.26.tgz", - "integrity": "sha512-I73Ej+PVoCJiYQHpy45CHKkLgFqrYv9O1CUJs6TIav6f8f9WAVeN/k0YXrs0tgMO20AfsyEN8zenz2wprVWOYQ==", + "version": "1.0.0-beta.29", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-beta.29.tgz", + "integrity": "sha512-fPqR6TfTqbzgKKCQYtcCS+Dms91YcptTbdlwJ13DxOUgMe8LgDIVsLLlEykfm7ijJd5mM4zNw0Hr2CJb6kvQZw==", "cpu": [ "arm64" ], @@ -6254,9 +6268,9 @@ ] }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.0.0-beta.26", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-beta.26.tgz", - "integrity": "sha512-IcXzfO2/9bnm6WfCNmGxBiD1kQQdA0pTjjGcjvglUub8H6RlEY0tz+IIQxUirsl/++84S0PkCuafAxZi8Am8fg==", + "version": "1.0.0-beta.29", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-beta.29.tgz", + "integrity": "sha512-7Z4qosL0xN8i6++txHOEPCVP3/lcGLOvftUJOWATZ5aDkDskwcZDa66BGiJt/K1/DgW4kpRVmnGWUWAORHBbFA==", "cpu": [ "x64" ], @@ -6268,9 +6282,9 @@ ] }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.0.0-beta.26", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-beta.26.tgz", - "integrity": "sha512-foLJNqEFdvwFm2MXDFxgywxJMic+wovbpEyszlz5K/sUbN7sP2+NJ7MZAUMHuggiswB4Rt1HqRLYKy26zJev8g==", + "version": "1.0.0-beta.29", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-beta.29.tgz", + "integrity": "sha512-0HLTfPW5Glh608s76qgayN/nPsXPchNUumavf7W5nh1eMG6qBsOO7Q1QaK0v4un7qtsn3IA/1Tgq0ZgNc0dbeg==", "cpu": [ "x64" ], @@ -6282,9 +6296,9 @@ ] }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.0.0-beta.26", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-beta.26.tgz", - "integrity": "sha512-1BWDpLtujfZCvWAcfIamqHGWo2+VnPWvpZQR0DL5qNit6cu3FC0sRZ+bZzTUK0QWDTA7nUy5RR9fUTL2PQxH2g==", + "version": "1.0.0-beta.29", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-beta.29.tgz", + "integrity": "sha512-QNboxdVTJOZS4zP8kA2+XUwAegejd5QNSH5zVR4neqG2AfbxRcMFzSVRkJHN6yDaaKweD/4sUvXfmef6p/7zsw==", "cpu": [ "arm" ], @@ -6296,9 +6310,9 @@ ] }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.0.0-beta.26", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-beta.26.tgz", - "integrity": "sha512-lg6DVwciFb7sIw0ONDHeLhRuFQl/wz+J26bxfVOVzVoQ7Zgl07gDklv7q96W7SRDAjlG/20flBOexdiPim/I3g==", + "version": "1.0.0-beta.29", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-beta.29.tgz", + "integrity": "sha512-hzBmOtYdC4369XxN2SNJ3oBlXKWNif3ieWBT+oh/qvAeox4fQR0ngqyh+kIGOufBnP5Zc2rqJf9LzIbJw3Tx/Q==", "cpu": [ "arm64" ], @@ -6310,9 +6324,9 @@ ] }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.0.0-beta.26", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-beta.26.tgz", - "integrity": "sha512-0X14trOBVtU13Y0XYeb8EvOvb3/TxJVOmalDakEID/UUX9qkvOmlU0fvoDVmsnhH6yx23bDlpmOj0f8V3BCgIw==", + "version": "1.0.0-beta.29", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-beta.29.tgz", + "integrity": "sha512-6B35GmFJJ4RX88OgubrnUmuJBUgRh6/OTXIpy8m/VUnoc683lufIPo26HW/0LxLgxp2GM7KHr3LOULcVxbqq4Q==", "cpu": [ "arm64" ], @@ -6323,10 +6337,24 @@ "linux" ] }, + "node_modules/@rolldown/binding-linux-arm64-ohos": { + "version": "1.0.0-beta.29", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-ohos/-/binding-linux-arm64-ohos-1.0.0-beta.29.tgz", + "integrity": "sha512-z3ru8fUCunQM8q9I7RbDVMT5cxzxVVVBNNKM5/qAQQrdObd1u8g0LR5z0yLtaFWzybwLVdPtJDRcXtLm5tOBFA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.0-beta.26", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-beta.26.tgz", - "integrity": "sha512-stb8XloM+N3hSKUs6kS5tNqrlTGsCoYuh9emFZtTovfFzzdFYevgXoOdeGoXv9KkPh5B7MOMl4/7c+WaX46Opg==", + "version": "1.0.0-beta.29", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-beta.29.tgz", + "integrity": "sha512-n6fs4L7j99MIiI6vKhQDdyScv4/uMAPtIMkB0zGbUX8MKWT1osym1hvWVdlENjnS/Phf0zzhjyOgoFDzdhI1cQ==", "cpu": [ "x64" ], @@ -6338,9 +6366,9 @@ ] }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.0.0-beta.26", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-beta.26.tgz", - "integrity": "sha512-5udEpAS5IUy2t74d/m40JUYyk3Ga8QXQDvK7eGqDDOwz8/7Piq0kCwmNuLnpSRiqbXNP8mnVlvtIcASJUEtRPA==", + "version": "1.0.0-beta.29", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-beta.29.tgz", + "integrity": "sha512-C5hcJgtDN4rp6/WsPTQSDVUWrdnIC//ynMGcUIh1O0anm9KnSy47zKQ5D9EqtlEKvO+2PPqmyUVJ2DTq18nlVA==", "cpu": [ "x64" ], @@ -6352,9 +6380,9 @@ ] }, "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.0.0-beta.26", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-beta.26.tgz", - "integrity": "sha512-Is5tTdScXXQzslj7+jCFncPoRNARJ/+fYt/C9+Yx0QQ67/m8pGPLFoCzIKmJQZ8QHzOfq5ML4CQlMgBbCFlZqQ==", + "version": "1.0.0-beta.29", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-beta.29.tgz", + "integrity": "sha512-lMN1IBItdZFO182Sdus9oVuNDqyIymn/bsR5KwgeGaiqLsrmpQHBSLwkS/nKJO1nzYlpGDRugFSpnrSJ5ZmihQ==", "cpu": [ "wasm32" ], @@ -6362,16 +6390,40 @@ "license": "MIT", "optional": true, "dependencies": { - "@napi-rs/wasm-runtime": "^0.2.10" + "@napi-rs/wasm-runtime": "^1.0.1" }, "engines": { - "node": ">=14.21.3" + "node": ">=14.0.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.1.tgz", + "integrity": "sha512-KVlQ/jgywZpixGCKMNwxStmmbYEMyokZpCf2YuIChhfJA2uqfAKNEM8INz7zzTo55iEXfBhIIs3VqYyqzDLj8g==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.5", + "@emnapi/runtime": "^1.4.5", + "@tybys/wasm-util": "^0.10.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@tybys/wasm-util": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.0.tgz", + "integrity": "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.0.0-beta.26", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-beta.26.tgz", - "integrity": "sha512-bH+TB+/8Z/95cxGws0fH995HsbsopVYdGcuM1Z/Hnqe7KPLkhqkubsambHQYd1V/QNbLzAgJ0nMAFLyBrwFZZQ==", + "version": "1.0.0-beta.29", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-beta.29.tgz", + "integrity": "sha512-0UrXCUAOrbWdyVJskzjtne/4d3YMMhhhpBnob3SeF4jAvbKYqPhCZJ71pP7yUpvbowGXXTnHWpKfitg4Sovmtw==", "cpu": [ "arm64" ], @@ -6383,9 +6435,9 @@ ] }, "node_modules/@rolldown/binding-win32-ia32-msvc": { - "version": "1.0.0-beta.26", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.0.0-beta.26.tgz", - "integrity": "sha512-Nsg7ZzfwLHwKGneuNHEpqdBekmZA5pzVOuFx5R8EVyva8dg+sgtDHQRmiVSVYe25YYISNFXDSuHKwNhrWI4HWA==", + "version": "1.0.0-beta.29", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.0.0-beta.29.tgz", + "integrity": "sha512-YX0OYL1dcB7rPnsndpEa68fytYyZZj1iaWzH7momFB2oBS2lXAe1UrrDWcdLoUXdzPIyzpvtBCiS2XcDgYG7ag==", "cpu": [ "ia32" ], @@ -6397,9 +6449,9 @@ ] }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.0-beta.26", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-beta.26.tgz", - "integrity": "sha512-NE5Btf10Fu3IbpHxrlRkgcO/d05iEpbIiP/XdMYW7Lc9BGSgE4f8njUHnM0V2XJKyXkC1fqv/uHSEw2dCNgzxQ==", + "version": "1.0.0-beta.29", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-beta.29.tgz", + "integrity": "sha512-azrPWbV+NZiCFNs59AgH9Y6vFKHoAI6T/XtKKsoLxkPyP1LpbdgL5eqRfeWz+GCAUY9qhDOC4hH1GjFG8PrZIg==", "cpu": [ "x64" ], @@ -6411,12 +6463,75 @@ ] }, "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.26", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.26.tgz", - "integrity": "sha512-r/5po89voz/QRPDmoErL10+hVuTAuz1SHvokx+yWBlOIPB5C41jC7QhLqq9kaebx/+EHyoV3z22/qBfX81Ns8A==", + "version": "1.0.0-beta.29", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.29.tgz", + "integrity": "sha512-NIJgOsMjbxAXvoGq/X0gD7VPMQ8j9g0BiDaNjVNVjvl+iKXxL3Jre0v31RmBYeLEmkbj2s02v8vFTbUXi5XS2Q==", "dev": true, "license": "MIT" }, + "node_modules/@rollup/plugin-babel": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.0.4.tgz", + "integrity": "sha512-YF7Y52kFdFT/xVSuVdjkV5ZdX/3YtmX0QulG+x0taQOtJdHYzVU61aSSkAgVJ7NOv6qPkIYiJSgSWWN/DM5sGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.18.6", + "@rollup/pluginutils": "^5.0.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@types/babel__core": "^7.1.9", + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "@types/babel__core": { + "optional": true + }, + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.2.0.tgz", + "integrity": "sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@sideway/address": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", @@ -8770,6 +8885,13 @@ "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -12719,33 +12841,35 @@ } }, "node_modules/rolldown": { - "version": "1.0.0-beta.26", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-beta.26.tgz", - "integrity": "sha512-2rad1JDFst/GD1J86RuqN1SIP8O8Xv4UbqNyKaVayXTjgF0D6HpvTnUZ1RQ6tANpZweGmq4v6Ay0uyRNEycFPw==", + "version": "1.0.0-beta.29", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-beta.29.tgz", + "integrity": "sha512-EsoOi8moHN6CAYyTZipxDDVTJn0j2nBCWor4wRU45RQ8ER2qREDykXLr3Ulz6hBh6oBKCFTQIjo21i0FXNo/IA==", "dev": true, "license": "MIT", "dependencies": { - "@oxc-project/runtime": "=0.76.0", - "@oxc-project/types": "=0.76.0", - "@rolldown/pluginutils": "1.0.0-beta.26", + "@oxc-project/runtime": "=0.77.3", + "@oxc-project/types": "=0.77.3", + "@rolldown/pluginutils": "1.0.0-beta.29", "ansis": "^4.0.0" }, "bin": { "rolldown": "bin/cli.mjs" }, "optionalDependencies": { - "@rolldown/binding-darwin-arm64": "1.0.0-beta.26", - "@rolldown/binding-darwin-x64": "1.0.0-beta.26", - "@rolldown/binding-freebsd-x64": "1.0.0-beta.26", - "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-beta.26", - "@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.26", - "@rolldown/binding-linux-arm64-musl": "1.0.0-beta.26", - "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.26", - "@rolldown/binding-linux-x64-musl": "1.0.0-beta.26", - "@rolldown/binding-wasm32-wasi": "1.0.0-beta.26", - "@rolldown/binding-win32-arm64-msvc": "1.0.0-beta.26", - "@rolldown/binding-win32-ia32-msvc": "1.0.0-beta.26", - "@rolldown/binding-win32-x64-msvc": "1.0.0-beta.26" + "@rolldown/binding-android-arm64": "1.0.0-beta.29", + "@rolldown/binding-darwin-arm64": "1.0.0-beta.29", + "@rolldown/binding-darwin-x64": "1.0.0-beta.29", + "@rolldown/binding-freebsd-x64": "1.0.0-beta.29", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-beta.29", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.29", + "@rolldown/binding-linux-arm64-musl": "1.0.0-beta.29", + "@rolldown/binding-linux-arm64-ohos": "1.0.0-beta.29", + "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.29", + "@rolldown/binding-linux-x64-musl": "1.0.0-beta.29", + "@rolldown/binding-wasm32-wasi": "1.0.0-beta.29", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-beta.29", + "@rolldown/binding-win32-ia32-msvc": "1.0.0-beta.29", + "@rolldown/binding-win32-x64-msvc": "1.0.0-beta.29" } }, "node_modules/run-parallel": { @@ -15345,12 +15469,14 @@ "packages/node-tests": { "name": "@react-native-node-api/node-tests", "devDependencies": { + "@rollup/plugin-babel": "^6.0.4", "cmake-js": "^7.3.1", "cmake-rn": "*", "gyp-to-cmake": "*", "prebuildify": "^6.0.1", + "react-native-node-api": "^0.3.2", "read-pkg": "^9.0.1", - "rolldown": "1.0.0-beta.26" + "rolldown": "1.0.0-beta.29" } }, "packages/react-native-node-api-cmake": { diff --git a/packages/node-tests/common.ts b/packages/node-tests/common.ts new file mode 100644 index 00000000..3264d808 --- /dev/null +++ b/packages/node-tests/common.ts @@ -0,0 +1 @@ +export const buildType = "Release"; diff --git a/packages/node-tests/package.json b/packages/node-tests/package.json index b9303b40..11a9d592 100644 --- a/packages/node-tests/package.json +++ b/packages/node-tests/package.json @@ -13,17 +13,18 @@ "scripts": { "copy-tests": "tsx scripts/copy-tests.mts", "gyp-to-cmake": "gyp-to-cmake ./tests", - "build": "tsx scripts/build-tests.mts", + "build-tests": "tsx scripts/build-tests.mts", "bundle": "rolldown -c rolldown.config.mts", - "copy-and-build": "npm run copy-tests && npm run gyp-to-cmake && npm run build", - "test": "npm run copy-and-build" + "bootstrap": "npm run copy-tests && npm run gyp-to-cmake && npm run build-tests && npm run bundle" }, "devDependencies": { + "@rollup/plugin-babel": "^6.0.4", "cmake-js": "^7.3.1", "cmake-rn": "*", "gyp-to-cmake": "*", "prebuildify": "^6.0.1", + "react-native-node-api": "^0.3.2", "read-pkg": "^9.0.1", - "rolldown": "1.0.0-beta.26" + "rolldown": "1.0.0-beta.29" } } diff --git a/packages/node-tests/rolldown.config.mts b/packages/node-tests/rolldown.config.mts index 5afedb77..601c8a74 100644 --- a/packages/node-tests/rolldown.config.mts +++ b/packages/node-tests/rolldown.config.mts @@ -1,15 +1,90 @@ -import { defineConfig } from "rolldown"; +import assert from "node:assert/strict"; +import fs from "node:fs"; +import path from "node:path"; -export default defineConfig([ - { - input: "tests/js-native-api/2_function_arguments/test.js", +import { defineConfig, type RolldownOptions } from "rolldown"; +import { aliasPlugin, replacePlugin } from "rolldown/experimental"; +import { babel } from "@rollup/plugin-babel"; + +import nodeApiBabelPlugin from "react-native-node-api/babel-plugin"; + +function readGypTargetNames(gypFilePath: string): string[] { + const contents = JSON.parse(fs.readFileSync(gypFilePath, "utf-8")) as unknown; + assert( + typeof contents === "object" && contents !== null, + "Expected gyp file to contain a valid JSON object" + ); + assert("targets" in contents, "Expected targets in gyp file"); + const { targets } = contents; + assert(Array.isArray(targets), "Expected targets to be an array"); + return targets.map(({ target_name }) => { + assert( + typeof target_name === "string", + "Expected target_name to be a string" + ); + return target_name; + }); +} + +function testBundle( + testDirectory: string, + testFiles: string[] +): RolldownOptions[] { + const gypFilePath = path.join(testDirectory, "binding.gyp"); + const targetNames = readGypTargetNames(gypFilePath); + return testFiles.map((testFile) => ({ + input: path.join(testDirectory, testFile), output: { - file: "bundle.js", + file: path.join( + testDirectory, + path.basename(testFile, ".js") + ".bundle.js" + ), }, resolve: { - alias: { - "../../common": "yo.ts", - }, + conditionNames: ["react-native"], }, - }, + polyfillRequire: false, + plugins: [ + // Replace dynamic require statements for addon targets to allow the babel plugin to handle them correctly + replacePlugin( + Object.fromEntries( + targetNames.map((targetName) => [ + `require(\`./build/\${common.buildType}/${targetName}\`)`, + `require('./build/Release/${targetName}')`, + ]) + ), + { + delimiters: ["", ""], + } + ), + // Use the babel plugin to transform require statements for addons before they get resolved + babel({ + babelHelpers: "bundled", + plugins: [nodeApiBabelPlugin], + }), + replacePlugin( + { + // Replace "__require" statement with a regular "require" to allow Metro to resolve it + '__require("react-native-node-api")': + 'require("react-native-node-api")', + }, + { + delimiters: ["", ""], + } + ), + aliasPlugin({ + entries: [ + { + find: "../../common", + replacement: "./common.ts", + }, + ], + }), + ], + external: ["react-native-node-api"], + })); +} + +export default defineConfig([ + ...testBundle("tests/js-native-api/2_function_arguments", ["test.js"]), ]); diff --git a/packages/node-tests/scripts/build-tests.mts b/packages/node-tests/scripts/build-tests.mts index 27bd9aae..bfd05f29 100644 --- a/packages/node-tests/scripts/build-tests.mts +++ b/packages/node-tests/scripts/build-tests.mts @@ -1,6 +1,6 @@ import { execSync } from "node:child_process"; -import { findCMakeProjects } from "./utils.mts"; +import { findCMakeProjects } from "./utils.mjs"; const projectDirectories = findCMakeProjects(); @@ -12,11 +12,4 @@ for (const projectDirectory of projectDirectories) { cwd: projectDirectory, stdio: "inherit", }); - - console.log(`Running "cmake-js" in ${projectDirectory} to build for Node.js`); - execSync("cmake-js", { - cwd: projectDirectory, - stdio: "inherit", - }); - console.log(); } diff --git a/packages/node-tests/scripts/copy-tests.mts b/packages/node-tests/scripts/copy-tests.mts index e1edd3c2..dc509960 100644 --- a/packages/node-tests/scripts/copy-tests.mts +++ b/packages/node-tests/scripts/copy-tests.mts @@ -2,7 +2,7 @@ import fs from "node:fs"; import path from "node:path"; import cp from "node:child_process"; -import { TESTS_DIR } from "./utils.mts"; +import { TESTS_DIR } from "./utils.mjs"; const NODE_REPO_URL = "git@github.com:nodejs/node.git"; const NODE_REPO_DIR = path.resolve(import.meta.dirname, "../node"); diff --git a/packages/node-tests/tsconfig.json b/packages/node-tests/tsconfig.json new file mode 100644 index 00000000..4b659503 --- /dev/null +++ b/packages/node-tests/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.tests.json" }, + { "path": "./tsconfig.node-scripts.json" } + ] +} diff --git a/packages/node-tests/tsconfig.node-scripts.json b/packages/node-tests/tsconfig.node-scripts.json new file mode 100644 index 00000000..e4ca4a5b --- /dev/null +++ b/packages/node-tests/tsconfig.node-scripts.json @@ -0,0 +1,12 @@ +{ + "extends": "@tsconfig/node22/tsconfig.json", + "compilerOptions": { + "composite": true, + "emitDeclarationOnly": true, + "outDir": "dist", + "rootDir": "scripts", + "types": ["node", "read-pkg"] + }, + "include": ["scripts/**/*.mts"], + "exclude": [] +} diff --git a/packages/node-tests/tsconfig.tests.json b/packages/node-tests/tsconfig.tests.json new file mode 100644 index 00000000..629f51e3 --- /dev/null +++ b/packages/node-tests/tsconfig.tests.json @@ -0,0 +1,12 @@ +{ + "extends": "@tsconfig/react-native", + "compilerOptions": { + "composite": true, + "noEmit": false, + "module": "commonjs", + "outDir": "dist", + "rootDir": "src", + "types": ["react-native"] + }, + "include": ["src/*.ts"] +} diff --git a/tsconfig.json b/tsconfig.json index b9af5629..f5c80f57 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,6 +5,7 @@ { "path": "./packages/gyp-to-cmake/tsconfig.json" }, { "path": "./packages/cmake-rn/tsconfig.json" }, { "path": "./packages/ferric/tsconfig.json" }, - { "path": "./packages/node-addon-examples/tsconfig.json" } + { "path": "./packages/node-addon-examples/tsconfig.json" }, + { "path": "./packages/node-tests/tsconfig.json" } ] } From 19b065e8938d25ab3a4b0187bb819140ee9cc5d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Thu, 24 Jul 2025 13:30:38 +0200 Subject: [PATCH 04/14] Run node tests in test app --- apps/test-app/App.tsx | 13 +++++++++++++ apps/test-app/package.json | 5 ++++- packages/node-tests/src/index.ts | 8 ++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 packages/node-tests/src/index.ts diff --git a/apps/test-app/App.tsx b/apps/test-app/App.tsx index 3fa20d0e..ae6a35f3 100644 --- a/apps/test-app/App.tsx +++ b/apps/test-app/App.tsx @@ -9,6 +9,7 @@ import { } from "mocha-remote-react-native"; import { suites as nodeAddonExamplesSuites } from "@react-native-node-api/node-addon-examples"; +import { suites as nodeTestsSuites } from "@react-native-node-api/node-tests"; function describeIf( condition: boolean, @@ -21,12 +22,14 @@ function describeIf( type Context = { allTests?: boolean; nodeAddonExamples?: boolean; + nodeTests?: boolean; ferricExample?: boolean; }; function loadTests({ allTests = false, nodeAddonExamples = allTests, + nodeTests = allTests, ferricExample = allTests, }: Context) { describeIf(nodeAddonExamples, "Node Addon Examples", () => { @@ -46,6 +49,16 @@ function loadTests({ } }); + describeIf(nodeTests, "Node Tests", () => { + for (const [suiteName, examples] of Object.entries(nodeTestsSuites)) { + describe(suiteName, () => { + for (const [exampleName, requireTest] of Object.entries(examples)) { + it(exampleName, requireTest); + } + }); + } + }); + describeIf(ferricExample, "ferric-example", () => { it("exports a callable sum function", () => { /* eslint-disable-next-line @typescript-eslint/no-require-imports -- TODO: Determine why a dynamic import doesn't work on Android */ diff --git a/apps/test-app/package.json b/apps/test-app/package.json index dc360b3a..f77dabf5 100644 --- a/apps/test-app/package.json +++ b/apps/test-app/package.json @@ -10,10 +10,12 @@ "test:android": "mocha-remote --exit-on-error -- concurrently --kill-others-on-fail --passthrough-arguments npm:metro 'npm:android -- {@}' --", "test:android:allTests": "MOCHA_REMOTE_CONTEXT=allTests npm run test:android -- ", "test:android:nodeAddonExamples": "MOCHA_REMOTE_CONTEXT=nodeAddonExamples npm run test:android -- ", + "test:android:nodeTests": "MOCHA_REMOTE_CONTEXT=nodeTests npm run test:android -- ", "test:android:ferricExample": "MOCHA_REMOTE_CONTEXT=ferricExample npm run test:android -- ", "test:ios": "mocha-remote --exit-on-error -- concurrently --passthrough-arguments --kill-others-on-fail npm:metro 'npm:ios -- {@}' --", "test:ios:allTests": "MOCHA_REMOTE_CONTEXT=allTests npm run test:ios -- ", "test:ios:nodeAddonExamples": "MOCHA_REMOTE_CONTEXT=nodeAddonExamples npm run test:ios -- ", + "test:ios:nodeTests": "MOCHA_REMOTE_CONTEXT=nodeTests npm run test:ios -- ", "test:ios:ferricExample": "MOCHA_REMOTE_CONTEXT=ferricExample npm run test:ios -- " }, "dependencies": { @@ -23,6 +25,8 @@ "@react-native-community/cli": "^18.0.0", "@react-native-community/cli-platform-android": "^18.0.0", "@react-native-community/cli-platform-ios": "^18.0.0", + "@react-native-node-api/node-addon-examples": "*", + "@react-native-node-api/node-tests": "*", "@react-native/babel-preset": "0.79.0", "@react-native/metro-config": "0.79.0", "@react-native/typescript-config": "0.79.0", @@ -36,7 +40,6 @@ "mocha-remote-react-native": "^1.13.2", "react": "19.0.0", "react-native": "0.79.5", - "react-native-node-addon-examples": "*", "react-native-node-api": "*", "react-native-test-app": "^4.3.3" } diff --git a/packages/node-tests/src/index.ts b/packages/node-tests/src/index.ts new file mode 100644 index 00000000..6e8e7f5c --- /dev/null +++ b/packages/node-tests/src/index.ts @@ -0,0 +1,8 @@ +/* eslint-disable @typescript-eslint/no-require-imports */ + +export const suites: Record void>> = { + "2_function_arguments": { + test: () => + require("../tests/js-native-api/2_function_arguments/test.bundle.js"), + }, +}; From 51734f43c90c8015b3f52237de0f3dc9cccc077f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Thu, 24 Jul 2025 14:34:45 +0200 Subject: [PATCH 05/14] Update copy-tests.mts to use https git url --- packages/node-tests/scripts/copy-tests.mts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node-tests/scripts/copy-tests.mts b/packages/node-tests/scripts/copy-tests.mts index dc509960..5e6a0638 100644 --- a/packages/node-tests/scripts/copy-tests.mts +++ b/packages/node-tests/scripts/copy-tests.mts @@ -4,7 +4,7 @@ import cp from "node:child_process"; import { TESTS_DIR } from "./utils.mjs"; -const NODE_REPO_URL = "git@github.com:nodejs/node.git"; +const NODE_REPO_URL = "https://github.com/nodejs/node.git"; const NODE_REPO_DIR = path.resolve(import.meta.dirname, "../node"); const ALLOW_LIST = [ From f1e42c889761e3157c373306f2bb7496e6e9987c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Thu, 24 Jul 2025 20:25:52 +0200 Subject: [PATCH 06/14] No need to babel transform from rolldown --- package-lock.json | 78 +------------------------ packages/node-tests/package.json | 1 - packages/node-tests/rolldown.config.mts | 24 +++----- 3 files changed, 11 insertions(+), 92 deletions(-) diff --git a/package-lock.json b/package-lock.json index a0c3d8df..20c9d3ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,6 +44,8 @@ "@react-native-community/cli": "^18.0.0", "@react-native-community/cli-platform-android": "^18.0.0", "@react-native-community/cli-platform-ios": "^18.0.0", + "@react-native-node-api/node-addon-examples": "*", + "@react-native-node-api/node-tests": "*", "@react-native/babel-preset": "0.79.0", "@react-native/metro-config": "0.79.0", "@react-native/typescript-config": "0.79.0", @@ -57,7 +59,6 @@ "mocha-remote-react-native": "^1.13.2", "react": "19.0.0", "react-native": "0.79.5", - "react-native-node-addon-examples": "*", "react-native-node-api": "*", "react-native-test-app": "^4.3.3" } @@ -6469,69 +6470,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@rollup/plugin-babel": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.0.4.tgz", - "integrity": "sha512-YF7Y52kFdFT/xVSuVdjkV5ZdX/3YtmX0QulG+x0taQOtJdHYzVU61aSSkAgVJ7NOv6qPkIYiJSgSWWN/DM5sGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.18.6", - "@rollup/pluginutils": "^5.0.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0", - "@types/babel__core": "^7.1.9", - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "@types/babel__core": { - "optional": true - }, - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/pluginutils": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.2.0.tgz", - "integrity": "sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/pluginutils/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/@sideway/address": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", @@ -8885,13 +8823,6 @@ "node": ">=4.0" } }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true, - "license": "MIT" - }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -12514,10 +12445,6 @@ } } }, - "node_modules/react-native-node-addon-examples": { - "resolved": "packages/node-addon-examples", - "link": true - }, "node_modules/react-native-node-api": { "resolved": "packages/host", "link": true @@ -15469,7 +15396,6 @@ "packages/node-tests": { "name": "@react-native-node-api/node-tests", "devDependencies": { - "@rollup/plugin-babel": "^6.0.4", "cmake-js": "^7.3.1", "cmake-rn": "*", "gyp-to-cmake": "*", diff --git a/packages/node-tests/package.json b/packages/node-tests/package.json index 11a9d592..1bcedb28 100644 --- a/packages/node-tests/package.json +++ b/packages/node-tests/package.json @@ -18,7 +18,6 @@ "bootstrap": "npm run copy-tests && npm run gyp-to-cmake && npm run build-tests && npm run bundle" }, "devDependencies": { - "@rollup/plugin-babel": "^6.0.4", "cmake-js": "^7.3.1", "cmake-rn": "*", "gyp-to-cmake": "*", diff --git a/packages/node-tests/rolldown.config.mts b/packages/node-tests/rolldown.config.mts index 601c8a74..4824d5e3 100644 --- a/packages/node-tests/rolldown.config.mts +++ b/packages/node-tests/rolldown.config.mts @@ -4,9 +4,6 @@ import path from "node:path"; import { defineConfig, type RolldownOptions } from "rolldown"; import { aliasPlugin, replacePlugin } from "rolldown/experimental"; -import { babel } from "@rollup/plugin-babel"; - -import nodeApiBabelPlugin from "react-native-node-api/babel-plugin"; function readGypTargetNames(gypFilePath: string): string[] { const contents = JSON.parse(fs.readFileSync(gypFilePath, "utf-8")) as unknown; @@ -50,24 +47,21 @@ function testBundle( Object.fromEntries( targetNames.map((targetName) => [ `require(\`./build/\${common.buildType}/${targetName}\`)`, - `require('./build/Release/${targetName}')`, + `require("./build/Release/${targetName}")`, ]) ), { delimiters: ["", ""], } ), - // Use the babel plugin to transform require statements for addons before they get resolved - babel({ - babelHelpers: "bundled", - plugins: [nodeApiBabelPlugin], - }), replacePlugin( - { - // Replace "__require" statement with a regular "require" to allow Metro to resolve it - '__require("react-native-node-api")': - 'require("react-native-node-api")', - }, + Object.fromEntries( + targetNames.map((targetName) => [ + // Replace "__require" statement with a regular "require" to allow Metro to resolve it + `__require("./build/Release/${targetName}")`, + `require("./build/Release/${targetName}")`, + ]) + ), { delimiters: ["", ""], } @@ -81,7 +75,7 @@ function testBundle( ], }), ], - external: ["react-native-node-api"], + external: targetNames.map((targetName) => `./build/Release/${targetName}`), })); } From 8d111d1d658903946ee7f71582d02d83121d29fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Thu, 24 Jul 2025 23:03:58 +0200 Subject: [PATCH 07/14] Build node-tests in parallel --- package-lock.json | 1 + packages/node-tests/package.json | 1 + packages/node-tests/scripts/build-tests.mts | 38 ++++++++++++++------- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 20c9d3ba..d0cd9c23 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15396,6 +15396,7 @@ "packages/node-tests": { "name": "@react-native-node-api/node-tests", "devDependencies": { + "bufout": "^0.3.2", "cmake-js": "^7.3.1", "cmake-rn": "*", "gyp-to-cmake": "*", diff --git a/packages/node-tests/package.json b/packages/node-tests/package.json index 1bcedb28..1d5fd420 100644 --- a/packages/node-tests/package.json +++ b/packages/node-tests/package.json @@ -18,6 +18,7 @@ "bootstrap": "npm run copy-tests && npm run gyp-to-cmake && npm run build-tests && npm run bundle" }, "devDependencies": { + "bufout": "^0.3.2", "cmake-js": "^7.3.1", "cmake-rn": "*", "gyp-to-cmake": "*", diff --git a/packages/node-tests/scripts/build-tests.mts b/packages/node-tests/scripts/build-tests.mts index bfd05f29..63f9e80a 100644 --- a/packages/node-tests/scripts/build-tests.mts +++ b/packages/node-tests/scripts/build-tests.mts @@ -1,15 +1,29 @@ -import { execSync } from "node:child_process"; +import path from "node:path"; + +import { spawn, SpawnFailure } from "bufout"; import { findCMakeProjects } from "./utils.mjs"; -const projectDirectories = findCMakeProjects(); - -for (const projectDirectory of projectDirectories) { - console.log( - `Running "cmake-rn" in ${projectDirectory} to build for React Native` - ); - execSync("cmake-rn", { - cwd: projectDirectory, - stdio: "inherit", - }); -} +const rootPath = path.join(import.meta.dirname, ".."); +const projectPaths = findCMakeProjects(); + +await Promise.all( + projectPaths.map(async (projectPath) => { + console.log( + `Running "cmake-rn" in ${path.relative( + rootPath, + projectPath + )} to build for React Native` + ); + await spawn("cmake-rn", [], { cwd: projectPath, outputMode: "buffered" }); + }) +).catch((err) => { + process.exitCode = 1; + if (err instanceof SpawnFailure) { + err.flushOutput("both"); + } else if (err instanceof Error) { + console.error(err.message); + } else { + console.error(err); + } +}); From e2524c71e9ada7020a0002f6cdc31d14f1a22112 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Thu, 24 Jul 2025 23:05:22 +0200 Subject: [PATCH 08/14] Add node-api tests to the node repo checkout --- packages/node-tests/scripts/copy-tests.mts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/node-tests/scripts/copy-tests.mts b/packages/node-tests/scripts/copy-tests.mts index 5e6a0638..25fbd4fe 100644 --- a/packages/node-tests/scripts/copy-tests.mts +++ b/packages/node-tests/scripts/copy-tests.mts @@ -12,6 +12,8 @@ const ALLOW_LIST = [ "js-native-api/common-inl.h", "js-native-api/entry_point.h", "js-native-api/2_function_arguments", + // "node-api/test_async", + // "node-api/test_buffer", ]; console.log("Copying files to", TESTS_DIR); @@ -35,10 +37,14 @@ if (!fs.existsSync(NODE_REPO_DIR)) { cwd: NODE_REPO_DIR, }); // Enable sparse checkout - cp.execFileSync("git", ["sparse-checkout", "set", "test/js-native-api"], { - stdio: "inherit", - cwd: NODE_REPO_DIR, - }); + cp.execFileSync( + "git", + ["sparse-checkout", "set", "test/js-native-api", "test/node-api"], + { + stdio: "inherit", + cwd: NODE_REPO_DIR, + } + ); // Pull the latest changes from the master branch console.log("Pulling latest changes from Node.js repository..."); cp.execFileSync("git", ["pull", "--depth=1", "origin", "main"], { @@ -63,7 +69,3 @@ for (const src of ALLOW_LIST) { console.log("Copying from", srcPath, "to", destPath); fs.cpSync(srcPath, destPath, { recursive: true }); } - -if (!fs.existsSync(path.join(TESTS_DIR, "common.js"))) { - // TODO: Perform a symlink of a common.js file from src/common.js -} From 89a2e8192adf3850d0fc897638276e4422be8e70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Thu, 24 Jul 2025 23:05:35 +0200 Subject: [PATCH 09/14] Use node --run --- packages/node-tests/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node-tests/package.json b/packages/node-tests/package.json index 1d5fd420..02e98b4f 100644 --- a/packages/node-tests/package.json +++ b/packages/node-tests/package.json @@ -15,7 +15,7 @@ "gyp-to-cmake": "gyp-to-cmake ./tests", "build-tests": "tsx scripts/build-tests.mts", "bundle": "rolldown -c rolldown.config.mts", - "bootstrap": "npm run copy-tests && npm run gyp-to-cmake && npm run build-tests && npm run bundle" + "bootstrap": "node --run copy-tests && node --run gyp-to-cmake && node --run build-tests && node --run bundle" }, "devDependencies": { "bufout": "^0.3.2", From 5898088537ab5a73637cfeab5c01c03069068f32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Fri, 25 Jul 2025 22:06:48 +0200 Subject: [PATCH 10/14] Generate entrypoint --- eslint.config.js | 3 + packages/node-tests/.gitignore | 2 + packages/node-tests/package.json | 5 +- .../scripts/generate-entrypoint.mts | 62 +++++++++++++++++++ packages/node-tests/src/index.ts | 8 --- packages/node-tests/tests.generated.d.ts | 7 +++ packages/node-tests/tsconfig.common.json | 11 ++++ packages/node-tests/tsconfig.json | 2 +- packages/node-tests/tsconfig.tests.json | 12 ---- 9 files changed, 89 insertions(+), 23 deletions(-) create mode 100644 packages/node-tests/scripts/generate-entrypoint.mts delete mode 100644 packages/node-tests/src/index.ts create mode 100644 packages/node-tests/tests.generated.d.ts create mode 100644 packages/node-tests/tsconfig.common.json delete mode 100644 packages/node-tests/tsconfig.tests.json diff --git a/eslint.config.js b/eslint.config.js index 9b1b463e..794defe7 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -13,6 +13,8 @@ export default tseslint.config( "packages/host/hermes/**", "packages/node-addon-examples/examples/**", "packages/ferric-example/ferric_example.d.ts", + "packages/node-tests/node/**", + "packages/node-tests/tests/**", ]), eslint.configs.recommended, tseslint.configs.recommended, @@ -23,6 +25,7 @@ export default tseslint.config( "packages/node-addon-examples/*.js", "packages/host/babel-plugin.js", "packages/host/react-native.config.js", + "packages/node-tests/tests.generated.js", ], languageOptions: { parserOptions: { diff --git a/packages/node-tests/.gitignore b/packages/node-tests/.gitignore index 88db8942..b73ec41d 100644 --- a/packages/node-tests/.gitignore +++ b/packages/node-tests/.gitignore @@ -1,2 +1,4 @@ node/ tests/ + +tests.generated.js diff --git a/packages/node-tests/package.json b/packages/node-tests/package.json index 02e98b4f..ccb9a8ad 100644 --- a/packages/node-tests/package.json +++ b/packages/node-tests/package.json @@ -2,7 +2,7 @@ "name": "@react-native-node-api/node-tests", "description": "Harness for running the Node.js tests from https://github.com/nodejs/node/tree/main/test", "type": "commonjs", - "main": "dist/index.js", + "main": "tests.generated.js", "private": true, "homepage": "https://github.com/callstackincubator/react-native-node-api", "repository": { @@ -15,7 +15,8 @@ "gyp-to-cmake": "gyp-to-cmake ./tests", "build-tests": "tsx scripts/build-tests.mts", "bundle": "rolldown -c rolldown.config.mts", - "bootstrap": "node --run copy-tests && node --run gyp-to-cmake && node --run build-tests && node --run bundle" + "generate-entrypoint": "tsx scripts/generate-entrypoint.mts", + "bootstrap": "node --run copy-tests && node --run gyp-to-cmake && node --run build-tests && node --run bundle && node --run generate-entrypoint" }, "devDependencies": { "bufout": "^0.3.2", diff --git a/packages/node-tests/scripts/generate-entrypoint.mts b/packages/node-tests/scripts/generate-entrypoint.mts new file mode 100644 index 00000000..95701a62 --- /dev/null +++ b/packages/node-tests/scripts/generate-entrypoint.mts @@ -0,0 +1,62 @@ +import assert from "node:assert/strict"; +import fs from "node:fs"; +import path from "node:path"; + +const packageRoot = path.join(import.meta.dirname, ".."); +const entrypointPath = path.join(packageRoot, "tests.generated.js"); + +const testPaths = fs.globSync("**/*.bundle.js", { + cwd: path.join(packageRoot, "tests"), +}); + +interface TestSuite { + [key: string]: string | TestSuite; +} + +const suites: TestSuite = {}; + +for (const testPath of testPaths) { + const paths = testPath.split(path.sep); + const testName = paths.pop(); + assert(typeof testName === "string"); + let parent: TestSuite = suites; + for (const part of paths) { + if (!parent[part]) { + // Init if missing + parent[part] = {}; + } + assert(typeof parent[part] === "object"); + parent = parent[part]; + } + parent[path.basename(testName, ".bundle.js")] = path.join("tests", testPath); +} + +function suiteToString(suite: TestSuite, indent = 1): string { + const padding = " ".repeat(indent); + return Object.entries(suite) + .map(([key, value]) => { + if (typeof value === "string") { + return `${padding}"${key}": () => require("./${value}")`; + } else { + return `${padding}"${key}": {\n${suiteToString( + value, + indent + 1 + )}\n${padding}}`; + } + }) + .join(", "); +} + +const comment = "Generated by ./scripts/generate-entrypoint.mts"; + +console.log( + `Writing entrypoint to ${path.relative( + import.meta.dirname, + entrypointPath + )} for ${testPaths.length} tests ...` +); + +fs.writeFileSync( + entrypointPath, + `/* ${comment} */\nmodule.exports.suites = {\n${suiteToString(suites)}\n};` +); diff --git a/packages/node-tests/src/index.ts b/packages/node-tests/src/index.ts deleted file mode 100644 index 6e8e7f5c..00000000 --- a/packages/node-tests/src/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* eslint-disable @typescript-eslint/no-require-imports */ - -export const suites: Record void>> = { - "2_function_arguments": { - test: () => - require("../tests/js-native-api/2_function_arguments/test.bundle.js"), - }, -}; diff --git a/packages/node-tests/tests.generated.d.ts b/packages/node-tests/tests.generated.d.ts new file mode 100644 index 00000000..e801e4b1 --- /dev/null +++ b/packages/node-tests/tests.generated.d.ts @@ -0,0 +1,7 @@ +// Despite the name, this file isn't generated. + +export interface TestSuite { + [key: string]: TestSuite | (() => void); +} + +export declare const suites: TestSuite; diff --git a/packages/node-tests/tsconfig.common.json b/packages/node-tests/tsconfig.common.json new file mode 100644 index 00000000..127dd86b --- /dev/null +++ b/packages/node-tests/tsconfig.common.json @@ -0,0 +1,11 @@ +{ + "extends": "@tsconfig/node22/tsconfig.json", + "compilerOptions": { + "composite": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "dist", + "types": [] + }, + "include": ["common.ts"] +} diff --git a/packages/node-tests/tsconfig.json b/packages/node-tests/tsconfig.json index 4b659503..ac70f799 100644 --- a/packages/node-tests/tsconfig.json +++ b/packages/node-tests/tsconfig.json @@ -1,7 +1,7 @@ { "files": [], "references": [ - { "path": "./tsconfig.tests.json" }, + { "path": "./tsconfig.common.json" }, { "path": "./tsconfig.node-scripts.json" } ] } diff --git a/packages/node-tests/tsconfig.tests.json b/packages/node-tests/tsconfig.tests.json deleted file mode 100644 index 629f51e3..00000000 --- a/packages/node-tests/tsconfig.tests.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "@tsconfig/react-native", - "compilerOptions": { - "composite": true, - "noEmit": false, - "module": "commonjs", - "outDir": "dist", - "rootDir": "src", - "types": ["react-native"] - }, - "include": ["src/*.ts"] -} From a011cf08021d1facbdc8c13317e00c827be1041a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Fri, 25 Jul 2025 22:07:10 +0200 Subject: [PATCH 11/14] Use fs to derive rolldown config --- packages/node-tests/rolldown.config.mts | 35 ++++++++++++++++--------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/packages/node-tests/rolldown.config.mts b/packages/node-tests/rolldown.config.mts index 4824d5e3..70a334cb 100644 --- a/packages/node-tests/rolldown.config.mts +++ b/packages/node-tests/rolldown.config.mts @@ -23,19 +23,17 @@ function readGypTargetNames(gypFilePath: string): string[] { }); } -function testBundle( - testDirectory: string, - testFiles: string[] -): RolldownOptions[] { - const gypFilePath = path.join(testDirectory, "binding.gyp"); +function testSuiteConfig(suitePath: string): RolldownOptions[] { + const testFiles = fs.globSync("*.js", { + cwd: suitePath, + exclude: ["*.bundle.js"], + }); + const gypFilePath = path.join(suitePath, "binding.gyp"); const targetNames = readGypTargetNames(gypFilePath); return testFiles.map((testFile) => ({ - input: path.join(testDirectory, testFile), + input: path.join(suitePath, testFile), output: { - file: path.join( - testDirectory, - path.basename(testFile, ".js") + ".bundle.js" - ), + file: path.join(suitePath, path.basename(testFile, ".js") + ".bundle.js"), }, resolve: { conditionNames: ["react-native"], @@ -79,6 +77,17 @@ function testBundle( })); } -export default defineConfig([ - ...testBundle("tests/js-native-api/2_function_arguments", ["test.js"]), -]); +const suitePaths = fs + .globSync("tests/*/*", { + cwd: import.meta.dirname, + withFileTypes: true, + }) + .filter((dirent) => dirent.isDirectory()) + .map((dirent) => + path.join( + path.relative(import.meta.dirname, dirent.parentPath), + dirent.name + ) + ); + +export default defineConfig(suitePaths.flatMap(testSuiteConfig)); From 77d261b9733ccc12c25fa4fa4932c34ac22e67a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Fri, 25 Jul 2025 22:10:18 +0200 Subject: [PATCH 12/14] Revert parallel builds This seemed to be causing issues on Windows --- package-lock.json | 2 -- packages/node-tests/package.json | 2 -- packages/node-tests/scripts/build-tests.mts | 32 +++++++-------------- 3 files changed, 10 insertions(+), 26 deletions(-) diff --git a/package-lock.json b/package-lock.json index d0cd9c23..5e84baf8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15396,8 +15396,6 @@ "packages/node-tests": { "name": "@react-native-node-api/node-tests", "devDependencies": { - "bufout": "^0.3.2", - "cmake-js": "^7.3.1", "cmake-rn": "*", "gyp-to-cmake": "*", "prebuildify": "^6.0.1", diff --git a/packages/node-tests/package.json b/packages/node-tests/package.json index ccb9a8ad..1cc6cd20 100644 --- a/packages/node-tests/package.json +++ b/packages/node-tests/package.json @@ -19,8 +19,6 @@ "bootstrap": "node --run copy-tests && node --run gyp-to-cmake && node --run build-tests && node --run bundle && node --run generate-entrypoint" }, "devDependencies": { - "bufout": "^0.3.2", - "cmake-js": "^7.3.1", "cmake-rn": "*", "gyp-to-cmake": "*", "prebuildify": "^6.0.1", diff --git a/packages/node-tests/scripts/build-tests.mts b/packages/node-tests/scripts/build-tests.mts index 63f9e80a..c2eb6b79 100644 --- a/packages/node-tests/scripts/build-tests.mts +++ b/packages/node-tests/scripts/build-tests.mts @@ -1,29 +1,17 @@ import path from "node:path"; - -import { spawn, SpawnFailure } from "bufout"; +import { spawnSync } from "node:child_process"; import { findCMakeProjects } from "./utils.mjs"; const rootPath = path.join(import.meta.dirname, ".."); const projectPaths = findCMakeProjects(); -await Promise.all( - projectPaths.map(async (projectPath) => { - console.log( - `Running "cmake-rn" in ${path.relative( - rootPath, - projectPath - )} to build for React Native` - ); - await spawn("cmake-rn", [], { cwd: projectPath, outputMode: "buffered" }); - }) -).catch((err) => { - process.exitCode = 1; - if (err instanceof SpawnFailure) { - err.flushOutput("both"); - } else if (err instanceof Error) { - console.error(err.message); - } else { - console.error(err); - } -}); +for (const projectPath of projectPaths) { + console.log( + `Running "cmake-rn" in ${path.relative( + rootPath, + projectPath + )} to build for React Native` + ); + spawnSync("cmake-rn", [], { cwd: projectPath, stdio: "inherit" }); +} From 58a58ca49dd92ea0168fe289edc31b22f33241f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Wed, 30 Jul 2025 19:33:37 +0200 Subject: [PATCH 13/14] Adopt test app to recursive suite of suites or tests --- apps/test-app/App.tsx | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/apps/test-app/App.tsx b/apps/test-app/App.tsx index ae6a35f3..102e3c8c 100644 --- a/apps/test-app/App.tsx +++ b/apps/test-app/App.tsx @@ -50,13 +50,19 @@ function loadTests({ }); describeIf(nodeTests, "Node Tests", () => { - for (const [suiteName, examples] of Object.entries(nodeTestsSuites)) { - describe(suiteName, () => { - for (const [exampleName, requireTest] of Object.entries(examples)) { - it(exampleName, requireTest); + function registerTestSuite(suite: typeof nodeTestsSuites) { + for (const [name, suiteOrTest] of Object.entries(suite)) { + if (typeof suiteOrTest === "function") { + it(name, suiteOrTest); + } else { + describe(name, () => { + registerTestSuite(suiteOrTest); + }); } - }); + } } + + registerTestSuite(nodeTestsSuites); }); describeIf(ferricExample, "ferric-example", () => { From 8d4c8f2f1c82fc952a6fd5036f4e34876334a165 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Wed, 30 Jul 2025 19:34:28 +0200 Subject: [PATCH 14/14] Ran prettier --- packages/node-tests/rolldown.config.mts | 16 ++++++++-------- packages/node-tests/scripts/build-tests.mts | 4 ++-- packages/node-tests/scripts/copy-tests.mts | 6 +++--- .../node-tests/scripts/generate-entrypoint.mts | 8 ++++---- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/node-tests/rolldown.config.mts b/packages/node-tests/rolldown.config.mts index 70a334cb..c1b7f327 100644 --- a/packages/node-tests/rolldown.config.mts +++ b/packages/node-tests/rolldown.config.mts @@ -9,7 +9,7 @@ function readGypTargetNames(gypFilePath: string): string[] { const contents = JSON.parse(fs.readFileSync(gypFilePath, "utf-8")) as unknown; assert( typeof contents === "object" && contents !== null, - "Expected gyp file to contain a valid JSON object" + "Expected gyp file to contain a valid JSON object", ); assert("targets" in contents, "Expected targets in gyp file"); const { targets } = contents; @@ -17,7 +17,7 @@ function readGypTargetNames(gypFilePath: string): string[] { return targets.map(({ target_name }) => { assert( typeof target_name === "string", - "Expected target_name to be a string" + "Expected target_name to be a string", ); return target_name; }); @@ -46,11 +46,11 @@ function testSuiteConfig(suitePath: string): RolldownOptions[] { targetNames.map((targetName) => [ `require(\`./build/\${common.buildType}/${targetName}\`)`, `require("./build/Release/${targetName}")`, - ]) + ]), ), { delimiters: ["", ""], - } + }, ), replacePlugin( Object.fromEntries( @@ -58,11 +58,11 @@ function testSuiteConfig(suitePath: string): RolldownOptions[] { // Replace "__require" statement with a regular "require" to allow Metro to resolve it `__require("./build/Release/${targetName}")`, `require("./build/Release/${targetName}")`, - ]) + ]), ), { delimiters: ["", ""], - } + }, ), aliasPlugin({ entries: [ @@ -86,8 +86,8 @@ const suitePaths = fs .map((dirent) => path.join( path.relative(import.meta.dirname, dirent.parentPath), - dirent.name - ) + dirent.name, + ), ); export default defineConfig(suitePaths.flatMap(testSuiteConfig)); diff --git a/packages/node-tests/scripts/build-tests.mts b/packages/node-tests/scripts/build-tests.mts index c2eb6b79..de879e8c 100644 --- a/packages/node-tests/scripts/build-tests.mts +++ b/packages/node-tests/scripts/build-tests.mts @@ -10,8 +10,8 @@ for (const projectPath of projectPaths) { console.log( `Running "cmake-rn" in ${path.relative( rootPath, - projectPath - )} to build for React Native` + projectPath, + )} to build for React Native`, ); spawnSync("cmake-rn", [], { cwd: projectPath, stdio: "inherit" }); } diff --git a/packages/node-tests/scripts/copy-tests.mts b/packages/node-tests/scripts/copy-tests.mts index 25fbd4fe..0b14099b 100644 --- a/packages/node-tests/scripts/copy-tests.mts +++ b/packages/node-tests/scripts/copy-tests.mts @@ -24,7 +24,7 @@ console.log("Copying files to", TESTS_DIR); if (!fs.existsSync(NODE_REPO_DIR)) { console.log( "Sparse and shallow cloning Node.js repository to", - NODE_REPO_DIR + NODE_REPO_DIR, ); // Init a new git repository @@ -43,7 +43,7 @@ if (!fs.existsSync(NODE_REPO_DIR)) { { stdio: "inherit", cwd: NODE_REPO_DIR, - } + }, ); // Pull the latest changes from the master branch console.log("Pulling latest changes from Node.js repository..."); @@ -61,7 +61,7 @@ for (const src of ALLOW_LIST) { if (fs.existsSync(destPath)) { console.warn( - `Destination path ${destPath} already exists - skipping copy of ${src}.` + `Destination path ${destPath} already exists - skipping copy of ${src}.`, ); continue; } diff --git a/packages/node-tests/scripts/generate-entrypoint.mts b/packages/node-tests/scripts/generate-entrypoint.mts index 95701a62..a0cf8c8d 100644 --- a/packages/node-tests/scripts/generate-entrypoint.mts +++ b/packages/node-tests/scripts/generate-entrypoint.mts @@ -40,7 +40,7 @@ function suiteToString(suite: TestSuite, indent = 1): string { } else { return `${padding}"${key}": {\n${suiteToString( value, - indent + 1 + indent + 1, )}\n${padding}}`; } }) @@ -52,11 +52,11 @@ const comment = "Generated by ./scripts/generate-entrypoint.mts"; console.log( `Writing entrypoint to ${path.relative( import.meta.dirname, - entrypointPath - )} for ${testPaths.length} tests ...` + entrypointPath, + )} for ${testPaths.length} tests ...`, ); fs.writeFileSync( entrypointPath, - `/* ${comment} */\nmodule.exports.suites = {\n${suiteToString(suites)}\n};` + `/* ${comment} */\nmodule.exports.suites = {\n${suiteToString(suites)}\n};`, );