@nestarc/feature-flag 0.4.0 → 0.6.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/CHANGELOG.md +186 -0
- package/README.md +130 -681
- package/dist/admin/feature-flag-admin.dto.d.ts +4 -3
- package/dist/admin/feature-flag-admin.dto.js +19 -13
- package/dist/admin/feature-flag-admin.dto.js.map +1 -1
- package/dist/feature-flag.module.d.ts +4 -1
- package/dist/feature-flag.module.js +37 -10
- package/dist/feature-flag.module.js.map +1 -1
- package/dist/flag-registry.js +3 -0
- package/dist/flag-registry.js.map +1 -1
- package/dist/interfaces/evaluation-context.interface.d.ts +5 -5
- package/dist/interfaces/evaluation-details.interface.d.ts +2 -0
- package/dist/interfaces/feature-flag-options.interface.d.ts +19 -5
- package/dist/interfaces/feature-flag.interface.d.ts +2 -2
- package/dist/openfeature.d.ts +6 -9
- package/dist/openfeature.js +38 -8
- package/dist/openfeature.js.map +1 -1
- package/dist/repositories/prisma-feature-flag.repository.js +9 -6
- package/dist/repositories/prisma-feature-flag.repository.js.map +1 -1
- package/dist/services/feature-flag.service.js +4 -2
- package/dist/services/feature-flag.service.js.map +1 -1
- package/dist/services/flag-context-resolver.js +1 -0
- package/dist/services/flag-context-resolver.js.map +1 -1
- package/docs/usage.md +720 -0
- package/package.json +30 -10
- package/prisma/schema.prisma +3 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@nestarc/feature-flag` will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [0.6.0] — 2026-09-10
|
|
6
|
+
|
|
7
|
+
Version 0.6.0 adds module provider options and corrects evaluation and SDK integration behavior from 0.5.0.
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- Accept custom `repository` and `tenantContextProvider` instances in synchronous and asynchronous module registration; Prisma is required only when no repository is supplied.
|
|
11
|
+
- Add invocation-level `bucketBy` selection, including the Admin evaluation endpoint.
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
- Preserve explicit `targetingKey` during service context resolution.
|
|
15
|
+
- Apply registry `bucketBy` to typed clients and bulk evaluation.
|
|
16
|
+
- Reject null and non-integer percentages before Prisma and align nullable description/context types with runtime behavior.
|
|
17
|
+
- Provide and test an OpenFeature SDK-compatible provider with boolean resolution and explicit unsupported-type errors.
|
|
18
|
+
|
|
19
|
+
### Documentation and verification
|
|
20
|
+
- Add a complete consumer guide, runnable standalone examples, and checks against a packed package in CI.
|
|
21
|
+
- Correct cache consistency, dependency, evaluation, and performance descriptions; link the existing 0.5 upgrade notes.
|
|
22
|
+
- Isolate benchmark data in a disposable schema and support environment metadata and raw timing output.
|
|
23
|
+
- Include the consumer guide and changelog in package files and connect npm metadata to the official documentation.
|
|
24
|
+
|
|
25
|
+
### Migration
|
|
26
|
+
- No Prisma schema migration is required from 0.5.0.
|
|
27
|
+
- Use the new module options for custom repositories and tenant providers; tokens declared only in an importing module do not replace this module's providers.
|
|
28
|
+
- Install `@openfeature/server-sdk@^1.23.0` when consuming the `/openfeature` entry point's public TypeScript types.
|
|
29
|
+
- Review partial-rollout cohorts if you previously supplied `targetingKey` or registry `bucketBy`: these values are now applied consistently, so existing evaluation results can change.
|
|
30
|
+
|
|
31
|
+
## [0.5.0] — 2026-08-02
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
- Prisma 7 is now the supported Prisma major (`prisma` and `@prisma/client` 7.9.1 in development)
|
|
35
|
+
- Prisma Client generation now uses the `prisma-client` generator with an explicit output path
|
|
36
|
+
- PostgreSQL tests, benchmarks, and examples now create Prisma Client with `@prisma/adapter-pg`
|
|
37
|
+
- Prisma CLI connection configuration moved from `schema.prisma` to `prisma.config.ts`
|
|
38
|
+
- Node.js 20.19+, 22.12+, or 24+ is now required to match Prisma 7
|
|
39
|
+
|
|
40
|
+
### Migration
|
|
41
|
+
- Install `@prisma/adapter-pg` and `pg`, then pass a `PrismaPg` adapter to `PrismaClient`
|
|
42
|
+
- Import `PrismaClient` from the generated output path instead of `@prisma/client`
|
|
43
|
+
- Move `DATABASE_URL` into `prisma.config.ts`; no database migration is required
|
|
44
|
+
|
|
45
|
+
## [0.4.0] — 2026-06-20
|
|
46
|
+
|
|
47
|
+
### Added
|
|
48
|
+
- `FeatureFlagService.evaluateBoolean()` for detailed boolean evaluation results with `source`, `reason`, `defaultUsed`, `bucket`, `targetingKey`, and timing metadata
|
|
49
|
+
- Invocation-level fallback via `EvaluateBooleanOptions.defaultValue`
|
|
50
|
+
- `FeatureFlagGuardOptions.defaultValue` for route-level missing/error fallback
|
|
51
|
+
- `EvaluationContext.targetingKey` and registry/metadata `bucketBy` support for explicit rollout bucketing
|
|
52
|
+
- Type-safe registry helpers: `defineFlags()`, `createFeatureFlagClient()`, `createFeatureFlagDecorators()`, and lifecycle status helpers
|
|
53
|
+
- `FeatureFlagModuleOptions.flags` for registry defaults, bucket keys, and exposure settings
|
|
54
|
+
- `FeatureFlagEvents.EXPOSED` opt-in exposure events
|
|
55
|
+
- Mutation event metadata fields: `actorId`, `actorType`, `reason`, `requestId`, and `correlationId`
|
|
56
|
+
- `TestFeatureFlagModule.registerRegistry()` and injectable `TestFeatureFlagController`
|
|
57
|
+
- Boolean-only OpenFeature provider adapter at `@nestarc/feature-flag/openfeature`
|
|
58
|
+
- Admin API `POST /feature-flags/:key/evaluate` endpoint
|
|
59
|
+
|
|
60
|
+
### Changed
|
|
61
|
+
- `isEnabled()` now delegates to `evaluateBoolean()` and returns its `value`
|
|
62
|
+
- Missing flags now emit a structured `feature-flag.evaluated` event with reason `FLAG_NOT_FOUND`
|
|
63
|
+
- Percentage rollout keeps the legacy `userId ?? tenantId` fallback unless `targetingKey` or `bucketBy` is provided
|
|
64
|
+
- `FlagEvaluatedEvent` now includes detailed evaluation fields
|
|
65
|
+
- Package version is now `0.4.0`
|
|
66
|
+
|
|
67
|
+
### Migration
|
|
68
|
+
- No Prisma migration is required for v0.4.0 core features.
|
|
69
|
+
- OpenFeature support is optional and does not require the SDK unless you wire the adapter into an OpenFeature setup.
|
|
70
|
+
- Variant flags, reusable rule segments, persisted audit logs, and persisted exposure analytics remain out of scope for this release.
|
|
71
|
+
|
|
72
|
+
## [0.3.0] — 2026-05-12
|
|
73
|
+
|
|
74
|
+
### Added
|
|
75
|
+
- Attribute-based override targeting with non-empty `attributes` JSON objects
|
|
76
|
+
- Override `priority` for tie-breaking between matching overrides with the same specificity
|
|
77
|
+
- Admin API DTO validation with `class-validator` and `class-transformer`
|
|
78
|
+
- Automatic Prisma migration from fixed override columns to `attributes`
|
|
79
|
+
- Top-level `userId`, `tenantId`, and `environment` merge into targeting attributes during evaluation
|
|
80
|
+
- Example apps for basic route guards, multi-tenant attribute targeting, and Redis events
|
|
81
|
+
|
|
82
|
+
### Changed
|
|
83
|
+
- `SetOverrideInput` and `RemoveOverrideInput` now use `attributes`
|
|
84
|
+
- `FlagOverride` now exposes `attributes` and `priority`
|
|
85
|
+
- Override evaluation now matches exact attribute key/value pairs instead of a fixed tenant/user/environment hierarchy
|
|
86
|
+
- Matching override tie-break order is more attributes, higher `priority`, earlier `createdAt`, then lower `id`
|
|
87
|
+
- Evaluation event source now uses `override` for matched attribute overrides
|
|
88
|
+
- `FeatureFlagOverride` storage now uses `attributes` `jsonb` plus `priority`
|
|
89
|
+
|
|
90
|
+
### Breaking
|
|
91
|
+
- Removed direct override fields `tenantId`, `userId`, and `environment`
|
|
92
|
+
- Removed `FeatureFlagRepository.updateOverrideEnabled()`
|
|
93
|
+
- `setOverride()` and Admin API override requests now require a non-empty `attributes` object
|
|
94
|
+
- Legacy override bodies such as `{ "tenantId": "tenant-1", "enabled": true }` are rejected
|
|
95
|
+
- Prisma schema migration is required
|
|
96
|
+
- Legacy global override rows with `tenant_id`, `user_id`, and `environment` all `NULL` are removed during migration
|
|
97
|
+
- Duplicate legacy override rows that backfill to the same `(flag_id, attributes)` are deduplicated during migration
|
|
98
|
+
- `feature_flag_overrides` no longer stores `tenant_id`, `user_id`, or `environment` columns
|
|
99
|
+
|
|
100
|
+
### Migration
|
|
101
|
+
- Run `npx prisma migrate deploy`
|
|
102
|
+
- Legacy `tenant_id`, `user_id`, and `environment` values are backfilled to `attributes.tenantId`, `attributes.userId`, and `attributes.environment`
|
|
103
|
+
- Duplicate backfilled overrides keep the latest `updated_at`, then latest `created_at`, then highest `id`
|
|
104
|
+
- Replace `{ "tenantId": "t-1", "enabled": true }` with `{ "attributes": { "tenantId": "t-1" }, "enabled": true }`
|
|
105
|
+
- Use `{ "attributes": { "tenantId": "tenant-1" }, "enabled": true }` for Admin API override requests
|
|
106
|
+
- Install `class-validator` and `class-transformer` with the required peer dependencies
|
|
107
|
+
|
|
108
|
+
## [0.2.0] — 2026-04-10
|
|
109
|
+
|
|
110
|
+
### Added
|
|
111
|
+
- `CacheAdapter` interface for pluggable cache backends
|
|
112
|
+
- `MemoryCacheAdapter` (refactored from internal FlagCacheService)
|
|
113
|
+
- `RedisCacheAdapter` with Redis Pub/Sub for cross-instance cache invalidation (SCAN-based flush)
|
|
114
|
+
- `FeatureFlagAdminModule` — opt-in REST Admin API with guard injection
|
|
115
|
+
- `POST /feature-flags` — create flag (409 on duplicate key)
|
|
116
|
+
- `GET /feature-flags` — list all flags
|
|
117
|
+
- `GET /feature-flags/:key` — get single flag (404 on missing)
|
|
118
|
+
- `PATCH /feature-flags/:key` — update flag (404 on missing)
|
|
119
|
+
- `DELETE /feature-flags/:key` — archive flag (404 on missing)
|
|
120
|
+
- `POST /feature-flags/:key/overrides` — set override (404 on missing flag)
|
|
121
|
+
- `DELETE /feature-flags/:key/overrides` — remove override (404 on missing flag)
|
|
122
|
+
- `FeatureFlagRepository` interface — pluggable persistence port for custom backends
|
|
123
|
+
- `PrismaFeatureFlagRepository` — default Prisma implementation with error mapping
|
|
124
|
+
- `TenantContextProvider` interface — pluggable tenant resolution port
|
|
125
|
+
- `DefaultTenantContextProvider` — automatic `@nestarc/tenancy` integration
|
|
126
|
+
- `FlagEventPublisher` — extracted conditional event emission service
|
|
127
|
+
- `FlagContextResolver` — extracted ambient/explicit context merge service
|
|
128
|
+
- `findByKey()` method on FeatureFlagService (throws NotFoundException)
|
|
129
|
+
- `removeOverride()` method on FeatureFlagService
|
|
130
|
+
- `RemoveOverrideInput` type
|
|
131
|
+
- `CACHE_ADAPTER`, `FEATURE_FLAG_REPOSITORY`, `TENANT_CONTEXT_PROVIDER` injection tokens
|
|
132
|
+
- `ioredis` as optional peer dependency
|
|
133
|
+
- Cache adapter contract test suite (`cache-adapter.contract.spec.ts`)
|
|
134
|
+
- Admin REST e2e test suite (`admin.e2e-spec.ts`)
|
|
135
|
+
- Redis cross-instance invalidation e2e test suite (`redis-cache.e2e-spec.ts`)
|
|
136
|
+
- Percentage (0-100) range validation in repository layer
|
|
137
|
+
|
|
138
|
+
### Changed
|
|
139
|
+
- All cache operations are now async (`CacheAdapter` interface)
|
|
140
|
+
- `cacheAdapter` option added to `FeatureFlagModuleOptions` (optional, defaults to `MemoryCacheAdapter`)
|
|
141
|
+
- `FeatureFlagService` now depends on `FeatureFlagRepository` instead of direct Prisma access
|
|
142
|
+
- Cache invalidation on mutation paths is now best-effort (non-fatal); stale entries self-heal via TTL
|
|
143
|
+
- `TestFeatureFlagModule` mock methods now return full `FeatureFlagWithOverrides` objects (LSP compliance)
|
|
144
|
+
- `RemoveOverrideInput` moved from `cache-adapter.interface` to `feature-flag.interface` (ISP)
|
|
145
|
+
- `FeatureFlagAdminModule` uses standard NestJS DI instead of `ModuleRef.get()` for service resolution
|
|
146
|
+
|
|
147
|
+
### Fixed
|
|
148
|
+
- `setOverride()` now throws `NotFoundException` (was generic `Error` causing 500)
|
|
149
|
+
- Admin `create()` returns 409 Conflict on duplicate key (was 500)
|
|
150
|
+
- Admin `update()`/`archive()` return 404 on missing key (was 500)
|
|
151
|
+
- Override race condition: concurrent `setOverride()` calls no longer 500 on unique index violation
|
|
152
|
+
- Override `deleteOverride()` is idempotent (concurrent delete no longer 500)
|
|
153
|
+
|
|
154
|
+
### Removed
|
|
155
|
+
- `FlagCacheService` (internal, replaced by `CacheAdapter` + `MemoryCacheAdapter`)
|
|
156
|
+
- Direct `prisma: any` dependency in `FeatureFlagService` (replaced by `FeatureFlagRepository`)
|
|
157
|
+
- `ModuleRef` dependency in `FeatureFlagService` (tenancy resolved via `TenantContextProvider`)
|
|
158
|
+
|
|
159
|
+
## [0.1.0] - 2026-04-05
|
|
160
|
+
|
|
161
|
+
### Added
|
|
162
|
+
|
|
163
|
+
- `FeatureFlagModule` with `forRoot` and `forRootAsync` (useFactory / useClass / useExisting) registration
|
|
164
|
+
- `FeatureFlagService` with CRUD operations: `create`, `update`, `archive`, `findAll`
|
|
165
|
+
- `isEnabled()` and `evaluateAll()` for flag evaluation with 6-layer cascade priority
|
|
166
|
+
- `setOverride()` for user / tenant / environment context-specific overrides
|
|
167
|
+
- `@FeatureFlag()` decorator with built-in `UseGuards(FeatureFlagGuard)` for automatic route gating
|
|
168
|
+
- `@BypassFeatureFlag()` decorator to exempt specific routes from guard checks
|
|
169
|
+
- `FlagContextMiddleware` with `AsyncLocalStorage` for request-scoped userId extraction
|
|
170
|
+
- `FlagCacheService` with configurable TTL-based in-memory caching
|
|
171
|
+
- `FlagEvaluatorService` with 5-layer override hierarchy and murmurhash3-based percentage rollout
|
|
172
|
+
- Optional `@nestjs/event-emitter` integration (`emitEvents: true`) sharing NestJS-managed `EventEmitter2` singleton
|
|
173
|
+
- `TestFeatureFlagModule` at `@nestarc/feature-flag/testing` for unit/integration test support
|
|
174
|
+
- Prisma schema with partial unique indexes for NULL-safe override uniqueness on PostgreSQL
|
|
175
|
+
- Docker Compose + e2e test environment with real PostgreSQL (service-level + HTTP tests)
|
|
176
|
+
- Explicit `null` context support: `{ userId: null }` suppresses ambient context from ALS
|
|
177
|
+
|
|
178
|
+
### Fixed
|
|
179
|
+
|
|
180
|
+
- Override uniqueness: replaced broken `@@unique` compound constraint with 8 partial unique indexes to handle PostgreSQL `NULL != NULL` semantics
|
|
181
|
+
- `allFlagsCache` staleness: per-key `invalidate(key)` now also clears the all-flags cache
|
|
182
|
+
- `forRootAsync` double factory invocation: introduced intermediate `FULL_OPTIONS` provider so factory runs exactly once
|
|
183
|
+
- `EVENT_EMITTER` isolation: changed from `new EventEmitter2()` to `useExisting` / `ModuleRef.get()` so `@OnEvent` listeners receive feature-flag events
|
|
184
|
+
- `@FeatureFlag()` fail-open: decorator now includes `UseGuards(FeatureFlagGuard)` automatically
|
|
185
|
+
- `buildContext()` null semantics: explicit `null` in `EvaluationContext` now overrides ambient values instead of falling through
|
|
186
|
+
- Lint errors: resolved unused destructured variable and unsafe `Function` type in guard tests
|