Repository: denoland/deno
Pull request: fix(ext/node): use primordials in `ext/node/polyfills/internal/validators.mjs`

Towards #24236. Replaces JS instrinsics with equivalent primordials.

<!--
Before submitting a PR, please read https://docs.deno.com/runtime/manual/references/contributing

1. Give the PR a descriptive title.

  Examples of good title:
    - fix(std/http): Fix race condition in server
    - docs(console): Update docstrings
    - feat(doc): Handle nested reexports

  Examples of bad title:
    - fix #7123
    - update docs
    - fix bugs

2. Ensure there is a related issue and it is referenced in the PR text.
3. Ensure there are tests that cover the changes.
4. Ensure `cargo test` passes.
5. Ensure `./tools/format.js` passes without changing files.
6. Ensure `./tools/lint.js` passes.
7. Open as a draft PR if your work is still in progress. The CI won't run
   all steps, but you can add '[ci]' to a commit message to force it to.
8. If you would like to run the benchmarks on the CI, add the 'ci-bench' label.
-->


Changed files:
filename: ext/node/polyfills/internal/validators.mjs
patch: @@ -1,13 +1,22 @@
 // Copyright 2018-2025 the Deno authors. MIT license.
 // Copyright Joyent and Node contributors. All rights reserved. MIT license.
 
-// TODO(petamoriken): enable prefer-primordials for node polyfills
-// deno-lint-ignore-file prefer-primordials
-
 import { primordials } from "ext:core/mod.js";
 const {
+  ArrayIsArray,
   ArrayPrototypeIncludes,
   ArrayPrototypeJoin,
+  ArrayPrototypeMap,
+  NumberIsInteger,
+  NumberIsNaN,
+  NumberMIN_SAFE_INTEGER,
+  NumberMAX_SAFE_INTEGER,
+  NumberParseInt,
+  SafeRegExp,
+  String,
+  StringPrototypeTrim,
+  ReflectHas,
+  RegExpPrototypeTest,
 } = primordials;
 
 import { codes } from "ext:deno_node/internal/error_codes.ts";
@@ -31,7 +40,7 @@ function isUint32(value) {
   return value === (value >>> 0);
 }
 
-const octalReg = /^[0-7]+$/;
+const octalReg = new SafeRegExp(/^[0-7]+$/);
 const modeDesc = "must be a 32-bit unsigned integer or an octal string";
 
 /**
@@ -49,10 +58,10 @@ const modeDesc = "must be a 32-bit unsigned integer or an octal string";
 function parseFileMode(value, name, def) {
   value ??= def;
   if (typeof value === "string") {
-    if (!octalReg.test(value)) {
+    if (!RegExpPrototypeTest(octalReg, value)) {
       throw new codes.ERR_INVALID_ARG_VALUE(name, value, modeDesc);
     }
-    value = Number.parseInt(value, 8);
+    value = NumberParseInt(value, 8);
   }
 
   validateInt32(value, name, 0, 2 ** 32 - 1);
@@ -73,13 +82,13 @@ const validateInteger = hideStackFrames(
   (
     value,
     name,
-    min = Number.MIN_SAFE_INTEGER,
-    max = Number.MAX_SAFE_INTEGER,
+    min = NumberMIN_SAFE_INTEGER,
+    max = NumberMAX_SAFE_INTEGER,
   ) => {
     if (typeof value !== "number") {
       throw new codes.ERR_INVALID_ARG_TYPE(name, "number", value);
     }
-    if (!Number.isInteger(value)) {
+    if (!NumberIsInteger(value)) {
       throw new codes.ERR_OUT_OF_RANGE(name, "an integer", value);
     }
     if (value < min || value > max) {
@@ -104,7 +113,7 @@ const validateObject = hideStackFrames((value, name, options) => {
   const nullable = useDefaultOptions ? false : options.nullable;
   if (
     (!nullable && value === null) ||
-    (!allowArray && Array.isArray(value)) ||
+    (!allowArray && ArrayIsArray(value)) ||
     (typeof value !== "object" && (
       !allowFunction || typeof value !== "function"
     ))
@@ -121,7 +130,7 @@ const validateInt32 = hideStackFrames(
         throw new codes.ERR_INVALID_ARG_TYPE(name, "number", value);
       }
 
-      if (!Number.isInteger(value)) {
+      if (!NumberIsInteger(value)) {
         throw new codes.ERR_OUT_OF_RANGE(name, "an integer", value);
       }
 
@@ -140,7 +149,7 @@ const validateUint32 = hideStackFrames(
       if (typeof value !== "number") {
         throw new codes.ERR_INVALID_ARG_TYPE(name, "number", value);
       }
-      if (!Number.isInteger(value)) {
+      if (!NumberIsInteger(value)) {
         throw new codes.ERR_OUT_OF_RANGE(name, "an integer", value);
       }
       const min = positive ? 1 : 0;
@@ -178,7 +187,7 @@ function validateNumber(value, name, min = undefined, max) {
 
   if (
     (min != null && value < min) || (max != null && value > max) ||
-    ((min != null || max != null) && Number.isNaN(value))
+    ((min != null || max != null) && NumberIsNaN(value))
   ) {
     throw new codes.ERR_OUT_OF_RANGE(
       name,
@@ -207,9 +216,9 @@ function validateBoolean(value, name) {
  */
 const validateOneOf = hideStackFrames(
   (value, name, oneOf) => {
-    if (!Array.prototype.includes.call(oneOf, value)) {
-      const allowed = Array.prototype.join.call(
-        Array.prototype.map.call(
+    if (!ArrayPrototypeIncludes(oneOf, value)) {
+      const allowed = ArrayPrototypeJoin(
+        ArrayPrototypeMap(
           oneOf,
           (v) => (typeof v === "string" ? `'${v}'` : String(v)),
         ),
@@ -245,7 +254,7 @@ function validatePort(port, name = "Port", allowZero = true) {
   if (
     (typeof port !== "number" && typeof port !== "string") ||
     (typeof port === "string" &&
-      String.prototype.trim.call(port).length === 0) ||
+      StringPrototypeTrim(port).length === 0) ||
     +port !== (+port >>> 0) ||
     port > 0xFFFF ||
     (port === 0 && !allowZero)
@@ -266,7 +275,7 @@ const validateAbortSignal = hideStackFrames(
       signal !== undefined &&
       (signal === null ||
         typeof signal !== "object" ||
-        !("aborted" in signal))
+        !ReflectHas(signal, "aborted"))
     ) {
       throw new codes.ERR_INVALID_ARG_TYPE(name, "AbortSignal", signal);
     }
@@ -291,7 +300,7 @@ const validateFunction = hideStackFrames(
  */
 const validateArray = hideStackFrames(
   (value, name, minLength = 0) => {
-    if (!Array.isArray(value)) {
+    if (!ArrayIsArray(value)) {
       throw new codes.ERR_INVALID_ARG_TYPE(name, "Array", value);
     }
     if (value.length < minLength) {