Commit Graph

187 Commits

Author SHA1 Message Date
Dominik Ferber e1d377c453 refactor(flags): extract framework-agnostic shared/ module
Both flags/next and flags/sveltekit implemented the same flag pipeline
twice and had drifted. This lifts the parts that are framework-agnostic
(or trivially so) into src/shared/, with each framework keeping thin
wrappers for its differences. Zero public API change — the generated
.d.ts for flags, flags/next and flags/sveltekit are byte-identical.

- shared/seal.ts: sealHeaders/sealCookies/transformToHeaders
  (was duplicated in next/evaluate.ts and sveltekit/index.ts)
- shared/overrides.ts: readOverrides + memoized decrypt; SvelteKit now
  gets the override memoization Next already had. Removes next/overrides.ts.
- shared/precompute.ts: combine/serialize/deserialize/generatePermutations
  + getPrecomputed core. Frameworks keep wrappers for secret defaulting
  and the getPrecomputed(flag) vs getPrecomputed(key) signatures.
- shared/discovery.ts: shared authorize -> 401-or-data -> version-header
  control flow behind createFlagsDiscoveryEndpoint.

Named "shared" rather than "core" to avoid confusion with the separate
@vercel/flags-core package.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 15:22:35 +03:00
Luis Meyer c35f38dfb9 Support createClient options-first overload (#406) 2026-06-23 14:32:06 +02:00
Rich Haines d8ed11ef08 Migrate docs app to @vercel/geistdocs (#391)
* Migrate docs app to Geistdocs canary

* Fix docs proxy matcher

* Use Geistdocs UI exports

* Update Geistdocs to 1.3.0

* upgrade geistdocs and fix svelte logo

* add copy prompt to certain docs pages

* migrate to 1.5.0

* refactor(docs): use geistdocs v1.5 Badge, CommandPrompt, ThemeAwareImage

Remove the local copies now exported by @vercel/geistdocs@1.5 and import
them from the package instead:

- Badge -> @vercel/geistdocs/components/badge (provider-list)
- CommandPrompt -> @vercel/geistdocs/components/command-prompt (install-command)
- ThemeAwareImage -> @vercel/geistdocs/components/theme-aware-image
  (docs MDX components); migrate the SvelteKit MDX call site to the new
  src={{ light, dark }} API.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(docs): restore install switcher width animation

The hero "For humans / For agents" switcher called router.refresh() on
every toggle (added in #366). That remounts/reconciles the switcher
subtree mid-toggle, resetting the CommandPrompt's measured width state so
the command-line width spring never plays — the line snapped instead of
growing.

Drop the refresh: this flag's only consumer is the switcher itself, so the
optimistic override already shows the correct command and the cookie
persists the choice across reloads (the server reads it and renders the
matching prebuilt `[code]`). The refresh changed nothing visible and only
broke the animation. startTransition() does not help, since router.refresh
already runs as a transition.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(docs): render home code blocks with geistdocs CodeBlock

Replace the hand-rolled shiki token renderer in HighlightedCode with
fumadocs highlight() + the geistdocs CodeBlock, highlighting with the
shared geistShikiTheme so the home page "Effortless setup" blocks match
the documentation (same syntax colors, header, language icon, copy
button, radius). transformerIcon() fills the filename icon slot; the
caption is preserved below.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(docs): equal-height home code blocks

Grow each HighlightedCode block to fill its grid cell (h-full root +
flex-1 wrapper forcing the Card to h-full) so both columns share the
taller block's height and their captions align. The Card and its <pre>
share bg-background-100, so the shorter block fills seamlessly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore(docs): drop dead shadcn tokens (chart-*, sidebar-primary)

Only chart-1..5 and sidebar-primary are unused by both the app and the
geistdocs/fumadocs package CSS. The other shadcn tokens (secondary,
card-foreground, the remaining sidebar-* set, etc.) must stay: the package
stylesheet consumes them via var(--token) for its fd-* utility mappings
and the #nd-sidebar rule, and does not self-define them — the consuming
app has to provide them.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(docs): migrate consumers off shadcn tokens to Geist scale

Switch every shadcn-token consumer (select, switch, iframe-browser, the
home marketing pages, and the illustrations SVGs) to the Geist --ds-*
scale using the geistdocs PR #75 mapping (foreground->gray-1000,
muted->gray-100, muted-foreground->gray-800, border/input->gray-alpha-400,
ring->gray-600, destructive->red-800, background/card/popover->
background-100, accent->gray-100, etc.).

With no consumers left, drop the entire local shadcn layer from
geistdocs.css (the @theme --color-* mappings and the :root/.dark oklch
palette) and instead override fumadocs --color-fd-* and #nd-sidebar to
--ds-* (so the package's docs UI keeps working without the raw palette),
matching the geistdocs template. The geist utilities themselves come from
@vercel/geistdocs/styles.css.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Update geistdocs.css

* migrate to 1.6.0

* chore(docs): bump @vercel/geistdocs to 1.6.1

Picks up the Next.js logo gradient-id fix so the framework logo renders
correctly in the mobile docs menu.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Update pnpm-lock.yaml

* fix(docs): drop language icons from landing-page code blocks

The home "Effortless setup" snippets are Next.js examples, but the
language-based transformerIcon rendered a React glyph for the .tsx block.
Remove the icons (these blocks never had them) and hide the now-empty
header icon slot so the filename stays flush.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore(docs): drop redundant streamdown @source

The streamdown @source pointed at a transitive dep path that doesn't
resolve under pnpm (matched nothing). Streamdown is now sourced upstream
from @vercel/geistdocs's own styles.css, so this line is unneeded.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* update

* bump @vercel/geistdocs

* Update pnpm-lock.yaml

* update

---------

Co-authored-by: christopherkindl <53372002+christopherkindl@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 18:37:35 +02:00
github-actions[bot] 0b40d46d26 Version Packages (#404)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-17 16:22:35 +03:00
Dominik Ferber 4705ac67cb [@flags-sdk/edge-config] support bulk and simple interface (#403)
* [@flags-sdk/edge-config] support bulk and simple interface

* reword
2026-06-17 13:17:48 +00:00
Dominik Ferber 2cb0b49698 Allow passing an adapter factory directly to flag() (#402)
* Allow passing an adapter factory directly to flag()

flag() now accepts the adapter factory by reference (`adapter: vercelAdapter`)
as a shorthand for calling it (`adapter: vercelAdapter()`). The factory is
resolved once per declaration; passing an instance keeps working. Applies to
both the Next.js and SvelteKit entrypoints.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* [@flags-sdk/vercel] reuse adapter instance

* reword changeset

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 16:14:25 +03:00
github-actions[bot] 158634cc5d Version Packages (#400)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-16 17:52:22 +03:00
Luc Leray b0150af9c8 [@vercel/flags-core] quiet noisy stream reconnect logs (#395)
* [@vercel/flags-core] quiet noisy stream reconnect logs

* [@vercel/flags-core] test exhaustion log + guard undefined reason
2026-06-16 14:43:25 +00:00
Josh Story b23b7b407b Recognize hanging promise rejection as internal (#397) 2026-06-15 14:31:10 +03:00
github-actions[bot] 5cf0950342 Version Packages (#388)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-05 10:27:31 +02:00
Dominik Ferber 201f9d5988 Add bulk evaluation (#385)
* [flags] avoid re-imports

Avoid re-importing next/headers since it adds unnecessary microtask queue overhead

* [flags] avoid iife microtask queue overhead

* [flags] skip awaits where possible

* [flags] allow bulk eval

* wip

* add bulk mode to playground

* first try of bulk eval

* add bulk evaluation to adapters

* reuse

* simplify

* versions

* rm outdated changeset

* rm outdated changeset

* revert playground

* revert playground flags

* rm logs

* reuse cache of resolved flags for bulk

* simplify

* changesets

* support bulk([]) and bulk({})

* flagKey → key

* allow any type in expectPermutations

* avoid unnecessary mapping

* fix changeset

* validate package.json fields

* update package.json fields

* keep covariant

* adjust adapter types

* Merge bulk into evaluate (#392)

* merge bulk into evaluate

* add pages router compatibility

* better types

* add array test

* add test

* changesets

* use type import

* fix import

* extract readOverrides

* fix import of reportValue

* tracing

* skip bulkDecide for overwritten flags

* update changesets

* [changesets] onlyUpdatePeerDependentsWhenOutOfRange

* add type guard

* adjust changeset
2026-06-05 08:14:29 +00:00
Luis Meyer 7b5ea9a808 Reapply OIDC (#390)
* Reapply "Add oidc support (#374)" (#389)

This reverts commit 357ca676c6.

* bump oidc package

* review

* comments
2026-06-04 16:37:03 +02:00
Luis Meyer 357ca676c6 Revert "Add oidc support (#374)" (#389)
This reverts commit 72d36511d0.
2026-05-28 10:16:43 +03:00
Luis Meyer 72d36511d0 Add oidc support (#374)
* Add oidc support

* changeset

* update tests

* update def script

* fix provider data

* update changeset

* fix createVercelAdapter

* comments

* error
2026-05-28 08:59:00 +02:00
Dominik Ferber bd31a462a6 Add package.json metadata & validation script (#387)
* validate package.json fields

* update package.json fields
2026-05-25 15:49:46 +03:00
Dominik Ferber 4d90e912a4 [flags-core] perf improvements (#382)
* [flags-core] perf improvements

* add changeset
2026-05-18 13:20:13 +03:00
Vincent Derks bd4d01a9b2 vercel-flags-core: jitter ingest retries and batch-wait window (#371)
Replace the deterministic 100/200ms retry schedule with full-jitter exponential
backoff, jitter MAX_BATCH_WAIT_MS by ±20% to desynchronize concurrent flushes,
and log when a flush exhausts all retries.

Helpers extracted to utils/backoff.ts so they can be reused.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-06 15:57:15 +02:00
Dominik Ferber 8e26cd8e40 update guidance (#369) 2026-04-24 16:40:22 +03:00
github-actions[bot] 2e932e6c62 Version Packages (#361)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-14 17:29:53 +03:00
Dominik Ferber 80dcdada34 [vercel flags] add progressive rollouts to sdk (#360)
* [vercel flags] add progressive rollouts

* fix slots

* add changeset
2026-04-14 16:55:57 +03:00
github-actions[bot] 1ac83900c8 Version Packages (#357)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-03 14:32:42 +03:00
Dominik Ferber c08f3e5614 [flags/next] perf improvements (#356)
* [flags] avoid re-imports

Avoid re-importing next/headers since it adds unnecessary microtask queue overhead

* [flags] avoid iife microtask queue overhead

* [flags] skip awaits where possible

* add undefined to headersModulePromise type
2026-04-03 11:24:31 +00:00
Dominik Ferber 9142790975 only build publishable packages during release process (#348)
* clean up

* fix release process
2026-03-21 21:17:04 +02:00
github-actions[bot] 14ef3fa940 Version Packages (#346)
* Version Packages

* blank commit

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Swarnava Sengupta <swarnava.sengupta@vercel.com>
2026-03-21 23:38:24 +05:30
Swarnava Sengupta b755ffecdf fix: SDK key detection to avoid false positives with third-party identifiers (#345)
The SDK key validation now uses a regex (/^vf_(?:server|client)_/) to require
the format vf_server_* or vf_client_* instead of accepting any string starting
with vf_. This prevents false positives with third-party service identifiers
that happen to start with vf_ (e.g., Stripe identity flow IDs like
vf_1PyHgVLpWuMxVFx...).

Adds isValidSdkKey() helper function and updates parseSdkKeyFromFlagsConnectionString()
to use the stricter validation. Updates all tests to use valid SDK key formats.
2026-03-21 17:39:00 +00:00
github-actions[bot] 471e0048b6 Version Packages (#342)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-20 21:19:04 +02:00
Dominik Ferber 44460570d4 [vercel/flags-core] allow json flags (#335)
* rm unused import

* [vercel-flags] allow json flags

* add flags-playground

* wip

* clean up type

* reword changeset

* rm examples/flags-playground
2026-03-20 14:03:53 +02:00
github-actions[bot] a3b536b504 Version Packages (#340)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-19 16:21:12 +02:00
Dominik Ferber b81963dc14 fix (#339) 2026-03-19 16:18:59 +02:00
github-actions[bot] b199f2083c Version Packages (#333)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-18 15:50:13 +02:00
Dominik Ferber 64619d7c66 @vercel/flags-core: allow specifying entities type when creating clients (#334)
* changeset

* adapt
2026-03-13 11:09:21 +02:00
Dominik Ferber 4a5f56a8c7 skip sending config reads (#330)
* skip sending config read for dev and custom envs

* add changeset

* clean up

* wip
2026-03-13 08:16:47 +01:00
github-actions[bot] 0af37593bd Version Packages (#331)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-12 21:53:04 +02:00
Dominik Ferber c9934fda03 [@vercel/flags-core] drop dependency on flags pkg (#332) 2026-03-12 21:24:11 +02:00
nadav dd1396e461 Guard missing Vercel Flags runtime helpers (#326)
* Guard request-context flag reporting

* Preserve request-context hook binding

* Guard core request-context reporting

* Guard missing bundled flag definitions

---------

Co-authored-by: Dominik Ferber <dominik.ferber@gmail.com>
2026-03-12 16:38:18 +02:00
github-actions[bot] e44eedf0cf Version Packages (#315)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-09 19:08:17 +02:00
Dominik Ferber df427e0e7a use catalog for react & react-dom (#318)
* use catalog for react & react-dom

this guarantees the same version for all packages and thus avoids type errors

* update lockfile
2026-03-09 19:01:30 +02:00
Dominik Ferber e5f3e34428 [docs] depend on workspace version of flags (#314)
* fix dep

* add packageManager

* move devDeps to top-level
2026-03-09 18:26:11 +02:00
Dominik Ferber 77727aaade use __no_flags__ to handle precompute with empty flags (#300)
* use __no_flags__ to handle precompute with empty flags

* handle __no_flags__ in serialize

* add __no_flags__ handling to sveltekit

* avoid returning undefined when defaultValue is set

This could only happen on precomputed flags in case of bad usage.

* add error messages

* test console logs

* update changeset
2026-03-09 15:10:47 +00:00
Dominik Ferber 2db1530275 Upgrade dependencies (#313)
* upgrade

* update biome

* upgrade more
2026-03-09 12:24:42 +00:00
github-actions[bot] 783b9efdda Version Packages (#312)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-09 12:29:55 +01:00
Luis Meyer 10c10b6aa4 Return meaningful result from prepareFlagsDefinitions (#311)
* Return meaningful result from prepareFlagsDefinitions

- Add PrepareFlagsDefinitionsResult discriminated union type that indicates whether definitions were created
- Change prepareFlagsDefinitions return type from Promise<void> to Promise<PrepareFlagsDefinitionsResult>
- Return { created: false, reason: 'no-sdk-keys' } when no SDK keys are found
- Return { created: true, sdkKeysCount: N } when definitions are successfully created
- Add tests for both return paths to verify the function communicates its result properly

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* Add changeset for prepareFlagsDefinitions result type

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-09 12:25:55 +01:00
Dominik Ferber 05a5ebfda1 Add userAgentSuffix to prepare-flags-definitions (#306)
* Replace version param with userAgentSuffix in prepare-flags-definitions

Changed the API to use a cleaner approach:
- Removed `version?: string` option in favor of `userAgentSuffix?: string`
- Now imports package version directly from package.json
- Constructs user-agent as: `@vercel/prepare-flags-definitions/{pkgVersion} {suffix}`
- Allows consumers (e.g., vercel-cli, vercel-api) to add context to the header

Added tests verifying both default and suffixed user-agent headers.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* add changeset

---------

Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-09 11:18:51 +00:00
Dominik Ferber e8539cd52a make version dynamic in tests (#304) 2026-03-06 12:02:03 +00:00
github-actions[bot] c1fbe2f19d Version Packages (#284)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-06 13:57:18 +02:00
Dominik Ferber 3f3ec2bbe2 Revert "fix main export (#302)" (#303)
This reverts commit 62afa7f64e.
2026-03-06 10:13:44 +00:00
Dominik Ferber 62afa7f64e fix main export (#302) 2026-03-06 09:42:16 +00:00
Luis Meyer 96ba1226c8 Extract @vercel/prepare-flags-definitions package (#301)
* Extract @vercel/prepare-flags-definitions package

Extract the core flag definitions preparation logic from the Vercel CLI into a standalone, reusable package. This includes:
- prepareFlagsDefinitions() function that collects SDK keys from env, fetches definitions, and writes to node_modules
- hashSdkKey() helper for SHA-256 hashing
- generateDefinitionsModule() for JS module generation with deduplication and lazy parsing

Follows repo conventions: pnpm workspaces, tsup, vitest, ES modules with CJS fallback.

* Add JSDoc comments from original CLI source

* Add inline comments from original CLI source

* Add optional output parameter with debug logging

* Add output.time for datafile fetching

* Add changeset for @vercel/prepare-flags-definitions
2026-03-06 10:10:01 +01:00
Dominik Ferber b70c2ea466 Control (#278)
* refactor

* remove retries

* simplify

* simplify options

* before

* rename DataSource to Controller

* refactor and better tests

* avoid double polling

* rename

* fix

* simplify test setup

* wip

* unify

* wip

* only track 1 read per build

* make BundledSource lazy

* clean up fallback behavior

* add mode

* mutually exclusive streaming & polling

* rely more on black box testing

* simplify

* Update CLAUDE.md

* various fixes

* add tests

* more fixes

* Update CLAUDE.md

* more fixes

* resolve more issues

* unite black box tests

* tests

* progress

* adjust

* don't report on 401s; use Response.json

* enforce min polling interval

* progress

* types

* capture all logs

* throw with prefix

* added a minimum gap of `BASE_DELAY_MS` (1 second) between connection
 attempts

* step

* progress

* use request context in tests

* add separate tests depending on context

* tests

* rm unused option

* add state machine chart

* rm sources

* use fake timers for more tests

* swap remaining tests from msw to mocked fetch

* update comments

* Update CLAUDE.md

* update comment

* fix comment

* fix types

* rm peek

* adds ping checks and sending x-revision header  (#282)

* abort on missed pings

* use revision from bundled definitions

* tests

* simplify

* send x-revsion on reconnects too

* simplify StreamSource

* rename

* rename in test

* wait for stream

* replace startBackgroundUpdates with explicit call

* Update CLAUDE.md

* restore stronger tests

* Update CLAUDE.md

* convert

* simplify tests

* fix test

* fixes

* rm state machine

* await first poll before resoliving init

* rm outdated comment

* avoid leaking _origin

* changeset

* avoid log on reconnect due to missed pings

* don't warn on missed pings

* Update event reporting for control rewrite (#289)

* Update event reporting for control rewrite

* Log ingest response

* Use string for revision

* Add retries when ingesting events

* adapt changeset

* adjust test

---------

Co-authored-by: Luis Meyer <luis.meyer@vercel.com>
Co-authored-by: Andy <AndyBitz@users.noreply.github.com>
Co-authored-by: Andy Bitz <artzbitz@gmail.com>
2026-03-06 10:05:01 +02:00
Vincent Derks 722b0d054e Added new comparators: (not_)contains and case-insensitive versions (#288)
* Added new comparators: (not_)contains and case-insensitive versions

* Switched to "ci" option instead of creating new condition for every ci-case

* Cleanup

* More cleanup

* Some more cleanup & finetuning

Made-with: Cursor

* Changeset

* Switch options key to just "i" and also allow for passing "i" as string instead of options object

* Apply suggestions from code review

* Update packages/vercel-flags-core/src/evaluate.ts

Co-authored-by: Dominik Ferber <dominik.ferber@gmail.com>

* naming

* Renaming

---------

Co-authored-by: Dominik Ferber <dominik.ferber@gmail.com>
2026-03-06 07:52:32 +02:00