@cldmv/slothlet-types 3.15.3 → 3.16.1

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 (58) hide show
  1. package/lib/builders/api-assignment.d.mts +125 -4
  2. package/lib/builders/api_builder.d.mts +104 -7
  3. package/lib/builders/builder.d.mts +82 -1
  4. package/lib/builders/modes-processor.d.mts +66 -3
  5. package/lib/errors.d.mts +114 -19
  6. package/lib/factories/component-base.d.mts +171 -8
  7. package/lib/factories/context.d.mts +22 -4
  8. package/lib/handlers/api-cache-manager.d.mts +209 -20
  9. package/lib/handlers/api-manager.d.mts +539 -38
  10. package/lib/handlers/context-async.d.mts +92 -25
  11. package/lib/handlers/context-live.d.mts +117 -30
  12. package/lib/handlers/framework-internals.d.mts +33 -2
  13. package/lib/handlers/hook-manager.d.mts +306 -73
  14. package/lib/handlers/lifecycle-token.d.mts +48 -3
  15. package/lib/handlers/lifecycle.d.mts +86 -5
  16. package/lib/handlers/materialize-manager.d.mts +76 -8
  17. package/lib/handlers/metadata.d.mts +238 -18
  18. package/lib/handlers/module-manager.d.mts +169 -21
  19. package/lib/handlers/ownership.d.mts +376 -45
  20. package/lib/handlers/permission-manager.d.mts +283 -46
  21. package/lib/handlers/routine-manager.d.mts +425 -0
  22. package/lib/handlers/trusted-root.d.mts +45 -4
  23. package/lib/handlers/unified-wrapper.d.mts +287 -26
  24. package/lib/handlers/version-manager.d.mts +236 -29
  25. package/lib/helpers/caller-pinning.d.mts +21 -2
  26. package/lib/helpers/class-instance-wrapper.d.mts +56 -2
  27. package/lib/helpers/config.d.mts +311 -161
  28. package/lib/helpers/defaults.d.mts +39 -0
  29. package/lib/helpers/eventemitter-context.d.mts +29 -3
  30. package/lib/helpers/eventtarget-context.d.mts +19 -1
  31. package/lib/helpers/eventtarget-property-context.d.mts +21 -0
  32. package/lib/helpers/generate-manifest.d.mts +174 -7
  33. package/lib/helpers/hint-detector.d.mts +22 -2
  34. package/lib/helpers/manifest-resolver.d.mts +100 -1
  35. package/lib/helpers/modes-utils.d.mts +30 -3
  36. package/lib/helpers/module-discovery.d.mts +80 -7
  37. package/lib/helpers/module-manifest-validator.d.mts +36 -13
  38. package/lib/helpers/module-sort.d.mts +64 -1
  39. package/lib/helpers/observer-context.d.mts +21 -0
  40. package/lib/helpers/pattern-matcher.d.mts +43 -3
  41. package/lib/helpers/platform.d.mts +109 -10
  42. package/lib/helpers/resolve-from-caller.d.mts +27 -3
  43. package/lib/helpers/sanitize.d.mts +92 -4
  44. package/lib/helpers/scheduler-context.d.mts +21 -1
  45. package/lib/helpers/utilities.d.mts +52 -4
  46. package/lib/i18n/translations.d.mts +50 -5
  47. package/lib/modes/eager.d.mts +46 -8
  48. package/lib/modes/lazy.d.mts +57 -10
  49. package/lib/processors/flatten.d.mts +116 -56
  50. package/lib/processors/loader.d.mts +77 -10
  51. package/lib/processors/type-generator.d.mts +16 -2
  52. package/lib/processors/typescript.d.mts +169 -13
  53. package/lib/runtime/runtime-asynclocalstorage.d.mts +71 -3
  54. package/lib/runtime/runtime-livebindings.d.mts +37 -2
  55. package/lib/runtime/runtime.d.mts +39 -3
  56. package/lib/typegen/typegen.d.mts +34 -2
  57. package/package.json +5 -23
  58. package/slothlet.d.mts +428 -3
