1 | const hasOwnProperty = require('has-own-prop')
|
2 | const {isObject, isArray} = require('core-util-is')
|
3 |
|
4 |
|
5 | const PREFIX_BEFORE = 'before'
|
6 | const PREFIX_AFTER_PROP = 'after-prop'
|
7 | const PREFIX_AFTER_COLON = 'after-colon'
|
8 | const PREFIX_AFTER_VALUE = 'after-value'
|
9 | const PREFIX_AFTER = 'after'
|
10 |
|
11 | const PREFIX_BEFORE_ALL = 'before-all'
|
12 | const PREFIX_AFTER_ALL = 'after-all'
|
13 |
|
14 | const BRACKET_OPEN = '['
|
15 | const BRACKET_CLOSE = ']'
|
16 | const CURLY_BRACKET_OPEN = '{'
|
17 | const CURLY_BRACKET_CLOSE = '}'
|
18 | const COMMA = ','
|
19 | const EMPTY = ''
|
20 | const MINUS = '-'
|
21 |
|
22 | const SYMBOL_PREFIXES = [
|
23 | PREFIX_BEFORE,
|
24 | PREFIX_AFTER_PROP,
|
25 | PREFIX_AFTER_COLON,
|
26 | PREFIX_AFTER_VALUE,
|
27 | PREFIX_AFTER
|
28 | ]
|
29 |
|
30 | const NON_PROP_SYMBOL_KEYS = [
|
31 | PREFIX_BEFORE,
|
32 | PREFIX_BEFORE_ALL,
|
33 | PREFIX_AFTER_ALL
|
34 | ].map(Symbol.for)
|
35 |
|
36 | const COLON = ':'
|
37 | const UNDEFINED = undefined
|
38 |
|
39 |
|
40 | const symbol = (prefix, key) => Symbol.for(prefix + COLON + key)
|
41 |
|
42 | const define = (target, key, value) => Object.defineProperty(target, key, {
|
43 | value,
|
44 | writable: true,
|
45 | configurable: true
|
46 | })
|
47 |
|
48 | const copy_comments = (
|
49 | target, source, target_key, source_key, prefix, remove_source
|
50 | ) => {
|
51 | const source_prop = symbol(prefix, source_key)
|
52 | if (!hasOwnProperty(source, source_prop)) {
|
53 | return
|
54 | }
|
55 |
|
56 | const target_prop = target_key === source_key
|
57 | ? source_prop
|
58 | : symbol(prefix, target_key)
|
59 |
|
60 | define(target, target_prop, source[source_prop])
|
61 |
|
62 | if (remove_source) {
|
63 | delete source[source_prop]
|
64 | }
|
65 | }
|
66 |
|
67 |
|
68 | const assign = (target, source, keys) => {
|
69 | keys.forEach(key => {
|
70 | if (!hasOwnProperty(source, key)) {
|
71 | return
|
72 | }
|
73 |
|
74 | target[key] = source[key]
|
75 | SYMBOL_PREFIXES.forEach(prefix => {
|
76 | copy_comments(target, source, key, key, prefix)
|
77 | })
|
78 | })
|
79 |
|
80 | return target
|
81 | }
|
82 |
|
83 |
|
84 | module.exports = {
|
85 | SYMBOL_PREFIXES,
|
86 | NON_PROP_SYMBOL_KEYS,
|
87 |
|
88 | PREFIX_BEFORE,
|
89 | PREFIX_AFTER_PROP,
|
90 | PREFIX_AFTER_COLON,
|
91 | PREFIX_AFTER_VALUE,
|
92 | PREFIX_AFTER,
|
93 |
|
94 | PREFIX_BEFORE_ALL,
|
95 | PREFIX_AFTER_ALL,
|
96 |
|
97 | BRACKET_OPEN,
|
98 | BRACKET_CLOSE,
|
99 | CURLY_BRACKET_OPEN,
|
100 | CURLY_BRACKET_CLOSE,
|
101 |
|
102 | COLON,
|
103 | COMMA,
|
104 | MINUS,
|
105 | EMPTY,
|
106 |
|
107 | UNDEFINED,
|
108 |
|
109 | symbol,
|
110 | define,
|
111 | copy_comments,
|
112 |
|
113 | assign (target, source, keys) {
|
114 | if (!isObject(target)) {
|
115 | throw new TypeError('Cannot convert undefined or null to object')
|
116 | }
|
117 |
|
118 | if (!isObject(source)) {
|
119 | return target
|
120 | }
|
121 |
|
122 | if (keys === UNDEFINED) {
|
123 | keys = Object.keys(source)
|
124 | } else if (!isArray(keys)) {
|
125 | throw new TypeError('keys must be array or undefined')
|
126 | }
|
127 |
|
128 | return assign(target, source, keys)
|
129 | }
|
130 | }
|