From d430f99eef82b8e9a27d17aa732f7539d3f814bf Mon Sep 17 00:00:00 2001 From: Tommy Nguyen <4123478+tido64@users.noreply.github.com> Date: Thu, 17 Oct 2024 09:10:35 +0200 Subject: [PATCH] fix(metro-plugin-typescript): fix beta versions of TypeScript failing version check (#3392) --- .changeset/silver-olives-explain.md | 5 +++++ packages/metro-plugin-typescript/package.json | 2 -- packages/metro-plugin-typescript/src/host.ts | 6 +++--- .../src/serializerHook.ts | 8 ++++---- packages/metro-plugin-typescript/src/version.ts | 8 ++++++++ .../metro-plugin-typescript/test/version.test.ts | 16 ++++++++++++++++ yarn.lock | 2 -- 7 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 .changeset/silver-olives-explain.md create mode 100644 packages/metro-plugin-typescript/src/version.ts create mode 100644 packages/metro-plugin-typescript/test/version.test.ts diff --git a/.changeset/silver-olives-explain.md b/.changeset/silver-olives-explain.md new file mode 100644 index 000000000..f83cf3da6 --- /dev/null +++ b/.changeset/silver-olives-explain.md @@ -0,0 +1,5 @@ +--- +"@rnx-kit/metro-plugin-typescript": patch +--- + +Fix beta versions of TypeScript failing version check diff --git a/packages/metro-plugin-typescript/package.json b/packages/metro-plugin-typescript/package.json index 504524fb6..4c846477f 100644 --- a/packages/metro-plugin-typescript/package.json +++ b/packages/metro-plugin-typescript/package.json @@ -31,7 +31,6 @@ "@rnx-kit/tools-node": "^3.0.0", "@rnx-kit/tools-react-native": "^2.0.0", "@rnx-kit/typescript-service": "^2.0.0", - "semver": "^7.0.0", "typescript": ">=4.7.0" }, "devDependencies": { @@ -40,7 +39,6 @@ "@rnx-kit/scripts": "*", "@rnx-kit/tsconfig": "*", "@types/node": "^20.0.0", - "@types/semver": "^7.0.0", "eslint": "^8.56.0", "jest": "^29.2.1", "metro": "^0.80.3", diff --git a/packages/metro-plugin-typescript/src/host.ts b/packages/metro-plugin-typescript/src/host.ts index d1925cbd8..e975929c1 100644 --- a/packages/metro-plugin-typescript/src/host.ts +++ b/packages/metro-plugin-typescript/src/host.ts @@ -1,7 +1,6 @@ import { getAvailablePlatforms } from "@rnx-kit/tools-react-native"; import type { AllPlatforms } from "@rnx-kit/tools-react-native/platform"; import { platformExtensions } from "@rnx-kit/tools-react-native/platform"; -import semverSatisfies from "semver/functions/satisfies"; import ts from "typescript"; import { resolveModuleNameLiterals, @@ -10,6 +9,7 @@ import { resolveTypeReferenceDirectives, } from "./resolver"; import type { ResolverContext } from "./types"; +import { greaterThanOrEqualTo } from "./version"; const DEFAULT_PACKAGE_NAME = "react-native"; @@ -68,7 +68,7 @@ export function createEnhanceLanguageServiceHost( * is available. We use this to configure the built-in module resolver for * React Native projects. */ - if (!semverSatisfies(tsVersion, ">=4.7.0")) { + if (!greaterThanOrEqualTo(tsVersion, "4.7.0")) { throw new Error("TypeScript >=4.7 is required"); } @@ -93,7 +93,7 @@ export function createEnhanceLanguageServiceHost( ), }; - if (semverSatisfies(tsVersion, ">=5.0")) { + if (greaterThanOrEqualTo(tsVersion, "5.0.0")) { host.resolveModuleNameLiterals = (...args) => resolveModuleNameLiterals(context, ...args); host.resolveTypeReferenceDirectiveReferences = (...args) => diff --git a/packages/metro-plugin-typescript/src/serializerHook.ts b/packages/metro-plugin-typescript/src/serializerHook.ts index b14422d9c..1f70e2332 100644 --- a/packages/metro-plugin-typescript/src/serializerHook.ts +++ b/packages/metro-plugin-typescript/src/serializerHook.ts @@ -4,17 +4,17 @@ import { normalizePath } from "@rnx-kit/tools-node/path"; import { getMetroVersion } from "@rnx-kit/tools-react-native/metro"; import type { AllPlatforms } from "@rnx-kit/tools-react-native/platform"; import type { Project } from "@rnx-kit/typescript-service"; -import * as semver from "semver"; import { createProjectCache } from "./projectCache"; import type { SerializerHook } from "./types"; +import { greaterThanOrEqualTo } from "./version"; -function checkMetroVersion(requiredVersion: string): string | undefined { +function requireMetroVersion(requiredVersion: string): string | undefined { const version = getMetroVersion(); if (!version) { return `Metro version ${requiredVersion} is required`; } - if (!semver.satisfies(version, requiredVersion)) { + if (!greaterThanOrEqualTo(version, requiredVersion)) { return `Metro version ${requiredVersion} is required; got ${version}`; } @@ -43,7 +43,7 @@ export function TypeScriptPlugin( // TypeScript plugin requires the `transformOptions` property that was added // in 0.66.1. If the version is older, disable the plugin. See // https://github.com/facebook/metro/commit/57106d273690bbcad0a795b337e43252edbc1091 - const unsupportedMetroVersion = checkMetroVersion(">=0.66.1"); + const unsupportedMetroVersion = requireMetroVersion("0.66.1"); if (unsupportedMetroVersion) { warn(`TypeScriptPlugin disabled: ${unsupportedMetroVersion}`); return () => void 0; diff --git a/packages/metro-plugin-typescript/src/version.ts b/packages/metro-plugin-typescript/src/version.ts new file mode 100644 index 000000000..bf9767bea --- /dev/null +++ b/packages/metro-plugin-typescript/src/version.ts @@ -0,0 +1,8 @@ +function versionNumber(version: string): number { + const [major, minor = 0, patch = 0] = version.split("-")[0].split("."); + return Number(major) * 1000000 + Number(minor) * 1000 + Number(patch); +} + +export function greaterThanOrEqualTo(lhs: string, rhs: string): boolean { + return versionNumber(lhs) >= versionNumber(rhs); +} diff --git a/packages/metro-plugin-typescript/test/version.test.ts b/packages/metro-plugin-typescript/test/version.test.ts new file mode 100644 index 000000000..86c9d8c7a --- /dev/null +++ b/packages/metro-plugin-typescript/test/version.test.ts @@ -0,0 +1,16 @@ +import { greaterThanOrEqualTo } from "../src/version"; + +describe("greaterThanOrEqualTo()", () => { + it("handles basic comparison", () => { + expect(greaterThanOrEqualTo("0.66.0", "0.66.1")).toBe(false); + expect(greaterThanOrEqualTo("0.66.1", "0.66.1")).toBe(true); + expect(greaterThanOrEqualTo("0.66.2", "0.66.1")).toBe(true); + expect(greaterThanOrEqualTo("4.7.0", "4.7.0")).toBe(true); + }); + + it("handles prereleases correctly", () => { + expect(greaterThanOrEqualTo("5.0.0-beta", "4.7.0")).toBe(true); + expect(greaterThanOrEqualTo("5.0.0-rc.0", "4.7.0")).toBe(true); + expect(greaterThanOrEqualTo("5.0.0-rc.0", "5.0.0")).toBe(true); + }); +}); diff --git a/yarn.lock b/yarn.lock index 22f411c8f..18049a853 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4066,12 +4066,10 @@ __metadata: "@rnx-kit/tsconfig": "npm:*" "@rnx-kit/typescript-service": "npm:^2.0.0" "@types/node": "npm:^20.0.0" - "@types/semver": "npm:^7.0.0" eslint: "npm:^8.56.0" jest: "npm:^29.2.1" metro: "npm:^0.80.3" prettier: "npm:^3.0.0" - semver: "npm:^7.0.0" typescript: "npm:>=4.7.0" languageName: unknown linkType: soft