@cldmv/slothlet 2.7.1 → 2.9.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 +253 -1475
- package/dist/lib/helpers/als-eventemitter.mjs +4 -5
- package/dist/lib/helpers/api_builder/add_api.mjs +237 -0
- package/dist/lib/helpers/api_builder/analysis.mjs +522 -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.mjs +16 -1567
- package/dist/lib/helpers/utilities.mjs +121 -0
- package/dist/lib/runtime/runtime-asynclocalstorage.mjs +44 -17
- package/dist/lib/runtime/runtime-livebindings.mjs +18 -3
- package/dist/lib/runtime/runtime.mjs +3 -3
- package/dist/slothlet.mjs +197 -547
- package/docs/API-RULES-CONDITIONS.md +508 -0
- package/{API-RULES.md → docs/API-RULES.md} +127 -72
- package/index.cjs +2 -1
- package/index.mjs +2 -1
- 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 +60 -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.d.mts +5 -448
- package/types/dist/lib/helpers/api_builder.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 +7 -0
- package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts.map +1 -1
- package/types/dist/lib/runtime/runtime-livebindings.d.mts +8 -0
- package/types/dist/lib/runtime/runtime-livebindings.d.mts.map +1 -1
- package/types/dist/slothlet.d.mts +23 -13
- 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,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @Project: @cldmv/slothlet
|
|
3
|
+
* @Filename: /src/lib/helpers/utilities.mjs
|
|
4
|
+
* @Date: 2025-12-30 08:44:44 -08:00 (1767113084)
|
|
5
|
+
* @Author: Nate Hyson <CLDMV>
|
|
6
|
+
* @Email: <Shinrai@users.noreply.github.com>
|
|
7
|
+
* -----
|
|
8
|
+
* @Last modified by: Nate Hyson <CLDMV> (Shinrai@users.noreply.github.com)
|
|
9
|
+
* @Last modified time: 2025-12-30 08:54:56 -08:00 (1767113696)
|
|
10
|
+
* -----
|
|
11
|
+
* @Copyright: Copyright (c) 2013-2025 Catalyzed Motivation Inc. All rights reserved.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* @fileoverview Utility functions for property manipulation and object operations.
|
|
15
|
+
* @module @cldmv/slothlet/lib/helpers/utilities
|
|
16
|
+
* @memberof module:@cldmv/slothlet.lib.helpers
|
|
17
|
+
* @internal
|
|
18
|
+
* @private
|
|
19
|
+
*
|
|
20
|
+
* @description
|
|
21
|
+
* Provides general-purpose utility functions for safe property definition, deep object merging,
|
|
22
|
+
* and live-binding variable mutation. These utilities are used throughout slothlet for
|
|
23
|
+
* object manipulation, property management, and live-binding operations.
|
|
24
|
+
*
|
|
25
|
+
* Exported Functions:
|
|
26
|
+
* - safeDefine: Safe property definition handling non-configurable properties
|
|
27
|
+
* - deepMerge: Recursive deep merge for object combining
|
|
28
|
+
* - mutateLiveBindingFunction: Live-binding variable mutation preserving references
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* // Internal usage in slothlet
|
|
32
|
+
* import { safeDefine, deepMerge, mutateLiveBindingFunction } from "./utilities.mjs";
|
|
33
|
+
*
|
|
34
|
+
* safeDefine(api, "shutdown", shutdownFunction, false);
|
|
35
|
+
* const merged = deepMerge(target, source);
|
|
36
|
+
* mutateLiveBindingFunction(boundapi, newApi);
|
|
37
|
+
*/
|
|
38
|
+
/**
|
|
39
|
+
* Safely defines a property on an object, handling non-configurable properties.
|
|
40
|
+
*
|
|
41
|
+
* @function safeDefine
|
|
42
|
+
* @memberof module:@cldmv/slothlet.lib.helpers.utilities
|
|
43
|
+
* @param {object} obj - Target object
|
|
44
|
+
* @param {string} key - Property key
|
|
45
|
+
* @param {*} value - Property value
|
|
46
|
+
* @param {boolean} [enumerable=false] - Whether the property should be enumerable (default: false for management methods)
|
|
47
|
+
* @param {object} [config=null] - Optional configuration object with debug flag
|
|
48
|
+
* @package
|
|
49
|
+
*
|
|
50
|
+
* @description
|
|
51
|
+
* Attempts to define a property on an object with the specified configuration.
|
|
52
|
+
* Handles cases where the property is non-configurable by logging a warning
|
|
53
|
+
* instead of throwing an error. Used for safely attaching management methods
|
|
54
|
+
* like shutdown, addApi, and describe to API objects.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* // Internal usage
|
|
58
|
+
* import { safeDefine } from "./utilities.mjs";
|
|
59
|
+
*
|
|
60
|
+
* safeDefine(api, "shutdown", shutdownFunction, false, { debug: true });
|
|
61
|
+
*/
|
|
62
|
+
export function safeDefine(obj: object, key: string, value: any, enumerable?: boolean, config?: object): void;
|
|
63
|
+
/**
|
|
64
|
+
* Deep merge two objects recursively.
|
|
65
|
+
*
|
|
66
|
+
* @function deepMerge
|
|
67
|
+
* @memberof module:@cldmv/slothlet.lib.helpers.utilities
|
|
68
|
+
* @param {object} target - Target object to merge into
|
|
69
|
+
* @param {object} source - Source object to merge from
|
|
70
|
+
* @returns {object} Merged object (mutates target)
|
|
71
|
+
* @package
|
|
72
|
+
*
|
|
73
|
+
* @description
|
|
74
|
+
* Performs a recursive deep merge of two objects, combining nested structures.
|
|
75
|
+
* Arrays are treated as primitive values and replaced rather than merged.
|
|
76
|
+
* Used for context merging in scope operations.
|
|
77
|
+
*
|
|
78
|
+
* **Security Note**: This function explicitly blocks the `__proto__`, `prototype`, and
|
|
79
|
+
* `constructor` keys to prevent prototype pollution attacks. Any attempt to merge
|
|
80
|
+
* these dangerous keys will be silently ignored.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* // Internal usage
|
|
84
|
+
* import { deepMerge } from "./utilities.mjs";
|
|
85
|
+
*
|
|
86
|
+
* const target = { a: 1, b: { c: 2 } };
|
|
87
|
+
* const source = { b: { d: 3 }, e: 4 };
|
|
88
|
+
* const merged = deepMerge(target, source);
|
|
89
|
+
* // Result: { a: 1, b: { c: 2, d: 3 }, e: 4 }
|
|
90
|
+
*/
|
|
91
|
+
export function deepMerge(target: object, source: object): object;
|
|
92
|
+
/**
|
|
93
|
+
* Mutates a live-binding variable (object or function) to match a new value, preserving reference.
|
|
94
|
+
*
|
|
95
|
+
* @function mutateLiveBindingFunction
|
|
96
|
+
* @memberof module:@cldmv/slothlet.lib.helpers.utilities
|
|
97
|
+
* @param {function|object} target - The variable to mutate (object or function)
|
|
98
|
+
* @param {function|object} source - The new value to copy from (object or function)
|
|
99
|
+
* @package
|
|
100
|
+
*
|
|
101
|
+
* @description
|
|
102
|
+
* Mutates an existing live-binding variable to match a new structure while
|
|
103
|
+
* preserving the original reference. This is critical for maintaining live
|
|
104
|
+
* bindings in modules that have imported self, context, or reference.
|
|
105
|
+
*
|
|
106
|
+
* For functions: Sets _impl to call source, removes old properties (except _impl and __ctx),
|
|
107
|
+
* and attaches new properties from source.
|
|
108
|
+
*
|
|
109
|
+
* For objects: Removes old properties (except _impl and __ctx), attaches new properties,
|
|
110
|
+
* and manually copies management methods (shutdown, addApi, describe).
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* // Internal usage
|
|
114
|
+
* import { mutateLiveBindingFunction } from "./utilities.mjs";
|
|
115
|
+
*
|
|
116
|
+
* mutateLiveBindingFunction(self, newSelf);
|
|
117
|
+
* mutateLiveBindingFunction(boundapi, newApi);
|
|
118
|
+
*/
|
|
119
|
+
export function mutateLiveBindingFunction(target: Function | object, source: Function | object): void;
|
|
120
|
+
//# sourceMappingURL=utilities.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utilities.d.mts","sourceRoot":"","sources":["../../../../dist/lib/helpers/utilities.mjs"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,gCAnBW,MAAM,OACN,MAAM,SACN,GAAC,eACD,OAAO,WACP,MAAM,QAkChB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,kCAvBW,MAAM,UACN,MAAM,GACJ,MAAM,CAkDlB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,kDAtBW,WAAS,MAAM,UACf,WAAS,MAAM,QAkEzB"}
|
|
@@ -5,6 +5,13 @@
|
|
|
5
5
|
* @public
|
|
6
6
|
*/
|
|
7
7
|
export const sharedALS: AsyncLocalStorageType;
|
|
8
|
+
/**
|
|
9
|
+
* Per-request AsyncLocalStorage instance for request-scoped context.
|
|
10
|
+
* Stores temporary context data that merges with instance context.
|
|
11
|
+
* @type {AsyncLocalStorageType}
|
|
12
|
+
* @public
|
|
13
|
+
*/
|
|
14
|
+
export const requestALS: AsyncLocalStorageType;
|
|
8
15
|
export function runWithCtx(ctx: object, fn: Function, thisArg: any, args: any[]): any;
|
|
9
16
|
export function getCtx(): object | null;
|
|
10
17
|
export function makeWrapper(ctx: object): Function;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-asynclocalstorage.d.mts","sourceRoot":"","sources":["../../../../dist/lib/runtime/runtime-asynclocalstorage.mjs"],"names":[],"mappings":"AAuCA;;;;;GAKG;AACH,wBAHU,qBAAqB,CAGkB;
|
|
1
|
+
{"version":3,"file":"runtime-asynclocalstorage.d.mts","sourceRoot":"","sources":["../../../../dist/lib/runtime/runtime-asynclocalstorage.mjs"],"names":[],"mappings":"AAuCA;;;;;GAKG;AACH,wBAHU,qBAAqB,CAGkB;AAEjD;;;;;GAKG;AACH,yBAHU,qBAAqB,CAGmB;AAsB3C,gCAdI,MAAM,yBAEN,GAAG,gBAED,GAAG,CAwGf;AAiBM,0BAZM,MAAM,GAAC,IAAI,CAY0B;AAkN3C,iCAjBI,MAAM,YAiJhB;AA2TD;;;;;;;;;;;;;GAaG;AACH,mBATU,WAAS,MAAM,CAS6B;AAEtD;;;;;;;;;;;;;GAaG;AACH,sBATU,MAAM,CAS4C;AAE5D;;;;;;;;;;;;;GAaG;AACH,wBATU,MAAM,CASgD;;kCAp1B9B,kBAAkB"}
|
|
@@ -23,6 +23,13 @@ export function makeWrapper(ctx: object): Function;
|
|
|
23
23
|
*/
|
|
24
24
|
export function getContext(): any;
|
|
25
25
|
export function setContext(newContext: any): void;
|
|
26
|
+
/**
|
|
27
|
+
* Per-request AsyncLocalStorage instance for request-scoped context.
|
|
28
|
+
* Works alongside live bindings to provide per-request context isolation.
|
|
29
|
+
* @type {AsyncLocalStorage}
|
|
30
|
+
* @public
|
|
31
|
+
*/
|
|
32
|
+
export const requestALS: AsyncLocalStorage<any>;
|
|
26
33
|
/**
|
|
27
34
|
* Live-binding reference to the current API instance.
|
|
28
35
|
* Automatically resolves to the appropriate instance based on calling context.
|
|
@@ -56,4 +63,5 @@ export namespace contextManager {
|
|
|
56
63
|
export { setContext as set };
|
|
57
64
|
export { runWithCtx };
|
|
58
65
|
}
|
|
66
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
59
67
|
//# sourceMappingURL=runtime-livebindings.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-livebindings.d.mts","sourceRoot":"","sources":["../../../../dist/lib/runtime/runtime-livebindings.mjs"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runtime-livebindings.d.mts","sourceRoot":"","sources":["../../../../dist/lib/runtime/runtime-livebindings.mjs"],"names":[],"mappings":"AA+SA;;;;;;;;;GASG;AACH,gCANW,MAAM,yBAEN,GAAG,gBAED,GAAG,CAoFf;AAED;;;;;;GAMG;AACH,iCAHW,MAAM,YAiEhB;AAID;;;GAGG;AAEH,kCAEC;AAED,kDASC;AA/bD;;;;;GAKG;AACH,gDAAkD;AA8ClD;;;;;GAKG;AACH,mBAHU,MAAM,CAmDd;AAEF;;;;;GAKG;AACH,sBAHU,MAAM,CA0Dd;AAEF;;;;;GAKG;AACH,wBAHU,MAAM,CA+Cd;AAEF;;;;;GAKG;AACH,yBAHU,MAAM,CAkCd;;;;;;kCA5QgC,kBAAkB"}
|