@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.
- package/lib/builders/api-assignment.d.mts +125 -4
- package/lib/builders/api_builder.d.mts +104 -7
- package/lib/builders/builder.d.mts +82 -1
- package/lib/builders/modes-processor.d.mts +66 -3
- package/lib/errors.d.mts +114 -19
- package/lib/factories/component-base.d.mts +171 -8
- package/lib/factories/context.d.mts +22 -4
- package/lib/handlers/api-cache-manager.d.mts +209 -20
- package/lib/handlers/api-manager.d.mts +539 -38
- package/lib/handlers/context-async.d.mts +92 -25
- package/lib/handlers/context-live.d.mts +117 -30
- package/lib/handlers/framework-internals.d.mts +33 -2
- package/lib/handlers/hook-manager.d.mts +306 -73
- package/lib/handlers/lifecycle-token.d.mts +48 -3
- package/lib/handlers/lifecycle.d.mts +86 -5
- package/lib/handlers/materialize-manager.d.mts +76 -8
- package/lib/handlers/metadata.d.mts +238 -18
- package/lib/handlers/module-manager.d.mts +169 -21
- package/lib/handlers/ownership.d.mts +376 -45
- package/lib/handlers/permission-manager.d.mts +283 -46
- package/lib/handlers/routine-manager.d.mts +425 -0
- package/lib/handlers/trusted-root.d.mts +45 -4
- package/lib/handlers/unified-wrapper.d.mts +287 -26
- package/lib/handlers/version-manager.d.mts +236 -29
- package/lib/helpers/caller-pinning.d.mts +21 -2
- package/lib/helpers/class-instance-wrapper.d.mts +56 -2
- package/lib/helpers/config.d.mts +311 -161
- package/lib/helpers/defaults.d.mts +39 -0
- package/lib/helpers/eventemitter-context.d.mts +29 -3
- package/lib/helpers/eventtarget-context.d.mts +19 -1
- package/lib/helpers/eventtarget-property-context.d.mts +21 -0
- package/lib/helpers/generate-manifest.d.mts +174 -7
- package/lib/helpers/hint-detector.d.mts +22 -2
- package/lib/helpers/manifest-resolver.d.mts +100 -1
- package/lib/helpers/modes-utils.d.mts +30 -3
- package/lib/helpers/module-discovery.d.mts +80 -7
- package/lib/helpers/module-manifest-validator.d.mts +36 -13
- package/lib/helpers/module-sort.d.mts +64 -1
- package/lib/helpers/observer-context.d.mts +21 -0
- package/lib/helpers/pattern-matcher.d.mts +43 -3
- package/lib/helpers/platform.d.mts +109 -10
- package/lib/helpers/resolve-from-caller.d.mts +27 -3
- package/lib/helpers/sanitize.d.mts +92 -4
- package/lib/helpers/scheduler-context.d.mts +21 -1
- package/lib/helpers/utilities.d.mts +52 -4
- package/lib/i18n/translations.d.mts +50 -5
- package/lib/modes/eager.d.mts +46 -8
- package/lib/modes/lazy.d.mts +57 -10
- package/lib/processors/flatten.d.mts +116 -56
- package/lib/processors/loader.d.mts +77 -10
- package/lib/processors/type-generator.d.mts +16 -2
- package/lib/processors/typescript.d.mts +169 -13
- package/lib/runtime/runtime-asynclocalstorage.d.mts +71 -3
- package/lib/runtime/runtime-livebindings.d.mts +37 -2
- package/lib/runtime/runtime.d.mts +39 -3
- package/lib/typegen/typegen.d.mts +34 -2
- package/package.json +5 -23
- package/slothlet.d.mts +428 -3
|
@@ -1,3 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @function runtime_shouldWrapMethod
|
|
3
|
+
* @package
|
|
4
|
+
* @param {*} value - The value to check
|
|
5
|
+
* @param {string|symbol} prop - The property name
|
|
6
|
+
* @returns {boolean} True if the method should be wrapped
|
|
7
|
+
*
|
|
8
|
+
* @description
|
|
9
|
+
* Determines if a method should be wrapped with context preservation.
|
|
10
|
+
* Excludes constructors, Object.prototype methods, and internal methods.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* runtime_shouldWrapMethod(myInstance.method, "method"); // true
|
|
14
|
+
* runtime_shouldWrapMethod(myInstance.constructor, "constructor"); // false
|
|
15
|
+
*/
|
|
16
|
+
export function runtime_shouldWrapMethod(value: any, prop: string | symbol): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* @function runtime_isClassInstance
|
|
19
|
+
* @package
|
|
20
|
+
* @param {*} val - The value to check
|
|
21
|
+
* @returns {boolean} True if the value is a class instance that should be wrapped
|
|
22
|
+
*
|
|
23
|
+
* @description
|
|
24
|
+
* Determines if a value is a class instance (not a plain object, array, or primitive)
|
|
25
|
+
* that should have its methods wrapped to preserve AsyncLocalStorage context.
|
|
26
|
+
* Uses systematic exclusion lists for better maintainability.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* // Check if value is a class instance
|
|
30
|
+
* const isInstance = runtime_isClassInstance(new MyClass());
|
|
31
|
+
*/
|
|
1
32
|
export function runtime_isClassInstance(val: any): boolean;
|
|
2
|
-
|
|
3
|
-
|
|
33
|
+
/**
|
|
34
|
+
* @function runtime_wrapClassInstance
|
|
35
|
+
* @package
|
|
36
|
+
* @param {object} instance - The class instance to wrap
|
|
37
|
+
* @param {object} contextManager - The context manager (async or live)
|
|
38
|
+
* @param {string} instanceID - The slothlet instance ID
|
|
39
|
+
* @param {WeakMap} instanceCache - The cache for wrapped instances
|
|
40
|
+
* @param {object} [capturedWrapper] - Wrapper of the module that created this instance,
|
|
41
|
+
* snapshotted at wrap time. Used as the caller identity for the instance's method calls so
|
|
42
|
+
* that `self.*` calls from a class method are permission-checked as the creating module
|
|
43
|
+
* (the method is neither exempt from nor spuriously denied by the permission layer).
|
|
44
|
+
* @returns {Proxy} A proxied instance with context-aware method calls
|
|
45
|
+
*
|
|
46
|
+
* @description
|
|
47
|
+
* Wraps a class instance so that all method calls maintain the AsyncLocalStorage context.
|
|
48
|
+
* This ensures that calls to methods on returned class instances preserve the slothlet
|
|
49
|
+
* context for runtime imports like `self` and `context`.
|
|
50
|
+
*
|
|
51
|
+
* V3 Adaptation: Uses contextManager.runInContext() instead of V2's runWithCtx().
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* // Wrap a class instance to preserve context
|
|
55
|
+
* const wrappedInstance = runtime_wrapClassInstance(instance, contextManager, instanceID, instanceCache, creatingWrapper);
|
|
56
|
+
*/
|
|
57
|
+
export function runtime_wrapClassInstance(instance: object, contextManager: object, instanceID: string, instanceCache: WeakMap<any, any>, capturedWrapper?: object): ProxyConstructor;
|
package/lib/helpers/config.d.mts
CHANGED
|
@@ -1,170 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalize the `hook` config (V2-style support) into a canonical
|
|
3
|
+
* `{ enabled, pattern, suppressErrors }` object.
|
|
4
|
+
*
|
|
5
|
+
* Accepts the boolean form (enable/disable with the catch-all pattern), the string form
|
|
6
|
+
* (enable, restricting hooks to a global path pattern — e.g. `"database.*"`), or the full
|
|
7
|
+
* object form. Idempotent: an already-normalized object normalizes to an equivalent object,
|
|
8
|
+
* so `reload()` can re-feed it.
|
|
9
|
+
*
|
|
10
|
+
* Exported as a standalone function (not just a {@link Config} method) because the HookManager
|
|
11
|
+
* is constructed during `_initializeComponents` — BEFORE `transformConfig` runs — so it cannot
|
|
12
|
+
* rely on the normalized config being in place yet, and must normalize the raw `config.hook`
|
|
13
|
+
* itself from the same source of truth.
|
|
14
|
+
*
|
|
15
|
+
* @param {boolean|string|Object} [hook] - Raw hook config in any supported form.
|
|
16
|
+
* @returns {{enabled: boolean, pattern: (string|null), suppressErrors: boolean, pin: boolean}} Normalized hook config.
|
|
17
|
+
* @public
|
|
18
|
+
*/
|
|
19
|
+
export function normalizeHookConfig(hook?: boolean | string | Object): {
|
|
20
|
+
enabled: boolean;
|
|
21
|
+
pattern: (string | null);
|
|
22
|
+
suppressErrors: boolean;
|
|
23
|
+
pin: boolean;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Configuration normalization utilities
|
|
27
|
+
* @class Config
|
|
28
|
+
* @extends ComponentBase
|
|
29
|
+
* @public
|
|
30
|
+
*/
|
|
1
31
|
export class Config extends ComponentBase {
|
|
2
32
|
static slothletProperty: string;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Normalize collision configuration for handling property collisions
|
|
35
|
+
* @param {string|Object} collision - Collision mode or object with per-context modes
|
|
36
|
+
* @returns {Object} Normalized collision configuration with initial and api.slothlet.api.add modes
|
|
37
|
+
* @public
|
|
38
|
+
*
|
|
39
|
+
* @description
|
|
40
|
+
* Normalizes collision handling configuration for both initial load (buildAPI)
|
|
41
|
+
* and hot reload (api.add) contexts. Supports six collision modes:
|
|
42
|
+
* - "skip": Silently ignore collision, keep existing value
|
|
43
|
+
* - "warn": Warn about collision, keep existing value
|
|
44
|
+
* - "replace": Replace existing value completely
|
|
45
|
+
* - "merge": Merge properties (preserve original + add new)
|
|
46
|
+
* - "merge-replace": Merge properties (add new + overwrite existing with new values)
|
|
47
|
+
* - "error": Throw error on collision
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* // String shorthand applies to both contexts
|
|
51
|
+
* normalizeCollision("merge")
|
|
52
|
+
* // => { initial: "merge", api: "merge" }
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* // Object allows per-context control
|
|
56
|
+
* normalizeCollision({ initial: "warn", api: "error" })
|
|
57
|
+
* // => { initial: "warn", api: "error" }
|
|
58
|
+
*/
|
|
59
|
+
public normalizeCollision(collision: string | Object): Object;
|
|
60
|
+
/**
|
|
61
|
+
* Normalize runtime input to internal standard format
|
|
62
|
+
* @param {string} runtime - Input runtime type (various formats accepted)
|
|
63
|
+
* @returns {string} Normalized runtime type ("async" or "live")
|
|
64
|
+
* @public
|
|
65
|
+
*/
|
|
66
|
+
public normalizeRuntime(runtime: string): string;
|
|
67
|
+
/**
|
|
68
|
+
* Normalize mode input to internal standard format
|
|
69
|
+
* @param {string} mode - Input mode type (various formats accepted)
|
|
70
|
+
* @returns {string} Normalized mode type ("eager" or "lazy")
|
|
71
|
+
* @public
|
|
72
|
+
*/
|
|
73
|
+
public normalizeMode(mode: string): string;
|
|
74
|
+
/**
|
|
75
|
+
* Normalize mutations configuration for API modification control
|
|
76
|
+
* @param {Object} mutations - Mutations config object with add/remove/reload properties
|
|
77
|
+
* @returns {Object} Normalized mutations configuration
|
|
78
|
+
* @public
|
|
79
|
+
*
|
|
80
|
+
* @description
|
|
81
|
+
* Normalizes mutation control configuration for API runtime modifications.
|
|
82
|
+
* Controls whether api.slothlet.api.add(), api.slothlet.api.remove(), and
|
|
83
|
+
* api.slothlet.reload() operations are allowed.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* // Allow all mutations (default)
|
|
87
|
+
* normalizeMutations({ add: true, remove: true, reload: true })
|
|
88
|
+
* // => { add: true, remove: true, reload: true }
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* // Disable all mutations
|
|
92
|
+
* normalizeMutations({ add: false, remove: false, reload: false })
|
|
93
|
+
* // => { add: false, remove: false, reload: false }
|
|
94
|
+
*/
|
|
95
|
+
public normalizeMutations(mutations: Object): Object;
|
|
96
|
+
/**
|
|
97
|
+
* Normalize debug configuration
|
|
98
|
+
* @param {boolean|Object} debug - Debug flag or object with targeted flags
|
|
99
|
+
* @returns {Object} Normalized debug object with all flags
|
|
100
|
+
* @public
|
|
101
|
+
*/
|
|
102
|
+
public normalizeDebug(debug: boolean | Object): Object;
|
|
103
|
+
/**
|
|
104
|
+
* Normalize execution-environment target from the raw `platform` config value.
|
|
105
|
+
*
|
|
106
|
+
* @description
|
|
107
|
+
* Distinct from `normalizeEnv()` which handles the `process.env` snapshot
|
|
108
|
+
* allowlist (`config.env`). This method determines *where* slothlet is executing
|
|
109
|
+
* so that filesystem-dependent code paths can be bypassed in browser/worker builds.
|
|
110
|
+
*
|
|
111
|
+
* When `platform` is omitted the method auto-detects by checking whether
|
|
112
|
+
* `process.versions.node` is available (true in Node.js; absent or undefined
|
|
113
|
+
* in browsers, web workers, and Electron renderers without nodeIntegration).
|
|
114
|
+
* Pass `"browser"` or `"node"` to override auto-detection for edge cases
|
|
115
|
+
* (e.g. Deno, Electron with custom process polyfills).
|
|
116
|
+
*
|
|
117
|
+
* @param {*} platform - Raw value of `config.platform` before normalisation.
|
|
118
|
+
* @returns {"browser"|"node"} Execution-environment target.
|
|
119
|
+
* @public
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* normalizeEnvTarget("browser"); // => "browser" (explicit override)
|
|
123
|
+
* normalizeEnvTarget("node"); // => "node" (explicit override)
|
|
124
|
+
* normalizeEnvTarget(undefined); // => "browser" or "node" (auto-detected)
|
|
125
|
+
*/
|
|
126
|
+
public normalizeEnvTarget(platform: any, hasManifest?: boolean): "browser" | "node";
|
|
127
|
+
/**
|
|
128
|
+
* Normalize the `hook` config (V2-style support) into a canonical
|
|
129
|
+
* `{ enabled, pattern, suppressErrors }` object.
|
|
130
|
+
*
|
|
131
|
+
* Accepts the boolean form (enable/disable with the catch-all pattern), the string form
|
|
132
|
+
* (enable, restricting hooks to a global path pattern — e.g. `"database.*"`), or the full
|
|
133
|
+
* object form. Idempotent: an already-normalized object normalizes to an equivalent object,
|
|
134
|
+
* so `reload()` can re-feed it. Shared by {@link transformConfig} and the HookManager so both
|
|
135
|
+
* derive the same values regardless of construction order (the manager is built before
|
|
136
|
+
* transformConfig runs, so it cannot rely on the normalized config being in place yet).
|
|
137
|
+
*
|
|
138
|
+
* @param {boolean|string|Object} [hook] - Raw hook config in any supported form.
|
|
139
|
+
* @returns {{enabled: boolean, pattern: (string|null), suppressErrors: boolean, pin: boolean}} Normalized hook config.
|
|
140
|
+
* @public
|
|
141
|
+
*/
|
|
142
|
+
public normalizeHook(hook?: boolean | string | Object): {
|
|
30
143
|
enabled: boolean;
|
|
31
|
-
pattern: string;
|
|
144
|
+
pattern: (string | null);
|
|
32
145
|
suppressErrors: boolean;
|
|
33
146
|
pin: boolean;
|
|
34
147
|
};
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
backgroundMaterialize: boolean;
|
|
96
|
-
silent: boolean;
|
|
97
|
-
typescript: {
|
|
98
|
-
enabled: boolean;
|
|
99
|
-
mode: string;
|
|
100
|
-
types?: undefined;
|
|
101
|
-
target?: undefined;
|
|
102
|
-
sourcemap?: undefined;
|
|
103
|
-
} | {
|
|
104
|
-
enabled: boolean;
|
|
105
|
-
mode: string;
|
|
106
|
-
types: any;
|
|
107
|
-
target: any;
|
|
108
|
-
sourcemap: any;
|
|
109
|
-
} | null;
|
|
110
|
-
env: {
|
|
111
|
-
include: any;
|
|
112
|
-
} | null;
|
|
113
|
-
versionDispatcher: any;
|
|
114
|
-
import: any;
|
|
115
|
-
permissions: {
|
|
116
|
-
defaultPolicy: string;
|
|
117
|
-
enabled: boolean;
|
|
118
|
-
audit: string;
|
|
119
|
-
readGating: boolean;
|
|
120
|
-
failOpenOnAbsentCaller: boolean;
|
|
121
|
-
references: {
|
|
122
|
-
capture: boolean;
|
|
123
|
-
};
|
|
124
|
-
private: {
|
|
125
|
-
host: string;
|
|
126
|
-
};
|
|
127
|
-
rules: any;
|
|
128
|
-
} | null;
|
|
129
|
-
suppressFixes: Set<any>;
|
|
130
|
-
};
|
|
131
|
-
normalizeSuppressFixes(suppressFixes: any, silent: any): Set<any>;
|
|
132
|
-
normalizeTypeScript(typescript: any): {
|
|
133
|
-
enabled: boolean;
|
|
134
|
-
mode: string;
|
|
135
|
-
types?: undefined;
|
|
136
|
-
target?: undefined;
|
|
137
|
-
sourcemap?: undefined;
|
|
138
|
-
} | {
|
|
139
|
-
enabled: boolean;
|
|
140
|
-
mode: string;
|
|
141
|
-
types: any;
|
|
142
|
-
target: any;
|
|
143
|
-
sourcemap: any;
|
|
144
|
-
} | null;
|
|
145
|
-
normalizeEnv(env: any): {
|
|
146
|
-
include: any;
|
|
147
|
-
} | null;
|
|
148
|
-
normalizeLifecycle(lifecycle: any): any;
|
|
149
|
-
normalizePermissions(permissions: any): {
|
|
150
|
-
defaultPolicy: string;
|
|
151
|
-
enabled: boolean;
|
|
152
|
-
audit: string;
|
|
153
|
-
readGating: boolean;
|
|
154
|
-
failOpenOnAbsentCaller: boolean;
|
|
155
|
-
references: {
|
|
156
|
-
capture: boolean;
|
|
157
|
-
};
|
|
158
|
-
private: {
|
|
159
|
-
host: string;
|
|
160
|
-
};
|
|
161
|
-
rules: any;
|
|
148
|
+
/**
|
|
149
|
+
* Transform and validate configuration
|
|
150
|
+
* @param {Object} config - Raw configuration options
|
|
151
|
+
* @returns {Object} Normalized configuration
|
|
152
|
+
* @throws {SlothletError} If configuration is invalid
|
|
153
|
+
* @public
|
|
154
|
+
*/
|
|
155
|
+
public transformConfig(config?: Object): Object;
|
|
156
|
+
/**
|
|
157
|
+
* Normalize and validate the suppressFixes option. Emits a deprecation warning for each
|
|
158
|
+
* rule ID present. Invalid entries (non-strings, unknown rule IDs) are silently dropped.
|
|
159
|
+
*
|
|
160
|
+
* @param {string[]|undefined} suppressFixes - Raw suppressFixes value from user config.
|
|
161
|
+
* @param {boolean} silent - If true, suppress warnings.
|
|
162
|
+
* @returns {Set<string>} Normalized set of suppressed rule IDs.
|
|
163
|
+
* @example
|
|
164
|
+
* // Rule IDs use the <rule>_<PR> form. The C03 fix landed in PR #116.
|
|
165
|
+
* normalizeSuppressFixes(["C03_116"], false); // emits WARN_SUPPRESS_FIX_ACTIVE for C03_116
|
|
166
|
+
* @public
|
|
167
|
+
*/
|
|
168
|
+
public normalizeSuppressFixes(suppressFixes: string[] | undefined, silent: boolean): Set<string>;
|
|
169
|
+
/**
|
|
170
|
+
* Normalize TypeScript configuration
|
|
171
|
+
* @param {boolean|string|Object} typescript - TypeScript config (true, "fast", or { mode: "fast"|"strict", ... })
|
|
172
|
+
* @returns {Object|null} Normalized TypeScript configuration or null if disabled
|
|
173
|
+
* @public
|
|
174
|
+
*/
|
|
175
|
+
public normalizeTypeScript(typescript: boolean | string | Object): Object | null;
|
|
176
|
+
/**
|
|
177
|
+
* Normalize env snapshot configuration.
|
|
178
|
+
*
|
|
179
|
+
* @description
|
|
180
|
+
* Validates the `env` option from user config. When `include` is a non-empty
|
|
181
|
+
* string array, returns `{ include }` (the allowlist used by `_captureEnvSnapshot`).
|
|
182
|
+
* Any other value — including `undefined`, `null`, `{}`, or an empty `include`
|
|
183
|
+
* array — is normalised to `null`, meaning the full `process.env` snapshot is used.
|
|
184
|
+
*
|
|
185
|
+
* @param {Object|null|undefined} env - Raw env option from user config.
|
|
186
|
+
* @param {string[]} [env.include] - Allowlist of env variable names to capture.
|
|
187
|
+
* @returns {{ include: string[] }|null} Normalized env config, or `null` for full snapshot.
|
|
188
|
+
* @public
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* // No restriction — full snapshot
|
|
192
|
+
* normalizeEnv(undefined); // => null
|
|
193
|
+
* normalizeEnv(null); // => null
|
|
194
|
+
* normalizeEnv({}); // => null
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* // Include allowlist
|
|
198
|
+
* normalizeEnv({ include: ["NODE_ENV", "PORT"] });
|
|
199
|
+
* // => { include: ["NODE_ENV", "PORT"] }
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* // Non-string keys in the include array are filtered out
|
|
203
|
+
* normalizeEnv({ include: ["NODE_ENV", 42, null] });
|
|
204
|
+
* // => { include: ["NODE_ENV"] }
|
|
205
|
+
*/
|
|
206
|
+
public normalizeEnv(env: Object | null | undefined): {
|
|
207
|
+
include: string[];
|
|
162
208
|
} | null;
|
|
209
|
+
/**
|
|
210
|
+
* Normalize + validate the construction-time `lifecycle` subscription map (#148).
|
|
211
|
+
*
|
|
212
|
+
* @description
|
|
213
|
+
* The `lifecycle` option registers event handlers on the Lifecycle emitter BEFORE the api builds,
|
|
214
|
+
* so events emitted during cold-start `buildAPI` (init-time `impl:warning` / `impl:created` / …)
|
|
215
|
+
* are observable. It is a plain object mapping an event name to a handler function or an array of
|
|
216
|
+
* handler functions. Any event name is accepted — registration is just early `subscribe()` calls,
|
|
217
|
+
* so these handlers also receive runtime events afterward.
|
|
218
|
+
*
|
|
219
|
+
* Idempotent: an already-normalized map (values already functions / arrays of functions) passes
|
|
220
|
+
* through unchanged, so `reload()` can re-feed it.
|
|
221
|
+
*
|
|
222
|
+
* @param {object|null|undefined} lifecycle - Raw `lifecycle` option from user config.
|
|
223
|
+
* @returns {object|null} The validated map, or `null` when absent.
|
|
224
|
+
* @throws {SlothletError} INVALID_CONFIG when the shape is not a plain object of functions / function arrays.
|
|
225
|
+
* @public
|
|
226
|
+
*
|
|
227
|
+
* @example
|
|
228
|
+
* normalizeLifecycle({ "impl:warning": (data) => log(data) });
|
|
229
|
+
* // => { "impl:warning": (data) => log(data) }
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* normalizeLifecycle({ "impl:error": [onError, auditError] });
|
|
233
|
+
* // => { "impl:error": [onError, auditError] }
|
|
234
|
+
*/
|
|
235
|
+
public normalizeLifecycle(lifecycle: object | null | undefined): object | null;
|
|
236
|
+
/**
|
|
237
|
+
* Normalize + validate the `routines` config option (#341).
|
|
238
|
+
*
|
|
239
|
+
* @description
|
|
240
|
+
* A routine is a named cross-module runnable: every mounted module that exports a function
|
|
241
|
+
* matching a configured routine name gets stacked into one chain at its resolved api path, and
|
|
242
|
+
* a root cascade runs every matching contribution anywhere, ordered per the entry's `order`.
|
|
243
|
+
* See `docs/LIFECYCLE.md` ("Routines") for the full contract.
|
|
244
|
+
*
|
|
245
|
+
* Each entry normalizes to `{ name, mode, recursive, order }` — `recursive` and `order` are
|
|
246
|
+
* always present on the normalized output, even when the raw entry omitted them:
|
|
247
|
+
* - `"name"` (string, no `:`) → `{ name, mode: "manual", recursive: false, order: "mount" }`.
|
|
248
|
+
* - `"name:mode"` (string, split once on the first `:`) → `{ name, mode, recursive: false, order: <mode-defaulted> }`.
|
|
249
|
+
* - `{ name, mode?, recursive?, order? }` (object) → `mode` defaults to `"manual"`, `recursive` to
|
|
250
|
+
* `false`, and `order` to {@link DEFAULT_ROUTINE_ORDER_BY_MODE}`[mode]` when each is omitted.
|
|
251
|
+
*
|
|
252
|
+
* Providing `routines` at all REPLACES {@link DEFAULT_ROUTINES} — that is the off-switch
|
|
253
|
+
* (`routines: []` disables every routine). Omitting the option keeps the built-in defaults.
|
|
254
|
+
* `slothlet.defaults.routines` is the frozen source of those defaults, exported for a consumer
|
|
255
|
+
* to spread (extend) or filter (drop one) rather than replace wholesale.
|
|
256
|
+
*
|
|
257
|
+
* Idempotent: an already-normalized list (every entry already `{ name, mode, recursive, order }`)
|
|
258
|
+
* normalizes to an equivalent list — same values, always freshly-built objects (never the same
|
|
259
|
+
* references) — so `reload()` can safely re-feed it.
|
|
260
|
+
*
|
|
261
|
+
* @param {undefined|null|Array<string|{name: string, mode?: string, recursive?: boolean, order?: string}>} routines - Raw `routines` option.
|
|
262
|
+
* @returns {Array<{name: string, mode: "manual"|"startup"|"shutdown"|"destroy", recursive: boolean, order: "mount"|"depth"}>} Normalized routines list.
|
|
263
|
+
* @throws {SlothletError} INVALID_CONFIG when the shape is invalid, a name is empty/reserved/an invalid glob, or a mode/order is unrecognized.
|
|
264
|
+
* @public
|
|
265
|
+
*
|
|
266
|
+
* @example
|
|
267
|
+
* normalizeRoutines(undefined);
|
|
268
|
+
* // => [{ name: "initialize", mode: "startup", recursive: false, order: "mount" },
|
|
269
|
+
* // { name: "shutdown", mode: "shutdown", recursive: false, order: "depth" }]
|
|
270
|
+
*
|
|
271
|
+
* @example
|
|
272
|
+
* normalizeRoutines(["launch", "prefetch:startup", { name: "warmup" }]);
|
|
273
|
+
* // => [{ name: "launch", mode: "manual", recursive: false, order: "mount" },
|
|
274
|
+
* // { name: "prefetch", mode: "startup", recursive: false, order: "mount" },
|
|
275
|
+
* // { name: "warmup", mode: "manual", recursive: false, order: "mount" }]
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* normalizeRoutines([]);
|
|
279
|
+
* // => [] — disables every routine
|
|
280
|
+
*/
|
|
281
|
+
public normalizeRoutines(routines: undefined | null | Array<string | {
|
|
282
|
+
name: string;
|
|
283
|
+
mode?: string;
|
|
284
|
+
recursive?: boolean;
|
|
285
|
+
order?: string;
|
|
286
|
+
}>): Array<{
|
|
287
|
+
name: string;
|
|
288
|
+
mode: "manual" | "startup" | "shutdown" | "destroy";
|
|
289
|
+
recursive: boolean;
|
|
290
|
+
order: "mount" | "depth";
|
|
291
|
+
}>;
|
|
292
|
+
/**
|
|
293
|
+
* Normalize permissions configuration.
|
|
294
|
+
*
|
|
295
|
+
* @param {object|null} [permissions] - Raw permissions config from user.
|
|
296
|
+
* @param {string} [permissions.defaultPolicy="allow"] - Fallback policy: "allow" or "deny".
|
|
297
|
+
* @param {boolean} [permissions.enabled=true] - Global toggle.
|
|
298
|
+
* @param {string|boolean} [permissions.audit="default"] - Audit level: `"default"` (denied + self-bypass only),
|
|
299
|
+
* `"verbose"` (all decisions). `true` and `false` are accepted and both normalize to `"default"`.
|
|
300
|
+
* @param {object} [permissions.references] - Options governing api functions held as references.
|
|
301
|
+
* @param {boolean} [permissions.references.capture=true] - When `true` (the default), a function read
|
|
302
|
+
* out of the api carries the identity of the module that read it, so it stays enforced as that module
|
|
303
|
+
* wherever it is later invoked. Set `false` to restore the older host-initiated treatment.
|
|
304
|
+
* @param {boolean} [permissions.failOpenOnAbsentCaller=false] - When `false` (the default), calls
|
|
305
|
+
* and reads occurring inside an active context with no resolvable (or forged) caller identity
|
|
306
|
+
* fail closed (denied); only genuinely host-initiated calls are exempt via the trusted-root
|
|
307
|
+
* marker. Set `true` to restore the legacy fail-open behaviour.
|
|
308
|
+
* @param {boolean} [permissions.readGating=true] - When `true` (the default), reading a terminal
|
|
309
|
+
* data value (primitive, Buffer, TypedArray, Date, Map, etc.) off a module API path is
|
|
310
|
+
* permission-checked, the same way calls are. Set `false` to opt out and gate calls only.
|
|
311
|
+
* @param {Array<object>} [permissions.rules=[]] - Initial permission rules.
|
|
312
|
+
* @returns {object|null} Normalized permissions config, or null when permissions is absent or not an object.
|
|
313
|
+
*
|
|
314
|
+
* @example
|
|
315
|
+
* normalizePermissions({ defaultPolicy: "deny", rules: [{ caller: "**", target: "admin.**", effect: "deny" }] });
|
|
316
|
+
* // => { defaultPolicy: "deny", enabled: true, audit: "default", readGating: true, rules: [...] }
|
|
317
|
+
*/
|
|
318
|
+
normalizePermissions(permissions?: object | null): object | null;
|
|
163
319
|
}
|
|
164
|
-
export function normalizeHookConfig(hook: any): {
|
|
165
|
-
enabled: boolean;
|
|
166
|
-
pattern: string;
|
|
167
|
-
suppressErrors: boolean;
|
|
168
|
-
pin: boolean;
|
|
169
|
-
};
|
|
170
320
|
import { ComponentBase } from "#factories/component-base";
|
|
@@ -1 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The default `apiDepth` (directory-traversal depth) applied when a caller does not specify one.
|
|
3
|
+
* Unbounded by default. The config normalizer ({@link module:@cldmv/slothlet/helpers/config}) is
|
|
4
|
+
* what every real compose path reads — it resolves `config.apiDepth` once and the mode processors
|
|
5
|
+
* receive that already-normalized value. The mode processors' and the loader's own parameter
|
|
6
|
+
* defaults exist only for the case where they are invoked directly, bypassing normalization (a
|
|
7
|
+
* standalone call, a future direct consumer); they read this same constant so that case can never
|
|
8
|
+
* silently disagree with the normalized default.
|
|
9
|
+
* @type {number}
|
|
10
|
+
*/
|
|
1
11
|
export const DEFAULT_API_DEPTH: number;
|
|
12
|
+
/**
|
|
13
|
+
* The built-in `routines` list applied when a caller omits the `routines` config option entirely.
|
|
14
|
+
* Each entry is `{ name, mode }` (bare mount-relative names, non-recursive, mode-defaulted `order`)
|
|
15
|
+
* — see `docs/LIFECYCLE.md` ("Routines") for the full contract, including the `recursive`/`order`/
|
|
16
|
+
* `destroy`-mode fields a caller-supplied entry may also set. Passing `routines` at all REPLACES
|
|
17
|
+
* this list (it is the off-switch); a consumer that wants to extend rather than replace it spreads
|
|
18
|
+
* this array: `slothlet.defaults.routines`.
|
|
19
|
+
*
|
|
20
|
+
* Frozen at every level (the array, and each entry object) so a consumer's spread copies the
|
|
21
|
+
* entries by reference safely without risking a mutation here leaking across consumers.
|
|
22
|
+
* @type {ReadonlyArray<{name: string, mode: "manual"|"startup"|"shutdown"|"destroy"}>}
|
|
23
|
+
*/
|
|
24
|
+
export const DEFAULT_ROUTINES: ReadonlyArray<{
|
|
25
|
+
name: string;
|
|
26
|
+
mode: "manual" | "startup" | "shutdown" | "destroy";
|
|
27
|
+
}>;
|
|
28
|
+
/**
|
|
29
|
+
* The complete set of framework-reserved export names — names a module export can never
|
|
30
|
+
* meaningfully claim because the framework's own wrapper machinery already owns them.
|
|
31
|
+
*
|
|
32
|
+
* Derived as the union of {@link ComponentBase.INTERNAL_KEYS} (wrapper state/control properties)
|
|
33
|
+
* and `IMPL_METADATA_KEYS` (child-adoption metadata) — the same two Sets `isFrameworkReservedKey()`
|
|
34
|
+
* (`#handlers/unified-wrapper`) checks against, combined here into one Set for convenient
|
|
35
|
+
* introspection. Wrapped via {@link freezeSet} — `Object.freeze()` alone would leave `add`/
|
|
36
|
+
* `delete`/`clear` callable, letting a consumer mutate this shared singleton (and corrupt what
|
|
37
|
+
* every other consumer in the same process sees) despite it claiming to be frozen.
|
|
38
|
+
* @type {ReadonlySet<string>}
|
|
39
|
+
*/
|
|
40
|
+
export const RESERVED_EXPORTS: ReadonlySet<string>;
|
|
@@ -1,4 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Set the context checker callback
|
|
3
|
+
* Called by the runtime to register a way to detect API context
|
|
4
|
+
* @param {Function} checker - Function that returns true if in API context
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export function setApiContextChecker(checker: Function): void;
|
|
8
|
+
/**
|
|
9
|
+
* Enable EventEmitter context propagation by patching EventEmitter.prototype.
|
|
10
|
+
* This should be called ONCE globally when the first slothlet instance is created.
|
|
11
|
+
* Subsequent calls will be ignored (patching is global).
|
|
12
|
+
*
|
|
13
|
+
* @public
|
|
14
|
+
*/
|
|
3
15
|
export function enableEventEmitterPatching(): void;
|
|
4
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Disable EventEmitter context propagation and restore original methods.
|
|
18
|
+
* This should only be called when ALL slothlet instances have been shut down.
|
|
19
|
+
*
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
export function disableEventEmitterPatching(): void;
|
|
23
|
+
/**
|
|
24
|
+
* Cleanup all tracked EventEmitters created within slothlet API context.
|
|
25
|
+
* This removes all listeners from tracked emitters and clears tracking structures.
|
|
26
|
+
* Should be called during shutdown to prevent memory leaks and hanging processes.
|
|
27
|
+
*
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
export function cleanupEventEmitterResources(): void;
|
|
@@ -1,2 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Enable context propagation through `EventTarget` listeners.
|
|
3
|
+
*
|
|
4
|
+
* Called once globally when the first instance is created; later calls are ignored, matching how
|
|
5
|
+
* EventEmitter patching behaves.
|
|
6
|
+
*
|
|
7
|
+
* @returns {void}
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
2
10
|
export function enableEventTargetPatching(): void;
|
|
11
|
+
/**
|
|
12
|
+
* Restore the original `EventTarget` methods.
|
|
13
|
+
*
|
|
14
|
+
* Restores a method only when the patch installed here is still in place, so anything that replaced
|
|
15
|
+
* it afterwards keeps ownership of its own restore.
|
|
16
|
+
*
|
|
17
|
+
* @returns {void}
|
|
18
|
+
* @public
|
|
19
|
+
*/
|
|
20
|
+
export function disableEventTargetPatching(): void;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pin `on*` handler assignments to the module that makes them.
|
|
3
|
+
*
|
|
4
|
+
* Called once globally when the first instance is created; later calls are ignored, matching how the
|
|
5
|
+
* other boundary patches behave. Costs nothing when no runtime registered a pinning strategy — the
|
|
6
|
+
* wrapper hands the callback straight through.
|
|
7
|
+
*
|
|
8
|
+
* @returns {void}
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
export function enableEventTargetPropertyPatching(): void;
|
|
12
|
+
/**
|
|
13
|
+
* Restore the original `on*` handler accessors.
|
|
14
|
+
*
|
|
15
|
+
* Restores an accessor only when the patch installed here is still in place, so anything that replaced
|
|
16
|
+
* it afterwards keeps ownership of its own restore.
|
|
17
|
+
*
|
|
18
|
+
* @returns {void}
|
|
19
|
+
* @public
|
|
20
|
+
*/
|
|
21
|
+
export function disableEventTargetPropertyPatching(): void;
|