@cldmv/slothlet 3.2.1 → 3.3.0

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 (38) hide show
  1. package/README.md +24 -10
  2. package/dist/lib/builders/api_builder.mjs +233 -3
  3. package/dist/lib/handlers/api-manager.mjs +23 -0
  4. package/dist/lib/handlers/context-async.mjs +4 -0
  5. package/dist/lib/handlers/context-live.mjs +5 -0
  6. package/dist/lib/handlers/hook-manager.mjs +5 -111
  7. package/dist/lib/handlers/permission-manager.mjs +408 -0
  8. package/dist/lib/handlers/unified-wrapper.mjs +90 -22
  9. package/dist/lib/handlers/version-manager.mjs +77 -4
  10. package/dist/lib/helpers/config.mjs +91 -7
  11. package/dist/lib/helpers/pattern-matcher.mjs +141 -0
  12. package/dist/lib/i18n/languages/de-de.json +21 -1
  13. package/dist/lib/i18n/languages/en-gb.json +21 -1
  14. package/dist/lib/i18n/languages/en-us.json +21 -1
  15. package/dist/lib/i18n/languages/es-mx.json +21 -1
  16. package/dist/lib/i18n/languages/fr-fr.json +21 -1
  17. package/dist/lib/i18n/languages/hi-in.json +21 -1
  18. package/dist/lib/i18n/languages/ja-jp.json +21 -1
  19. package/dist/lib/i18n/languages/ko-kr.json +21 -1
  20. package/dist/lib/i18n/languages/pt-br.json +21 -1
  21. package/dist/lib/i18n/languages/ru-ru.json +21 -1
  22. package/dist/lib/i18n/languages/zh-cn.json +21 -1
  23. package/dist/slothlet.mjs +11 -2
  24. package/package.json +4 -1
  25. package/types/dist/lib/builders/api_builder.d.mts.map +1 -1
  26. package/types/dist/lib/handlers/api-manager.d.mts.map +1 -1
  27. package/types/dist/lib/handlers/context-async.d.mts.map +1 -1
  28. package/types/dist/lib/handlers/context-live.d.mts.map +1 -1
  29. package/types/dist/lib/handlers/hook-manager.d.mts.map +1 -1
  30. package/types/dist/lib/handlers/permission-manager.d.mts +151 -0
  31. package/types/dist/lib/handlers/permission-manager.d.mts.map +1 -0
  32. package/types/dist/lib/handlers/unified-wrapper.d.mts.map +1 -1
  33. package/types/dist/lib/handlers/version-manager.d.mts.map +1 -1
  34. package/types/dist/lib/helpers/config.d.mts +16 -0
  35. package/types/dist/lib/helpers/config.d.mts.map +1 -1
  36. package/types/dist/lib/helpers/pattern-matcher.d.mts +44 -0
  37. package/types/dist/lib/helpers/pattern-matcher.d.mts.map +1 -0
  38. package/types/dist/slothlet.d.mts.map +1 -1
