This document covers development, testing, and contribution guidelines for the FAIM n8n node.
faim-n8n/
├── src/
│ ├── api/ # HTTP API client & request building
│ │ ├── forecastClient.ts # Main client with retry logic & reshaping
│ │ └── requestBuilder.ts # JSON request assembly & validation
│ ├── data/ # Data processing & validation
│ │ ├── shapeConverter.ts # 1D/2D/3D normalization
│ │ ├── shapeReshaper.ts # Output reshaping to input format
│ │ └── jsonSerializer.ts # JSON serialization & type checks
│ ├── errors/ # Error handling
│ │ ├── customErrors.ts # Error classes
│ │ └── errorHandler.ts # Error mapping & messages
│ ├── nodes/ # n8n node definitions
│ │ └── FAIMForecast/
│ │ ├── FAIMForecast.node.ts
│ │ ├── FAIMForecast.credentials.ts
│ │ └── faim.png
│ └── index.ts # Public exports
├── tests/ # Test files
│ ├── shapeConverter.test.ts # Data normalization tests
│ ├── shapeReshaper.test.ts # Output reshaping tests
│ ├── requestBuilder.test.ts # Request assembly tests
│ └── setup.ts # Test configuration
├── examples/ # Example n8n workflows
├── .github/workflows/ # CI/CD pipelines
├── README.md # User documentation
├── EXAMPLES.md # Workflow examples
└── package.json # Dependencies & scripts
- Node.js 18+ or 20+
- pnpm 10.20.0+ (package manager)
- n8n instance (for local testing)
# Install dependencies
pnpm install
# Watch mode (auto-rebuild on changes)
pnpm run dev
# Build once
pnpm run build
# Run tests
pnpm run test
# Watch tests
pnpm run test:watch
# Coverage report
pnpm run test:coverage
# Lint code
pnpm run lint
# Fix linting issues
pnpm run lint:fixn8n Input Data
↓
ShapeConverter (normalize 1D/2D/3D)
↓
RequestBuilder (validate & prepare JSON)
↓
ForecastClient (HTTP + retry logic)
↓
API Response (JSON)
↓
ShapeReshaper (reshape to input format)
↓
n8n Output JSON
- Validation errors (422): Fail immediately with clear field-level messages
- Auth errors (401): Fail immediately with credential message
- Resource errors (413, 404): Fail immediately with specific guidance
- Transient errors (503, 504): Retry with exponential backoff (2s, 4s, 8s)
- Server errors (500): Determine if retryable based on error code
See src/errors/errorHandler.ts for error mapping.
Request
↓
Failed?
├─ Retryable error → Sleep (exponential backoff + jitter)
│ ↓
│ Retry (max 3 times)
└─ Non-retryable → Throw immediately
Test individual modules in isolation:
# Test shape converter
pnpm test -- data/shapeConverter.test.ts
# Test error handling
pnpm test -- errors/errorHandler.test.ts
# Run all unit tests
pnpm test -- src/Test API interaction with mocked responses:
pnpm test -- tests/integration/Target 80%+ coverage:
pnpm run test:coverageCurrent coverage status tracked in CI/CD.
- Purpose: Normalize various input formats to 3D (batch, sequence, features)
- Inputs: 1D, 2D, 3D arrays or JSON strings
- Outputs: Validated 3D structure with metadata
- Validation: Size limits, numeric values, consistent dimensions
- Purpose: Assemble JSON API requests and validate parameters
- Features:
- Model-specific parameter handling
- Metadata schema construction
- HTTP header generation (Authorization, Content-Type)
- Input validation before API call
- Request URL construction
- Purpose: Execute forecasts with automatic retry and output reshaping
- Features:
- Bearer token authentication
- Exponential backoff retry (2s, 4s, 8s + jitter)
- Timeout management (default 30s)
- Error mapping & classification
- Response deserialization (JSON)
- Output reshaping to original input format
- Purpose: Transform API outputs back to original input dimensions
- Features:
- Reshape point forecasts to 1D/2D format
- Reshape quantiles to 1D/2D/3D format
- Reshape samples to 1D/2D/3D format
- Handle univariate outputs (features=1)
- Edit
src/api/requestBuilder.ts- Add tobuildMetadata() - Edit
src/nodes/FAIMForecast/FAIMForecast.node.ts- Add UI field and parameter handling - Add tests in
tests/unit/
- Add model name to
VALID_MODELSinrequestBuilder.ts - Add model-specific UI fields in node definition
- Update
buildMetadata()to handle new parameters - Add examples in
examples/
- Edit
src/errors/errorHandler.ts- UpdategetUserMessage() - Add specific guidance for common issues
- Update README troubleshooting section
- None (zero external dependencies for n8n Cloud compatibility)
- n8n's
this.helpers.httpRequest: HTTP client (built-in, no dependency)
- typescript: Type checking
- jest: Testing framework
- ts-jest: TypeScript + Jest integration
- eslint: Code quality
- @typescript-eslint: TS linting rules
- n8n-core, n8n-workflow: n8n types (peer dependencies)
Use semantic versioning:
- Major (1.0.0 → 2.0.0): Breaking changes
- Minor (1.0.0 → 1.1.0): New features
- Patch (1.0.0 → 1.0.1): Bug fixes
- Update version in
package.json - Add entry to CHANGELOG (if applicable)
- Create git tag:
git tag v1.0.0 - Push to main branch
- CI/CD automatically publishes to npm (if
NPM_TOKENsecret is set)
# Manual publish (if CI/CD not available)
pnpm publish --access publicRequires npm account and authentication.
- Input size limited to 50M elements (configurable in ShapeConverter)
- JSON serialization kept minimal - no binary overhead
- Batch processing reduces per-request overhead
- Default timeout: 30s (including retries)
- Exponential backoff jitter prevents thundering herd
- Batch processing reduces round-trip time
- Batch multiple requests when possible
- Use smaller horizons if not needed
- Point forecasts cheaper than quantiles/samples
This node is designed for n8n Cloud compliance:
- Zero external dependencies: Uses only n8n built-in helpers
- No restricted globals: No
setTimeout,setInterval, orconsole.log - JSON-only serialization: No binary formats required
- n8n helpers only: Uses
this.helpers.httpRequestfor HTTP calls
# Clear build cache
rm -rf dist/
pnpm run build# Run specific test with verbose output
pnpm test -- tests/unit/mytest.test.ts --verbose
# Run with debugging
node --inspect-brk node_modules/.bin/jest --runInBand# Check types without building
pnpm exec tsc --noEmit# Auto-fix all fixable issues
pnpm run lint:fix- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make changes and add tests
- Ensure tests pass:
pnpm run test - Ensure linting passes:
pnpm run lint - Commit with clear message:
git commit -m 'Add amazing feature' - Push to branch and create Pull Request