unreflect 0.0.6 → 0.0.7

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.
Files changed (2) hide show
  1. package/dist/index.mjs +41 -67
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -23,8 +23,11 @@ var ReflectionClass = class {
23
23
  }
24
24
  this.values.set(name, value);
25
25
  const proto = Object.getPrototypeOf(obj);
26
+ const classSource = proto.constructor.toString();
27
+ if (!(/* @__PURE__ */ new RegExp(`#${baseName}\\b`)).test(classSource)) return;
26
28
  const protoDescriptors = Object.getOwnPropertyDescriptors(proto);
27
29
  let targetGetterName = null;
30
+ let isGetter = true;
28
31
  for (const [propName, descriptor] of Object.entries(protoDescriptors)) {
29
32
  if (propName === "constructor") continue;
30
33
  if (descriptor.get) {
@@ -34,40 +37,53 @@ var ReflectionClass = class {
34
37
  }
35
38
  }
36
39
  }
40
+ if (!targetGetterName) for (const [propName, descriptor] of Object.entries(protoDescriptors)) {
41
+ if (propName === "constructor") continue;
42
+ if (descriptor.get) {
43
+ targetGetterName = propName;
44
+ break;
45
+ }
46
+ }
37
47
  if (!targetGetterName) for (const [propName, descriptor] of Object.entries(protoDescriptors)) {
38
48
  if (propName === "constructor") continue;
39
49
  if (typeof descriptor.value === "function") {
40
50
  if (descriptor.value.toString().includes(`#${baseName}`)) {
41
51
  targetGetterName = propName;
52
+ isGetter = false;
42
53
  break;
43
54
  }
44
55
  }
45
56
  }
57
+ if (!targetGetterName) for (const [propName, descriptor] of Object.entries(protoDescriptors)) {
58
+ if (propName === "constructor") continue;
59
+ if (typeof descriptor.value === "function") {
60
+ targetGetterName = propName;
61
+ isGetter = false;
62
+ break;
63
+ }
64
+ }
46
65
  if (!targetGetterName) return;
47
66
  const objId = `__reflection_obj_${Date.now()}_${Math.random().toString(36).slice(2)}__`;
48
67
  const valId = `__reflection_val_${Date.now()}_${Math.random().toString(36).slice(2)}__`;
49
- const doneId = `__reflection_done_${Date.now()}_${Math.random().toString(36).slice(2)}__`;
50
68
  globalThis[objId] = obj;
51
69
  globalThis[valId] = value;
52
- globalThis[doneId] = false;
53
70
  const session = new inspector.Session();
54
71
  session.connect();
