fix(ext/node): adapt dynamic type checking to Node.js behavior (#21014)

This commit is contained in:
Kenta Moriuchi 2023-11-01 16:06:25 +09:00 committed by GitHub
parent d1ef561dbf
commit 841f215fd4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 39 deletions

View file

@ -46,8 +46,8 @@ Deno.test({
name: "[util] isBoolean",
fn() {
assert(util.isBoolean(true));
assert(util.isBoolean(new Boolean()));
assert(util.isBoolean(new Boolean(true)));
assert(!util.isBoolean(new Boolean()));
assert(!util.isBoolean(new Boolean(true)));
assert(util.isBoolean(false));
assert(!util.isBoolean("deno"));
assert(!util.isBoolean("true"));
@ -80,7 +80,7 @@ Deno.test({
name: "[util] isNumber",
fn() {
assert(util.isNumber(666));
assert(util.isNumber(new Number(666)));
assert(!util.isNumber(new Number(666)));
assert(!util.isNumber("999"));
assert(!util.isNumber(null));
},
@ -90,7 +90,7 @@ Deno.test({
name: "[util] isString",
fn() {
assert(util.isString("deno"));
assert(util.isString(new String("DIO")));
assert(!util.isString(new String("DIO")));
assert(!util.isString(1337));
},
});
@ -99,6 +99,7 @@ Deno.test({
name: "[util] isSymbol",
fn() {
assert(util.isSymbol(Symbol()));
assert(!util.isSymbol(Object(Symbol())));
assert(!util.isSymbol(123));
assert(!util.isSymbol("string"));
},
@ -128,7 +129,7 @@ Deno.test({
name: "[util] isError",
fn() {
const java = new Error();
const nodejs = new TypeError();
const nodejs = Reflect.construct(Error, [], Object);
const deno = "Future";
assert(util.isError(java));
assert(util.isError(nodejs));

View file

@ -1,8 +1,5 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
// TODO(petamoriken): enable prefer-primordials for node polyfills
// deno-lint-ignore-file prefer-primordials
import { promisify } from "ext:deno_node/internal/util.mjs";
import { callbackify } from "ext:deno_node/_util/_util_callbackify.ts";
import { debuglog } from "ext:deno_node/internal/util/debuglog.ts";
@ -18,6 +15,30 @@ import { Buffer } from "node:buffer";
import { isDeepStrictEqual } from "ext:deno_node/internal/util/comparisons.ts";
import process from "node:process";
import { validateString } from "ext:deno_node/internal/validators.mjs";
const primordials = globalThis.__bootstrap.primordials;
const {
ArrayIsArray,
ArrayPrototypeJoin,
Date,
DatePrototypeGetDate,
DatePrototypeGetHours,
DatePrototypeGetMinutes,
DatePrototypeGetMonth,
DatePrototypeGetSeconds,
ErrorPrototype,
NumberPrototypeToString,
ObjectDefineProperty,
ObjectKeys,
ObjectPrototypeIsPrototypeOf,
ObjectPrototypeToString,
ObjectSetPrototypeOf,
ReflectApply,
ReflectConstruct,
SafeSet,
SetPrototypeAdd,
SetPrototypeHas,
StringPrototypePadStart,
} = primordials;
export {
callbackify,
@ -31,13 +52,11 @@ export {
};
/** @deprecated - use `Array.isArray()` instead. */
export function isArray(value: unknown): boolean {
return Array.isArray(value);
}
export const isArray = ArrayIsArray;
/** @deprecated - use `typeof value === "boolean" || value instanceof Boolean` instead. */
/** @deprecated - use `typeof value === "boolean" instead. */
export function isBoolean(value: unknown): boolean {
return typeof value === "boolean" || value instanceof Boolean;
return typeof value === "boolean";
}
/** @deprecated - use `value === null` instead. */
@ -50,14 +69,14 @@ export function isNullOrUndefined(value: unknown): boolean {
return value === null || value === undefined;
}
/** @deprecated - use `typeof value === "number" || value instanceof Number` instead. */
/** @deprecated - use `typeof value === "number" instead. */
export function isNumber(value: unknown): boolean {
return typeof value === "number" || value instanceof Number;
return typeof value === "number";
}
/** @deprecated - use `typeof value === "string" || value instanceof String` instead. */
/** @deprecated - use `typeof value === "string" instead. */
export function isString(value: unknown): boolean {
return typeof value === "string" || value instanceof String;
return typeof value === "string";
}
/** @deprecated - use `typeof value === "symbol"` instead. */
@ -77,7 +96,8 @@ export function isObject(value: unknown): boolean {
/** @deprecated - use `e instanceof Error` instead. */
export function isError(e: unknown): boolean {
return e instanceof Error;
return ObjectPrototypeToString(e) === "[object Error]" ||
ObjectPrototypeIsPrototypeOf(ErrorPrototype, e);
}
/** @deprecated - use `typeof value === "function"` instead. */
@ -103,9 +123,7 @@ export function isPrimitive(value: unknown): boolean {
}
/** @deprecated Use Buffer.isBuffer() instead. */
export function isBuffer(value: unknown): boolean {
return Buffer.isBuffer(value);
}
export const isBuffer = Buffer.isBuffer;
/** @deprecated Use Object.assign() instead. */
export function _extend(
@ -115,7 +133,7 @@ export function _extend(
// Don't do anything if source isn't an object
if (source === null || typeof source !== "object") return target;
const keys = Object.keys(source!);
const keys = ObjectKeys(source!);
let i = keys.length;
while (i--) {
target[keys[i]] = (source as Record<string, unknown>)[keys[i]];
@ -147,12 +165,12 @@ export function inherits<T, U>(
superCtor.prototype,
);
}
Object.defineProperty(ctor, "super_", {
ObjectDefineProperty(ctor, "super_", {
value: superCtor,
writable: true,
configurable: true,
});
Object.setPrototypeOf(ctor.prototype, superCtor.prototype);
ObjectSetPrototypeOf(ctor.prototype, superCtor.prototype);
}
import {
@ -170,7 +188,7 @@ export type TextEncoder = import("./_utils.ts")._TextEncoder;
export const TextEncoder = _TextEncoder;
function pad(n: number) {
return n.toString().padStart(2, "0");
return StringPrototypePadStart(NumberPrototypeToString(n), 2, "0");
}
const months = [
@ -193,12 +211,12 @@ const months = [
*/
function timestamp(): string {
const d = new Date();
const t = [
pad(d.getHours()),
pad(d.getMinutes()),
pad(d.getSeconds()),
].join(":");
return `${(d.getDate())} ${months[d.getMonth()]} ${t}`;
const t = ArrayPrototypeJoin([
pad(DatePrototypeGetHours(d)),
pad(DatePrototypeGetMinutes(d)),
pad(DatePrototypeGetSeconds(d)),
], ":");
return `${DatePrototypeGetDate(d)} ${months[DatePrototypeGetMonth(d)]} ${t}`;
}
/**
@ -207,12 +225,12 @@ function timestamp(): string {
*/
// deno-lint-ignore no-explicit-any
export function log(...args: any[]) {
console.log("%s - %s", timestamp(), format(...args));
console.log("%s - %s", timestamp(), ReflectApply(format, undefined, args));
}
// Keep a list of deprecation codes that have been warned on so we only warn on
// each one once.
const codesWarned = new Set();
const codesWarned = new SafeSet();
// Mark that a method should not be used.
// Returns a modified function which warns once by default.
@ -233,9 +251,9 @@ export function deprecate(fn: any, msg: string, code?: any) {
if (!warned) {
warned = true;
if (code !== undefined) {
if (!codesWarned.has(code)) {
if (!SetPrototypeHas(codesWarned, code)) {
process.emitWarning(msg, "DeprecationWarning", code, deprecated);
codesWarned.add(code);
SetPrototypeAdd(codesWarned, code);
}
} else {
// deno-lint-ignore no-explicit-any
@ -243,13 +261,13 @@ export function deprecate(fn: any, msg: string, code?: any) {
}
}
if (new.target) {
return Reflect.construct(fn, args, new.target);
return ReflectConstruct(fn, args, new.target);
}
return Reflect.apply(fn, this, args);
return ReflectApply(fn, this, args);
}
// The wrapper will keep the same prototype as fn to maintain prototype chain
Object.setPrototypeOf(deprecated, fn);
ObjectSetPrototypeOf(deprecated, fn);
if (fn.prototype) {
// Setting this (rather than using Object.setPrototype, as above) ensures
// that calling the unwrapped constructor gives an instanceof the wrapped

View file

@ -16,7 +16,7 @@ export { delay } from "../test_util/std/async/delay.ts";
// [toolName] --version output
const versions = {
"dprint": "dprint 0.40.0",
"dlint": "dlint 0.51.0",
"dlint": "dlint 0.52.2",
};
export const ROOT_PATH = dirname(dirname(fromFileUrl(import.meta.url)));