@flagsync/nextjs-sdk 0.2.6 → 0.2.8

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/LICENSE CHANGED
@@ -186,7 +186,7 @@
186
186
  same "printed page" as the copyright notice for easier
187
187
  identification within third-party archives.
188
188
 
189
- Copyright [yyyy] [name of copyright owner]
189
+ Copyright 2005 Mike Chabot (FlagSync)
190
190
 
191
191
  Licensed under the Apache License, Version 2.0 (the "License");
192
192
  you may not use this file except in compliance with the License.
package/README.md CHANGED
@@ -1,288 +1,14 @@
1
- # FlagSync Adapter for Vercel Flags
1
+ # FlagSync SDK for Next.js
2
2
 
3
- [FlagSync](https://www.flagsync.com) brings affordable, user-friendly feature flags and A/B testing to indie hackers and growing businesses. This adapter integrates FlagSync with [Vercel Flags](https://vercel.com/docs/flags) in Next.js apps. [Get started](https://docs.flagsync.com/getting-started/set-up-flagsync) today!
3
+ The `@flagsync/nextjs-sdk` integrates into Next.js applications with [Vercel Flags](https://flags-sdk.dev/) for feature management and event tracking—ideal for SSR and static site generation workflows.
4
4
 
5
5
  [![npm version](https://badge.fury.io/js/%40flagsync%2Fvercel-flags-sdk.svg)](https://badge.fury.io/js/%40flagsync%2Fvercel-flags-sdk)
6
- [![Twitter](https://img.shields.io/twitter/url/https/twitter.com/flagsync.svg?style=social&label=Follow%20%40flagsync)](https://twitter.com/flagsync)
7
- [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)
8
-
9
- ---
10
-
11
- ## Getting Started
12
-
13
- Refer to the [SDK documentation](https://docs.flagsync.com/sdks/next.js) for more information on how to use this library.
14
-
15
- ### Compatibility
6
+ [![Twitter URL](https://img.shields.io/twitter/url/https/twitter.com/flagsync.svg?style=social&label=Follow%20%40flagsync)](https://twitter.com/flagsync)
16
7
 
8
+ ## Compatibility
17
9
  - Requires [Next.js](https://nextjs.org/) 14+
18
- - Compatible with Node.js 16+ and ES5.
19
- - TypeScript is fully supported.
20
- - **Note:** This SDK is optimized for Next.js App Router. For non-Next.js Node.js apps, use the [FlagSync Node SDK](https://github.com/flagsync/node-client) instead.
21
-
22
- ### Prerequisites
23
- - Install the SDK: `npm install @flagsync/vercel-flags-sdk flags/next`
24
- - Set the `FLAGSYNC_SDK_KEY` environment variable in your `.env` file.
25
-
26
- ## Basic Setup
27
-
28
- FlagSync lets you toggle features and personalize experiences in your Next.js App Router application. Follow these steps to set it up.
29
-
30
- ### Step 1: Create the FlagSync client singleton
31
-
32
- Initialize the client with your server-side SDK key:
33
-
34
- ```typescript
35
- // lib/flagsync.ts
36
- import { createFlagSyncClient } from '@flagsync/vercel-flags-sdk';
37
-
38
- export const client = createFlagSyncClient({
39
- sdkKey: process.env.FLAGSYNC_SDK_KEY!,
40
- });
41
- ```
42
-
43
- ### Step 2: Set up user identification
44
-
45
- > [!NOTE]
46
- > Feature flags in FlagSync use user context (e.g. via `identify`) to enable personalized experiences.
47
-
48
- The `identify` function defines how users are identified (e.g., via cookies, headers, or session data). See [Identify](#identify) for more details.
49
-
50
- ```typescript
51
- // lib/flagsync.ts
52
- import {
53
- createIdentify,
54
- createFlagSyncClient,
55
- } from '@flagsync/vercel-flags-sdk';
56
-
57
- export const identify = createIdentify(({ cookies }) => {
58
- const userId = cookies.get('user-id')?.value; // Authenticated user ID
59
- const visitorId = cookies.get('visitor-id')?.value; // Unauthenticated visitor ID
60
- return {
61
- key: userId ?? visitorId ?? 'anonymous' // Fallback to 'anonymous'
62
- };
63
- });
64
- ```
65
- > [!CAUTION]
66
- > While `anonymous` user contexts are supported, always provide a unique identifier (even for unauthenticated users) to ensure consistent flag evaluation.
67
- >
68
- > See [Identify](#identify) for more details.
69
-
70
- ### Step 3: Define a feature flag
71
-
72
- Create a flag definition using the shared `client` and `identify` function:
73
-
74
- ```typescript
75
- // app/dashboard/flags.ts
76
- import { flag } from 'flags/next';
77
- import { client, identify } from '@/lib/flagsync';
78
- import { createStringFlagAdaptor } from '@flagsync/vercel-flags-sdk';
79
-
80
- export const dashboardFlag = flag<string>({
81
- identify, // Links flag to user context
82
- key: 'dashboardFlag', // Unique flag key
83
- adapter: createStringFlagAdaptor(client), // Retrieves the flag with type safety
84
- });
85
- ```
86
-
87
- ### Step 4: Use the flag in your app
88
-
89
- Now you can use `dashboardFlag` in your Server Components:
90
-
91
- ```typescript jsx
92
- // app/dashboard/page.tsx
93
-
94
- import { dashboardFlag } from '@/app/dashboard/flags';
95
-
96
- export default async function DashboardPage() {
97
- const dashboard = await dashboardFlag();
98
-
99
- return (
100
- <div>The value of {dashboardFlag.key} is {dashboard}</div>
101
- );
102
- }
103
- ```
104
-
105
- ## Type-Safe Feature Flags
106
-
107
- FlagSync supports multiple flag types for different use cases. Use the type-specific adapter depending on your flag type:
108
-
109
- - `createBoolFlagAdaptor`: For boolean flags
110
- - `createStringFlagAdaptor`: For string flags
111
- - `createNumberFlagAdaptor`: For numeric flags
112
- - `createJsonFlagAdaptor`: For JSON object flags
113
-
114
- ```typescript
115
- // app/<route>/flags.ts
116
- import { client, identify } from '@/lib/flagsync';
117
- import {
118
- createBoolFlagAdaptor,
119
- createJsonFlagAdaptor,
120
- createNumberFlagAdaptor,
121
- createStringFlagAdaptor,
122
- } from '@flagsync/vercel-flags-sdk';
123
- import { flag } from '@vercel/flags';
124
-
125
- // Boolean flag for feature toggles
126
- export const betaFeatureFlag = flag<boolean>({
127
- identify,
128
- key: 'beta-feature-enabled',
129
- adapter: createBoolFlagAdaptor(client),
130
- });
131
-
132
- // String flag for UI variants
133
- export const heroCtaFlag = flag<string>({
134
- identify,
135
- key: 'hero-cta',
136
- adapter: createStringFlagAdaptor(client),
137
- });
138
-
139
- // Number flag for pricing tiers
140
- export const discountFlag = flag<number>({
141
- identify,
142
- key: 'price-discount',
143
- adapter: createNumberFlagAdaptor(client),
144
- });
10
+ - Compatible with Node.js 16+ and ES5
11
+ - TypeScript is fully supported
145
12
 
146
- // JSON flag for complex configurations
147
- export const featureConfigFlag = flag<{
148
- enabled: boolean;
149
- limits: { requests: number; storage: number };
150
- }>({
151
- identify,
152
- key: 'feature-config',
153
- adapter: createJsonFlagAdaptor(client),
154
- });
155
- ```
156
-
157
- ## Identify
158
-
159
- The `identify` function links feature flags to user contexts in FlagSync by returning an `FsUserContext` object.
160
-
161
- ```typescript
162
- type FsUserContext = {
163
- key: string; // Unique identifier for the user
164
- attributes?: Record<string, string | number | boolean>; // Optional custom data (used in individual targeting)
165
- };
166
- ```
167
- * `key`: A unique ID for the user (required)
168
- * `attributes`: Optional metadata (e.g., user agent, region, role, department) to personalize flag evaluations.
169
-
170
- > [!IMPORTANT]
171
- > User contexts enable personalized flag evaluations via [Individual Targeting](https://docs.flagsync.com/sdks/sdk-concepts/flag-evaluation#does-the-flag-have-any-individual-targeting-rules), and consistent experiences during [Percentage Rollouts](https://docs.flagsync.com/sdks/sdk-concepts/flag-evaluation#does-the-flag-have-a-percentage-rollout).
172
-
173
- We recommend:
174
- 1. Using a helper function (getFlagSyncUserContext) to build the full context.
175
- 2. Setting cookies in middleware for the key.
176
-
177
- Here's how:
178
-
179
- ### Step 1: Define a helper function
180
-
181
- Create a utility to build the user context:
182
-
183
- ```typescript
184
- // lib/flagsync.user-context.ts
185
- import type { ReadonlyRequestCookies, ReadonlyHeaders } from 'flags';
186
- import { dedupe } from 'flags/next';
187
- import { nanoid } from 'nanoid';
188
- import type { NextRequest } from 'next/server';
189
-
190
- const generateId = dedupe(async () => nanoid());
191
-
192
- export const getFlagSyncUserContext = async (
193
- cookies: ReadonlyRequestCookies | NextRequest['cookies'],
194
- headers: ReadonlyHeaders | NextRequest['headers'],
195
- ) => {
196
- const userId = cookies.get('user-id')?.value; // Authenticated user
197
- const visitorId = cookies.get('visitor-id')?.value; // Anonymous visitor
198
-
199
- return {
200
- key: userId ?? visitorId ?? (await generateId()), // Fallback to new ID
201
- attributes: {
202
- userAgent: headers.get('user-agent') || 'unknown', // Browser info
203
- region: headers.get('x-region-code') || 'default', // Custom header
204
- },
205
- };
206
- };
207
-
208
- ```
209
- ### Step 2: Set up identification
210
-
211
- Use the helper in `identify`:
212
-
213
- ```typescript
214
- // lib/flagsync.ts
215
- import { createIdentify, createFlagSyncClient } from '@flagsync/vercel-flags-sdk';
216
- import { getFlagSyncUserContext } from '@lib/flagsync.user-context';
217
-
218
- export const identify = createIdentify(({ cookies, headers }) => {
219
- return getFlagSyncUserContext(cookies, headers);
220
- });
221
-
222
- export const client = createFlagSyncClient({
223
- sdkKey: process.env.FLAGSYNC_SDK_KEY!,
224
- });
225
- ```
226
-
227
- ### Step 3: Handle cookies in middleware
228
-
229
- ```typescript
230
- // middleware.ts
231
- import { NextRequest, NextResponse } from 'next/server';
232
- import { nanoid } from 'nanoid';
233
-
234
- export async function middleware(request: NextRequest) {
235
- const response = NextResponse.next();
236
-
237
- // Example: Get userId from a JWT or API call (replace with your logic)
238
- const jwt = request.cookies.get('jwt')?.value;
239
- let userId: string | undefined;
240
- if (jwt) {
241
- userId = 'user@example.com'; // Stub: e.g., await decodeJwt(jwt).email
242
- }
243
-
244
- if (userId) {
245
- response.cookies.set('user-id', userId, { maxAge: 60 * 60 * 24 * 7 });
246
- } else {
247
- const visitorId = request.cookies.get('visitor-id')?.value ?? nanoid();
248
- response.cookies.set('visitor-id', visitorId, { maxAge: 60 * 60 * 24 * 365 });
249
- }
250
-
251
- return response;
252
- }
253
-
254
- export const config = {
255
- matcher: [
256
- /*
257
- * Match all request paths except for the ones starting with:
258
- * - api (API routes)
259
- * - _next/static (static files)
260
- * - _next/image (image optimization files)
261
- * - favicon.ico (favicon file)
262
- */
263
- {
264
- source: '/((?!api|_next/static|_next/image|favicon.ico).*)',
265
- missing: [
266
- { type: 'header', key: 'next-router-prefetch' },
267
- { type: 'header', key: 'purpose', value: 'prefetch' },
268
- ],
269
- },
270
- ],
271
- };
272
-
273
- ```
274
-
275
- ## Next Steps
276
-
277
- - Configure flags in the [FlagSync dashboard](https://www.flagsync.com/dashboard).
278
- - Explore the [Docs](https://docs.flagsync.com/) for information on how to use FlagSync.
279
-
280
- ## Environment Variables
281
-
282
- Required environment variables:
283
-
284
- - `FLAGSYNC_SDK_KEY`: Your server-side FlagSync SDK key (required)
285
-
286
- ### License
287
-
288
- [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)
13
+ ## Getting Started
14
+ Refer to the [SDK documentation](https://docs.flagsync.com/sdks-server-side/nextjs) for setup instructions and usage details.
package/dist/index.cjs CHANGED
@@ -39,7 +39,7 @@ function createFlagSyncClient(config) {
39
39
  ...config,
40
40
  metadata: {
41
41
  sdkName: "@flagsync/nextjs-sdk",
42
- sdkVersion: "0.2.6"
42
+ sdkVersion: "0.2.8"
43
43
  }
44
44
  });
45
45
  return instance.client();
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/adapter.ts","../src/identify.ts"],"sourcesContent":["export type {\n CustomAttributes,\n CustomAttributeValue,\n FsConfig,\n FsClient,\n LogLevel,\n FsUserContext,\n} from '@flagsync/node-sdk';\n\nexport { SyncType } from '@flagsync/node-sdk';\n\nexport type { JsonObject } from './types';\n\nexport {\n createFlagSyncClient,\n createFlagSyncAdapter,\n createBoolFlagAdaptor,\n createStringFlagAdaptor,\n createJsonFlagAdaptor,\n createNumberFlagAdaptor,\n} from './adapter';\n\nexport { createIdentify } from './identify';\n","import {\n FlagSyncFactory,\n FsClient,\n type FsConfig,\n type FsUserContext,\n} from '@flagsync/node-sdk';\nimport type { Adapter } from '@vercel/flags';\n\nimport { JsonObject } from './types';\n\n/**\n * Creates a FlagSync client instance that can be used across multiple feature flags.\n * This function should be called once to create a singleton client for your application.\n */\nexport function createFlagSyncClient(config: FsConfig): FsClient {\n const instance = FlagSyncFactory({\n ...config,\n metadata: {\n sdkName: '@flagsync/nextjs-sdk',\n sdkVersion: '0.2.6',\n },\n });\n return instance.client();\n}\n\n/**\n * Creates an adapter factory that integrates FlagSync with Vercel's feature flag system.\n * This adapter handles the communication between your application and the FlagSync service.\n */\nexport function createFlagSyncAdapter(client: FsClient) {\n let isReady = false;\n\n /**\n * Ensures the FlagSync client is ready before making any flag decisions.\n * This is called internally before each flag evaluation.\n */\n const ensureReady = async () => {\n if (!isReady) {\n await client.waitForReady();\n isReady = true;\n }\n };\n\n /**\n * Creates a typed adapter instance for a specific flag value type.\n */\n return function flagSyncAdapter<ValueType>(): Adapter<\n ValueType,\n FsUserContext\n > {\n return {\n /**\n * Evaluates a feature flag for a given context and returns its value.\n */\n async decide({ key, entities }) {\n await ensureReady();\n\n const userContext: FsUserContext = {\n key: 'anonymous',\n ...(entities ?? {}),\n };\n\n return client.flag<ValueType>(userContext, key);\n },\n };\n };\n}\n\n/** Creates an adapter for string-typed flags */\nexport const createStringFlagAdaptor = (\n client: FsClient,\n): Adapter<string, FsUserContext> => createFlagSyncAdapter(client)<string>();\n\n/** Creates an adapter for boolean-typed flags */\nexport const createBoolFlagAdaptor = (\n client: FsClient,\n): Adapter<boolean, FsUserContext> => createFlagSyncAdapter(client)<boolean>();\n\n/** Creates an adapter for number-typed flags */\nexport const createNumberFlagAdaptor = (\n client: FsClient,\n): Adapter<number, FsUserContext> => createFlagSyncAdapter(client)<number>();\n\n/** Creates an adapter for JSON object-typed flags */\nexport const createJsonFlagAdaptor = (\n client: FsClient,\n): Adapter<JsonObject, FsUserContext> =>\n createFlagSyncAdapter(client)<JsonObject>();\n","import { FsUserContext } from '@flagsync/node-sdk';\nimport { Identify } from '@vercel/flags';\n\ntype ExtractParams<T> = T extends (params: infer P) => any ? P : never;\n\nexport const createIdentify =\n (\n callback: (\n params: ExtractParams<Identify<FsUserContext>>,\n ) => Promise<FsUserContext> | FsUserContext,\n ): Identify<FsUserContext> =>\n (params) =>\n callback(params);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,IAAAA,mBAAyB;;;ACTzB,sBAKO;AASA,SAAS,qBAAqB,QAA4B;AAC/D,QAAM,eAAW,iCAAgB;AAAA,IAC/B,GAAG;AAAA,IACH,UAAU;AAAA,MACR,SAAS;AAAA,MACT,YAAY;AAAA,IACd;AAAA,EACF,CAAC;AACD,SAAO,SAAS,OAAO;AACzB;AAMO,SAAS,sBAAsB,QAAkB;AACtD,MAAI,UAAU;AAMd,QAAM,cAAc,YAAY;AAC9B,QAAI,CAAC,SAAS;AACZ,YAAM,OAAO,aAAa;AAC1B,gBAAU;AAAA,IACZ;AAAA,EACF;AAKA,SAAO,SAAS,kBAGd;AACA,WAAO;AAAA;AAAA;AAAA;AAAA,MAIL,MAAM,OAAO,EAAE,KAAK,SAAS,GAAG;AAC9B,cAAM,YAAY;AAElB,cAAM,cAA6B;AAAA,UACjC,KAAK;AAAA,UACL,GAAI,YAAY,CAAC;AAAA,QACnB;AAEA,eAAO,OAAO,KAAgB,aAAa,GAAG;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AACF;AAGO,IAAM,0BAA0B,CACrC,WACmC,sBAAsB,MAAM,EAAU;AAGpE,IAAM,wBAAwB,CACnC,WACoC,sBAAsB,MAAM,EAAW;AAGtE,IAAM,0BAA0B,CACrC,WACmC,sBAAsB,MAAM,EAAU;AAGpE,IAAM,wBAAwB,CACnC,WAEA,sBAAsB,MAAM,EAAc;;;AClFrC,IAAM,iBACX,CACE,aAIF,CAAC,WACC,SAAS,MAAM;","names":["import_node_sdk"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/adapter.ts","../src/identify.ts"],"sourcesContent":["export type {\n CustomAttributes,\n CustomAttributeValue,\n FsConfig,\n FsClient,\n LogLevel,\n FsUserContext,\n} from '@flagsync/node-sdk';\n\nexport { SyncType } from '@flagsync/node-sdk';\n\nexport type { JsonObject } from './types';\n\nexport {\n createFlagSyncClient,\n createFlagSyncAdapter,\n createBoolFlagAdaptor,\n createStringFlagAdaptor,\n createJsonFlagAdaptor,\n createNumberFlagAdaptor,\n} from './adapter';\n\nexport { createIdentify } from './identify';\n","import {\n FlagSyncFactory,\n FsClient,\n type FsConfig,\n type FsUserContext,\n} from '@flagsync/node-sdk';\nimport type { Adapter } from '@vercel/flags';\n\nimport { JsonObject } from './types';\n\n/**\n * Creates a FlagSync client instance that can be used across multiple feature flags.\n * This function should be called once to create a singleton client for your application.\n */\nexport function createFlagSyncClient(config: FsConfig): FsClient {\n const instance = FlagSyncFactory({\n ...config,\n metadata: {\n sdkName: '@flagsync/nextjs-sdk',\n sdkVersion: '0.2.8',\n },\n });\n return instance.client();\n}\n\n/**\n * Creates an adapter factory that integrates FlagSync with Vercel's feature flag system.\n * This adapter handles the communication between your application and the FlagSync service.\n */\nexport function createFlagSyncAdapter(client: FsClient) {\n let isReady = false;\n\n /**\n * Ensures the FlagSync client is ready before making any flag decisions.\n * This is called internally before each flag evaluation.\n */\n const ensureReady = async () => {\n if (!isReady) {\n await client.waitForReady();\n isReady = true;\n }\n };\n\n /**\n * Creates a typed adapter instance for a specific flag value type.\n */\n return function flagSyncAdapter<ValueType>(): Adapter<\n ValueType,\n FsUserContext\n > {\n return {\n /**\n * Evaluates a feature flag for a given context and returns its value.\n */\n async decide({ key, entities }) {\n await ensureReady();\n\n const userContext: FsUserContext = {\n key: 'anonymous',\n ...(entities ?? {}),\n };\n\n return client.flag<ValueType>(userContext, key);\n },\n };\n };\n}\n\n/** Creates an adapter for string-typed flags */\nexport const createStringFlagAdaptor = (\n client: FsClient,\n): Adapter<string, FsUserContext> => createFlagSyncAdapter(client)<string>();\n\n/** Creates an adapter for boolean-typed flags */\nexport const createBoolFlagAdaptor = (\n client: FsClient,\n): Adapter<boolean, FsUserContext> => createFlagSyncAdapter(client)<boolean>();\n\n/** Creates an adapter for number-typed flags */\nexport const createNumberFlagAdaptor = (\n client: FsClient,\n): Adapter<number, FsUserContext> => createFlagSyncAdapter(client)<number>();\n\n/** Creates an adapter for JSON object-typed flags */\nexport const createJsonFlagAdaptor = (\n client: FsClient,\n): Adapter<JsonObject, FsUserContext> =>\n createFlagSyncAdapter(client)<JsonObject>();\n","import { FsUserContext } from '@flagsync/node-sdk';\nimport { Identify } from '@vercel/flags';\n\ntype ExtractParams<T> = T extends (params: infer P) => any ? P : never;\n\nexport const createIdentify =\n (\n callback: (\n params: ExtractParams<Identify<FsUserContext>>,\n ) => Promise<FsUserContext> | FsUserContext,\n ): Identify<FsUserContext> =>\n (params) =>\n callback(params);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,IAAAA,mBAAyB;;;ACTzB,sBAKO;AASA,SAAS,qBAAqB,QAA4B;AAC/D,QAAM,eAAW,iCAAgB;AAAA,IAC/B,GAAG;AAAA,IACH,UAAU;AAAA,MACR,SAAS;AAAA,MACT,YAAY;AAAA,IACd;AAAA,EACF,CAAC;AACD,SAAO,SAAS,OAAO;AACzB;AAMO,SAAS,sBAAsB,QAAkB;AACtD,MAAI,UAAU;AAMd,QAAM,cAAc,YAAY;AAC9B,QAAI,CAAC,SAAS;AACZ,YAAM,OAAO,aAAa;AAC1B,gBAAU;AAAA,IACZ;AAAA,EACF;AAKA,SAAO,SAAS,kBAGd;AACA,WAAO;AAAA;AAAA;AAAA;AAAA,MAIL,MAAM,OAAO,EAAE,KAAK,SAAS,GAAG;AAC9B,cAAM,YAAY;AAElB,cAAM,cAA6B;AAAA,UACjC,KAAK;AAAA,UACL,GAAI,YAAY,CAAC;AAAA,QACnB;AAEA,eAAO,OAAO,KAAgB,aAAa,GAAG;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AACF;AAGO,IAAM,0BAA0B,CACrC,WACmC,sBAAsB,MAAM,EAAU;AAGpE,IAAM,wBAAwB,CACnC,WACoC,sBAAsB,MAAM,EAAW;AAGtE,IAAM,0BAA0B,CACrC,WACmC,sBAAsB,MAAM,EAAU;AAGpE,IAAM,wBAAwB,CACnC,WAEA,sBAAsB,MAAM,EAAc;;;AClFrC,IAAM,iBACX,CACE,aAIF,CAAC,WACC,SAAS,MAAM;","names":["import_node_sdk"]}
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ function createFlagSyncClient(config) {
10
10
  ...config,
11
11
  metadata: {
12
12
  sdkName: "@flagsync/nextjs-sdk",
13
- sdkVersion: "0.2.6"
13
+ sdkVersion: "0.2.8"
14
14
  }
15
15
  });
16
16
  return instance.client();
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/adapter.ts","../src/identify.ts"],"sourcesContent":["export type {\n CustomAttributes,\n CustomAttributeValue,\n FsConfig,\n FsClient,\n LogLevel,\n FsUserContext,\n} from '@flagsync/node-sdk';\n\nexport { SyncType } from '@flagsync/node-sdk';\n\nexport type { JsonObject } from './types';\n\nexport {\n createFlagSyncClient,\n createFlagSyncAdapter,\n createBoolFlagAdaptor,\n createStringFlagAdaptor,\n createJsonFlagAdaptor,\n createNumberFlagAdaptor,\n} from './adapter';\n\nexport { createIdentify } from './identify';\n","import {\n FlagSyncFactory,\n FsClient,\n type FsConfig,\n type FsUserContext,\n} from '@flagsync/node-sdk';\nimport type { Adapter } from '@vercel/flags';\n\nimport { JsonObject } from './types';\n\n/**\n * Creates a FlagSync client instance that can be used across multiple feature flags.\n * This function should be called once to create a singleton client for your application.\n */\nexport function createFlagSyncClient(config: FsConfig): FsClient {\n const instance = FlagSyncFactory({\n ...config,\n metadata: {\n sdkName: '@flagsync/nextjs-sdk',\n sdkVersion: '0.2.6',\n },\n });\n return instance.client();\n}\n\n/**\n * Creates an adapter factory that integrates FlagSync with Vercel's feature flag system.\n * This adapter handles the communication between your application and the FlagSync service.\n */\nexport function createFlagSyncAdapter(client: FsClient) {\n let isReady = false;\n\n /**\n * Ensures the FlagSync client is ready before making any flag decisions.\n * This is called internally before each flag evaluation.\n */\n const ensureReady = async () => {\n if (!isReady) {\n await client.waitForReady();\n isReady = true;\n }\n };\n\n /**\n * Creates a typed adapter instance for a specific flag value type.\n */\n return function flagSyncAdapter<ValueType>(): Adapter<\n ValueType,\n FsUserContext\n > {\n return {\n /**\n * Evaluates a feature flag for a given context and returns its value.\n */\n async decide({ key, entities }) {\n await ensureReady();\n\n const userContext: FsUserContext = {\n key: 'anonymous',\n ...(entities ?? {}),\n };\n\n return client.flag<ValueType>(userContext, key);\n },\n };\n };\n}\n\n/** Creates an adapter for string-typed flags */\nexport const createStringFlagAdaptor = (\n client: FsClient,\n): Adapter<string, FsUserContext> => createFlagSyncAdapter(client)<string>();\n\n/** Creates an adapter for boolean-typed flags */\nexport const createBoolFlagAdaptor = (\n client: FsClient,\n): Adapter<boolean, FsUserContext> => createFlagSyncAdapter(client)<boolean>();\n\n/** Creates an adapter for number-typed flags */\nexport const createNumberFlagAdaptor = (\n client: FsClient,\n): Adapter<number, FsUserContext> => createFlagSyncAdapter(client)<number>();\n\n/** Creates an adapter for JSON object-typed flags */\nexport const createJsonFlagAdaptor = (\n client: FsClient,\n): Adapter<JsonObject, FsUserContext> =>\n createFlagSyncAdapter(client)<JsonObject>();\n","import { FsUserContext } from '@flagsync/node-sdk';\nimport { Identify } from '@vercel/flags';\n\ntype ExtractParams<T> = T extends (params: infer P) => any ? P : never;\n\nexport const createIdentify =\n (\n callback: (\n params: ExtractParams<Identify<FsUserContext>>,\n ) => Promise<FsUserContext> | FsUserContext,\n ): Identify<FsUserContext> =>\n (params) =>\n callback(params);\n"],"mappings":";AASA,SAAS,gBAAgB;;;ACTzB;AAAA,EACE;AAAA,OAIK;AASA,SAAS,qBAAqB,QAA4B;AAC/D,QAAM,WAAW,gBAAgB;AAAA,IAC/B,GAAG;AAAA,IACH,UAAU;AAAA,MACR,SAAS;AAAA,MACT,YAAY;AAAA,IACd;AAAA,EACF,CAAC;AACD,SAAO,SAAS,OAAO;AACzB;AAMO,SAAS,sBAAsB,QAAkB;AACtD,MAAI,UAAU;AAMd,QAAM,cAAc,YAAY;AAC9B,QAAI,CAAC,SAAS;AACZ,YAAM,OAAO,aAAa;AAC1B,gBAAU;AAAA,IACZ;AAAA,EACF;AAKA,SAAO,SAAS,kBAGd;AACA,WAAO;AAAA;AAAA;AAAA;AAAA,MAIL,MAAM,OAAO,EAAE,KAAK,SAAS,GAAG;AAC9B,cAAM,YAAY;AAElB,cAAM,cAA6B;AAAA,UACjC,KAAK;AAAA,UACL,GAAI,YAAY,CAAC;AAAA,QACnB;AAEA,eAAO,OAAO,KAAgB,aAAa,GAAG;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AACF;AAGO,IAAM,0BAA0B,CACrC,WACmC,sBAAsB,MAAM,EAAU;AAGpE,IAAM,wBAAwB,CACnC,WACoC,sBAAsB,MAAM,EAAW;AAGtE,IAAM,0BAA0B,CACrC,WACmC,sBAAsB,MAAM,EAAU;AAGpE,IAAM,wBAAwB,CACnC,WAEA,sBAAsB,MAAM,EAAc;;;AClFrC,IAAM,iBACX,CACE,aAIF,CAAC,WACC,SAAS,MAAM;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/adapter.ts","../src/identify.ts"],"sourcesContent":["export type {\n CustomAttributes,\n CustomAttributeValue,\n FsConfig,\n FsClient,\n LogLevel,\n FsUserContext,\n} from '@flagsync/node-sdk';\n\nexport { SyncType } from '@flagsync/node-sdk';\n\nexport type { JsonObject } from './types';\n\nexport {\n createFlagSyncClient,\n createFlagSyncAdapter,\n createBoolFlagAdaptor,\n createStringFlagAdaptor,\n createJsonFlagAdaptor,\n createNumberFlagAdaptor,\n} from './adapter';\n\nexport { createIdentify } from './identify';\n","import {\n FlagSyncFactory,\n FsClient,\n type FsConfig,\n type FsUserContext,\n} from '@flagsync/node-sdk';\nimport type { Adapter } from '@vercel/flags';\n\nimport { JsonObject } from './types';\n\n/**\n * Creates a FlagSync client instance that can be used across multiple feature flags.\n * This function should be called once to create a singleton client for your application.\n */\nexport function createFlagSyncClient(config: FsConfig): FsClient {\n const instance = FlagSyncFactory({\n ...config,\n metadata: {\n sdkName: '@flagsync/nextjs-sdk',\n sdkVersion: '0.2.8',\n },\n });\n return instance.client();\n}\n\n/**\n * Creates an adapter factory that integrates FlagSync with Vercel's feature flag system.\n * This adapter handles the communication between your application and the FlagSync service.\n */\nexport function createFlagSyncAdapter(client: FsClient) {\n let isReady = false;\n\n /**\n * Ensures the FlagSync client is ready before making any flag decisions.\n * This is called internally before each flag evaluation.\n */\n const ensureReady = async () => {\n if (!isReady) {\n await client.waitForReady();\n isReady = true;\n }\n };\n\n /**\n * Creates a typed adapter instance for a specific flag value type.\n */\n return function flagSyncAdapter<ValueType>(): Adapter<\n ValueType,\n FsUserContext\n > {\n return {\n /**\n * Evaluates a feature flag for a given context and returns its value.\n */\n async decide({ key, entities }) {\n await ensureReady();\n\n const userContext: FsUserContext = {\n key: 'anonymous',\n ...(entities ?? {}),\n };\n\n return client.flag<ValueType>(userContext, key);\n },\n };\n };\n}\n\n/** Creates an adapter for string-typed flags */\nexport const createStringFlagAdaptor = (\n client: FsClient,\n): Adapter<string, FsUserContext> => createFlagSyncAdapter(client)<string>();\n\n/** Creates an adapter for boolean-typed flags */\nexport const createBoolFlagAdaptor = (\n client: FsClient,\n): Adapter<boolean, FsUserContext> => createFlagSyncAdapter(client)<boolean>();\n\n/** Creates an adapter for number-typed flags */\nexport const createNumberFlagAdaptor = (\n client: FsClient,\n): Adapter<number, FsUserContext> => createFlagSyncAdapter(client)<number>();\n\n/** Creates an adapter for JSON object-typed flags */\nexport const createJsonFlagAdaptor = (\n client: FsClient,\n): Adapter<JsonObject, FsUserContext> =>\n createFlagSyncAdapter(client)<JsonObject>();\n","import { FsUserContext } from '@flagsync/node-sdk';\nimport { Identify } from '@vercel/flags';\n\ntype ExtractParams<T> = T extends (params: infer P) => any ? P : never;\n\nexport const createIdentify =\n (\n callback: (\n params: ExtractParams<Identify<FsUserContext>>,\n ) => Promise<FsUserContext> | FsUserContext,\n ): Identify<FsUserContext> =>\n (params) =>\n callback(params);\n"],"mappings":";AASA,SAAS,gBAAgB;;;ACTzB;AAAA,EACE;AAAA,OAIK;AASA,SAAS,qBAAqB,QAA4B;AAC/D,QAAM,WAAW,gBAAgB;AAAA,IAC/B,GAAG;AAAA,IACH,UAAU;AAAA,MACR,SAAS;AAAA,MACT,YAAY;AAAA,IACd;AAAA,EACF,CAAC;AACD,SAAO,SAAS,OAAO;AACzB;AAMO,SAAS,sBAAsB,QAAkB;AACtD,MAAI,UAAU;AAMd,QAAM,cAAc,YAAY;AAC9B,QAAI,CAAC,SAAS;AACZ,YAAM,OAAO,aAAa;AAC1B,gBAAU;AAAA,IACZ;AAAA,EACF;AAKA,SAAO,SAAS,kBAGd;AACA,WAAO;AAAA;AAAA;AAAA;AAAA,MAIL,MAAM,OAAO,EAAE,KAAK,SAAS,GAAG;AAC9B,cAAM,YAAY;AAElB,cAAM,cAA6B;AAAA,UACjC,KAAK;AAAA,UACL,GAAI,YAAY,CAAC;AAAA,QACnB;AAEA,eAAO,OAAO,KAAgB,aAAa,GAAG;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AACF;AAGO,IAAM,0BAA0B,CACrC,WACmC,sBAAsB,MAAM,EAAU;AAGpE,IAAM,wBAAwB,CACnC,WACoC,sBAAsB,MAAM,EAAW;AAGtE,IAAM,0BAA0B,CACrC,WACmC,sBAAsB,MAAM,EAAU;AAGpE,IAAM,wBAAwB,CACnC,WAEA,sBAAsB,MAAM,EAAc;;;AClFrC,IAAM,iBACX,CACE,aAIF,CAAC,WACC,SAAS,MAAM;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flagsync/nextjs-sdk",
3
- "version": "0.2.6",
3
+ "version": "0.2.8",
4
4
  "description": "FlagSync adapter for Vercel's Flags SDK",
5
5
  "author": "Mike Chabot",
6
6
  "license": "Apache-2.0",
@@ -39,7 +39,7 @@
39
39
  "@vercel/flags": "^3.1.1"
40
40
  },
41
41
  "dependencies": {
42
- "@flagsync/node-sdk": "^0.2.1"
42
+ "@flagsync/node-sdk": "^0.2.2"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@trivago/prettier-plugin-sort-imports": "^5.2.2",