-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
index.js
111 lines (89 loc) · 2.58 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*!
* extend-proto
* Copyright (c) 2016 Jeremiah Senkpiel
* MIT Licensed
*/
/**
* Expose `Proto`.
*/
module.exports = Proto
/**
* Initialize a new `Proto` with the given `options`.
*
* @param {object} options
* @return {middleware} for prototype extension
* @public
*/
function Proto(protos, options) {
var opts = options || {}
if (!protos) {
throw new TypeError('argument `protos` is required')
}
if (typeof protos !== 'object' || Array.isArray(protos)) {
throw new TypeError('argument `protos` must be an object')
}
var _protos = Object.keys(protos)
// default `configurable` to `true` so that properties may be overwriten
opts.configurable = undefined === opts.configurable ? true : opts.configurable
// default `enumerable` to `true` so that prototypes may be properly inspected
opts.enumerable = undefined === opts.enumerable ? true : opts.enumerable
/**
* prototype extension middlware
*/
var middleware = function setProto() {
var i = arguments.length
while (i--) {
arguments[i].__proto__ = middleware[_protos[i]].proto
}
}
// setup prototypes
var i = _protos.length
while (i--) {
var name = _protos[i]
var prop = middleware[name] = {
proto: { __proto__: protos[name].prototype }
, _opts: opts
}
prop.defineProperty = defineProperty.bind(prop)
prop.defineProperties = defineProperties.bind(prop)
}
return middleware
}
/**
* define a property onto the __proto__
*/
function defineProperty(name, descriptor) {
if (!name) {
throw new TypeError('argument `name` is required')
}
if (typeof name !== 'string') {
throw new TypeError('argument `name` must be a string')
}
if (!descriptor) {
throw new TypeError('argument `descriptor` is required')
}
if (typeof descriptor !== 'object' || Array.isArray(descriptor)) {
throw new TypeError('argument `descriptor` must be an object')
}
// set user-defined options
descriptor.configurable = this._opts.configurable
descriptor.enumerable = this._opts.enumerable
Object.defineProperty(this.proto, name, descriptor)
}
/**
* define properties on __proto__ via an object map
*/
function defineProperties(props) {
if (!props) {
throw new TypeError('argument `props` is required')
}
if (typeof props !== 'object' || Array.isArray(props)) {
throw new TypeError('argument `props` must be an object')
}
// set user-defined options
for (var key in props) {
props[key].configurable = this._opts.configurable
props[key].enumerable = this._opts.enumerable
}
Object.defineProperties(this.proto, props)
}