@cldmv/slothlet 2.11.0 → 3.0.1
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 +355 -325
- package/README.md +554 -238
- package/dist/lib/builders/api-assignment.mjs +605 -0
- package/dist/lib/builders/api_builder.mjs +1073 -0
- package/dist/lib/builders/builder.mjs +94 -0
- package/dist/lib/builders/modes-processor.mjs +1816 -0
- package/dist/lib/errors.mjs +227 -0
- package/dist/lib/factories/component-base.mjs +96 -0
- package/dist/lib/factories/context.mjs +38 -0
- package/dist/lib/handlers/api-cache-manager.mjs +216 -0
- package/dist/lib/handlers/api-manager.mjs +2364 -0
- package/dist/lib/handlers/context-async.mjs +184 -0
- package/dist/lib/handlers/context-live.mjs +184 -0
- package/dist/lib/handlers/hook-manager.mjs +789 -0
- package/dist/lib/handlers/lifecycle-token.mjs +44 -0
- package/dist/lib/handlers/lifecycle.mjs +131 -0
- package/dist/lib/handlers/materialize-manager.mjs +64 -0
- package/dist/lib/handlers/metadata.mjs +500 -0
- package/dist/lib/handlers/ownership.mjs +338 -0
- package/dist/lib/handlers/unified-wrapper.mjs +3031 -0
- package/dist/lib/helpers/class-instance-wrapper.mjs +125 -0
- package/dist/lib/helpers/config.mjs +343 -0
- package/dist/lib/helpers/eventemitter-context.mjs +365 -0
- package/dist/lib/helpers/hint-detector.mjs +63 -0
- package/dist/lib/helpers/modes-utils.mjs +53 -0
- package/dist/lib/helpers/resolve-from-caller.mjs +123 -117
- package/dist/lib/helpers/sanitize.mjs +247 -168
- package/dist/lib/helpers/utilities.mjs +46 -81
- package/dist/lib/i18n/languages/de-de.json +377 -0
- package/dist/lib/i18n/languages/en-gb.json +377 -0
- package/dist/lib/i18n/languages/en-us.json +377 -0
- package/dist/lib/i18n/languages/es-mx.json +377 -0
- package/dist/lib/i18n/languages/fr-fr.json +377 -0
- package/dist/lib/i18n/languages/hi-in.json +377 -0
- package/dist/lib/i18n/languages/ja-jp.json +377 -0
- package/dist/lib/i18n/languages/ko-kr.json +377 -0
- package/dist/lib/i18n/languages/pt-br.json +377 -0
- package/dist/lib/i18n/languages/ru-ru.json +377 -0
- package/dist/lib/i18n/languages/zh-cn.json +377 -0
- package/dist/lib/i18n/translations.mjs +140 -0
- package/dist/lib/modes/eager.mjs +75 -0
- package/dist/lib/modes/lazy.mjs +97 -0
- package/dist/lib/processors/flatten.mjs +453 -0
- package/dist/lib/processors/loader.mjs +355 -0
- package/dist/lib/processors/type-generator.mjs +291 -0
- package/dist/lib/processors/typescript.mjs +188 -0
- package/dist/lib/runtime/runtime-asynclocalstorage.mjs +80 -522
- package/dist/lib/runtime/runtime-livebindings.mjs +45 -390
- package/dist/lib/runtime/runtime.mjs +39 -159
- package/dist/slothlet.mjs +525 -744
- package/docs/API-RULES.md +338 -486
- package/index.cjs +4 -4
- package/index.mjs +82 -45
- package/package.json +143 -30
- package/types/dist/lib/builders/api-assignment.d.mts +97 -0
- package/types/dist/lib/builders/api-assignment.d.mts.map +1 -0
- package/types/dist/lib/builders/api_builder.d.mts +96 -0
- package/types/dist/lib/builders/api_builder.d.mts.map +1 -0
- package/types/dist/lib/builders/builder.d.mts +60 -0
- package/types/dist/lib/builders/builder.d.mts.map +1 -0
- package/types/dist/lib/builders/modes-processor.d.mts +32 -0
- package/types/dist/lib/builders/modes-processor.d.mts.map +1 -0
- package/types/dist/lib/errors.d.mts +118 -0
- package/types/dist/lib/errors.d.mts.map +1 -0
- package/types/dist/lib/factories/component-base.d.mts +182 -0
- package/types/dist/lib/factories/component-base.d.mts.map +1 -0
- package/types/dist/lib/factories/context.d.mts +26 -0
- package/types/dist/lib/factories/context.d.mts.map +1 -0
- package/types/dist/lib/handlers/api-cache-manager.d.mts +208 -0
- package/types/dist/lib/handlers/api-cache-manager.d.mts.map +1 -0
- package/types/dist/lib/handlers/api-manager.d.mts +392 -0
- package/types/dist/lib/handlers/api-manager.d.mts.map +1 -0
- package/types/dist/lib/handlers/context-async.d.mts +66 -0
- package/types/dist/lib/handlers/context-async.d.mts.map +1 -0
- package/types/dist/lib/handlers/context-live.d.mts +65 -0
- package/types/dist/lib/handlers/context-live.d.mts.map +1 -0
- package/types/dist/lib/handlers/hook-manager.d.mts +199 -0
- package/types/dist/lib/handlers/hook-manager.d.mts.map +1 -0
- package/types/dist/lib/handlers/lifecycle-token.d.mts +49 -0
- package/types/dist/lib/handlers/lifecycle-token.d.mts.map +1 -0
- package/types/dist/lib/handlers/lifecycle.d.mts +90 -0
- package/types/dist/lib/handlers/lifecycle.d.mts.map +1 -0
- package/types/dist/lib/handlers/materialize-manager.d.mts +75 -0
- package/types/dist/lib/handlers/materialize-manager.d.mts.map +1 -0
- package/types/dist/lib/handlers/metadata.d.mts +215 -0
- package/types/dist/lib/handlers/metadata.d.mts.map +1 -0
- package/types/dist/lib/handlers/ownership.d.mts +170 -0
- package/types/dist/lib/handlers/ownership.d.mts.map +1 -0
- package/types/dist/lib/handlers/unified-wrapper.d.mts +250 -0
- package/types/dist/lib/handlers/unified-wrapper.d.mts.map +1 -0
- package/types/dist/lib/helpers/class-instance-wrapper.d.mts +54 -0
- package/types/dist/lib/helpers/class-instance-wrapper.d.mts.map +1 -0
- package/types/dist/lib/helpers/config.d.mts +96 -0
- package/types/dist/lib/helpers/config.d.mts.map +1 -0
- package/types/dist/lib/helpers/eventemitter-context.d.mts +31 -0
- package/types/dist/lib/helpers/eventemitter-context.d.mts.map +1 -0
- package/types/dist/lib/helpers/hint-detector.d.mts +20 -0
- package/types/dist/lib/helpers/hint-detector.d.mts.map +1 -0
- package/types/dist/lib/helpers/modes-utils.d.mts +35 -0
- package/types/dist/lib/helpers/modes-utils.d.mts.map +1 -0
- package/types/dist/lib/helpers/resolve-from-caller.d.mts +29 -145
- package/types/dist/lib/helpers/resolve-from-caller.d.mts.map +1 -1
- package/types/dist/lib/helpers/sanitize.d.mts +95 -94
- package/types/dist/lib/helpers/sanitize.d.mts.map +1 -1
- package/types/dist/lib/helpers/utilities.d.mts +53 -116
- package/types/dist/lib/helpers/utilities.d.mts.map +1 -1
- package/types/dist/lib/i18n/translations.d.mts +39 -0
- package/types/dist/lib/i18n/translations.d.mts.map +1 -0
- package/types/dist/lib/modes/eager.d.mts +36 -0
- package/types/dist/lib/modes/eager.d.mts.map +1 -0
- package/types/dist/lib/modes/lazy.d.mts +49 -0
- package/types/dist/lib/modes/lazy.d.mts.map +1 -0
- package/types/dist/lib/processors/flatten.d.mts +114 -0
- package/types/dist/lib/processors/flatten.d.mts.map +1 -0
- package/types/dist/lib/processors/loader.d.mts +47 -0
- package/types/dist/lib/processors/loader.d.mts.map +1 -0
- package/types/dist/lib/processors/type-generator.d.mts +19 -0
- package/types/dist/lib/processors/type-generator.d.mts.map +1 -0
- package/types/dist/lib/processors/typescript.d.mts +55 -0
- package/types/dist/lib/processors/typescript.d.mts.map +1 -0
- package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts +47 -42
- package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts.map +1 -1
- package/types/dist/lib/runtime/runtime-livebindings.d.mts +34 -65
- package/types/dist/lib/runtime/runtime-livebindings.d.mts.map +1 -1
- package/types/dist/lib/runtime/runtime.d.mts +39 -9
- package/types/dist/lib/runtime/runtime.d.mts.map +1 -1
- package/types/dist/slothlet.d.mts +184 -111
- package/types/dist/slothlet.d.mts.map +1 -1
- package/types/index.d.mts +1 -3
- package/dist/lib/engine/README.md +0 -21
- package/dist/lib/engine/slothlet_child.mjs +0 -59
- package/dist/lib/engine/slothlet_engine.mjs +0 -372
- package/dist/lib/engine/slothlet_esm.mjs +0 -230
- package/dist/lib/engine/slothlet_helpers.mjs +0 -455
- package/dist/lib/engine/slothlet_worker.mjs +0 -149
- package/dist/lib/helpers/als-eventemitter.mjs +0 -256
- package/dist/lib/helpers/api_builder/add_api.mjs +0 -553
- package/dist/lib/helpers/api_builder/analysis.mjs +0 -532
- package/dist/lib/helpers/api_builder/construction.mjs +0 -495
- package/dist/lib/helpers/api_builder/decisions.mjs +0 -748
- package/dist/lib/helpers/api_builder/metadata.mjs +0 -248
- package/dist/lib/helpers/api_builder.mjs +0 -41
- package/dist/lib/helpers/auto-wrap.mjs +0 -62
- package/dist/lib/helpers/hooks.mjs +0 -389
- package/dist/lib/helpers/instance-manager.mjs +0 -111
- package/dist/lib/helpers/metadata-api.mjs +0 -201
- package/dist/lib/helpers/multidefault.mjs +0 -216
- package/dist/lib/modes/slothlet_eager.mjs +0 -154
- package/dist/lib/modes/slothlet_lazy.mjs +0 -594
- package/docs/API-RULES-CONDITIONS.md +0 -712
- package/types/dist/lib/engine/slothlet_child.d.mts +0 -2
- package/types/dist/lib/engine/slothlet_child.d.mts.map +0 -1
- package/types/dist/lib/engine/slothlet_engine.d.mts +0 -31
- package/types/dist/lib/engine/slothlet_engine.d.mts.map +0 -1
- package/types/dist/lib/engine/slothlet_esm.d.mts +0 -19
- package/types/dist/lib/engine/slothlet_esm.d.mts.map +0 -1
- package/types/dist/lib/engine/slothlet_helpers.d.mts +0 -25
- package/types/dist/lib/engine/slothlet_helpers.d.mts.map +0 -1
- package/types/dist/lib/engine/slothlet_worker.d.mts +0 -2
- package/types/dist/lib/engine/slothlet_worker.d.mts.map +0 -1
- package/types/dist/lib/helpers/als-eventemitter.d.mts +0 -56
- package/types/dist/lib/helpers/als-eventemitter.d.mts.map +0 -1
- package/types/dist/lib/helpers/api_builder/add_api.d.mts +0 -102
- package/types/dist/lib/helpers/api_builder/add_api.d.mts.map +0 -1
- package/types/dist/lib/helpers/api_builder/analysis.d.mts +0 -189
- package/types/dist/lib/helpers/api_builder/analysis.d.mts.map +0 -1
- package/types/dist/lib/helpers/api_builder/construction.d.mts +0 -107
- package/types/dist/lib/helpers/api_builder/construction.d.mts.map +0 -1
- package/types/dist/lib/helpers/api_builder/decisions.d.mts +0 -213
- package/types/dist/lib/helpers/api_builder/decisions.d.mts.map +0 -1
- package/types/dist/lib/helpers/api_builder/metadata.d.mts +0 -99
- package/types/dist/lib/helpers/api_builder/metadata.d.mts.map +0 -1
- package/types/dist/lib/helpers/api_builder.d.mts +0 -6
- package/types/dist/lib/helpers/api_builder.d.mts.map +0 -1
- package/types/dist/lib/helpers/auto-wrap.d.mts +0 -49
- package/types/dist/lib/helpers/auto-wrap.d.mts.map +0 -1
- package/types/dist/lib/helpers/hooks.d.mts +0 -342
- package/types/dist/lib/helpers/hooks.d.mts.map +0 -1
- package/types/dist/lib/helpers/instance-manager.d.mts +0 -41
- package/types/dist/lib/helpers/instance-manager.d.mts.map +0 -1
- package/types/dist/lib/helpers/metadata-api.d.mts +0 -132
- package/types/dist/lib/helpers/metadata-api.d.mts.map +0 -1
- package/types/dist/lib/helpers/multidefault.d.mts +0 -90
- package/types/dist/lib/helpers/multidefault.d.mts.map +0 -1
- package/types/dist/lib/modes/slothlet_eager.d.mts +0 -65
- package/types/dist/lib/modes/slothlet_eager.d.mts.map +0 -1
- package/types/dist/lib/modes/slothlet_lazy.d.mts +0 -31
- package/types/dist/lib/modes/slothlet_lazy.d.mts.map +0 -1
- 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
|