cfprotected 1.1.2 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.mjs +49 -32
- package/package.json +1 -1
- package/test/test.mjs +17 -3
package/index.mjs
CHANGED
|
@@ -8,6 +8,28 @@ function getAllOwnKeys(o) {
|
|
|
8
8
|
.concat(Object.getOwnPropertySymbols(o));
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
function useDescriptor(desc, fn) {
|
|
12
|
+
if ("value" in desc) {
|
|
13
|
+
if (typeof(desc.value) == "function") {
|
|
14
|
+
fn("value");
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
if (typeof(desc.get) == "function") {
|
|
19
|
+
fn("get");
|
|
20
|
+
}
|
|
21
|
+
if (typeof(desc.set) == "function") {
|
|
22
|
+
fn("set");
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function bindDescriptor(desc, context) {
|
|
28
|
+
useDescriptor(desc, (key) => {
|
|
29
|
+
desc[key] = desc[key].bind(context);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
11
33
|
/**
|
|
12
34
|
* Used to both store inherited property information as well as retrieve it.
|
|
13
35
|
* @param {Object} inst The instance object that will own the shared members.
|
|
@@ -17,8 +39,6 @@ function getAllOwnKeys(o) {
|
|
|
17
39
|
* @returns {Object} The fully constructed inheritance object.
|
|
18
40
|
*/
|
|
19
41
|
function share(inst, klass, members) {
|
|
20
|
-
let retval = {};
|
|
21
|
-
|
|
22
42
|
if ((typeof(inst) == "function")
|
|
23
43
|
&& klass && (typeof(klass) == "object")
|
|
24
44
|
&& (members === void 0)) {
|
|
@@ -63,58 +83,55 @@ function share(inst, klass, members) {
|
|
|
63
83
|
|
|
64
84
|
//Get the protected data object.
|
|
65
85
|
let ancestorKey = (inst === klass) ? ancestor : inst;
|
|
66
|
-
let memo = ancestorMemo.get(ancestorKey) || {
|
|
67
|
-
|
|
86
|
+
let memo = ancestorMemo.get(ancestorKey) || {
|
|
87
|
+
data: {},
|
|
88
|
+
$uper: {},
|
|
89
|
+
};
|
|
90
|
+
let retval = {};
|
|
68
91
|
|
|
69
92
|
//Get the details of the protected properties.
|
|
70
93
|
let mDesc = Object.getOwnPropertyDescriptors(members);
|
|
71
94
|
let mKeys = getAllOwnKeys(members);
|
|
72
95
|
|
|
73
96
|
//Change the prototype of protoData using the new members.
|
|
74
|
-
let prototype = Object.getPrototypeOf(
|
|
97
|
+
let prototype = Object.getPrototypeOf(memo.data);
|
|
75
98
|
let proto = Object.create(prototype,
|
|
76
99
|
Object.fromEntries(mKeys
|
|
77
|
-
.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
: mDesc[m];
|
|
90
|
-
|
|
91
|
-
Object.defineProperty(retval, m, desc);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
//Define the "super" accessors
|
|
95
|
-
Object.defineProperty(retval, "$uper", { value: {} });
|
|
100
|
+
.map(k => {
|
|
101
|
+
if (mDesc[k].value?.hasOwnProperty(ACCESSOR)) {
|
|
102
|
+
Object.assign(mDesc[k], mDesc[k].value);
|
|
103
|
+
mDesc[k].enumerable = true;
|
|
104
|
+
delete mDesc[k][ACCESSOR];
|
|
105
|
+
delete mDesc[k].value;
|
|
106
|
+
delete mDesc[k].writable;
|
|
107
|
+
}
|
|
108
|
+
bindDescriptor(mDesc[k], inst);
|
|
109
|
+
return [k, mDesc[k]];
|
|
110
|
+
})));
|
|
111
|
+
Object.setPrototypeOf(retval, proto);
|
|
96
112
|
|
|
113
|
+
//Define the "$uper" accessors
|
|
114
|
+
let $uper = {};
|
|
115
|
+
Object.defineProperty(retval, "$uper", { value: $uper });
|
|
116
|
+
|
|
117
|
+
//Build up the "$uper" object
|
|
97
118
|
for (let key of mKeys) {
|
|
98
119
|
if (key in prototype) {
|
|
99
120
|
let obj = prototype;
|
|
100
121
|
while (!obj.hasOwnProperty(key)) {
|
|
101
122
|
obj = Object.getPrototypeOf(obj);
|
|
102
123
|
}
|
|
103
|
-
Object.defineProperty(
|
|
124
|
+
Object.defineProperty($uper, key, Object.getOwnPropertyDescriptor(obj, key));
|
|
104
125
|
}
|
|
105
126
|
}
|
|
106
127
|
|
|
107
128
|
//Attach the super inheritance
|
|
108
|
-
Object.setPrototypeOf(
|
|
109
|
-
|
|
110
|
-
//Inherit the inheritance
|
|
111
|
-
Object.setPrototypeOf(retval, memo.inheritance);
|
|
129
|
+
Object.setPrototypeOf($uper, memo.$uper);
|
|
112
130
|
|
|
113
131
|
//Save the inheritance & protected data
|
|
114
132
|
memos.get(klass).set(inst, {
|
|
115
|
-
data:
|
|
116
|
-
|
|
117
|
-
$uper: retval.$uper
|
|
133
|
+
data: retval,
|
|
134
|
+
$uper: $uper
|
|
118
135
|
});
|
|
119
136
|
|
|
120
137
|
return retval;
|
package/package.json
CHANGED
package/test/test.mjs
CHANGED
|
@@ -2,6 +2,10 @@ import { TestWatcher } from "@jest/core";
|
|
|
2
2
|
import { share, saveSelf, accessor, abstract, final } from "../index"; //require("cfprotected");
|
|
3
3
|
|
|
4
4
|
class Base {
|
|
5
|
+
static #greeting = "Hello!";
|
|
6
|
+
static #sprot = share(this, {
|
|
7
|
+
getGreeting() { return this.#greeting; }
|
|
8
|
+
});
|
|
5
9
|
#prot = share(this, Base, {
|
|
6
10
|
num: 42,
|
|
7
11
|
name: "John Jacob Jingleheimerschmidt",
|
|
@@ -12,7 +16,6 @@ class Base {
|
|
|
12
16
|
get: () => this.propTestVal
|
|
13
17
|
}),
|
|
14
18
|
superTest: () => {
|
|
15
|
-
console.log(`Called Base::superTest() ...`);
|
|
16
19
|
return 1;
|
|
17
20
|
}
|
|
18
21
|
});
|
|
@@ -76,12 +79,16 @@ class Derived extends Base {
|
|
|
76
79
|
class NonParticipant extends Base {}
|
|
77
80
|
|
|
78
81
|
class GrandChild extends NonParticipant {
|
|
82
|
+
static #sprot = share(this, {
|
|
83
|
+
getGreeting() {
|
|
84
|
+
return `${this.#sprot.$uper.getGreeting()} My name is`;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
79
87
|
#prot = share(this, GrandChild, {
|
|
80
88
|
otherMethod: () => {
|
|
81
89
|
this.#prot.name = this.testName;
|
|
82
90
|
},
|
|
83
91
|
superTest: () => {
|
|
84
|
-
console.log(`Called GrandChild::superTest() ...`);
|
|
85
92
|
return 1 + this.pvt.#prot.$uper.superTest();
|
|
86
93
|
}
|
|
87
94
|
});
|
|
@@ -103,9 +110,13 @@ class GrandChild extends NonParticipant {
|
|
|
103
110
|
}
|
|
104
111
|
|
|
105
112
|
class SuperTest extends GrandChild {
|
|
113
|
+
static #sprot = share(this, {
|
|
114
|
+
getGreeting() {
|
|
115
|
+
return `${this.#sprot.$uper.getGreeting()} "${this.name}"!`
|
|
116
|
+
}
|
|
117
|
+
});
|
|
106
118
|
#prot = share(this, SuperTest, {
|
|
107
119
|
superTest: () => {
|
|
108
|
-
console.log(`Called SuperTest::superTest() ...`);
|
|
109
120
|
return 1 + this.pvt.#prot.$uper.superTest();
|
|
110
121
|
}
|
|
111
122
|
});
|
|
@@ -119,6 +130,9 @@ class SuperTest extends GrandChild {
|
|
|
119
130
|
test(`Should be able to call super through the entire inheritance chain`, () => {
|
|
120
131
|
expect(this.pvt.#prot.superTest()).toBe(3);
|
|
121
132
|
});
|
|
133
|
+
test(`Should be able to call super through the entire static inheritance chain`, () => {
|
|
134
|
+
expect(SuperTest.#sprot.getGreeting()).toBe(`Hello! My name is "SuperTest"!`);
|
|
135
|
+
});
|
|
122
136
|
}
|
|
123
137
|
}
|
|
124
138
|
|