72
+ const capturedGetterName = targetGetterName;
55
73
  return new Promise((resolve, reject) => {
56
- let callFrameId = null;
57
74
  let resolved = false;
58
75
  const cleanup = () => {
59
76
  if (!resolved) {
60
77
  resolved = true;
61
78
  delete globalThis[objId];
62
79
  delete globalThis[valId];
63
- delete globalThis[doneId];
64
80
  session.disconnect();
65
81
  }
66
82
  };
67
83
  session.on("Debugger.paused", (message) => {
68
84
  const frames = message.params.callFrames;
69
85
  if (frames && frames.length > 0) {
70
- callFrameId = frames[0].callFrameId;
86
+ const callFrameId = frames[0].callFrameId;
71
87
  session.post("Debugger.evaluateOnCallFrame", {
72
88
  callFrameId,
73
89
  expression: `this.#${baseName} = globalThis["${valId}"]`
@@ -85,84 +101,42 @@ var ReflectionClass = class {
85
101
  reject(err);
86
102
  return;
87
103
  }
88
- const descriptor = protoDescriptors[targetGetterName];
89
- const targetFn = descriptor?.get || descriptor?.value;
90
- if (!targetFn) {
91
- cleanup();
92
- reject(/* @__PURE__ */ new Error("Target function not found"));
93
- return;
94
- }
95
- const lines = targetFn.toString().split("\n");
96
- for (const [i, line] of lines.entries()) if (line.includes(`#${baseName}`)) break;
97
104
  session.post("Runtime.enable", (err$1) => {
98
105
  if (err$1) {
99
106
  cleanup();
100
107
  reject(err$1);
101
108
  return;
102
109
  }
103
- session.post("Runtime.evaluate", { expression: `globalThis["${objId}"]` }, (err$2, result) => {
104
- if (err$2 || !result?.result?.objectId) {
110
+ session.post("Runtime.evaluate", { expression: `(function() {
111
+ const proto = Object.getPrototypeOf(globalThis["${objId}"]);
112
+ const desc = Object.getOwnPropertyDescriptor(proto, "${capturedGetterName}");
113
+ return ${isGetter} ? (desc && desc.get) : (desc && desc.value);
114
+ })()` }, (err$2, fnResult) => {
115
+ if (err$2 || !fnResult?.result?.objectId) {
105
116
  cleanup();
106
- reject(err$2 || /* @__PURE__ */ new Error("Failed to get object"));
117
+ reject(err$2 || /* @__PURE__ */ new Error("Failed to get getter function"));
107
118
  return;
108
119
  }
109
- session.post("Runtime.getProperties", {
110
- objectId: result.result.objectId,
111
- ownProperties: true
112
- }, (err$3, propsResult) => {
120
+ session.post("Debugger.setBreakpointOnFunctionCall", { objectId: fnResult.result.objectId }, (err$3, bpResult) => {
113
121
  if (err$3) {
114
122
  cleanup();
115
123
  reject(err$3);
116
124
  return;
117
125
  }
118
- const protoInternal = (propsResult.internalProperties || []).find((p) => p.name === "[[Prototype]]");
119
- if (!protoInternal?.value?.objectId) {
120
- cleanup();
121
- reject(/* @__PURE__ */ new Error("Prototype not found"));
122
- return;
123
- }
124
- session.post("Runtime.getProperties", {
125
- objectId: protoInternal.value.objectId,
126
- ownProperties: true
127
- }, (err$4, protoPropsResult) => {
128
- if (err$4) {
129
- cleanup();
130
- reject(err$4);
131
- return;
132
- }
133
- const targetProp = protoPropsResult.result?.find((p) => p.name === targetGetterName);
134
- let fnObjectId = null;
135
- if (targetProp?.get?.objectId) fnObjectId = targetProp.get.objectId;
136
- else if (targetProp?.value?.objectId) fnObjectId = targetProp.value.objectId;
137
- if (!fnObjectId) {
126
+ const breakpointId = bpResult?.breakpointId;
127
+ setTimeout(() => {
128
+ try {
129
+ if (isGetter) obj[capturedGetterName];
130
+ else obj[capturedGetterName]();
131
+ } catch {}
132
+ }, 0);
133
+ setTimeout(() => {
134
+ if (!resolved) {
135
+ if (breakpointId) session.post("Debugger.removeBreakpoint", { breakpointId }, () => {});
138
136
  cleanup();
139
- reject(/* @__PURE__ */ new Error("Function not found"));
140
- return;
137
+ reject(/* @__PURE__ */ new Error("Timeout waiting for breakpoint"));
141
138
  }
142
- session.post("Debugger.setBreakpointOnFunctionCall", { objectId: fnObjectId }, (err$5, bpResult) => {
143
- if (err$5) {
144
- cleanup();
145
- reject(err$5);
146
- return;
147
- }
148
- const breakpointId = bpResult?.breakpointId;
149
- setTimeout(() => {
150
- try {
151
- if (descriptor?.get) obj[targetGetterName];
152
- else if (typeof descriptor?.value === "function") try {
153
- descriptor.value.call(obj);
154
- } catch {}
155
- } catch {}
156
- }, 0);
157
- setTimeout(() => {
158
- if (!resolved) {
159
- if (breakpointId) session.post("Debugger.removeBreakpoint", { breakpointId }, () => {});
160
- cleanup();
161
- reject(/* @__PURE__ */ new Error("Timeout waiting for breakpoint"));
162
- }
163
- }, 5e3);
164
- });
165
- });
139
+ }, 5e3);
166
140
  });
167
141
  });
168
142
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unreflect",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
4
4
  "description": "Access and modify private class fields and methods in JavaScript",
5
5
  "repository": "KABBOUCHI/unreflect",
6
6
  "license": "MIT",