unreflect 0.0.1 → 0.0.2
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/README.md +16 -10
- package/dist/index.d.mts +2 -0
- package/dist/index.mjs +34 -23
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ import { ReflectionClass } from "unreflect";
|
|
|
22
22
|
|
|
23
23
|
class User {
|
|
24
24
|
#name = "John";
|
|
25
|
-
|
|
25
|
+
email = "john@example.com";
|
|
26
26
|
|
|
27
27
|
getName() {
|
|
28
28
|
return this.#name;
|
|
@@ -35,22 +35,27 @@ const ref = new ReflectionClass(user);
|
|
|
35
35
|
// Get class name
|
|
36
36
|
ref.getClassName(); // "User"
|
|
37
37
|
|
|
38
|
-
// Get/set
|
|
39
|
-
await ref.getPropertyValue("name"); // "John"
|
|
38
|
+
// Get/set public properties
|
|
40
39
|
await ref.getPropertyValue("email"); // "john@example.com"
|
|
40
|
+
ref.setProperty("email", "jane@example.com");
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
// Get/set private properties (use # prefix)
|
|
43
|
+
await ref.getPropertyValue("#name"); // "John"
|
|
44
|
+
ref.setProperty("#name", "Jane");
|
|
43
45
|
user.getName(); // "Jane"
|
|
44
46
|
|
|
45
47
|
// Get property metadata
|
|
46
|
-
await ref.getProperty("name");
|
|
47
|
-
// { name: "name", visibility: "private", value: "Jane" }
|
|
48
|
+
await ref.getProperty("#name");
|
|
49
|
+
// { name: "#name", visibility: "private", value: "Jane" }
|
|
50
|
+
|
|
51
|
+
await ref.getProperty("email");
|
|
52
|
+
// { name: "email", visibility: "public", value: "jane@example.com" }
|
|
48
53
|
|
|
49
54
|
// List all properties
|
|
50
55
|
await ref.getProperties();
|
|
51
56
|
// [
|
|
52
|
-
// { name: "email", visibility: "public", value: "
|
|
53
|
-
// { name: "name", visibility: "private" }
|
|
57
|
+
// { name: "email", visibility: "public", value: "jane@example.com" },
|
|
58
|
+
// { name: "#name", visibility: "private" }
|
|
54
59
|
// ]
|
|
55
60
|
|
|
56
61
|
// List all methods (including private)
|
|
@@ -60,7 +65,8 @@ await ref.getMethods();
|
|
|
60
65
|
// ]
|
|
61
66
|
|
|
62
67
|
// Check existence
|
|
63
|
-
await ref.hasProperty("name"); // true
|
|
68
|
+
await ref.hasProperty("#name"); // true
|
|
69
|
+
await ref.hasProperty("email"); // true
|
|
64
70
|
await ref.hasMethod("getName"); // true
|
|
65
71
|
```
|
|
66
72
|
|
|
@@ -69,7 +75,7 @@ await ref.hasMethod("getName"); // true
|
|
|
69
75
|
| Method | Description |
|
|
70
76
|
| -------------------------- | --------------------------------------------------- |
|
|
71
77
|
| `getClassName()` | Returns the class name |
|
|
72
|
-
| `setProperty(name, value)` | Sets a property value (
|
|
78
|
+
| `setProperty(name, value)` | Sets a property value (use `#` prefix for private) |
|
|
73
79
|
| `getProperty(name)` | Returns property metadata with visibility and value |
|
|
74
80
|
| `getPropertyValue(name)` | Returns just the property value |
|
|
75
81
|
| `getProperties()` | Returns all properties with visibility |
|
package/dist/index.d.mts
CHANGED
|
@@ -14,6 +14,8 @@ declare class ReflectionClass {
|
|
|
14
14
|
private obj;
|
|
15
15
|
private values;
|
|
16
16
|
constructor(obj: any);
|
|
17
|
+
private isPrivateName;
|
|
18
|
+
private getBaseName;
|
|
17
19
|
setProperty(name: string, value: any): void;
|
|
18
20
|
getProperty(name: string): Promise<ReflectionProperty | undefined>;
|
|
19
21
|
getPropertyValue(name: string): Promise<any>;
|
package/dist/index.mjs
CHANGED
|
@@ -8,19 +8,24 @@ var ReflectionClass = class {
|
|
|
8
8
|
constructor(obj) {
|
|
9
9
|
this.obj = obj;
|
|
10
10
|
}
|
|
11
|
+
isPrivateName(name) {
|
|
12
|
+
return name.startsWith("#");
|
|
13
|
+
}
|
|
14
|
+
getBaseName(name) {
|
|
15
|
+
return name.startsWith("#") ? name.slice(1) : name;
|
|
16
|
+
}
|
|
11
17
|
setProperty(name, value) {
|
|
12
18
|
const obj = this.obj;
|
|
13
|
-
|
|
14
|
-
|
|
19
|
+
const isPrivate = this.isPrivateName(name);
|
|
20
|
+
const baseName = this.getBaseName(name);
|
|
21
|
+
if (!isPrivate) {
|
|
22
|
+
obj[baseName] = value;
|
|
15
23
|
return;
|
|
16
24
|
}
|
|
17
25
|
const proto = Object.getPrototypeOf(obj);
|
|
18
26
|
const classSource = proto.constructor.toString();
|
|
19
|
-
if (!classSource.includes(`#${
|
|
20
|
-
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
const modifiedSource = classSource.replace(/#(\w+)\s*=\s*[^;]+;/g, "#$1;").replace(/^(class\s+\w+)\s*\{/, `$1 { static __reflectionSet__(obj, val) { obj.#${name} = val; } static __reflectionGet__(obj) { return obj.#${name}; }`);
|
|
27
|
+
if (!classSource.includes(`#${baseName}`)) return;
|
|
28
|
+
const modifiedSource = classSource.replace(/#(\w+)\s*=\s*[^;]+;/g, "#$1;").replace(/^(class\s+\w+)\s*\{/, `$1 { static __reflectionSet__(obj, val) { obj.#${baseName} = val; } static __reflectionGet__(obj) { return obj.#${baseName}; }`);
|
|
24
29
|
const ModifiedClass = vm.runInThisContext(`(${modifiedSource})`);
|
|
25
30
|
Object.setPrototypeOf(obj, ModifiedClass.prototype);
|
|
26
31
|
const originalProps = Object.getOwnPropertyDescriptors(obj);
|
|
@@ -33,7 +38,7 @@ var ReflectionClass = class {
|
|
|
33
38
|
});
|
|
34
39
|
Object.setPrototypeOf(obj, proto);
|
|
35
40
|
const methodNames = Object.getOwnPropertyNames(proto).filter((n) => n !== "constructor" && typeof proto[n] === "function");
|
|
36
|
-
for (const methodName of methodNames) if (proto[methodName].toString().includes(`#${
|
|
41
|
+
for (const methodName of methodNames) if (proto[methodName].toString().includes(`#${baseName}`)) {
|
|
37
42
|
const boundMethod = ModifiedClass.prototype[methodName].bind(freshInstance);
|
|
38
43
|
Object.defineProperty(obj, methodName, {
|
|
39
44
|
value: boundMethod,
|
|
@@ -44,10 +49,21 @@ var ReflectionClass = class {
|
|
|
44
49
|
}
|
|
45
50
|
async getProperty(name) {
|
|
46
51
|
const obj = this.obj;
|
|
47
|
-
|
|
52
|
+
const isPrivate = this.isPrivateName(name);
|
|
53
|
+
const baseName = this.getBaseName(name);
|
|
54
|
+
if (!isPrivate) {
|
|
55
|
+
if (Object.prototype.hasOwnProperty.call(obj, baseName)) return {
|
|
56
|
+
name: baseName,
|
|
57
|
+
visibility: "public",
|
|
58
|
+
value: obj[baseName]
|
|
59
|
+
};
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const cached = this.values.get(name);
|
|
63
|
+
if (cached) return {
|
|
48
64
|
name,
|
|
49
|
-
visibility: "
|
|
50
|
-
value:
|
|
65
|
+
visibility: "private",
|
|
66
|
+
value: cached.ModifiedClass.__reflectionGet__(cached.freshInstance)
|
|
51
67
|
};
|
|
52
68
|
const id = `__ref_${Date.now()}_${Math.random().toString(36).slice(2)}__`;
|
|
53
69
|
globalThis[id] = obj;
|
|
@@ -59,7 +75,7 @@ var ReflectionClass = class {
|
|
|
59
75
|
const privateProp = (await session.post("Runtime.getProperties", {
|
|
60
76
|
objectId: result.objectId,
|
|
61
77
|
ownProperties: true
|
|
62
|
-
})).privateProperties?.find((p) => p.name === `#${
|
|
78
|
+
})).privateProperties?.find((p) => p.name === `#${baseName}`);
|
|
63
79
|
if (!privateProp) return;
|
|
64
80
|
let value;
|
|
65
81
|
if (privateProp.value.type === "object" && privateProp.value.objectId) {
|
|
@@ -82,8 +98,6 @@ var ReflectionClass = class {
|
|
|
82
98
|
}
|
|
83
99
|
}
|
|
84
100
|
async getPropertyValue(name) {
|
|
85
|
-
const cached = this.values.get(name);
|
|
86
|
-
if (cached) return cached.ModifiedClass.__reflectionGet__(cached.freshInstance);
|
|
87
101
|
return (await this.getProperty(name))?.value;
|
|
88
102
|
}
|
|
89
103
|
getClassName() {
|
|
@@ -112,13 +126,10 @@ var ReflectionClass = class {
|
|
|
112
126
|
objectId: result.objectId,
|
|
113
127
|
ownProperties: true
|
|
114
128
|
});
|
|
115
|
-
if (props.privateProperties) for (const prop of props.privateProperties) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
visibility: "private"
|
|
120
|
-
});
|
|
121
|
-
}
|
|
129
|
+
if (props.privateProperties) for (const prop of props.privateProperties) properties.push({
|
|
130
|
+
name: prop.name,
|
|
131
|
+
visibility: "private"
|
|
132
|
+
});
|
|
122
133
|
} finally {
|
|
123
134
|
delete globalThis[id];
|
|
124
135
|
session.disconnect();
|
|
@@ -163,7 +174,7 @@ var ReflectionClass = class {
|
|
|
163
174
|
ownProperties: true
|
|
164
175
|
});
|
|
165
176
|
for (const prop of methodsProps.result || []) {
|
|
166
|
-
const match = (prop.value?.description || "").match(
|
|
177
|
+
const match = (prop.value?.description || "").match(/^(#\w+)\s*\(/);
|
|
167
178
|
if (match) methods.push({
|
|
168
179
|
name: match[1],
|
|
169
180
|
visibility: "private",
|
|
@@ -178,7 +189,7 @@ var ReflectionClass = class {
|
|
|
178
189
|
return methods;
|
|
179
190
|
}
|
|
180
191
|
async hasProperty(name) {
|
|
181
|
-
return
|
|
192
|
+
return await this.getProperty(name) !== void 0;
|
|
182
193
|
}
|
|
183
194
|
async hasMethod(name) {
|
|
184
195
|
return (await this.getMethods()).some((m) => m.name === name);
|