@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
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
# Slothlet Source Code Conditions Reference
|
|
2
|
+
|
|
3
|
+
**Reference Document for All API Generation Conditional Logic**
|
|
4
|
+
|
|
5
|
+
- **Commit ID**: `a50531d1ba712f0c4efd9ab9b7cf8f62a0d379da`
|
|
6
|
+
- **Date**: December 30, 2025
|
|
7
|
+
- **Purpose**: Complete traceability of all conditional statements that control slothlet API structure generation
|
|
8
|
+
- **Status**: ? **CURRENT AND ACCURATE**
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Overview
|
|
13
|
+
|
|
14
|
+
This document catalogs every conditional statement in slothlet's API generation system. Each condition is numbered (C01, C02, etc.) with exact line numbers and direct links to source code.
|
|
15
|
+
|
|
16
|
+
**Core Decision Functions:**
|
|
17
|
+
|
|
18
|
+
- [`getFlatteningDecision()`](#getflatteningdecision-conditions) - 4 rules controlling when modules flatten
|
|
19
|
+
- [`processModuleForAPI()`](#processmoduleforapi-conditions) - 9 conditions for module processing
|
|
20
|
+
- [`buildCategoryDecisions()`](#buildcategorydecisions-conditions) - 11 decisions for directory structure
|
|
21
|
+
- [`buildCategoryStructure()`](#buildcategorystructure-conditions) - 6 structural assembly conditions
|
|
22
|
+
- [`multidefault_getFlatteningDecision()`](#multidefault_getflatteningdecision-conditions) - 4 multi-default rules
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Table of Contents
|
|
27
|
+
|
|
28
|
+
1. [getFlatteningDecision() Conditions](#getflatteningdecision-conditions) (4 rules)
|
|
29
|
+
2. [processModuleForAPI() Conditions](#processmoduleforapi-conditions) (9 conditions)
|
|
30
|
+
3. [buildCategoryDecisions() Conditions](#buildcategorydecisions-conditions) (11 decisions)
|
|
31
|
+
4. [buildCategoryStructure() Conditions](#buildcategorystructure-conditions) (6 structural)
|
|
32
|
+
5. [multidefault_getFlatteningDecision() Conditions](#multidefault_getflatteningdecision-conditions) (4 rules)
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## getFlatteningDecision() Conditions
|
|
37
|
+
|
|
38
|
+
**File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L87-L189)
|
|
39
|
+
**Function**: `getFlatteningDecision(options)`
|
|
40
|
+
**Lines**: [87-189](../src/lib/helpers/api_builder/decisions.mjs#L87-L189)
|
|
41
|
+
|
|
42
|
+
This function determines whether and how to flatten module exports to avoid unnecessary nesting.
|
|
43
|
+
|
|
44
|
+
### C01: Self-Referential Check
|
|
45
|
+
|
|
46
|
+
**Line**: [105](../src/lib/helpers/api_builder/decisions.mjs#L105)
|
|
47
|
+
**Condition**: `if (isSelfReferential)`
|
|
48
|
+
**Purpose**: Self-referential exports (where filename matches an exported property) never flatten to avoid infinite nesting
|
|
49
|
+
**Result**: `shouldFlatten: false, preserveAsNamespace: true`
|
|
50
|
+
**Reason**: `"self-referential export"`
|
|
51
|
+
|
|
52
|
+
**Example**: `math.mjs` exports `{ math: { add, subtract } }` → preserves as namespace to avoid circular structure
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
### C02: Multi-Default Context With Default Export
|
|
57
|
+
|
|
58
|
+
**Line**: [117](../src/lib/helpers/api_builder/decisions.mjs#L117)
|
|
59
|
+
**Condition**: `if (hasMultipleDefaultExports)` → [118](../src/lib/helpers/api_builder/decisions.mjs#L118): `if (moduleHasDefault)`
|
|
60
|
+
**Purpose**: In multi-default context, modules WITH default exports are preserved as namespaces to avoid conflicts
|
|
61
|
+
**Result**: `shouldFlatten: false, preserveAsNamespace: true`
|
|
62
|
+
**Reason**: `"multi-default context with default export"`
|
|
63
|
+
|
|
64
|
+
**Example**: Folder has 3 files with default exports → each keeps namespace to prevent collision
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
### C03: Multi-Default Context Without Default Export
|
|
69
|
+
|
|
70
|
+
**Line**: [117](../src/lib/helpers/api_builder/decisions.mjs#L117) → [129](../src/lib/helpers/api_builder/decisions.mjs#L129): `else`
|
|
71
|
+
**Condition**: `if (hasMultipleDefaultExports)` → `else` (when !moduleHasDefault)
|
|
72
|
+
**Purpose**: In multi-default context, modules WITHOUT default exports flatten to avoid empty namespaces
|
|
73
|
+
**Result**: `shouldFlatten: true, flattenToRoot: true, flattenToCategory: true`
|
|
74
|
+
**Reason**: `"multi-default context without default export"`
|
|
75
|
+
|
|
76
|
+
**Example**: Folder has mix of default/named exports → named-only files flatten to category level
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
### C04: Auto-Flatten Single Named Export Matching Filename
|
|
81
|
+
|
|
82
|
+
**Line**: [142](../src/lib/helpers/api_builder/decisions.mjs#L142)
|
|
83
|
+
**Condition**: `if (moduleKeys.length === 1 && moduleKeys[0] === apiPathKey)`
|
|
84
|
+
**Purpose**: When module exports single named export matching filename, use the export directly
|
|
85
|
+
**Result**: `shouldFlatten: true, useAutoFlattening: true`
|
|
86
|
+
**Reason**: `"auto-flatten single named export matching filename"`
|
|
87
|
+
|
|
88
|
+
**Example**: `math.mjs` exports `{ math: { add } }` → becomes `api.math.add()` not `api.math.math.add()`
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
### C05: Filename Matches Container (Category-Level Flatten)
|
|
93
|
+
|
|
94
|
+
**Line**: [154](../src/lib/helpers/api_builder/decisions.mjs#L154)
|
|
95
|
+
**Condition**: `if (categoryName && fileName === categoryName && !moduleHasDefault && moduleKeys.length > 0)`
|
|
96
|
+
**Purpose**: When filename matches folder name and has named exports but no default, flatten to category level
|
|
97
|
+
**Result**: `shouldFlatten: true, flattenToCategory: true`
|
|
98
|
+
**Reason**: `"filename matches container, flatten to category"`
|
|
99
|
+
|
|
100
|
+
**Example**: `math/math.mjs` with named exports → flattens to `api.math.add()` not `api.math.math.add()`
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
### C06: Single File Context (COMMENTED OUT)
|
|
105
|
+
|
|
106
|
+
**Lines**: [169-182](../src/lib/helpers/api_builder/decisions.mjs#L169-L182)
|
|
107
|
+
**Status**: ?? **DISABLED** - Commented out in current code
|
|
108
|
+
**Original Purpose**: Flatten single-file folders with named exports only
|
|
109
|
+
**Comment**: "This rule reduces API path flexibility. If users want flattening, they can use other rules like naming the file to match the folder."
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
### C07: Default Fallback - Preserve as Namespace
|
|
114
|
+
|
|
115
|
+
**Line**: [184](../src/lib/helpers/api_builder/decisions.mjs#L184)
|
|
116
|
+
**Condition**: Default case (no conditions matched)
|
|
117
|
+
**Purpose**: Traditional namespace preservation when no flattening rules apply
|
|
118
|
+
**Result**: `shouldFlatten: false, preserveAsNamespace: true`
|
|
119
|
+
**Reason**: `"traditional namespace preservation"`
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## processModuleForAPI() Conditions
|
|
124
|
+
|
|
125
|
+
**File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L315-L466)
|
|
126
|
+
**Function**: `processModuleForAPI(options)`
|
|
127
|
+
**Lines**: [315-466](../src/lib/helpers/api_builder/decisions.mjs#L315-L466)
|
|
128
|
+
|
|
129
|
+
This function processes individual modules and determines how they integrate into the API structure.
|
|
130
|
+
|
|
131
|
+
### C08: Has Default Function Export
|
|
132
|
+
|
|
133
|
+
**Line**: [345](../src/lib/helpers/api_builder/decisions.mjs#L345)
|
|
134
|
+
**Condition**: `if (hasDefaultFunction)`
|
|
135
|
+
**Purpose**: Handles modules that export functions as default (either direct function or mod.default function)
|
|
136
|
+
**Branches**: 3 major sub-conditions (C08a, C08b, C08c)
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
#### C08a: Multi-Default Function (Non-Self-Referential)
|
|
141
|
+
|
|
142
|
+
**Line**: [351](../src/lib/helpers/api_builder/decisions.mjs#L351)
|
|
143
|
+
**Condition**: `if (hasMultipleDefaultExports && !isSelfReferential)`
|
|
144
|
+
**Purpose**: In multi-default context, function defaults use filename as API key to avoid conflicts
|
|
145
|
+
**Result**: `apiAssignments[apiPathKey] = mod, namespaced = true`
|
|
146
|
+
|
|
147
|
+
**Example**: Multiple files with function defaults → each uses filename as namespace key
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
#### C08b: Self-Referential Function
|
|
152
|
+
|
|
153
|
+
**Line**: [361](../src/lib/helpers/api_builder/decisions.mjs#L361)
|
|
154
|
+
**Condition**: `else if (isSelfReferential)`
|
|
155
|
+
**Purpose**: Self-referential function exports preserve as namespace
|
|
156
|
+
**Result**: `apiAssignments[apiPathKey] = mod, namespaced = true`
|
|
157
|
+
|
|
158
|
+
**Example**: `logger.mjs` exports function with `logger` property → preserves namespace structure
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
#### C08c: Traditional Default Function - Root API
|
|
163
|
+
|
|
164
|
+
**Line**: [378](../src/lib/helpers/api_builder/decisions.mjs#L378)
|
|
165
|
+
**Condition**: `if (mode === "root" && getRootDefault && setRootDefault && !hasMultipleDefaultExports && !getRootDefault())`
|
|
166
|
+
**Purpose**: In root context with no existing root function, set as the callable root API
|
|
167
|
+
**Result**: `setRootDefault(defaultFunction), rootDefaultSet = true`
|
|
168
|
+
|
|
169
|
+
**Example**: Root folder has single default function → API becomes callable: `api()`
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
#### C08d: Function As Namespace (Subfolder Context)
|
|
174
|
+
|
|
175
|
+
**Line**: [387](../src/lib/helpers/api_builder/decisions.mjs#L387)
|
|
176
|
+
**Condition**: `else` (when C08c doesn't apply)
|
|
177
|
+
**Purpose**: In subfolder context or when root already exists, treat function as namespace
|
|
178
|
+
**Result**: `apiAssignments[apiPathKey] = mod, namespaced = true`
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
### C09: Non-Function Modules (Objects/Named Exports)
|
|
183
|
+
|
|
184
|
+
**Line**: [398](../src/lib/helpers/api_builder/decisions.mjs#L398)
|
|
185
|
+
**Condition**: `else` (when !hasDefaultFunction)
|
|
186
|
+
**Purpose**: Handles object exports, named-only exports, and non-function defaults
|
|
187
|
+
**Branches**: 4 sub-conditions based on flattening decision
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
#### C09a: Use Auto-Flattening
|
|
192
|
+
|
|
193
|
+
**Line**: [425](../src/lib/helpers/api_builder/decisions.mjs#L425)
|
|
194
|
+
**Condition**: `if (decision.useAutoFlattening)`
|
|
195
|
+
**Purpose**: Apply auto-flattening decision from getFlatteningDecision()
|
|
196
|
+
**Result**: `apiAssignments[apiPathKey] = mod[moduleKeys[0]], flattened = true`
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
#### C09b: Flatten To Root/Category
|
|
201
|
+
|
|
202
|
+
**Line**: [429](../src/lib/helpers/api_builder/decisions.mjs#L429)
|
|
203
|
+
**Condition**: `else if (decision.flattenToRoot || decision.flattenToCategory)`
|
|
204
|
+
**Purpose**: Merge all named exports into target based on flattening decision
|
|
205
|
+
**Result**: Loop assigns `apiAssignments[key] = mod[key], flattened = true`
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
#### C09c: Self-Referential Non-Function
|
|
210
|
+
|
|
211
|
+
**Line**: [440](../src/lib/helpers/api_builder/decisions.mjs#L440)
|
|
212
|
+
**Condition**: `else if (isSelfReferential)`
|
|
213
|
+
**Purpose**: Self-referential non-function exports use direct property access
|
|
214
|
+
**Result**: `apiAssignments[apiPathKey] = mod[apiPathKey] || mod, namespaced = true`
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
#### C09d: Traditional Namespace Preservation
|
|
219
|
+
|
|
220
|
+
**Line**: [444](../src/lib/helpers/api_builder/decisions.mjs#L444)
|
|
221
|
+
**Condition**: `else`
|
|
222
|
+
**Purpose**: Default behavior preserves module as namespace
|
|
223
|
+
**Result**: `apiAssignments[apiPathKey] = mod, namespaced = true`
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## buildCategoryDecisions() Conditions
|
|
228
|
+
|
|
229
|
+
**File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L505-L899)
|
|
230
|
+
**Function**: `buildCategoryDecisions(categoryPath, options)`
|
|
231
|
+
**Lines**: [505-899](../src/lib/helpers/api_builder/decisions.mjs#L505-L899)
|
|
232
|
+
|
|
233
|
+
Centralized category building decisions - analyzes directories and returns structural decisions.
|
|
234
|
+
|
|
235
|
+
### C10: Single-File Function Folder Match
|
|
236
|
+
|
|
237
|
+
**Line**: [584](../src/lib/helpers/api_builder/decisions.mjs#L584)
|
|
238
|
+
**Condition**: `if (moduleName === categoryName && typeof mod === "function" && currentDepth > 0)`
|
|
239
|
+
**Purpose**: Flatten when filename matches folder name and exports function (not at root level)
|
|
240
|
+
**Result**: `shouldFlatten: true, flattenType: "function-folder-match"`
|
|
241
|
+
|
|
242
|
+
**Example**: `nest/nest.mjs` exports function → becomes `api.nest()` not `api.nest.nest()`
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
### C11: Default Export Flattening (CJS/ESM Uniform)
|
|
247
|
+
|
|
248
|
+
**Line**: [593](../src/lib/helpers/api_builder/decisions.mjs#L593)
|
|
249
|
+
**Condition**: `if (analysis.hasDefault && analysis.defaultExportType === "object" && moduleName === categoryName && currentDepth > 0)`
|
|
250
|
+
**Purpose**: Flatten default object exports when filename matches folder (handles both CJS and ESM uniformly)
|
|
251
|
+
**Result**: `shouldFlatten: true, flattenType: "default-export-flatten"`
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
### C12: Object Auto-Flatten (Single Named Export Match)
|
|
256
|
+
|
|
257
|
+
**Line**: [604](../src/lib/helpers/api_builder/decisions.mjs#L604)
|
|
258
|
+
**Condition**: `if (moduleName === categoryName && mod && typeof mod === "object" && !Array.isArray(mod) && currentDepth > 0)`
|
|
259
|
+
**Sub-condition**: [609](../src/lib/helpers/api_builder/decisions.mjs#L609): `if (moduleKeys.length === 1 && moduleKeys[0] === moduleName)`
|
|
260
|
+
**Purpose**: When single named export matches filename, flatten the object contents
|
|
261
|
+
**Result**: `shouldFlatten: true, flattenType: "object-auto-flatten"`
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
### C13: Filename-Folder Exact Match Flattening
|
|
266
|
+
|
|
267
|
+
**Line**: [619](../src/lib/helpers/api_builder/decisions.mjs#L619)
|
|
268
|
+
**Condition**: `if (fileBaseName === categoryName && moduleKeys.length > 0)`
|
|
269
|
+
**Purpose**: Avoid double nesting when file basename matches folder (e.g., nest/nest.mjs)
|
|
270
|
+
**Result**: `shouldFlatten: true, flattenType: "filename-folder-match-flatten"`
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
### C14: Parent-Level Flattening (Generic Filenames)
|
|
275
|
+
|
|
276
|
+
**Line**: [641](../src/lib/helpers/api_builder/decisions.mjs#L641)
|
|
277
|
+
**Condition**: `if (moduleFiles.length === 1 && currentDepth > 0 && mod && typeof mod === "object" && !Array.isArray(mod))`
|
|
278
|
+
**Sub-condition**: [649](../src/lib/helpers/api_builder/decisions.mjs#L649): `if (moduleKeys.length === 1 && isGenericFilename)`
|
|
279
|
+
**Purpose**: Eliminate intermediate namespace for generic filenames (singlefile, index, main, default)
|
|
280
|
+
**Result**: `shouldFlatten: true, flattenType: "parent-level-flatten"`
|
|
281
|
+
|
|
282
|
+
**Example**: `nest4/singlefile.mjs` → `api.nest4.beta()` not `api.nest4.singlefile.beta()`
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
### C15: Function Name Matches Folder
|
|
287
|
+
|
|
288
|
+
**Line**: [663](../src/lib/helpers/api_builder/decisions.mjs#L663)
|
|
289
|
+
**Condition**: `if (functionNameMatchesFolder && currentDepth > 0)`
|
|
290
|
+
**Purpose**: Flatten when function name matches folder name (case-insensitive), prefer function name
|
|
291
|
+
**Result**: `shouldFlatten: true, flattenType: "function-folder-match", preferredName: mod.name`
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
### C16: Function Name Matches Filename (Name Preference)
|
|
296
|
+
|
|
297
|
+
**Line**: [671](../src/lib/helpers/api_builder/decisions.mjs#L671)
|
|
298
|
+
**Condition**: `if (functionNameMatchesFilename)`
|
|
299
|
+
**Purpose**: Use original function name instead of sanitized filename when they match semantically
|
|
300
|
+
**Result**: `shouldFlatten: false, preferredName: mod.name`
|
|
301
|
+
|
|
302
|
+
**Example**: `auto-ip.mjs` exports `autoIP` function → uses `autoIP` not `autoIp`
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
### C17: Default Function Export
|
|
307
|
+
|
|
308
|
+
**Line**: [680](../src/lib/helpers/api_builder/decisions.mjs#L680)
|
|
309
|
+
**Condition**: `if (typeof mod === "function" && (!mod.name || mod.name === "default" || mod.__slothletDefault === true) && currentDepth > 0)`
|
|
310
|
+
**Purpose**: Flatten functions marked as default exports (not at root level)
|
|
311
|
+
**Result**: `shouldFlatten: true, flattenType: "default-function"`
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
### C18: Single Named Export Match (Secondary Check)
|
|
316
|
+
|
|
317
|
+
**Line**: [693](../src/lib/helpers/api_builder/decisions.mjs#L693)
|
|
318
|
+
**Condition**: `if (moduleKeys.length === 1 && moduleKeys[0] === moduleName)`
|
|
319
|
+
**Purpose**: Auto-flatten when module exports single named export matching filename
|
|
320
|
+
**Result**: `shouldFlatten: true, flattenType: "object-auto-flatten"`
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
### C19: Multi-File Function with Preferred Name
|
|
325
|
+
|
|
326
|
+
**Line**: [844](../src/lib/helpers/api_builder/decisions.mjs#L844)
|
|
327
|
+
**Condition**: `if (hasPreferredName)` (from function name preference logic)
|
|
328
|
+
**Purpose**: Use original function names over sanitized filenames when they match semantically
|
|
329
|
+
**Result**: `specialHandling: "preferred-export-names"`
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
### C20: Multi-File Self-Referential
|
|
334
|
+
|
|
335
|
+
**Line**: [846](../src/lib/helpers/api_builder/decisions.mjs#L846)
|
|
336
|
+
**Condition**: `else if (selfReferentialFiles.has(moduleName))`
|
|
337
|
+
**Purpose**: Self-referential files in multi-file context get special namespace handling
|
|
338
|
+
**Result**: `type: "self-referential"`
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
### C21: Multi-File Flattening Scenarios
|
|
343
|
+
|
|
344
|
+
**Line**: [753](../src/lib/helpers/api_builder/decisions.mjs#L753)
|
|
345
|
+
**Condition**: `else` (standard multi-file processing)
|
|
346
|
+
**Sub-conditions**: 4 flattening scenarios (C21a-C21d)
|
|
347
|
+
|
|
348
|
+
#### C21a: Single Default Object
|
|
349
|
+
|
|
350
|
+
**Line**: [859](../src/lib/helpers/api_builder/decisions.mjs#L859)
|
|
351
|
+
**Condition**: `if (!hasMultipleDefaultExports && mod.default && typeof mod.default === "object")`
|
|
352
|
+
**Result**: `shouldFlatten: true, flattenType: "single-default-object"`
|
|
353
|
+
|
|
354
|
+
#### C21b: Multi-Default No Default
|
|
355
|
+
|
|
356
|
+
**Line**: [863](../src/lib/helpers/api_builder/decisions.mjs#L863)
|
|
357
|
+
**Condition**: `else if (hasMultipleDefaultExports && !mod.default && moduleKeys.length > 0)`
|
|
358
|
+
**Result**: `shouldFlatten: true, flattenType: "multi-default-no-default"`
|
|
359
|
+
|
|
360
|
+
#### C21c: Single Named Export Match
|
|
361
|
+
|
|
362
|
+
**Line**: [867](../src/lib/helpers/api_builder/decisions.mjs#L867)
|
|
363
|
+
**Condition**: `else if (moduleKeys.length === 1 && moduleKeys[0] === apiPathKey)`
|
|
364
|
+
**Result**: `shouldFlatten: true, flattenType: "single-named-export-match"`
|
|
365
|
+
|
|
366
|
+
#### C21d: Category Name Match Flatten
|
|
367
|
+
|
|
368
|
+
**Line**: [873](../src/lib/helpers/api_builder/decisions.mjs#L873)
|
|
369
|
+
**Condition**: `else if (!mod.default && moduleKeys.length > 0 && moduleName === categoryName)`
|
|
370
|
+
**Result**: `shouldFlatten: true, flattenType: "category-name-match-flatten"`
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
## buildCategoryStructure() Conditions
|
|
375
|
+
|
|
376
|
+
**File**: [`src/lib/helpers/api_builder/construction.mjs`](../src/lib/helpers/api_builder/construction.mjs#L125-L555)
|
|
377
|
+
**Function**: `buildCategoryStructure(categoryPath, options)`
|
|
378
|
+
**Lines**: [125-555](../src/lib/helpers/api_builder/construction.mjs#L125-L555)
|
|
379
|
+
|
|
380
|
+
Assembles the actual API structure based on decisions from buildCategoryDecisions().
|
|
381
|
+
|
|
382
|
+
### C22: Single-File Flattening Cases
|
|
383
|
+
|
|
384
|
+
**Line**: [145](../src/lib/helpers/api_builder/construction.mjs#L145)
|
|
385
|
+
**Condition**: `if (decisions.shouldFlatten)`
|
|
386
|
+
**Purpose**: Apply flattening decisions to single-file cases
|
|
387
|
+
**Branches**: 5 flatten types handled via switch statement [146-175](../src/lib/helpers/api_builder/construction.mjs#L146-L175)
|
|
388
|
+
|
|
389
|
+
### C23: Single-File Preferred Name (No Flatten)
|
|
390
|
+
|
|
391
|
+
**Line**: [180](../src/lib/helpers/api_builder/construction.mjs#L180)
|
|
392
|
+
**Condition**: `if (decisions.preferredName && decisions.preferredName !== moduleName)`
|
|
393
|
+
**Purpose**: Use preferred name without flattening
|
|
394
|
+
**Result**: `return { [decisions.preferredName]: mod }`
|
|
395
|
+
|
|
396
|
+
### C24: Category Merge Special Handling
|
|
397
|
+
|
|
398
|
+
**Line**: [195](../src/lib/helpers/api_builder/construction.mjs#L195)
|
|
399
|
+
**Condition**: `if (specialHandling === "category-merge")`
|
|
400
|
+
**Purpose**: Merge logic when module filename matches category name
|
|
401
|
+
**Result**: Merges module contents into categoryModules
|
|
402
|
+
|
|
403
|
+
### C25: Multi-File Flattening
|
|
404
|
+
|
|
405
|
+
**Line**: [217](../src/lib/helpers/api_builder/construction.mjs#L217)
|
|
406
|
+
**Condition**: `if (shouldFlatten)`
|
|
407
|
+
**Purpose**: Apply various flattening strategies in multi-file context
|
|
408
|
+
**Branches**: Switch statement handling 4 flatten types [218-318](../src/lib/helpers/api_builder/construction.mjs#L218-L318)
|
|
409
|
+
|
|
410
|
+
**Special Case - Double Proxy Layer**: [245-290](../src/lib/helpers/api_builder/construction.mjs#L245-L290)
|
|
411
|
+
When Proxy assignment fails, creates wrapper proxy to ensure API completeness while preserving original proxy behavior
|
|
412
|
+
|
|
413
|
+
### C26: Upward Flattening (Single Key Matching Category)
|
|
414
|
+
|
|
415
|
+
**Line**: [384](../src/lib/helpers/api_builder/construction.mjs#L384)
|
|
416
|
+
**Condition**: `if (keys.length === 1)`
|
|
417
|
+
**Sub-condition**: [386](../src/lib/helpers/api_builder/construction.mjs#L386): `if (singleKey === categoryName)`
|
|
418
|
+
**Purpose**: When category contains single key matching category name, flatten upward
|
|
419
|
+
**Result**: Return contents directly, avoiding redundant nesting
|
|
420
|
+
|
|
421
|
+
---
|
|
422
|
+
|
|
423
|
+
## multidefault_getFlatteningDecision() Conditions
|
|
424
|
+
|
|
425
|
+
**File**: [`src/lib/helpers/multidefault.mjs`](../src/lib/helpers/multidefault.mjs#L178-L262)
|
|
426
|
+
**Function**: `multidefault_getFlatteningDecision(options)`
|
|
427
|
+
**Lines**: [178-262](../src/lib/helpers/multidefault.mjs#L178-L262)
|
|
428
|
+
|
|
429
|
+
Specialized flattening logic for multi-default export contexts.
|
|
430
|
+
|
|
431
|
+
### C27: Multi-Default Self-Referential
|
|
432
|
+
|
|
433
|
+
**Line**: [199](../src/lib/helpers/multidefault.mjs#L199)
|
|
434
|
+
**Condition**: `if (isSelfReferential)`
|
|
435
|
+
**Purpose**: Self-referential default exports in multi-default context preserve as namespace
|
|
436
|
+
**Result**: `shouldFlatten: false, preserveAsNamespace: true`
|
|
437
|
+
**Reason**: `"self-referential default export"`
|
|
438
|
+
|
|
439
|
+
### C28: Multi-Default With Default Export
|
|
440
|
+
|
|
441
|
+
**Line**: [202](../src/lib/helpers/multidefault.mjs#L202)
|
|
442
|
+
**Condition**: `if (hasMultipleDefaultExports)` → [203](../src/lib/helpers/multidefault.mjs#L203): `if (moduleHasDefault)`
|
|
443
|
+
**Purpose**: Modules WITH default exports in multi-default context preserve as namespaces
|
|
444
|
+
**Result**: `shouldFlatten: false, preserveAsNamespace: true`
|
|
445
|
+
**Reason**: `"multi-default context with default export"`
|
|
446
|
+
|
|
447
|
+
### C29: Multi-Default Without Default Export
|
|
448
|
+
|
|
449
|
+
**Line**: [209](../src/lib/helpers/multidefault.mjs#L209) ? [219](../src/lib/helpers/multidefault.mjs#L219): `else`
|
|
450
|
+
**Condition**: `if (hasMultipleDefaultExports)` → `else` (when !moduleHasDefault)
|
|
451
|
+
**Purpose**: Modules WITHOUT default exports in multi-default context flatten to root
|
|
452
|
+
**Result**: `shouldFlatten: true, flattenToRoot: true`
|
|
453
|
+
**Reason**: `"multi-default context without default export"`
|
|
454
|
+
|
|
455
|
+
### C30: Single Named Export Match
|
|
456
|
+
|
|
457
|
+
**Line**: [227](../src/lib/helpers/multidefault.mjs#L227)
|
|
458
|
+
**Condition**: `if (moduleKeys.length === 1 && moduleKeys[0] === apiPathKey)`
|
|
459
|
+
**Purpose**: Single named export matching filename in multi-default context
|
|
460
|
+
**Result**: `shouldFlatten: true, flattenToRoot: false`
|
|
461
|
+
**Reason**: `"single named export matching filename"`
|
|
462
|
+
|
|
463
|
+
### C31: Single File No Default (Commented Out)
|
|
464
|
+
|
|
465
|
+
**Lines**: [238-247](../src/lib/helpers/multidefault.mjs#L238-L247)
|
|
466
|
+
**Status**: ⚠️ **DISABLED** - Commented out
|
|
467
|
+
**Original Purpose**: Flatten single file with named exports only in multi-default context
|
|
468
|
+
|
|
469
|
+
### C32: Default Namespace Preservation
|
|
470
|
+
|
|
471
|
+
**Line**: [250](../src/lib/helpers/multidefault.mjs#L250)
|
|
472
|
+
**Condition**: Default case
|
|
473
|
+
**Purpose**: Preserve as namespace when no multi-default flattening rules apply
|
|
474
|
+
**Result**: `shouldFlatten: false, preserveAsNamespace: true`
|
|
475
|
+
**Reason**: `"default namespace preservation"`
|
|
476
|
+
|
|
477
|
+
---
|
|
478
|
+
|
|
479
|
+
## Summary
|
|
480
|
+
|
|
481
|
+
**Total Active Conditions**: 32 documented conditions (2 commented out: C06, C31)
|
|
482
|
+
**Primary Functions**: 5 key functions containing API generation logic
|
|
483
|
+
**File Locations**: 3 source files across api_builder/ and multidefault.mjs
|
|
484
|
+
|
|
485
|
+
### Condition Categories
|
|
486
|
+
|
|
487
|
+
- **Flattening Rules** (7): C01-C07
|
|
488
|
+
- **Module Processing** (9): C08-C09d
|
|
489
|
+
- **Category Decisions** (13): C10-C21d
|
|
490
|
+
- **Structural Assembly** (5): C22-C26
|
|
491
|
+
- **Multi-Default Logic** (6): C27-C32
|
|
492
|
+
|
|
493
|
+
### Key Architectural Patterns
|
|
494
|
+
|
|
495
|
+
1. **Self-Referential Protection**: Multiple conditions (C01, C08b, C09c, C20, C27) prevent circular structures
|
|
496
|
+
2. **Multi-Default Coordination**: Specialized handling (C02, C03, C08a, C21b, C28, C29) prevents naming conflicts
|
|
497
|
+
3. **Smart Flattening**: Auto-detection (C04, C05, C12, C13, C18, C30) reduces unnecessary nesting
|
|
498
|
+
4. **Name Preservation**: Function name preference (C16, C19) maintains semantic meaning
|
|
499
|
+
5. **Depth Awareness**: Many conditions check `currentDepth > 0` to preserve root-level structure
|
|
500
|
+
|
|
501
|
+
---
|
|
502
|
+
|
|
503
|
+
## Document Maintenance
|
|
504
|
+
|
|
505
|
+
**Last Full Audit**: December 30, 2025
|
|
506
|
+
**Commit**: a50531d1ba712f0c4efd9ab9b7cf8f62a0d379da
|
|
507
|
+
**Lines Verified**: All line numbers manually verified against source code
|
|
508
|
+
**Links**: All GitHub-style links use `#Lxxx-Lyyy` format for precise navigation
|