@cldmv/slothlet 3.3.0 → 3.4.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/README.md +9 -10
- package/REFERENCE.md +23 -0
- package/dist/lib/builders/api-assignment.mjs +1 -589
- package/dist/lib/builders/api_builder.mjs +1 -1385
- package/dist/lib/builders/builder.mjs +1 -78
- package/dist/lib/builders/modes-processor.mjs +1 -1800
- package/dist/lib/errors.mjs +9 -211
- package/dist/lib/factories/component-base.mjs +1 -80
- package/dist/lib/factories/context.mjs +1 -22
- package/dist/lib/handlers/api-cache-manager.mjs +1 -200
- package/dist/lib/handlers/api-manager.mjs +1 -2536
- package/dist/lib/handlers/context-async.mjs +1 -172
- package/dist/lib/handlers/context-live.mjs +1 -173
- package/dist/lib/handlers/hook-manager.mjs +1 -667
- package/dist/lib/handlers/lifecycle-token.mjs +1 -28
- package/dist/lib/handlers/lifecycle.mjs +1 -115
- package/dist/lib/handlers/materialize-manager.mjs +1 -48
- package/dist/lib/handlers/metadata.mjs +1 -501
- package/dist/lib/handlers/ownership.mjs +1 -322
- package/dist/lib/handlers/permission-manager.mjs +1 -392
- package/dist/lib/handlers/unified-wrapper.mjs +1 -3110
- package/dist/lib/handlers/version-manager.mjs +1 -885
- package/dist/lib/helpers/class-instance-wrapper.mjs +1 -109
- package/dist/lib/helpers/config.mjs +1 -439
- package/dist/lib/helpers/eventemitter-context.mjs +1 -349
- package/dist/lib/helpers/hint-detector.mjs +1 -47
- package/dist/lib/helpers/modes-utils.mjs +1 -37
- package/dist/lib/helpers/pattern-matcher.mjs +1 -125
- package/dist/lib/helpers/resolve-from-caller.mjs +1 -169
- package/dist/lib/helpers/sanitize.mjs +1 -340
- package/dist/lib/helpers/utilities.mjs +1 -70
- package/dist/lib/i18n/languages/de-de.json +1 -0
- package/dist/lib/i18n/languages/en-gb.json +1 -0
- package/dist/lib/i18n/languages/en-us.json +1 -0
- package/dist/lib/i18n/languages/es-es.json +412 -0
- package/dist/lib/i18n/languages/es-mx.json +1 -0
- package/dist/lib/i18n/languages/fr-fr.json +1 -0
- package/dist/lib/i18n/languages/hi-in.json +2 -1
- package/dist/lib/i18n/languages/ja-jp.json +1 -0
- package/dist/lib/i18n/languages/ko-kr.json +1 -0
- package/dist/lib/i18n/languages/pt-br.json +21 -20
- package/dist/lib/i18n/languages/ru-ru.json +2 -1
- package/dist/lib/i18n/languages/zh-cn.json +6 -5
- package/dist/lib/i18n/translations.mjs +1 -126
- package/dist/lib/modes/eager.mjs +1 -59
- package/dist/lib/modes/lazy.mjs +1 -81
- package/dist/lib/processors/flatten.mjs +1 -437
- package/dist/lib/processors/loader.mjs +1 -339
- package/dist/lib/processors/type-generator.mjs +1 -275
- package/dist/lib/processors/typescript.mjs +1 -172
- package/dist/lib/runtime/runtime-asynclocalstorage.mjs +1 -113
- package/dist/lib/runtime/runtime-livebindings.mjs +1 -78
- package/dist/lib/runtime/runtime.mjs +1 -102
- package/dist/slothlet.mjs +1 -817
- package/package.json +35 -31
- package/types/dist/lib/builders/api-assignment.d.mts +3 -92
- package/types/dist/lib/builders/api-assignment.d.mts.map +1 -1
- package/types/dist/lib/builders/api_builder.d.mts +102 -91
- package/types/dist/lib/builders/api_builder.d.mts.map +1 -1
- package/types/dist/lib/builders/builder.d.mts +1 -55
- package/types/dist/lib/builders/builder.d.mts.map +1 -1
- package/types/dist/lib/builders/modes-processor.d.mts +3 -27
- package/types/dist/lib/builders/modes-processor.d.mts.map +1 -1
- package/types/dist/lib/errors.d.mts +19 -109
- package/types/dist/lib/errors.d.mts.map +1 -1
- package/types/dist/lib/factories/component-base.d.mts +7 -177
- package/types/dist/lib/factories/component-base.d.mts.map +1 -1
- package/types/dist/lib/factories/context.d.mts +4 -22
- package/types/dist/lib/factories/context.d.mts.map +1 -1
- package/types/dist/lib/handlers/api-cache-manager.d.mts +20 -203
- package/types/dist/lib/handlers/api-cache-manager.d.mts.map +1 -1
- package/types/dist/lib/handlers/api-manager.d.mts +34 -408
- package/types/dist/lib/handlers/api-manager.d.mts.map +1 -1
- package/types/dist/lib/handlers/context-async.d.mts +23 -61
- package/types/dist/lib/handlers/context-async.d.mts.map +1 -1
- package/types/dist/lib/handlers/context-live.d.mts +22 -59
- package/types/dist/lib/handlers/context-live.d.mts.map +1 -1
- package/types/dist/lib/handlers/hook-manager.d.mts +46 -185
- package/types/dist/lib/handlers/hook-manager.d.mts.map +1 -1
- package/types/dist/lib/handlers/lifecycle-token.d.mts +3 -48
- package/types/dist/lib/handlers/lifecycle-token.d.mts.map +1 -1
- package/types/dist/lib/handlers/lifecycle.d.mts +5 -82
- package/types/dist/lib/handlers/lifecycle.d.mts.map +1 -1
- package/types/dist/lib/handlers/materialize-manager.d.mts +8 -70
- package/types/dist/lib/handlers/materialize-manager.d.mts.map +1 -1
- package/types/dist/lib/handlers/metadata.d.mts +17 -221
- package/types/dist/lib/handlers/metadata.d.mts.map +1 -1
- package/types/dist/lib/handlers/ownership.d.mts +44 -160
- package/types/dist/lib/handlers/ownership.d.mts.map +1 -1
- package/types/dist/lib/handlers/permission-manager.d.mts +40 -141
- package/types/dist/lib/handlers/permission-manager.d.mts.map +1 -1
- package/types/dist/lib/handlers/unified-wrapper.d.mts +26 -239
- package/types/dist/lib/handlers/unified-wrapper.d.mts.map +1 -1
- package/types/dist/lib/handlers/version-manager.d.mts +28 -225
- package/types/dist/lib/handlers/version-manager.d.mts.map +1 -1
- package/types/dist/lib/helpers/class-instance-wrapper.d.mts +2 -52
- package/types/dist/lib/helpers/class-instance-wrapper.d.mts.map +1 -1
- package/types/dist/lib/helpers/config.d.mts +125 -139
- package/types/dist/lib/helpers/config.d.mts.map +1 -1
- package/types/dist/lib/helpers/eventemitter-context.d.mts +3 -29
- package/types/dist/lib/helpers/eventemitter-context.d.mts.map +1 -1
- package/types/dist/lib/helpers/hint-detector.d.mts +2 -15
- package/types/dist/lib/helpers/hint-detector.d.mts.map +1 -1
- package/types/dist/lib/helpers/modes-utils.d.mts +3 -30
- package/types/dist/lib/helpers/modes-utils.d.mts.map +1 -1
- package/types/dist/lib/helpers/pattern-matcher.d.mts +3 -43
- package/types/dist/lib/helpers/pattern-matcher.d.mts.map +1 -1
- package/types/dist/lib/helpers/resolve-from-caller.d.mts +3 -27
- package/types/dist/lib/helpers/resolve-from-caller.d.mts.map +1 -1
- package/types/dist/lib/helpers/sanitize.d.mts +4 -92
- package/types/dist/lib/helpers/sanitize.d.mts.map +1 -1
- package/types/dist/lib/helpers/utilities.d.mts +4 -52
- package/types/dist/lib/helpers/utilities.d.mts.map +1 -1
- package/types/dist/lib/i18n/translations.d.mts +4 -37
- package/types/dist/lib/i18n/translations.d.mts.map +1 -1
- package/types/dist/lib/modes/eager.d.mts +8 -30
- package/types/dist/lib/modes/eager.d.mts.map +1 -1
- package/types/dist/lib/modes/lazy.d.mts +10 -43
- package/types/dist/lib/modes/lazy.d.mts.map +1 -1
- package/types/dist/lib/processors/flatten.d.mts +56 -107
- package/types/dist/lib/processors/flatten.d.mts.map +1 -1
- package/types/dist/lib/processors/loader.d.mts +6 -41
- package/types/dist/lib/processors/loader.d.mts.map +1 -1
- package/types/dist/lib/processors/type-generator.d.mts +2 -16
- package/types/dist/lib/processors/type-generator.d.mts.map +1 -1
- package/types/dist/lib/processors/typescript.d.mts +6 -53
- package/types/dist/lib/processors/typescript.d.mts.map +1 -1
- package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts +3 -71
- package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts.map +1 -1
- package/types/dist/lib/runtime/runtime-livebindings.d.mts +2 -37
- package/types/dist/lib/runtime/runtime-livebindings.d.mts.map +1 -1
- package/types/dist/lib/runtime/runtime.d.mts +3 -39
- package/types/dist/lib/runtime/runtime.d.mts.map +1 -1
- package/types/dist/slothlet.d.mts +3 -249
- package/types/dist/slothlet.d.mts.map +1 -1
- package/types/index.d.mts +36 -16
- package/types/index.d.mts.map +1 -0
- package/AGENT-USAGE.md +0 -736
- package/docs/API-RULES.md +0 -712
package/docs/API-RULES.md
DELETED
|
@@ -1,712 +0,0 @@
|
|
|
1
|
-
# Slothlet API Rules
|
|
2
|
-
|
|
3
|
-
**Complete Guide to All API Generation Behaviors**
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Document Hierarchy
|
|
8
|
-
|
|
9
|
-
This is the **middle layer** of slothlet's three-tier documentation system:
|
|
10
|
-
|
|
11
|
-
```text
|
|
12
|
-
📋 API-RULES/API-FLATTENING.md (F##) ← User Guide: Clear examples and flowcharts
|
|
13
|
-
↑ links to ↓ links to
|
|
14
|
-
📊 API-RULES.md (1-13) ← YOU ARE HERE: Complete behavior catalog
|
|
15
|
-
↑ links to ↓ links to
|
|
16
|
-
🔧 API-RULES/API-RULES-CONDITIONS.md ← Technical: Exact source code locations
|
|
17
|
-
↓ mapped in
|
|
18
|
-
🗺️ API-RULES/API-RULE-MAPPING.md ← Traceability Matrix: Rule # ↔ F## ↔ C##
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
**Cross-Reference Navigation:**
|
|
22
|
-
|
|
23
|
-
- **For Users**: See [API-RULES/API-FLATTENING.md](API-RULES/API-FLATTENING.md) for user-friendly explanations with examples
|
|
24
|
-
- **For Developers**: See [API-RULES/API-RULES-CONDITIONS.md](API-RULES/API-RULES-CONDITIONS.md) for exact source code locations
|
|
25
|
-
- **Rule Mapping**: See [API-RULES/API-RULE-MAPPING.md](API-RULES/API-RULE-MAPPING.md) for complete Rule # ↔ F## ↔ C## traceability matrix
|
|
26
|
-
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
## Overview
|
|
30
|
-
|
|
31
|
-
This document catalogs **all 13 API generation behaviors** in slothlet with:
|
|
32
|
-
|
|
33
|
-
- Verified examples from actual test files with source attribution
|
|
34
|
-
- Cross-references to user guide (F##) and technical details (C##)
|
|
35
|
-
- Source code locations with function names and file references
|
|
36
|
-
- Test file sources demonstrating each behavior in action
|
|
37
|
-
- Processing contexts (Root/Subfolder/Multi-Default/AddApi)
|
|
38
|
-
|
|
39
|
-
**Why 13 Rules vs Flattening Patterns?**
|
|
40
|
-
|
|
41
|
-
The [Flattening guide](API-RULES/API-FLATTENING.md) focuses on **when content gets promoted/flattened**. This comprehensive guide covers **all API behaviors** including cases where flattening doesn't occur but specific handling is still needed:
|
|
42
|
-
|
|
43
|
-
- **Flattening Rules** (1, 7, 8, 10, 11, 13): Core flattening patterns
|
|
44
|
-
- **Non-Flattening Rules** (2, 3, 4, 5, 6, 9): Export collection, function naming, empty modules, mixed exports
|
|
45
|
-
- **AddApi Rules** (11, 12, 13): Runtime API extension behaviors
|
|
46
|
-
|
|
47
|
-
**Methodology**: Each rule has been systematically verified against test files and source code.
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
## Rule Categories
|
|
52
|
-
|
|
53
|
-
| Category | Rules | Focus | Cross-References |
|
|
54
|
-
| --------------------- | ------------ | --------------------------- | ---------------- |
|
|
55
|
-
| **Basic Flattening** | 1, 7, 8 | Core flattening patterns | [F01-F05](API-RULES/API-FLATTENING.md) → [C01-C11](API-RULES/API-RULES-CONDITIONS.md) |
|
|
56
|
-
| **Export Handling** | 2, 4, 5 | Default vs Named exports | [F04-F05](API-RULES/API-FLATTENING.md) → [C08-C21](API-RULES/API-RULES-CONDITIONS.md) |
|
|
57
|
-
| **Special Cases** | 3, 6, 9, 10 | Edge cases and protections | [C10, C01, C16-C19](API-RULES/API-RULES-CONDITIONS.md) |
|
|
58
|
-
| **AddApi Extensions** | 11, 12, 13 | Runtime API extensions | [F06-F08](API-RULES/API-FLATTENING.md) → [C33, C34](API-RULES/API-RULES-CONDITIONS.md) |
|
|
59
|
-
|
|
60
|
-
---
|
|
61
|
-
|
|
62
|
-
## Table of Contents
|
|
63
|
-
|
|
64
|
-
1. [Rule 1: Filename Matches Container Flattening](#rule-1-filename-matches-container-flattening)
|
|
65
|
-
2. [Rule 2: Named-Only Export Collection](#rule-2-named-only-export-collection)
|
|
66
|
-
3. [Rule 3: Empty Module Handling](#rule-3-empty-module-handling)
|
|
67
|
-
4. [Rule 4: Named Export with Function Name Preservation](#rule-4-named-export-with-function-name-preservation)
|
|
68
|
-
5. [Rule 5: Multiple Module Default Export Handling](#rule-5-multiple-module-default-export-handling)
|
|
69
|
-
6. [Rule 6: Multiple Module Mixed Exports](#rule-6-multiple-module-mixed-exports)
|
|
70
|
-
7. [Rule 7: Single Module Named Export Flattening](#rule-7-single-module-named-export-flattening)
|
|
71
|
-
8. [Rule 8: Single Module Default Export Promotion](#rule-8-single-module-default-export-promotion)
|
|
72
|
-
9. [Rule 9: Function Name Preference Over Sanitization](#rule-9-function-name-preference-over-sanitization)
|
|
73
|
-
10. [Rule 10: Generic Filename Parent-Level Promotion](#rule-10-generic-filename-parent-level-promotion)
|
|
74
|
-
11. [Rule 11: AddApi Special File Pattern](#rule-11-addapi-special-file-pattern)
|
|
75
|
-
12. [Rule 12: Module Ownership and Selective API Overwriting](#rule-12-module-ownership-and-selective-api-overwriting)
|
|
76
|
-
13. [Rule 13: AddApi Path Deduplication Flattening](#rule-13-addapi-path-deduplication-flattening)
|
|
77
|
-
14. [Verification Status](#verification-status)
|
|
78
|
-
15. [Cross-Reference Index](#cross-reference-index)
|
|
79
|
-
|
|
80
|
-
---
|
|
81
|
-
|
|
82
|
-
## Rule 1: Filename Matches Container Flattening
|
|
83
|
-
|
|
84
|
-
**Category**: Basic Flattening
|
|
85
|
-
**Status**: ✅ Verified (`api_tests/api_test`)
|
|
86
|
-
**User Guide**: [F01](API-RULES/API-FLATTENING.md#f01-folder-file-name-matching)
|
|
87
|
-
**Technical**: [C05, C09b](API-RULES/API-RULES-CONDITIONS.md#c05)
|
|
88
|
-
|
|
89
|
-
**Condition**: Filename matches folder name AND no default export AND has named exports
|
|
90
|
-
**Source Files**: `api_tests/api_test/math/math.mjs`
|
|
91
|
-
**Implementation**: `buildCategoryDecisions()` → `getFlatteningDecision()` → `processModuleForAPI()`
|
|
92
|
-
|
|
93
|
-
**Verified Examples**:
|
|
94
|
-
|
|
95
|
-
```javascript
|
|
96
|
-
// File: api_tests/api_test/math/math.mjs
|
|
97
|
-
export function add(a, b) {
|
|
98
|
-
return a + b;
|
|
99
|
-
}
|
|
100
|
-
export function subtract(a, b) {
|
|
101
|
-
return a - b;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Without Rule 1: api.math.math.add(2, 3) ❌ (redundant nesting)
|
|
105
|
-
// With Rule 1: api.math.add(2, 3) ✅ (clean flattening)
|
|
106
|
-
api.math.add(2, 3); // 5
|
|
107
|
-
api.math.subtract(5, 2); // 3
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
**Technical Implementation**:
|
|
111
|
-
|
|
112
|
-
- **Primary Condition**: [C05](API-RULES/API-RULES-CONDITIONS.md#c05) - `fileName === categoryName && !moduleHasDefault && moduleKeys.length > 0`
|
|
113
|
-
- **Processing**: [C09b](API-RULES/API-RULES-CONDITIONS.md#c09b) - `flattenToCategory: true` → category-level flattening
|
|
114
|
-
|
|
115
|
-
```javascript
|
|
116
|
-
// C05: Filename Matches Container (Category-Level Flatten)
|
|
117
|
-
// Location: src/lib/helpers/api_builder/decisions.mjs
|
|
118
|
-
if (categoryName && fileName === categoryName && !moduleHasDefault && moduleKeys.length > 0) {
|
|
119
|
-
return {
|
|
120
|
-
shouldFlatten: true,
|
|
121
|
-
flattenToRoot: false,
|
|
122
|
-
flattenToCategory: true,
|
|
123
|
-
preserveAsNamespace: false,
|
|
124
|
-
useAutoFlattening: false,
|
|
125
|
-
reason: "filename matches container, flatten to category"
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
**Processing Path**: Subfolder processing via `getFlatteningDecision()` (currentDepth > 0)
|
|
131
|
-
**Source Code Location**: `src/lib/helpers/api_builder/decisions.mjs` - `getFlatteningDecision()`
|
|
132
|
-
|
|
133
|
-
---
|
|
134
|
-
|
|
135
|
-
## Rule 2: Named-Only Export Collection
|
|
136
|
-
|
|
137
|
-
**Category**: Export Handling
|
|
138
|
-
**Status**: ✅ Verified (`api_tests/api_test`)
|
|
139
|
-
**User Guide**: [F04](API-RULES/API-FLATTENING.md#f04)
|
|
140
|
-
**Technical**: [C15, C09d](API-RULES/API-RULES-CONDITIONS.md#c15)
|
|
141
|
-
|
|
142
|
-
**Condition**: Directory contains files with only named exports (no default exports)
|
|
143
|
-
**Behavior**: All named exports collected and made accessible at the appropriate namespace level
|
|
144
|
-
|
|
145
|
-
**Verified Examples**:
|
|
146
|
-
|
|
147
|
-
```javascript
|
|
148
|
-
// File: constants/values.mjs
|
|
149
|
-
export const PI = 3.14159;
|
|
150
|
-
export const E = 2.71828;
|
|
151
|
-
|
|
152
|
-
// File: constants/messages.mjs
|
|
153
|
-
export const SUCCESS = "Operation completed";
|
|
154
|
-
export const ERROR = "Operation failed";
|
|
155
|
-
|
|
156
|
-
api.constants.values.PI; // 3.14159
|
|
157
|
-
api.constants.values.E; // 2.71828
|
|
158
|
-
api.constants.messages.SUCCESS; // "Operation completed"
|
|
159
|
-
api.constants.messages.ERROR; // "Operation failed"
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
**Technical Implementation**:
|
|
163
|
-
|
|
164
|
-
- **Detection**: [C15](API-RULES/API-RULES-CONDITIONS.md#c15) - `defaultExportCount === 0`
|
|
165
|
-
- **Processing**: [C09d](API-RULES/API-RULES-CONDITIONS.md#c09d) - Standard namespace preservation
|
|
166
|
-
- **Strategy**: `processingStrategy = "named-only"` → category-level collection
|
|
167
|
-
|
|
168
|
-
**Key Behavior**:
|
|
169
|
-
|
|
170
|
-
- Preserves all named export names and values
|
|
171
|
-
- Maintains clear namespace separation between files
|
|
172
|
-
- No flattening when multiple named exports exist (prevents naming conflicts)
|
|
173
|
-
|
|
174
|
-
**Source Code Location**: `src/lib/helpers/api_builder/decisions.mjs` - `processModuleForAPI()`
|
|
175
|
-
**Processing Path**: Both Root and Subfolder processing via `processModuleForAPI`
|
|
176
|
-
|
|
177
|
-
---
|
|
178
|
-
|
|
179
|
-
## Rule 3: Empty Module Handling
|
|
180
|
-
|
|
181
|
-
**Category**: Special Cases
|
|
182
|
-
**Status**: ✅ Verified
|
|
183
|
-
**Technical**: [C10](API-RULES/API-RULES-CONDITIONS.md#c10)
|
|
184
|
-
|
|
185
|
-
**Condition**: Directory contains no loadable module files
|
|
186
|
-
**Behavior**: Graceful handling - creates empty namespace
|
|
187
|
-
**Processing Path**: Early detection in `buildCategoryDecisions()`
|
|
188
|
-
|
|
189
|
-
**Mode Differences**:
|
|
190
|
-
|
|
191
|
-
- **EAGER**: Empty folder → `{}` object (not callable)
|
|
192
|
-
- **LAZY**: Empty folder → lazy proxy that resolves to `{}` when called
|
|
193
|
-
|
|
194
|
-
**Technical Implementation**:
|
|
195
|
-
|
|
196
|
-
- **Detection**: [C10](API-RULES/API-RULES-CONDITIONS.md#c10) - `moduleFiles.length === 0`
|
|
197
|
-
- **Strategy**: `processingStrategy = "empty"` → graceful empty handling
|
|
198
|
-
|
|
199
|
-
```javascript
|
|
200
|
-
// Detection in analyzeDirectoryStructure
|
|
201
|
-
if (moduleFiles.length === 0) {
|
|
202
|
-
processingStrategy = "empty";
|
|
203
|
-
}
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
**Source Code Location**: `src/lib/helpers/api_builder/analysis.mjs`
|
|
207
|
-
**Processing Path**: All paths (detected in `analyzeDirectoryStructure`)
|
|
208
|
-
|
|
209
|
-
---
|
|
210
|
-
|
|
211
|
-
## Rule 4: Named Export with Function Name Preservation
|
|
212
|
-
|
|
213
|
-
**Category**: Export Handling
|
|
214
|
-
**Status**: ✅ Verified (`api_tests/api_test`)
|
|
215
|
-
**User Guide**: [F04](API-RULES/API-FLATTENING.md#f04)
|
|
216
|
-
**Technical**: [C16, C23](API-RULES/API-RULES-CONDITIONS.md#c16)
|
|
217
|
-
|
|
218
|
-
**Condition**: Named export with a function name that differs from the sanitized filename
|
|
219
|
-
**Behavior**: Preserves the original function name rather than using the filename-derived name
|
|
220
|
-
**Priority**: Function names take precedence over filename-based naming
|
|
221
|
-
|
|
222
|
-
**Verified Examples**:
|
|
223
|
-
|
|
224
|
-
```javascript
|
|
225
|
-
// File: auto-ip.mjs
|
|
226
|
-
export function autoIP() { /* ... */ }
|
|
227
|
-
api.autoIP(); // ✅ Function name preserved (not api.autoIp)
|
|
228
|
-
|
|
229
|
-
// File: json-parser.mjs
|
|
230
|
-
export function parseJSON(data) { /* ... */ }
|
|
231
|
-
api.parseJSON(data); // ✅ Original casing preserved (not api.jsonParser)
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
**Function Name Priority**:
|
|
235
|
-
|
|
236
|
-
1. Original function name (if available)
|
|
237
|
-
2. Filename-based sanitization (if no function name)
|
|
238
|
-
|
|
239
|
-
**Technical Implementation**:
|
|
240
|
-
|
|
241
|
-
- **Detection**: [C16](API-RULES/API-RULES-CONDITIONS.md#c16) - Function name availability check
|
|
242
|
-
- **Processing**: [C23](API-RULES/API-RULES-CONDITIONS.md#c23) - Function name takes precedence
|
|
243
|
-
|
|
244
|
-
---
|
|
245
|
-
|
|
246
|
-
## Rule 5: Multiple Module Default Export Handling
|
|
247
|
-
|
|
248
|
-
**Category**: Export Handling
|
|
249
|
-
**Status**: ✅ Verified (`api_tests/api_test`)
|
|
250
|
-
**Technical**: [C08, C09d](API-RULES/API-RULES-CONDITIONS.md#c08)
|
|
251
|
-
|
|
252
|
-
**Condition**: Category contains multiple modules with default exports
|
|
253
|
-
**Behavior**: Each module maintains its own namespace with the default export accessible directly
|
|
254
|
-
**Processing Path**: Standard namespace preservation (no flattening)
|
|
255
|
-
|
|
256
|
-
**Verified Examples**:
|
|
257
|
-
|
|
258
|
-
```javascript
|
|
259
|
-
// File: validators/email.mjs
|
|
260
|
-
export default function validateEmail(email) { /* ... */ }
|
|
261
|
-
|
|
262
|
-
// File: validators/phone.mjs
|
|
263
|
-
export default function validatePhone(phone) { /* ... */ }
|
|
264
|
-
|
|
265
|
-
api.validators.email("test@example.com"); // ✅ Default function callable
|
|
266
|
-
api.validators.phone("+1234567890"); // ✅ Default function callable
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
**Technical Implementation**:
|
|
270
|
-
|
|
271
|
-
- **Detection**: [C08](API-RULES/API-RULES-CONDITIONS.md#c08) - `moduleCount > 1 && defaultExportCount > 0`
|
|
272
|
-
- **Processing**: [C09d](API-RULES/API-RULES-CONDITIONS.md#c09d) - Standard namespace preservation
|
|
273
|
-
- **Strategy**: `processingStrategy = "standard"` → no flattening
|
|
274
|
-
|
|
275
|
-
**Key Behavior**:
|
|
276
|
-
|
|
277
|
-
- Maintains clear namespace separation between modules
|
|
278
|
-
- Prevents naming conflicts where multiple defaults would collide
|
|
279
|
-
- No automatic flattening when multiple defaults are present
|
|
280
|
-
|
|
281
|
-
---
|
|
282
|
-
|
|
283
|
-
## Rule 6: Multiple Module Mixed Exports
|
|
284
|
-
|
|
285
|
-
**Category**: Special Cases
|
|
286
|
-
**Status**: ✅ Verified (`api_tests/api_test_mixed`)
|
|
287
|
-
**Technical**: [C14, C09d](API-RULES/API-RULES-CONDITIONS.md#c14)
|
|
288
|
-
|
|
289
|
-
**Condition**: Category contains modules with mixed export types (some default, some named-only)
|
|
290
|
-
**Behavior**: Standard namespace processing - each module maintains a distinct namespace
|
|
291
|
-
**Processing Path**: Conservative approach to prevent conflicts
|
|
292
|
-
|
|
293
|
-
**Verified Examples**:
|
|
294
|
-
|
|
295
|
-
```javascript
|
|
296
|
-
// File: mixed/calculator.mjs (default export)
|
|
297
|
-
export default function calculate(operation, a, b) { /* ... */ }
|
|
298
|
-
|
|
299
|
-
// File: mixed/constants.mjs (named exports only)
|
|
300
|
-
export const PI = 3.14159;
|
|
301
|
-
export const E = 2.71828;
|
|
302
|
-
|
|
303
|
-
api.mixed.calculator("add", 2, 3); // ✅ Default accessible
|
|
304
|
-
api.mixed.constants.PI; // ✅ Named exports accessible
|
|
305
|
-
api.mixed.constants.E; // ✅ Clear namespace separation
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
**Technical Implementation**:
|
|
309
|
-
|
|
310
|
-
- **Detection**: [C14](API-RULES/API-RULES-CONDITIONS.md#c14) - Mixed export types present
|
|
311
|
-
- **Processing**: [C09d](API-RULES/API-RULES-CONDITIONS.md#c09d) - Conservative namespace preservation
|
|
312
|
-
|
|
313
|
-
---
|
|
314
|
-
|
|
315
|
-
## Rule 7: Single Module Named Export Flattening
|
|
316
|
-
|
|
317
|
-
**Category**: Basic Flattening
|
|
318
|
-
**Status**: ✅ Verified (`api_tests/api_test`)
|
|
319
|
-
**User Guide**: [F02](API-RULES/API-FLATTENING.md#f02)
|
|
320
|
-
**Technical**: [C06, C09b](API-RULES/API-RULES-CONDITIONS.md#c06)
|
|
321
|
-
|
|
322
|
-
**Condition**: Category has one module file, module has named exports (no default export), filename ≠ category name
|
|
323
|
-
**Source Files**: `api_tests/api_test/config/settings.mjs`
|
|
324
|
-
**Implementation**: `getFlatteningDecision()` → single module named export flattening
|
|
325
|
-
|
|
326
|
-
**Verified Examples**:
|
|
327
|
-
|
|
328
|
-
```javascript
|
|
329
|
-
// File: api_tests/api_test/config/settings.mjs
|
|
330
|
-
export const DATABASE_URL = "mongodb://localhost:27017/testdb";
|
|
331
|
-
export const API_PORT = 3000;
|
|
332
|
-
export const DEBUG_MODE = true;
|
|
333
|
-
|
|
334
|
-
// Without Rule 7: api.config.settings.DATABASE_URL ❌ (unnecessary nesting)
|
|
335
|
-
// With Rule 7: api.config.DATABASE_URL ✅ (clean flattening)
|
|
336
|
-
api.config.DATABASE_URL; // "mongodb://localhost:27017/testdb"
|
|
337
|
-
api.config.API_PORT; // 3000
|
|
338
|
-
api.config.DEBUG_MODE; // true
|
|
339
|
-
```
|
|
340
|
-
|
|
341
|
-
**Technical Implementation**:
|
|
342
|
-
|
|
343
|
-
- **Primary Condition**: [C06](API-RULES/API-RULES-CONDITIONS.md#c06) - `moduleCount === 1 && !moduleHasDefault && moduleKeys.length > 0`
|
|
344
|
-
- **Processing**: [C09b](API-RULES/API-RULES-CONDITIONS.md#c09b) - `flattenToCategory: true`
|
|
345
|
-
|
|
346
|
-
---
|
|
347
|
-
|
|
348
|
-
## Rule 8: Single Module Default Export Promotion
|
|
349
|
-
|
|
350
|
-
**Category**: Basic Flattening
|
|
351
|
-
**Status**: ✅ Verified (`api_tests/api_test`)
|
|
352
|
-
**User Guide**: [F03](API-RULES/API-FLATTENING.md#f03)
|
|
353
|
-
**Technical**: [C07, C09c](API-RULES/API-RULES-CONDITIONS.md#c07)
|
|
354
|
-
|
|
355
|
-
**Condition**: Category has one module file with a default export
|
|
356
|
-
**Source Files**: `api_tests/api_test/logger.mjs`
|
|
357
|
-
**Implementation**: `getFlatteningDecision()` → single module default export promotion
|
|
358
|
-
|
|
359
|
-
**Verified Examples**:
|
|
360
|
-
|
|
361
|
-
```javascript
|
|
362
|
-
// File: api_tests/api_test/logger.mjs
|
|
363
|
-
export default function logger(message) {
|
|
364
|
-
console.log(`[LOG] ${message}`);
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// Without Rule 8: api.logger.logger("Hello World") ❌ (redundant nesting)
|
|
368
|
-
// With Rule 8: api.logger("Hello World") ✅ (direct callable)
|
|
369
|
-
api.logger("Hello World"); // [LOG] Hello World
|
|
370
|
-
typeof api.logger; // "function"
|
|
371
|
-
```
|
|
372
|
-
|
|
373
|
-
**Callable Namespace Pattern**: When a folder contains a file matching the folder name with a default export (e.g. `logger/logger.mjs`), the default function becomes the namespace itself. Other files in the folder become properties on that function:
|
|
374
|
-
|
|
375
|
-
```javascript
|
|
376
|
-
// File: logger/logger.mjs → export default function log()
|
|
377
|
-
// File: logger/utils.mjs → named exports
|
|
378
|
-
api.logger("message"); // calls the default function
|
|
379
|
-
api.logger.utils.debug("x"); // other files remain as namespace properties
|
|
380
|
-
```
|
|
381
|
-
|
|
382
|
-
This pattern applies consistently at root level and category level.
|
|
383
|
-
|
|
384
|
-
**Technical Implementation**:
|
|
385
|
-
|
|
386
|
-
- **Primary Condition**: [C07](API-RULES/API-RULES-CONDITIONS.md#c07) - `moduleCount === 1 && moduleHasDefault`
|
|
387
|
-
- **Processing**: [C09c](API-RULES/API-RULES-CONDITIONS.md#c09c) - `promoteToCategory: true`
|
|
388
|
-
|
|
389
|
-
---
|
|
390
|
-
|
|
391
|
-
## Rule 9: Function Name Preference Over Sanitization
|
|
392
|
-
|
|
393
|
-
**Category**: Special Cases
|
|
394
|
-
**Status**: ✅ Fully Verified (autoIP, parseJSON, getHTTPStatus, XMLParser)
|
|
395
|
-
**User Guide**: [API-RULES/API-FLATTENING.md - Name Preservation](API-RULES/API-FLATTENING.md)
|
|
396
|
-
**Technical**: [C16, C19](API-RULES/API-RULES-CONDITIONS.md#c16)
|
|
397
|
-
|
|
398
|
-
**Condition**: Exported function has an explicit name that differs from the sanitized filename
|
|
399
|
-
**Behavior**: Preserve the original function name over the filename-based API path
|
|
400
|
-
|
|
401
|
-
**Verified Examples**:
|
|
402
|
-
|
|
403
|
-
```javascript
|
|
404
|
-
// File: auto-ip.mjs
|
|
405
|
-
export function autoIP() { /* Get automatic IP */ }
|
|
406
|
-
// Sanitized filename: "autoIp" ❌
|
|
407
|
-
// Function name: "autoIP" ✅
|
|
408
|
-
|
|
409
|
-
// File: get-http-status.mjs
|
|
410
|
-
export function getHTTPStatus() { /* ... */ }
|
|
411
|
-
// Sanitized filename: "getHttpStatus" ❌
|
|
412
|
-
// Function name: "getHTTPStatus" ✅
|
|
413
|
-
|
|
414
|
-
// File: parse-json.mjs
|
|
415
|
-
export function parseJSON(data) { /* ... */ }
|
|
416
|
-
// Sanitized filename: "parseJson" ❌
|
|
417
|
-
// Function name: "parseJSON" ✅
|
|
418
|
-
```
|
|
419
|
-
|
|
420
|
-
**Technical Implementation**:
|
|
421
|
-
|
|
422
|
-
- **Primary Check**: [C16](API-RULES/API-RULES-CONDITIONS.md#c16) - `exportedFunctionName !== sanitizedName`
|
|
423
|
-
- **Detailed Check**: [C19](API-RULES/API-RULES-CONDITIONS.md#c19) - `exportedFunction.name !== sanitizedFileName`
|
|
424
|
-
- **Precedence**: Function name takes precedence over filename in API structure
|
|
425
|
-
|
|
426
|
-
**Common Preserved Patterns**:
|
|
427
|
-
|
|
428
|
-
- Technical acronyms: IP, HTTP, API, URL, JSON, XML, HTML
|
|
429
|
-
- Protocol names: TCP, UDP, FTP, SSH, SSL, TLS
|
|
430
|
-
- Format specs: JSON, XML, CSV, YAML, TOML
|
|
431
|
-
- Industry standards: OAuth, JWT, REST, GraphQL
|
|
432
|
-
|
|
433
|
-
---
|
|
434
|
-
|
|
435
|
-
## Rule 10: Generic Filename Parent-Level Promotion
|
|
436
|
-
|
|
437
|
-
**Category**: Special Cases
|
|
438
|
-
**Status**: ✅ Verified (`api_tests/api_test/nest4/singlefile.mjs`)
|
|
439
|
-
**User Guide**: [API-RULES/API-FLATTENING.md - Index File Pattern](API-RULES/API-FLATTENING.md)
|
|
440
|
-
**Technical**: [C17](API-RULES/API-RULES-CONDITIONS.md#c17)
|
|
441
|
-
|
|
442
|
-
**Condition**: File has a generic name (`index`, `main`, `default`, etc.)
|
|
443
|
-
**Behavior**: Generic filename becomes transparent; content is promoted to the meaningful parent name
|
|
444
|
-
|
|
445
|
-
**Verified Examples**:
|
|
446
|
-
|
|
447
|
-
```javascript
|
|
448
|
-
// File: database/main.mjs
|
|
449
|
-
export function connect() { /* ... */ }
|
|
450
|
-
export function query() { /* ... */ }
|
|
451
|
-
|
|
452
|
-
// Without Rule 10: api.database.main.connect() ❌ (generic 'main' adds no value)
|
|
453
|
-
// With Rule 10: api.database.connect() ✅ (promoted to parent level)
|
|
454
|
-
|
|
455
|
-
// File: auth/index.mjs
|
|
456
|
-
export function login() { /* ... */ }
|
|
457
|
-
export function logout() { /* ... */ }
|
|
458
|
-
|
|
459
|
-
// Without Rule 10: api.auth.index.login() ❌ (generic 'index' is noise)
|
|
460
|
-
// With Rule 10: api.auth.login() ✅ (clean parent-level promotion)
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
**Technical Implementation**:
|
|
464
|
-
|
|
465
|
-
- **Detection**: [C17](API-RULES/API-RULES-CONDITIONS.md#c17) - `isGenericFilename(fileName)`
|
|
466
|
-
- **Promotion**: Content promoted to parent namespace; generic filename becomes invisible
|
|
467
|
-
|
|
468
|
-
**Note**: Promotion is guarded against name collisions - checked against existing parent namespace properties before promoting.
|
|
469
|
-
|
|
470
|
-
---
|
|
471
|
-
|
|
472
|
-
## Rule 11: AddApi Special File Pattern
|
|
473
|
-
|
|
474
|
-
**Category**: AddApi
|
|
475
|
-
**Status**: ✅ Verified (`api_tests/api_smart_flatten_addapi`)
|
|
476
|
-
**User Guide**: [F06](API-RULES/API-FLATTENING.md#f06)
|
|
477
|
-
**Technical**: [C33](API-RULES/API-RULES-CONDITIONS.md#c33)
|
|
478
|
-
|
|
479
|
-
**Condition**: A file named `addapi.mjs` is loaded via `api.slothlet.api.add()`
|
|
480
|
-
**Behavior**: Exports are always flattened to the mount namespace regardless of other settings
|
|
481
|
-
**Processing Path**: Detection in `getFlatteningDecision()` (`src/lib/processors/flatten.mjs`); execution in `src/lib/builders/modes-processor.mjs`
|
|
482
|
-
|
|
483
|
-
**Verified Example**:
|
|
484
|
-
|
|
485
|
-
```javascript
|
|
486
|
-
// File: plugin-folder/addapi.mjs
|
|
487
|
-
export function initializePlugin() { /* ... */ }
|
|
488
|
-
export function cleanup() { /* ... */ }
|
|
489
|
-
export function configure() { /* ... */ }
|
|
490
|
-
|
|
491
|
-
await api.slothlet.api.add("plugins", "./plugin-folder");
|
|
492
|
-
|
|
493
|
-
// addapi.mjs exports are always flattened - never nested:
|
|
494
|
-
api.plugins.initializePlugin(); // ✅
|
|
495
|
-
api.plugins.cleanup(); // ✅
|
|
496
|
-
api.plugins.configure(); // ✅
|
|
497
|
-
// NOT: api.plugins.addapi.initializePlugin() ❌
|
|
498
|
-
```
|
|
499
|
-
|
|
500
|
-
**Technical Implementation**:
|
|
501
|
-
|
|
502
|
-
```javascript
|
|
503
|
-
// C33: AddApi Special File Detection
|
|
504
|
-
if (moduleKeys.includes("addapi")) {
|
|
505
|
-
const addapiModule = newModules["addapi"];
|
|
506
|
-
const otherModules = { ...newModules };
|
|
507
|
-
delete otherModules["addapi"];
|
|
508
|
-
modulesToMerge = { ...addapiModule, ...otherModules };
|
|
509
|
-
}
|
|
510
|
-
```
|
|
511
|
-
|
|
512
|
-
**Use Cases**:
|
|
513
|
-
|
|
514
|
-
- Plugin systems that extend the API at a known namespace
|
|
515
|
-
- Hot-reloadable API extension points
|
|
516
|
-
- Clean integration of external modules into a live API surface
|
|
517
|
-
|
|
518
|
-
---
|
|
519
|
-
|
|
520
|
-
## Rule 12: Module Ownership and Selective API Overwriting
|
|
521
|
-
|
|
522
|
-
**Category**: AddApi
|
|
523
|
-
**Status**: ✅ Implemented (`src/lib/handlers/ownership.mjs`)
|
|
524
|
-
**User Guide**: [F07](API-RULES/API-FLATTENING.md#f07)
|
|
525
|
-
**Technical**: [C19-C22](API-RULES/API-RULES-CONDITIONS.md#c19)
|
|
526
|
-
|
|
527
|
-
**Purpose**: Track which module registered each API path, enabling safe hot-reloading and cross-module conflict protection.
|
|
528
|
-
|
|
529
|
-
**Implementation**: Stack-based ownership system. Each API path maintains an independent ownership history stack. Removing a module automatically rolls back to the previous owner. Collision behavior is controlled by the `api.collision` configuration.
|
|
530
|
-
|
|
531
|
-
### Configuration
|
|
532
|
-
|
|
533
|
-
```javascript
|
|
534
|
-
const api = await slothlet({
|
|
535
|
-
dir: "./api",
|
|
536
|
-
api: {
|
|
537
|
-
collision: {
|
|
538
|
-
initial: "merge", // During initial API build
|
|
539
|
-
api: "replace" // During api.slothlet.api.add()
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
});
|
|
543
|
-
```
|
|
544
|
-
|
|
545
|
-
### moduleId Tracking
|
|
546
|
-
|
|
547
|
-
Each `api.slothlet.api.add()` call accepts an optional `moduleId`. This is the key for ownership tracking:
|
|
548
|
-
|
|
549
|
-
```javascript
|
|
550
|
-
// Module A registers plugins namespace
|
|
551
|
-
await api.slothlet.api.add("plugins.moduleA", "./modules/moduleA", {}, {
|
|
552
|
-
moduleId: "moduleA"
|
|
553
|
-
});
|
|
554
|
-
|
|
555
|
-
// Module B registers in the same parent namespace
|
|
556
|
-
await api.slothlet.api.add("plugins.moduleB", "./modules/moduleB", {}, {
|
|
557
|
-
moduleId: "moduleB"
|
|
558
|
-
});
|
|
559
|
-
|
|
560
|
-
// Hot-reload Module A - ownership system allows this because moduleA owns these paths
|
|
561
|
-
await api.slothlet.api.add("plugins.moduleA", "./modules/moduleA-v2", {}, {
|
|
562
|
-
moduleId: "moduleA",
|
|
563
|
-
forceOverwrite: true
|
|
564
|
-
});
|
|
565
|
-
|
|
566
|
-
// Cross-module overwrite - blocked if collision mode is "error"
|
|
567
|
-
await api.slothlet.api.add("plugins.moduleB", "./modules/other", {}, {
|
|
568
|
-
moduleId: "moduleA", // moduleA does not own moduleB's paths
|
|
569
|
-
forceOverwrite: true // Throws OWNERSHIP_CONFLICT in "error" mode
|
|
570
|
-
});
|
|
571
|
-
```
|
|
572
|
-
|
|
573
|
-
### Ownership Stack
|
|
574
|
-
|
|
575
|
-
Each API path has a history stack. When a module is removed, the previous owner is automatically restored:
|
|
576
|
-
|
|
577
|
-
```javascript
|
|
578
|
-
// Stack for "plugins.tools": [module-a, module-b] (module-b is current owner)
|
|
579
|
-
await api.slothlet.api.remove("module-b");
|
|
580
|
-
// Stack restored to: [module-a] (module-a is active again)
|
|
581
|
-
```
|
|
582
|
-
|
|
583
|
-
### Collision Modes
|
|
584
|
-
|
|
585
|
-
| Mode | Behavior |
|
|
586
|
-
| ---- | -------- |
|
|
587
|
-
| `"merge"` (default) | Preserve existing properties, add new ones |
|
|
588
|
-
| `"merge-replace"` | Add new properties, overwrite existing |
|
|
589
|
-
| `"replace"` | Completely replace the existing value |
|
|
590
|
-
| `"skip"` | Keep existing value, silently ignore new |
|
|
591
|
-
| `"warn"` | Keep existing value, log a warning |
|
|
592
|
-
| `"error"` | Throw `OWNERSHIP_CONFLICT` error |
|
|
593
|
-
|
|
594
|
-
### forceOverwrite
|
|
595
|
-
|
|
596
|
-
`forceOverwrite: true` requires an explicit `moduleId` and performs a complete replacement regardless of collision mode. Use for cases where a module must fully replace its own prior registration:
|
|
597
|
-
|
|
598
|
-
```javascript
|
|
599
|
-
await api.slothlet.api.add("config", "./new-config", {}, {
|
|
600
|
-
moduleId: "config-v2",
|
|
601
|
-
forceOverwrite: true
|
|
602
|
-
});
|
|
603
|
-
```
|
|
604
|
-
|
|
605
|
-
**Source Code**: `src/lib/handlers/ownership.mjs`
|
|
606
|
-
|
|
607
|
-
---
|
|
608
|
-
|
|
609
|
-
## Rule 13: AddApi Path Deduplication Flattening
|
|
610
|
-
|
|
611
|
-
> **New in v3**
|
|
612
|
-
|
|
613
|
-
**Category**: AddApi
|
|
614
|
-
**Status**: ✅ Implemented (`api_tests/smart_flatten/api_smart_flatten_folder_config`)
|
|
615
|
-
**User Guide**: [F08](API-RULES/API-FLATTENING.md#f08)
|
|
616
|
-
**Technical**: [C34](API-RULES/API-RULES-CONDITIONS.md#c34)
|
|
617
|
-
|
|
618
|
-
**Purpose**: When `api.slothlet.api.add("config", folder)` is called and the folder contains a subfolder whose name matches the last segment of the mount path (e.g. `config/config.mjs`), prevent double-nesting `api.config.config.*` by hoisting the subfolder's exports up to `api.config.*`.
|
|
619
|
-
|
|
620
|
-
**Condition**: After `buildAPI` returns `newApi`, if `newApi` contains a key equal to `lastPart` (last segment of `normalizedPath`) AND the matching value's `filePath` has its parent directory equal to `resolvedFolderPath/lastPart` (direct child check), hoist that key's own exports to the same level as the other keys in `newApi` and remove the duplicate key.
|
|
621
|
-
|
|
622
|
-
**Verified Example**:
|
|
623
|
-
|
|
624
|
-
```javascript
|
|
625
|
-
// Folder structure: api_smart_flatten_folder_config/
|
|
626
|
-
// main.mjs ← exports getRootInfo, setRootConfig
|
|
627
|
-
// config/
|
|
628
|
-
// config.mjs ← exports getNestedConfig, setNestedConfig
|
|
629
|
-
|
|
630
|
-
await api.slothlet.api.add("config", "./api_smart_flatten_folder_config", {});
|
|
631
|
-
|
|
632
|
-
// Without Rule 13 (double-nested):
|
|
633
|
-
api.config.config.getNestedConfig(); // ❌
|
|
634
|
-
|
|
635
|
-
// With Rule 13 (hoisted):
|
|
636
|
-
api.config.getNestedConfig(); // ✅ subfolder exports promoted
|
|
637
|
-
api.config.setNestedConfig(); // ✅
|
|
638
|
-
api.config.main.getRootInfo(); // ✅ other files unaffected
|
|
639
|
-
```
|
|
640
|
-
|
|
641
|
-
**Guard - `isDirectChild`**: Rule 13 only fires when the matching key's `filePath` is **directly** inside `resolvedFolderPath/lastPart`. This prevents false positives when a deeper nested folder coincidentally shares the mount-path name:
|
|
642
|
-
|
|
643
|
-
```javascript
|
|
644
|
-
// Should NOT hoist (services/services/services.mjs):
|
|
645
|
-
// api.add("services", folder) → newApi has key "services"
|
|
646
|
-
// but filePath = .../services/services/services.mjs
|
|
647
|
-
// dirname = .../services/services ≠ resolvedFolderPath/services
|
|
648
|
-
// → Rule 13 does NOT fire
|
|
649
|
-
// → api.services.services.getNestedService remains properly nested ✅
|
|
650
|
-
```
|
|
651
|
-
|
|
652
|
-
**Implementation**: `src/lib/handlers/api-manager.mjs` - immediately after `buildAPI` call, before `setValueAtPath`
|
|
653
|
-
|
|
654
|
-
---
|
|
655
|
-
|
|
656
|
-
## Verification Status
|
|
657
|
-
|
|
658
|
-
| Rule | Title | Status | Test Source |
|
|
659
|
-
| ---- | ---------------------------------------------- | ------------ | ----------- |
|
|
660
|
-
| 1 | Filename Matches Container Flattening | ✅ Verified | `api_tests/api_test` |
|
|
661
|
-
| 2 | Named-Only Export Collection | ✅ Verified | `api_tests/api_test` |
|
|
662
|
-
| 3 | Empty Module Handling | ✅ Verified | debug testing |
|
|
663
|
-
| 4 | Named Export with Function Name Preservation | ✅ Verified | `api_tests/api_test`, `api_tests/api_tv_test` |
|
|
664
|
-
| 5 | Multiple Module Default Export Handling | ✅ Verified | `api_tests/api_tv_test` |
|
|
665
|
-
| 6 | Multiple Module Mixed Exports | ✅ Verified | `api_tests/api_test_mixed` |
|
|
666
|
-
| 7 | Single Module Named Export Flattening | ✅ Verified | `api_tests/api_test` |
|
|
667
|
-
| 8 | Single Module Default Export Promotion | ✅ Verified | Multiple test files |
|
|
668
|
-
| 9 | Function Name Preference Over Sanitization | ✅ Verified | autoIP, parseJSON, getHTTPStatus, XMLParser |
|
|
669
|
-
| 10 | Generic Filename Parent-Level Promotion | ✅ Verified | `api_tests/api_test/nest4/singlefile.mjs` |
|
|
670
|
-
| 11 | AddApi Special File Pattern | ✅ Verified | `api_tests/api_smart_flatten_addapi` |
|
|
671
|
-
| 12 | Module Ownership and Selective API Overwriting | ✅ Verified | `src/lib/handlers/ownership.mjs` |
|
|
672
|
-
| 13 | AddApi Path Deduplication Flattening | ✅ Verified | `api_tests/smart_flatten/api_smart_flatten_folder_config` |
|
|
673
|
-
|
|
674
|
-
---
|
|
675
|
-
|
|
676
|
-
## Cross-Reference Index
|
|
677
|
-
|
|
678
|
-
### By Flattening Pattern (F##)
|
|
679
|
-
|
|
680
|
-
| Flattening Pattern | API Rules | Technical Conditions |
|
|
681
|
-
| ------------------ | --------- | -------------------- |
|
|
682
|
-
| [F01](API-RULES/API-FLATTENING.md#f01) | Rule 1 | [C05, C09b, C11](API-RULES/API-RULES-CONDITIONS.md#c05) |
|
|
683
|
-
| [F02](API-RULES/API-FLATTENING.md#f02) | Rule 8 (Pattern A) | [C12, C21a](API-RULES/API-RULES-CONDITIONS.md#c12) |
|
|
684
|
-
| [F03](API-RULES/API-FLATTENING.md#f03) | Rule 7 | [C04, C09a, C18, C21c, C30](API-RULES/API-RULES-CONDITIONS.md#c04) |
|
|
685
|
-
| [F04](API-RULES/API-FLATTENING.md#f04) | Rule 4, Rule 8 (Pattern B) | [C08c, C24](API-RULES/API-RULES-CONDITIONS.md#c08c) |
|
|
686
|
-
| [F05](API-RULES/API-FLATTENING.md#f05) | Rule 4, Rule 8 (Pattern C) | [C08c, C11](API-RULES/API-RULES-CONDITIONS.md#c08c) |
|
|
687
|
-
| [F06](API-RULES/API-FLATTENING.md#f06) | Rule 11 | [C33](API-RULES/API-RULES-CONDITIONS.md#c33) |
|
|
688
|
-
| [F07](API-RULES/API-FLATTENING.md#f07) | Rule 12 | [C19-C22](API-RULES/API-RULES-CONDITIONS.md#c19) |
|
|
689
|
-
| [F08](API-RULES/API-FLATTENING.md#f08) | Rule 13 | [C34](API-RULES/API-RULES-CONDITIONS.md#c34) |
|
|
690
|
-
|
|
691
|
-
### By Technical Condition (C##)
|
|
692
|
-
|
|
693
|
-
| Condition | API Rules | Flattening Patterns |
|
|
694
|
-
| --------- | --------- | ------------------- |
|
|
695
|
-
| [C01-C07](API-RULES/API-RULES-CONDITIONS.md#c01) | Rules 1, 6, 7, 8 | F01, F03 |
|
|
696
|
-
| [C08-C09d](API-RULES/API-RULES-CONDITIONS.md#c08) | Rules 4, 6, 7 | F04, F05 |
|
|
697
|
-
| [C10-C21d](API-RULES/API-RULES-CONDITIONS.md#c10) | Rules 1, 2, 3, 5, 7, 8, 9, 10 | F01, F02, F03 |
|
|
698
|
-
| [C22-C26](API-RULES/API-RULES-CONDITIONS.md#c22) | Rules 4, 6 | F04, F05 |
|
|
699
|
-
| [C27-C32](API-RULES/API-RULES-CONDITIONS.md#c27) | Rules 5, 6, 7 | Multi-default scenarios |
|
|
700
|
-
| [C33](API-RULES/API-RULES-CONDITIONS.md#c33) | Rule 11 | F06 |
|
|
701
|
-
| [C34](API-RULES/API-RULES-CONDITIONS.md#c34) | Rule 13 | F08 |
|
|
702
|
-
|
|
703
|
-
### By Processing Context
|
|
704
|
-
|
|
705
|
-
| Context | Rules | Primary Conditions |
|
|
706
|
-
| ------- | ----- | ------------------ |
|
|
707
|
-
| **Single-File Directories** | 1, 7, 8, 10 | C11, C12, C04, C17 |
|
|
708
|
-
| **Multi-File Directories** | 1, 2, 5, 7, 9 | C13, C15, C21a-d, C16, C19 |
|
|
709
|
-
| **Multi-Default Scenarios** | 5, 6, 7 | C02, C03, C27-C32 |
|
|
710
|
-
| **AddApi Operations** | 11, 12, 13 | C33, C34, C19-C22 |
|
|
711
|
-
| **Root-Level Processing** | 4, 8, 10 | C08c, C22, C17 |
|
|
712
|
-
| **Subfolder Processing** | 4, 6, 8 | C08d, C20, C24 |
|