flaglint 0.3.0 → 0.4.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 +37 -0
- package/README.md +185 -81
- package/dist/bin/flaglint.js +941 -210
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,43 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.4.0] - 2026-05-24
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Release preparation: bump package version to 0.4.0, normalize repository URL, and adjust release workflow to publish only from manual GitHub Releases. No publish or tag created by this change.
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **`flaglint migrate --dry-run`**: Generates reviewable before/after diffs for every automatable
|
|
19
|
+
call-site, including inline provider setup guidance (packages, bootstrap file, `targetingKey`
|
|
20
|
+
context requirement). Does not write any files; output is to stdout.
|
|
21
|
+
|
|
22
|
+
- **Docs**: Repositioned public copy and website messaging to explicitly state scope (LaunchDarkly Node.js server SDK only), clarify that `--apply` is guarded, confirm provider/bootstrap setup is manual, and limit precision/recall claims to the 120 deterministic benchmark cases within that supported scope.
|
|
23
|
+
|
|
24
|
+
- **`flaglint migrate --apply`**: Applies only guarded, provably automatable transformations
|
|
25
|
+
in-place. Safety contracts: refuses on a dirty git working tree (override with `--allow-dirty`);
|
|
26
|
+
skips any file without a proven `openFeatureClient = OpenFeature.getClient()` binding from
|
|
27
|
+
`@openfeature/server-sdk` (AST-grounded, not regex); never rewrites detail methods, dynamic
|
|
28
|
+
keys, unknown fallbacks, or bulk calls; preserves `await` and all call arguments exactly;
|
|
29
|
+
idempotent (re-running a stale analysis is a no-op via range-content guard).
|
|
30
|
+
|
|
31
|
+
- **`flaglint validate [dir]`**: New command for CI enforcement.
|
|
32
|
+
- Without `--no-direct-launchdarkly`: reports usages, always exits 0.
|
|
33
|
+
- `--no-direct-launchdarkly`: exits 1 if any direct LaunchDarkly Node server evaluation call
|
|
34
|
+
is found (static, dynamic, detail, or bulk — all count as violations).
|
|
35
|
+
- `--bootstrap-exclude <glob>` (repeatable): exclude provider bootstrap files from violations.
|
|
36
|
+
Supports exact paths, `*` (within one directory), `**` (across directories), and `?` wildcards.
|
|
37
|
+
- Never claims flags are stale or safe to delete.
|
|
38
|
+
|
|
39
|
+
### Scope clarification
|
|
40
|
+
|
|
41
|
+
Current scope: **LaunchDarkly Node.js server-side SDK** (`launchdarkly-node-server-sdk`).
|
|
42
|
+
React hooks, HOC, and client-side SDK patterns are detected by `scan` but are not automatically
|
|
43
|
+
migrated by `--apply`.
|
|
44
|
+
|
|
8
45
|
## [0.3.0] - 2026-05-23
|
|
9
46
|
|
|
10
47
|
### Added
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
|
-
<strong>
|
|
6
|
+
<strong>LaunchDarkly Node.js server SDK -> OpenFeature migration</strong>
|
|
7
7
|
</p>
|
|
8
8
|
|
|
9
9
|
<p align="center">
|
|
@@ -21,35 +21,41 @@
|
|
|
21
21
|
</a>
|
|
22
22
|
</p>
|
|
23
23
|
|
|
24
|
+
> ⚠️ **Early preview.** Current scope: **LaunchDarkly Node.js server-side SDK** only.
|
|
25
|
+
> React hooks, HOC, and client-side SDK patterns are detected by `scan` but are not
|
|
26
|
+
> automatically migrated.
|
|
24
27
|
|
|
25
28
|
# FlagLint
|
|
26
29
|
|
|
27
|
-
|
|
28
|
-
migration
|
|
30
|
+
FlagLint inventories direct LaunchDarkly Node.js server SDK calls in your TypeScript/JavaScript
|
|
31
|
+
codebase, generates reviewable OpenFeature migration diffs, applies only guarded transformations,
|
|
32
|
+
and enforces migration state in CI.
|
|
29
33
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
## The problem
|
|
34
|
+
**LaunchDarkly remains your provider. OpenFeature becomes the evaluation API your application code calls.**
|
|
33
35
|
|
|
34
|
-
|
|
36
|
+
---
|
|
35
37
|
|
|
36
|
-
|
|
38
|
+
## Workflow
|
|
37
39
|
|
|
38
|
-
|
|
40
|
+
| Step | Command | Purpose |
|
|
41
|
+
|------|---------|---------|
|
|
42
|
+
| 1 | `flaglint scan` | AST inventory of every direct LD Node server SDK call |
|
|
43
|
+
| 2 | `flaglint migrate --dry-run` | Reviewable before/after diffs with provider setup guidance |
|
|
44
|
+
| 3 | `flaglint migrate --apply` | Apply only guarded, provably automatable transformations |
|
|
45
|
+
| 4 | `flaglint validate --no-direct-launchdarkly` | CI gate: exit 1 if direct LD calls remain |
|
|
39
46
|
|
|
40
47
|
---
|
|
41
48
|
|
|
42
49
|
## Quick start
|
|
43
50
|
|
|
44
51
|
```bash
|
|
45
|
-
npx flaglint scan
|
|
52
|
+
npx flaglint scan ./src
|
|
46
53
|
```
|
|
47
54
|
|
|
48
55
|
Example output:
|
|
49
56
|
|
|
50
57
|
```text
|
|
51
58
|
✓ 15 flag usages found across 6 unique flags (48ms)
|
|
52
|
-
⚠ 5 potentially stale flag(s) — review recommended
|
|
53
59
|
ℹ 1 dynamic flag key(s) require manual review
|
|
54
60
|
```
|
|
55
61
|
|
|
@@ -57,34 +63,25 @@ Markdown report excerpt:
|
|
|
57
63
|
|
|
58
64
|
```markdown
|
|
59
65
|
## Flag Inventory
|
|
60
|
-
| Flag Key | Usages | Files | Call Types |
|
|
61
|
-
|
|
62
|
-
|
|
|
63
|
-
|
|
|
64
|
-
|
|
|
65
|
-
|
|
66
|
-
## ⚠ Stale Flag Candidates
|
|
67
|
-
| Flag Key | Reason | Location |
|
|
68
|
-
|----------|--------|----------|
|
|
69
|
-
| old-checkout | Contains "old" in key | ld-stale.ts:1 |
|
|
66
|
+
| Flag Key | Usages | Files | Call Types |
|
|
67
|
+
|----------|--------|-------|------------|
|
|
68
|
+
| checkout-v2 | 3 | 2 | boolVariation |
|
|
69
|
+
| color-theme | 1 | 1 | stringVariation |
|
|
70
|
+
| timeout-ms | 1 | 1 | numberVariation |
|
|
70
71
|
```
|
|
71
72
|
|
|
72
73
|
### JSON output (`--format json`)
|
|
73
74
|
|
|
74
|
-
Pipe-friendly. Every usage includes file, line, call type,
|
|
75
|
-
and structured staleness signals:
|
|
75
|
+
Pipe-friendly. Every usage includes file, line, call type, and staleness signals:
|
|
76
76
|
|
|
77
77
|
```json
|
|
78
78
|
{
|
|
79
|
-
"flagKey": "
|
|
79
|
+
"flagKey": "checkout-v2",
|
|
80
80
|
"isDynamic": false,
|
|
81
|
-
"file": "src/
|
|
81
|
+
"file": "src/services/checkout.ts",
|
|
82
82
|
"line": 14,
|
|
83
|
-
"callType": "
|
|
84
|
-
"stalenessSignals": [
|
|
85
|
-
{ "source": "keyword", "keyword": "old" },
|
|
86
|
-
{ "source": "minFileCount", "fileCount": 1, "threshold": 1 }
|
|
87
|
-
]
|
|
83
|
+
"callType": "boolVariation",
|
|
84
|
+
"stalenessSignals": []
|
|
88
85
|
}
|
|
89
86
|
```
|
|
90
87
|
|
|
@@ -104,7 +101,7 @@ npx flaglint
|
|
|
104
101
|
|
|
105
102
|
### `flaglint scan [dir]`
|
|
106
103
|
|
|
107
|
-
|
|
104
|
+
AST-based inventory of direct LaunchDarkly Node.js server SDK calls.
|
|
108
105
|
|
|
109
106
|
```bash
|
|
110
107
|
flaglint scan ./src
|
|
@@ -120,7 +117,8 @@ flaglint scan --format sarif --output flaglint.sarif
|
|
|
120
117
|
| `--config` | auto-detect | Path to a config file |
|
|
121
118
|
| `--exclude-tests` | — | Exclude test files from scan results |
|
|
122
119
|
|
|
123
|
-
Exit code `0` when no
|
|
120
|
+
Exit code `0` when no staleness signals detected, `1` when staleness signals are present —
|
|
121
|
+
enabling CI visibility into flag usage patterns.
|
|
124
122
|
|
|
125
123
|
---
|
|
126
124
|
|
|
@@ -129,17 +127,146 @@ Exit code `0` when no stale flags found, `1` when stale flags exist — enabling
|
|
|
129
127
|
Analyzes migration readiness and generates an OpenFeature migration plan.
|
|
130
128
|
|
|
131
129
|
```bash
|
|
132
|
-
flaglint migrate ./src
|
|
133
|
-
flaglint migrate --dry-run
|
|
134
|
-
flaglint migrate --
|
|
130
|
+
flaglint migrate ./src # write MIGRATION.md
|
|
131
|
+
flaglint migrate --dry-run # reviewable diffs to stdout
|
|
132
|
+
flaglint migrate --apply # guarded: apply only provably automatable transformations in-place
|
|
133
|
+
flaglint migrate --apply --allow-dirty # apply even on a dirty working tree
|
|
134
|
+
flaglint migrate --output plan.md # write to custom file
|
|
135
|
+
flaglint migrate --exclude-tests # skip test and spec files
|
|
135
136
|
```
|
|
136
137
|
|
|
137
138
|
| Option | Default | Description |
|
|
138
139
|
|--------|---------|-------------|
|
|
139
140
|
| `--output` | `MIGRATION.md` | Write migration plan to file |
|
|
140
|
-
| `--dry-run` | — | Print
|
|
141
|
+
| `--dry-run` | — | Print reviewable diffs to stdout; includes provider setup guidance |
|
|
142
|
+
| `--apply` | — | Apply automatable transformations in-place (requires clean git tree) |
|
|
143
|
+
| `--allow-dirty` | — | Override dirty-tree guard for `--apply` |
|
|
144
|
+
| `--config` | auto-detect | Path to a config file |
|
|
145
|
+
| `--exclude-tests` | — | Skip `*.test.*`, `*.spec.*`, `__tests__/`, `tests/` |
|
|
146
|
+
|
|
147
|
+
**`--apply` safety contracts:**
|
|
148
|
+
- Refuses on a dirty git working tree unless `--allow-dirty`
|
|
149
|
+
- Skips any file that does not already contain a proven `openFeatureClient` binding
|
|
150
|
+
(`openFeatureClient = OpenFeature.getClient()` from `@openfeature/server-sdk`)
|
|
151
|
+
- Never touches detail methods, dynamic keys, unknown fallbacks, or bulk calls
|
|
152
|
+
- Preserves `await` and original call arguments exactly
|
|
153
|
+
- Idempotent: re-running with the same analysis has no effect
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
### `flaglint validate [dir]`
|
|
158
|
+
|
|
159
|
+
Validates that your codebase complies with feature flag policy rules.
|
|
160
|
+
Designed for CI enforcement after migration is complete.
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
flaglint validate # report usages, always exits 0
|
|
164
|
+
flaglint validate --no-direct-launchdarkly # exit 1 on any direct LD eval call
|
|
165
|
+
flaglint validate --no-direct-launchdarkly \
|
|
166
|
+
--bootstrap-exclude src/provider/setup.ts # allow specific bootstrap file
|
|
167
|
+
flaglint validate --no-direct-launchdarkly \
|
|
168
|
+
--bootstrap-exclude "src/provider/**" # allow all provider-directory files
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
| Option | Default | Description |
|
|
172
|
+
|--------|---------|-------------|
|
|
173
|
+
| `--no-direct-launchdarkly` | — | Exit 1 if any direct LD Node server evaluation calls found |
|
|
174
|
+
| `--bootstrap-exclude <glob>` | — | Repeatable glob; matching files excluded from violations |
|
|
141
175
|
| `--config` | auto-detect | Path to a config file |
|
|
142
176
|
|
|
177
|
+
Exit codes: `0` = passed, `1` = violations found, `130` = SIGINT.
|
|
178
|
+
|
|
179
|
+
**Example pass output:**
|
|
180
|
+
```
|
|
181
|
+
✓ validate --no-direct-launchdarkly: no direct LaunchDarkly evaluation calls found.
|
|
182
|
+
Scanned 42 file(s).
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**Example fail output:**
|
|
186
|
+
```
|
|
187
|
+
✗ validate --no-direct-launchdarkly: 2 direct LaunchDarkly evaluation call(s) found.
|
|
188
|
+
|
|
189
|
+
src/services/checkout.ts:42:8 — boolVariation("checkout-v2")
|
|
190
|
+
src/services/pricing.ts:17:4 — boolVariation(dynamic key — manual review required)
|
|
191
|
+
|
|
192
|
+
These files must migrate to OpenFeature before this rule passes.
|
|
193
|
+
Run `flaglint migrate --dry-run` to review the migration plan.
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Supported API matrix
|
|
199
|
+
|
|
200
|
+
**Scope: LaunchDarkly Node.js server-side SDK** (`launchdarkly-node-server-sdk`).
|
|
201
|
+
|
|
202
|
+
| LaunchDarkly call | Automatable | OpenFeature equivalent |
|
|
203
|
+
|---|---|---|
|
|
204
|
+
| `ldClient.boolVariation(key, ctx, false)` | ✓ | `openFeatureClient.getBooleanValue(key, false, ctx)` |
|
|
205
|
+
| `ldClient.stringVariation(key, ctx, "")` | ✓ | `openFeatureClient.getStringValue(key, "", ctx)` |
|
|
206
|
+
| `ldClient.numberVariation(key, ctx, 0)` | ✓ | `openFeatureClient.getNumberValue(key, 0, ctx)` |
|
|
207
|
+
| `ldClient.jsonVariation(key, ctx, {})` | ✓ | `openFeatureClient.getObjectValue(key, {}, ctx)` |
|
|
208
|
+
| `ldClient.*VariationDetail(...)` | ✗ manual | Detail result shapes differ — requires manual review |
|
|
209
|
+
| Dynamic flag key | ✗ manual | Key must be a static string literal |
|
|
210
|
+
| `ldClient.allFlags()` / `allFlagsState()` | ✗ manual | Bulk calls — no single-flag codemod |
|
|
211
|
+
| Unknown fallback type | ✗ manual | Fallback type must be determinable statically |
|
|
212
|
+
| React `useFlags()`, `useLDClient()` | detect only | Client-side — outside Node.js server SDK scope |
|
|
213
|
+
| React HOC / `<LDProvider>` | detect only | Client-side — outside Node.js server SDK scope |
|
|
214
|
+
|
|
215
|
+
`flaglint scan` and `flaglint migrate --dry-run` report all detected patterns including manual-review cases.
|
|
216
|
+
`flaglint migrate --apply` rewrites only the ✓ rows above.
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## Provider setup (one-time manual step)
|
|
221
|
+
|
|
222
|
+
`flaglint migrate --dry-run` includes this guidance inline. **Complete provider setup in
|
|
223
|
+
one dedicated file before running `--apply`.**
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
npm install @openfeature/server-sdk \
|
|
227
|
+
@launchdarkly/node-server-sdk \
|
|
228
|
+
@launchdarkly/openfeature-node-server
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Bootstrap file (do not apply automatically — bootstrap is intentionally manual):
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
import LaunchDarkly from "@launchdarkly/node-server-sdk";
|
|
235
|
+
import { LaunchDarklyProvider } from "@launchdarkly/openfeature-node-server";
|
|
236
|
+
import { OpenFeature } from "@openfeature/server-sdk";
|
|
237
|
+
|
|
238
|
+
const ldClient = LaunchDarkly.init(process.env.LD_SDK_KEY!);
|
|
239
|
+
await OpenFeature.setProviderAndWait(new LaunchDarklyProvider(ldClient));
|
|
240
|
+
|
|
241
|
+
// Evaluation context must include targetingKey (or key):
|
|
242
|
+
// { targetingKey: user.id }
|
|
243
|
+
export const openFeatureClient = OpenFeature.getClient();
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
**Do not remove any LaunchDarkly packages.** LaunchDarkly remains your feature flag provider;
|
|
247
|
+
`@openfeature/server-sdk` becomes the evaluation interface your application code calls.
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## Example transformation
|
|
252
|
+
|
|
253
|
+
**Before — direct LaunchDarkly Node.js server SDK:**
|
|
254
|
+
```typescript
|
|
255
|
+
const enabled = await ldClient.boolVariation("checkout-v2", { key: user.id }, false);
|
|
256
|
+
const theme = await ldClient.stringVariation("color-theme", { key: user.id }, "light");
|
|
257
|
+
const timeout = await ldClient.numberVariation("timeout-ms", { key: user.id }, 5000);
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
**After — OpenFeature via LaunchDarkly provider:**
|
|
261
|
+
```typescript
|
|
262
|
+
const enabled = await openFeatureClient.getBooleanValue("checkout-v2", false, { targetingKey: user.id });
|
|
263
|
+
const theme = await openFeatureClient.getStringValue("color-theme", "light", { targetingKey: user.id });
|
|
264
|
+
const timeout = await openFeatureClient.getNumberValue("timeout-ms", 5000, { targetingKey: user.id });
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Flag key, fallback value, `await`, and evaluation context are preserved exactly.
|
|
268
|
+
LaunchDarkly continues to serve the flags — only the call-site API changes.
|
|
269
|
+
|
|
143
270
|
---
|
|
144
271
|
|
|
145
272
|
## Configuration
|
|
@@ -161,8 +288,8 @@ Create `.flaglintrc`, `.flaglintrc.json`, or `flaglint.config.json` in your proj
|
|
|
161
288
|
| `include` | `string[]` | `["**/*.{ts,tsx,js,jsx}"]` | Glob patterns to scan |
|
|
162
289
|
| `exclude` | `string[]` | `["**/node_modules/**", ...]` | Glob patterns to ignore |
|
|
163
290
|
| `provider` | `string` | `"launchdarkly"` | Feature flag provider |
|
|
164
|
-
| `minFileCount` | `number` | `1` | A flag is
|
|
165
|
-
| `wrappers` | `string[]` | `[]` | Function names
|
|
291
|
+
| `minFileCount` | `number` | `1` | A flag is a staleness candidate if it appears in ≤ N files |
|
|
292
|
+
| `wrappers` | `string[]` | `[]` | Function names wrapping LD SDK calls. Example: `["flagPredicate", "useFlag"]` |
|
|
166
293
|
| `reportTitle` | `string` | — | Custom title for generated reports |
|
|
167
294
|
| `outputDir` | `string` | `"."` | Default output directory |
|
|
168
295
|
|
|
@@ -172,18 +299,17 @@ FlagLint searches for config in this order: `--config` path → `.flaglintrc`
|
|
|
172
299
|
|
|
173
300
|
## CI Integration
|
|
174
301
|
|
|
175
|
-
###
|
|
302
|
+
### Enforce OpenFeature migration: block PRs with direct LD calls
|
|
176
303
|
|
|
177
304
|
```yaml
|
|
178
|
-
- name:
|
|
179
|
-
run:
|
|
180
|
-
|
|
305
|
+
- name: Validate — no direct LaunchDarkly evaluations
|
|
306
|
+
run: |
|
|
307
|
+
npx flaglint validate --no-direct-launchdarkly \
|
|
308
|
+
--bootstrap-exclude "src/provider/setup.ts"
|
|
309
|
+
# exits 1 if any direct LD evaluation calls remain outside the bootstrap file
|
|
181
310
|
```
|
|
182
311
|
|
|
183
|
-
###
|
|
184
|
-
|
|
185
|
-
Stale flags appear as warnings directly in the PR diff —
|
|
186
|
-
no dashboard, no separate tool.
|
|
312
|
+
### Full migration CI pipeline with SARIF annotations
|
|
187
313
|
|
|
188
314
|
```yaml
|
|
189
315
|
name: FlagLint
|
|
@@ -200,46 +326,32 @@ jobs:
|
|
|
200
326
|
- uses: actions/setup-node@v4
|
|
201
327
|
with:
|
|
202
328
|
node-version: 20
|
|
203
|
-
|
|
329
|
+
|
|
330
|
+
- name: Scan for LaunchDarkly SDK usage
|
|
204
331
|
run: npx flaglint scan --format sarif --output flaglint.sarif
|
|
205
332
|
continue-on-error: true
|
|
333
|
+
|
|
206
334
|
- name: Upload to GitHub Code Scanning
|
|
207
335
|
uses: github/codeql-action/upload-sarif@v3
|
|
208
336
|
with:
|
|
209
337
|
sarif_file: flaglint.sarif
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
Stale flags show up as Code Scanning alerts on the exact file
|
|
213
|
-
and line where the flag is used — reviewers see them in the PR
|
|
214
|
-
without running anything locally.
|
|
215
338
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
- `ldClient.allFlags()`
|
|
222
|
-
- `useFlags()`, `useLDClient()` React hooks
|
|
223
|
-
- `<LDProvider>` and `withLDConsumer()` patterns
|
|
224
|
-
- Custom wrapper calls such as `flagPredicate("my-flag", false)` when configured with `wrappers`
|
|
225
|
-
- Dynamic flag keys (runtime-determined, flagged for manual review)
|
|
339
|
+
- name: Enforce OpenFeature migration
|
|
340
|
+
run: |
|
|
341
|
+
npx flaglint validate --no-direct-launchdarkly \
|
|
342
|
+
--bootstrap-exclude "src/provider/setup.ts"
|
|
343
|
+
```
|
|
226
344
|
|
|
227
|
-
|
|
345
|
+
Code Scanning alerts show the exact file and line of each direct LD call — reviewers see them in the PR without running anything locally.
|
|
228
346
|
|
|
229
347
|
---
|
|
230
348
|
|
|
231
|
-
##
|
|
349
|
+
## Precision
|
|
232
350
|
|
|
233
|
-
|
|
351
|
+
Validated against 120 deterministic benchmark cases within the supported LaunchDarkly Node.js server-side SDK scope. 100% precision and recall are limited to those 120 tested cases and to the Node.js server-side SDK call patterns explicitly listed in the Supported API matrix above.
|
|
234
352
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
| `ldClient.variation(key, ctx, false)` | `client.getBooleanValue(key, false, ctx)` |
|
|
238
|
-
| `ldClient.variationDetail(key, ctx, def)` | `client.getBooleanDetails(key, def, ctx)` |
|
|
239
|
-
| `useFlags()` | `useFlag(key)` per flag |
|
|
240
|
-
| `useLDClient()` | `useOpenFeatureClient()` |
|
|
241
|
-
| `<LDProvider>` | `<OpenFeatureProvider provider={...}>` |
|
|
242
|
-
| `withLDConsumer()(Component)` | `withOpenFeature()(Component)` |
|
|
353
|
+
Detection is AST-based, not regex: client binding patterns, import aliases, CJS require forms,
|
|
354
|
+
and custom wrappers are all resolved before matching.
|
|
243
355
|
|
|
244
356
|
---
|
|
245
357
|
|
|
@@ -249,14 +361,6 @@ See [CONTRIBUTING.md](./CONTRIBUTING.md).
|
|
|
249
361
|
|
|
250
362
|
---
|
|
251
363
|
|
|
252
|
-
## Free flag debt audit
|
|
253
|
-
|
|
254
|
-
Running this on a real codebase?
|
|
255
|
-
[Book a free 30-minute audit →](https://flaglint.dev#waitlist)
|
|
256
|
-
I'll run FlagLint on your repo and walk you through the results.
|
|
257
|
-
|
|
258
|
-
---
|
|
259
|
-
|
|
260
364
|
## License
|
|
261
365
|
|
|
262
366
|
MIT — see [LICENSE](./LICENSE).
|