Node.js API compatibility - Utils
The util module in Node.js provides a set of utility functions that assist with various tasks, enhancing the functionality of JavaScript and Node.js applications. It’s particularly useful for developers looking to simplify common programming tasks and improve code readability. This module is available in the Azion Runtime through Node.js compatibility, where helpers such as promisify and inspect are handy for adapting callback-based code and for logging structured data inside a function.
Example: Promisify and inspect
The example below shows how to use the util module in a function:
/** * An example of using Node.js Util API in an Azion Function. * Support: * - Partially supported (Extended by library `util`) * @module runtime-apis/nodejs/util/main * @example * // Execute with Azion Bundler: * npx edge-functions build * npx edge-functions dev */import util from "node:util";
const myTest = (callback) => { try { callback(null, "Success!"); } catch (err) { callback(err); }};
/** * An example of using the Node.js Util API in an Azion Function. * @param {*} event * @returns {Promise<Response>} */const main = async (event) => { const promisifyTest = util.promisify(myTest); const result = await promisifyTest(); console.log(util.inspect(result, { showHidden: false, depth: null }));
return new Response("Done!", { status: 200 });};
export default main;Example: Converting callbacks to promises
Use promisify to convert callback-style functions to async/await:
import util from "node:util";import { setTimeout } from "node:timers";
// Simulate a callback-based APIconst fetchData = (id, callback) => { setTimeout(() => { if (id > 0) { callback(null, { id, data: `Item ${id}`, timestamp: Date.now() }); } else { callback(new Error("Invalid ID")); } }, 100);};
// Convert to promise-basedconst fetchDataAsync = util.promisify(fetchData);
const main = async (event) => { try { // Now can use with async/await const result1 = await fetchDataAsync(1); const result2 = await fetchDataAsync(2);
console.log("Result 1:", result1); console.log("Result 2:", result2);
return new Response(JSON.stringify({ results: [result1, result2] }), { headers: { "Content-Type": "application/json" } }); } catch (error) { console.error("Error:", error.message); return new Response(JSON.stringify({ error: error.message }), { status: 400, headers: { "Content-Type": "application/json" } }); }};
export default main;Example: Deep object inspection
Use inspect for detailed object logging and debugging:
import util from "node:util";
const main = async (event) => { // Complex object to inspect const requestInfo = { url: event.request.url, method: event.request.method, headers: Object.fromEntries(event.request.headers), timestamp: new Date().toISOString() };
// Nested object const complexData = { level1: { level2: { level3: { value: "deep", array: [1, 2, { nested: true }] } } } };
// Inspect with options const inspected = util.inspect(requestInfo, { depth: null, // Unlimited depth colors: false, // Explicitly disabled since output goes into JSON response compact: false, // Multi-line output showHidden: false, // Don't show non-enumerable maxArrayLength: 10 // Limit array display });
console.log("Request info:", inspected);
// Format string with placeholders const formatted = util.format( "Request %s to %s at %s", requestInfo.method, requestInfo.url, requestInfo.timestamp ); console.log(formatted);
return new Response(JSON.stringify({ requestInfo, formatted, inspectedDepth: util.inspect(complexData, { depth: 2 }) }), { headers: { "Content-Type": "application/json" } });};
export default main;Example: Type checking utilities
Use util.types for runtime type checking:
import util from "node:util";
const main = async (event) => { const values = { string: "hello", number: 42, boolean: true, object: { key: "value" }, array: [1, 2, 3], null: null, undefined: undefined, date: new Date(), regex: /test/, promise: Promise.resolve("test"), buffer: new ArrayBuffer(8) };
// Type checking results const typeChecks = { isDate: util.types.isDate(values.date), isRegExp: util.types.isRegExp(values.regex), isPromise: util.types.isPromise(values.promise), isArrayBuffer: util.types.isArrayBuffer(values.buffer), isNativeError: util.types.isNativeError(new Error("test")), isTypedArray: util.types.isTypedArray(new Uint8Array(4)), isMap: util.types.isMap(new Map()), isSet: util.types.isSet(new Set()) };
// Note: isConstructor is not part of util.types API // Use typeof for function/constructor checking class MyClass {} const isFunction = typeof MyClass === "function";
console.log("Type checks:", typeChecks);
return new Response(JSON.stringify({ values: Object.keys(values).map(k => ({ key: k, type: typeof values[k], isDate: util.types.isDate(values[k]), isRegExp: util.types.isRegExp(values[k]) })), typeChecks, isFunction }), { headers: { "Content-Type": "application/json" } });};
export default main;Example: String formatting and deprecation
Use format strings and mark deprecated functions:
import util from "node:util";
// Mark a function as deprecatedconst oldFunction = util.deprecate( () => "This is the old function", "oldFunction is deprecated. Use newFunction instead.");
const newFunction = () => "This is the new function";
const main = async (event) => { const results = [];
// String formatting with %s, %d, %j, %% results.push(util.format("Hello %s!", "World")); results.push(util.format("Number: %d, String: %s", 42, "test")); results.push(util.format("JSON: %j", { key: "value" })); results.push(util.format("Percent: %%"));
// Style strings (for console output) // Note: ANSI codes are only meaningful in terminal output // They will appear as escape sequences in HTTP responses const styled = util.format( "%s %s %s", "\x1b[31mRed\x1b[0m", "\x1b[32mGreen\x1b[0m", "\x1b[34mBlue\x1b[0m" ); console.log(styled); // Useful in logs only
// Call deprecated function (will show warning in console) const oldResult = oldFunction(); const newResult = newFunction();
// Get object's own property names const obj = { a: 1, b: 2, c: 3 }; const keys = Object.keys(obj);
return new Response(JSON.stringify({ formattedStrings: results, oldFunctionResult: oldResult, newFunctionResult: newResult, objectKeys: keys // Note: styled string not included - ANSI codes not useful in JSON }), { headers: { "Content-Type": "application/json" } });};
export default main;Example: Inheritance and class utilities
Use inherits for prototypal inheritance patterns:
import util from "node:util";import { EventEmitter } from "node:events";
// ⚠️ Note: util.inherits() is deprecated since Node.js v5.0.0// Prefer ES6 class syntax instead:// class CustomEmitter extends EventEmitter {// constructor() {// super();// this.events = [];// }// }
// Legacy pattern shown for compatibility with older codebases// Create a custom class that inherits from EventEmitterfunction CustomEmitter() { EventEmitter.call(this); this.events = [];}
// Inherit from EventEmitter (deprecated pattern)util.inherits(CustomEmitter, EventEmitter);
// Add custom methodsCustomEmitter.prototype.recordEvent = function(name, data) { this.events.push({ name, data, timestamp: Date.now() }); this.emit(name, data);};
const main = async (event) => { const emitter = new CustomEmitter(); const recordedEvents = [];
// Listen to events emitter.on("data", (data) => { console.log("Received data:", data); recordedEvents.push({ type: "data", value: data }); });
emitter.on("complete", () => { console.log("Process complete"); recordedEvents.push({ type: "complete" }); });
// Emit events emitter.recordEvent("data", { id: 1, message: "First" }); emitter.recordEvent("data", { id: 2, message: "Second" }); emitter.recordEvent("complete", null);
// Check inheritance const isEmitter = emitter instanceof EventEmitter;
return new Response(JSON.stringify({ recordedEvents, emitterEvents: emitter.events, isEventEmitter: isEmitter }), { headers: { "Content-Type": "application/json" } });};
export default main;Supported APIs
| API | Status |
|---|---|
util.promisify() | 🟢 Supported |
util.inspect() | 🟢 Supported |
util.format() | 🟢 Supported |
util.deprecate() | 🟢 Supported |
util.isDeepStrictEqual() | 🟢 Supported |
util.inherits() | 🟡 Deprecated (use ES6 classes) |
util.callbackify() | 🟡 Partially supported |
util.formatWithOptions() | 🟡 Partially supported |
util.getSystemErrorMap() | 🟡 Partially supported |
util.getSystemErrorName() | 🟡 Partially supported |
util.log() | 🟡 Partially supported |
util.stripVTControlCharacters() | 🟡 Partially supported |
util.styleText() | 🟡 Partially supported |
util.types.isDate() | 🟢 Supported |
util.types.isRegExp() | 🟢 Supported |
util.types.isPromise() | 🟢 Supported |
util.types.isArrayBuffer() | 🟢 Supported |
util.types.isNativeError() | 🟢 Supported |
util.types.isTypedArray() | 🟢 Supported |
util.types.isMap() | 🟢 Supported |
util.types.isSet() | 🟢 Supported |
util.types.isCryptoKey() | 🟢 Supported |
util.types.isKeyObject() | 🟢 Supported |
Note: APIs marked as 🟡 Partially supported have limited functionality compared to the full Node.js implementation. Note that
util.inherits()is deprecated since Node.js v5.0.0 — prefer ES6classsyntax withextendsfor inheritance. For type checking,util.typesprovides runtime-safe alternatives toinstanceofchecks.