diff --git a/.changeset/fresh-nails-repair.md b/.changeset/fresh-nails-repair.md new file mode 100644 index 00000000..2de1fa30 --- /dev/null +++ b/.changeset/fresh-nails-repair.md @@ -0,0 +1,8 @@ +--- +"gyp-to-cmake": patch +"cmake-rn": patch +"ferric-cli": patch +"react-native-node-api": patch +--- + +Refactored CLIs to use a shared utility package diff --git a/configs/tsconfig.cli.json b/configs/tsconfig.cli.json new file mode 100644 index 00000000..4e77cced --- /dev/null +++ b/configs/tsconfig.cli.json @@ -0,0 +1,12 @@ +{ + "extends": "@tsconfig/node22/tsconfig.json", + "compilerOptions": { + "composite": true, + "declarationMap": true, + "outDir": "${configDir}/dist", + "rootDir": "${configDir}/src", + "types": ["node"] + }, + "include": ["${configDir}/src/*.ts"], + "exclude": ["${configDir}/**.test.ts"] +} diff --git a/package-lock.json b/package-lock.json index 98108da6..96a644fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "license": "MIT", "workspaces": [ "apps/test-app", + "packages/cli-utils", "packages/gyp-to-cmake", "packages/cmake-rn", "packages/ferric", @@ -5404,63 +5405,6 @@ "yaml": "^2.2.1" } }, - "node_modules/@react-native-community/cli-doctor/node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "license": "MIT", - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@react-native-community/cli-doctor/node_modules/is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@react-native-community/cli-doctor/node_modules/ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "license": "MIT", - "dependencies": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@react-native-community/cli-doctor/node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "license": "MIT", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@react-native-community/cli-doctor/node_modules/semver": { "version": "7.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", @@ -5473,12 +5417,6 @@ "node": ">=10" } }, - "node_modules/@react-native-community/cli-doctor/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "license": "ISC" - }, "node_modules/@react-native-community/cli-platform-android": { "version": "20.0.2", "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-android/-/cli-platform-android-20.0.2.tgz", @@ -5550,18 +5488,6 @@ "semver": "^7.5.2" } }, - "node_modules/@react-native-community/cli-tools/node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "license": "MIT", - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@react-native-community/cli-tools/node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -5578,15 +5504,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@react-native-community/cli-tools/node_modules/is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/@react-native-community/cli-tools/node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -5602,29 +5519,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@react-native-community/cli-tools/node_modules/ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "license": "MIT", - "dependencies": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@react-native-community/cli-tools/node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -5655,19 +5549,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@react-native-community/cli-tools/node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "license": "MIT", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@react-native-community/cli-tools/node_modules/semver": { "version": "7.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", @@ -5680,12 +5561,6 @@ "node": ">=10" } }, - "node_modules/@react-native-community/cli-tools/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "license": "ISC" - }, "node_modules/@react-native-community/cli-tools/node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -5806,6 +5681,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@react-native-node-api/cli-utils": { + "resolved": "packages/cli-utils", + "link": true + }, "node_modules/@react-native-node-api/ferric-example": { "resolved": "packages/ferric-example", "link": true @@ -6678,9 +6557,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.18.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.5.tgz", - "integrity": "sha512-g9BpPfJvxYBXUWI9bV37j6d6LTMNQ88hPwdWWUeYZnMhlo66FIg9gCc1/DZb15QylJSKwOZjwrckvOTWpOiChg==", + "version": "22.18.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.6.tgz", + "integrity": "sha512-r8uszLPpeIWbNKtvWRt/DbVi5zbqZyj1PTmhRMqBMvDnaz1QpmSKujUtJLrqGZeoM8v72MfYggDceY4K1itzWQ==", "license": "MIT", "dependencies": { "undici-types": "~6.21.0" @@ -7943,18 +7822,15 @@ } }, "node_modules/cli-cursor": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", - "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "license": "MIT", "dependencies": { - "restore-cursor": "^5.0.0" + "restore-cursor": "^3.1.0" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/cli-spinners": { @@ -8007,35 +7883,6 @@ "node": ">=12" } }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/cliui/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -8647,9 +8494,9 @@ } }, "node_modules/emoji-regex": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.5.0.tgz", - "integrity": "sha512-lb49vf1Xzfx080OKA0o6l8DQQpV+6Vg95zyCJX9VB/BqKYlhG7N4wgROUUHRA+ZPUefLnteQOad7z1kT2bV7bg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "license": "MIT" }, "node_modules/encodeurl": { @@ -9624,23 +9471,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/gauge/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/gauge/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/gauge/node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -9648,21 +9478,6 @@ "dev": true, "license": "ISC" }, - "node_modules/gauge/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -10295,15 +10110,12 @@ } }, "node_modules/is-interactive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", - "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/is-nan": { @@ -10923,35 +10735,6 @@ "node": ">=0.10.0" } }, - "node_modules/logkitty/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/logkitty/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/logkitty/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/logkitty/node_modules/y18n": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", @@ -12247,107 +12030,28 @@ } }, "node_modules/ora": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz", - "integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", "license": "MIT", "dependencies": { - "chalk": "^5.3.0", - "cli-cursor": "^5.0.0", - "cli-spinners": "^2.9.2", - "is-interactive": "^2.0.0", - "is-unicode-supported": "^2.0.0", - "log-symbols": "^6.0.0", - "stdin-discarder": "^0.2.2", - "string-width": "^7.2.0", - "strip-ansi": "^7.1.0" + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" }, "engines": { - "node": ">=18" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ora/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/ora/node_modules/chalk": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/ora/node_modules/is-unicode-supported": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", - "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ora/node_modules/log-symbols": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", - "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", - "license": "MIT", - "dependencies": { - "chalk": "^5.3.0", - "is-unicode-supported": "^1.3.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ora/node_modules/log-symbols/node_modules/is-unicode-supported": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ora/node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/outdent": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.5.0.tgz", @@ -13317,35 +13021,23 @@ } }, "node_modules/restore-cursor": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", - "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "license": "MIT", "dependencies": { - "onetime": "^7.0.0", - "signal-exit": "^4.1.0" + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/restore-cursor/node_modules/onetime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", - "license": "MIT", - "dependencies": { - "mimic-function": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" }, "node_modules/reusify": { "version": "1.1.0", @@ -13965,20 +13657,17 @@ } }, "node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/string-width-cjs": { @@ -13996,12 +13685,6 @@ "node": ">=8" } }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -14011,31 +13694,13 @@ "node": ">=8" } }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "node_modules/string-width/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "node": ">=8" } }, "node_modules/strip-ansi": { @@ -14722,38 +14387,6 @@ "string-width": "^1.0.2 || 2 || 3 || 4" } }, - "node_modules/wide-align/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/wide-align/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wide-align/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", @@ -14802,64 +14435,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -14963,35 +14538,6 @@ "node": ">=10" } }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/yocto-queue": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.1.tgz", @@ -15026,34 +14572,39 @@ "url": "https://github.com/sponsors/colinhacks" } }, - "packages/cmake-rn": { - "version": "0.3.1", + "packages/cli-utils": { + "name": "@react-native-node-api/cli-utils", + "version": "0.1.0", "dependencies": { - "@commander-js/extra-typings": "^13.1.0", + "@commander-js/extra-typings": "^14.0.0", "bufout": "^0.3.2", "chalk": "^5.4.1", - "commander": "^13.1.0", - "ora": "^8.2.0", - "react-native-node-api": "0.4.0" - }, - "bin": { - "cmake-rn": "bin/cmake-rn.js" - }, - "peerDependencies": { - "node-addon-api": "^8.3.1", - "node-api-headers": "^1.5.0" + "commander": "^14.0.1", + "ora": "^8.2.0" } }, - "packages/cmake-rn/node_modules/@commander-js/extra-typings": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/@commander-js/extra-typings/-/extra-typings-13.1.0.tgz", - "integrity": "sha512-q5P52BYb1hwVWE6dtID7VvuJWrlfbCv4klj7BjUUOqMz4jbSZD4C9fJ9lRjL2jnBGTg+gDDlaXN51rkWcLk4fg==", + "packages/cli-utils/node_modules/@commander-js/extra-typings": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@commander-js/extra-typings/-/extra-typings-14.0.0.tgz", + "integrity": "sha512-hIn0ncNaJRLkZrxBIp5AsW/eXEHNKYQBh0aPdoUqNgD+Io3NIykQqpKFyKcuasZhicGaEZJX/JBSIkZ4e5x8Dg==", "license": "MIT", "peerDependencies": { - "commander": "~13.1.0" + "commander": "~14.0.0" } }, - "packages/cmake-rn/node_modules/chalk": { + "packages/cli-utils/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "packages/cli-utils/node_modules/chalk": { "version": "5.6.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", @@ -15065,107 +14616,223 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "packages/cmake-rn/node_modules/commander": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", - "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", + "packages/cli-utils/node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, "engines": { "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/ferric": { - "name": "ferric-cli", - "version": "0.3.1", - "dependencies": { - "@commander-js/extra-typings": "^13.1.0", - "@napi-rs/cli": "~3.0.3", - "bufout": "^0.3.2", - "chalk": "^5.4.1", - "commander": "^13.1.0", - "ora": "^8.2.0", - "react-native-node-api": "0.4.0" + "packages/cli-utils/node_modules/commander": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.1.tgz", + "integrity": "sha512-2JkV3gUZUVrbNA+1sjBOYLsMZ5cEEl8GTFP2a4AVz5hvasAMCQ1D2l2le/cX+pV4N6ZU17zjUahLpIXRrnWL8A==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "packages/cli-utils/node_modules/emoji-regex": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.5.0.tgz", + "integrity": "sha512-lb49vf1Xzfx080OKA0o6l8DQQpV+6Vg95zyCJX9VB/BqKYlhG7N4wgROUUHRA+ZPUefLnteQOad7z1kT2bV7bg==", + "license": "MIT" + }, + "packages/cli-utils/node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "license": "MIT", + "engines": { + "node": ">=12" }, - "bin": { - "ferric": "bin/ferric.js" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/ferric-example": { - "name": "@react-native-node-api/ferric-example", - "version": "0.1.1", - "devDependencies": { - "ferric-cli": "*" + "packages/cli-utils/node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/ferric/node_modules/@commander-js/extra-typings": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/@commander-js/extra-typings/-/extra-typings-13.1.0.tgz", - "integrity": "sha512-q5P52BYb1hwVWE6dtID7VvuJWrlfbCv4klj7BjUUOqMz4jbSZD4C9fJ9lRjL2jnBGTg+gDDlaXN51rkWcLk4fg==", + "packages/cli-utils/node_modules/log-symbols": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", + "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", "license": "MIT", - "peerDependencies": { - "commander": "~13.1.0" + "dependencies": { + "chalk": "^5.3.0", + "is-unicode-supported": "^1.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/ferric/node_modules/chalk": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "packages/cli-utils/node_modules/log-symbols/node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", "license": "MIT", "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" + "node": ">=12" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/ferric/node_modules/commander": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", - "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", + "packages/cli-utils/node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, "engines": { "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/gyp-to-cmake": { - "version": "0.2.0", + "packages/cli-utils/node_modules/ora": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz", + "integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==", + "license": "MIT", "dependencies": { - "@commander-js/extra-typings": "^13.1.0", - "commander": "^13.1.0", - "gyp-parser": "^1.0.4" + "chalk": "^5.3.0", + "cli-cursor": "^5.0.0", + "cli-spinners": "^2.9.2", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.0.0", + "log-symbols": "^6.0.0", + "stdin-discarder": "^0.2.2", + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0" }, - "bin": { - "gyp-to-cmake": "bin/gyp-to-cmake.js" + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/gyp-to-cmake/node_modules/@commander-js/extra-typings": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/@commander-js/extra-typings/-/extra-typings-13.1.0.tgz", - "integrity": "sha512-q5P52BYb1hwVWE6dtID7VvuJWrlfbCv4klj7BjUUOqMz4jbSZD4C9fJ9lRjL2jnBGTg+gDDlaXN51rkWcLk4fg==", + "packages/cli-utils/node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", "license": "MIT", - "peerDependencies": { - "commander": "~13.1.0" + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/gyp-to-cmake/node_modules/commander": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", - "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", + "packages/cli-utils/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, "engines": { "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/cli-utils/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "packages/cmake-rn": { + "version": "0.3.2", + "dependencies": { + "@react-native-node-api/cli-utils": "0.1.0", + "react-native-node-api": "0.5.0" + }, + "bin": { + "cmake-rn": "bin/cmake-rn.js" + }, + "peerDependencies": { + "node-addon-api": "^8.3.1", + "node-api-headers": "^1.5.0" + } + }, + "packages/ferric": { + "name": "ferric-cli", + "version": "0.3.2", + "dependencies": { + "@napi-rs/cli": "~3.0.3", + "@react-native-node-api/cli-utils": "0.1.0", + "react-native-node-api": "0.5.0" + }, + "bin": { + "ferric": "bin/ferric.js" + } + }, + "packages/ferric-example": { + "name": "@react-native-node-api/ferric-example", + "version": "0.1.1", + "devDependencies": { + "ferric-cli": "*" + } + }, + "packages/gyp-to-cmake": { + "version": "0.2.0", + "dependencies": { + "@react-native-node-api/cli-utils": "0.1.0", + "gyp-parser": "^1.0.4" + }, + "bin": { + "gyp-to-cmake": "bin/gyp-to-cmake.js" } }, "packages/host": { "name": "react-native-node-api", - "version": "0.4.0", + "version": "0.5.0", "license": "MIT", "dependencies": { - "@commander-js/extra-typings": "^13.1.0", - "bufout": "^0.3.2", - "chalk": "^5.4.1", - "commander": "^13.1.0", - "ora": "^8.2.0", + "@react-native-node-api/cli-utils": "0.1.0", "pkg-dir": "^8.0.0", "read-pkg": "^9.0.1" }, @@ -15184,36 +14851,6 @@ "react-native": "0.79.1 || 0.79.2 || 0.79.3 || 0.79.4 || 0.79.5 || 0.79.6 || 0.80.0 || 0.80.1 || 0.80.2 || 0.81.0 || 0.81.1 || 0.81.2 || 0.81.3 || 0.81.4" } }, - "packages/host/node_modules/@commander-js/extra-typings": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/@commander-js/extra-typings/-/extra-typings-13.1.0.tgz", - "integrity": "sha512-q5P52BYb1hwVWE6dtID7VvuJWrlfbCv4klj7BjUUOqMz4jbSZD4C9fJ9lRjL2jnBGTg+gDDlaXN51rkWcLk4fg==", - "license": "MIT", - "peerDependencies": { - "commander": "~13.1.0" - } - }, - "packages/host/node_modules/chalk": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "packages/host/node_modules/commander": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", - "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, "packages/node-addon-examples": { "name": "@react-native-node-api/node-addon-examples", "dependencies": { @@ -15232,7 +14869,7 @@ "cmake-rn": "*", "gyp-to-cmake": "*", "prebuildify": "^6.0.1", - "react-native-node-api": "^0.4.0", + "react-native-node-api": "^0.5.0", "read-pkg": "^9.0.1", "rolldown": "1.0.0-beta.29" } diff --git a/package.json b/package.json index 083d3d02..c20b5813 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "private": true, "workspaces": [ "apps/test-app", + "packages/cli-utils", "packages/gyp-to-cmake", "packages/cmake-rn", "packages/ferric", diff --git a/packages/cli-utils/package.json b/packages/cli-utils/package.json new file mode 100644 index 00000000..bd86f925 --- /dev/null +++ b/packages/cli-utils/package.json @@ -0,0 +1,14 @@ +{ + "name": "@react-native-node-api/cli-utils", + "version": "0.1.0", + "description": "Useful utilities for the CLIs in the React Native Node API mono-repo", + "type": "module", + "main": "dist/index.js", + "dependencies": { + "@commander-js/extra-typings": "^14.0.0", + "bufout": "^0.3.2", + "chalk": "^5.4.1", + "commander": "^14.0.1", + "ora": "^8.2.0" + } +} diff --git a/packages/cli-utils/src/actions.ts b/packages/cli-utils/src/actions.ts new file mode 100644 index 00000000..8cd15a03 --- /dev/null +++ b/packages/cli-utils/src/actions.ts @@ -0,0 +1,50 @@ +import { SpawnFailure } from "bufout"; +import chalk from "chalk"; +import * as commander from "@commander-js/extra-typings"; + +import { UsageError } from "./errors.js"; + +function wrapAction( + fn: (this: Command, ...args: Args) => void | Promise, +) { + return async function (this: Command, ...args: Args) { + try { + await fn.call(this, ...args); + } catch (error) { + process.exitCode = 1; + if (error instanceof SpawnFailure) { + error.flushOutput("both"); + } + if (error instanceof UsageError || error instanceof SpawnFailure) { + console.error(chalk.red("ERROR"), error.message); + if (error.cause instanceof Error) { + console.error(chalk.red("CAUSE"), error.cause.message); + } + if (error instanceof UsageError && error.fix) { + console.error( + chalk.green("FIX"), + error.fix.command + ? chalk.dim("Run: ") + error.fix.command + : error.fix.instructions, + ); + } + } else { + throw error; + } + } + }; +} + +import { Command } from "@commander-js/extra-typings"; + +// Patch Command to wrap all actions with our error handler + +// eslint-disable-next-line @typescript-eslint/unbound-method +const originalAction = Command.prototype.action; + +Command.prototype.action = function action( + this: Command, + fn: Parameters[0], +) { + return originalAction.call(this, wrapAction(fn)); +}; diff --git a/packages/ferric/src/errors.ts b/packages/cli-utils/src/errors.ts similarity index 100% rename from packages/ferric/src/errors.ts rename to packages/cli-utils/src/errors.ts diff --git a/packages/cli-utils/src/index.ts b/packages/cli-utils/src/index.ts new file mode 100644 index 00000000..bf9232fa --- /dev/null +++ b/packages/cli-utils/src/index.ts @@ -0,0 +1,7 @@ +export * from "@commander-js/extra-typings"; +export { default as chalk } from "chalk"; +export * from "ora"; +export * from "bufout"; + +export * from "./actions.js"; +export * from "./errors.js"; diff --git a/packages/cli-utils/tsconfig.json b/packages/cli-utils/tsconfig.json new file mode 100644 index 00000000..aa43e9d9 --- /dev/null +++ b/packages/cli-utils/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../../configs/tsconfig.cli.json" +} diff --git a/packages/cmake-rn/package.json b/packages/cmake-rn/package.json index 694cfe84..74b24aea 100644 --- a/packages/cmake-rn/package.json +++ b/packages/cmake-rn/package.json @@ -22,11 +22,7 @@ "test": "tsx --test --test-reporter=@reporters/github --test-reporter-destination=stdout --test-reporter=spec --test-reporter-destination=stdout" }, "dependencies": { - "@commander-js/extra-typings": "^13.1.0", - "bufout": "^0.3.2", - "chalk": "^5.4.1", - "commander": "^13.1.0", - "ora": "^8.2.0", + "@react-native-node-api/cli-utils": "0.1.0", "react-native-node-api": "0.5.0" }, "peerDependencies": { diff --git a/packages/cmake-rn/src/cli.ts b/packages/cmake-rn/src/cli.ts index 2a0324a5..477f5feb 100644 --- a/packages/cmake-rn/src/cli.ts +++ b/packages/cmake-rn/src/cli.ts @@ -3,10 +3,14 @@ import path from "node:path"; import fs from "node:fs"; import { EventEmitter } from "node:events"; -import { Command, Option } from "@commander-js/extra-typings"; -import { spawn, SpawnFailure } from "bufout"; -import { oraPromise } from "ora"; -import chalk from "chalk"; +import { + chalk, + Command, + Option, + spawn, + oraPromise, +} from "@react-native-node-api/cli-utils"; +import { isSupportedTriplet } from "react-native-node-api"; import { getWeakNodeApiVariables } from "./weak-node-api.js"; import { @@ -16,7 +20,6 @@ import { platformHasTarget, } from "./platforms.js"; import { BaseOpts, TargetContext, Platform } from "./platforms/types.js"; -import { isSupportedTriplet } from "react-native-node-api"; // We're attaching a lot of listeners when spawning in parallel EventEmitter.defaultMaxListeners = 100; @@ -128,126 +131,110 @@ for (const platform of platforms) { program = program.action( async ({ target: requestedTargets, ...baseOptions }) => { - try { - const buildPath = getBuildPath(baseOptions); - if (baseOptions.clean) { - await fs.promises.rm(buildPath, { recursive: true, force: true }); + const buildPath = getBuildPath(baseOptions); + if (baseOptions.clean) { + await fs.promises.rm(buildPath, { recursive: true, force: true }); + } + const targets = new Set(requestedTargets); + + for (const platform of Object.values(platforms)) { + // Forcing the types a bit here, since the platform id option is dynamically added + if ((baseOptions as Record)[platform.id]) { + for (const target of platform.targets) { + targets.add(target); + } } - const targets = new Set(requestedTargets); + } + if (targets.size === 0) { for (const platform of Object.values(platforms)) { - // Forcing the types a bit here, since the platform id option is dynamically added - if ((baseOptions as Record)[platform.id]) { - for (const target of platform.targets) { + if (platform.isSupportedByHost()) { + for (const target of await platform.defaultTargets()) { targets.add(target); } } } - if (targets.size === 0) { - for (const platform of Object.values(platforms)) { - if (platform.isSupportedByHost()) { - for (const target of await platform.defaultTargets()) { - targets.add(target); - } - } - } - if (targets.size === 0) { - throw new Error( - "Found no default targets: Install some platform specific build tools", - ); - } else { - console.error( - chalk.yellowBright("ℹ"), - "Using default targets", - chalk.dim("(" + [...targets].join(", ") + ")"), - ); - } + throw new Error( + "Found no default targets: Install some platform specific build tools", + ); + } else { + console.error( + chalk.yellowBright("ℹ"), + "Using default targets", + chalk.dim("(" + [...targets].join(", ") + ")"), + ); } + } - if (!baseOptions.out) { - baseOptions.out = path.join(buildPath, baseOptions.configuration); - } + if (!baseOptions.out) { + baseOptions.out = path.join(buildPath, baseOptions.configuration); + } - const targetContexts = [...targets].map((target) => { - const platform = findPlatformForTarget(target); - const targetBuildPath = getTargetBuildPath(buildPath, target); - return { - target, - platform, - buildPath: targetBuildPath, - outputPath: path.join(targetBuildPath, "out"), - options: baseOptions, - }; - }); - - // Configure every triplet project - const targetsSummary = chalk.dim( - `(${getTargetsSummary(targetContexts)})`, - ); - await oraPromise( - Promise.all( - targetContexts.map(({ platform, ...context }) => - configureProject(platform, context, baseOptions), - ), + const targetContexts = [...targets].map((target) => { + const platform = findPlatformForTarget(target); + const targetBuildPath = getTargetBuildPath(buildPath, target); + return { + target, + platform, + buildPath: targetBuildPath, + outputPath: path.join(targetBuildPath, "out"), + options: baseOptions, + }; + }); + + // Configure every triplet project + const targetsSummary = chalk.dim(`(${getTargetsSummary(targetContexts)})`); + await oraPromise( + Promise.all( + targetContexts.map(({ platform, ...context }) => + configureProject(platform, context, baseOptions), ), - { - text: `Configuring projects ${targetsSummary}`, - isSilent: baseOptions.verbose, - successText: `Configured projects ${targetsSummary}`, - failText: ({ message }) => `Failed to configure projects: ${message}`, - }, - ); + ), + { + text: `Configuring projects ${targetsSummary}`, + isSilent: baseOptions.verbose, + successText: `Configured projects ${targetsSummary}`, + failText: ({ message }) => `Failed to configure projects: ${message}`, + }, + ); - // Build every triplet project - await oraPromise( - Promise.all( - targetContexts.map(async ({ platform, ...context }) => { - // Delete any stale build artifacts before building - // This is important, since we might rename the output files - await fs.promises.rm(context.outputPath, { - recursive: true, - force: true, - }); - await buildProject(platform, context, baseOptions); - }), - ), + // Build every triplet project + await oraPromise( + Promise.all( + targetContexts.map(async ({ platform, ...context }) => { + // Delete any stale build artifacts before building + // This is important, since we might rename the output files + await fs.promises.rm(context.outputPath, { + recursive: true, + force: true, + }); + await buildProject(platform, context, baseOptions); + }), + ), + { + text: "Building projects", + isSilent: baseOptions.verbose, + successText: "Built projects", + failText: ({ message }) => `Failed to build projects: ${message}`, + }, + ); + + // Perform post-build steps for each platform in sequence + for (const platform of platforms) { + const relevantTargets = targetContexts.filter(({ target }) => + platformHasTarget(platform, target), + ); + if (relevantTargets.length == 0) { + continue; + } + await platform.postBuild( { - text: "Building projects", - isSilent: baseOptions.verbose, - successText: "Built projects", - failText: ({ message }) => `Failed to build projects: ${message}`, + outputPath: baseOptions.out || baseOptions.source, + targets: relevantTargets, }, + baseOptions, ); - - // Perform post-build steps for each platform in sequence - for (const platform of platforms) { - const relevantTargets = targetContexts.filter(({ target }) => - platformHasTarget(platform, target), - ); - if (relevantTargets.length == 0) { - continue; - } - await platform.postBuild( - { - outputPath: baseOptions.out || baseOptions.source, - targets: relevantTargets, - }, - baseOptions, - ); - } - } catch (error) { - if (error instanceof SpawnFailure) { - process.exitCode = 1; - error.flushOutput("both"); - if (baseOptions.verbose) { - console.error( - `\nFailed running: ${chalk.dim(error.command, ...error.args)}\n`, - ); - } - } else { - throw error; - } } }, ); diff --git a/packages/cmake-rn/src/platforms/android.ts b/packages/cmake-rn/src/platforms/android.ts index 63397aa0..ef71afe1 100644 --- a/packages/cmake-rn/src/platforms/android.ts +++ b/packages/cmake-rn/src/platforms/android.ts @@ -2,7 +2,7 @@ import assert from "node:assert/strict"; import fs from "node:fs"; import path from "node:path"; -import { Option } from "@commander-js/extra-typings"; +import { Option, oraPromise, chalk } from "@react-native-node-api/cli-utils"; import { createAndroidLibsDirectory, determineAndroidLibsFilename, @@ -10,8 +10,6 @@ import { } from "react-native-node-api"; import type { Platform } from "./types.js"; -import { oraPromise } from "ora"; -import chalk from "chalk"; // This should match https://github.com/react-native-community/template/blob/main/template/android/build.gradle#L7 const DEFAULT_NDK_VERSION = "27.1.12297006"; diff --git a/packages/cmake-rn/src/platforms/apple.ts b/packages/cmake-rn/src/platforms/apple.ts index ce091dc4..c92c5b9c 100644 --- a/packages/cmake-rn/src/platforms/apple.ts +++ b/packages/cmake-rn/src/platforms/apple.ts @@ -2,8 +2,7 @@ import assert from "node:assert/strict"; import path from "node:path"; import fs from "node:fs"; -import { Option } from "@commander-js/extra-typings"; -import { oraPromise } from "ora"; +import { Option, oraPromise, chalk } from "@react-native-node-api/cli-utils"; import { AppleTriplet as Target, createAppleFramework, @@ -12,7 +11,6 @@ import { } from "react-native-node-api"; import type { Platform } from "./types.js"; -import chalk from "chalk"; type XcodeSDKName = | "iphoneos" diff --git a/packages/cmake-rn/src/platforms/types.ts b/packages/cmake-rn/src/platforms/types.ts index fb7c8f5f..bd3e06a2 100644 --- a/packages/cmake-rn/src/platforms/types.ts +++ b/packages/cmake-rn/src/platforms/types.ts @@ -1,12 +1,13 @@ -import * as commander from "@commander-js/extra-typings"; +import * as cli from "@react-native-node-api/cli-utils"; + import type { program } from "../cli.js"; -type InferOptionValues = ReturnType< +type InferOptionValues = ReturnType< Command["opts"] >; type BaseCommand = typeof program; -type ExtendedCommand = commander.Command< +type ExtendedCommand = cli.Command< [], Opts & InferOptionValues, Record // Global opts are not supported @@ -22,7 +23,7 @@ export type TargetContext = { export type Platform< Targets extends string[] = string[], - Opts extends commander.OptionValues = Record, + Opts extends cli.OptionValues = Record, Command = ExtendedCommand, > = { /** diff --git a/packages/ferric/package.json b/packages/ferric/package.json index 1db23db9..85b8fef6 100644 --- a/packages/ferric/package.json +++ b/packages/ferric/package.json @@ -17,11 +17,7 @@ }, "dependencies": { "@napi-rs/cli": "~3.0.3", - "@commander-js/extra-typings": "^13.1.0", - "bufout": "^0.3.2", - "chalk": "^5.4.1", - "commander": "^13.1.0", - "react-native-node-api": "0.5.0", - "ora": "^8.2.0" + "@react-native-node-api/cli-utils": "0.1.0", + "react-native-node-api": "0.5.0" } } diff --git a/packages/ferric/src/banner.ts b/packages/ferric/src/banner.ts index 820b681d..8bf44cc5 100644 --- a/packages/ferric/src/banner.ts +++ b/packages/ferric/src/banner.ts @@ -1,4 +1,4 @@ -import chalk from "chalk"; +import { chalk } from "@react-native-node-api/cli-utils"; const LINES = [ // Pagga on https://www.asciiart.eu/text-to-ascii-art diff --git a/packages/ferric/src/build.ts b/packages/ferric/src/build.ts index aaf97d77..ec8992ec 100644 --- a/packages/ferric/src/build.ts +++ b/packages/ferric/src/build.ts @@ -1,10 +1,13 @@ import path from "node:path"; import fs from "node:fs"; -import { Command, Option } from "@commander-js/extra-typings"; -import chalk from "chalk"; -import { SpawnFailure } from "bufout"; -import { oraPromise } from "ora"; +import { + chalk, + Command, + Option, + oraPromise, + assertFixable, +} from "@react-native-node-api/cli-utils"; import { determineAndroidLibsFilename, @@ -18,7 +21,6 @@ import { prettyPath, } from "react-native-node-api"; -import { UsageError, assertFixable } from "./errors.js"; import { ensureCargo, build } from "./cargo.js"; import { ALL_TARGETS, @@ -123,208 +125,185 @@ export const buildCommand = new Command("build") configuration, xcframeworkExtension, }) => { - try { - const targets = new Set([...targetArg]); - if (apple) { - for (const target of APPLE_TARGETS) { - targets.add(target); - } + const targets = new Set([...targetArg]); + if (apple) { + for (const target of APPLE_TARGETS) { + targets.add(target); } - if (android) { - for (const target of ANDROID_TARGETS) { - targets.add(target); - } + } + if (android) { + for (const target of ANDROID_TARGETS) { + targets.add(target); } + } - if (targets.size === 0) { - if (isAndroidSupported()) { - if (process.arch === "arm64") { - targets.add("aarch64-linux-android"); - } else if (process.arch === "x64") { - targets.add("x86_64-linux-android"); - } + if (targets.size === 0) { + if (isAndroidSupported()) { + if (process.arch === "arm64") { + targets.add("aarch64-linux-android"); + } else if (process.arch === "x64") { + targets.add("x86_64-linux-android"); } - if (isAppleSupported()) { - if (process.arch === "arm64") { - targets.add("aarch64-apple-ios-sim"); - } + } + if (isAppleSupported()) { + if (process.arch === "arm64") { + targets.add("aarch64-apple-ios-sim"); } - console.error( - chalk.yellowBright("ℹ"), - chalk.dim( - `Using default targets, pass ${chalk.italic( - "--android", - )}, ${chalk.italic("--apple")} or individual ${chalk.italic( - "--target", - )} options, to avoid this.`, - ), - ); } - ensureCargo(); - ensureInstalledTargets(targets); + console.error( + chalk.yellowBright("ℹ"), + chalk.dim( + `Using default targets, pass ${chalk.italic( + "--android", + )}, ${chalk.italic("--apple")} or individual ${chalk.italic( + "--target", + )} options, to avoid this.`, + ), + ); + } + ensureCargo(); + ensureInstalledTargets(targets); - const appleTargets = filterTargetsByPlatform(targets, "apple"); - const androidTargets = filterTargetsByPlatform(targets, "android"); + const appleTargets = filterTargetsByPlatform(targets, "apple"); + const androidTargets = filterTargetsByPlatform(targets, "android"); - const targetsDescription = - targets.size + - (targets.size === 1 ? " target" : " targets") + - chalk.dim(" (" + [...targets].join(", ") + ")"); - const [appleLibraries, androidLibraries] = await oraPromise( - Promise.all([ - Promise.all( - appleTargets.map( - async (target) => - [target, await build({ configuration, target })] as const, - ), + const targetsDescription = + targets.size + + (targets.size === 1 ? " target" : " targets") + + chalk.dim(" (" + [...targets].join(", ") + ")"); + const [appleLibraries, androidLibraries] = await oraPromise( + Promise.all([ + Promise.all( + appleTargets.map( + async (target) => + [target, await build({ configuration, target })] as const, ), - Promise.all( - androidTargets.map( - async (target) => - [ + ), + Promise.all( + androidTargets.map( + async (target) => + [ + target, + await build({ + configuration, target, - await build({ - configuration, - target, - ndkVersion, - androidApiLevel: ANDROID_API_LEVEL, - }), - ] as const, - ), + ndkVersion, + androidApiLevel: ANDROID_API_LEVEL, + }), + ] as const, ), - ]), - { - text: `Building ${targetsDescription}`, - successText: `Built ${targetsDescription}`, - failText: (error: Error) => `Failed to build: ${error.message}`, - }, - ); - - if (androidLibraries.length > 0) { - const libraryPathByTriplet = Object.fromEntries( - androidLibraries.map(([target, outputPath]) => [ - ANDROID_TRIPLET_PER_TARGET[target], - outputPath, - ]), - ) as Record; - - const androidLibsFilename = determineAndroidLibsFilename( - Object.values(libraryPathByTriplet), - ); - const androidLibsOutputPath = path.resolve( - outputPath, - androidLibsFilename, - ); - - await oraPromise( - createAndroidLibsDirectory({ - outputPath: androidLibsOutputPath, - libraryPathByTriplet, - autoLink: true, - }), - { - text: "Assembling Android libs directory", - successText: `Android libs directory assembled into ${prettyPath( - androidLibsOutputPath, - )}`, - failText: ({ message }) => - `Failed to assemble Android libs directory: ${message}`, - }, - ); - } - - if (appleLibraries.length > 0) { - const libraryPaths = await combineLibraries(appleLibraries); - const frameworkPaths = libraryPaths.map(createAppleFramework); - const xcframeworkFilename = determineXCFrameworkFilename( - frameworkPaths, - xcframeworkExtension ? ".xcframework" : ".apple.node", - ); + ), + ]), + { + text: `Building ${targetsDescription}`, + successText: `Built ${targetsDescription}`, + failText: (error: Error) => `Failed to build: ${error.message}`, + }, + ); - // Create the xcframework - const xcframeworkOutputPath = path.resolve( + if (androidLibraries.length > 0) { + const libraryPathByTriplet = Object.fromEntries( + androidLibraries.map(([target, outputPath]) => [ + ANDROID_TRIPLET_PER_TARGET[target], outputPath, - xcframeworkFilename, - ); - - await oraPromise( - createXCframework({ - outputPath: xcframeworkOutputPath, - frameworkPaths, - autoLink: true, - }), - { - text: "Assembling XCFramework", - successText: `XCFramework assembled into ${chalk.dim( - path.relative(process.cwd(), xcframeworkOutputPath), - )}`, - failText: ({ message }) => - `Failed to assemble XCFramework: ${message}`, - }, - ); - } + ]), + ) as Record; - const libraryName = determineLibraryBasename([ - ...androidLibraries.map(([, outputPath]) => outputPath), - ...appleLibraries.map(([, outputPath]) => outputPath), - ]); + const androidLibsFilename = determineAndroidLibsFilename( + Object.values(libraryPathByTriplet), + ); + const androidLibsOutputPath = path.resolve( + outputPath, + androidLibsFilename, + ); - const declarationsFilename = `${libraryName}.d.ts`; - const declarationsPath = path.join(outputPath, declarationsFilename); await oraPromise( - generateTypeScriptDeclarations({ - outputFilename: declarationsFilename, - createPath: process.cwd(), - outputPath, + createAndroidLibsDirectory({ + outputPath: androidLibsOutputPath, + libraryPathByTriplet, + autoLink: true, }), { - text: "Generating TypeScript declarations", - successText: `Generated TypeScript declarations ${prettyPath( - declarationsPath, + text: "Assembling Android libs directory", + successText: `Android libs directory assembled into ${prettyPath( + androidLibsOutputPath, )}`, - failText: (error) => - `Failed to generate TypeScript declarations: ${error.message}`, + failText: ({ message }) => + `Failed to assemble Android libs directory: ${message}`, }, ); + } - const entrypointPath = path.join(outputPath, `${libraryName}.js`); + if (appleLibraries.length > 0) { + const libraryPaths = await combineLibraries(appleLibraries); + const frameworkPaths = libraryPaths.map(createAppleFramework); + const xcframeworkFilename = determineXCFrameworkFilename( + frameworkPaths, + xcframeworkExtension ? ".xcframework" : ".apple.node", + ); + + // Create the xcframework + const xcframeworkOutputPath = path.resolve( + outputPath, + xcframeworkFilename, + ); await oraPromise( - generateEntrypoint({ - libraryName, - outputPath: entrypointPath, + createXCframework({ + outputPath: xcframeworkOutputPath, + frameworkPaths, + autoLink: true, }), { - text: `Generating entrypoint`, - successText: `Generated entrypoint into ${prettyPath( - entrypointPath, + text: "Assembling XCFramework", + successText: `XCFramework assembled into ${chalk.dim( + path.relative(process.cwd(), xcframeworkOutputPath), )}`, - failText: (error) => - `Failed to generate entrypoint: ${error.message}`, + failText: ({ message }) => + `Failed to assemble XCFramework: ${message}`, }, ); - } catch (error) { - process.exitCode = 1; - if (error instanceof SpawnFailure) { - error.flushOutput("both"); - } - if (error instanceof UsageError || error instanceof SpawnFailure) { - console.error(chalk.red("ERROR"), error.message); - if (error.cause instanceof Error) { - console.error(chalk.red("CAUSE"), error.cause.message); - } - if (error instanceof UsageError && error.fix) { - console.error( - chalk.green("FIX"), - error.fix.command - ? chalk.dim("Run: ") + error.fix.command - : error.fix.instructions, - ); - } - } else { - throw error; - } } + + const libraryName = determineLibraryBasename([ + ...androidLibraries.map(([, outputPath]) => outputPath), + ...appleLibraries.map(([, outputPath]) => outputPath), + ]); + + const declarationsFilename = `${libraryName}.d.ts`; + const declarationsPath = path.join(outputPath, declarationsFilename); + await oraPromise( + generateTypeScriptDeclarations({ + outputFilename: declarationsFilename, + createPath: process.cwd(), + outputPath, + }), + { + text: "Generating TypeScript declarations", + successText: `Generated TypeScript declarations ${prettyPath( + declarationsPath, + )}`, + failText: (error) => + `Failed to generate TypeScript declarations: ${error.message}`, + }, + ); + + const entrypointPath = path.join(outputPath, `${libraryName}.js`); + + await oraPromise( + generateEntrypoint({ + libraryName, + outputPath: entrypointPath, + }), + { + text: `Generating entrypoint`, + successText: `Generated entrypoint into ${prettyPath( + entrypointPath, + )}`, + failText: (error) => + `Failed to generate entrypoint: ${error.message}`, + }, + ); }, ); diff --git a/packages/ferric/src/cargo.ts b/packages/ferric/src/cargo.ts index da4e8be9..edc88481 100644 --- a/packages/ferric/src/cargo.ts +++ b/packages/ferric/src/cargo.ts @@ -3,10 +3,14 @@ import cp from "node:child_process"; import fs from "node:fs"; import path from "node:path"; -import { spawn } from "bufout"; -import chalk from "chalk"; +import { + chalk, + assertFixable, + UsageError, + spawn, +} from "@react-native-node-api/cli-utils"; +import { weakNodeApiPath } from "react-native-node-api"; -import { assertFixable, UsageError } from "./errors.js"; import { AndroidTargetName, AppleTargetName, @@ -14,8 +18,6 @@ import { isAppleTarget, } from "./targets.js"; -import { weakNodeApiPath } from "react-native-node-api"; - const APPLE_XCFRAMEWORK_CHILDS_PER_TARGET: Record = { "aarch64-apple-darwin": "macos-arm64_x86_64", // Universal "x86_64-apple-darwin": "macos-arm64_x86_64", // Universal diff --git a/packages/ferric/src/program.ts b/packages/ferric/src/program.ts index f8059c48..422c4ecc 100644 --- a/packages/ferric/src/program.ts +++ b/packages/ferric/src/program.ts @@ -1,4 +1,4 @@ -import { Command } from "@commander-js/extra-typings"; +import { Command } from "@react-native-node-api/cli-utils"; import { printBanner } from "./banner.js"; import { buildCommand } from "./build.js"; diff --git a/packages/ferric/src/run.ts b/packages/ferric/src/run.ts index 7b390d6c..01311284 100644 --- a/packages/ferric/src/run.ts +++ b/packages/ferric/src/run.ts @@ -1,4 +1,5 @@ import EventEmitter from "node:events"; + import { program } from "./program.js"; // We're attaching a lot of listeners when spawning in parallel diff --git a/packages/ferric/src/rustup.ts b/packages/ferric/src/rustup.ts index b246c0c0..11064dd1 100644 --- a/packages/ferric/src/rustup.ts +++ b/packages/ferric/src/rustup.ts @@ -1,6 +1,6 @@ -import cp from "child_process"; +import cp from "node:child_process"; -import { UsageError } from "./errors.js"; +import { UsageError } from "@react-native-node-api/cli-utils"; export function getInstalledTargets() { try { diff --git a/packages/ferric/src/targets.ts b/packages/ferric/src/targets.ts index 5cc7d80f..b7696a10 100644 --- a/packages/ferric/src/targets.ts +++ b/packages/ferric/src/targets.ts @@ -1,6 +1,4 @@ -import chalk from "chalk"; - -import { UsageError } from "./errors.js"; +import { chalk, UsageError } from "@react-native-node-api/cli-utils"; import { getInstalledTargets } from "./rustup.js"; export const ANDROID_TARGETS = [ diff --git a/packages/gyp-to-cmake/package.json b/packages/gyp-to-cmake/package.json index a45bbcc8..e0b5acb4 100644 --- a/packages/gyp-to-cmake/package.json +++ b/packages/gyp-to-cmake/package.json @@ -22,8 +22,7 @@ "test": "tsx --test --test-reporter=@reporters/github --test-reporter-destination=stdout --test-reporter=spec --test-reporter-destination=stdout" }, "dependencies": { - "@commander-js/extra-typings": "^13.1.0", - "commander": "^13.1.0", + "@react-native-node-api/cli-utils": "0.1.0", "gyp-parser": "^1.0.4" } } diff --git a/packages/gyp-to-cmake/src/cli.ts b/packages/gyp-to-cmake/src/cli.ts index 133bd6f9..5556c730 100644 --- a/packages/gyp-to-cmake/src/cli.ts +++ b/packages/gyp-to-cmake/src/cli.ts @@ -1,6 +1,7 @@ import fs from "node:fs"; import path from "node:path"; -import { Command } from "@commander-js/extra-typings"; + +import { Command } from "@react-native-node-api/cli-utils"; import { readBindingFile } from "./gyp.js"; import { diff --git a/packages/gyp-to-cmake/src/run.ts b/packages/gyp-to-cmake/src/run.ts index c64a70b0..feff7eb2 100644 --- a/packages/gyp-to-cmake/src/run.ts +++ b/packages/gyp-to-cmake/src/run.ts @@ -1,2 +1,3 @@ import { program } from "./cli.js"; -program.parse(process.argv); + +program.parseAsync(process.argv).catch(console.error); diff --git a/packages/host/package.json b/packages/host/package.json index 9ddc3c4a..57d12c9f 100644 --- a/packages/host/package.json +++ b/packages/host/package.json @@ -78,11 +78,7 @@ ], "license": "MIT", "dependencies": { - "@commander-js/extra-typings": "^13.1.0", - "bufout": "^0.3.2", - "chalk": "^5.4.1", - "commander": "^13.1.0", - "ora": "^8.2.0", + "@react-native-node-api/cli-utils": "0.1.0", "pkg-dir": "^8.0.0", "read-pkg": "^9.0.1" }, diff --git a/packages/host/src/node/cli/apple.ts b/packages/host/src/node/cli/apple.ts index a04405cb..92fe6468 100644 --- a/packages/host/src/node/cli/apple.ts +++ b/packages/host/src/node/cli/apple.ts @@ -3,7 +3,7 @@ import path from "node:path"; import fs from "node:fs"; import os from "node:os"; -import { spawn } from "bufout"; +import { spawn } from "@react-native-node-api/cli-utils"; import { getLatestMtime, getLibraryName } from "../path-utils.js"; import { diff --git a/packages/host/src/node/cli/hermes.ts b/packages/host/src/node/cli/hermes.ts index 4fddebe6..f3c884b5 100644 --- a/packages/host/src/node/cli/hermes.ts +++ b/packages/host/src/node/cli/hermes.ts @@ -2,9 +2,12 @@ import assert from "node:assert/strict"; import fs from "node:fs"; import path from "node:path"; -import { Command } from "@commander-js/extra-typings"; -import { spawn, SpawnFailure } from "bufout"; -import { oraPromise } from "ora"; +import { + Command, + oraPromise, + spawn, + SpawnFailure, +} from "@react-native-node-api/cli-utils"; import { packageDirectorySync } from "pkg-dir"; import { prettyPath } from "../path-utils"; diff --git a/packages/host/src/node/cli/link-modules.ts b/packages/host/src/node/cli/link-modules.ts index 6053fc68..9b44d921 100644 --- a/packages/host/src/node/cli/link-modules.ts +++ b/packages/host/src/node/cli/link-modules.ts @@ -1,7 +1,8 @@ import path from "node:path"; import fs from "node:fs"; -import { SpawnFailure } from "bufout"; +import { chalk, SpawnFailure } from "@react-native-node-api/cli-utils"; + import { findNodeApiModulePathsByDependency, getAutolinkPath, @@ -11,7 +12,6 @@ import { PlatformName, prettyPath, } from "../path-utils"; -import chalk from "chalk"; export type ModuleLinker = ( options: LinkModuleOptions, diff --git a/packages/host/src/node/cli/options.ts b/packages/host/src/node/cli/options.ts index 1f81f306..0944f7c9 100644 --- a/packages/host/src/node/cli/options.ts +++ b/packages/host/src/node/cli/options.ts @@ -1,4 +1,4 @@ -import { Option } from "@commander-js/extra-typings"; +import { Option } from "@react-native-node-api/cli-utils"; import { assertPathSuffix, PATH_SUFFIX_CHOICES } from "../path-utils"; diff --git a/packages/host/src/node/cli/program.ts b/packages/host/src/node/cli/program.ts index 4747a23e..4e6b7bd7 100644 --- a/packages/host/src/node/cli/program.ts +++ b/packages/host/src/node/cli/program.ts @@ -2,10 +2,12 @@ import assert from "node:assert/strict"; import path from "node:path"; import { EventEmitter } from "node:stream"; -import { Command } from "@commander-js/extra-typings"; -import { SpawnFailure } from "bufout"; -import chalk from "chalk"; -import { oraPromise } from "ora"; +import { + Command, + chalk, + SpawnFailure, + oraPromise, +} from "@react-native-node-api/cli-utils"; import { determineModuleContext, diff --git a/packages/host/src/node/cli/run.ts b/packages/host/src/node/cli/run.ts index ee4c5620..da5566fe 100644 --- a/packages/host/src/node/cli/run.ts +++ b/packages/host/src/node/cli/run.ts @@ -1,2 +1,3 @@ import { program } from "./program"; + program.parseAsync(process.argv).catch(console.error); diff --git a/packages/host/src/node/path-utils.ts b/packages/host/src/node/path-utils.ts index ffec330a..1fe6170e 100644 --- a/packages/host/src/node/path-utils.ts +++ b/packages/host/src/node/path-utils.ts @@ -1,12 +1,14 @@ import assert from "node:assert/strict"; import path from "node:path"; import fs from "node:fs"; -import { findDuplicates } from "./duplicates"; -import chalk from "chalk"; import { packageDirectorySync } from "pkg-dir"; import { readPackageSync } from "read-pkg"; import { createRequire } from "node:module"; +import { chalk } from "@react-native-node-api/cli-utils"; + +import { findDuplicates } from "./duplicates"; + // TODO: Change to .apple.node export const PLATFORMS = ["android", "apple"] as const; export type PlatformName = "android" | "apple"; diff --git a/packages/host/src/node/prebuilds/apple.ts b/packages/host/src/node/prebuilds/apple.ts index 9b7765fb..693c90b6 100644 --- a/packages/host/src/node/prebuilds/apple.ts +++ b/packages/host/src/node/prebuilds/apple.ts @@ -4,7 +4,7 @@ import path from "node:path"; import os from "node:os"; import cp from "node:child_process"; -import { spawn } from "bufout"; +import { spawn } from "@react-native-node-api/cli-utils"; import { AppleTriplet } from "./triplets.js"; import { determineLibraryBasename } from "../path-utils.js"; diff --git a/tsconfig.json b/tsconfig.json index 77eba035..cde11ae1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,7 @@ }, "files": ["prettier.config.js", "eslint.config.js"], "references": [ + { "path": "./packages/cli-utils/tsconfig.json" }, { "path": "./packages/host/tsconfig.json" }, { "path": "./packages/gyp-to-cmake/tsconfig.json" }, { "path": "./packages/cmake-rn/tsconfig.json" },