Skip to content

Commit 2bf9f64

Browse files
committed
util: add Temporal support to inspect()
Signed-off-by: Renegade334 <contact.9a5d6388@renegade334.me.uk>
1 parent 20e6a54 commit 2bf9f64

1 file changed

Lines changed: 43 additions & 0 deletions

File tree

lib/internal/util/inspect.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,40 @@ function isURL(value) {
208208
return typeof value.href === 'string' && value instanceof internalUrl.URL;
209209
}
210210

211+
const temporalConstructors = [
212+
{ name: 'Duration', fullName: 'Temporal.Duration' },
213+
{ name: 'Instant', fullName: 'Temporal.Instant' },
214+
{ name: 'PlainDate', fullName: 'Temporal.PlainDate' },
215+
{ name: 'PlainDateTime', fullName: 'Temporal.PlainDateTime' },
216+
{ name: 'PlainMonthDay', fullName: 'Temporal.PlainMonthDay' },
217+
{ name: 'PlainTime', fullName: 'Temporal.PlainTime' },
218+
{ name: 'PlainYearMonth', fullName: 'Temporal.PlainYearMonth' },
219+
{ name: 'ZonedDateTime', fullName: 'Temporal.ZonedDateTime' },
220+
];
221+
222+
// Best-effort, using instanceof. Polyfills will likely pass these checks.
223+
// TODO: Hopefully the V8 API will expose typechecks at some point.
224+
function getTemporalInfo(value) {
225+
try {
226+
const { Temporal } = globalThis;
227+
if (Temporal != null) {
228+
for (let i = 0; i < temporalConstructors.length; i++) {
229+
const entry = temporalConstructors[i];
230+
const constructor = Temporal[entry.name];
231+
if (typeof constructor !== 'function' || !FunctionPrototypeSymbolHasInstance(constructor, value)) {
232+
continue;
233+
}
234+
const { prototype } = constructor;
235+
if (!ObjectPrototypeHasOwnProperty(prototype, 'toString')) {
236+
return;
237+
}
238+
const result = FunctionPrototypeCall(prototype.toString, value);
239+
return { ...entry, result };
240+
}
241+
}
242+
} catch { /* void */ }
243+
}
244+
211245
const builtInObjects = new SafeSet(
212246
ArrayPrototypeFilter(
213247
ObjectGetOwnPropertyNames(globalThis),
@@ -1321,6 +1355,7 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
13211355
if (noIterator) {
13221356
keys = getKeys(value, ctx.showHidden);
13231357
braces = ['{', '}'];
1358+
let temporalInfo;
13241359
if (typeof value === 'function') {
13251360
base = getFunctionBase(ctx, value, constructor, tag);
13261361
if (keys.length === 0 && protoProps === undefined)
@@ -1404,6 +1439,14 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
14041439
if (keys.length === 0 && protoProps === undefined) {
14051440
return base;
14061441
}
1442+
} else if ((temporalInfo = getTemporalInfo(value))) {
1443+
const prefix = constructor === temporalInfo.name && tag === temporalInfo.fullName ?
1444+
(temporalInfo.fullName + ' ') :
1445+
getPrefix(constructor, tag, temporalInfo.fullName);
1446+
base = `${prefix}${temporalInfo.result}`;
1447+
if (keys.length === 0 && protoProps === undefined) {
1448+
return ctx.stylize(base, 'date');
1449+
}
14071450
} else {
14081451
if (keys.length === 0 && protoProps === undefined) {
14091452
if (isExternal(value)) {

0 commit comments

Comments
 (0)