@@ -1,59 +1,296 @@
1
+ /**
2
+ * Manages access control rules for API path invocations.
3
+ * Rules are glob-pattern-based (same syntax as hooks: *, **, ?, {a,b}, !negation).
4
+ * Self-calls (same moduleID) always bypass the permission system.
5
+ *
6
+ * @class PermissionManager
7
+ * @extends ComponentBase
8
+ */
1
9
  export class PermissionManager extends ComponentBase {
10
+ /**
11
+ * Property name for auto-discovery by _initializeComponents.
12
+ * @type {string}
13
+ * @static
14
+ */
2
15
  static slothletProperty: string;
3
- addRule(rule: any, ownerModuleID?: null, ruleId?: null): string;
4
- removeRule(ruleId: any, callerModuleID?: null): boolean;
5
- checkAccess(callerPath: any, targetPath: any, callerFilePath?: null, targetFilePath?: null, runtimeContext?: null, options?: null): any;
6
- matchesCondition(condition: any, runtimeContext?: null): boolean;
7
- enforceAccess(callerPath: any, targetPath: any, callerFilePath?: null, targetFilePath?: null, runtimeContext?: null): any;
8
- enforceHookAccess(callerPath: any, hookPath: any, hookType: any, callerFilePath?: null, targetFilePath?: null, runtimeContext?: null): any;
9
- checkHookAccess(callerPath: any, hookPath: any, hookType: any, callerFilePath?: null, targetFilePath?: null, runtimeContext?: null): any;
10
- getRulesForPath(targetPath: any): {
11
- id: any;
12
- caller: any;
13
- target: any;
14
- effect: any;
15
- condition: any;
16
- ownerModuleID: any;
17
- registeredAt: any;
18
- }[];
19
- getRulesByModule(moduleID: any): {
20
- id: any;
21
- caller: any;
22
- target: any;
23
- effect: any;
24
- condition: any;
25
- ownerModuleID: any;
26
- registeredAt: any;
27
- }[];
28
- getRulesForCaller(callerPath: any): {
29
- id: any;
30
- caller: any;
31
- target: any;
32
- effect: any;
33
- condition: any;
34
- ownerModuleID: any;
35
- registeredAt: any;
36
- }[];
16
+ /**
17
+ * Creates a new PermissionManager instance.
18
+ *
19
+ * @param {object} slothlet - Parent slothlet instance.
20
+ * @example
21
+ * const pm = new PermissionManager(slothlet);
22
+ */
23
+ constructor(slothlet: object);
24
+ /**
25
+ * Add a permission rule.
26
+ *
27
+ * @param {object} rule - The rule definition.
28
+ * @param {string} rule.caller - Glob pattern matching caller API paths.
29
+ * @param {string} rule.target - Glob pattern matching target API paths.
30
+ * @param {string} rule.effect - "allow" or "deny".
31
+ * @param {string|null} [ownerModuleID=null] - Module ID that owns this rule.
32
+ * @param {string|null} [ruleId=null] - Optional rule ID to reuse (for replay).
33
+ * @returns {string} The rule ID (generated or reused).
34
+ * @throws {SlothletError} INVALID_PERMISSION_RULE if rule is malformed.
35
+ * @example
36
+ * pm.addRule({ caller: "payments.**", target: "db.write", effect: "allow" }, "mod_abc123");
37
+ */
38
+ addRule(rule: {
39
+ caller: string;
40
+ target: string;
41
+ effect: string;
42
+ }, ownerModuleID?: string | null, ruleId?: string | null): string;
43
+ /**
44
+ * Remove a permission rule by ID.
45
+ * A module cannot remove rules it owns (immutability).
46
+ *
47
+ * @param {string} ruleId - The rule ID to remove.
48
+ * @param {string|null} [callerModuleID=null] - Module ID of the caller attempting removal.
49
+ * @returns {boolean} True if the rule was removed.
50
+ * @throws {SlothletError} PERMISSION_SELF_MODIFY if caller owns the rule.
51
+ * @example
52
+ * pm.removeRule("perm-3", "mod_other");
53
+ */
54
+ removeRule(ruleId: string, callerModuleID?: string | null): boolean;
55
+ /**
56
+ * Silent query: check whether a caller path is allowed to access a target path.
57
+ * Never emits lifecycle or debug events — use {@link enforceAccess} at actual enforcement points.
58
+ * May read/write the resolved-decision cache unless `options.useCache` is explicitly `false`.
59
+ *
60
+ * @param {string} callerPath - The calling module's API path.
61
+ * @param {string} targetPath - The target API path being accessed.
62
+ * @param {string|null} [callerFilePath=null] - Caller's source file path (for self-call bypass).
63
+ * @param {string|null} [targetFilePath=null] - Target's source file path (for self-call bypass).
64
+ * @param {object|null} [runtimeContext=null] - Per-request ALS context for condition evaluation.
65
+ * @param {{ useCache?: boolean }|null} [options=null] - Query options.
66
+ * @param {boolean} [options.useCache=true] - Read/write resolved decision cache.
67
+ * @returns {boolean} True if access is allowed.
68
+ * @example
69
+ * const allowed = pm.checkAccess("payments.charge", "db.write", "/src/pay.mjs", "/src/db.mjs");
70
+ */
71
+ checkAccess(callerPath: string, targetPath: string, callerFilePath?: string | null, targetFilePath?: string | null, runtimeContext?: object | null, options?: {
72
+ useCache?: boolean;
73
+ } | null): boolean;
74
+ /**
75
+ * Check whether a condition payload matches the provided runtime context.
76
+ * Mirrors permission rule condition semantics used during enforcement.
77
+ *
78
+ * @param {Record<string, unknown>|Function|Array<Record<string, unknown>|Function>|null|undefined} condition - Rule condition payload.
79
+ * @param {object|null} [runtimeContext=null] - Per-request ALS context for condition evaluation.
80
+ * @returns {boolean} True when condition semantics match the runtime context.
81
+ * @example
82
+ * const ok = pm.matchesCondition({ role: "admin" }, { role: "admin" });
83
+ */
84
+ matchesCondition(condition: Record<string, unknown> | Function | Array<Record<string, unknown> | Function> | null | undefined, runtimeContext?: object | null): boolean;
85
+ /**
86
+ * Enforce access: check whether a caller is allowed to access a target and emit audit events.
87
+ * Called at actual module invocation points (applyTrap, enforceInternalPermission).
88
+ * Use {@link checkAccess} for silent queries that should not generate audit events.
89
+ *
90
+ * @param {string} callerPath - The calling module's API path.
91
+ * @param {string} targetPath - The target API path being accessed.
92
+ * @param {string|null} [callerFilePath=null] - Caller's source file path (for self-call bypass).
93
+ * @param {string|null} [targetFilePath=null] - Target's source file path (for self-call bypass).
94
+ * @param {object|null} [runtimeContext=null] - Per-request ALS context for condition evaluation.
95
+ * @returns {boolean} True if access is allowed.
96
+ * @example
97
+ * if (!pm.enforceAccess("payments.charge", "db.write", "/src/pay.mjs", "/src/db.mjs")) {
98
+ * throw new SlothletError("PERMISSION_DENIED", { caller, target });
99
+ * }
100
+ */
101
+ enforceAccess(callerPath: string, targetPath: string, callerFilePath?: string | null, targetFilePath?: string | null, runtimeContext?: object | null): boolean;
102
+ /**
103
+ * Enforce whether a caller may register or fire a hook of `hookType` on `hookPath`.
104
+ *
105
+ * Layered resolution: hook-target rules (`pattern:type`) decide when any match; otherwise the
106
+ * decision falls back to the CALL decision for `hookPath` — a path the caller may not call may
107
+ * not be hooked either. A specific-type rule (`:before`) outranks an any-type rule (`:hook`).
108
+ * Host-registered hooks (no owner identity) are always allowed (the trusted host). Emits audit
109
+ * events; use {@link checkHookAccess} for a silent query (fire-time filtering).
110
+ *
111
+ * @param {string|null} callerPath - Hook owner's API path (the registering module); null for a
112
+ * host-registered hook (no owner identity), which is always allowed.
113
+ * @param {string} hookPath - Concrete API path (fire-time) or registration pattern (registration).
114
+ * @param {string} hookType - Hook type: "before", "after", "always", or "error".
115
+ * @param {string|null} [callerFilePath=null] - Owner's source file path (for self-hook bypass).
116
+ * @param {string|null} [targetFilePath=null] - Hooked path's source file path (for self-hook bypass).
117
+ * @param {object|null} [runtimeContext=null] - Per-request ALS context for condition evaluation.
118
+ * @returns {boolean} True if hooking is allowed.
119
+ * @example
120
+ * if (!pm.enforceHookAccess("audit.log", "db.write", "error", "/src/audit.mjs", "/src/db.mjs")) {
121
+ * throw new SlothletError("PERMISSION_DENIED", { caller, target });
122
+ * }
123
+ */
124
+ enforceHookAccess(callerPath: string | null, hookPath: string, hookType: string, callerFilePath?: string | null, targetFilePath?: string | null, runtimeContext?: object | null): boolean;
125
+ /**
126
+ * Silent variant of {@link enforceHookAccess} — never emits audit/lifecycle events. Used for
127
+ * fire-time hook filtering, where emitting on every intercepted call would flood the audit stream.
128
+ *
129
+ * @param {string|null} callerPath - Hook owner's API path; null for a host-registered hook (always allowed).
130
+ * @param {string} hookPath - Concrete API path being hooked.
131
+ * @param {string} hookType - Hook type: "before", "after", "always", or "error".
132
+ * @param {string|null} [callerFilePath=null] - Owner's source file path (for self-hook bypass).
133
+ * @param {string|null} [targetFilePath=null] - Hooked path's source file path (for self-hook bypass).
134
+ * Typically null at fire time, where the target's source file isn't resolved — the filepath
135
+ * self-bypass is registration-only, so a self-hook is admitted at on()-time, not re-checked here.
136
+ * @param {object|null} [runtimeContext=null] - Per-request ALS context for condition evaluation.
137
+ * @returns {boolean} True if hooking is allowed.
138
+ * @example
139
+ * const visible = pm.checkHookAccess(hook.ownerPath, "db.write", "after");
140
+ */
141
+ checkHookAccess(callerPath: string | null, hookPath: string, hookType: string, callerFilePath?: string | null, targetFilePath?: string | null, runtimeContext?: object | null): boolean;
142
+ /**
143
+ * Get all rules that match a given target path.
144
+ *
145
+ * @param {string} targetPath - Target API path to check.
146
+ * @returns {Array<object>} Array of matching rule objects (serialized).
147
+ * @example
148
+ * const rules = pm.getRulesForPath("db.write");
149
+ */
150
+ getRulesForPath(targetPath: string): Array<object>;
151
+ /**
152
+ * Get all rules owned by a given module.
153
+ *
154
+ * @param {string} moduleID - Module ID to look up.
155
+ * @returns {Array<object>} Array of rule objects (serialized).
156
+ * @example
157
+ * const rules = pm.getRulesByModule("mod_abc123");
158
+ */
159
+ getRulesByModule(moduleID: string): Array<object>;
160
+ /**
161
+ * Get all rules where the caller pattern matches a given caller path.
162
+ * Used by `self.rules()` to show what rules affect the calling module.
163
+ *
164
+ * @param {string} callerPath - Caller API path.
165
+ * @returns {Array<object>} Array of matching rule objects (serialized).
166
+ * @example
167
+ * const rules = pm.getRulesForCaller("payments.charge");
168
+ */
169
+ getRulesForCaller(callerPath: string): Array<object>;
170
+ /**
171
+ * Enable the permission system globally.
172
+ *
173
+ * @returns {void}
174
+ * @example
175
+ * pm.enable();
176
+ */
37
177
  enable(): void;
178
+ /**
179
+ * Seal the control surface (one-way, no unseal). After sealing, `enable`, `disable`, `addRule`,
180
+ * `removeRule`, and `setReadGating` throw `PERMISSION_SEALED`. Enforcement continues to evaluate
181
+ * normally, and `shutdown()` still works. Idempotent — calling twice is a no-op.
182
+ * @returns {void}
183
+ * @example
184
+ * pm.seal();
185
+ */
38
186
  seal(): void;
187
+ /**
188
+ * Whether the control surface has been sealed.
189
+ * @returns {boolean} True if sealed.
190
+ * @example
191
+ * if (pm.isSealed()) { ... }
192
+ */
39
193
  isSealed(): boolean;
194
+ /**
195
+ * Disable the permission system globally (all calls allowed).
196
+ *
197
+ * @returns {void}
198
+ * @example
199
+ * pm.disable();
200
+ */
40
201
  disable(): void;
202
+ /**
203
+ * Whether the permission system is currently enabled.
204
+ *
205
+ * @returns {boolean} True if enabled.
206
+ * @example
207
+ * if (pm.isEnabled()) { ... }
208
+ */
41
209
  isEnabled(): boolean;
210
+ /**
211
+ * Whether terminal data-value property reads are permission-gated.
212
+ * Separate from {@link isEnabled} so call enforcement is unaffected by this default-on
213
+ * flag (opt out via `permissions.readGating: false`).
214
+ *
215
+ * @returns {boolean} True if read gating is enabled.
216
+ * @example
217
+ * if (pm.isReadGatingEnabled()) { ... }
218
+ */
42
219
  isReadGatingEnabled(): boolean;
220
+ /**
221
+ * Whether a function read out of the api keeps the identity of the module that read it.
222
+ *
223
+ * Consulted on the read path, so it is a method rather than a config lookup: reading it off the
224
+ * manager is one call instead of walking the instance's config object on every property read.
225
+ *
226
+ * @returns {boolean} True when captured references stay attributed to their capturer.
227
+ * @example
228
+ * if (pm.isCaptureEnabled()) { ... }
229
+ */
43
230
  isCaptureEnabled(): boolean;
44
- isPrivateTarget(targetPath: any): boolean;
45
- setReadGating(value: any): void;
46
- exportRules(): {
47
- rule: {
48
- caller: any;
49
- target: any;
50
- effect: any;
51
- };
52
- ownerModuleID: any;
53
- }[];
54
- importRules(registrations: any): void;
231
+ /**
232
+ * Whether an api path targets a module-private (`_`/`__`-prefixed) member (#260).
233
+ *
234
+ * @param {string|null|undefined} targetPath - Dotted api path of the read/call target.
235
+ * @returns {boolean} True when the terminal segment is underscore-prefixed.
236
+ * @public
237
+ *
238
+ * @description
239
+ * The wrapper layer consults this at its trusted-root short-circuits: a host-initiated
240
+ * read/call normally bypasses enforcement entirely, but a private-named target must still
241
+ * route through {@link enforceAccess} so the configured `permissions.private.host` policy
242
+ * applies and the denial is audited like any other.
243
+ */
244
+ public isPrivateTarget(targetPath: string | null | undefined): boolean;
245
+ /**
246
+ * Enable or disable read-level permission gating at runtime.
247
+ * Unlike {@link enable}/{@link disable}, this does not clear the resolved cache —
248
+ * the flag only controls whether property reads consult the rule set; it never
249
+ * changes the allow/deny outcome of an evaluated caller→target pair.
250
+ *
251
+ * @param {boolean} value - True to gate terminal data-value reads, false to stop.
252
+ * @returns {void}
253
+ * @throws {SlothletError} INVALID_ARGUMENT if `value` is not a boolean.
254
+ * @example
255
+ * pm.setReadGating(true);
256
+ */
257
+ setReadGating(value: boolean): void;
258
+ /**
259
+ * Export all registered rules for replay during full reload.
260
+ *
261
+ * @returns {Array<object>} Snapshot of all current rules.
262
+ * @example
263
+ * const snapshot = pm.exportRules();
264
+ */
265
+ exportRules(): Array<object>;
266
+ /**
267
+ * Re-register rules exported by {@link exportRules}.
268
+ * Called after a full reload to restore programmatic rules.
269
+ *
270
+ * @param {Array<object>} registrations - Snapshot returned by exportRules().
271
+ * @returns {void}
272
+ * @example
273
+ * pm.importRules(snapshot);
274
+ */
275
+ importRules(registrations: Array<object>): void;
276
+ /**
277
+ * Cleanup permission manager on shutdown.
278
+ * Clears all internal state.
279
+ *
280
+ * @returns {Promise<void>}
281
+ * @example
282
+ * await pm.shutdown();
283
+ */
55
284
  shutdown(): Promise<void>;
56
- debug(category: any, data: any): void;
285
+ /**
286
+ * Emit a debug message. Delegates to slothlet.debug().
287
+ *
288
+ * @param {string} category - Debug category.
289
+ * @param {object} data - Debug data.
290
+ * @returns {void}
291
+ * @private
292
+ */
293
+ private debug;
57
294
  #private;
58
295
  }
59
296
  import { ComponentBase } from "#factories/component-base";