@@ -0,0 +1,408 @@
1
+ /*
2
+ Copyright 2026 CLDMV/Shinrai
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+
17
+
18
+
19
+
20
+
21
+ import { ComponentBase } from "@cldmv/slothlet/factories/component-base";
22
+ import { compilePattern } from "@cldmv/slothlet/helpers/pattern-matcher";
23
+ import { translate } from "@cldmv/slothlet/i18n";
24
+
25
+
26
+ let ruleIdCounter = 0;
27
+
28
+
29
+ export class PermissionManager extends ComponentBase {
30
+
31
+ static slothletProperty = "permissionManager";
32
+
33
+
34
+ #rules = new Map();
35
+
36
+
37
+ #defaultPolicy = "allow";
38
+
39
+
40
+ #enabled = false;
41
+
42
+
43
+ #audit = "default";
44
+
45
+
46
+ #resolvedCache = new Map();
47
+
48
+
49
+ #compiledCache = new Map();
50
+
51
+
52
+ constructor(slothlet) {
53
+ super(slothlet);
54
+
55
+ const permConfig = slothlet.config?.permissions;
56
+ if (permConfig) {
57
+
58
+
59
+ this.#defaultPolicy = permConfig.defaultPolicy || "allow";
60
+ this.#enabled = permConfig.enabled !== false;
61
+ this.#audit = permConfig.audit || "default";
62
+
63
+
64
+ if (Array.isArray(permConfig.rules)) {
65
+ for (const rule of permConfig.rules) {
66
+ this.addRule(rule, null);
67
+ }
68
+ }
69
+ }
70
+
71
+
72
+ this.addRule({ caller: "**", target: "slothlet.permissions.control.**", effect: "deny" }, "__builtin__");
73
+ }
74
+
75
+
76
+ addRule(rule, ownerModuleID = null, ruleId = null) {
77
+ this.#validateRule(rule);
78
+
79
+ const id = ruleId || `perm-${++ruleIdCounter}`;
80
+ const entry = {
81
+ id,
82
+ caller: rule.caller,
83
+ target: rule.target,
84
+ effect: rule.effect,
85
+ ownerModuleID: ownerModuleID,
86
+ registeredAt: Date.now()
87
+ };
88
+
89
+ this.#rules.set(id, entry);
90
+ this.#clearCache();
91
+
92
+ this.debug("permissions", {
93
+ key: "DEBUG_PERMISSION_RULE_ADDED",
94
+ ruleId: id,
95
+ caller: rule.caller,
96
+ target: rule.target,
97
+ effect: rule.effect,
98
+ ownerModuleID
99
+ });
100
+
101
+ return id;
102
+ }
103
+
104
+
105
+ removeRule(ruleId, callerModuleID = null) {
106
+ const entry = this.#rules.get(ruleId);
107
+ if (!entry) return false;
108
+
109
+
110
+
111
+
112
+
113
+
114
+ if (callerModuleID && entry.ownerModuleID && callerModuleID === entry.ownerModuleID) {
115
+ throw new this.SlothletError("PERMISSION_SELF_MODIFY", {
116
+ ruleId,
117
+ moduleID: callerModuleID
118
+ });
119
+ }
120
+
121
+ this.#rules.delete(ruleId);
122
+ this.#clearCache();
123
+
124
+ this.debug("permissions", {
125
+ key: "DEBUG_PERMISSION_RULE_REMOVED",
126
+ ruleId,
127
+ caller: entry.caller,
128
+ target: entry.target,
129
+ effect: entry.effect
130
+ });
131
+
132
+ return true;
133
+ }
134
+
135
+
136
+ checkAccess(callerPath, targetPath, callerFilePath = null, targetFilePath = null) {
137
+
138
+
139
+
140
+
141
+
142
+
143
+ const isControlTarget = targetPath?.startsWith("slothlet.permissions.control.");
144
+ if (!this.#enabled && !isControlTarget) return true;
145
+
146
+
147
+ if (callerFilePath && targetFilePath && callerFilePath === targetFilePath) {
148
+ this.#emitAuditEvent("permission:self-bypass", {
149
+ caller: callerPath,
150
+ target: targetPath,
151
+ filePath: callerFilePath
152
+ });
153
+ return true;
154
+ }
155
+
156
+
157
+ const cacheKey = `${callerPath}::${targetPath}`;
158
+ if (this.#resolvedCache.has(cacheKey)) {
159
+ const cached = this.#resolvedCache.get(cacheKey);
160
+ this.#emitAuditEvent(cached.event, cached.payload);
161
+ return cached.allowed;
162
+ }
163
+
164
+
165
+ const entry = this.#evaluate(callerPath, targetPath);
166
+ this.#resolvedCache.set(cacheKey, entry);
167
+ this.#emitAuditEvent(entry.event, entry.payload);
168
+ return entry.allowed;
169
+ }
170
+
171
+
172
+ getRulesForPath(targetPath) {
173
+ const matching = [];
174
+ for (const entry of this.#rules.values()) {
175
+ const targetMatcher = this.#getCompiledPattern(entry.target);
176
+ if (targetMatcher(targetPath)) {
177
+ matching.push(this.#serializeRule(entry));
178
+ }
179
+ }
180
+ return matching;
181
+ }
182
+
183
+
184
+ getRulesByModule(moduleID) {
185
+ const matching = [];
186
+ for (const entry of this.#rules.values()) {
187
+ if (entry.ownerModuleID === moduleID) {
188
+ matching.push(this.#serializeRule(entry));
189
+ }
190
+ }
191
+ return matching;
192
+ }
193
+
194
+
195
+ getRulesForCaller(callerPath) {
196
+ const matching = [];
197
+ for (const entry of this.#rules.values()) {
198
+ const callerMatcher = this.#getCompiledPattern(entry.caller);
199
+ if (callerMatcher(callerPath)) {
200
+ matching.push(this.#serializeRule(entry));
201
+ }
202
+ }
203
+ return matching;
204
+ }
205
+
206
+
207
+ enable() {
208
+ this.#enabled = true;
209
+ this.#clearCache();
210
+ }
211
+
212
+
213
+ disable() {
214
+ this.#enabled = false;
215
+ this.#clearCache();
216
+ }
217
+
218
+
219
+ isEnabled() {
220
+ return this.#enabled;
221
+ }
222
+
223
+
224
+
225
+
226
+
227
+ exportRules() {
228
+ const rules = [];
229
+ for (const entry of this.#rules.values()) {
230
+ rules.push({
231
+ rule: { caller: entry.caller, target: entry.target, effect: entry.effect },
232
+ ownerModuleID: entry.ownerModuleID
233
+ });
234
+ }
235
+ return rules;
236
+ }
237
+
238
+
239
+ importRules(registrations) {
240
+ if (!Array.isArray(registrations)) return;
241
+ for (const reg of registrations) {
242
+ this.addRule(reg.rule, reg.ownerModuleID);
243
+ }
244
+ }
245
+
246
+
247
+
248
+ async shutdown() {
249
+ this.#rules.clear();
250
+ this.#resolvedCache.clear();
251
+ this.#compiledCache.clear();
252
+ this.#enabled = false;
253
+ this.#defaultPolicy = "allow";
254
+ this.#audit = "default";
255
+ }
256
+
257
+
258
+
259
+
260
+ #validateRule(rule) {
261
+ if (!rule || typeof rule !== "object") {
262
+ throw new this.SlothletError("INVALID_PERMISSION_RULE", {
263
+ reason: translate("PERM_RULE_NOT_OBJECT"),
264
+ received: typeof rule
265
+ });
266
+ }
267
+ if (typeof rule.caller !== "string" || !rule.caller) {
268
+ throw new this.SlothletError("INVALID_PERMISSION_RULE", {
269
+ reason: translate("PERM_RULE_CALLER_REQUIRED"),
270
+ received: typeof rule.caller
271
+ });
272
+ }
273
+ if (typeof rule.target !== "string" || !rule.target) {
274
+ throw new this.SlothletError("INVALID_PERMISSION_RULE", {
275
+ reason: translate("PERM_RULE_TARGET_REQUIRED"),
276
+ received: typeof rule.target
277
+ });
278
+ }
279
+ if (rule.effect !== "allow" && rule.effect !== "deny") {
280
+ throw new this.SlothletError("INVALID_PERMISSION_RULE", {
281
+ reason: translate("PERM_RULE_EFFECT_INVALID"),
282
+ received: rule.effect
283
+ });
284
+ }
285
+ }
286
+
287
+
288
+ #evaluate(callerPath, targetPath) {
289
+
290
+ const matches = [];
291
+
292
+ for (const entry of this.#rules.values()) {
293
+ const callerMatcher = this.#getCompiledPattern(entry.caller);
294
+ const targetMatcher = this.#getCompiledPattern(entry.target);
295
+
296
+ if (callerMatcher(callerPath) && targetMatcher(targetPath)) {
297
+ matches.push(entry);
298
+ }
299
+ }
300
+
301
+
302
+ if (matches.length === 0) {
303
+ const allowed = this.#defaultPolicy === "allow";
304
+ return {
305
+ allowed,
306
+ event: "permission:default",
307
+ payload: { caller: callerPath, target: targetPath, policy: this.#defaultPolicy }
308
+ };
309
+ }
310
+
311
+
312
+ matches.sort((a, b) => {
313
+ const specA = this.#computeSpecificity(a, callerPath, targetPath);
314
+ const specB = this.#computeSpecificity(b, callerPath, targetPath);
315
+ if (specA !== specB) return specB - specA;
316
+ return a.registeredAt - b.registeredAt;
317
+ });
318
+
319
+
320
+ const highestSpec = this.#computeSpecificity(matches[0], callerPath, targetPath);
321
+ const topTier = matches.filter((m) => this.#computeSpecificity(m, callerPath, targetPath) === highestSpec);
322
+
323
+ const winner = topTier[topTier.length - 1];
324
+ const allowed = winner.effect === "allow";
325
+
326
+ return {
327
+ allowed,
328
+ event: allowed ? "permission:allowed" : "permission:denied",
329
+ payload: { caller: callerPath, target: targetPath, rule: this.#serializeRule(winner) }
330
+ };
331
+ }
332
+
333
+
334
+ #computeSpecificity(entry, callerPath, targetPath) {
335
+ return this.#patternSpecificity(entry.caller, callerPath) + this.#patternSpecificity(entry.target, targetPath);
336
+ }
337
+
338
+
339
+ #patternSpecificity(pattern, _path) {
340
+
341
+ if (!pattern.includes("*") && !pattern.includes("?") && !pattern.includes("{")) {
342
+ return 3;
343
+ }
344
+
345
+ if (pattern.includes("**")) {
346
+ return 1;
347
+ }
348
+
349
+ return 2;
350
+ }
351
+
352
+
353
+ #getCompiledPattern(pattern) {
354
+ let matcher = this.#compiledCache.get(pattern);
355
+ if (!matcher) {
356
+ matcher = compilePattern(pattern);
357
+ this.#compiledCache.set(pattern, matcher);
358
+ }
359
+ return matcher;
360
+ }
361
+
362
+
363
+ #clearCache() {
364
+ this.#resolvedCache.clear();
365
+ }
366
+
367
+
368
+ #emitAuditEvent(event, payload) {
369
+
370
+ this.debug("permissions", {
371
+ key:
372
+ event === "permission:denied"
373
+ ? "DEBUG_PERMISSION_DENIED"
374
+ : event === "permission:allowed"
375
+ ? "DEBUG_PERMISSION_ALLOWED"
376
+ : event === "permission:self-bypass"
377
+ ? "DEBUG_PERMISSION_SELF_BYPASS"
378
+ : "DEBUG_PERMISSION_DEFAULT",
379
+ ...payload
380
+ });
381
+
382
+
383
+ const alwaysEmit = event === "permission:denied" || event === "permission:self-bypass";
384
+ if (!alwaysEmit && this.#audit !== "verbose") return;
385
+
386
+ const lifecycle = this.slothlet.handlers?.lifecycle;
387
+ if (lifecycle) {
388
+ lifecycle.emit(event, { ...payload, timestamp: Date.now() });
389
+ }
390
+ }
391
+
392
+
393
+ #serializeRule(entry) {
394
+ return {
395
+ id: entry.id,
396
+ caller: entry.caller,
397
+ target: entry.target,
398
+ effect: entry.effect,
399
+ ownerModuleID: entry.ownerModuleID,
400
+ registeredAt: entry.registeredAt
401
+ };
402
+ }
403
+
404
+
405
+ debug(category, data) {
406
+ this.slothlet.debug(category, data);
407
+ }
408
+ }
@@ -1654,6 +1654,13 @@ export class UnifiedWrapper extends ComponentBase {
1654
1654
  },
1655
1655
 
1656
1656
  async apply(___target, ___thisArg, args) {
1657
+
1658
+
1659
+
1660
+
1661
+
1662
+ const ___capturedCallerWrapper = wrapper.slothlet.contextManager?.tryGetContext?.()?.currentWrapper ?? null;
1663
+
1657
1664
  wrapper.slothlet.debug("wrapper", {
1658
1665
  key: "DEBUG_MODE_WAITING_APPLY_ENTRY",
1659
1666
  apiPath: wrapper.____slothletInternal.apiPath,
@@ -1834,6 +1841,27 @@ export class UnifiedWrapper extends ComponentBase {
1834
1841
 
1835
1842
 
1836
1843
 
1844
+
1845
+
1846
+
1847
+
1848
+
1849
+
1850
+ if (___capturedCallerWrapper && wrapper.slothlet.contextManager) {
1851
+ const ___instanceStore = wrapper.slothlet.contextManager.instances?.get?.(wrapper.instanceID);
1852
+
1853
+
1854
+
1855
+ if (___instanceStore && !___instanceStore.currentWrapper) {
1856
+ return wrapper.slothlet.contextManager.runInContext(
1857
+ wrapper.instanceID,
1858
+ () => Reflect.apply(current, lastObject, args),
1859
+ null,
1860
+ [],
1861
+ ___capturedCallerWrapper
1862
+ );
1863
+ }
1864
+ }
1837
1865
  return Reflect.apply(current, lastObject, args);
1838
1866
  }
1839
1867
 
@@ -2540,6 +2568,35 @@ export class UnifiedWrapper extends ComponentBase {
2540
2568
  }
2541
2569
 
2542
2570
 
2571
+
2572
+
2573
+ const permissionManager = wrapper.slothlet.handlers?.permissionManager;
2574
+ if (permissionManager && permissionManager.isEnabled()) {
2575
+ const ctx = wrapper.slothlet.contextManager?.tryGetContext?.();
2576
+
2577
+
2578
+ const callerWrapper = ctx?.currentWrapper;
2579
+
2580
+
2581
+ if (callerWrapper) {
2582
+
2583
+
2584
+ const callerPath = callerWrapper.____slothletInternal?.apiPath ?? "";
2585
+ const callerFilePath = callerWrapper.____slothletInternal?.filePath ?? null;
2586
+ const targetPath = wrapper.____slothletInternal.apiPath;
2587
+ const targetFilePath = wrapper.____slothletInternal.filePath ?? null;
2588
+
2589
+
2590
+ if (!permissionManager.checkAccess(callerPath, targetPath, callerFilePath, targetFilePath)) {
2591
+ throw new wrapper.SlothletError("PERMISSION_DENIED", {
2592
+ caller: callerPath,
2593
+ target: targetPath
2594
+ });
2595
+ }
2596
+ }
2597
+ }
2598
+
2599
+
2543
2600
  const hookManager = wrapper.slothlet.handlers?.hookManager;
2544
2601
 
2545
2602
  const hasHooks = hookManager && hookManager.enabled && !wrapper.____slothletInternal.apiPath.startsWith("slothlet.hook");
@@ -2584,33 +2641,43 @@ export class UnifiedWrapper extends ComponentBase {
2584
2641
  const checkMaterialized = () => {
2585
2642
  if (wrapper.____slothletInternal.state.materialized) {
2586
2643
  const impl = wrapper.____slothletInternal.impl;
2587
- if (typeof impl === "function") {
2588
- if (wrapper.slothlet.contextManager) {
2589
- resolve(wrapper.slothlet.contextManager.runInContext(wrapper.instanceID, impl, thisArg, args, wrapper));
2590
- } else {
2591
- resolve(impl.apply(thisArg, args));
2592
- }
2593
- } else if (impl && typeof impl === "object" && typeof impl.default === "function") {
2594
- if (wrapper.contextManager) {
2595
- resolve(wrapper.contextManager.runInContext(wrapper.instanceID, impl.default, impl, args, wrapper));
2644
+ try {
2645
+ if (typeof impl === "function") {
2646
+ if (wrapper.slothlet.contextManager) {
2647
+ resolve(wrapper.slothlet.contextManager.runInContext(wrapper.instanceID, impl, thisArg, args, wrapper));
2648
+ } else {
2649
+ resolve(impl.apply(thisArg, args));
2650
+ }
2651
+ } else if (impl && typeof impl === "object" && typeof impl.default === "function") {
2652
+ if (wrapper.contextManager) {
2653
+ resolve(wrapper.contextManager.runInContext(wrapper.instanceID, impl.default, impl, args, wrapper));
2654
+ } else {
2655
+ resolve(impl.default.apply(impl, args));
2656
+ }
2596
2657
  } else {
2597
- resolve(impl.default.apply(impl, args));
2658
+ reject(
2659
+ new wrapper.slothlet.SlothletError(
2660
+ "INVALID_CONFIG_NOT_A_FUNCTION",
2661
+ {
2662
+ apiPath: wrapper.____slothletInternal.apiPath,
2663
+ actualType: typeof impl
2664
+ },
2665
+ null,
2666
+ { validationError: true }
2667
+ )
2668
+ );
2598
2669
  }
2599
- } else {
2600
- reject(
2601
- new wrapper.slothlet.SlothletError(
2602
- "INVALID_CONFIG_NOT_A_FUNCTION",
2603
- {
2604
- apiPath: wrapper.____slothletInternal.apiPath,
2605
- actualType: typeof impl
2606
- },
2607
- null,
2608
- { validationError: true }
2609
- )
2610
- );
2670
+ } catch (err) {
2671
+
2672
+
2673
+
2674
+ reject(err);
2611
2675
  }
2612
2676
  return;
2613
2677
  }
2678
+
2679
+
2680
+
2614
2681
  if (!wrapper.____slothletInternal.state.inFlight) {
2615
2682
  reject(
2616
2683
  new wrapper.slothlet.SlothletError(
@@ -2623,6 +2690,7 @@ export class UnifiedWrapper extends ComponentBase {
2623
2690
  )
2624
2691
  );
2625
2692
  return;
2693
+
2626
2694
  }
2627
2695
  setImmediate(checkMaterialized);
2628
2696
  };
@@ -508,6 +508,30 @@ export class VersionManager extends ComponentBase {
508
508
  return manager.#walkApiPath([versionTag, ...logicalPath.split(".")]);
509
509
  };
510
510
 
511
+
512
+
513
+
514
+
515
+
516
+ target[Symbol.for("nodejs.util.inspect.custom")] = function (_depth, options, inspectFn) {
517
+ const vw = resolveVersionedWrapper();
518
+ if (vw) {
519
+ try {
520
+ return typeof inspectFn === "function" ? inspectFn(vw, options) : inspect(vw, options);
521
+ } catch {
522
+
523
+
524
+ void 0;
525
+ }
526
+ }
527
+
528
+
529
+
530
+ const entry = manager.#registry.get(logicalPath);
531
+ const versions = entry ? Array.from(entry.versions.keys()) : [];
532
+ return { __versionDispatcher: logicalPath, versions };
533
+ };
534
+
511
535
  const handlers = {
512
536
 
513
537
  get(t, prop) {
@@ -566,24 +590,26 @@ export class VersionManager extends ComponentBase {
566
590
 
567
591
 
568
592
 
569
- if (typeof prop === "symbol" && prop.toString() === "Symbol(nodejs.util.inspect.custom)") {
570
- return () => {
593
+
594
+ if (prop === inspect.custom) {
595
+ return (_depth, options, inspectFn) => {
571
596
  const vw = resolveVersionedWrapper();
572
597
  if (vw) {
573
598
  try {
574
- return inspect(vw);
599
+ return typeof inspectFn === "function" ? inspectFn(vw, options) : inspect(vw, options);
575
600
  } catch {
576
601
 
602
+
577
603
  void 0;
578
604
  }
579
605
  }
580
606
 
607
+
581
608
  const entry = manager.#registry.get(logicalPath);
582
609
  const versions = entry ? Array.from(entry.versions.keys()) : [];
583
610
  return { __versionDispatcher: logicalPath, versions };
584
611
  };
585
612
  }
586
-
587
613
 
588
614
 
589
615
  if (prop === "toString") return () => `[VersionDispatcher: ${logicalPath}]`;
@@ -741,6 +767,53 @@ export class VersionManager extends ComponentBase {
741
767
  }
742
768
 
743
769
  return Reflect.defineProperty(vw, prop, descriptor);
770
+ },
771
+
772
+
773
+ set(t, prop, value) {
774
+
775
+
776
+
777
+
778
+
779
+ if (typeof prop === "symbol") return true;
780
+
781
+
782
+ if (prop === "____slothletInternal" || prop === "_impl" || prop === "__impl" || prop === "__state" || prop === "__invalid")
783
+ return true;
784
+
785
+
786
+ if (
787
+ prop === "__isVersionDispatcher" ||
788
+ prop === "__mode" ||
789
+ prop === "__apiPath" ||
790
+ prop === "__slothletPath" ||
791
+ prop === "__isCallable" ||
792
+ prop === "__materializeOnCreate" ||
793
+ prop === "__materialized" ||
794
+ prop === "__inFlight" ||
795
+ prop === "__displayName" ||
796
+ prop === "__moduleID" ||
797
+ prop === "_materialize" ||
798
+ prop === "length" ||
799
+ prop === "name"
800
+ )
801
+ return true;
802
+
803
+
804
+ if (prop === "then" || prop === "constructor" || prop === "toString" || prop === "valueOf" || prop === "toJSON") return true;
805
+
806
+ const vw = resolveVersionedWrapper();
807
+
808
+
809
+
810
+
811
+
812
+ if (!vw) return true;
813
+
814
+
815
+
816
+ return Reflect.set(vw, prop, value, vw);
744
817
  }
745
818
  };
746
819