@cldmv/slothlet 2.11.0 → 3.0.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.
Files changed (189) hide show
  1. package/AGENT-USAGE.md +355 -325
  2. package/README.md +554 -238
  3. package/dist/lib/builders/api-assignment.mjs +605 -0
  4. package/dist/lib/builders/api_builder.mjs +1073 -0
  5. package/dist/lib/builders/builder.mjs +94 -0
  6. package/dist/lib/builders/modes-processor.mjs +1816 -0
  7. package/dist/lib/errors.mjs +227 -0
  8. package/dist/lib/factories/component-base.mjs +96 -0
  9. package/dist/lib/factories/context.mjs +38 -0
  10. package/dist/lib/handlers/api-cache-manager.mjs +216 -0
  11. package/dist/lib/handlers/api-manager.mjs +2364 -0
  12. package/dist/lib/handlers/context-async.mjs +184 -0
  13. package/dist/lib/handlers/context-live.mjs +184 -0
  14. package/dist/lib/handlers/hook-manager.mjs +789 -0
  15. package/dist/lib/handlers/lifecycle-token.mjs +44 -0
  16. package/dist/lib/handlers/lifecycle.mjs +131 -0
  17. package/dist/lib/handlers/materialize-manager.mjs +64 -0
  18. package/dist/lib/handlers/metadata.mjs +500 -0
  19. package/dist/lib/handlers/ownership.mjs +338 -0
  20. package/dist/lib/handlers/unified-wrapper.mjs +3031 -0
  21. package/dist/lib/helpers/class-instance-wrapper.mjs +125 -0
  22. package/dist/lib/helpers/config.mjs +343 -0
  23. package/dist/lib/helpers/eventemitter-context.mjs +365 -0
  24. package/dist/lib/helpers/hint-detector.mjs +63 -0
  25. package/dist/lib/helpers/modes-utils.mjs +53 -0
  26. package/dist/lib/helpers/resolve-from-caller.mjs +119 -116
  27. package/dist/lib/helpers/sanitize.mjs +247 -168
  28. package/dist/lib/helpers/utilities.mjs +46 -81
  29. package/dist/lib/i18n/languages/de-de.json +377 -0
  30. package/dist/lib/i18n/languages/en-gb.json +377 -0
  31. package/dist/lib/i18n/languages/en-us.json +377 -0
  32. package/dist/lib/i18n/languages/es-mx.json +377 -0
  33. package/dist/lib/i18n/languages/fr-fr.json +377 -0
  34. package/dist/lib/i18n/languages/hi-in.json +377 -0
  35. package/dist/lib/i18n/languages/ja-jp.json +377 -0
  36. package/dist/lib/i18n/languages/ko-kr.json +377 -0
  37. package/dist/lib/i18n/languages/pt-br.json +377 -0
  38. package/dist/lib/i18n/languages/ru-ru.json +377 -0
  39. package/dist/lib/i18n/languages/zh-cn.json +377 -0
  40. package/dist/lib/i18n/translations.mjs +140 -0
  41. package/dist/lib/modes/eager.mjs +75 -0
  42. package/dist/lib/modes/lazy.mjs +97 -0
  43. package/dist/lib/processors/flatten.mjs +453 -0
  44. package/dist/lib/processors/loader.mjs +355 -0
  45. package/dist/lib/processors/type-generator.mjs +291 -0
  46. package/dist/lib/processors/typescript.mjs +188 -0
  47. package/dist/lib/runtime/runtime-asynclocalstorage.mjs +80 -522
  48. package/dist/lib/runtime/runtime-livebindings.mjs +45 -390
  49. package/dist/lib/runtime/runtime.mjs +39 -159
  50. package/dist/slothlet.mjs +525 -744
  51. package/docs/API-RULES.md +338 -486
  52. package/index.cjs +4 -4
  53. package/index.mjs +82 -45
  54. package/package.json +138 -25
  55. package/types/dist/lib/builders/api-assignment.d.mts +97 -0
  56. package/types/dist/lib/builders/api-assignment.d.mts.map +1 -0
  57. package/types/dist/lib/builders/api_builder.d.mts +96 -0
  58. package/types/dist/lib/builders/api_builder.d.mts.map +1 -0
  59. package/types/dist/lib/builders/builder.d.mts +60 -0
  60. package/types/dist/lib/builders/builder.d.mts.map +1 -0
  61. package/types/dist/lib/builders/modes-processor.d.mts +32 -0
  62. package/types/dist/lib/builders/modes-processor.d.mts.map +1 -0
  63. package/types/dist/lib/errors.d.mts +118 -0
  64. package/types/dist/lib/errors.d.mts.map +1 -0
  65. package/types/dist/lib/factories/component-base.d.mts +182 -0
  66. package/types/dist/lib/factories/component-base.d.mts.map +1 -0
  67. package/types/dist/lib/factories/context.d.mts +26 -0
  68. package/types/dist/lib/factories/context.d.mts.map +1 -0
  69. package/types/dist/lib/handlers/api-cache-manager.d.mts +208 -0
  70. package/types/dist/lib/handlers/api-cache-manager.d.mts.map +1 -0
  71. package/types/dist/lib/handlers/api-manager.d.mts +392 -0
  72. package/types/dist/lib/handlers/api-manager.d.mts.map +1 -0
  73. package/types/dist/lib/handlers/context-async.d.mts +66 -0
  74. package/types/dist/lib/handlers/context-async.d.mts.map +1 -0
  75. package/types/dist/lib/handlers/context-live.d.mts +65 -0
  76. package/types/dist/lib/handlers/context-live.d.mts.map +1 -0
  77. package/types/dist/lib/handlers/hook-manager.d.mts +199 -0
  78. package/types/dist/lib/handlers/hook-manager.d.mts.map +1 -0
  79. package/types/dist/lib/handlers/lifecycle-token.d.mts +49 -0
  80. package/types/dist/lib/handlers/lifecycle-token.d.mts.map +1 -0
  81. package/types/dist/lib/handlers/lifecycle.d.mts +90 -0
  82. package/types/dist/lib/handlers/lifecycle.d.mts.map +1 -0
  83. package/types/dist/lib/handlers/materialize-manager.d.mts +75 -0
  84. package/types/dist/lib/handlers/materialize-manager.d.mts.map +1 -0
  85. package/types/dist/lib/handlers/metadata.d.mts +215 -0
  86. package/types/dist/lib/handlers/metadata.d.mts.map +1 -0
  87. package/types/dist/lib/handlers/ownership.d.mts +170 -0
  88. package/types/dist/lib/handlers/ownership.d.mts.map +1 -0
  89. package/types/dist/lib/handlers/unified-wrapper.d.mts +250 -0
  90. package/types/dist/lib/handlers/unified-wrapper.d.mts.map +1 -0
  91. package/types/dist/lib/helpers/class-instance-wrapper.d.mts +54 -0
  92. package/types/dist/lib/helpers/class-instance-wrapper.d.mts.map +1 -0
  93. package/types/dist/lib/helpers/config.d.mts +96 -0
  94. package/types/dist/lib/helpers/config.d.mts.map +1 -0
  95. package/types/dist/lib/helpers/eventemitter-context.d.mts +31 -0
  96. package/types/dist/lib/helpers/eventemitter-context.d.mts.map +1 -0
  97. package/types/dist/lib/helpers/hint-detector.d.mts +20 -0
  98. package/types/dist/lib/helpers/hint-detector.d.mts.map +1 -0
  99. package/types/dist/lib/helpers/modes-utils.d.mts +35 -0
  100. package/types/dist/lib/helpers/modes-utils.d.mts.map +1 -0
  101. package/types/dist/lib/helpers/resolve-from-caller.d.mts +29 -145
  102. package/types/dist/lib/helpers/resolve-from-caller.d.mts.map +1 -1
  103. package/types/dist/lib/helpers/sanitize.d.mts +95 -94
  104. package/types/dist/lib/helpers/sanitize.d.mts.map +1 -1
  105. package/types/dist/lib/helpers/utilities.d.mts +53 -116
  106. package/types/dist/lib/helpers/utilities.d.mts.map +1 -1
  107. package/types/dist/lib/i18n/translations.d.mts +39 -0
  108. package/types/dist/lib/i18n/translations.d.mts.map +1 -0
  109. package/types/dist/lib/modes/eager.d.mts +36 -0
  110. package/types/dist/lib/modes/eager.d.mts.map +1 -0
  111. package/types/dist/lib/modes/lazy.d.mts +49 -0
  112. package/types/dist/lib/modes/lazy.d.mts.map +1 -0
  113. package/types/dist/lib/processors/flatten.d.mts +114 -0
  114. package/types/dist/lib/processors/flatten.d.mts.map +1 -0
  115. package/types/dist/lib/processors/loader.d.mts +47 -0
  116. package/types/dist/lib/processors/loader.d.mts.map +1 -0
  117. package/types/dist/lib/processors/type-generator.d.mts +19 -0
  118. package/types/dist/lib/processors/type-generator.d.mts.map +1 -0
  119. package/types/dist/lib/processors/typescript.d.mts +55 -0
  120. package/types/dist/lib/processors/typescript.d.mts.map +1 -0
  121. package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts +47 -42
  122. package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts.map +1 -1
  123. package/types/dist/lib/runtime/runtime-livebindings.d.mts +34 -65
  124. package/types/dist/lib/runtime/runtime-livebindings.d.mts.map +1 -1
  125. package/types/dist/lib/runtime/runtime.d.mts +39 -9
  126. package/types/dist/lib/runtime/runtime.d.mts.map +1 -1
  127. package/types/dist/slothlet.d.mts +184 -111
  128. package/types/dist/slothlet.d.mts.map +1 -1
  129. package/types/index.d.mts +1 -3
  130. package/dist/lib/engine/README.md +0 -21
  131. package/dist/lib/engine/slothlet_child.mjs +0 -59
  132. package/dist/lib/engine/slothlet_engine.mjs +0 -372
  133. package/dist/lib/engine/slothlet_esm.mjs +0 -230
  134. package/dist/lib/engine/slothlet_helpers.mjs +0 -455
  135. package/dist/lib/engine/slothlet_worker.mjs +0 -149
  136. package/dist/lib/helpers/als-eventemitter.mjs +0 -256
  137. package/dist/lib/helpers/api_builder/add_api.mjs +0 -553
  138. package/dist/lib/helpers/api_builder/analysis.mjs +0 -532
  139. package/dist/lib/helpers/api_builder/construction.mjs +0 -495
  140. package/dist/lib/helpers/api_builder/decisions.mjs +0 -748
  141. package/dist/lib/helpers/api_builder/metadata.mjs +0 -248
  142. package/dist/lib/helpers/api_builder.mjs +0 -41
  143. package/dist/lib/helpers/auto-wrap.mjs +0 -62
  144. package/dist/lib/helpers/hooks.mjs +0 -389
  145. package/dist/lib/helpers/instance-manager.mjs +0 -111
  146. package/dist/lib/helpers/metadata-api.mjs +0 -201
  147. package/dist/lib/helpers/multidefault.mjs +0 -216
  148. package/dist/lib/modes/slothlet_eager.mjs +0 -154
  149. package/dist/lib/modes/slothlet_lazy.mjs +0 -594
  150. package/docs/API-RULES-CONDITIONS.md +0 -712
  151. package/types/dist/lib/engine/slothlet_child.d.mts +0 -2
  152. package/types/dist/lib/engine/slothlet_child.d.mts.map +0 -1
  153. package/types/dist/lib/engine/slothlet_engine.d.mts +0 -31
  154. package/types/dist/lib/engine/slothlet_engine.d.mts.map +0 -1
  155. package/types/dist/lib/engine/slothlet_esm.d.mts +0 -19
  156. package/types/dist/lib/engine/slothlet_esm.d.mts.map +0 -1
  157. package/types/dist/lib/engine/slothlet_helpers.d.mts +0 -25
  158. package/types/dist/lib/engine/slothlet_helpers.d.mts.map +0 -1
  159. package/types/dist/lib/engine/slothlet_worker.d.mts +0 -2
  160. package/types/dist/lib/engine/slothlet_worker.d.mts.map +0 -1
  161. package/types/dist/lib/helpers/als-eventemitter.d.mts +0 -56
  162. package/types/dist/lib/helpers/als-eventemitter.d.mts.map +0 -1
  163. package/types/dist/lib/helpers/api_builder/add_api.d.mts +0 -102
  164. package/types/dist/lib/helpers/api_builder/add_api.d.mts.map +0 -1
  165. package/types/dist/lib/helpers/api_builder/analysis.d.mts +0 -189
  166. package/types/dist/lib/helpers/api_builder/analysis.d.mts.map +0 -1
  167. package/types/dist/lib/helpers/api_builder/construction.d.mts +0 -107
  168. package/types/dist/lib/helpers/api_builder/construction.d.mts.map +0 -1
  169. package/types/dist/lib/helpers/api_builder/decisions.d.mts +0 -213
  170. package/types/dist/lib/helpers/api_builder/decisions.d.mts.map +0 -1
  171. package/types/dist/lib/helpers/api_builder/metadata.d.mts +0 -99
  172. package/types/dist/lib/helpers/api_builder/metadata.d.mts.map +0 -1
  173. package/types/dist/lib/helpers/api_builder.d.mts +0 -6
  174. package/types/dist/lib/helpers/api_builder.d.mts.map +0 -1
  175. package/types/dist/lib/helpers/auto-wrap.d.mts +0 -49
  176. package/types/dist/lib/helpers/auto-wrap.d.mts.map +0 -1
  177. package/types/dist/lib/helpers/hooks.d.mts +0 -342
  178. package/types/dist/lib/helpers/hooks.d.mts.map +0 -1
  179. package/types/dist/lib/helpers/instance-manager.d.mts +0 -41
  180. package/types/dist/lib/helpers/instance-manager.d.mts.map +0 -1
  181. package/types/dist/lib/helpers/metadata-api.d.mts +0 -132
  182. package/types/dist/lib/helpers/metadata-api.d.mts.map +0 -1
  183. package/types/dist/lib/helpers/multidefault.d.mts +0 -90
  184. package/types/dist/lib/helpers/multidefault.d.mts.map +0 -1
  185. package/types/dist/lib/modes/slothlet_eager.d.mts +0 -65
  186. package/types/dist/lib/modes/slothlet_eager.d.mts.map +0 -1
  187. package/types/dist/lib/modes/slothlet_lazy.d.mts +0 -31
  188. package/types/dist/lib/modes/slothlet_lazy.d.mts.map +0 -1
  189. package/types/index.d.mts.map +0 -1
