From 7dc71038d7b36e5339b4e0076c2ac0592245b89c Mon Sep 17 00:00:00 2001 From: Nystik <236107-Nystik@users.noreply.gitlab.com> Date: Sun, 29 Mar 2026 18:43:23 +0200 Subject: [PATCH] add utils shim (needed by templater plugin) --- src/shims/node/util.js | 163 +++++++++++++++++++++++++++++++++++++++++ src/shims/require.js | 2 + 2 files changed, 165 insertions(+) create mode 100644 src/shims/node/util.js diff --git a/src/shims/node/util.js b/src/shims/node/util.js new file mode 100644 index 0000000..5dfe270 --- /dev/null +++ b/src/shims/node/util.js @@ -0,0 +1,163 @@ +// Shim for Node's `util` module. +// Implements the most commonly used functions; stubs the rest. + +function promisify(fn) { + if (typeof fn !== "function") { + throw new TypeError('The "original" argument must be of type Function'); + } + + // If the function already has a custom promisified version, use it. + if (fn[promisify.custom]) { + return fn[promisify.custom]; + } + + function promisified(...args) { + return new Promise((resolve, reject) => { + fn.call(this, ...args, (err, ...results) => { + if (err) { + reject(err); + } else if (results.length <= 1) { + resolve(results[0]); + } else { + resolve(results); + } + }); + }); + } + + return promisified; +} + +promisify.custom = Symbol.for("nodejs.util.promisify.custom"); + +function callbackify(fn) { + if (typeof fn !== "function") { + throw new TypeError('The "original" argument must be of type Function'); + } + + function callbackified(...args) { + const callback = args.pop(); + + fn.apply(this, args).then( + (result) => callback(null, result), + (err) => callback(err), + ); + } + + return callbackified; +} + +function inherits(ctor, superCtor) { + ctor.super_ = superCtor; + Object.setPrototypeOf(ctor.prototype, superCtor.prototype); +} + +function deprecate(fn, msg) { + let warned = false; + + function deprecated(...args) { + if (!warned) { + console.warn("[ignis:util] DeprecationWarning:", msg); + warned = true; + } + + return fn.apply(this, args); + } + + return deprecated; +} + +function inspect(obj, opts) { + try { + return JSON.stringify(obj, null, 2); + } catch { + return String(obj); + } +} + +function format(fmt, ...args) { + if (typeof fmt !== "string") { + return [fmt, ...args].map(String).join(" "); + } + + let i = 0; + + const result = fmt.replace(/%[sdjifoO%]/g, (match) => { + if (match === "%%") { + return "%"; + } + + if (i >= args.length) { + return match; + } + + const arg = args[i++]; + + switch (match) { + case "%s": + return String(arg); + case "%d": + case "%i": + return parseInt(arg, 10).toString(); + case "%f": + return parseFloat(arg).toString(); + case "%j": + try { + return JSON.stringify(arg); + } catch { + return "[Circular]"; + } + case "%o": + case "%O": + return inspect(arg); + default: + return match; + } + }); + + // Append remaining args. + const remaining = args.slice(i); + + if (remaining.length > 0) { + return result + " " + remaining.map(String).join(" "); + } + + return result; +} + +function debuglog(section) { + return function () {}; +} + +function isDeepStrictEqual(a, b) { + return JSON.stringify(a) === JSON.stringify(b); +} + +const types = { + isArray: Array.isArray, + isDate: (v) => v instanceof Date, + isRegExp: (v) => v instanceof RegExp, + isAsyncFunction: (v) => typeof v === "function" && v.constructor.name === "AsyncFunction", + isPromise: (v) => v instanceof Promise, + isGeneratorFunction: (v) => typeof v === "function" && v.constructor.name === "GeneratorFunction", + isArrayBuffer: (v) => v instanceof ArrayBuffer, + isTypedArray: (v) => ArrayBuffer.isView(v) && !(v instanceof DataView), + isMap: (v) => v instanceof Map, + isSet: (v) => v instanceof Set, + isWeakMap: (v) => v instanceof WeakMap, + isWeakSet: (v) => v instanceof WeakSet, +}; + +module.exports = { + promisify, + callbackify, + inherits, + deprecate, + inspect, + format, + debuglog, + isDeepStrictEqual, + types, + TextEncoder: globalThis.TextEncoder, + TextDecoder: globalThis.TextDecoder, +}; diff --git a/src/shims/require.js b/src/shims/require.js index 637f230..d2a9a55 100644 --- a/src/shims/require.js +++ b/src/shims/require.js @@ -10,6 +10,7 @@ import * as osShim from "./node/os.js"; import * as netShim from "./node/net.js"; import * as httpShim from "./node/http.js"; import * as zlibShim from "./node/zlib.js"; +import * as utilShim from "./node/util.js"; import { wrapWithProxy, installDebugHelpers } from "./debug.js"; const rawRegistry = { @@ -27,6 +28,7 @@ const rawRegistry = { http: httpShim, https: httpShim, zlib: zlibShim, + util: utilShim, }; const shimRegistry = {};