mirror of
https://github.com/Snigdha-OS/documentation.git
synced 2025-09-07 19:25:13 +02:00
149 lines
5.2 KiB
JavaScript
149 lines
5.2 KiB
JavaScript
import isPlainObject from 'is-plain-obj';
|
|
/**
|
|
* Convert a value to an ESTree node
|
|
*
|
|
* @param value The value to convert
|
|
* @param options Additional options to configure the output.
|
|
* @returns The ESTree node.
|
|
*/
|
|
export function valueToEstree(value, options = {}) {
|
|
if (value === undefined || value === Number.POSITIVE_INFINITY || Number.isNaN(value)) {
|
|
return { type: 'Identifier', name: String(value) };
|
|
}
|
|
if (value == null || typeof value === 'string' || typeof value === 'boolean') {
|
|
return { type: 'Literal', value };
|
|
}
|
|
if (typeof value === 'bigint') {
|
|
return value >= 0
|
|
? { type: 'Literal', value, bigint: String(value) }
|
|
: {
|
|
type: 'UnaryExpression',
|
|
operator: '-',
|
|
prefix: true,
|
|
argument: valueToEstree(-value, options)
|
|
};
|
|
}
|
|
if (typeof value === 'number') {
|
|
return value >= 0 && !Object.is(value, -0)
|
|
? { type: 'Literal', value }
|
|
: {
|
|
type: 'UnaryExpression',
|
|
operator: '-',
|
|
prefix: true,
|
|
argument: valueToEstree(-value, options)
|
|
};
|
|
}
|
|
if (typeof value === 'symbol') {
|
|
if (value.description && value === Symbol.for(value.description)) {
|
|
return {
|
|
type: 'CallExpression',
|
|
optional: false,
|
|
callee: {
|
|
type: 'MemberExpression',
|
|
computed: false,
|
|
optional: false,
|
|
object: { type: 'Identifier', name: 'Symbol' },
|
|
property: { type: 'Identifier', name: 'for' }
|
|
},
|
|
arguments: [valueToEstree(value.description, options)]
|
|
};
|
|
}
|
|
throw new TypeError(`Only global symbols are supported, got: ${String(value)}`);
|
|
}
|
|
if (Array.isArray(value)) {
|
|
const elements = [];
|
|
for (let i = 0; i < value.length; i += 1) {
|
|
elements.push(i in value ? valueToEstree(value[i], options) : null);
|
|
}
|
|
return { type: 'ArrayExpression', elements };
|
|
}
|
|
if (value instanceof Boolean || value instanceof Number || value instanceof String) {
|
|
return {
|
|
type: 'NewExpression',
|
|
callee: { type: 'Identifier', name: value.constructor.name },
|
|
arguments: [valueToEstree(value.valueOf())]
|
|
};
|
|
}
|
|
if (value instanceof RegExp) {
|
|
return {
|
|
type: 'Literal',
|
|
value,
|
|
regex: { pattern: value.source, flags: value.flags }
|
|
};
|
|
}
|
|
if (value instanceof Date) {
|
|
return {
|
|
type: 'NewExpression',
|
|
callee: { type: 'Identifier', name: 'Date' },
|
|
arguments: [valueToEstree(value.getTime(), options)]
|
|
};
|
|
}
|
|
if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {
|
|
return {
|
|
type: 'CallExpression',
|
|
optional: false,
|
|
callee: {
|
|
type: 'MemberExpression',
|
|
computed: false,
|
|
optional: false,
|
|
object: { type: 'Identifier', name: 'Buffer' },
|
|
property: { type: 'Identifier', name: 'from' }
|
|
},
|
|
arguments: [valueToEstree([...value])]
|
|
};
|
|
}
|
|
if (value instanceof BigInt64Array ||
|
|
value instanceof BigUint64Array ||
|
|
value instanceof Float32Array ||
|
|
value instanceof Float64Array ||
|
|
value instanceof Int8Array ||
|
|
value instanceof Int16Array ||
|
|
value instanceof Int32Array ||
|
|
value instanceof Map ||
|
|
value instanceof Set ||
|
|
value instanceof Uint8Array ||
|
|
value instanceof Uint8ClampedArray ||
|
|
value instanceof Uint16Array ||
|
|
value instanceof Uint32Array) {
|
|
return {
|
|
type: 'NewExpression',
|
|
callee: { type: 'Identifier', name: value.constructor.name },
|
|
arguments: [valueToEstree([...value], options)]
|
|
};
|
|
}
|
|
if (value instanceof URL || value instanceof URLSearchParams) {
|
|
return {
|
|
type: 'NewExpression',
|
|
callee: { type: 'Identifier', name: value.constructor.name },
|
|
arguments: [valueToEstree(String(value), options)]
|
|
};
|
|
}
|
|
if (options.instanceAsObject || isPlainObject(value)) {
|
|
const properties = Reflect.ownKeys(value).map((key) => ({
|
|
type: 'Property',
|
|
method: false,
|
|
shorthand: false,
|
|
computed: typeof key !== 'string',
|
|
kind: 'init',
|
|
key: valueToEstree(key, options),
|
|
value: valueToEstree(value[key], options)
|
|
}));
|
|
if (Object.getPrototypeOf(value) == null) {
|
|
properties.unshift({
|
|
type: 'Property',
|
|
method: false,
|
|
shorthand: false,
|
|
computed: false,
|
|
kind: 'init',
|
|
key: { type: 'Identifier', name: '__proto__' },
|
|
value: { type: 'Literal', value: null }
|
|
});
|
|
}
|
|
return {
|
|
type: 'ObjectExpression',
|
|
properties
|
|
};
|
|
}
|
|
throw new TypeError(`Unsupported value: ${String(value)}`);
|
|
}
|