@@ -1,712 +0,0 @@
1
- # Slothlet Source Code Conditions Reference (v2)
2
-
3
- **Complete Traceability Document for All API Generation Conditional Logic**
4
-
5
- - **Version**: 2.0
6
- - **Date**: January 3, 2026
7
- - **Purpose**: Foundation documentation mapping every conditional statement in slothlet API generation to exact source code locations
8
- - **Status**: ✅ **VERIFIED AND CURRENT** - All conditions verified against actual source code
9
- - **Cross-Reference Support**: Provides technical foundation for [API-RULES-v2.md](API-RULES-v2.md) and [API-FLATTENING-v2.md](API-FLATTENING-v2.md)
10
-
11
- ---
12
-
13
- ## Document Hierarchy
14
-
15
- This is the **foundation level** of slothlet's three-tier documentation system:
16
-
17
- ```text
18
- 📋 API-FLATTENING-v2.md (F##) ← User Guide: "How flattening works"
19
- ↓ references
20
- 📊 API-RULES-v2.md (1-12) ← Maintainer Guide: "All API behaviors"
21
- ↓ references
22
- 🔧 API-RULES-CONDITIONS-v2.md ← Developer/Debug Guide: "Exact code locations"
23
- ```
24
-
25
- **Numbering System**: This document uses **C##** (C01, C02, etc.) for all conditions to avoid confusion with the other files' numbering systems.
26
-
27
- ---
28
-
29
- ## Overview
30
-
31
- This document catalogs every conditional statement in slothlet's API generation system. Each condition provides:
32
-
33
- - **Exact line numbers** and source file locations
34
- - **Direct GitHub-style links** for precise code navigation
35
- - **Input parameters** and **result values** for debugging
36
- - **Cross-references** to higher-level rules that use these conditions
37
- - **Examples** showing the condition in action
38
-
39
- **Architecture Pattern**: The API generation system uses 3 core functions with 18 conditional statements that determine how file structures become API surfaces.
40
-
41
- ---
42
-
43
- ## Core Decision Functions Summary
44
-
45
- | Function | File | Conditions | Purpose |
46
- | -------------------------- | ------------------------------------------------------------- | ---------- | ------------------------------ |
47
- | `getFlatteningDecision()` | [decisions.mjs](../src/lib/helpers/api_builder/decisions.mjs) | C01-C07 | Basic flattening rules |
48
- | `processModuleForAPI()` | [decisions.mjs](../src/lib/helpers/api_builder/decisions.mjs) | C08-C09b | Module-level processing |
49
- | `buildCategoryDecisions()` | [decisions.mjs](../src/lib/helpers/api_builder/decisions.mjs) | C10-C18 | Single-file directory handling |
50
-
51
- ---
52
-
53
- ## Table of Contents
54
-
55
- 1. [C01: Self-Referential Check](#c01-self-referential-check)
56
- 2. [C02: Multi-Default Context With Default Export](#c02-multi-default-context-with-default-export)
57
- 3. [C03: Multi-Default Context Without Default Export](#c03-multi-default-context-without-default-export)
58
- 4. [C04: Auto-Flatten Single Named Export Matching Filename](#c04-auto-flatten-single-named-export-matching-filename)
59
- 5. [C05: Filename Matches Container (Category-Level Flatten)](#c05-filename-matches-container-category-level-flatten)
60
- 6. [C06: Single File Context (COMMENTED OUT)](#c06-single-file-context-commented-out)
61
- 7. [C07: Default Fallback - Preserve as Namespace](#c07-default-fallback---preserve-as-namespace)
62
- 8. [C08: Auto-Flattening](#c08-auto-flattening)
63
- 9. [C09: Flatten To Root/Category](#c09-flatten-to-rootcategory)
64
- 10. [C09a: Self-Referential Non-Function](#c09a-self-referential-non-function)
65
- 11. [C09b: Traditional Namespace Preservation](#c09b-traditional-namespace-preservation)
66
- 12. [C10: Single-File Function Folder Match](#c10-single-file-function-folder-match)
67
- 13. [C11: Default Export Flattening](#c11-default-export-flattening)
68
- 14. [C12: Object Auto-Flatten](#c12-object-auto-flatten)
69
- 15. [C13: Filename-Folder Exact Match Flattening](#c13-filename-folder-exact-match-flattening)
70
- 16. [C14: Parent-Level Flattening (Generic Filenames)](#c14-parent-level-flattening-generic-filenames)
71
- 17. [C15: Function Name Matches Folder](#c15-function-name-matches-folder)
72
- 18. [C16: Function Name Preference](#c16-function-name-preference)
73
- 19. [C17: Default Function Export Flattening](#c17-default-function-export-flattening)
74
- 20. [C18: Object Auto-Flatten (Final Check)](#c18-object-auto-flatten-final-check)
75
- 21. [Cross-Reference Index](#cross-reference-index)
76
-
77
- ---
78
-
79
- ## C01: Self-Referential Check
80
-
81
- **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L87-L189)
82
- **Function**: `getFlatteningDecision(options)`
83
- **Line**: [100](../src/lib/helpers/api_builder/decisions.mjs#L100)
84
- **Condition**: `if (isSelfReferential)`
85
- **Purpose**: Self-referential exports (where filename matches an exported property) never flatten to avoid infinite nesting
86
- **Input**: `isSelfReferential` (boolean)
87
- **Result**: `{ shouldFlatten: false, preserveAsNamespace: true, reason: "self-referential export" }`
88
- **Used By**: [API-RULES Rule 6](API-RULES-v2.md#rule-6-self-referential-export-protection)
89
-
90
- **Example**:
91
-
92
- ```javascript
93
- // math.mjs exports { math: { add, subtract } }
94
- // → preserves as api.math.math.add() to avoid circular structure
95
- ```
96
-
97
- ---
98
-
99
- ## C02: Multi-Default Context With Default Export
100
-
101
- **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L87-L189)
102
- **Function**: `getFlatteningDecision(options)`
103
- **Line**: [113](../src/lib/helpers/api_builder/decisions.mjs#L113) → [114](../src/lib/helpers/api_builder/decisions.mjs#L114)
104
- **Condition**: `if (hasMultipleDefaultExports) → if (moduleHasDefault)`
105
- **Purpose**: In multi-default context, modules WITH default exports are preserved as namespaces to avoid conflicts
106
- **Input**: `hasMultipleDefaultExports` (boolean), `moduleHasDefault` (boolean)
107
- **Result**: `{ shouldFlatten: false, preserveAsNamespace: true, reason: "multi-default context with default export" }`
108
- **Used By**: [API-RULES Rule 5](API-RULES-v2.md#rule-5-multi-default-export-mixed-pattern)
109
-
110
- **Example**:
111
-
112
- ```javascript
113
- // Folder has 3 files with default exports
114
- // → each keeps namespace to prevent collision
115
- ```
116
-
117
- ---
118
-
119
- ## C03: Multi-Default Context Without Default Export
120
-
121
- **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L87-L189)
122
- **Function**: `getFlatteningDecision(options)`
123
- **Line**: [113](../src/lib/helpers/api_builder/decisions.mjs#L113) → [125](../src/lib/helpers/api_builder/decisions.mjs#L125)
124
- **Condition**: `if (hasMultipleDefaultExports) → else (!moduleHasDefault)`
125
- **Purpose**: In multi-default context, modules WITHOUT default exports flatten to avoid empty namespaces
126
- **Input**: `hasMultipleDefaultExports` (boolean), `moduleHasDefault` (boolean)
127
- **Result**: `{ shouldFlatten: true, flattenToRoot: true, flattenToCategory: true, reason: "multi-default context without default export" }`
128
- **Used By**: [API-RULES Rule 5](API-RULES-v2.md#rule-5-multi-default-export-mixed-pattern)
129
-
130
- **Example**:
131
-
132
- ```javascript
133
- // Folder has mix of default/named exports
134
- // → named-only files flatten to category level
135
- ```
136
-
137
- ---
138
-
139
- ## C04: Auto-Flatten Single Named Export Matching Filename
140
-
141
- **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L87-L189)
142
- **Function**: `getFlatteningDecision(options)`
143
- **Line**: [138](../src/lib/helpers/api_builder/decisions.mjs#L138)
144
- **Condition**: `if (moduleKeys.length === 1 && moduleKeys[0] === apiPathKey)`
145
- **Purpose**: When module exports single named export matching filename, use the export directly
146
- **Input**: `moduleKeys` (array), `apiPathKey` (string)
147
- **Result**: `{ shouldFlatten: true, useAutoFlattening: true, reason: "auto-flatten single named export matching filename" }`
148
- **Used By**: [API-RULES Rule 7](API-RULES-v2.md#rule-7-auto-flattening-single-named-export) | [FLATTENING F03](API-FLATTENING-v2.md#f03)
149
-
150
- **Example**:
151
-
152
- ```javascript
153
- // math.mjs exports { math: { add } }
154
- // → becomes api.math.add() not api.math.math.add()
155
- ```
156
-
157
- ---
158
-
159
- ## C05: Filename Matches Container (Category-Level Flatten)
160
-
161
- **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L87-L189)
162
- **Function**: `getFlatteningDecision(options)`
163
- **Line**: [150](../src/lib/helpers/api_builder/decisions.mjs#L150)
164
- **Condition**: `if (categoryName && fileName === categoryName && !moduleHasDefault && moduleKeys.length > 0)`
165
- **Purpose**: When filename matches folder name and has named exports but no default, flatten to category level
166
- **Input**: `categoryName` (string), `fileName` (string), `moduleHasDefault` (boolean), `moduleKeys` (array)
167
- **Result**: `{ shouldFlatten: true, flattenToCategory: true, reason: "filename matches container, flatten to category" }`
168
- **Used By**: [API-RULES Rule 1](API-RULES-v2.md#rule-1-filename-matches-container-flattening) | [FLATTENING F01](API-FLATTENING-v2.md#f01)
169
-
170
- **Example**:
171
-
172
- ```javascript
173
- // math/math.mjs with named exports
174
- // → becomes api.math.add() not api.math.math.add()
175
- ```
176
-
177
- ---
178
-
179
- ## C06: Single File Context (COMMENTED OUT)
180
-
181
- **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L87-L189)
182
- **Function**: `getFlatteningDecision(options)`
183
- **Line**: [162-170](../src/lib/helpers/api_builder/decisions.mjs#L162-L170) _(commented out)_
184
- **Condition**: `// if (totalModules === 1 && !moduleHasDefault && moduleKeys.length > 0)`
185
- **Purpose**: **INTENTIONALLY DISABLED** - Would flatten single files, but removed for API path flexibility
186
- **Status**: **DEPRECATED** - Architectural decision documented in source comments
187
- **Reason**: "This rule reduces API path flexibility. If users want flattening, they can use other rules like naming the file to match the folder."
188
-
189
- ---
190
-
191
- ## C07: Default Fallback - Preserve as Namespace
192
-
193
- **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L87-L189)
194
- **Function**: `getFlatteningDecision(options)`
195
- **Line**: [174](../src/lib/helpers/api_builder/decisions.mjs#L174)
196
- **Condition**: `else` (default case when no other conditions match)
197
- **Purpose**: When no flattening rules apply, preserve module as namespace
198
- **Input**: All other conditions failed
199
- **Result**: `{ shouldFlatten: false, preserveAsNamespace: true, reason: "traditional namespace preservation" }`
200
- **Used By**: Default behavior for all rules
201
-
202
- **Example**:
203
-
204
- ```javascript
205
- // Complex module structures that don't match flattening patterns
206
- // → preserved with full namespace hierarchy
207
- ```
208
-
209
- ---
210
-
211
- ## C08: Auto-Flattening
212
-
213
- **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L315-L480)
214
- **Function**: `processModuleForAPI(options)`
215
- **Line**: [424](../src/lib/helpers/api_builder/decisions.mjs#L424)
216
- **Condition**: `if (decision.useAutoFlattening)`
217
- **Purpose**: Apply auto-flattening when single named export matches filename
218
- **Input**: `decision.useAutoFlattening` (boolean from getFlatteningDecision)
219
- **Result**: `apiAssignments[apiPathKey] = mod[moduleKeys[0]], flattened = true`
220
- **Used By**: [API-RULES Rule 7](API-RULES-v2.md#rule-7-auto-flattening-single-named-export)
221
-
222
- **Example**:
223
-
224
- ```javascript
225
- // math.mjs exports { math: { add } }
226
- // → auto-flattened to api.math.add()
227
- ```
228
-
229
- ---
230
-
231
- ## C09: Flatten To Root/Category
232
-
233
- **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L315-L480)
234
- **Function**: `processModuleForAPI(options)`
235
- **Line**: [430](../src/lib/helpers/api_builder/decisions.mjs#L430)
236
- **Condition**: `else if (decision.flattenToRoot || decision.flattenToCategory)`
237
- **Purpose**: Merge all named exports into target based on flattening decision
238
- **Input**: `decision.flattenToRoot` or `decision.flattenToCategory` (boolean)
239
- **Processing**: Loop assigns `apiAssignments[key] = mod[key], flattened = true`
240
- **Used By**: [API-RULES Rule 1, 5](API-RULES-v2.md#rule-1-filename-matches-container-flattening)
241
-
242
- **Example**:
243
-
244
- ```javascript
245
- // logger.mjs exports function with properties
246
- // → preserved as api.logger() with api.logger.info
247
- ```
248
-
249
- ---
250
-
251
- ## C09a: Self-Referential Non-Function
252
-
253
- **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L315-L480)
254
- **Function**: `processModuleForAPI(options)`
255
- **Line**: [440](../src/lib/helpers/api_builder/decisions.mjs#L440)
256
- **Condition**: `else if (isSelfReferential)`
257
- **Purpose**: Self-referential non-function exports use direct property access
258
- **Input**: `isSelfReferential` (boolean)
259
- **Result**: `apiAssignments[apiPathKey] = mod[apiPathKey] || mod, namespaced = true`
260
- **Used By**: [API-RULES Rule 6](API-RULES-v2.md#rule-6-self-referential-export-protection)
261
-
262
- ---
263
-
264
- ## C09b: Traditional Namespace Preservation
265
-
266
- **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L315-L480)
267
- **Function**: `processModuleForAPI(options)`
268
- **Line**: [444](../src/lib/helpers/api_builder/decisions.mjs#L444)
269
- **Condition**: `else` (default behavior)
270
- **Purpose**: Default behavior preserves module as namespace
271
- **Input**: All other conditions failed
272
- **Result**: `apiAssignments[apiPathKey] = mod, namespaced = true`
273
- **Used By**: Default behavior for complex modules
274
-
275
- **Example**:
276
-
277
- ```javascript
278
- // math/math.mjs named exports flatten to category level
279
- // → api.math.add(), api.math.subtract()
280
- ```
281
-
282
- ---
283
-
284
- ## C10: Single-File Function Folder Match
285
-
286
- **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L516-L715)
287
- **Function**: `buildCategoryDecisions(categoryPath, options)`
288
- **Line**: [580](../src/lib/helpers/api_builder/decisions.mjs#L580)
289
- **Condition**: `if (moduleName === categoryName && typeof mod === "function" && currentDepth > 0)`
290
- **Purpose**: Flatten when filename matches folder name and exports function (not at root level)
291
- **Input**: `moduleName` (string), `categoryName` (string), `typeof mod` ("function"), `currentDepth > 0`
292
- **Result**: `shouldFlatten: true, flattenType: "function-folder-match"`
293
- **Used By**: [API-RULES Rule 2](API-RULES-v2.md#rule-2-filename-folder-match-flattening)
294
-
295
- ---
296
-
297
- ## C11: Default Export Flattening
298
-
299
- **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L516-L715)
300
- **Function**: `buildCategoryDecisions(categoryPath, options)`
301
- **Line**: [588](../src/lib/helpers/api_builder/decisions.mjs#L588)
302
- **Condition**: `if (analysis.hasDefault && analysis.defaultExportType === "object" && moduleName === categoryName && currentDepth > 0)`
303
- **Purpose**: Flatten default object exports when filename matches folder (handles both CJS and ESM uniformly)
304
- **Input**: `analysis.hasDefault`, `analysis.defaultExportType === "object"`, filename/folder match, not root level
305
- **Result**: `shouldFlatten: true, flattenType: "default-export-flatten"`
306
- **Used By**: [API-RULES Rule 4](API-RULES-v2.md#rule-4-default-export-object-flattening)
307
-
308
- ---
309
-
310
- ## C12: Object Auto-Flatten
311
-
312
- **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L516-L715)
313
- **Function**: `buildCategoryDecisions(categoryPath, options)`
314
- **Line**: [596](../src/lib/helpers/api_builder/decisions.mjs#L596)
315
- **Condition**: `if (moduleName === categoryName && mod && typeof mod === "object" && !Array.isArray(mod) && currentDepth > 0)`
316
- **Sub-condition**: [601](../src/lib/helpers/api_builder/decisions.mjs#L601): `if (moduleKeys.length === 1 && moduleKeys[0] === moduleName)`
317
- **Purpose**: When single named export matches filename, flatten the object contents
318
- **Input**: Filename/category match, object type, single named export matching filename
319
- **Result**: `shouldFlatten: true, flattenType: "object-auto-flatten"`
320
- **Used By**: [API-RULES Rule 7](API-RULES-v2.md#rule-7-auto-flattening-single-named-export)
321
-
322
- ---
323
-
324
- ## C13: Filename-Folder Exact Match Flattening
325
-
326
- **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L516-L715)
327
- **Function**: `buildCategoryDecisions(categoryPath, options)`
328
- **Line**: [611](../src/lib/helpers/api_builder/decisions.mjs#L611)
329
- **Condition**: `if (fileBaseName === categoryName && moduleKeys.length > 0)`
330
- **Purpose**: Avoid double nesting when file basename matches folder (e.g., nest/nest.mjs)
331
- **Input**: `fileBaseName === categoryName` and has named exports
332
- **Result**: `shouldFlatten: true, flattenType: "filename-folder-match-flatten"`
333
- **Used By**: [API-RULES Rule 1, 2](API-RULES-v2.md#rule-1-filename-matches-container-flattening)
334
-
335
- ---
336
-
337
- ## C14: Parent-Level Flattening (Generic Filenames)
338
-
339
- **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L516-L715)
340
- **Function**: `buildCategoryDecisions(categoryPath, options)`
341
- **Line**: [653](../src/lib/helpers/api_builder/decisions.mjs#L653)
342
- **Condition**: `if (moduleFiles.length === 1 && currentDepth > 0 && mod && typeof mod === "object" && !Array.isArray(mod))`
343
- **Sub-condition**: [661](../src/lib/helpers/api_builder/decisions.mjs#L661): `if (moduleKeys.length === 1 && isGenericFilename)`
344
- **Purpose**: Eliminate intermediate namespace for generic filenames (singlefile, index, main, default)
345
- **Input**: Single file, object export, generic filename pattern: `["singlefile", "index", "main", "default"]`
346
- **Result**: `shouldFlatten: true, flattenType: "parent-level-flatten"`
347
- **Used By**: [API-RULES Rule 8](API-RULES-v2.md#rule-8-generic-filename-parent-flattening)
348
-
349
- ---
350
-
351
- ## C15: Function Name Matches Folder
352
-
353
- **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L516-L715)
354
- **Function**: `buildCategoryDecisions(categoryPath, options)`
355
- **Line**: [670](../src/lib/helpers/api_builder/decisions.mjs#L670)
356
- **Condition**: `if (functionNameMatchesFolder && currentDepth > 0)`
357
- **Purpose**: Flatten when function name matches folder name (case-insensitive), prefer function name
358
- **Input**: Function name matches folder name (case-insensitive check), not at root level
359
- **Result**: `shouldFlatten: true, flattenType: "function-folder-match", preferredName: mod.name`
360
- **Used By**: [API-RULES Rule 9](API-RULES-v2.md#rule-9-function-name-preservation)
361
-
362
- ---
363
-
364
- ## C16: Function Name Preference
365
-
366
- **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L516-L715)
367
- **Function**: `buildCategoryDecisions(categoryPath, options)`
368
- **Line**: [678](../src/lib/helpers/api_builder/decisions.mjs#L678)
369
- **Condition**: `if (functionNameMatchesFilename)`
370
- **Purpose**: Use original function name instead of sanitized filename when they match semantically
371
- **Input**: Function name matches filename semantically (case-insensitive, ignores sanitization differences)
372
- **Result**: `shouldFlatten: false, preferredName: mod.name`
373
- **Used By**: [API-RULES Rule 9](API-RULES-v2.md#rule-9-function-name-preservation)
374
-
375
- ---
376
-
377
- ## C17: Default Function Export Flattening
378
-
379
- **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L516-L715)
380
- **Function**: `buildCategoryDecisions(categoryPath, options)`
381
- **Line**: [687](../src/lib/helpers/api_builder/decisions.mjs#L687)
382
- **Condition**: `if (typeof mod === "function" && (!mod.name || mod.name === "default" || mod.__slothletDefault === true) && currentDepth > 0)`
383
- **Purpose**: Flatten functions marked as default exports (not at root level)
384
- **Input**: Function with no name, "default" name, or marked as default export
385
- **Result**: `shouldFlatten: true, flattenType: "default-function", preferredName: categoryName`
386
- **Used By**: [API-RULES Rule 4](API-RULES-v2.md#rule-4-default-export-object-flattening)
387
-
388
- ---
389
-
390
- ## C18: Object Auto-Flatten (Final Check)
391
-
392
- **File**: [`src/lib/helpers/api_builder/decisions.mjs`](../src/lib/helpers/api_builder/decisions.mjs#L516-L715)
393
- **Function**: `buildCategoryDecisions(categoryPath, options)`
394
- **Line**: [704](../src/lib/helpers/api_builder/decisions.mjs#L704)
395
- **Condition**: `if (moduleKeys.length === 1 && moduleKeys[0] === moduleName)`
396
- **Purpose**: Auto-flatten when module has single named export matching filename (final check for single-file case)
397
- **Input**: Single named export with name matching module name
398
- **Result**: `shouldFlatten: true, flattenType: "object-auto-flatten", preferredName: moduleName`
399
- **Used By**: [API-RULES Rule 7](API-RULES-v2.md#rule-7-auto-flattening-single-named-export)
400
-
401
- ---
402
-
403
- ## Cross-Reference Index
404
-
405
- **By Rule Number**:
406
-
407
- **By Rule Number**:
408
-
409
- - **Rule 1**: [C05](#c05-filename-matches-container-category-level-flatten), [C09](#c09-flatten-to-rootcategory), [C13](#c13-filename-folder-exact-match-flattening)
410
- - **Rule 2**: [C10](#c10-single-file-function-folder-match), [C13](#c13-filename-folder-exact-match-flattening)
411
- - **Rule 4**: [C11](#c11-default-export-flattening), [C17](#c17-default-function-export-flattening)
412
- - **Rule 5**: [C02](#c02-multi-default-context-with-default-export), [C03](#c03-multi-default-context-without-default-export)
413
- - **Rule 6**: [C01](#c01-self-referential-check), [C09a](#c09a-self-referential-non-function)
414
- - **Rule 7**: [C04](#c04-auto-flatten-single-named-export-matching-filename), [C08](#c08-auto-flattening), [C12](#c12-object-auto-flatten), [C18](#c18-object-auto-flatten-final-check)
415
- - **Rule 8**: [C14](#c14-parent-level-flattening-generic-filenames)
416
- - **Rule 9**: [C15](#c15-function-name-matches-folder), [C16](#c16-function-name-preference)
417
-
418
- **By Flattening Feature**:
419
-
420
- - **F01 (Basic Rules)**: [C01](#c01-self-referential-check), [C05](#c05-filename-matches-container-category-level-flatten), [C07](#c07-default-fallback---preserve-as-namespace)
421
- - **F02 (Function Folder Match)**: [C10](#c10-single-file-function-folder-match), [C15](#c15-function-name-matches-folder)
422
- - **F03 (Auto-Flatten)**: [C04](#c04-auto-flatten-single-named-export-matching-filename), [C08](#c08-auto-flattening)
423
- - **F04 (Object Flatten)**: [C11](#c11-default-export-flattening), [C12](#c12-object-auto-flatten)
424
- - **F05 (Processing)**: [C08](#c08-auto-flattening), [C09](#c09-flatten-to-rootcategory), [C09b](#c09b-traditional-namespace-preservation)
425
- - **F06 (Mixed Patterns)**: [C02](#c02-multi-default-context-with-default-export), [C03](#c03-multi-default-context-without-default-export)
426
-
427
- ---
428
-
429
- ## Summary
430
-
431
- **Total Active Conditions**: 18 documented conditions from actual source code
432
- **Primary Functions**: 3 main functions containing API generation logic
433
- **File Locations**: 1 primary source file - decisions.mjs
434
-
435
- ### Condition Categories
436
-
437
- - **Basic Flattening** (C01-C07): Core flattening decision logic from `getFlatteningDecision()`
438
- - **Module Processing** (C08-C09b): Module handling from `processModuleForAPI()`
439
- - **Single-File Decisions** (C10-C18): Directory-level logic from `buildCategoryDecisions()`
440
-
441
- ### Key Architectural Patterns
442
-
443
- 1. **Self-Referential Protection**: Conditions C01, C09a prevent circular structures
444
- 2. **Multi-Default Coordination**: Conditions C02, C03 handle mixed export patterns
445
- 3. **Smart Flattening**: Auto-detection conditions C04, C08 reduce unnecessary nesting
446
- 4. **Filename Matching**: Conditions C10-C13 handle folder/file name matching
447
- 5. **Function Name Preference**: Conditions C15-C16 preserve semantic naming
448
-
449
- ### Implementation Notes
450
-
451
- - **Line Numbers**: All verified against commit `a50531d1ba712f0c4efd9ab9b7cf8f62a0d379da`
452
- - **GitHub Links**: Use `#Lxxx-Lyyy` format for precise source navigation
453
- - **Test Verification**: Each condition has corresponding test cases in `/tests/` directory
454
- - **Debug Support**: Most conditions log decisions when `config.debug` is enabled
455
-
456
- ---
457
-
458
- ## Document Maintenance
459
-
460
- **Version**: 2.0
461
- **Last Full Audit**: January 3, 2026
462
- **Status**: ✅ **COMPLETE** - All conditions documented with technical details
463
- **Cross-References**: Complete integration with API-RULES-v2.md and API-FLATTENING-v2.md
464
- **Next Review**: When source code conditions change or new features are added
465
-
466
- **Verification Commands**:
467
-
468
- ```bash
469
- # Test all condition behaviors
470
- npm run debug # Runs comprehensive API validation
471
- npm run test:node # Core functionality tests
472
-
473
- # Verify specific conditions
474
- node tests/debug-slothlet.mjs --slothletdebug # Detailed decision tracing
475
- ```
476
-
477
- This section maps conditions to the higher-level documentation they support.
478
-
479
- ## Summary
480
-
481
- **Total Active Conditions**: 33 documented conditions (2 commented out: C06, C31)
482
- **Primary Functions**: 6 key functions containing API generation logic
483
- **File Locations**: 3 source files across api_builder/ modules
484
-
485
- ### Condition Categories
486
-
487
- - **Basic Flattening** (C01-C07): Core flattening decision logic
488
- - **Module Processing** (C08-C09d): Individual module handling
489
- - **Category Decisions** (C10-C21d): Directory-level coordination
490
- - **Structural Assembly** (C22-C26): Final API structure building
491
- - **Multi-Default Logic** (C27-C32): Specialized multi-default handling
492
- - **AddApi Special Cases** (C33): Always-flatten AddApi behavior
493
-
494
- ### Key Architectural Patterns
495
-
496
- 1. **Self-Referential Protection**: Multiple conditions (C01, C08b, C09c, C20, C27) prevent circular structures
497
- 2. **Multi-Default Coordination**: Specialized handling (C02, C03, C08a, C21b, C28, C29) prevents naming conflicts
498
- 3. **Smart Flattening**: Auto-detection (C04, C05, C12, C13, C18, C30) reduces unnecessary nesting
499
- 4. **Name Preservation**: Function name preference (C16, C19) maintains semantic meaning
500
- 5. **Depth Awareness**: Many conditions check `currentDepth` to preserve root-level structure
501
- 6. **Special Cases**: AddApi files (C33) get always-flatten treatment for API extension
502
-
503
- ---
504
-
505
- ## Document Maintenance
506
-
507
- **Version**: 2.0
508
- **Last Full Audit**: January 3, 2026
509
- **Lines Verified**: All line numbers manually verified against source code
510
- **Cross-References**: Enhanced linking to API-RULES-v2.md and API-FLATTENING-v2.md
511
- **Links**: All GitHub-style links use `#Lxxx-Lyyy` format for precise navigation
512
-
513
- **Next Steps**:
514
-
515
- - Verify line numbers after any source code changes
516
- - Update cross-references when higher-level documentation changes
517
-
518
- ---
519
-
520
- ## C19-C22: Rule 12 Module Ownership Conditions
521
-
522
- **Functionality**: Module ownership tracking and selective API overwriting validation
523
- **Primary Rule**: [Rule 12 - Module Ownership and Selective API Overwriting](API-RULES-v2.md#rule-12-module-ownership-and-selective-api-overwriting)
524
- **Source Code**: [slothlet.mjs](../src/slothlet.mjs) (ownership tracking), [add_api.mjs](../src/lib/helpers/api_builder/add_api.mjs) (validation)
525
-
526
- ### C19: Configuration Validation Condition
527
-
528
- **Code Location**: [slothlet.mjs#L85-L90](../src/slothlet.mjs#L85-L90)
529
-
530
- ```javascript
531
- if (options.forceOverwrite && !this._config.enableModuleOwnership) {
532
- throw new Error("forceOverwrite requires enableModuleOwnership: true in slothlet configuration");
533
- }
534
- ```
535
-
536
- **Triggers**: `options.forceOverwrite === true && this._config.enableModuleOwnership !== true`
537
- **Logic**: Configuration consistency validation
538
- **Result**: Throws error requiring enableModuleOwnership for forceOverwrite operations
539
-
540
- ### C20: Module ID Requirement Condition
541
-
542
- **Code Location**: [slothlet.mjs#L90-L95](../src/slothlet.mjs#L90-L95)
543
-
544
- ```javascript
545
- if (options.forceOverwrite && !options.moduleId) {
546
- throw new Error("forceOverwrite requires moduleId parameter for ownership tracking");
547
- }
548
- ```
549
-
550
- **Triggers**: `options.forceOverwrite === true && !options.moduleId`
551
- **Logic**: Module identification requirement for ownership tracking
552
- **Result**: Throws error requiring moduleId for ownership-tracked operations
553
-
554
- ### C21: Function Ownership Validation Condition
555
-
556
- **Code Location**: [add_api.mjs#L145-L155](../src/lib/helpers/api_builder/add_api.mjs#L145-L155)
557
-
558
- ```javascript
559
- if (currentTarget[finalKey] !== undefined && typeof currentTarget[finalKey] === "function" && this._config.enableModuleOwnership) {
560
- const existingOwner = this._getApiOwnership(fullPath);
561
- if (existingOwner && existingOwner !== options.moduleId) {
562
- throw new Error(
563
- `Cannot overwrite API "${fullPath}" - owned by module "${existingOwner}", attempted by module "${options.moduleId}". Modules can only overwrite APIs they own.`
564
- );
565
- }
566
- }
567
- ```
568
-
569
- **Triggers**: Function overwrite attempt with ownership tracking enabled
570
- **Logic**: Cross-module ownership violation detection for functions
571
- **Result**: Throws error if moduleId doesn't match existing function owner
572
-
573
- ### C22: Object Ownership Validation Condition
574
-
575
- **Code Location**: [add_api.mjs#L160-L170](../src/lib/helpers/api_builder/add_api.mjs#L160-L170)
576
-
577
- ```javascript
578
- if (currentTarget[finalKey] !== undefined && this._config.enableModuleOwnership && options.moduleId) {
579
- const existingOwner = this._getApiOwnership(fullPath);
580
- if (existingOwner && existingOwner !== options.moduleId) {
581
- throw new Error(
582
- `Cannot overwrite API "${fullPath}" - owned by module "${existingOwner}", attempted by module "${options.moduleId}". Modules can only overwrite APIs they own.`
583
- );
584
- }
585
- }
586
- ```
587
-
588
- **Triggers**: Object/namespace overwrite attempt with ownership tracking enabled
589
- **Logic**: Cross-module ownership violation detection for objects/namespaces
590
- **Result**: Throws error if moduleId doesn't match existing object owner
591
-
592
- **Common Implementation Pattern**:
593
-
594
- - ✅ Ownership tracking via `Map<string, string>` in `_moduleOwnership`
595
- - ✅ Registration via `_registerApiOwnership(apiPath, moduleId)`
596
- - ✅ Validation via `_getApiOwnership(apiPath)` lookup
597
- - ✅ Cross-module protection regardless of `allowApiOverwrite` setting
598
-
599
- ---
600
-
601
- ## C33: AddApi Special File Detection
602
-
603
- **Category**: AddApi
604
- **Related Rule**: [Rule 11](API-RULES-v2.md#rule-11-addapi-special-file-pattern)
605
- **Flattening Guide**: [F06: AddApi Special File Pattern](API-FLATTENING-v2.md#f06-addapi-special-file-pattern)
606
- **Status**: ✅ **VERIFIED** (api_tests/api_smart_flatten_addapi)
607
-
608
- **Pattern**: Files named `addapi.mjs` loaded via `addApi()` method always flatten regardless of `autoFlatten` setting
609
-
610
- **Purpose**: Designed for seamless API namespace extensions - `addapi.mjs` files should extend the target API path directly without creating an intermediate `.addapi.` namespace level
611
-
612
- **Implementation Location**: [src/lib/helpers/api_builder/add_api.mjs](../../src/lib/helpers/api_builder/add_api.mjs#L266-L310) (lines 266-310)
613
-
614
- **When Evaluated**: During `addApiFromFolder()` execution, after modules are loaded but before they are merged into the API
615
-
616
- **Condition Check**:
617
-
618
- ```javascript
619
- // Rule 6: AddApi Special File Pattern - Handle addapi.mjs flattening
620
- // Check if the loaded modules contain an 'addapi' key and flatten it
621
- if (newModules && typeof newModules === "object" && newModules.addapi) {
622
- if (instance.config.debug) {
623
- console.log(`[DEBUG] addApi: Found addapi.mjs - applying Rule 6 flattening`);
624
- console.log(`[DEBUG] addApi: Original structure:`, Object.keys(newModules));
625
- console.log(`[DEBUG] addApi: Addapi contents:`, Object.keys(newModules.addapi));
626
- }
627
-
628
- // Extract the addapi module content
629
- const addapiContent = newModules.addapi;
630
-
631
- // Remove the addapi key from newModules
632
- delete newModules.addapi;
633
-
634
- // Merge addapi content directly into the root level of newModules
635
- if (addapiContent && typeof addapiContent === "object") {
636
- // Handle both function exports and object exports
637
- Object.assign(newModules, addapiContent);
638
-
639
- if (instance.config.debug) {
640
- console.log(`[DEBUG] addApi: After addapi flattening:`, Object.keys(newModules));
641
- }
642
- } else if (typeof addapiContent === "function") {
643
- // If addapi exports a single function, merge its properties
644
- Object.assign(newModules, addapiContent);
645
-
646
- if (instance.config.debug) {
647
- console.log(`[DEBUG] addApi: Flattened addapi function with properties:`, Object.keys(newModules));
648
- }
649
- }
650
- }
651
- ```
652
-
653
- **Example Structure**:
654
-
655
- ```text
656
- plugin-folder/
657
- └── addapi.mjs
658
- export function initializePlugin() {...}
659
- export function cleanup() {...}
660
- export function configure() {...}
661
- ```
662
-
663
- **API Usage**:
664
-
665
- ```javascript
666
- // Load plugin folder via addApi
667
- await api.addApi("plugins", "./plugin-folder");
668
-
669
- // Result: addapi.mjs always flattens (no .addapi. level)
670
- api.plugins.initializePlugin(); // ✅ Direct extension
671
- api.plugins.cleanup(); // ✅ Seamless integration
672
- api.plugins.configure(); // ✅ No intermediate namespace
673
- ```
674
-
675
- **Without C33 Behavior** (hypothetical):
676
-
677
- ```javascript
678
- // Without special handling, would create nested structure
679
- api.plugins.addapi.initializePlugin(); // ❌ Unwanted intermediate level
680
- api.plugins.addapi.cleanup(); // ❌ Breaks API extension pattern
681
- ```
682
-
683
- **Key Implementation Details**:
684
-
685
- 1. **Detection**: Checks for `newModules.addapi` key in loaded module structure
686
- 2. **Extraction**: Stores content of `addapi` module in `addapiContent` variable
687
- 3. **Removal**: Deletes the `addapi` key from `newModules` to prevent namespace creation
688
- 4. **Flattening**: Merges all exports from `addapi.mjs` directly into root level of `newModules`
689
- 5. **Type Handling**: Supports both object exports and function exports with properties
690
-
691
- **Use Cases**:
692
-
693
- - 🔌 **Plugin Systems**: Runtime plugin loading that extends existing API namespaces
694
- - 🔄 **Hot Reloading**: Dynamic API updates during development without intermediate levels
695
- - 📦 **Modular Extensions**: Clean extension of existing API surfaces
696
- - 🎯 **Targeted Integration**: Specific API namespace enhancement for add-on functionality
697
-
698
- **Behavior Characteristics**:
699
-
700
- - ✅ **Always Active**: Works regardless of `autoFlatten` configuration setting
701
- - ✅ **Priority Processing**: Occurs before other flattening rules are applied
702
- - ✅ **Transparent Integration**: Exports appear as if they were originally part of target namespace
703
- - ✅ **Works with addApi Only**: Special handling only applies to `addApi()` method, not initial load
704
-
705
- **Result**: `addapi.mjs` file contents are merged directly at the target API path level, eliminating the intermediate `.addapi.` namespace
706
-
707
- **Common Implementation Pattern**:
708
-
709
- - ✅ Detection via `newModules.addapi` property check
710
- - ✅ Extraction and deletion of `addapi` key
711
- - ✅ Direct merge using `Object.assign(newModules, addapiContent)`
712
- - ✅ Support for both object and function exports