@cldmv/slothlet 2.8.0 → 2.10.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.
- package/AGENT-USAGE.md +1 -1
- package/README.md +300 -1557
- package/dist/lib/engine/slothlet_child.mjs +1 -1
- package/dist/lib/engine/slothlet_engine.mjs +1 -1
- package/dist/lib/engine/slothlet_esm.mjs +1 -1
- package/dist/lib/engine/slothlet_helpers.mjs +1 -1
- package/dist/lib/engine/slothlet_worker.mjs +1 -1
- package/dist/lib/helpers/als-eventemitter.mjs +5 -6
- package/dist/lib/helpers/api_builder/add_api.mjs +292 -0
- package/dist/lib/helpers/api_builder/analysis.mjs +532 -0
- package/dist/lib/helpers/api_builder/construction.mjs +457 -0
- package/dist/lib/helpers/api_builder/decisions.mjs +737 -0
- package/dist/lib/helpers/api_builder/metadata.mjs +248 -0
- package/dist/lib/helpers/api_builder.mjs +17 -1568
- package/dist/lib/helpers/auto-wrap.mjs +1 -1
- package/dist/lib/helpers/hooks.mjs +1 -1
- package/dist/lib/helpers/instance-manager.mjs +1 -1
- package/dist/lib/helpers/metadata-api.mjs +201 -0
- package/dist/lib/helpers/multidefault.mjs +12 -3
- package/dist/lib/helpers/resolve-from-caller.mjs +1 -1
- package/dist/lib/helpers/sanitize.mjs +1 -1
- package/dist/lib/helpers/utilities.mjs +121 -0
- package/dist/lib/modes/slothlet_eager.mjs +1 -1
- package/dist/lib/modes/slothlet_lazy.mjs +10 -1
- package/dist/lib/runtime/runtime-asynclocalstorage.mjs +49 -18
- package/dist/lib/runtime/runtime-livebindings.mjs +23 -4
- package/dist/lib/runtime/runtime.mjs +15 -4
- package/dist/slothlet.mjs +164 -748
- package/docs/API-RULES-CONDITIONS.md +508 -0
- package/{API-RULES.md → docs/API-RULES.md} +127 -72
- package/package.json +11 -9
- package/types/dist/lib/helpers/als-eventemitter.d.mts.map +1 -1
- package/types/dist/lib/helpers/api_builder/add_api.d.mts +76 -0
- package/types/dist/lib/helpers/api_builder/add_api.d.mts.map +1 -0
- package/types/dist/lib/helpers/api_builder/analysis.d.mts +189 -0
- package/types/dist/lib/helpers/api_builder/analysis.d.mts.map +1 -0
- package/types/dist/lib/helpers/api_builder/construction.d.mts +107 -0
- package/types/dist/lib/helpers/api_builder/construction.d.mts.map +1 -0
- package/types/dist/lib/helpers/api_builder/decisions.d.mts +213 -0
- package/types/dist/lib/helpers/api_builder/decisions.d.mts.map +1 -0
- package/types/dist/lib/helpers/api_builder/metadata.d.mts +99 -0
- package/types/dist/lib/helpers/api_builder/metadata.d.mts.map +1 -0
- package/types/dist/lib/helpers/api_builder.d.mts +5 -448
- package/types/dist/lib/helpers/api_builder.d.mts.map +1 -1
- package/types/dist/lib/helpers/metadata-api.d.mts +132 -0
- package/types/dist/lib/helpers/metadata-api.d.mts.map +1 -0
- package/types/dist/lib/helpers/multidefault.d.mts.map +1 -1
- package/types/dist/lib/helpers/utilities.d.mts +120 -0
- package/types/dist/lib/helpers/utilities.d.mts.map +1 -0
- package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts +9 -0
- package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts.map +1 -1
- package/types/dist/lib/runtime/runtime-livebindings.d.mts +10 -0
- package/types/dist/lib/runtime/runtime-livebindings.d.mts.map +1 -1
- package/types/dist/lib/runtime/runtime.d.mts +1 -0
- package/types/dist/lib/runtime/runtime.d.mts.map +1 -1
- package/types/dist/slothlet.d.mts +0 -11
- package/types/dist/slothlet.d.mts.map +1 -1
- package/types/index.d.mts +0 -1
- package/API-RULES-CONDITIONS.md +0 -367
|
@@ -1,449 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* @internal
|
|
7
|
-
* @package
|
|
8
|
-
* @param {string} modulePath - Absolute path to the module file
|
|
9
|
-
* @param {object} options - Analysis options
|
|
10
|
-
* @param {boolean} [options.debug=false] - Enable debug logging
|
|
11
|
-
* @param {object} [options.instance] - Slothlet instance for accessing config and methods
|
|
12
|
-
* @returns {Promise<{
|
|
13
|
-
* rawModule: object,
|
|
14
|
-
* processedModule: object,
|
|
15
|
-
* isFunction: boolean,
|
|
16
|
-
* hasDefault: boolean,
|
|
17
|
-
* isCjs: boolean,
|
|
18
|
-
* exports: Array<[string, any]>,
|
|
19
|
-
* defaultExportType: 'function'|'object'|null,
|
|
20
|
-
* shouldWrapAsCallable: boolean,
|
|
21
|
-
* namedExports: object,
|
|
22
|
-
* metadata: object
|
|
23
|
-
* }>} Module analysis results
|
|
24
|
-
* @example
|
|
25
|
-
* // Analyze a module file
|
|
26
|
-
* const analysis = await analyzeModule("./api/math.mjs", { instance });
|
|
27
|
-
* // Eager mode: use analysis.processedModule directly
|
|
28
|
-
* // Lazy mode: create proxy based on analysis.isFunction, analysis.exports, etc.
|
|
29
|
-
*/
|
|
30
|
-
export function analyzeModule(modulePath: string, options?: {
|
|
31
|
-
debug?: boolean;
|
|
32
|
-
instance?: object;
|
|
33
|
-
}): Promise<{
|
|
34
|
-
rawModule: object;
|
|
35
|
-
processedModule: object;
|
|
36
|
-
isFunction: boolean;
|
|
37
|
-
hasDefault: boolean;
|
|
38
|
-
isCjs: boolean;
|
|
39
|
-
exports: Array<[string, any]>;
|
|
40
|
-
defaultExportType: "function" | "object" | null;
|
|
41
|
-
shouldWrapAsCallable: boolean;
|
|
42
|
-
namedExports: object;
|
|
43
|
-
metadata: object;
|
|
44
|
-
}>;
|
|
45
|
-
/**
|
|
46
|
-
* Processes module analysis results into a final module object using slothlet's established patterns.
|
|
47
|
-
* This centralizes the processing logic while allowing both modes to apply the results differently.
|
|
48
|
-
* @function processModuleFromAnalysis
|
|
49
|
-
* @internal
|
|
50
|
-
* @package
|
|
51
|
-
* @param {object} analysis - Results from analyzeModule
|
|
52
|
-
* @param {object} options - Processing options
|
|
53
|
-
* @param {object} [options.instance] - Slothlet instance for accessing _toapiPathKey method
|
|
54
|
-
* @param {boolean} [options.debug=false] - Enable debug logging
|
|
55
|
-
* @returns {object} Processed module ready for API integration
|
|
56
|
-
* @example
|
|
57
|
-
* // Process analyzed module
|
|
58
|
-
* const analysis = await analyzeModule(modulePath, { instance });
|
|
59
|
-
* const processed = processModuleFromAnalysis(analysis, { instance });
|
|
60
|
-
* // Both modes can use 'processed' but integrate it differently
|
|
61
|
-
*/
|
|
62
|
-
export function processModuleFromAnalysis(analysis: object, options?: {
|
|
63
|
-
instance?: object;
|
|
64
|
-
debug?: boolean;
|
|
65
|
-
}): object;
|
|
66
|
-
/**
|
|
67
|
-
* Analyzes a directory and returns structural decisions that both eager and lazy modes can use.
|
|
68
|
-
* This provides the decision-making logic for directory handling without implementing the actual
|
|
69
|
-
* loading strategy (allowing lazy mode to create proxies while eager mode materializes).
|
|
70
|
-
* @function analyzeDirectoryStructure
|
|
71
|
-
* @internal
|
|
72
|
-
* @package
|
|
73
|
-
* @param {string} categoryPath - Absolute path to the directory
|
|
74
|
-
* @param {object} options - Analysis options
|
|
75
|
-
* @param {object} options.instance - Slothlet instance for accessing config and methods
|
|
76
|
-
* @param {number} [options.currentDepth=0] - Current traversal depth
|
|
77
|
-
* @param {number} [options.maxDepth=Infinity] - Maximum traversal depth
|
|
78
|
-
* @param {boolean} [options.debug=false] - Enable debug logging
|
|
79
|
-
* @returns {Promise<{
|
|
80
|
-
* isSingleFile: boolean,
|
|
81
|
-
* shouldAutoFlatten: boolean,
|
|
82
|
-
* categoryName: string,
|
|
83
|
-
* moduleFiles: Array<import('fs').Dirent>,
|
|
84
|
-
* subDirs: Array<import('fs').Dirent>,
|
|
85
|
-
* multiDefaultAnalysis: object,
|
|
86
|
-
* processingStrategy: 'single-file'|'multi-file'|'empty',
|
|
87
|
-
* flatteningHints: object
|
|
88
|
-
* }>} Directory structure analysis
|
|
89
|
-
* @example
|
|
90
|
-
* // Analyze directory structure
|
|
91
|
-
* const analysis = await analyzeDirectoryStructure(categoryPath, { instance });
|
|
92
|
-
* if (analysis.isSingleFile) {
|
|
93
|
-
* // Both modes: handle as single file (but differently)
|
|
94
|
-
* } else {
|
|
95
|
-
* // Both modes: handle as multi-file (but differently)
|
|
96
|
-
* }
|
|
97
|
-
*/
|
|
98
|
-
export function analyzeDirectoryStructure(categoryPath: string, options?: {
|
|
99
|
-
instance: object;
|
|
100
|
-
currentDepth?: number;
|
|
101
|
-
maxDepth?: number;
|
|
102
|
-
debug?: boolean;
|
|
103
|
-
}): Promise<{
|
|
104
|
-
isSingleFile: boolean;
|
|
105
|
-
shouldAutoFlatten: boolean;
|
|
106
|
-
categoryName: string;
|
|
107
|
-
moduleFiles: Array<import("fs").Dirent>;
|
|
108
|
-
subDirs: Array<import("fs").Dirent>;
|
|
109
|
-
multiDefaultAnalysis: object;
|
|
110
|
-
processingStrategy: "single-file" | "multi-file" | "empty";
|
|
111
|
-
flatteningHints: object;
|
|
112
|
-
}>;
|
|
113
|
-
/**
|
|
114
|
-
* Returns category building decisions and processed modules that both eager and lazy modes can use.
|
|
115
|
-
* This provides all the structural information needed to build a category but lets each mode
|
|
116
|
-
* implement the actual building strategy (materialization vs proxy creation).
|
|
117
|
-
* @function getCategoryBuildingDecisions
|
|
118
|
-
* @internal
|
|
119
|
-
* @package
|
|
120
|
-
* @param {string} categoryPath - Absolute path to the directory
|
|
121
|
-
* @param {object} options - Building options
|
|
122
|
-
* @param {object} options.instance - Slothlet instance for accessing config and methods
|
|
123
|
-
* @param {number} [options.currentDepth=0] - Current traversal depth
|
|
124
|
-
* @param {number} [options.maxDepth=Infinity] - Maximum traversal depth
|
|
125
|
-
* @param {boolean} [options.debug=false] - Enable debug logging
|
|
126
|
-
* @returns {Promise<{
|
|
127
|
-
* processingStrategy: 'single-file'|'multi-file'|'empty',
|
|
128
|
-
* categoryName: string,
|
|
129
|
-
* shouldFlattenSingle: boolean,
|
|
130
|
-
* processedModules: Array<{file: import('fs').Dirent, moduleName: string, processedModule: any, flattening: object}>,
|
|
131
|
-
* subDirectories: Array<{dirEntry: import('fs').Dirent, apiPathKey: string}>,
|
|
132
|
-
* multiDefaultAnalysis: object,
|
|
133
|
-
* flatteningDecisions: object,
|
|
134
|
-
* upwardFlatteningCandidate: {shouldFlatten: boolean, apiPathKey: string}
|
|
135
|
-
* }>} Complete category building information
|
|
136
|
-
* @example
|
|
137
|
-
* // Get category building decisions
|
|
138
|
-
* const decisions = await getCategoryBuildingDecisions(categoryPath, { instance });
|
|
139
|
-
* if (decisions.processingStrategy === "single-file") {
|
|
140
|
-
* // Both modes: handle single file differently
|
|
141
|
-
* // Eager: return decisions.processedModules[0].processedModule
|
|
142
|
-
* // Lazy: create proxy based on decisions.processedModules[0].flattening
|
|
143
|
-
* }
|
|
144
|
-
*/
|
|
145
|
-
export function getCategoryBuildingDecisions(categoryPath: string, options?: {
|
|
146
|
-
instance: object;
|
|
147
|
-
currentDepth?: number;
|
|
148
|
-
maxDepth?: number;
|
|
149
|
-
debug?: boolean;
|
|
150
|
-
}): Promise<{
|
|
151
|
-
processingStrategy: "single-file" | "multi-file" | "empty";
|
|
152
|
-
categoryName: string;
|
|
153
|
-
shouldFlattenSingle: boolean;
|
|
154
|
-
processedModules: Array<{
|
|
155
|
-
file: import("fs").Dirent;
|
|
156
|
-
moduleName: string;
|
|
157
|
-
processedModule: any;
|
|
158
|
-
flattening: object;
|
|
159
|
-
}>;
|
|
160
|
-
subDirectories: Array<{
|
|
161
|
-
dirEntry: import("fs").Dirent;
|
|
162
|
-
apiPathKey: string;
|
|
163
|
-
}>;
|
|
164
|
-
multiDefaultAnalysis: object;
|
|
165
|
-
flatteningDecisions: object;
|
|
166
|
-
upwardFlatteningCandidate: {
|
|
167
|
-
shouldFlatten: boolean;
|
|
168
|
-
apiPathKey: string;
|
|
169
|
-
};
|
|
170
|
-
}>;
|
|
171
|
-
/**
|
|
172
|
-
* Auto-flattening decision logic that determines whether a module should be flattened
|
|
173
|
-
* based on filename matching, export patterns, and context.
|
|
174
|
-
* @function getFlatteningDecision
|
|
175
|
-
* @internal
|
|
176
|
-
* @package
|
|
177
|
-
* @param {object} options - Flattening analysis options
|
|
178
|
-
* @param {object} options.mod - The loaded module object
|
|
179
|
-
* @param {string} options.fileName - Original filename (without extension)
|
|
180
|
-
* @param {string} options.apiPathKey - Sanitized API key for the module
|
|
181
|
-
* @param {boolean} options.hasMultipleDefaultExports - Whether multiple default exports exist in the container
|
|
182
|
-
* @param {boolean} options.isSelfReferential - Whether this is a self-referential export
|
|
183
|
-
* @param {boolean} [options.moduleHasDefault] - Whether this specific module has a default export.
|
|
184
|
-
* Should use originalAnalysis.hasDefault when available for accuracy, as !!mod.default
|
|
185
|
-
* may be inaccurate after processModuleFromAnalysis modifies module structure.
|
|
186
|
-
* @param {string} [options.categoryName] - Container/category name for context
|
|
187
|
-
* @param {number} [options.totalModules=1] - Total number of modules in container
|
|
188
|
-
* @param {boolean} [options.debug=false] - Enable debug logging
|
|
189
|
-
* @returns {{
|
|
190
|
-
* shouldFlatten: boolean,
|
|
191
|
-
* flattenToRoot: boolean,
|
|
192
|
-
* flattenToCategory: boolean,
|
|
193
|
-
* preserveAsNamespace: boolean,
|
|
194
|
-
* useAutoFlattening: boolean,
|
|
195
|
-
* reason: string
|
|
196
|
-
* }} Flattening decision result
|
|
197
|
-
*
|
|
198
|
-
* @description
|
|
199
|
-
* Determines flattening behavior based on slothlet's established rules:
|
|
200
|
-
*
|
|
201
|
-
* 1. Self-referential exports: Never flatten (preserve as namespace)
|
|
202
|
-
* 2. Multi-default context: Flatten modules WITHOUT defaults, preserve WITH defaults
|
|
203
|
-
* 3. Single named export matching filename: Auto-flatten to use export directly
|
|
204
|
-
* 4. Filename matches container: Flatten contents to container level
|
|
205
|
-
* 5. Traditional context: Preserve as namespace unless auto-flattening applies
|
|
206
|
-
*
|
|
207
|
-
* @example
|
|
208
|
-
* // Internal usage - single named export matching filename
|
|
209
|
-
* const decision = getFlatteningDecision({
|
|
210
|
-
* mod: { math: { add: fn, multiply: fn } },
|
|
211
|
-
* fileName: "math", apiPathKey: "math",
|
|
212
|
-
* hasMultipleDefaultExports: false, isSelfReferential: false
|
|
213
|
-
* });
|
|
214
|
-
* // Returns: { shouldFlatten: true, useAutoFlattening: true, reason: "auto-flatten single named export" }
|
|
215
|
-
*/
|
|
216
|
-
export function getFlatteningDecision(options: {
|
|
217
|
-
mod: object;
|
|
218
|
-
fileName: string;
|
|
219
|
-
apiPathKey: string;
|
|
220
|
-
hasMultipleDefaultExports: boolean;
|
|
221
|
-
isSelfReferential: boolean;
|
|
222
|
-
moduleHasDefault?: boolean;
|
|
223
|
-
categoryName?: string;
|
|
224
|
-
totalModules?: number;
|
|
225
|
-
debug?: boolean;
|
|
226
|
-
}): {
|
|
227
|
-
shouldFlatten: boolean;
|
|
228
|
-
flattenToRoot: boolean;
|
|
229
|
-
flattenToCategory: boolean;
|
|
230
|
-
preserveAsNamespace: boolean;
|
|
231
|
-
useAutoFlattening: boolean;
|
|
232
|
-
reason: string;
|
|
233
|
-
};
|
|
234
|
-
/**
|
|
235
|
-
* Processes a single module and applies it to the target API object based on flattening decisions.
|
|
236
|
-
* @function processModuleForAPI
|
|
237
|
-
* @internal
|
|
238
|
-
* @package
|
|
239
|
-
* @param {object} options - Module processing options
|
|
240
|
-
* @param {object} options.mod - The loaded module object
|
|
241
|
-
* @param {string} options.fileName - Original filename (without extension)
|
|
242
|
-
* @param {string} options.apiPathKey - Sanitized API key for the module
|
|
243
|
-
* @param {boolean} options.hasMultipleDefaultExports - Whether multiple default exports exist
|
|
244
|
-
* @param {boolean} options.isSelfReferential - Whether this is a self-referential export
|
|
245
|
-
* @param {object} options.api - Target API object to modify (could be root api or categoryModules)
|
|
246
|
-
* @param {function} [options.getRootDefault] - Function to get current root default function
|
|
247
|
-
* @param {function} [options.setRootDefault] - Function to set the root default function
|
|
248
|
-
* @param {object} [options.context] - Processing context
|
|
249
|
-
* @param {boolean} [options.context.debug=false] - Enable debug logging
|
|
250
|
-
* @param {string} [options.context.mode="unknown"] - Processing mode (root, subfolder, eager, lazy)
|
|
251
|
-
* @param {string} [options.context.categoryName] - Container/category name
|
|
252
|
-
* @param {number} [options.context.totalModules=1] - Total modules in container
|
|
253
|
-
* @returns {{
|
|
254
|
-
* processed: boolean,
|
|
255
|
-
* rootDefaultSet: boolean,
|
|
256
|
-
* flattened: boolean,
|
|
257
|
-
* namespaced: boolean,
|
|
258
|
-
* apiAssignments: Record<string, any>
|
|
259
|
-
* }} Processing result
|
|
260
|
-
*
|
|
261
|
-
* @description
|
|
262
|
-
* Unified module processing logic that handles:
|
|
263
|
-
* 1. Function default exports (multi-default, self-referential, traditional root contributor)
|
|
264
|
-
* 2. Object/named exports with flattening decisions
|
|
265
|
-
* 3. Export merging and namespace assignments
|
|
266
|
-
* 4. Function name preference logic
|
|
267
|
-
* 5. Root default function management
|
|
268
|
-
*
|
|
269
|
-
* @example
|
|
270
|
-
* // Internal usage for root-level processing
|
|
271
|
-
* const result = processModuleForAPI({
|
|
272
|
-
* mod, fileName, apiPathKey, hasMultipleDefaultExports, isSelfReferential, api,
|
|
273
|
-
* getRootDefault: () => rootDefaultFunction,
|
|
274
|
-
* setRootDefault: (fn) => { rootDefaultFunction = fn; },
|
|
275
|
-
* context: { debug: true, mode: "root", totalModules: 3 },
|
|
276
|
-
* originalAnalysis: { hasDefault: true, namedExportsCount: 2 }
|
|
277
|
-
* });
|
|
278
|
-
*/
|
|
279
|
-
export function processModuleForAPI(options: {
|
|
280
|
-
mod: object;
|
|
281
|
-
fileName: string;
|
|
282
|
-
apiPathKey: string;
|
|
283
|
-
hasMultipleDefaultExports: boolean;
|
|
284
|
-
isSelfReferential: boolean;
|
|
285
|
-
api: object;
|
|
286
|
-
getRootDefault?: Function;
|
|
287
|
-
setRootDefault?: Function;
|
|
288
|
-
context?: {
|
|
289
|
-
debug?: boolean;
|
|
290
|
-
mode?: string;
|
|
291
|
-
categoryName?: string;
|
|
292
|
-
totalModules?: number;
|
|
293
|
-
};
|
|
294
|
-
}): {
|
|
295
|
-
processed: boolean;
|
|
296
|
-
rootDefaultSet: boolean;
|
|
297
|
-
flattened: boolean;
|
|
298
|
-
namespaced: boolean;
|
|
299
|
-
apiAssignments: Record<string, any>;
|
|
300
|
-
};
|
|
301
|
-
/**
|
|
302
|
-
* Handles function name preference logic for better API naming.
|
|
303
|
-
* @function applyFunctionNamePreference
|
|
304
|
-
* @internal
|
|
305
|
-
* @package
|
|
306
|
-
* @param {object} options - Name preference options
|
|
307
|
-
* @param {object} options.mod - The loaded module object
|
|
308
|
-
* @param {string} options.fileName - Original filename (without extension)
|
|
309
|
-
* @param {string} options.apiPathKey - Sanitized API key
|
|
310
|
-
* @param {object} options.categoryModules - Target category modules object
|
|
311
|
-
* @param {function} options.toapiPathKey - Function to sanitize names to API keys
|
|
312
|
-
* @param {boolean} [options.debug=false] - Enable debug logging
|
|
313
|
-
* @returns {{hasPreferredName: boolean, preferredKey: string}} Name preference result
|
|
314
|
-
*
|
|
315
|
-
* @description
|
|
316
|
-
* Implements slothlet's function name preference logic where the original function name
|
|
317
|
-
* is preferred over the sanitized filename when they represent the same semantic meaning
|
|
318
|
-
* but have different capitalization (e.g., autoIP vs autoIp, parseJSON vs parseJson).
|
|
319
|
-
*
|
|
320
|
-
* @example
|
|
321
|
-
* // Internal usage in _buildCategory
|
|
322
|
-
* const preference = applyFunctionNamePreference({
|
|
323
|
-
* mod: { autoIP: function autoIP() {} },
|
|
324
|
-
* fileName: "auto-ip", apiPathKey: "autoIp",
|
|
325
|
-
* categoryModules, toapiPathKey: this._toapiPathKey, debug: true
|
|
326
|
-
* });
|
|
327
|
-
* // Returns: { hasPreferredName: true, preferredKey: "autoIP" }
|
|
328
|
-
*/
|
|
329
|
-
export function applyFunctionNamePreference(options: {
|
|
330
|
-
mod: object;
|
|
331
|
-
fileName: string;
|
|
332
|
-
apiPathKey: string;
|
|
333
|
-
categoryModules: object;
|
|
334
|
-
toapiPathKey: Function;
|
|
335
|
-
debug?: boolean;
|
|
336
|
-
}): {
|
|
337
|
-
hasPreferredName: boolean;
|
|
338
|
-
preferredKey: string;
|
|
339
|
-
};
|
|
340
|
-
/**
|
|
341
|
-
* Comprehensive category/directory building function that replaces _buildCategory.
|
|
342
|
-
* Handles complete directory structure processing with all flattening rules.
|
|
343
|
-
* @function buildCategoryStructure
|
|
344
|
-
* @internal
|
|
345
|
-
* @package
|
|
346
|
-
* @async
|
|
347
|
-
* @param {string} categoryPath - Absolute path to the category directory
|
|
348
|
-
* @param {object} options - Building options
|
|
349
|
-
* @param {number} [options.currentDepth=0] - Current recursion depth
|
|
350
|
-
* @param {number} [options.maxDepth=Infinity] - Maximum recursion depth
|
|
351
|
-
* @param {string} [options.mode="eager"] - Loading mode ("eager" or "lazy")
|
|
352
|
-
* @param {function} [options.subdirHandler] - Custom subdirectory handler for lazy mode
|
|
353
|
-
* @param {object} options.instance - Slothlet instance for access to helper methods
|
|
354
|
-
* @returns {Promise<object>} Complete category API structure
|
|
355
|
-
*
|
|
356
|
-
* @description
|
|
357
|
-
* Complete directory structure building pipeline that handles:
|
|
358
|
-
* - Single-file vs multi-file directory processing
|
|
359
|
-
* - Auto-flattening decisions for single files matching directory names
|
|
360
|
-
* - Multi-default export detection and processing
|
|
361
|
-
* - Self-referential export handling
|
|
362
|
-
* - Recursive subdirectory traversal with depth control
|
|
363
|
-
* - Function name preference over sanitized names
|
|
364
|
-
* - All established slothlet flattening rules and conventions
|
|
365
|
-
*
|
|
366
|
-
* @example
|
|
367
|
-
* // Internal usage - build complete category structure
|
|
368
|
-
* const categoryApi = await buildCategoryStructure("/path/to/category", {
|
|
369
|
-
* currentDepth: 0, maxDepth: 3, mode: "eager", instance: slothletInstance
|
|
370
|
-
* });
|
|
371
|
-
*/
|
|
372
|
-
export function buildCategoryStructure(categoryPath: string, options?: {
|
|
373
|
-
currentDepth?: number;
|
|
374
|
-
maxDepth?: number;
|
|
375
|
-
mode?: string;
|
|
376
|
-
subdirHandler?: Function;
|
|
377
|
-
instance: object;
|
|
378
|
-
}): Promise<object>;
|
|
379
|
-
/**
|
|
380
|
-
* Comprehensive root API building function that replaces eager/lazy create methods.
|
|
381
|
-
* Handles complete root-level API construction with mode-specific optimizations.
|
|
382
|
-
* @function buildRootAPI
|
|
383
|
-
* @internal
|
|
384
|
-
* @package
|
|
385
|
-
* @async
|
|
386
|
-
* @param {string} dir - Root directory path to build API from
|
|
387
|
-
* @param {object} options - Building options
|
|
388
|
-
* @param {boolean} [options.lazy=false] - Whether to use lazy loading mode
|
|
389
|
-
* @param {number} [options.maxDepth=Infinity] - Maximum recursion depth
|
|
390
|
-
* @param {object} options.instance - Slothlet instance for access to helper methods
|
|
391
|
-
* @returns {Promise<object|function>} Complete root API (object or function with properties)
|
|
392
|
-
*
|
|
393
|
-
* @description
|
|
394
|
-
* Complete root API building pipeline that handles:
|
|
395
|
-
* - Root-level module processing with multi-default detection
|
|
396
|
-
* - Root contributor pattern (default function becomes callable API)
|
|
397
|
-
* - Named export merging and flattening decisions
|
|
398
|
-
* - Recursive directory structure building via buildCategoryStructure
|
|
399
|
-
* - Mode-specific optimizations (eager vs lazy)
|
|
400
|
-
* - All established slothlet API construction patterns
|
|
401
|
-
*
|
|
402
|
-
* @example
|
|
403
|
-
* // Internal usage - build complete root API
|
|
404
|
-
* const rootApi = await buildRootAPI("/path/to/api", {
|
|
405
|
-
* lazy: false, maxDepth: 3, instance: slothletInstance
|
|
406
|
-
* });
|
|
407
|
-
*/
|
|
408
|
-
export function buildRootAPI(dir: string, options?: {
|
|
409
|
-
lazy?: boolean;
|
|
410
|
-
maxDepth?: number;
|
|
411
|
-
instance: object;
|
|
412
|
-
}): Promise<object | Function>;
|
|
413
|
-
/**
|
|
414
|
-
* Centralized category building decisions - contains ALL logic for directory/category processing.
|
|
415
|
-
* This function analyzes a directory and returns decisions about how to structure the API,
|
|
416
|
-
* but doesn't actually build the API (allowing eager/lazy modes to implement differently).
|
|
417
|
-
*
|
|
418
|
-
* @function buildCategoryDecisions
|
|
419
|
-
* @param {string} categoryPath - Path to the category directory
|
|
420
|
-
* @param {object} options - Configuration options
|
|
421
|
-
* @param {number} [options.currentDepth=0] - Current nesting depth
|
|
422
|
-
* @param {number} [options.maxDepth=Infinity] - Maximum nesting depth
|
|
423
|
-
* @param {string} [options.mode="eager"] - Loading mode ("eager" or "lazy")
|
|
424
|
-
* @param {Function} [options.subdirHandler] - Handler for subdirectories (lazy mode)
|
|
425
|
-
* @param {object} options.instance - Slothlet instance with _toapiPathKey, _shouldIncludeFile, config
|
|
426
|
-
* @returns {Promise<object>} Category building decisions and data
|
|
427
|
-
*
|
|
428
|
-
* @example // ESM usage
|
|
429
|
-
* import { buildCategoryDecisions } from "@cldmv/slothlet/helpers/api_builder";
|
|
430
|
-
* const decisions = await buildCategoryDecisions("/path/to/category", {
|
|
431
|
-
* currentDepth: 1,
|
|
432
|
-
* instance: slothletInstance
|
|
433
|
-
* });
|
|
434
|
-
*
|
|
435
|
-
* @example // CJS usage
|
|
436
|
-
* const { buildCategoryDecisions } = require("@cldmv/slothlet/helpers/api_builder");
|
|
437
|
-
* const decisions = await buildCategoryDecisions("/path/to/category", {
|
|
438
|
-
* currentDepth: 1,
|
|
439
|
-
* instance: slothletInstance
|
|
440
|
-
* });
|
|
441
|
-
*/
|
|
442
|
-
export function buildCategoryDecisions(categoryPath: string, options?: {
|
|
443
|
-
currentDepth?: number;
|
|
444
|
-
maxDepth?: number;
|
|
445
|
-
mode?: string;
|
|
446
|
-
subdirHandler?: Function;
|
|
447
|
-
instance: object;
|
|
448
|
-
}): Promise<object>;
|
|
1
|
+
export { addApiFromFolder } from "@cldmv/slothlet/helpers/api_builder/add_api";
|
|
2
|
+
export { isLikelySerializable, analyzeModule, processModuleFromAnalysis, analyzeDirectoryStructure, getCategoryBuildingDecisions } from "@cldmv/slothlet/helpers/api_builder/analysis";
|
|
3
|
+
export { getFlatteningDecision, applyFunctionNamePreference, processModuleForAPI, buildCategoryDecisions } from "@cldmv/slothlet/helpers/api_builder/decisions";
|
|
4
|
+
export { buildCategoryStructure, buildRootAPI, toapiPathKey, shouldIncludeFile } from "@cldmv/slothlet/helpers/api_builder/construction";
|
|
5
|
+
export { safeDefine, deepMerge, mutateLiveBindingFunction } from "@cldmv/slothlet/helpers/utilities";
|
|
449
6
|
//# sourceMappingURL=api_builder.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api_builder.d.mts","sourceRoot":"","sources":["../../../../dist/lib/helpers/api_builder.mjs"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"api_builder.d.mts","sourceRoot":"","sources":["../../../../dist/lib/helpers/api_builder.mjs"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
export namespace metadataAPI {
|
|
2
|
+
/**
|
|
3
|
+
* Get metadata of the function that called the current function.
|
|
4
|
+
*
|
|
5
|
+
* @function caller
|
|
6
|
+
* @memberof metadataAPI
|
|
7
|
+
* @returns {object|null} Caller's metadata object or null if not found
|
|
8
|
+
* @public
|
|
9
|
+
*
|
|
10
|
+
* @description
|
|
11
|
+
* Uses stack trace analysis to identify the calling function and retrieve
|
|
12
|
+
* its attached metadata. Useful for implementing access control where a
|
|
13
|
+
* function needs to verify the identity/permissions of its caller.
|
|
14
|
+
*
|
|
15
|
+
* Stack trace structure:
|
|
16
|
+
* - Line 0: Error
|
|
17
|
+
* - Line 1: metadataAPI.caller (this function)
|
|
18
|
+
* - Line 2: Current function (the one checking)
|
|
19
|
+
* - Line 3: The caller we want to identify
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* // In a secure function
|
|
23
|
+
* import { metadataAPI } from "@cldmv/slothlet/runtime";
|
|
24
|
+
*
|
|
25
|
+
* export function getSecrets() {
|
|
26
|
+
* const caller = metadataAPI.caller();
|
|
27
|
+
*
|
|
28
|
+
* if (!caller?.trusted) {
|
|
29
|
+
* throw new Error("Access denied: untrusted caller");
|
|
30
|
+
* }
|
|
31
|
+
*
|
|
32
|
+
* if (!caller.permissions?.includes("read_secrets")) {
|
|
33
|
+
* throw new Error("Access denied: insufficient permissions");
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* return { apiKey: "secret123", token: "xyz" };
|
|
37
|
+
* }
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* // With custom metadata tags
|
|
41
|
+
* const caller = metadataAPI.caller();
|
|
42
|
+
* console.log("Caller source:", caller?.sourceFolder);
|
|
43
|
+
* console.log("Caller version:", caller?.version);
|
|
44
|
+
* console.log("Caller author:", caller?.author);
|
|
45
|
+
*/
|
|
46
|
+
function caller(): object | null;
|
|
47
|
+
/**
|
|
48
|
+
* Get metadata of the current function.
|
|
49
|
+
*
|
|
50
|
+
* @function self
|
|
51
|
+
* @memberof metadataAPI
|
|
52
|
+
* @returns {object|null} Current function's metadata or null if not found
|
|
53
|
+
* @public
|
|
54
|
+
*
|
|
55
|
+
* @description
|
|
56
|
+
* Retrieves metadata attached to the currently executing function. Useful
|
|
57
|
+
* for functions that need to inspect their own metadata (e.g., for logging,
|
|
58
|
+
* conditional behavior based on load source).
|
|
59
|
+
*
|
|
60
|
+
* Stack trace structure:
|
|
61
|
+
* - Line 0: Error
|
|
62
|
+
* - Line 1: metadataAPI.self (this function)
|
|
63
|
+
* - Line 2: Current function (the one we want to identify)
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* // Function checking its own metadata
|
|
67
|
+
* import { metadataAPI } from "@cldmv/slothlet/runtime";
|
|
68
|
+
*
|
|
69
|
+
* export function smartFunction() {
|
|
70
|
+
* const meta = metadataAPI.self();
|
|
71
|
+
*
|
|
72
|
+
* if (meta?.environment === "development") {
|
|
73
|
+
* console.log("Running in development mode");
|
|
74
|
+
* }
|
|
75
|
+
*
|
|
76
|
+
* if (meta?.version) {
|
|
77
|
+
* console.log(`Function version: ${meta.version}`);
|
|
78
|
+
* }
|
|
79
|
+
*
|
|
80
|
+
* return "result";
|
|
81
|
+
* }
|
|
82
|
+
*/
|
|
83
|
+
function self(): object | null;
|
|
84
|
+
/**
|
|
85
|
+
* Get metadata of any function by API path.
|
|
86
|
+
*
|
|
87
|
+
* @function get
|
|
88
|
+
* @memberof metadataAPI
|
|
89
|
+
* @param {string} path - Dot-notation API path (e.g., "math.add", "plugins.helper")
|
|
90
|
+
* @param {object} [apiRoot] - Optional API root object (uses runtime.self if not provided)
|
|
91
|
+
* @returns {object|null} Function's metadata or null if not found
|
|
92
|
+
* @public
|
|
93
|
+
*
|
|
94
|
+
* @description
|
|
95
|
+
* Retrieves metadata for any function in the API tree by its path. Useful
|
|
96
|
+
* for checking metadata of functions you have references to, or for
|
|
97
|
+
* administrative/introspection purposes.
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* // Check metadata of a specific function
|
|
101
|
+
* import { metadataAPI } from "@cldmv/slothlet/runtime";
|
|
102
|
+
*
|
|
103
|
+
* export function checkPermissions() {
|
|
104
|
+
* const pluginMeta = metadataAPI.get("plugins.userPlugin");
|
|
105
|
+
*
|
|
106
|
+
* if (!pluginMeta) {
|
|
107
|
+
* throw new Error("Plugin not found or has no metadata");
|
|
108
|
+
* }
|
|
109
|
+
*
|
|
110
|
+
* if (pluginMeta.trusted) {
|
|
111
|
+
* console.log("Plugin is trusted");
|
|
112
|
+
* } else {
|
|
113
|
+
* console.log("Plugin is untrusted");
|
|
114
|
+
* }
|
|
115
|
+
* }
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* // Iterate and check all plugins
|
|
119
|
+
* const pluginPaths = ["plugins.auth", "plugins.logger", "plugins.cache"];
|
|
120
|
+
* for (const path of pluginPaths) {
|
|
121
|
+
* const meta = metadataAPI.get(path);
|
|
122
|
+
* console.log(`${path}: ${meta?.version || "unknown"}`);
|
|
123
|
+
* }
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* // From outside slothlet context, pass API root explicitly
|
|
127
|
+
* const api = await slothlet({ dir: "./modules" });
|
|
128
|
+
* const meta = await metadataAPI.get("plugins.helper", api);
|
|
129
|
+
*/
|
|
130
|
+
function get(path: string, apiRoot?: object): object | null;
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=metadata-api.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata-api.d.mts","sourceRoot":"","sources":["../../../../dist/lib/helpers/metadata-api.mjs"],"names":[],"mappings":";IAmNC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2CG;IACH,mBAvCa,MAAM,GAAC,IAAI,CAgEvB;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCG;IACH,iBA/Ba,MAAM,GAAC,IAAI,CAsDvB;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6CG;IACH,mBAzCW,MAAM,YACN,MAAM,GACJ,MAAM,GAAC,IAAI,CAsDvB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multidefault.d.mts","sourceRoot":"","sources":["../../../../dist/lib/helpers/multidefault.mjs"],"names":[],"mappings":"AAoBA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,yDAlBW,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,CAAC,WACrB,MAAM,YAEd;IAA0B,KAAK,GAAvB,OAAO;IACe,QAAQ,GAA9B,MAAM,GAAC,IAAI;CACnB,GAAU,OAAO,CAAC;IAChB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,yBAAyB,EAAE,OAAO,CAAC;IACnC,oBAAoB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAClC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,kBAAkB,EAAE,KAAK,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAC,CAAC,CAAA;CACjE,CAAC,
|
|
1
|
+
{"version":3,"file":"multidefault.d.mts","sourceRoot":"","sources":["../../../../dist/lib/helpers/multidefault.mjs"],"names":[],"mappings":"AAoBA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,yDAlBW,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,CAAC,WACrB,MAAM,YAEd;IAA0B,KAAK,GAAvB,OAAO;IACe,QAAQ,GAA9B,MAAM,GAAC,IAAI;CACnB,GAAU,OAAO,CAAC;IAChB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,yBAAyB,EAAE,OAAO,CAAC;IACnC,oBAAoB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAClC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,kBAAkB,EAAE,KAAK,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAC,CAAC,CAAA;CACjE,CAAC,CAuGJ;AAED;;;;;;;;GAQG;AACH,0DALW,MAAM,GACJ,OAAO,CAWnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,4DAvBG;IAAyB,yBAAyB,EAA1C,OAAO;IACU,gBAAgB,EAAjC,OAAO;IACU,iBAAiB,EAAlC,OAAO;IACgB,UAAU,EAAjC,KAAK,CAAC,MAAM,CAAC;IACG,UAAU,EAA1B,MAAM;IACU,gBAAgB,EAAhC,MAAM;IACY,KAAK,GAAvB,OAAO;CACf,GAAU;IACR,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAA;CACf,CA4FH"}
|