npm package: @neoimpulse/cap-js-bootstrap
Description: SICP-compliant CAP bootstrap package by Neoimpulse
Author: Neoimpulse GmbH
Latest version: 1.0.9

# Bootstrap - SICP-konform

Dieses Bootstrap-Modul folgt strikten SICP-Prinzipien (Structure and Interpretation of Computer Programs) und ist als npm-Paket vorbereitet.

## Installation (Consumer-Projekt)

```bash
npm install @neoimpulse/cap-js-bootstrap
```

## Verwendung

```bash
# Aus dem Consumer-Projekt
npx cap-js-bootstrap --verbose
```

Alternativ direkt:

```bash
node node_modules/@neoimpulse/cap-js-bootstrap/dist/index.js --verbose
```

## Konfiguration

Das Bootstrap liest seine Konfiguration aus der `bootstrap`-Sektion der `package.json` im jeweiligen Projektverzeichnis.
CLI-Parameter ueberschreiben die Werte aus der Konfiguration.

### CLI-Parameter

- `--help`: Hilfe anzeigen und beenden
- `--debug`: Debug-Modus fuer Services aktivieren
- `--with-bindings-update`: Bindings/Default-Env aktualisieren
- `--no-bindings`: Bindings-Update deaktivieren (ueberschreibt `withBindingsUpdate`)
- `--parallel`: Services parallel starten (schneller, ggf. Limits beachten)
- `--verbose`: Ausfuehrliche Ausgabe
- `--profile <name>`: CDS-Profil fuer Binding/Start (z. B. `hybrid`, `pg`)
- `--runtime <js|ts>`: Runtime-Auswahl (js -> `cds`, ts -> `cds-ts`)

### package.json: `bootstrap`-Konfiguration

Beispiel:

```json
{
	"bootstrap": {
		"debug": false,
		"withBindingsUpdate": false,
		"parallel": false,
		"verboseOutput": true,
		"profile": "pg",
		"runtime": "ts",
		"approuterPath": "recollection",
		"basePath": "./",
		"services": [
			{
				"path": "recollection",
				"name": "recollection-srv",
				"port": 4004,
				"addPoolConfiguration": false,
				"boundServices": ["uaa-service", "destination-service", "connectivity-service"]
			}
		]
	}
}
```

#### Bedeutung der Felder

- `debug`: Aktiviert Debug-Ausgabe fuer gestartete Services (kann per `--debug` ueberschrieben werden)
- `withBindingsUpdate`: Fuehrt `cds bind`/`default-env` aus (per `--with-bindings-update` oder `--no-bindings`)
- `parallel`: Startet Services parallel (per `--parallel`)
- `verboseOutput`: Aktiviert detaillierte Logs (per `--verbose`)
- `profile`: CDS-Profil fuer Bindings und Service-Start (per `--profile`)
- `runtime`: Runtime-Auswahl fuer Service-Start (`ts` -> `cds-ts`, `js` -> `cds`)
- `basePath`: Basisverzeichnis fuer Service-Pfade (relativ zum Projekt-Root)
- `approuterPath`: Pfad zum Approuter relativ zu `basePath`
- `services`: Liste der zu startenden Services
  - `path`: Relativer Pfad des Services (wird mit `basePath` kombiniert)
  - `name`: Service-Name fuer `default-env`/Bindings
  - `port`: HTTP-Port des Services
  - `boundServices`: Liste externer Services, die gebunden werden
  - `addPoolConfiguration`: Wenn `true`, fuegt DB-Pool-Config in `.cdsrc-private.json` hinzu

## Entwicklung

```bash
npm install
npm run build
node dist/index.js --verbose
```

## Architektur

### Vier-Schichten-Architektur Visualisierung

