|
|
|
export const escaped = { |
|
'<': '\\u003C', |
|
'\\': '\\\\', |
|
'\b': '\\b', |
|
'\f': '\\f', |
|
'\n': '\\n', |
|
'\r': '\\r', |
|
'\t': '\\t', |
|
'\u2028': '\\u2028', |
|
'\u2029': '\\u2029' |
|
}; |
|
|
|
export class DevalueError extends Error { |
|
|
|
|
|
|
|
|
|
constructor(message, keys) { |
|
super(message); |
|
this.name = 'DevalueError'; |
|
this.path = keys.join(''); |
|
} |
|
} |
|
|
|
|
|
export function is_primitive(thing) { |
|
return Object(thing) !== thing; |
|
} |
|
|
|
const object_proto_names = Object.getOwnPropertyNames( |
|
Object.prototype |
|
) |
|
.sort() |
|
.join('\0'); |
|
|
|
|
|
export function is_plain_object(thing) { |
|
const proto = Object.getPrototypeOf(thing); |
|
|
|
return ( |
|
proto === Object.prototype || |
|
proto === null || |
|
Object.getOwnPropertyNames(proto).sort().join('\0') === object_proto_names |
|
); |
|
} |
|
|
|
|
|
export function get_type(thing) { |
|
return Object.prototype.toString.call(thing).slice(8, -1); |
|
} |
|
|
|
|
|
function get_escaped_char(char) { |
|
switch (char) { |
|
case '"': |
|
return '\\"'; |
|
case '<': |
|
return '\\u003C'; |
|
case '\\': |
|
return '\\\\'; |
|
case '\n': |
|
return '\\n'; |
|
case '\r': |
|
return '\\r'; |
|
case '\t': |
|
return '\\t'; |
|
case '\b': |
|
return '\\b'; |
|
case '\f': |
|
return '\\f'; |
|
case '\u2028': |
|
return '\\u2028'; |
|
case '\u2029': |
|
return '\\u2029'; |
|
default: |
|
return char < ' ' |
|
? `\\u${char.charCodeAt(0).toString(16).padStart(4, '0')}` |
|
: ''; |
|
} |
|
} |
|
|
|
|
|
export function stringify_string(str) { |
|
let result = ''; |
|
let last_pos = 0; |
|
const len = str.length; |
|
|
|
for (let i = 0; i < len; i += 1) { |
|
const char = str[i]; |
|
const replacement = get_escaped_char(char); |
|
if (replacement) { |
|
result += str.slice(last_pos, i) + replacement; |
|
last_pos = i + 1; |
|
} |
|
} |
|
|
|
return `"${last_pos === 0 ? str : result + str.slice(last_pos)}"`; |
|
} |
|
|
|
|
|
export function enumerable_symbols(object) { |
|
return Object.getOwnPropertySymbols(object).filter( |
|
(symbol) => Object.getOwnPropertyDescriptor(object, symbol).enumerable |
|
); |
|
} |
|
|