cerber-core 1.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.
- package/.cerber-example/BIBLE.md +132 -0
- package/.cerber-example/CERBER_LAW.md +200 -0
- package/.cerber-example/connections/contracts/booking-to-pricing.json +44 -0
- package/.cerber-example/connections/contracts/pricing-to-booking.json +37 -0
- package/.cerber-example/modules/booking-calendar/MODULE.md +225 -0
- package/.cerber-example/modules/booking-calendar/contract.json +106 -0
- package/.cerber-example/modules/booking-calendar/dependencies.json +8 -0
- package/.cerber-example/modules/pricing-engine/MODULE.md +160 -0
- package/.cerber-example/modules/pricing-engine/contract.json +64 -0
- package/.cerber-example/modules/pricing-engine/dependencies.json +8 -0
- package/CHANGELOG.md +68 -0
- package/LICENSE +21 -0
- package/README.md +1379 -0
- package/bin/cerber +105 -0
- package/bin/cerber-focus +31 -0
- package/bin/cerber-guardian +90 -0
- package/bin/cerber-health +113 -0
- package/bin/cerber-morning +19 -0
- package/bin/cerber-repair +21 -0
- package/dist/cerber/index.d.ts +47 -0
- package/dist/cerber/index.d.ts.map +1 -0
- package/dist/cerber/index.js +154 -0
- package/dist/cerber/index.js.map +1 -0
- package/dist/guardian/index.d.ts +70 -0
- package/dist/guardian/index.d.ts.map +1 -0
- package/dist/guardian/index.js +271 -0
- package/dist/guardian/index.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +76 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/examples/backend-schema.ts +72 -0
- package/examples/frontend-schema.ts +67 -0
- package/examples/health-checks.ts +196 -0
- package/examples/solo-integration/README.md +457 -0
- package/examples/solo-integration/package.json +47 -0
- package/examples/team-integration/README.md +347 -0
- package/examples/team-integration/package.json +23 -0
- package/package.json +104 -0
- package/solo/README.md +258 -0
- package/solo/config/performance-budget.json +53 -0
- package/solo/config/solo-contract.json +71 -0
- package/solo/lib/feature-flags.ts +177 -0
- package/solo/scripts/cerber-auto-repair.js +260 -0
- package/solo/scripts/cerber-daily-check.js +282 -0
- package/solo/scripts/cerber-dashboard.js +191 -0
- package/solo/scripts/cerber-deps-health.js +247 -0
- package/solo/scripts/cerber-docs-sync.js +304 -0
- package/solo/scripts/cerber-flags-check.js +229 -0
- package/solo/scripts/cerber-performance-budget.js +271 -0
- package/solo/scripts/cerber-rollback.js +229 -0
- package/solo/scripts/cerber-snapshot.js +319 -0
- package/team/README.md +327 -0
- package/team/config/team-contract.json +27 -0
- package/team/lib/module-system.ts +157 -0
- package/team/scripts/cerber-add-module.sh +195 -0
- package/team/scripts/cerber-connections-check.sh +186 -0
- package/team/scripts/cerber-focus.sh +170 -0
- package/team/scripts/cerber-module-check.sh +165 -0
- package/team/scripts/cerber-team-morning.sh +210 -0
- package/team/templates/BIBLE_TEMPLATE.md +52 -0
- package/team/templates/CONNECTION_TEMPLATE.json +20 -0
- package/team/templates/MODULE_TEMPLATE.md +60 -0
package/solo/README.md
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
# 🛡️ Cerber SOLO
|
|
2
|
+
|
|
3
|
+
> **Automation tools for solo developers**
|
|
4
|
+
|
|
5
|
+
Extends Cerber Core (Guardian 1.0 + Cerber 2.1) with intelligent automation specifically designed for solo developers.
|
|
6
|
+
|
|
7
|
+
**Author:** Stefan Pitek
|
|
8
|
+
**Version:** 2.0
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 🎯 What is Cerber SOLO?
|
|
13
|
+
|
|
14
|
+
Cerber SOLO adds an automation layer on top of Guardian and Cerber, providing:
|
|
15
|
+
|
|
16
|
+
- **Auto-repair** - Fixes package.json, .env.example, CHANGELOG automatically
|
|
17
|
+
- **Performance budget** - Enforces bundle size limits
|
|
18
|
+
- **Dependency health** - Weekly security & deprecation checks
|
|
19
|
+
- **Documentation sync** - Validates code vs docs
|
|
20
|
+
- **Feature flags** - Toggle features without redeploy
|
|
21
|
+
- **Daily dashboard** - Morning health overview
|
|
22
|
+
- **Smart rollback** - Surgical file rollback
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## ⚡ Quick Start
|
|
27
|
+
|
|
28
|
+
### Add Scripts to package.json
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"scripts": {
|
|
33
|
+
"cerber:morning": "node solo/scripts/cerber-daily-check.js",
|
|
34
|
+
"cerber:repair": "node solo/scripts/cerber-auto-repair.js",
|
|
35
|
+
"cerber:deps": "node solo/scripts/cerber-deps-health.js",
|
|
36
|
+
"cerber:perf": "node solo/scripts/cerber-performance-budget.js",
|
|
37
|
+
"cerber:docs": "node solo/scripts/cerber-docs-sync.js",
|
|
38
|
+
"cerber:flags": "node solo/scripts/cerber-flags-check.js",
|
|
39
|
+
"cerber:snapshot": "node solo/scripts/cerber-snapshot.js",
|
|
40
|
+
"cerber:pre-push": "npm run cerber:deps && npm run cerber:docs && npm run cerber:perf"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Daily Workflow
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# Morning
|
|
49
|
+
npm run cerber:morning # Start day (2 min)
|
|
50
|
+
|
|
51
|
+
# Development
|
|
52
|
+
npm run cerber:repair # Auto-fix issues
|
|
53
|
+
git commit # Guardian validates
|
|
54
|
+
|
|
55
|
+
# Before Push
|
|
56
|
+
npm run cerber:pre-push # Full check (3 min)
|
|
57
|
+
|
|
58
|
+
# End of Day
|
|
59
|
+
npm run cerber:snapshot # Capture progress
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 📚 Tools Overview
|
|
65
|
+
|
|
66
|
+
### 🔧 Auto-Repair
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npm run cerber:repair
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Automatically fixes:**
|
|
73
|
+
- Format and sort package.json
|
|
74
|
+
- Sync .env.example with code
|
|
75
|
+
- Generate CHANGELOG from git log
|
|
76
|
+
- Remove console.logs (with approval)
|
|
77
|
+
|
|
78
|
+
### 🏥 Dependency Health
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npm run cerber:deps
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Checks:**
|
|
85
|
+
- Security vulnerabilities
|
|
86
|
+
- Outdated packages
|
|
87
|
+
- Deprecated packages
|
|
88
|
+
- Lock file sync
|
|
89
|
+
|
|
90
|
+
**Output:** Health score (0-100) and actionable report
|
|
91
|
+
|
|
92
|
+
### 📊 Performance Budget
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
npm run cerber:perf
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Enforces:**
|
|
99
|
+
- Total bundle size limit (500 KB)
|
|
100
|
+
- Largest chunk limit (250 KB)
|
|
101
|
+
- Image size constraints
|
|
102
|
+
|
|
103
|
+
**Configuration:** `solo/config/performance-budget.json`
|
|
104
|
+
|
|
105
|
+
### 📚 Documentation Sync
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
npm run cerber:docs
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Validates:**
|
|
112
|
+
- API endpoints in code vs README
|
|
113
|
+
- ENV vars in code vs .env.example
|
|
114
|
+
- Detects stale documentation
|
|
115
|
+
|
|
116
|
+
### 🚩 Feature Flags
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
npm run cerber:flags
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Checks:**
|
|
123
|
+
- Active flags
|
|
124
|
+
- Expired flags
|
|
125
|
+
- Per-environment status
|
|
126
|
+
|
|
127
|
+
**TypeScript API:** `solo/lib/feature-flags.ts`
|
|
128
|
+
|
|
129
|
+
### ⏪ Smart Rollback
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
node solo/scripts/cerber-rollback.js <hash> --file=path.ts
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Features:**
|
|
136
|
+
- Rollback specific file from commit
|
|
137
|
+
- Safety checks
|
|
138
|
+
- Diff preview
|
|
139
|
+
- Dry-run mode
|
|
140
|
+
|
|
141
|
+
### ☀️ Daily Check
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
npm run cerber:morning
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Shows:**
|
|
148
|
+
- Backend health
|
|
149
|
+
- Guardian status
|
|
150
|
+
- Git status
|
|
151
|
+
- Yesterday's snapshot
|
|
152
|
+
- Today's priorities
|
|
153
|
+
|
|
154
|
+
### 📸 Snapshot
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
npm run cerber:snapshot
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
**Captures:**
|
|
161
|
+
- Git statistics
|
|
162
|
+
- File counts
|
|
163
|
+
- LOC metrics
|
|
164
|
+
- Saves to `.cerber/snapshots/` (30-day retention)
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## 🎨 Feature Flags
|
|
169
|
+
|
|
170
|
+
### Usage
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
import { isFeatureEnabled } from './solo/lib/feature-flags';
|
|
174
|
+
|
|
175
|
+
if (isFeatureEnabled('new-feature')) {
|
|
176
|
+
// Show new feature
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Configuration
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
export const FLAGS = {
|
|
184
|
+
"new-ui": {
|
|
185
|
+
enabled: true,
|
|
186
|
+
description: "New UI redesign",
|
|
187
|
+
owner: "team",
|
|
188
|
+
environments: ["development", "staging"],
|
|
189
|
+
expiresAt: "2026-06-01"
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## 🔧 Configuration
|
|
197
|
+
|
|
198
|
+
### Main Config
|
|
199
|
+
|
|
200
|
+
**File:** `solo/config/solo-contract.json`
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
{
|
|
204
|
+
"version": "2.0-solo",
|
|
205
|
+
"autoRepair": {
|
|
206
|
+
"enabled": true,
|
|
207
|
+
"safe": ["format-package-json", "sync-env", "changelog"]
|
|
208
|
+
},
|
|
209
|
+
"performanceBudget": {
|
|
210
|
+
"bundleSize": { "max": 500, "warning": 400 }
|
|
211
|
+
},
|
|
212
|
+
"snapshots": {
|
|
213
|
+
"retentionDays": 30
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## 📖 Full Documentation
|
|
221
|
+
|
|
222
|
+
**[Read complete documentation →](../docs/SOLO.md)**
|
|
223
|
+
|
|
224
|
+
- Installation
|
|
225
|
+
- Daily workflow
|
|
226
|
+
- Command reference
|
|
227
|
+
- Integration with Guardian
|
|
228
|
+
- Troubleshooting
|
|
229
|
+
- Best practices
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## 🤝 Integration with Guardian
|
|
234
|
+
|
|
235
|
+
Cerber SOLO works **alongside** your existing Guardian setup:
|
|
236
|
+
|
|
237
|
+
```
|
|
238
|
+
Morning: npm run cerber:morning # SOLO dashboard
|
|
239
|
+
Development: git commit # Guardian validates
|
|
240
|
+
Before Push: npm run cerber:pre-push # SOLO checks
|
|
241
|
+
Deploy: curl /api/health # Cerber 2.1 validates
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## 💡 Example Project
|
|
247
|
+
|
|
248
|
+
See [`examples/solo-integration/`](../examples/solo-integration/) for complete integration example.
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## 📄 License
|
|
253
|
+
|
|
254
|
+
MIT © 2026 Stefan Pitek
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
**Built with ❤️ for solo developers**
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.0",
|
|
3
|
+
"description": "Performance budget configuration for Cerber SOLO",
|
|
4
|
+
|
|
5
|
+
"bundleSize": {
|
|
6
|
+
"max": 500,
|
|
7
|
+
"warning": 400,
|
|
8
|
+
"unit": "KB",
|
|
9
|
+
"description": "Total bundle size limit"
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
"largestChunk": {
|
|
13
|
+
"max": 250,
|
|
14
|
+
"warning": 200,
|
|
15
|
+
"unit": "KB",
|
|
16
|
+
"description": "Maximum size for a single chunk"
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
"images": {
|
|
20
|
+
"max": 200,
|
|
21
|
+
"unit": "KB",
|
|
22
|
+
"description": "Maximum image file size"
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
"thresholds": {
|
|
26
|
+
"critical": {
|
|
27
|
+
"description": "Build fails if exceeded",
|
|
28
|
+
"bundleSize": 500,
|
|
29
|
+
"chunkSize": 250
|
|
30
|
+
},
|
|
31
|
+
"warning": {
|
|
32
|
+
"description": "Warning issued but build continues",
|
|
33
|
+
"bundleSize": 400,
|
|
34
|
+
"chunkSize": 200
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
"excludePaths": [
|
|
39
|
+
"node_modules",
|
|
40
|
+
"dist",
|
|
41
|
+
"build",
|
|
42
|
+
"coverage",
|
|
43
|
+
".next"
|
|
44
|
+
],
|
|
45
|
+
|
|
46
|
+
"recommendations": [
|
|
47
|
+
"Enable code splitting",
|
|
48
|
+
"Use dynamic imports",
|
|
49
|
+
"Compress images",
|
|
50
|
+
"Remove unused dependencies",
|
|
51
|
+
"Analyze bundle with webpack-bundle-analyzer"
|
|
52
|
+
]
|
|
53
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "2.0-solo",
|
|
3
|
+
"extends": "cerber-core",
|
|
4
|
+
"description": "Cerber SOLO configuration for solo developers",
|
|
5
|
+
|
|
6
|
+
"autoRepair": {
|
|
7
|
+
"enabled": true,
|
|
8
|
+
"safe": [
|
|
9
|
+
"format-package-json",
|
|
10
|
+
"sync-env",
|
|
11
|
+
"changelog"
|
|
12
|
+
],
|
|
13
|
+
"description": "Automatically repair common issues"
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
"performanceBudget": {
|
|
17
|
+
"bundleSize": {
|
|
18
|
+
"max": 500,
|
|
19
|
+
"warning": 400,
|
|
20
|
+
"unit": "KB"
|
|
21
|
+
},
|
|
22
|
+
"largestChunk": {
|
|
23
|
+
"max": 250,
|
|
24
|
+
"warning": 200,
|
|
25
|
+
"unit": "KB"
|
|
26
|
+
},
|
|
27
|
+
"images": {
|
|
28
|
+
"max": 200,
|
|
29
|
+
"unit": "KB"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
"snapshots": {
|
|
34
|
+
"enabled": true,
|
|
35
|
+
"retentionDays": 30,
|
|
36
|
+
"directory": ".cerber/snapshots"
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
"dailyChecks": {
|
|
40
|
+
"enabled": true,
|
|
41
|
+
"healthEndpoints": [
|
|
42
|
+
"http://localhost:3000/api/health",
|
|
43
|
+
"http://localhost:4000/api/health",
|
|
44
|
+
"http://localhost:5000/api/health"
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"checkVulnerabilities": true,
|
|
50
|
+
"checkOutdated": true,
|
|
51
|
+
"checkDeprecated": true,
|
|
52
|
+
"healthScoreThreshold": 60
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
"documentation": {
|
|
56
|
+
"syncEnabled": true,
|
|
57
|
+
"checkEndpoints": true,
|
|
58
|
+
"checkEnvVars": true,
|
|
59
|
+
"checkTodos": true
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
"featureFlags": {
|
|
63
|
+
"enabled": true,
|
|
64
|
+
"checkExpired": true
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
"rollback": {
|
|
68
|
+
"safetyChecks": true,
|
|
69
|
+
"requireCleanWorkingDirectory": true
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cerber SOLO - Feature Flags System
|
|
3
|
+
*
|
|
4
|
+
* Extends Cerber Core with automation for solo developers
|
|
5
|
+
*
|
|
6
|
+
* @author Stefan Pitek
|
|
7
|
+
* @copyright 2026 Stefan Pitek
|
|
8
|
+
* @license MIT
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export type FeatureFlag = string;
|
|
12
|
+
|
|
13
|
+
export interface FlagConfig {
|
|
14
|
+
enabled: boolean;
|
|
15
|
+
description: string;
|
|
16
|
+
owner: string;
|
|
17
|
+
expiresAt?: string;
|
|
18
|
+
environments?: ("development" | "staging" | "production")[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface FeatureFlagsConfig {
|
|
22
|
+
[key: string]: FlagConfig;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Default feature flags configuration
|
|
27
|
+
*/
|
|
28
|
+
const defaultFlags: FeatureFlagsConfig = {
|
|
29
|
+
"example-feature": {
|
|
30
|
+
enabled: false,
|
|
31
|
+
description: "Example feature flag",
|
|
32
|
+
owner: "team",
|
|
33
|
+
environments: ["development"]
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Load feature flags from environment or use defaults
|
|
39
|
+
*/
|
|
40
|
+
let featureFlags: FeatureFlagsConfig = defaultFlags;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Initialize feature flags with custom configuration
|
|
44
|
+
* @param config - Custom feature flags configuration
|
|
45
|
+
*/
|
|
46
|
+
export function initializeFeatureFlags(config: FeatureFlagsConfig): void {
|
|
47
|
+
featureFlags = { ...defaultFlags, ...config };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Check if a feature flag is enabled
|
|
52
|
+
* @param flag - Feature flag name
|
|
53
|
+
* @returns true if the flag is enabled, false otherwise
|
|
54
|
+
*/
|
|
55
|
+
export function isFeatureEnabled(flag: FeatureFlag): boolean {
|
|
56
|
+
const config = featureFlags[flag];
|
|
57
|
+
|
|
58
|
+
if (!config) {
|
|
59
|
+
console.warn(`Feature flag "${flag}" not found, defaulting to false`);
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Check if flag is enabled
|
|
64
|
+
if (!config.enabled) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Check environment restrictions
|
|
69
|
+
if (config.environments && config.environments.length > 0) {
|
|
70
|
+
const currentEnv = process.env.NODE_ENV || "development";
|
|
71
|
+
if (!config.environments.includes(currentEnv as any)) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Check expiry date
|
|
77
|
+
if (config.expiresAt) {
|
|
78
|
+
const expiryDate = new Date(config.expiresAt);
|
|
79
|
+
const now = new Date();
|
|
80
|
+
|
|
81
|
+
if (now > expiryDate) {
|
|
82
|
+
console.warn(`Feature flag "${flag}" has expired on ${config.expiresAt}`);
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* React hook for feature flags
|
|
92
|
+
* @param flag - Feature flag name
|
|
93
|
+
* @returns true if the flag is enabled, false otherwise
|
|
94
|
+
*/
|
|
95
|
+
export function useFeatureFlag(flag: FeatureFlag): boolean {
|
|
96
|
+
return isFeatureEnabled(flag);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Higher-order component for conditional rendering based on feature flags
|
|
101
|
+
* @param flag - Feature flag name
|
|
102
|
+
* @param Component - Component to render if flag is enabled
|
|
103
|
+
* @param Fallback - Optional fallback component if flag is disabled
|
|
104
|
+
* @returns Component or Fallback based on flag status
|
|
105
|
+
*/
|
|
106
|
+
export function withFeatureFlag(
|
|
107
|
+
flag: FeatureFlag,
|
|
108
|
+
Component: any,
|
|
109
|
+
Fallback?: any
|
|
110
|
+
): any {
|
|
111
|
+
return function FeatureFlagWrapper(props: any) {
|
|
112
|
+
const isEnabled = isFeatureEnabled(flag);
|
|
113
|
+
|
|
114
|
+
if (isEnabled) {
|
|
115
|
+
return Component(props);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (Fallback) {
|
|
119
|
+
return Fallback(props);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return null;
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Get all feature flags
|
|
128
|
+
* @returns All feature flags configuration
|
|
129
|
+
*/
|
|
130
|
+
export function getAllFlags(): FeatureFlagsConfig {
|
|
131
|
+
return { ...featureFlags };
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Get enabled feature flags
|
|
136
|
+
* @returns List of enabled feature flag names
|
|
137
|
+
*/
|
|
138
|
+
export function getEnabledFlags(): string[] {
|
|
139
|
+
return Object.keys(featureFlags).filter(flag => isFeatureEnabled(flag));
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Get feature flag configuration
|
|
144
|
+
* @param flag - Feature flag name
|
|
145
|
+
* @returns Feature flag configuration or undefined
|
|
146
|
+
*/
|
|
147
|
+
export function getFlagConfig(flag: FeatureFlag): FlagConfig | undefined {
|
|
148
|
+
return featureFlags[flag];
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Check if a feature flag exists
|
|
153
|
+
* @param flag - Feature flag name
|
|
154
|
+
* @returns true if the flag exists, false otherwise
|
|
155
|
+
*/
|
|
156
|
+
export function flagExists(flag: FeatureFlag): boolean {
|
|
157
|
+
return flag in featureFlags;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Get expired feature flags
|
|
162
|
+
* @returns List of expired feature flag names
|
|
163
|
+
*/
|
|
164
|
+
export function getExpiredFlags(): string[] {
|
|
165
|
+
const now = new Date();
|
|
166
|
+
|
|
167
|
+
return Object.keys(featureFlags).filter(flag => {
|
|
168
|
+
const config = featureFlags[flag];
|
|
169
|
+
if (!config.expiresAt) return false;
|
|
170
|
+
|
|
171
|
+
const expiryDate = new Date(config.expiresAt);
|
|
172
|
+
return now > expiryDate;
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Export types
|
|
177
|
+
export type { FeatureFlag, FlagConfig, FeatureFlagsConfig };
|