```
┌─────────────────────────────────────────────────────────────────────┐
│ Layer 4: I/O & Orchestration (handlers/)                           │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  index.ts (Main)                                                    │
│    ├── checkCfLogin()              [cloud-foundry.ts]              │
│    ├── downloadCredentials()       [binding-orchestration.ts]      │
│    ├── loadServicesSequentially()  [service-operations.ts]         │
│    ├── loadServicesParallel()      [service-operations.ts]         │
│    ├── loadApprouter()             [service-operations.ts]         │
│    └── createShutdownHandler()     [shutdown.ts]                   │
│                                                                     │
│  binding-orchestration.ts                                           │
│    ├── bindServices()                                               │
│    │   ├── checkFileExists()       [file-operations.ts]            │
│    │   ├── downloadDefaultEnv()    [cloud-foundry.ts]              │
│    │   ├── bindServiceToCds()      [cloud-foundry.ts]              │
│    │   └── addPoolConfiguration()  [configuration.ts]              │
│    └── downloadCredentials()                                        │
│                                                                     │
│  service-operations.ts                                              │
│    ├── loadService()                                                │
│    │   ├── spawnProcess()          [process-operations.ts]         │
│    │   └── waitForProcessOutput()  [process-operations.ts]         │
│    ├── loadServicesSequentially()                                   │
│    ├── loadServicesParallel()                                       │
│    └── loadApprouter()                                              │
│                                                                     │
│  cloud-foundry.ts                                                   │
│    ├── checkCfLogin()                                               │
│    ├── downloadDefaultEnv()                                         │
│    └── bindServiceToCds()                                           │
│                                                                     │
│  configuration.ts                                                   │
│    └── addPoolConfiguration()                                       │
│        ├── readJsonFile()          [file-operations.ts]            │
│        └── writeJsonFile()         [file-operations.ts]            │
│                                                                     │
│  file-operations.ts                                                 │
│    ├── checkFileExists()                                            │
│    ├── readJsonFile()                                               │
│    └── writeJsonFile()                                              │
│                                                                     │
│  process-operations.ts                                              │
│    ├── spawnProcess()                                               │
│    ├── waitForProcessOutput()                                       │
│    ├── waitForProcessClose()                                        │
│    └── terminateProcess()                                           │
│                                                                     │
│  logging.ts                                                         │
│    ├── createLogger()                                               │
│    ├── logMessage()                                                 │
│    └── logError()                                                   │
│                                                                     │
│  shutdown.ts                                                        │
│    └── createShutdownHandler()                                      │
│                                                                     │
│  help.ts                                                            │
│    ├── showHelp()                                                   │
│    ├── showParallelHints()                                          │
│    └── showTroubleshootingHints()                                   │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘
                              ↓ ruft auf
┌─────────────────────────────────────────────────────────────────────┐
│ Layer 3: Domain Operations (domain/)                               │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  validation.ts                                                      │
│    ├── validatePattern()           → Pure Function                 │
│    ├── findMatchingPattern()       → Pure Function                 │
│    └── hasRejectPattern()          → Pure Function                 │
│                                                                     │
│  transformation.ts                                                  │
│    ├── formatLogLine()             → Pure Function                 │
│    ├── formatLogChunk()            → Pure Function                 │
│    ├── buildServiceTask()          → Pure Function                 │
│    ├── mergeConfigWithPath()       → Pure Function                 │
│    ├── buildPoolConfig()           → Pure Function                 │
│    ├── parseUserArgs()             → Pure Function                 │
│    └── extractProfileArg()         → Pure Function                 │
│                                                                     │
│  calculation.ts                                                     │
│    ├── calculateDebugPort()        → Pure Function                 │
│    ├── calculateStartupTime()      → Pure Function                 │
│    └── shouldLoadSequentially()    → Pure Function                 │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘
                              ↓ ruft auf
┌─────────────────────────────────────────────────────────────────────┐
│ Layer 2: Generic Utilities (lib/)                                  │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  result-helpers.ts                                                  │
│    ├── chain()                     → Pure Function                 │
│    ├── pipeline()                  → Pure Function                 │
│    ├── success()                   → Pure Function                 │
│    └── failure()                   → Pure Function                 │
│                                                                     │
│  array-utils.ts                                                     │
│    ├── mapArray()                  → Pure Function                 │
│    ├── filterArray()               → Pure Function                 │
│    └── reduceArray()               → Pure Function                 │
│                                                                     │
│  string-utils.ts                                                    │
│    ├── splitLines()                → Pure Function                 │
│    ├── joinLines()                 → Pure Function                 │
│    └── addPrefix()                 → Pure Function                 │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘
                              ↓ ruft auf
┌─────────────────────────────────────────────────────────────────────┐
│ Layer 1: Language Primitives                                       │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  Array.map()   Array.filter()   Array.reduce()                     │
│  String.split()   String.join()   Object.keys()                    │
│  Promise.all()   Promise.resolve()                                 │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘
```

### Datenfluss

#### Beispiel: Service starten

```
User
  ↓
main() [Layer 4]
  ↓ ruft
loadServicesParallel() [Layer 4]
  ↓ ruft
loadService() [Layer 4]
  ├→ calculateDebugPort() [Layer 3] → Pure
  ├→ spawnProcess() [Layer 4] → I/O
  ├→ waitForProcessOutput() [Layer 4] → I/O
  │   ├→ hasRejectPattern() [Layer 3] → Pure
  │   └→ findMatchingPattern() [Layer 3] → Pure
  │       └→ validatePattern() [Layer 3] → Pure
  └→ createLogger() [Layer 4] → I/O
      └→ formatLogChunk() [Layer 3] → Pure
          └→ splitLines() [Layer 2] → Pure
```

#### Beispiel: Config aktualisieren

```
User
  ↓
main() [Layer 4]
  ↓ ruft
downloadCredentials() [Layer 4]
  ↓ ruft
bindServices() [Layer 4]
  ↓ ruft
addPoolConfiguration() [Layer 4]
  ├→ readJsonFile() [Layer 4] → I/O
  ├→ buildPoolConfig() [Layer 3] → Pure
  └→ writeJsonFile() [Layer 4] → I/O
```

### Dependency Graph

```mermaid
graph TD
    A[index.ts] --> B[binding-orchestration.ts]
    A --> C[service-operations.ts]
    A --> D[shutdown.ts]
    A --> E[help.ts]

    B --> F[cloud-foundry.ts]
    B --> G[configuration.ts]
    B --> H[file-operations.ts]

    C --> I[process-operations.ts]
    C --> J[logging.ts]

    F --> I
    F --> J

    G --> H

    I --> K[validation.ts]
    J --> L[transformation.ts]

    K --> M[result-helpers.ts]
    L --> M
    L --> N[string-utils.ts]

    style A fill:#f9f,stroke:#333
    style K fill:#9f9,stroke:#333
    style L fill:#9f9,stroke:#333
    style M fill:#99f,stroke:#333
    style N fill:#99f,stroke:#333
```

**Legende:**

-   🟪 Layer 4 (I/O & Orchestration)
-   🟩 Layer 3 (Domain Operations - Pure)
-   🟦 Layer 2 (Generic Utilities - Pure)

### Verifizierung

#### ✅ Keine Schicht wird übersprungen

-   Layer 4 ruft NUR Layer 3 und andere Layer 4 auf
-   Layer 3 ruft NUR Layer 2 auf
-   Layer 2 ruft NUR Layer 1 (Language Primitives) auf
-   Keine Aufrufe nach oben

#### ✅ Pure Functions in Layer 2 & 3

-   Alle Funktionen in `lib/` sind pure
-   Alle Funktionen in `domain/` sind pure
-   Keine Seiteneffekte außer in Layer 4

#### ✅ I/O nur in Layer 4

-   `handlers/` enthält alle I/O-Operationen
-   Klare Benennung: `load*`, `write*`, `read*`, `spawn*`, `log*`

## Ordnerstruktur (Source)

```
src/
├── types.ts                 # Plain Data Types
├── index.ts                 # Main Entry Point (Layer 4)
│
├── lib/                     # Layer 2: Generic Utilities
│   ├── result-helpers.ts    # Result type operations
│   ├── array-utils.ts       # Array operations
│   └── string-utils.ts      # String operations
│
├── domain/                  # Layer 3: Business Logic
│   ├── validation.ts        # Validation functions
│   ├── transformation.ts    # Data transformations
│   └── calculation.ts       # Calculations
│
└── handlers/                # Layer 4: I/O & Orchestration
    ├── file-operations.ts   # File I/O
    ├── process-operations.ts # Process spawning
    ├── logging.ts           # Logging
    ├── cloud-foundry.ts     # CF operations
    ├── service-operations.ts # Service management
    ├── configuration.ts     # Config management
    ├── binding-orchestration.ts # Service binding
    ├── shutdown.ts          # Shutdown handler
    └── help.ts              # Help messages
```