@configdirector/nextjs-sdk 1.10.0 → 1.11.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.
Files changed (59) hide show
  1. package/dist/client/index.cjs +1 -1
  2. package/dist/client/index.d.cts +21 -8
  3. package/dist/client/index.d.cts.map +1 -1
  4. package/dist/client/index.d.mts +21 -8
  5. package/dist/client/index.d.mts.map +1 -1
  6. package/dist/client/index.mjs +1 -1
  7. package/dist/client/index.mjs.map +1 -1
  8. package/dist/client/installedTestClient-BhHUzJ9D.cjs +6 -0
  9. package/dist/client/installedTestClient-BwTUOOhP.mjs +7 -0
  10. package/dist/client/installedTestClient-BwTUOOhP.mjs.map +1 -0
  11. package/dist/client/testing.cjs +1 -1
  12. package/dist/client/testing.d.cts +5 -14
  13. package/dist/client/testing.d.cts.map +1 -1
  14. package/dist/client/testing.d.mts +5 -14
  15. package/dist/client/testing.d.mts.map +1 -1
  16. package/dist/client/testing.mjs +1 -1
  17. package/dist/client/testing.mjs.map +1 -1
  18. package/dist/client/{types-De4z0tu4.d.mts → types-2Z0rA7lF.d.cts} +23 -3
  19. package/dist/client/types-2Z0rA7lF.d.cts.map +1 -0
  20. package/dist/client/{types-Cz68hQ6f.d.cts → types-6a1uEkD0.d.mts} +23 -3
  21. package/dist/client/types-6a1uEkD0.d.mts.map +1 -0
  22. package/dist/server/DefaultConfigDirectorClient-BplPvnEk.mjs +6 -0
  23. package/dist/server/DefaultConfigDirectorClient-BplPvnEk.mjs.map +1 -0
  24. package/dist/server/DefaultConfigDirectorClient-oT53aH0F.cjs +5 -0
  25. package/dist/server/{types-BBEEMV5Y.d.cts → errors-EfmnEmll.d.cts} +108 -38
  26. package/dist/server/errors-EfmnEmll.d.cts.map +1 -0
  27. package/dist/server/{types-B_mGbQaa.d.mts → errors-r1MHQ8L5.d.mts} +108 -38
  28. package/dist/server/errors-r1MHQ8L5.d.mts.map +1 -0
  29. package/dist/server/index.cjs +1 -1
  30. package/dist/server/index.d.cts +44 -9
  31. package/dist/server/index.d.cts.map +1 -1
  32. package/dist/server/index.d.mts +44 -9
  33. package/dist/server/index.d.mts.map +1 -1
  34. package/dist/server/index.mjs +1 -1
  35. package/dist/server/index.mjs.map +1 -1
  36. package/dist/server/native-values-CfqV9hAq.mjs +2 -0
  37. package/dist/server/native-values-CfqV9hAq.mjs.map +1 -0
  38. package/dist/server/native-values-UCK4hh1Z.cjs +1 -0
  39. package/dist/server/testing.cjs +1 -1
  40. package/dist/server/testing.d.cts +5 -25
  41. package/dist/server/testing.d.cts.map +1 -1
  42. package/dist/server/testing.d.mts +5 -25
  43. package/dist/server/testing.d.mts.map +1 -1
  44. package/dist/server/testing.mjs +1 -1
  45. package/dist/server/testing.mjs.map +1 -1
  46. package/package.json +1 -1
  47. package/dist/client/installedTestClient-CW29YuQC.cjs +0 -6
  48. package/dist/client/installedTestClient-CpjJvHZD.mjs +0 -7
  49. package/dist/client/installedTestClient-CpjJvHZD.mjs.map +0 -1
  50. package/dist/client/types-Cz68hQ6f.d.cts.map +0 -1
  51. package/dist/client/types-De4z0tu4.d.mts.map +0 -1
  52. package/dist/server/DefaultConfigDirectorClient-BTTja_j3.mjs +0 -6
  53. package/dist/server/DefaultConfigDirectorClient-BTTja_j3.mjs.map +0 -1
  54. package/dist/server/DefaultConfigDirectorClient-CqXqwNpW.cjs +0 -5
  55. package/dist/server/errors-BGpFuqOO.mjs +0 -2
  56. package/dist/server/errors-BGpFuqOO.mjs.map +0 -1
  57. package/dist/server/errors-CCbuIqT8.cjs +0 -1
  58. package/dist/server/types-BBEEMV5Y.d.cts.map +0 -1
  59. package/dist/server/types-B_mGbQaa.d.mts.map +0 -1
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./DefaultConfigDirectorClient-CqXqwNpW.cjs`);const e=require(`./errors-CCbuIqT8.cjs`);let t=require(`@configdirector/nextjs-sdk/client`),n=require(`react/jsx-runtime`);var r=class{decorateMessage(e){return`[ConfigDirector:nextjs-sdk] ${e}`}};const i=(t,n)=>new e.i(t??`warn`,n??new r),a=(t,n)=>new e.i(t,n??new r);async function o(t){if(process.env.NEXT_RUNTIME===`nodejs`){if(!t.serverSdkKey){let t=`The ConfigDirector serverSdkKey must be provided to register(). You can pass it via process.env.CONFIGDIRECTOR_SERVER_KEY.`;throw i().error(t),new e.n(t)}if(!globalThis.__configDirectorServerClient){let{DefaultConfigDirectorClient:e}=await Promise.resolve().then(()=>require(`./DefaultConfigDirectorClient-CqXqwNpW.cjs`)).then(e=>e.n),{serverSdkKey:n,...r}=t;globalThis.__configDirectorAppMeta={appName:t.metadata?.appName,appVersion:t.metadata?.appVersion};let i=new e(n,{sdkName:`nextjs-sdk`,sdkVersion:`1.10.0`},r);globalThis.__configDirectorServerClient=i,await i.initialize()}}}function s(){return globalThis.__configDirectorAppMeta??{}}function c(){if(!globalThis.__configDirectorServerClient)throw new e.n(`[ConfigDirector] Server client not initialized. Make sure to call register() in your instrumentation.ts file before using the SDK.`);return globalThis.__configDirectorServerClient}const l=i();function u(e){try{return c().getAllConfigs(e)}catch(e){return l.error(`Error retrieving SSR config set:`,e),{}}}async function d({children:e,configKeys:r,...i}){let a=u({context:i.context,configKeys:r}),o=s();return(0,n.jsx)(t.ConfigDirectorProvider,{...i,appName:i.appName??o.appName,appVersion:i.appVersion??o.appVersion,initialConfigs:a,children:e})}exports.ConfigDirectorProvider=d,exports.createConsoleLogger=a,exports.generateSsrConfigSet=u,exports.getAppMeta=s,exports.getConfigClient=c,exports.register=o;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./DefaultConfigDirectorClient-oT53aH0F.cjs`);const e=require(`./native-values-UCK4hh1Z.cjs`);let t=require(`@configdirector/nextjs-sdk/client`),n=require(`react/jsx-runtime`);var r=class{decorateMessage(e){return`[ConfigDirector:nextjs-sdk] ${e}`}};const i=(t,n)=>new e.o(t??`warn`,n??new r),a=(t,n)=>new e.o(t,n??new r);async function o(t){if(process.env.NEXT_RUNTIME===`nodejs`){let n=t.connection?.mode??`streaming`;if(n!==`offline`&&!t.serverSdkKey){let t=`The ConfigDirector serverSdkKey must be provided to register(). You can pass it via process.env.CONFIGDIRECTOR_SERVER_KEY.`;throw i().error(t),new e.i(t)}if(!globalThis.__configDirectorServerClient){let{DefaultConfigDirectorClient:e}=await Promise.resolve().then(()=>require(`./DefaultConfigDirectorClient-oT53aH0F.cjs`)).then(e=>e.n),{serverSdkKey:r,...i}=t;globalThis.__configDirectorAppMeta={appName:t.metadata?.appName,appVersion:t.metadata?.appVersion},globalThis.__configDirectorServerConnectionMode=n;let a=new e(r,{sdkName:`nextjs-sdk`,sdkVersion:`1.11.0`},i);globalThis.__configDirectorServerClient=a;try{await a.initialize()}catch(e){throw globalThis.__configDirectorServerClient=void 0,globalThis.__configDirectorServerConnectionMode=void 0,globalThis.__configDirectorAppMeta=void 0,a.dispose(),e}}}}function s(){return globalThis.__configDirectorAppMeta??{}}function c(){return globalThis.__configDirectorServerConnectionMode}function l(){if(!globalThis.__configDirectorServerClient)throw new e.i(`[ConfigDirector] Server client not initialized. Make sure to call register() in your instrumentation.ts file before using the SDK.`);return globalThis.__configDirectorServerClient}const u=i();function d(e){try{return l().getAllConfigs(e)}catch(e){return u.error(`Error retrieving SSR config set:`,e),{}}}const f=(e,t)=>e.mode!==void 0||e.values!==void 0?`as-given`:t===`offline`?`inherit-offline`:`connect`,p=e=>typeof e.value==`string`,m=t=>Object.fromEntries(Object.values(t).filter(p).map(t=>[t.key,e.t(t.type,t.value)]));async function h({children:e,configKeys:r,...i}){let a=d({context:i.context,configKeys:r}),o=s();return(0,n.jsx)(t.ConfigDirectorProvider,{...i,...g(a,i),appName:i.appName??o.appName,appVersion:i.appVersion??o.appVersion,initialConfigs:a,children:e})}const g=(e,t)=>{switch(f(t,c())){case`as-given`:return{};case`inherit-offline`:return{mode:`offline`,values:m(e)};case`connect`:return{}}};exports.ConfigDirectorInitializationError=e.i,exports.ConfigDirectorProvider=h,exports.createConsoleLogger=a,exports.generateSsrConfigSet=d,exports.getAppMeta=s,exports.getConfigClient=l,exports.register=o;
@@ -1,22 +1,30 @@
1
- import { a as ConfigDirectorLogger, c as ConfigEvaluation, d as ConnectionMode, i as ConfigDirectorLogMessageDecorator, l as ConfigState, n as ConfigDirectorClientOptions, o as ConfigDirectorLoggingLevel, r as ConfigDirectorContext, s as ConfigDirectorMetaContext, t as ConfigDirectorClient, u as ConfigValueType } from "./types-BBEEMV5Y.cjs";
1
+ import { _ as ConfigEvaluation, a as ConfigDirectorClientOptions, b as ConnectionMode, c as OfflineValues, d as NativeValues, f as ConfigDirectorContext, g as ConfigDirectorMetaContext, h as ConfigDirectorLoggingLevel, i as ConfigDirectorClient, m as ConfigDirectorLogger, n as ConfigDirectorInitializationError, o as OfflineClientOptions, p as ConfigDirectorLogMessageDecorator, s as OfflineValue, v as ConfigState, y as ConfigValueType } from "./errors-EfmnEmll.cjs";
2
2
  import * as _$react_jsx_runtime0 from "react/jsx-runtime";
3
3
  import { PropsWithChildren } from "react";
4
4
 
5
5
  //#region src/server/singleton.d.ts
6
6
  declare global {
7
7
  var __configDirectorServerClient: ConfigDirectorClient | undefined;
8
+ var __configDirectorServerConnectionMode: ConnectionMode | undefined;
8
9
  var __configDirectorAppMeta: {
9
10
  appName?: string;
10
11
  appVersion?: string;
11
12
  } | undefined;
12
13
  }
13
- type RegisterOptions = {
14
+ /**
15
+ * Options of {@link register}. A server SDK key is required unless `connection.mode` is `offline`,
16
+ * in which case the server singleton never connects and serves `connection.file` or
17
+ * `connection.values` instead.
18
+ */
19
+ type RegisterOptions = ({
14
20
  /**
15
21
  * Your ConfigDirector Server SDK key. This is a secret value — do not commit it to source
16
22
  * control. Provide it via an environment variable (e.g. process.env.CONFIGDIRECTOR_SERVER_KEY).
17
23
  */
18
24
  serverSdkKey: string;
19
- } & ConfigDirectorClientOptions;
25
+ } & ConfigDirectorClientOptions) | (OfflineClientOptions & {
26
+ serverSdkKey?: undefined;
27
+ });
20
28
  /**
21
29
  * Initializes the ConfigDirector server SDK singleton. Call this from your Next.js
22
30
  * `instrumentation.ts` file so it runs once when the server starts:
@@ -28,6 +36,15 @@ type RegisterOptions = {
28
36
  * await register({ serverSdkKey: process.env.CONFIGDIRECTOR_SERVER_KEY! });
29
37
  * }
30
38
  * ```
39
+ *
40
+ * In `offline` mode no key is needed, and the server never connects:
41
+ *
42
+ * ```ts
43
+ * await register({ connection: { mode: "offline", file: "./flags/new-checkout-on.json" } });
44
+ * ```
45
+ *
46
+ * Rejects with a `ConfigDirectorInitializationError` when the key is missing outside `offline`
47
+ * mode, or when the offline file or values cannot be loaded.
31
48
  */
32
49
  declare function register(options: RegisterOptions): Promise<void>;
33
50
  declare function getAppMeta(): {
@@ -58,6 +75,11 @@ type GenerateSsrConfigSetOptions = {
58
75
  declare function generateSsrConfigSet(options?: GenerateSsrConfigSetOptions): Record<string, ConfigState>;
59
76
  //#endregion
60
77
  //#region ../js-client-core/src/types.d.ts
78
+ /**
79
+ * The values an offline client serves, keyed by config key. See {@link OfflineValue} for how each
80
+ * value's config type is decided. Every context receives the same value.
81
+ */
82
+ type OfflineValues$1 = NativeValues;
61
83
  type ClientHooks = {
62
84
  clientReady?: HookHandler<"clientReady"> | HookHandler<"clientReady">[];
63
85
  configsUpdated?: HookHandler<"configsUpdated"> | HookHandler<"configsUpdated">[];
@@ -102,9 +124,10 @@ declare class DefaultConsoleLogger implements ConfigDirectorLogger {
102
124
  //#region src/client/types.d.ts
103
125
  type ConfigDirectorProviderOptions = {
104
126
  /**
105
- * Your ConfigDirector Client SDK key. This is a public value safe for the browser.
127
+ * Your ConfigDirector Client SDK key. This is a public value safe for the browser. Required
128
+ * unless `mode` is `offline`.
106
129
  */
107
- sdkKey: string;
130
+ sdkKey?: string;
108
131
  appName?: string;
109
132
  appVersion?: string;
110
133
  /**
@@ -116,11 +139,23 @@ type ConfigDirectorProviderOptions = {
116
139
  */
117
140
  timeout?: number;
118
141
  /**
119
- * The connection mode, one of `streaming` or `polling`. In `streaming` mode the connection stays
120
- * open and receives config updates as they happen. In `polling` mode configs are fetched once during
121
- * initialization and then again on every `pollingInterval`. Defaults to `streaming`.
142
+ * The connection mode, one of `streaming`, `polling` or `offline`. In `streaming` mode the connection
143
+ * stays open and receives config updates as they happen. In `polling` mode configs are fetched once
144
+ * during initialization and then again on every `pollingInterval`. In `offline` mode the browser
145
+ * client never connects to ConfigDirector and sends nothing: it serves `values` to every context,
146
+ * or the in-code default values when none are given, and needs no `sdkKey`. Defaults to `streaming`.
147
+ *
148
+ * The server `ConfigDirectorProvider` sets `offline` and `values` for you when `register()` ran in
149
+ * `offline` mode and you give neither prop.
122
150
  */
123
151
  mode?: ConnectionMode;
152
+ /**
153
+ * The values to serve in `offline` mode, keyed by config key. The config type of each value follows
154
+ * from the value: a boolean, an integral number (`integer`), any other number (`float`), a string, or
155
+ * a plain object or array (`json`). Can be given only in `offline` mode; otherwise the client fails
156
+ * to initialize.
157
+ */
158
+ values?: OfflineValues$1;
124
159
  /**
125
160
  * The polling interval in seconds when `mode` is `polling`. Has no effect in `streaming` mode.
126
161
  * Defaults to 60 seconds. A value below the minimum of 30 seconds is raised to 30 seconds and a
@@ -228,5 +263,5 @@ declare function ConfigDirectorProvider({
228
263
  //#region src/server/logger.d.ts
229
264
  declare const createConsoleLogger: (level: ConfigDirectorLoggingLevel, messageDecorator?: ConfigDirectorLogMessageDecorator) => DefaultConsoleLogger;
230
265
  //#endregion
231
- export { type ConfigDirectorClient, type ConfigDirectorClientOptions, type ConfigDirectorContext, type ConfigDirectorLogger, type ConfigDirectorMetaContext, ConfigDirectorProvider, type ConfigDirectorProviderProps, type ConfigValueType, type ConnectionMode, type GenerateSsrConfigSetOptions, type RegisterOptions, createConsoleLogger, generateSsrConfigSet, getAppMeta, getConfigClient, register };
266
+ export { type ConfigDirectorClient, type ConfigDirectorClientOptions, type ConfigDirectorContext, ConfigDirectorInitializationError, type ConfigDirectorLogger, type ConfigDirectorMetaContext, ConfigDirectorProvider, type ConfigDirectorProviderProps, type ConfigValueType, type ConnectionMode, type GenerateSsrConfigSetOptions, type OfflineClientOptions, type OfflineValue, type OfflineValues, type RegisterOptions, createConsoleLogger, generateSsrConfigSet, getAppMeta, getConfigClient, register };
232
267
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/server/singleton.ts","../../src/server/ssr.ts","../../../js-client-core/src/types.ts","../../../shared/src/logger.ts","../../src/client/types.ts","../../src/server/ConfigDirectorProvider.tsx","../../src/server/logger.ts"],"mappings":";;;;;QAIQ,MAAA;EAAA,IACF,4BAAA,EAA8B,oBAAA;EAAA,IAC9B,uBAAA;IAA2B,OAAA;IAAkB,UAAA;EAAA;AAAA;AAAA,KAGvC,eAAA;EALJ;;;;EAUN,YAAA;AAAA,IACE,2BAAA;;;;AANJ;;;;;AAoBA;;;;iBAAsB,QAAA,CAAS,OAAA,EAAS,eAAA,GAAkB,OAAA;AAAA,iBA6B1C,UAAA,CAAA;EAAgB,OAAA;EAAkB,UAAA;AAAA;AAAA,iBAIlC,eAAA,CAAA,GAAmB,oBAAA;;;KCxDvB,2BAAA;oDAEV,OAAA,GAAU,qBAAA;;ADRkF;;;ECa5F,UAAA;AAAA;;;;;;;;;ADJF;;iBCiBgB,oBAAA,CAAqB,OAAA,GAAU,2BAAA,GAA8B,MAAA,SAAe,WAAA;;;KCqGhF,WAAA;EACV,WAAA,GAAc,WAAA,kBAA6B,WAAA;EAC3C,cAAA,GAAiB,WAAA,qBAAgC,WAAA;EACjD,cAAA,GAAiB,WAAA,qBAAgC,WAAA;EACjD,eAAA,GAAkB,WAAA,sBAAiC,WAAA;EACnD,eAAA,GAAkB,WAAA,sBAAiC,WAAA;AAAA;AAAA,KAGzC,mBAAA;AAAA,KAEA,WAAA,sBAAiC,YAAA,KAAiB,OAAA,EAAS,YAAA,CAAa,MAAA;AAAA,KAExE,YAAA;EACV,cAAA;IAAkB,IAAA;IAAgB,WAAA;EAAA;EAClC,WAAA;IAAe,MAAA,EAAQ,mBAAA;EAAA;EACvB,cAAA;IAAkB,OAAA,EAAS,qBAAA;EAAA;EAC3B,eAAA;IAAmB,UAAA,EAAY,gBAAA;EAAA;EAC/B,eAAA;IAAmB,KAAA,EAAO,KAAA;EAAA;AAAA;;;cCjHf,oBAAA,YAAgC,oBAAA;EAAA,iBAGd,KAAA;EAAA,iBAAoD,SAAA;EAAA,iBAFhE,aAAA;cAEY,KAAA,EAAO,0BAAA,EAA6C,SAAA,EAAW,iCAAA;EAM5F,KAAA,CAAM,OAAA,aAAoB,IAAA;EAI1B,IAAA,CAAK,OAAA,aAAoB,IAAA;EAIzB,IAAA,CAAK,OAAA,aAAoB,IAAA;EAIzB,KAAA,CAAM,OAAA,aAAoB,IAAA;EAAA,UAIhB,GAAA,CAAI,cAAA,MAAoB,IAAA,gBAAoB,KAAA,EAAO,0BAAA,EAA4B,OAAA,aAAoB,IAAA;AAAA;;;KClCnG,6BAAA;EJhBqB;;;EIoB/B,MAAA;EACA,OAAA;EACA,UAAA;EJnBU;;;EIuBV,GAAA;EJjB6B;AAc/B;;EIOE,OAAA;EJP+D;;;;;EIa/D,IAAA,GAAO,cAAA;EJgBO;;;;;EIVd,eAAA;EJc6B;;;EIV7B,OAAA,GAAU,qBAAA;;;;EAIV,QAAA,GAAW,0BAAA;EAEX,KAAA,GAAQ,WAAA;;;;;;;;AHhCV;;;EG2CE,cAAA,GAAiB,MAAA,SAAe,WAAA;AAAA;;;;;;AJrE4D;KKUlF,2BAAA,GAA8B,IAAA,CAAK,6BAAA;;;;;;EAM7C,UAAA;AAAA;;;;;ALPF;;;;;AAoBA;;;;;;;;;AA6BA;;;;;AAIA;;;;;;;;ACxDA;;;;;;;;;AAoBA;;;;;;;;;;;;;;;;;iBIkDsB,sBAAA,CAAA;EACpB,QAAA;EACA,UAAA;EAAA,GACG;AAAA,GACF,iBAAA,CAAkB,2BAAA,IAA4B,OAAA,CAAA,oBAAA,CAAA,GAAA,CAAA,OAAA;;;cChEpC,mBAAA,GACX,KAAA,EAAO,0BAAA,EACP,gBAAA,GAAmB,iCAAA,KAAiC,oBAAA"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/server/singleton.ts","../../src/server/ssr.ts","../../../js-client-core/src/types.ts","../../../shared/src/logger.ts","../../src/client/types.ts","../../src/server/ConfigDirectorProvider.tsx","../../src/server/logger.ts"],"mappings":"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"}
@@ -1,22 +1,30 @@
1
- import { a as ConfigDirectorLogger, c as ConfigEvaluation, d as ConnectionMode, i as ConfigDirectorLogMessageDecorator, l as ConfigState, n as ConfigDirectorClientOptions, o as ConfigDirectorLoggingLevel, r as ConfigDirectorContext, s as ConfigDirectorMetaContext, t as ConfigDirectorClient, u as ConfigValueType } from "./types-B_mGbQaa.mjs";
1
+ import { _ as ConfigEvaluation, a as ConfigDirectorClientOptions, b as ConnectionMode, c as OfflineValues, d as NativeValues, f as ConfigDirectorContext, g as ConfigDirectorMetaContext, h as ConfigDirectorLoggingLevel, i as ConfigDirectorClient, m as ConfigDirectorLogger, n as ConfigDirectorInitializationError, o as OfflineClientOptions, p as ConfigDirectorLogMessageDecorator, s as OfflineValue, v as ConfigState, y as ConfigValueType } from "./errors-r1MHQ8L5.mjs";
2
2
  import * as _$react_jsx_runtime0 from "react/jsx-runtime";
3
3
  import { PropsWithChildren } from "react";
4
4
 
5
5
  //#region src/server/singleton.d.ts
6
6
  declare global {
7
7
  var __configDirectorServerClient: ConfigDirectorClient | undefined;
8
+ var __configDirectorServerConnectionMode: ConnectionMode | undefined;
8
9
  var __configDirectorAppMeta: {
9
10
  appName?: string;
10
11
  appVersion?: string;
11
12
  } | undefined;
12
13
  }
13
- type RegisterOptions = {
14
+ /**
15
+ * Options of {@link register}. A server SDK key is required unless `connection.mode` is `offline`,
16
+ * in which case the server singleton never connects and serves `connection.file` or
17
+ * `connection.values` instead.
18
+ */
19
+ type RegisterOptions = ({
14
20
  /**
15
21
  * Your ConfigDirector Server SDK key. This is a secret value — do not commit it to source
16
22
  * control. Provide it via an environment variable (e.g. process.env.CONFIGDIRECTOR_SERVER_KEY).
17
23
  */
18
24
  serverSdkKey: string;
19
- } & ConfigDirectorClientOptions;
25
+ } & ConfigDirectorClientOptions) | (OfflineClientOptions & {
26
+ serverSdkKey?: undefined;
27
+ });
20
28
  /**
21
29
  * Initializes the ConfigDirector server SDK singleton. Call this from your Next.js
22
30
  * `instrumentation.ts` file so it runs once when the server starts:
@@ -28,6 +36,15 @@ type RegisterOptions = {
28
36
  * await register({ serverSdkKey: process.env.CONFIGDIRECTOR_SERVER_KEY! });
29
37
  * }
30
38
  * ```
39
+ *
40
+ * In `offline` mode no key is needed, and the server never connects:
41
+ *
42
+ * ```ts
43
+ * await register({ connection: { mode: "offline", file: "./flags/new-checkout-on.json" } });
44
+ * ```
45
+ *
46
+ * Rejects with a `ConfigDirectorInitializationError` when the key is missing outside `offline`
47
+ * mode, or when the offline file or values cannot be loaded.
31
48
  */
32
49
  declare function register(options: RegisterOptions): Promise<void>;
33
50
  declare function getAppMeta(): {
@@ -58,6 +75,11 @@ type GenerateSsrConfigSetOptions = {
58
75
  declare function generateSsrConfigSet(options?: GenerateSsrConfigSetOptions): Record<string, ConfigState>;
59
76
  //#endregion
60
77
  //#region ../js-client-core/src/types.d.ts
78
+ /**
79
+ * The values an offline client serves, keyed by config key. See {@link OfflineValue} for how each
80
+ * value's config type is decided. Every context receives the same value.
81
+ */
82
+ type OfflineValues$1 = NativeValues;
61
83
  type ClientHooks = {
62
84
  clientReady?: HookHandler<"clientReady"> | HookHandler<"clientReady">[];
63
85
  configsUpdated?: HookHandler<"configsUpdated"> | HookHandler<"configsUpdated">[];
@@ -102,9 +124,10 @@ declare class DefaultConsoleLogger implements ConfigDirectorLogger {
102
124
  //#region src/client/types.d.ts
103
125
  type ConfigDirectorProviderOptions = {
104
126
  /**
105
- * Your ConfigDirector Client SDK key. This is a public value safe for the browser.
127
+ * Your ConfigDirector Client SDK key. This is a public value safe for the browser. Required
128
+ * unless `mode` is `offline`.
106
129
  */
107
- sdkKey: string;
130
+ sdkKey?: string;
108
131
  appName?: string;
109
132
  appVersion?: string;
110
133
  /**
@@ -116,11 +139,23 @@ type ConfigDirectorProviderOptions = {
116
139
  */
117
140
  timeout?: number;
118
141
  /**
119
- * The connection mode, one of `streaming` or `polling`. In `streaming` mode the connection stays
120
- * open and receives config updates as they happen. In `polling` mode configs are fetched once during
121
- * initialization and then again on every `pollingInterval`. Defaults to `streaming`.
142
+ * The connection mode, one of `streaming`, `polling` or `offline`. In `streaming` mode the connection
143
+ * stays open and receives config updates as they happen. In `polling` mode configs are fetched once
144
+ * during initialization and then again on every `pollingInterval`. In `offline` mode the browser
145
+ * client never connects to ConfigDirector and sends nothing: it serves `values` to every context,
146
+ * or the in-code default values when none are given, and needs no `sdkKey`. Defaults to `streaming`.
147
+ *
148
+ * The server `ConfigDirectorProvider` sets `offline` and `values` for you when `register()` ran in
149
+ * `offline` mode and you give neither prop.
122
150
  */
123
151
  mode?: ConnectionMode;
152
+ /**
153
+ * The values to serve in `offline` mode, keyed by config key. The config type of each value follows
154
+ * from the value: a boolean, an integral number (`integer`), any other number (`float`), a string, or
155
+ * a plain object or array (`json`). Can be given only in `offline` mode; otherwise the client fails
156
+ * to initialize.
157
+ */
158
+ values?: OfflineValues$1;
124
159
  /**
125
160
  * The polling interval in seconds when `mode` is `polling`. Has no effect in `streaming` mode.
126
161
  * Defaults to 60 seconds. A value below the minimum of 30 seconds is raised to 30 seconds and a
@@ -228,5 +263,5 @@ declare function ConfigDirectorProvider({
228
263
  //#region src/server/logger.d.ts
229
264
  declare const createConsoleLogger: (level: ConfigDirectorLoggingLevel, messageDecorator?: ConfigDirectorLogMessageDecorator) => DefaultConsoleLogger;
230
265
  //#endregion
231
- export { type ConfigDirectorClient, type ConfigDirectorClientOptions, type ConfigDirectorContext, type ConfigDirectorLogger, type ConfigDirectorMetaContext, ConfigDirectorProvider, type ConfigDirectorProviderProps, type ConfigValueType, type ConnectionMode, type GenerateSsrConfigSetOptions, type RegisterOptions, createConsoleLogger, generateSsrConfigSet, getAppMeta, getConfigClient, register };
266
+ export { type ConfigDirectorClient, type ConfigDirectorClientOptions, type ConfigDirectorContext, ConfigDirectorInitializationError, type ConfigDirectorLogger, type ConfigDirectorMetaContext, ConfigDirectorProvider, type ConfigDirectorProviderProps, type ConfigValueType, type ConnectionMode, type GenerateSsrConfigSetOptions, type OfflineClientOptions, type OfflineValue, type OfflineValues, type RegisterOptions, createConsoleLogger, generateSsrConfigSet, getAppMeta, getConfigClient, register };
232
267
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/server/singleton.ts","../../src/server/ssr.ts","../../../js-client-core/src/types.ts","../../../shared/src/logger.ts","../../src/client/types.ts","../../src/server/ConfigDirectorProvider.tsx","../../src/server/logger.ts"],"mappings":";;;;;QAIQ,MAAA;EAAA,IACF,4BAAA,EAA8B,oBAAA;EAAA,IAC9B,uBAAA;IAA2B,OAAA;IAAkB,UAAA;EAAA;AAAA;AAAA,KAGvC,eAAA;EALJ;;;;EAUN,YAAA;AAAA,IACE,2BAAA;;;;AANJ;;;;;AAoBA;;;;iBAAsB,QAAA,CAAS,OAAA,EAAS,eAAA,GAAkB,OAAA;AAAA,iBA6B1C,UAAA,CAAA;EAAgB,OAAA;EAAkB,UAAA;AAAA;AAAA,iBAIlC,eAAA,CAAA,GAAmB,oBAAA;;;KCxDvB,2BAAA;oDAEV,OAAA,GAAU,qBAAA;;ADRkF;;;ECa5F,UAAA;AAAA;;;;;;;;;ADJF;;iBCiBgB,oBAAA,CAAqB,OAAA,GAAU,2BAAA,GAA8B,MAAA,SAAe,WAAA;;;KCqGhF,WAAA;EACV,WAAA,GAAc,WAAA,kBAA6B,WAAA;EAC3C,cAAA,GAAiB,WAAA,qBAAgC,WAAA;EACjD,cAAA,GAAiB,WAAA,qBAAgC,WAAA;EACjD,eAAA,GAAkB,WAAA,sBAAiC,WAAA;EACnD,eAAA,GAAkB,WAAA,sBAAiC,WAAA;AAAA;AAAA,KAGzC,mBAAA;AAAA,KAEA,WAAA,sBAAiC,YAAA,KAAiB,OAAA,EAAS,YAAA,CAAa,MAAA;AAAA,KAExE,YAAA;EACV,cAAA;IAAkB,IAAA;IAAgB,WAAA;EAAA;EAClC,WAAA;IAAe,MAAA,EAAQ,mBAAA;EAAA;EACvB,cAAA;IAAkB,OAAA,EAAS,qBAAA;EAAA;EAC3B,eAAA;IAAmB,UAAA,EAAY,gBAAA;EAAA;EAC/B,eAAA;IAAmB,KAAA,EAAO,KAAA;EAAA;AAAA;;;cCjHf,oBAAA,YAAgC,oBAAA;EAAA,iBAGd,KAAA;EAAA,iBAAoD,SAAA;EAAA,iBAFhE,aAAA;cAEY,KAAA,EAAO,0BAAA,EAA6C,SAAA,EAAW,iCAAA;EAM5F,KAAA,CAAM,OAAA,aAAoB,IAAA;EAI1B,IAAA,CAAK,OAAA,aAAoB,IAAA;EAIzB,IAAA,CAAK,OAAA,aAAoB,IAAA;EAIzB,KAAA,CAAM,OAAA,aAAoB,IAAA;EAAA,UAIhB,GAAA,CAAI,cAAA,MAAoB,IAAA,gBAAoB,KAAA,EAAO,0BAAA,EAA4B,OAAA,aAAoB,IAAA;AAAA;;;KClCnG,6BAAA;EJhBqB;;;EIoB/B,MAAA;EACA,OAAA;EACA,UAAA;EJnBU;;;EIuBV,GAAA;EJjB6B;AAc/B;;EIOE,OAAA;EJP+D;;;;;EIa/D,IAAA,GAAO,cAAA;EJgBO;;;;;EIVd,eAAA;EJc6B;;;EIV7B,OAAA,GAAU,qBAAA;;;;EAIV,QAAA,GAAW,0BAAA;EAEX,KAAA,GAAQ,WAAA;;;;;;;;AHhCV;;;EG2CE,cAAA,GAAiB,MAAA,SAAe,WAAA;AAAA;;;;;;AJrE4D;KKUlF,2BAAA,GAA8B,IAAA,CAAK,6BAAA;;;;;;EAM7C,UAAA;AAAA;;;;;ALPF;;;;;AAoBA;;;;;;;;;AA6BA;;;;;AAIA;;;;;;;;ACxDA;;;;;;;;;AAoBA;;;;;;;;;;;;;;;;;iBIkDsB,sBAAA,CAAA;EACpB,QAAA;EACA,UAAA;EAAA,GACG;AAAA,GACF,iBAAA,CAAkB,2BAAA,IAA4B,OAAA,CAAA,oBAAA,CAAA,GAAA,CAAA,OAAA;;;cChEpC,mBAAA,GACX,KAAA,EAAO,0BAAA,EACP,gBAAA,GAAmB,iCAAA,KAAiC,oBAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/server/singleton.ts","../../src/server/ssr.ts","../../../js-client-core/src/types.ts","../../../shared/src/logger.ts","../../src/client/types.ts","../../src/server/ConfigDirectorProvider.tsx","../../src/server/logger.ts"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{i as e,n as t}from"./errors-BGpFuqOO.mjs";import{ConfigDirectorProvider as n}from"@configdirector/nextjs-sdk/client";import{jsx as r}from"react/jsx-runtime";var i=class{decorateMessage(e){return`[ConfigDirector:nextjs-sdk] ${e}`}};const a=(t,n)=>new e(t??`warn`,n??new i),o=(t,n)=>new e(t,n??new i);async function s(e){if(process.env.NEXT_RUNTIME===`nodejs`){if(!e.serverSdkKey){let e=`The ConfigDirector serverSdkKey must be provided to register(). You can pass it via process.env.CONFIGDIRECTOR_SERVER_KEY.`;throw a().error(e),new t(e)}if(!globalThis.__configDirectorServerClient){let{DefaultConfigDirectorClient:t}=await import(`./DefaultConfigDirectorClient-BTTja_j3.mjs`).then(e=>e.n),{serverSdkKey:n,...r}=e;globalThis.__configDirectorAppMeta={appName:e.metadata?.appName,appVersion:e.metadata?.appVersion};let i=new t(n,{sdkName:`nextjs-sdk`,sdkVersion:`1.10.0`},r);globalThis.__configDirectorServerClient=i,await i.initialize()}}}function c(){return globalThis.__configDirectorAppMeta??{}}function l(){if(!globalThis.__configDirectorServerClient)throw new t(`[ConfigDirector] Server client not initialized. Make sure to call register() in your instrumentation.ts file before using the SDK.`);return globalThis.__configDirectorServerClient}const u=a();function d(e){try{return l().getAllConfigs(e)}catch(e){return u.error(`Error retrieving SSR config set:`,e),{}}}async function f({children:e,configKeys:t,...i}){let a=d({context:i.context,configKeys:t}),o=c();return r(n,{...i,appName:i.appName??o.appName,appVersion:i.appVersion??o.appVersion,initialConfigs:a,children:e})}export{f as ConfigDirectorProvider,o as createConsoleLogger,d as generateSsrConfigSet,c as getAppMeta,l as getConfigClient,s as register};
1
+ import{i as e,o as t,t as n}from"./native-values-CfqV9hAq.mjs";import{ConfigDirectorProvider as r}from"@configdirector/nextjs-sdk/client";import{jsx as i}from"react/jsx-runtime";var a=class{decorateMessage(e){return`[ConfigDirector:nextjs-sdk] ${e}`}};const o=(e,n)=>new t(e??`warn`,n??new a),s=(e,n)=>new t(e,n??new a);async function c(t){if(process.env.NEXT_RUNTIME===`nodejs`){let n=t.connection?.mode??`streaming`;if(n!==`offline`&&!t.serverSdkKey){let t=`The ConfigDirector serverSdkKey must be provided to register(). You can pass it via process.env.CONFIGDIRECTOR_SERVER_KEY.`;throw o().error(t),new e(t)}if(!globalThis.__configDirectorServerClient){let{DefaultConfigDirectorClient:e}=await import(`./DefaultConfigDirectorClient-BplPvnEk.mjs`).then(e=>e.n),{serverSdkKey:r,...i}=t;globalThis.__configDirectorAppMeta={appName:t.metadata?.appName,appVersion:t.metadata?.appVersion},globalThis.__configDirectorServerConnectionMode=n;let a=new e(r,{sdkName:`nextjs-sdk`,sdkVersion:`1.11.0`},i);globalThis.__configDirectorServerClient=a;try{await a.initialize()}catch(e){throw globalThis.__configDirectorServerClient=void 0,globalThis.__configDirectorServerConnectionMode=void 0,globalThis.__configDirectorAppMeta=void 0,a.dispose(),e}}}}function l(){return globalThis.__configDirectorAppMeta??{}}function u(){return globalThis.__configDirectorServerConnectionMode}function d(){if(!globalThis.__configDirectorServerClient)throw new e(`[ConfigDirector] Server client not initialized. Make sure to call register() in your instrumentation.ts file before using the SDK.`);return globalThis.__configDirectorServerClient}const f=o();function p(e){try{return d().getAllConfigs(e)}catch(e){return f.error(`Error retrieving SSR config set:`,e),{}}}const m=(e,t)=>e.mode!==void 0||e.values!==void 0?`as-given`:t===`offline`?`inherit-offline`:`connect`,h=e=>typeof e.value==`string`,g=e=>Object.fromEntries(Object.values(e).filter(h).map(e=>[e.key,n(e.type,e.value)]));async function _({children:e,configKeys:t,...n}){let a=p({context:n.context,configKeys:t}),o=l();return i(r,{...n,...v(a,n),appName:n.appName??o.appName,appVersion:n.appVersion??o.appVersion,initialConfigs:a,children:e})}const v=(e,t)=>{switch(m(t,u())){case`as-given`:return{};case`inherit-offline`:return{mode:`offline`,values:g(e)};case`connect`:return{}}};export{e as ConfigDirectorInitializationError,_ as ConfigDirectorProvider,s as createConsoleLogger,p as generateSsrConfigSet,l as getAppMeta,d as getConfigClient,c as register};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["ClientProvider"],"sources":["../../src/server/logger.ts","../../src/server/singleton.ts","../../src/server/ssr.ts","../../src/server/ConfigDirectorProvider.tsx"],"sourcesContent":["import { DefaultConsoleLogger } from \"@shared/logger\";\nimport type { ConfigDirectorLoggingLevel, ConfigDirectorLogMessageDecorator } from \"@shared/types\";\n\nclass LogMessageDecorator implements ConfigDirectorLogMessageDecorator {\n decorateMessage(message: string): string {\n return `[ConfigDirector:nextjs-sdk] ${message}`;\n }\n}\n\nexport const createDefaultLogger = (\n level?: ConfigDirectorLoggingLevel,\n messageDecorator?: ConfigDirectorLogMessageDecorator,\n) => {\n return new DefaultConsoleLogger(level ?? \"warn\", messageDecorator ?? new LogMessageDecorator());\n};\n\nexport const createConsoleLogger = (\n level: ConfigDirectorLoggingLevel,\n messageDecorator?: ConfigDirectorLogMessageDecorator,\n) => {\n return new DefaultConsoleLogger(level, messageDecorator ?? new LogMessageDecorator());\n};\n","import type { ConfigDirectorClient, ConfigDirectorClientOptions } from \"@js-server-sdk/types\";\nimport { createDefaultLogger } from \"./logger\";\nimport { ConfigDirectorInitializationError } from \"@shared/errors\";\n\ndeclare global {\n var __configDirectorServerClient: ConfigDirectorClient | undefined;\n var __configDirectorAppMeta: { appName?: string; appVersion?: string } | undefined;\n}\n\nexport type RegisterOptions = {\n /**\n * Your ConfigDirector Server SDK key. This is a secret value — do not commit it to source\n * control. Provide it via an environment variable (e.g. process.env.CONFIGDIRECTOR_SERVER_KEY).\n */\n serverSdkKey: string;\n} & ConfigDirectorClientOptions;\n\n/**\n * Initializes the ConfigDirector server SDK singleton. Call this from your Next.js\n * `instrumentation.ts` file so it runs once when the server starts:\n *\n * ```ts\n * // instrumentation.ts\n * export async function register() {\n * const { register } = await import(\"@configdirector/nextjs-sdk/server\");\n * await register({ serverSdkKey: process.env.CONFIGDIRECTOR_SERVER_KEY! });\n * }\n * ```\n */\nexport async function register(options: RegisterOptions): Promise<void> {\n if (process.env[\"NEXT_RUNTIME\"] !== \"nodejs\") {\n return;\n }\n\n if (!options.serverSdkKey) {\n const message =\n \"The ConfigDirector serverSdkKey must be provided to register(). You can pass it via process.env.CONFIGDIRECTOR_SERVER_KEY.\";\n createDefaultLogger().error(message);\n throw new ConfigDirectorInitializationError(message);\n }\n\n if (!globalThis.__configDirectorServerClient) {\n const { DefaultConfigDirectorClient } = await import(\"@js-server-sdk/DefaultConfigDirectorClient\");\n const { serverSdkKey, ...clientOptions } = options;\n globalThis.__configDirectorAppMeta = {\n appName: options.metadata?.appName,\n appVersion: options.metadata?.appVersion,\n };\n const client = new DefaultConfigDirectorClient(\n serverSdkKey,\n { sdkName: \"nextjs-sdk\", sdkVersion: \"__VERSION__\" },\n clientOptions,\n );\n globalThis.__configDirectorServerClient = client;\n await client.initialize();\n }\n}\n\nexport function getAppMeta(): { appName?: string; appVersion?: string } {\n return globalThis.__configDirectorAppMeta ?? {};\n}\n\nexport function getConfigClient(): ConfigDirectorClient {\n if (!globalThis.__configDirectorServerClient) {\n throw new ConfigDirectorInitializationError(\n \"[ConfigDirector] Server client not initialized. Make sure to call register() in your instrumentation.ts file before using the SDK.\",\n );\n }\n return globalThis.__configDirectorServerClient;\n}\n","import type { ConfigDirectorContext, ConfigState } from \"@js-server-sdk/types\";\nimport { getConfigClient } from \"./singleton\";\nimport { createDefaultLogger } from \"./logger\";\n\nconst logger = createDefaultLogger();\n\nexport type GenerateSsrConfigSetOptions = {\n /** User context for targeting rule evaluation. */\n context?: ConfigDirectorContext;\n /**\n * Restrict the returned config set to these keys. When omitted, all known configs are\n * returned. Useful when you want to pre-evaluate only a specific subset of flags.\n */\n configKeys?: string[];\n};\n\n/**\n * Evaluates configs server-side and returns a map of {@link ConfigState} objects keyed by\n * config key, suitable for passing as `initialConfigs` to `ConfigDirectorProvider`.\n *\n * Returns an empty object when the server SDK isn't initialized yet (e.g. during\n * `next build` static analysis without a live connection).\n *\n * In most cases you don't need this directly — use the `ConfigDirectorProvider` exported\n * from `@configdirector/nextjs-sdk/server`, which calls this automatically.\n */\nexport function generateSsrConfigSet(options?: GenerateSsrConfigSetOptions): Record<string, ConfigState> {\n try {\n return getConfigClient().getAllConfigs(options);\n } catch (error) {\n logger.error(\"Error retrieving SSR config set:\", error);\n return {};\n }\n}\n","import type { PropsWithChildren } from \"react\";\nimport { ConfigDirectorProvider as ClientProvider } from \"@configdirector/nextjs-sdk/client\";\nimport type { ConfigDirectorProviderOptions } from \"../client/types\";\nimport { generateSsrConfigSet } from \"./ssr\";\nimport { getAppMeta } from \"./singleton\";\n\n/**\n * Props for {@link ConfigDirectorProvider}. Identical to the client provider options\n * except `initialConfigs` is omitted — SSR-evaluated values are injected automatically.\n */\nexport type ConfigDirectorProviderProps = Omit<ConfigDirectorProviderOptions, \"initialConfigs\"> & {\n /**\n * Restrict SSR pre-evaluation to these config keys. When omitted, all known configs are\n * pre-evaluated. Useful when you have a large config set and only need a subset hydrated\n * on this layout.\n */\n configKeys?: string[];\n};\n\n/**\n * React Server Component wrapper around the ConfigDirector client provider.\n *\n * Place this in your root layout. It pre-evaluates all configs on the server using the\n * provided context and passes them to the client provider, preventing any flash of wrong\n * content on hydration.\n *\n * Requires Next.js 13+ (App Router) and React 18+.\n *\n * Read `sdkKey` from a plain environment variable (e.g. `CONFIGDIRECTOR_CLIENT_KEY`), NOT one\n * prefixed with `NEXT_PUBLIC_` — even here, inside a Server Component. Next.js substitutes\n * `NEXT_PUBLIC_*` references with a literal string at compile time wherever they appear in\n * code it bundles, with no exemption for Server Components; that permanently freezes the\n * value into the build artifact the moment you reference it here, regardless of the two\n * deployment strategies below. A plain variable, by contrast, is read live from `process.env`\n * — its resolved value (not the variable lookup itself) is what gets passed as a prop to the\n * client provider below, which is how it safely reaches the browser without ever being baked\n * into the bundle as source.\n *\n * **Deploying one build artifact to multiple environments (e.g. one Docker image promoted\n * from staging to prod):** a plain variable is only read fresh per request if this component's\n * render actually re-runs on each request — otherwise Next.js still statically prerenders the\n * route once at build time and caches the output to a static HTML file, silently freezing\n * whichever value was set at build time. Make sure your root layout either reads a per-request\n * API like `cookies()` (as below, which forces dynamic rendering as a side effect) or adds\n * `export const dynamic = \"force-dynamic\";` if it doesn't otherwise need one. The trade-off is\n * that the route loses static generation/ISR caching, since it now renders on every request.\n *\n * **Building a separate artifact per environment:** if you'd rather keep static generation\n * (and are fine building once per environment, e.g. as a distinct step per env in CI), no\n * layout changes are needed — a plain environment variable set at build time is read once and\n * baked into the static output for that build, same as `NEXT_PUBLIC_` would be, just without\n * also exposing it to arbitrary client-side code that isn't a descendant of this provider.\n *\n * @example\n * ```tsx\n * // app/layout.tsx\n * import { ConfigDirectorProvider } from \"@configdirector/nextjs-sdk/server\";\n * import { cookies } from \"next/headers\";\n *\n * export default async function RootLayout({ children }) {\n * const userId = (await cookies()).get(\"userId\")?.value;\n * return (\n * <html>\n * <body>\n * <ConfigDirectorProvider\n * sdkKey={process.env.CONFIGDIRECTOR_CLIENT_KEY!}\n * context={{ userId }}\n * >\n * {children}\n * </ConfigDirectorProvider>\n * </body>\n * </html>\n * );\n * }\n * ```\n */\nexport async function ConfigDirectorProvider({\n children,\n configKeys,\n ...props\n}: PropsWithChildren<ConfigDirectorProviderProps>) {\n const initialConfigs = generateSsrConfigSet({ context: props.context, configKeys });\n const appMeta = getAppMeta();\n return (\n <ClientProvider\n {...props}\n appName={props.appName ?? appMeta.appName}\n appVersion={props.appVersion ?? appMeta.appVersion}\n initialConfigs={initialConfigs}>\n {children}\n </ClientProvider>\n );\n}\n"],"mappings":"oKAGA,IAAM,EAAN,KAAuE,CACrE,gBAAgB,EAAyB,CACvC,MAAO,+BAA+B,MAI1C,MAAa,GACX,EACA,IAEO,IAAI,EAAqB,GAAS,OAAQ,GAAoB,IAAI,EAAsB,CAGpF,GACX,EACA,IAEO,IAAI,EAAqB,EAAO,GAAoB,IAAI,EAAsB,CCSvF,eAAsB,EAAS,EAAyC,CAClE,WAAQ,IAAI,eAAoB,SAIpC,IAAI,CAAC,EAAQ,aAAc,CACzB,IAAM,EACJ,6HAEF,MADA,GAAqB,CAAC,MAAM,EAAQ,CAC9B,IAAI,EAAkC,EAAQ,CAGtD,GAAI,CAAC,WAAW,6BAA8B,CAC5C,GAAM,CAAE,+BAAgC,MAAM,OAAO,8CAAA,KAAA,GAAA,EAAA,EAAA,CAC/C,CAAE,eAAc,GAAG,GAAkB,EAC3C,WAAW,wBAA0B,CACnC,QAAS,EAAQ,UAAU,QAC3B,WAAY,EAAQ,UAAU,WAC/B,CACD,IAAM,EAAS,IAAI,EACjB,EACA,CAAE,QAAS,aAAc,WAAY,SAAe,CACpD,EACD,CACD,WAAW,6BAA+B,EAC1C,MAAM,EAAO,YAAY,GAI7B,SAAgB,GAAwD,CACtE,OAAO,WAAW,yBAA2B,EAAE,CAGjD,SAAgB,GAAwC,CACtD,GAAI,CAAC,WAAW,6BACd,MAAM,IAAI,EACR,qIACD,CAEH,OAAO,WAAW,6BChEpB,MAAM,EAAS,GAAqB,CAsBpC,SAAgB,EAAqB,EAAoE,CACvG,GAAI,CACF,OAAO,GAAiB,CAAC,cAAc,EAAQ,OACxC,EAAO,CAEd,OADA,EAAO,MAAM,mCAAoC,EAAM,CAChD,EAAE,EC6Cb,eAAsB,EAAuB,CAC3C,WACA,aACA,GAAG,GAC8C,CACjD,IAAM,EAAiB,EAAqB,CAAE,QAAS,EAAM,QAAS,aAAY,CAAC,CAC7E,EAAU,GAAY,CAC5B,OACE,EAACA,EAAD,CACE,GAAI,EACJ,QAAS,EAAM,SAAW,EAAQ,QAClC,WAAY,EAAM,YAAc,EAAQ,WACxB,iBACf,WACc,CAAA"}
1
+ {"version":3,"file":"index.mjs","names":["ClientProvider"],"sources":["../../src/server/logger.ts","../../src/server/singleton.ts","../../src/server/ssr.ts","../../../shared/src/browser-half.ts","../../src/server/ConfigDirectorProvider.tsx"],"sourcesContent":["import { DefaultConsoleLogger } from \"@shared/logger\";\nimport type { ConfigDirectorLoggingLevel, ConfigDirectorLogMessageDecorator } from \"@shared/types\";\n\nclass LogMessageDecorator implements ConfigDirectorLogMessageDecorator {\n decorateMessage(message: string): string {\n return `[ConfigDirector:nextjs-sdk] ${message}`;\n }\n}\n\nexport const createDefaultLogger = (\n level?: ConfigDirectorLoggingLevel,\n messageDecorator?: ConfigDirectorLogMessageDecorator,\n) => {\n return new DefaultConsoleLogger(level ?? \"warn\", messageDecorator ?? new LogMessageDecorator());\n};\n\nexport const createConsoleLogger = (\n level: ConfigDirectorLoggingLevel,\n messageDecorator?: ConfigDirectorLogMessageDecorator,\n) => {\n return new DefaultConsoleLogger(level, messageDecorator ?? new LogMessageDecorator());\n};\n","import type {\n ConfigDirectorClient,\n ConfigDirectorClientOptions,\n ConnectionMode,\n OfflineClientOptions,\n} from \"@js-server-sdk/types\";\nimport { createDefaultLogger } from \"./logger\";\nimport { ConfigDirectorInitializationError } from \"@shared/errors\";\n\ndeclare global {\n var __configDirectorServerClient: ConfigDirectorClient | undefined;\n var __configDirectorServerConnectionMode: ConnectionMode | undefined;\n var __configDirectorAppMeta: { appName?: string; appVersion?: string } | undefined;\n}\n\n/**\n * Options of {@link register}. A server SDK key is required unless `connection.mode` is `offline`,\n * in which case the server singleton never connects and serves `connection.file` or\n * `connection.values` instead.\n */\nexport type RegisterOptions =\n | ({\n /**\n * Your ConfigDirector Server SDK key. This is a secret value — do not commit it to source\n * control. Provide it via an environment variable (e.g. process.env.CONFIGDIRECTOR_SERVER_KEY).\n */\n serverSdkKey: string;\n } & ConfigDirectorClientOptions)\n | (OfflineClientOptions & { serverSdkKey?: undefined });\n\n/**\n * Initializes the ConfigDirector server SDK singleton. Call this from your Next.js\n * `instrumentation.ts` file so it runs once when the server starts:\n *\n * ```ts\n * // instrumentation.ts\n * export async function register() {\n * const { register } = await import(\"@configdirector/nextjs-sdk/server\");\n * await register({ serverSdkKey: process.env.CONFIGDIRECTOR_SERVER_KEY! });\n * }\n * ```\n *\n * In `offline` mode no key is needed, and the server never connects:\n *\n * ```ts\n * await register({ connection: { mode: \"offline\", file: \"./flags/new-checkout-on.json\" } });\n * ```\n *\n * Rejects with a `ConfigDirectorInitializationError` when the key is missing outside `offline`\n * mode, or when the offline file or values cannot be loaded.\n */\nexport async function register(options: RegisterOptions): Promise<void> {\n // Next.js also compiles instrumentation.ts for the edge runtime, with NEXT_RUNTIME replaced by \"edge\".\n // Keep all of the work inside this branch, not after an early return, so webpack drops it from that\n // compile: the server client it imports needs Node-only modules such as node:crypto.\n if (process.env[\"NEXT_RUNTIME\"] === \"nodejs\") {\n const connectionMode = options.connection?.mode ?? \"streaming\";\n if (connectionMode !== \"offline\" && !options.serverSdkKey) {\n const message =\n \"The ConfigDirector serverSdkKey must be provided to register(). You can pass it via process.env.CONFIGDIRECTOR_SERVER_KEY.\";\n createDefaultLogger().error(message);\n throw new ConfigDirectorInitializationError(message);\n }\n\n if (!globalThis.__configDirectorServerClient) {\n const { DefaultConfigDirectorClient } = await import(\"@js-server-sdk/DefaultConfigDirectorClient\");\n const { serverSdkKey, ...clientOptions } = options;\n globalThis.__configDirectorAppMeta = {\n appName: options.metadata?.appName,\n appVersion: options.metadata?.appVersion,\n };\n globalThis.__configDirectorServerConnectionMode = connectionMode;\n const client = new DefaultConfigDirectorClient(\n serverSdkKey,\n { sdkName: \"nextjs-sdk\", sdkVersion: \"__VERSION__\" },\n clientOptions,\n );\n globalThis.__configDirectorServerClient = client;\n try {\n await client.initialize();\n } catch (error) {\n globalThis.__configDirectorServerClient = undefined;\n globalThis.__configDirectorServerConnectionMode = undefined;\n globalThis.__configDirectorAppMeta = undefined;\n client.dispose();\n throw error;\n }\n }\n }\n}\n\nexport function getAppMeta(): { appName?: string; appVersion?: string } {\n return globalThis.__configDirectorAppMeta ?? {};\n}\n\nexport function getServerConnectionMode(): ConnectionMode | undefined {\n return globalThis.__configDirectorServerConnectionMode;\n}\n\nexport function getConfigClient(): ConfigDirectorClient {\n if (!globalThis.__configDirectorServerClient) {\n throw new ConfigDirectorInitializationError(\n \"[ConfigDirector] Server client not initialized. Make sure to call register() in your instrumentation.ts file before using the SDK.\",\n );\n }\n return globalThis.__configDirectorServerClient;\n}\n","import type { ConfigDirectorContext, ConfigState } from \"@js-server-sdk/types\";\nimport { getConfigClient } from \"./singleton\";\nimport { createDefaultLogger } from \"./logger\";\n\nconst logger = createDefaultLogger();\n\nexport type GenerateSsrConfigSetOptions = {\n /** User context for targeting rule evaluation. */\n context?: ConfigDirectorContext;\n /**\n * Restrict the returned config set to these keys. When omitted, all known configs are\n * returned. Useful when you want to pre-evaluate only a specific subset of flags.\n */\n configKeys?: string[];\n};\n\n/**\n * Evaluates configs server-side and returns a map of {@link ConfigState} objects keyed by\n * config key, suitable for passing as `initialConfigs` to `ConfigDirectorProvider`.\n *\n * Returns an empty object when the server SDK isn't initialized yet (e.g. during\n * `next build` static analysis without a live connection).\n *\n * In most cases you don't need this directly — use the `ConfigDirectorProvider` exported\n * from `@configdirector/nextjs-sdk/server`, which calls this automatically.\n */\nexport function generateSsrConfigSet(options?: GenerateSsrConfigSetOptions): Record<string, ConfigState> {\n try {\n return getConfigClient().getAllConfigs(options);\n } catch (error) {\n logger.error(\"Error retrieving SSR config set:\", error);\n return {};\n }\n}\n","import type { ConfigState, ConnectionMode } from \"./types\";\nimport { decodeNativeValue, type NativeValues } from \"./native-values\";\n\ntype BrowserHalfSource = \"as-given\" | \"inherit-offline\" | \"connect\";\n\nexport const decideBrowserHalfSource = (\n browserHalf: { mode?: ConnectionMode; values?: NativeValues },\n serverConnectionMode: ConnectionMode | undefined,\n): BrowserHalfSource => {\n if (browserHalf.mode !== undefined || browserHalf.values !== undefined) {\n return \"as-given\";\n }\n if (serverConnectionMode === \"offline\") {\n return \"inherit-offline\";\n }\n return \"connect\";\n};\n\nconst holdsAValue = (config: ConfigState): config is ConfigState & { value: string } =>\n typeof config.value === \"string\";\n\nexport const offlineValuesOf = (configs: Record<string, ConfigState>): NativeValues =>\n Object.fromEntries(\n Object.values(configs)\n .filter(holdsAValue)\n .map((config) => [config.key, decodeNativeValue(config.type, config.value)]),\n );\n","import type { PropsWithChildren } from \"react\";\nimport { ConfigDirectorProvider as ClientProvider } from \"@configdirector/nextjs-sdk/client\";\nimport type { ConfigDirectorProviderOptions } from \"../client/types\";\nimport type { ConfigState } from \"@js-server-sdk/types\";\nimport { generateSsrConfigSet } from \"./ssr\";\nimport { getAppMeta, getServerConnectionMode } from \"./singleton\";\nimport { decideBrowserHalfSource, offlineValuesOf } from \"@shared/browser-half\";\n\n/**\n * Props for {@link ConfigDirectorProvider}. Identical to the client provider options\n * except `initialConfigs` is omitted — SSR-evaluated values are injected automatically.\n */\nexport type ConfigDirectorProviderProps = Omit<ConfigDirectorProviderOptions, \"initialConfigs\"> & {\n /**\n * Restrict SSR pre-evaluation to these config keys. When omitted, all known configs are\n * pre-evaluated. Useful when you have a large config set and only need a subset hydrated\n * on this layout.\n */\n configKeys?: string[];\n};\n\n/**\n * React Server Component wrapper around the ConfigDirector client provider.\n *\n * Place this in your root layout. It pre-evaluates all configs on the server using the\n * provided context and passes them to the client provider, preventing any flash of wrong\n * content on hydration.\n *\n * Requires Next.js 13+ (App Router) and React 18+.\n *\n * Read `sdkKey` from a plain environment variable (e.g. `CONFIGDIRECTOR_CLIENT_KEY`), NOT one\n * prefixed with `NEXT_PUBLIC_` — even here, inside a Server Component. Next.js substitutes\n * `NEXT_PUBLIC_*` references with a literal string at compile time wherever they appear in\n * code it bundles, with no exemption for Server Components; that permanently freezes the\n * value into the build artifact the moment you reference it here, regardless of the two\n * deployment strategies below. A plain variable, by contrast, is read live from `process.env`\n * — its resolved value (not the variable lookup itself) is what gets passed as a prop to the\n * client provider below, which is how it safely reaches the browser without ever being baked\n * into the bundle as source.\n *\n * **Deploying one build artifact to multiple environments (e.g. one Docker image promoted\n * from staging to prod):** a plain variable is only read fresh per request if this component's\n * render actually re-runs on each request — otherwise Next.js still statically prerenders the\n * route once at build time and caches the output to a static HTML file, silently freezing\n * whichever value was set at build time. Make sure your root layout either reads a per-request\n * API like `cookies()` (as below, which forces dynamic rendering as a side effect) or adds\n * `export const dynamic = \"force-dynamic\";` if it doesn't otherwise need one. The trade-off is\n * that the route loses static generation/ISR caching, since it now renders on every request.\n *\n * **Building a separate artifact per environment:** if you'd rather keep static generation\n * (and are fine building once per environment, e.g. as a distinct step per env in CI), no\n * layout changes are needed — a plain environment variable set at build time is read once and\n * baked into the static output for that build, same as `NEXT_PUBLIC_` would be, just without\n * also exposing it to arbitrary client-side code that isn't a descendant of this provider.\n *\n * @example\n * ```tsx\n * // app/layout.tsx\n * import { ConfigDirectorProvider } from \"@configdirector/nextjs-sdk/server\";\n * import { cookies } from \"next/headers\";\n *\n * export default async function RootLayout({ children }) {\n * const userId = (await cookies()).get(\"userId\")?.value;\n * return (\n * <html>\n * <body>\n * <ConfigDirectorProvider\n * sdkKey={process.env.CONFIGDIRECTOR_CLIENT_KEY!}\n * context={{ userId }}\n * >\n * {children}\n * </ConfigDirectorProvider>\n * </body>\n * </html>\n * );\n * }\n * ```\n */\nexport async function ConfigDirectorProvider({\n children,\n configKeys,\n ...props\n}: PropsWithChildren<ConfigDirectorProviderProps>) {\n const initialConfigs = generateSsrConfigSet({ context: props.context, configKeys });\n const appMeta = getAppMeta();\n return (\n <ClientProvider\n {...props}\n {...browserHalfConnectionProps(initialConfigs, props)}\n appName={props.appName ?? appMeta.appName}\n appVersion={props.appVersion ?? appMeta.appVersion}\n initialConfigs={initialConfigs}>\n {children}\n </ClientProvider>\n );\n}\n\nconst browserHalfConnectionProps = (\n initialConfigs: Record<string, ConfigState>,\n props: ConfigDirectorProviderProps,\n): Pick<ConfigDirectorProviderOptions, \"mode\" | \"values\"> => {\n switch (decideBrowserHalfSource(props, getServerConnectionMode())) {\n case \"as-given\":\n return {};\n case \"inherit-offline\":\n return { mode: \"offline\", values: offlineValuesOf(initialConfigs) };\n case \"connect\":\n return {};\n }\n};\n"],"mappings":"kLAGA,IAAM,EAAN,KAAuE,CACrE,gBAAgB,EAAyB,CACvC,MAAO,+BAA+B,MAI1C,MAAa,GACX,EACA,IAEO,IAAI,EAAqB,GAAS,OAAQ,GAAoB,IAAI,EAAsB,CAGpF,GACX,EACA,IAEO,IAAI,EAAqB,EAAO,GAAoB,IAAI,EAAsB,CC+BvF,eAAsB,EAAS,EAAyC,CAItE,GAAI,QAAQ,IAAI,eAAoB,SAAU,CAC5C,IAAM,EAAiB,EAAQ,YAAY,MAAQ,YACnD,GAAI,IAAmB,WAAa,CAAC,EAAQ,aAAc,CACzD,IAAM,EACJ,6HAEF,MADA,GAAqB,CAAC,MAAM,EAAQ,CAC9B,IAAI,EAAkC,EAAQ,CAGtD,GAAI,CAAC,WAAW,6BAA8B,CAC5C,GAAM,CAAE,+BAAgC,MAAM,OAAO,8CAAA,KAAA,GAAA,EAAA,EAAA,CAC/C,CAAE,eAAc,GAAG,GAAkB,EAC3C,WAAW,wBAA0B,CACnC,QAAS,EAAQ,UAAU,QAC3B,WAAY,EAAQ,UAAU,WAC/B,CACD,WAAW,qCAAuC,EAClD,IAAM,EAAS,IAAI,EACjB,EACA,CAAE,QAAS,aAAc,WAAY,SAAe,CACpD,EACD,CACD,WAAW,6BAA+B,EAC1C,GAAI,CACF,MAAM,EAAO,YAAY,OAClB,EAAO,CAKd,KAJA,YAAW,6BAA+B,IAAA,GAC1C,WAAW,qCAAuC,IAAA,GAClD,WAAW,wBAA0B,IAAA,GACrC,EAAO,SAAS,CACV,KAMd,SAAgB,GAAwD,CACtE,OAAO,WAAW,yBAA2B,EAAE,CAGjD,SAAgB,GAAsD,CACpE,OAAO,WAAW,qCAGpB,SAAgB,GAAwC,CACtD,GAAI,CAAC,WAAW,6BACd,MAAM,IAAI,EACR,qIACD,CAEH,OAAO,WAAW,6BCrGpB,MAAM,EAAS,GAAqB,CAsBpC,SAAgB,EAAqB,EAAoE,CACvG,GAAI,CACF,OAAO,GAAiB,CAAC,cAAc,EAAQ,OACxC,EAAO,CAEd,OADA,EAAO,MAAM,mCAAoC,EAAM,CAChD,EAAE,EC1Bb,MAAa,GACX,EACA,IAEI,EAAY,OAAS,IAAA,IAAa,EAAY,SAAW,IAAA,GACpD,WAEL,IAAyB,UACpB,kBAEF,UAGH,EAAe,GACnB,OAAO,EAAO,OAAU,SAEb,EAAmB,GAC9B,OAAO,YACL,OAAO,OAAO,EAAQ,CACnB,OAAO,EAAY,CACnB,IAAK,GAAW,CAAC,EAAO,IAAK,EAAkB,EAAO,KAAM,EAAO,MAAM,CAAC,CAAC,CAC/E,CCoDH,eAAsB,EAAuB,CAC3C,WACA,aACA,GAAG,GAC8C,CACjD,IAAM,EAAiB,EAAqB,CAAE,QAAS,EAAM,QAAS,aAAY,CAAC,CAC7E,EAAU,GAAY,CAC5B,OACE,EAACA,EAAD,CACE,GAAI,EACJ,GAAI,EAA2B,EAAgB,EAAM,CACrD,QAAS,EAAM,SAAW,EAAQ,QAClC,WAAY,EAAM,YAAc,EAAQ,WACxB,iBACf,WACc,CAAA,CAIrB,MAAM,GACJ,EACA,IAC2D,CAC3D,OAAQ,EAAwB,EAAO,GAAyB,CAAC,CAAjE,CACE,IAAK,WACH,MAAO,EAAE,CACX,IAAK,kBACH,MAAO,CAAE,KAAM,UAAW,OAAQ,EAAgB,EAAe,CAAE,CACrE,IAAK,UACH,MAAO,EAAE"}
@@ -0,0 +1,2 @@
1
+ const e={off:-1,error:0,warn:1,info:2,debug:3},t=()=>{let e={year:`numeric`,month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`,second:`2-digit`,timeZoneName:`short`};try{return new Intl.DateTimeFormat(void 0,{...e,fractionalSecondDigits:3})}catch{return new Intl.DateTimeFormat(void 0,e)}};var n=class{constructor(e,n){this.level=e,this.decorator=n,this.level=e,this.decorator=n,this.dateFormatter=t()}debug(e,...t){this.log(console.debug,`debug`,e,...t)}info(e,...t){this.log(console.info,`info`,e,...t)}warn(e,...t){this.log(console.warn,`warn`,e,...t)}error(e,...t){this.log(console.error,`error`,e,...t)}log(t,n,r,...i){e[this.level]>=e[n]&&t(`[${this.dateFormatter.format(new Date)}] ${this.decorator?.decorateMessage(r)}`,...i)}},r=class e extends Error{constructor(t,n){super(t),this.name=`ConfigDirectorConnectionError`,this.status=n,Object.setPrototypeOf(this,e.prototype)}},i=class e extends Error{constructor(t){super(t),this.name=`ConfigDirectorValidationError`,Object.setPrototypeOf(this,e.prototype)}},a=class e extends Error{constructor(t){super(t),this.name=`ConfigDirectorInitializationError`,Object.setPrototypeOf(this,e.prototype)}};const o=(e,t)=>{if(e.trim().length==0)throw new i(`Invalid config key. The key of a value cannot be empty.`);return l(e,t)},s={boolean:e=>e===`true`,integer:Number,float:Number,string:e=>e,enum:e=>e,url:e=>e,custom:e=>e,json:e=>JSON.parse(e)},c=(e,t)=>s[e](t),l=(e,t)=>{switch(typeof t){case`boolean`:return{type:`boolean`,value:t?`true`:`false`};case`number`:return u(e,t);case`string`:return{type:`string`,value:t};case`object`:if(t!==null)return f(e,t,``),{type:`json`,value:JSON.stringify(t)}}throw new i(`Invalid value for '${e}': ${h(t)}. Use a boolean, a number, a string, a plain object, or an array.`)},u=(e,t)=>{if(!Number.isFinite(t))throw new i(`Invalid value for '${e}': ${h(t)} is not a finite number.`);if(Number.isInteger(t)){if(!Number.isSafeInteger(t))throw new i(`Invalid value for '${e}': ${t} is not a safe integer, so the SDK could not read it back exactly.`);return{type:`integer`,value:String(t)}}return{type:`float`,value:d(t)}},d=e=>{let t=String(e),n=t.indexOf(`e-`);if(n<0)return t;let r=t.startsWith(`-`)?`-`:``,[i=``,a=``]=t.slice(r.length,n).split(`.`),o=Number(t.slice(n+2))-i.length;return`${r}0.${`0`.repeat(o)}${i}${a}`},f=(e,t,n)=>{if(!(t===null||typeof t==`boolean`||typeof t==`string`)){if(typeof t==`number`){if(!Number.isFinite(t))throw p(e,n,`${h(t)} is not a finite number`);return}if(Array.isArray(t)){t.forEach((t,r)=>f(e,t,`${n}[${r}]`));return}if(m(t)){for(let[r,i]of Object.entries(t))f(e,i,n?`${n}.${r}`:r);return}throw p(e,n,`${h(t)} cannot be encoded as JSON`)}},p=(e,t,n)=>new i(`Invalid value for '${e}'${t?` at '${t}'`:``}: ${n}. JSON contents can hold booleans, finite numbers, strings, null, arrays, and plain objects.`),m=e=>{if(typeof e!=`object`||!e)return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null},h=e=>e===null?`null`:typeof e==`function`?`a function`:typeof e==`object`?`a ${e.constructor?.name??`object`} instance`:typeof e==`symbol`?`a symbol`:String(e);export{i as a,a as i,o as n,n as o,r,c as t};
2
+ //# sourceMappingURL=native-values-CfqV9hAq.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-values-CfqV9hAq.mjs","names":[],"sources":["../../../shared/src/logger.ts","../../../shared/src/errors.ts","../../../shared/src/native-values.ts"],"sourcesContent":["import type { ConfigDirectorLogger, ConfigDirectorLogMessageDecorator, ConfigDirectorLoggingLevel } from \"./types\";\n\nconst LEVELS: Record<ConfigDirectorLoggingLevel, number> = {\n off: -1,\n error: 0,\n warn: 1,\n info: 2,\n debug: 3,\n};\n\nconst buildDateFormatter = () => {\n const baseOptions: Intl.DateTimeFormatOptions = {\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n timeZoneName: \"short\",\n };\n\n try {\n return new Intl.DateTimeFormat(\n undefined,\n { ...baseOptions, fractionalSecondDigits: 3 } as Intl.DateTimeFormatOptions,\n );\n } catch {\n return new Intl.DateTimeFormat(undefined, baseOptions);\n }\n};\n\nexport class DefaultConsoleLogger implements ConfigDirectorLogger {\n private readonly dateFormatter;\n\n constructor(private readonly level: ConfigDirectorLoggingLevel, private readonly decorator: ConfigDirectorLogMessageDecorator) {\n this.level = level;\n this.decorator = decorator;\n this.dateFormatter = buildDateFormatter();\n }\n\n debug(message: string, ...args: any): void {\n this.log(console.debug, \"debug\", message, ...args);\n }\n\n info(message: string, ...args: any): void {\n this.log(console.info, \"info\", message, ...args);\n }\n\n warn(message: string, ...args: any): void {\n this.log(console.warn, \"warn\", message, ...args);\n }\n\n error(message: string, ...args: any): void {\n this.log(console.error, \"error\", message, ...args);\n }\n\n protected log(loggerFunction: (...args: any) => void, level: ConfigDirectorLoggingLevel, message: string, ...args: any) {\n if (LEVELS[this.level] >= LEVELS[level]) {\n loggerFunction(`[${this.dateFormatter.format(new Date())}] ${this.decorator?.decorateMessage(message)}`, ...args);\n }\n }\n}\n","export class ConfigDirectorConnectionError extends Error {\n public override readonly name: string = \"ConfigDirectorConnectionError\";\n public readonly status?: number;\n\n constructor(message: string, status?: number) {\n super(message);\n this.status = status;\n\n Object.setPrototypeOf(this, ConfigDirectorConnectionError.prototype);\n }\n}\n\nexport class ConfigDirectorValidationError extends Error {\n public override readonly name: string = \"ConfigDirectorValidationError\";\n\n constructor(message: string) {\n super(message);\n\n Object.setPrototypeOf(this, ConfigDirectorValidationError.prototype);\n }\n}\n\nexport class ConfigDirectorInitializationError extends Error {\n public override readonly name: string = \"ConfigDirectorInitializationError\";\n\n constructor(message: string) {\n super(message);\n\n Object.setPrototypeOf(this, ConfigDirectorInitializationError.prototype);\n }\n}\n","import type { ConfigType } from \"./types\";\nimport { ConfigDirectorValidationError } from \"./errors\";\n\nexport type NativeJsonValue = boolean | number | string | null | NativeJsonValue[] | { [key: string]: NativeJsonValue };\n\nexport type NativeValue = boolean | number | string | NativeJsonValue[] | { [key: string]: NativeJsonValue };\n\nexport type NativeValues = Record<string, NativeValue>;\n\nexport type EncodedNativeValue = { type: ConfigType; value: string };\n\nexport const encodeNativeValue = (key: string, value: NativeValue): EncodedNativeValue => {\n if (key.trim().length == 0) {\n throw new ConfigDirectorValidationError(\"Invalid config key. The key of a value cannot be empty.\");\n }\n return encode(key, value);\n};\n\nconst decoders: { [T in ConfigType]: (value: string) => NativeValue } = {\n boolean: (value) => value === \"true\",\n integer: Number,\n float: Number,\n string: (value) => value,\n enum: (value) => value,\n url: (value) => value,\n custom: (value) => value,\n json: (value) => JSON.parse(value),\n};\n\nexport const decodeNativeValue = (type: ConfigType, value: string): NativeValue => decoders[type](value);\n\nconst encode = (key: string, value: NativeValue): EncodedNativeValue => {\n switch (typeof value) {\n case \"boolean\":\n return { type: \"boolean\", value: value ? \"true\" : \"false\" };\n case \"number\":\n return encodeNumber(key, value);\n case \"string\":\n return { type: \"string\", value };\n case \"object\":\n if (value !== null) {\n assertJsonContents(key, value, \"\");\n return { type: \"json\", value: JSON.stringify(value) };\n }\n }\n throw new ConfigDirectorValidationError(\n `Invalid value for '${key}': ${describe(value)}. Use a boolean, a number, a string, a plain object, or an array.`,\n );\n};\n\nconst encodeNumber = (key: string, value: number): EncodedNativeValue => {\n if (!Number.isFinite(value)) {\n throw new ConfigDirectorValidationError(`Invalid value for '${key}': ${describe(value)} is not a finite number.`);\n }\n if (Number.isInteger(value)) {\n if (!Number.isSafeInteger(value)) {\n throw new ConfigDirectorValidationError(\n `Invalid value for '${key}': ${value} is not a safe integer, so the SDK could not read it back exactly.`,\n );\n }\n return { type: \"integer\", value: String(value) };\n }\n return { type: \"float\", value: toPlainDecimal(value) };\n};\n\nconst toPlainDecimal = (value: number): string => {\n const text = String(value);\n const exponentIndex = text.indexOf(\"e-\");\n if (exponentIndex < 0) {\n return text;\n }\n const sign = text.startsWith(\"-\") ? \"-\" : \"\";\n const [integerDigits = \"\", fractionDigits = \"\"] = text.slice(sign.length, exponentIndex).split(\".\");\n const leadingZeros = Number(text.slice(exponentIndex + 2)) - integerDigits.length;\n return `${sign}0.${\"0\".repeat(leadingZeros)}${integerDigits}${fractionDigits}`;\n};\n\nconst assertJsonContents = (key: string, value: unknown, path: string): void => {\n if (value === null || typeof value === \"boolean\" || typeof value === \"string\") {\n return;\n }\n if (typeof value === \"number\") {\n if (!Number.isFinite(value)) {\n throw invalidJsonContents(key, path, `${describe(value)} is not a finite number`);\n }\n return;\n }\n if (Array.isArray(value)) {\n value.forEach((item, index) => assertJsonContents(key, item, `${path}[${index}]`));\n return;\n }\n if (isPlainObject(value)) {\n for (const [property, item] of Object.entries(value)) {\n assertJsonContents(key, item, path ? `${path}.${property}` : property);\n }\n return;\n }\n throw invalidJsonContents(key, path, `${describe(value)} cannot be encoded as JSON`);\n};\n\nconst invalidJsonContents = (key: string, path: string, problem: string) =>\n new ConfigDirectorValidationError(\n `Invalid value for '${key}'${path ? ` at '${path}'` : \"\"}: ${problem}. JSON contents can hold booleans, finite numbers, strings, null, arrays, and plain objects.`,\n );\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n};\n\nconst describe = (value: unknown): string => {\n if (value === null) {\n return \"null\";\n }\n if (typeof value === \"function\") {\n return \"a function\";\n }\n if (typeof value === \"object\") {\n return `a ${value.constructor?.name ?? \"object\"} instance`;\n }\n if (typeof value === \"symbol\") {\n return \"a symbol\";\n }\n return String(value);\n};\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ const e={off:-1,error:0,warn:1,info:2,debug:3},t=()=>{let e={year:`numeric`,month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`,second:`2-digit`,timeZoneName:`short`};try{return new Intl.DateTimeFormat(void 0,{...e,fractionalSecondDigits:3})}catch{return new Intl.DateTimeFormat(void 0,e)}};var n=class{constructor(e,n){this.level=e,this.decorator=n,this.level=e,this.decorator=n,this.dateFormatter=t()}debug(e,...t){this.log(console.debug,`debug`,e,...t)}info(e,...t){this.log(console.info,`info`,e,...t)}warn(e,...t){this.log(console.warn,`warn`,e,...t)}error(e,...t){this.log(console.error,`error`,e,...t)}log(t,n,r,...i){e[this.level]>=e[n]&&t(`[${this.dateFormatter.format(new Date)}] ${this.decorator?.decorateMessage(r)}`,...i)}},r=class e extends Error{constructor(t,n){super(t),this.name=`ConfigDirectorConnectionError`,this.status=n,Object.setPrototypeOf(this,e.prototype)}},i=class e extends Error{constructor(t){super(t),this.name=`ConfigDirectorValidationError`,Object.setPrototypeOf(this,e.prototype)}},a=class e extends Error{constructor(t){super(t),this.name=`ConfigDirectorInitializationError`,Object.setPrototypeOf(this,e.prototype)}};const o=(e,t)=>{if(e.trim().length==0)throw new i(`Invalid config key. The key of a value cannot be empty.`);return l(e,t)},s={boolean:e=>e===`true`,integer:Number,float:Number,string:e=>e,enum:e=>e,url:e=>e,custom:e=>e,json:e=>JSON.parse(e)},c=(e,t)=>s[e](t),l=(e,t)=>{switch(typeof t){case`boolean`:return{type:`boolean`,value:t?`true`:`false`};case`number`:return u(e,t);case`string`:return{type:`string`,value:t};case`object`:if(t!==null)return f(e,t,``),{type:`json`,value:JSON.stringify(t)}}throw new i(`Invalid value for '${e}': ${h(t)}. Use a boolean, a number, a string, a plain object, or an array.`)},u=(e,t)=>{if(!Number.isFinite(t))throw new i(`Invalid value for '${e}': ${h(t)} is not a finite number.`);if(Number.isInteger(t)){if(!Number.isSafeInteger(t))throw new i(`Invalid value for '${e}': ${t} is not a safe integer, so the SDK could not read it back exactly.`);return{type:`integer`,value:String(t)}}return{type:`float`,value:d(t)}},d=e=>{let t=String(e),n=t.indexOf(`e-`);if(n<0)return t;let r=t.startsWith(`-`)?`-`:``,[i=``,a=``]=t.slice(r.length,n).split(`.`),o=Number(t.slice(n+2))-i.length;return`${r}0.${`0`.repeat(o)}${i}${a}`},f=(e,t,n)=>{if(!(t===null||typeof t==`boolean`||typeof t==`string`)){if(typeof t==`number`){if(!Number.isFinite(t))throw p(e,n,`${h(t)} is not a finite number`);return}if(Array.isArray(t)){t.forEach((t,r)=>f(e,t,`${n}[${r}]`));return}if(m(t)){for(let[r,i]of Object.entries(t))f(e,i,n?`${n}.${r}`:r);return}throw p(e,n,`${h(t)} cannot be encoded as JSON`)}},p=(e,t,n)=>new i(`Invalid value for '${e}'${t?` at '${t}'`:``}: ${n}. JSON contents can hold booleans, finite numbers, strings, null, arrays, and plain objects.`),m=e=>{if(typeof e!=`object`||!e)return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null},h=e=>e===null?`null`:typeof e==`function`?`a function`:typeof e==`object`?`a ${e.constructor?.name??`object`} instance`:typeof e==`symbol`?`a symbol`:String(e);Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return c}});
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./DefaultConfigDirectorClient-CqXqwNpW.cjs`),t=require(`./errors-CCbuIqT8.cjs`);let n=require(`node:events`);n=e.i(n);const r=(e,n)=>{if(e.trim().length==0)throw new t.r(`Invalid config key. The key of a test value cannot be empty.`);return i(e,n)},i=(e,n)=>{switch(typeof n){case`boolean`:return{type:`boolean`,value:n?`true`:`false`};case`number`:return a(e,n);case`string`:return{type:`string`,value:n};case`object`:if(n!==null)return s(e,n,``),{type:`json`,value:JSON.stringify(n)}}throw new t.r(`Invalid test value for '${e}': ${u(n)}. Use a boolean, a number, a string, a plain object, or an array.`)},a=(e,n)=>{if(!Number.isFinite(n))throw new t.r(`Invalid test value for '${e}': ${u(n)} is not a finite number.`);if(Number.isInteger(n)){if(!Number.isSafeInteger(n))throw new t.r(`Invalid test value for '${e}': ${n} is not a safe integer, so the SDK could not read it back exactly.`);return{type:`integer`,value:String(n)}}return{type:`float`,value:o(n)}},o=e=>{let t=String(e),n=t.indexOf(`e-`);if(n<0)return t;let r=t.startsWith(`-`)?`-`:``,[i=``,a=``]=t.slice(r.length,n).split(`.`),o=Number(t.slice(n+2))-i.length;return`${r}0.${`0`.repeat(o)}${i}${a}`},s=(e,t,n)=>{if(!(t===null||typeof t==`boolean`||typeof t==`string`)){if(typeof t==`number`){if(!Number.isFinite(t))throw c(e,n,`${u(t)} is not a finite number`);return}if(Array.isArray(t)){t.forEach((t,r)=>s(e,t,`${n}[${r}]`));return}if(l(t)){for(let[r,i]of Object.entries(t))s(e,i,n?`${n}.${r}`:r);return}throw c(e,n,`${u(t)} cannot be encoded as JSON`)}},c=(e,n,r)=>new t.r(`Invalid test value for '${e}'${n?` at '${n}'`:``}: ${r}. JSON contents can hold booleans, finite numbers, strings, null, arrays, and plain objects.`),l=e=>{if(typeof e!=`object`||!e)return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null},u=e=>e===null?`null`:typeof e==`function`?`a function`:typeof e==`object`?`a ${e.constructor?.name??`object`} instance`:typeof e==`symbol`?`a symbol`:String(e),d=(e,t)=>{let n=r(e,t);return{id:`test-config:${e}`,key:e,type:n.type,variations:[{name:null,value:n.value}],target:{defaultValue:n.value,rules:[]}}},f={environmentId:`test-environment`,projectId:`test-project`};var p=class{constructor(e,t){this.logger=e,this.emitter=new n.default,this.configs=new Map,this.pendingDeliveries=[],this.armed=`nothing`,this.connected=!1,this.delivering=!1,this.encodeAll(t).forEach((e,t)=>this.configs.set(t,e))}setValue(e,t){let n=d(e,t);this.configs.set(e,n),this.deliverIfConnected({...f,kind:`delta`,configs:{[e]:n}})}removeValue(e){this.configs.delete(e),this.deliverIfConnected(this.fullUpdate())}replaceValues(e){let t=this.encodeAll(e);this.configs.clear(),t.forEach((e,t)=>this.configs.set(t,e)),this.armed=`nothing`,this.deliverIfConnected(this.fullUpdate())}hold(){this.armed=`hold`}complete(){this.pendingHold?this.pendingHold.complete():this.armed===`hold`&&(this.armed=`nothing`)}fail(){this.pendingHold?this.pendingHold.fail():this.armed=`failure`}connect(e){this.endAttempt();let t=this.armed;switch(this.armed=`nothing`,t){case`failure`:return this.failNow();case`hold`:return this.holdNow(e);default:return this.connectNow(),Promise.resolve(this)}}get isConnected(){return this.connected}on(e,t){this.emitter.on(e,t)}off(e,t){t?this.emitter.off(e,t):this.emitter.removeAllListeners(e)}close(){this.endAttempt()}dispose(){this.close(),this.emitter.removeAllListeners()}endAttempt(){this.connected=!1,this.pendingHold?.end()}connectNow(){this.connected=!0,this.deliver(this.fullUpdate())}holdNow(e){return new Promise((t,n)=>{let r=setTimeout(()=>this.pendingHold?.end(),e),i=()=>{clearTimeout(r),this.pendingHold=void 0};this.pendingHold={end:()=>{i(),t(this)},complete:()=>{i(),this.connectNow(),t(this)},fail:()=>{i();let e=this.fatalError();this.emitter.emit(`connectionError`,e),n(e)}}})}failNow(){let e=this.fatalError();return this.emitter.emit(`connectionError`,e),Promise.reject(e)}fatalError(){return new t.t(`Connection failed with status: 401. Error: the test client failed this initialization. This is an unrecoverable error, will not attempt to reconnect.`,401)}deliverIfConnected(e){this.connected&&this.deliver(e)}deliver(e){if(this.pendingDeliveries.push(e),!this.delivering){this.delivering=!0;try{let e=this.pendingDeliveries.shift();for(;e;)this.emitCaught(e),e=this.pendingDeliveries.shift()}finally{this.delivering=!1}}}emitCaught(e){try{this.emitter.emit(`configBundleReceived`,e)}catch(e){this.logger.error(`[InMemoryConnection] Error dispatching a config update from the test client: `,e)}}fullUpdate(){return{...f,kind:`full`,configs:Object.fromEntries(this.configs)}}encodeAll(e){let t=new Map;for(let[n,r]of Object.entries(e))t.set(n,d(n,r));return t}};const m={start:()=>{},evaluatedConfig:()=>{},recordInvalidContext:()=>`new-kind-sample`,close:async()=>{}};var h=class{constructor(e,t){this.client=e,this.connection=t}setValue(e,t){this.connection.setValue(e,t)}removeValue(e){this.connection.removeValue(e)}replaceValues(e){this.connection.replaceValues(e)}holdInitialization(){this.connection.hold()}completeInitialization(){this.connection.complete()}failInitialization(){this.connection.fail()}};const g=(t,n)=>{let r=n?.logger??e.r(),i=new p(r,n?.values??{});return new h(new e.t(`test-client`,t,{logger:r,connection:{timeout:n?.timeout}},{transport:i,telemetry:m}),i)},_=e=>g({sdkName:`nextjs-sdk`,sdkVersion:`1.10.0`},e),v=e=>{let t=globalThis.__configDirectorServerClient;return globalThis.__configDirectorServerClient=e.client,()=>{globalThis.__configDirectorServerClient=t}};exports.ConfigDirectorConnectionError=t.t,exports.ConfigDirectorValidationError=t.r,exports.createTestClient=_,exports.installServerTestClient=v;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./DefaultConfigDirectorClient-oT53aH0F.cjs`),t=require(`./native-values-UCK4hh1Z.cjs`);let n=require(`node:events`);n=e.o(n);const r={environmentId:`test-environment`,projectId:`test-project`};var i=class{constructor(e,t){this.logger=e,this.emitter=new n.default,this.configs=new Map,this.pendingDeliveries=[],this.armed=`nothing`,this.connected=!1,this.delivering=!1,this.encodeAll(t).forEach((e,t)=>this.configs.set(t,e))}setValue(e,t){let n=this.encode(e,t);this.configs.set(e,n),this.deliverIfConnected({...r,kind:`delta`,configs:{[e]:n}})}removeValue(e){this.configs.delete(e),this.deliverIfConnected(this.fullUpdate())}replaceValues(e){let t=this.encodeAll(e);this.configs.clear(),t.forEach((e,t)=>this.configs.set(t,e)),this.armed=`nothing`,this.deliverIfConnected(this.fullUpdate())}hold(){this.armed=`hold`}complete(){this.pendingHold?this.pendingHold.complete():this.armed===`hold`&&(this.armed=`nothing`)}fail(){this.pendingHold?this.pendingHold.fail():this.armed=`failure`}connect(e){this.endAttempt();let t=this.armed;switch(this.armed=`nothing`,t){case`failure`:return this.failNow();case`hold`:return this.holdNow(e);default:return this.connectNow(),Promise.resolve(this)}}get isConnected(){return this.connected}on(e,t){this.emitter.on(e,t)}off(e,t){t?this.emitter.off(e,t):this.emitter.removeAllListeners(e)}close(){this.endAttempt()}dispose(){this.close(),this.emitter.removeAllListeners()}endAttempt(){this.connected=!1,this.pendingHold?.end()}connectNow(){this.connected=!0,this.deliver(this.fullUpdate())}holdNow(e){return new Promise((t,n)=>{let r=setTimeout(()=>this.pendingHold?.end(),e),i=()=>{clearTimeout(r),this.pendingHold=void 0};this.pendingHold={end:()=>{i(),t(this)},complete:()=>{i(),this.connectNow(),t(this)},fail:()=>{i();let e=this.fatalError();this.emitter.emit(`connectionError`,e),n(e)}}})}failNow(){let e=this.fatalError();return this.emitter.emit(`connectionError`,e),Promise.reject(e)}fatalError(){return new t.r(`Connection failed with status: 401. Error: the test client failed this initialization. This is an unrecoverable error, will not attempt to reconnect.`,401)}deliverIfConnected(e){this.connected&&this.deliver(e)}deliver(e){if(this.pendingDeliveries.push(e),!this.delivering){this.delivering=!0;try{let e=this.pendingDeliveries.shift();for(;e;)this.emitCaught(e),e=this.pendingDeliveries.shift()}finally{this.delivering=!1}}}emitCaught(e){try{this.emitter.emit(`configBundleReceived`,e)}catch(e){this.logger.error(`[InMemoryConnection] Error dispatching a config update from the test client: `,e)}}fullUpdate(){return{...r,kind:`full`,configs:Object.fromEntries(this.configs)}}encodeAll(e){let t=new Map;for(let[n,r]of Object.entries(e))t.set(n,this.encode(n,r));return t}encode(t,n){return e.a(`test-config:${t}`,t,n)}},a=class{constructor(e,t){this.client=e,this.connection=t}setValue(e,t){this.connection.setValue(e,t)}removeValue(e){this.connection.removeValue(e)}replaceValues(e){this.connection.replaceValues(e)}holdInitialization(){this.connection.hold()}completeInitialization(){this.connection.complete()}failInitialization(){this.connection.fail()}};const o=(t,n)=>{let r=n?.logger??e.i(),o=new i(r,n?.values??{});return new a(new e.t(`test-client`,t,{logger:r,connection:{timeout:n?.timeout}},{transport:o,telemetry:e.r}),o)},s=e=>o({sdkName:`nextjs-sdk`,sdkVersion:`1.11.0`},e),c=e=>{let t=globalThis.__configDirectorServerClient;return globalThis.__configDirectorServerClient=e.client,()=>{globalThis.__configDirectorServerClient=t}};exports.ConfigDirectorConnectionError=t.r,exports.ConfigDirectorValidationError=t.a,exports.createTestClient=s,exports.installServerTestClient=c;
@@ -1,25 +1,5 @@
1
- import { a as ConfigDirectorLogger, t as ConfigDirectorClient } from "./types-BBEEMV5Y.cjs";
1
+ import { d as NativeValues, i as ConfigDirectorClient, l as NativeJsonValue, m as ConfigDirectorLogger, r as ConfigDirectorValidationError, t as ConfigDirectorConnectionError, u as NativeValue } from "./errors-EfmnEmll.cjs";
2
2
 
3
- //#region ../shared/src/errors.d.ts
4
- declare class ConfigDirectorConnectionError extends Error {
5
- readonly name: string;
6
- readonly status?: number;
7
- constructor(message: string, status?: number);
8
- }
9
- declare class ConfigDirectorValidationError extends Error {
10
- readonly name: string;
11
- constructor(message: string);
12
- }
13
- //#endregion
14
- //#region ../shared/src/testing/values.d.ts
15
- type TestJsonValue = boolean | number | string | null | TestJsonValue[] | {
16
- [key: string]: TestJsonValue;
17
- };
18
- type TestValue = boolean | number | string | TestJsonValue[] | {
19
- [key: string]: TestJsonValue;
20
- };
21
- type TestValues = Record<string, TestValue>;
22
- //#endregion
23
3
  //#region ../js-server-sdk/src/testing/TestClient.d.ts
24
4
  /**
25
5
  * Options for {@link createTestClient}. Every option is optional.
@@ -31,7 +11,7 @@ type TestClientOptions = {
31
11
  * number (`float`), a string, or a plain object or array (`json`). Every context receives the
32
12
  * same value.
33
13
  */
34
- values?: TestValues;
14
+ values?: NativeValues;
35
15
  /**
36
16
  * The connection timeout of the SDK client, in milliseconds. It bounds how long a held
37
17
  * `initialize` waits. Defaults to the SDK's production timeout.
@@ -62,7 +42,7 @@ interface TestClient {
62
42
  * Stores `value` under `key` and, when the client is connected, delivers it as an update, so
63
43
  * reads, watchers, and `configsUpdated` handlers see it.
64
44
  */
65
- setValue(key: string, value: TestValue): void;
45
+ setValue(key: string, value: NativeValue): void;
66
46
  /**
67
47
  * Removes `key` and, when the client is connected, delivers a full update without it, so reads
68
48
  * fall back to the in-code default value and watchers of `key` receive that default.
@@ -72,7 +52,7 @@ interface TestClient {
72
52
  * Replaces every stored value with `values`, disarms any armed hold or failure, and, when the
73
53
  * client is connected, delivers the new values as a full update.
74
54
  */
75
- replaceValues(values: TestValues): void;
55
+ replaceValues(values: NativeValues): void;
76
56
  /**
77
57
  * Makes the next `initialize` wait until {@link completeInitialization} or
78
58
  * {@link failInitialization} is called, or until the client's timeout elapses.
@@ -117,5 +97,5 @@ declare const createTestClient: (options?: TestClientOptions) => TestClient;
117
97
  */
118
98
  declare const installServerTestClient: (testClient: TestClient) => (() => void);
119
99
  //#endregion
120
- export { ConfigDirectorConnectionError, ConfigDirectorValidationError, type TestClient, type TestClientOptions, type TestJsonValue, type TestValue, type TestValues, createTestClient, installServerTestClient };
100
+ export { ConfigDirectorConnectionError, ConfigDirectorValidationError, type TestClient, type TestClientOptions, type NativeJsonValue as TestJsonValue, type NativeValue as TestValue, type NativeValues as TestValues, createTestClient, installServerTestClient };
121
101
  //# sourceMappingURL=testing.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"testing.d.cts","names":[],"sources":["../../../shared/src/errors.ts","../../../shared/src/testing/values.ts","../../../js-server-sdk/src/testing/TestClient.ts","../../src/server/testing.ts"],"mappings":";;;cAAa,6BAAA,SAAsC,KAAA;EAAA,SACxB,IAAA;EAAA,SACT,MAAA;cAEJ,OAAA,UAAiB,MAAA;AAAA;AAAA,cAQlB,6BAAA,SAAsC,KAAA;EAAA,SACxB,IAAA;cAEb,OAAA;AAAA;;;KCZF,aAAA,sCAAmD,aAAA;EAAA,CAAqB,GAAA,WAAc,aAAA;AAAA;AAAA,KAEtF,SAAA,+BAAwC,aAAA;EAAA,CAAqB,GAAA,WAAc,aAAA;AAAA;AAAA,KAE3E,UAAA,GAAa,MAAA,SAAe,SAAA;;;;ADPxC;;KEYY,iBAAA;EFZ4C;;;;;;EEmBtD,MAAA,GAAS,UAAA;EFfmC;;AAQ9C;;EEYE,OAAA;EFZsD;;;;;EEkBtD,MAAA,GAAS,oBAAA;AAAA;;;;AD3BX;;;;;UCsCiB,UAAA;EDtCiF;;;AAElG;EAFkG,SC2CvF,MAAA,EAAQ,oBAAA;;;;;EAMjB,QAAA,CAAS,GAAA,UAAa,KAAA,EAAO,SAAA;ED/CqE;;AAEpG;;ECmDE,WAAA,CAAY,GAAA;EDnDW;;;;ECyDvB,aAAA,CAAc,MAAA,EAAQ,UAAA;EApDZ;;;;EA0DV,kBAAA;EAnDS;;;;EAyDT,sBAAA;EA9C6B;AAW/B;;;EAyCE,kBAAA;AAAA;;;;;;;;;;;;;;AFtEF;;;;cGUa,gBAAA,GAAoB,OAAA,GAAU,iBAAA,KAAoB,UAAA;;;;;;;;;cAYlD,uBAAA,GAA2B,UAAA,EAAY,UAAA"}
1
+ {"version":3,"file":"testing.d.cts","names":[],"sources":["../../../js-server-sdk/src/testing/TestClient.ts","../../src/server/testing.ts"],"mappings":";;;;AAYA;;KAAY,iBAAA;EAkBmB;;;;;;EAX7B,MAAA,GAAS,YAAA;EAWoB;AAW/B;;;EAjBE,OAAA;EA4B6B;;;;;EAtB7B,MAAA,GAAS,oBAAA;AAAA;;;;;;;;;UAWM,UAAA;EAmCf;;;;EAAA,SA9BS,MAAA,EAAQ,oBAAA;;;ACxBnB;;ED8BE,QAAA,CAAS,GAAA,UAAa,KAAA,EAAO,WAAA;EC5B9B;;;;EDkCC,WAAA,CAAY,GAAA;EClCb;AAUD;;;ED8BE,aAAA,CAAc,MAAA,EAAQ,YAAA;EC9BsC;;;;EDoC5D,kBAAA;;;;;EAMA,sBAAA;;;;;EAMA,kBAAA;AAAA;;;;;;;;;;;;;AAzCF;;;;;cCnBa,gBAAA,GAAoB,OAAA,GAAU,iBAAA,KAAoB,UAAA;;;;;;;;;cAYlD,uBAAA,GAA2B,UAAA,EAAY,UAAA"}
@@ -1,25 +1,5 @@
1
- import { a as ConfigDirectorLogger, t as ConfigDirectorClient } from "./types-B_mGbQaa.mjs";
1
+ import { d as NativeValues, i as ConfigDirectorClient, l as NativeJsonValue, m as ConfigDirectorLogger, r as ConfigDirectorValidationError, t as ConfigDirectorConnectionError, u as NativeValue } from "./errors-r1MHQ8L5.mjs";
2
2
 
3
- //#region ../shared/src/errors.d.ts
4
- declare class ConfigDirectorConnectionError extends Error {
5
- readonly name: string;
6
- readonly status?: number;
7
- constructor(message: string, status?: number);
8
- }
9
- declare class ConfigDirectorValidationError extends Error {
10
- readonly name: string;
11
- constructor(message: string);
12
- }
13
- //#endregion
14
- //#region ../shared/src/testing/values.d.ts
15
- type TestJsonValue = boolean | number | string | null | TestJsonValue[] | {
16
- [key: string]: TestJsonValue;
17
- };
18
- type TestValue = boolean | number | string | TestJsonValue[] | {
19
- [key: string]: TestJsonValue;
20
- };
21
- type TestValues = Record<string, TestValue>;
22
- //#endregion
23
3
  //#region ../js-server-sdk/src/testing/TestClient.d.ts
24
4
  /**
25
5
  * Options for {@link createTestClient}. Every option is optional.
@@ -31,7 +11,7 @@ type TestClientOptions = {
31
11
  * number (`float`), a string, or a plain object or array (`json`). Every context receives the
32
12
  * same value.
33
13
  */
34
- values?: TestValues;
14
+ values?: NativeValues;
35
15
  /**
36
16
  * The connection timeout of the SDK client, in milliseconds. It bounds how long a held
37
17
  * `initialize` waits. Defaults to the SDK's production timeout.
@@ -62,7 +42,7 @@ interface TestClient {
62
42
  * Stores `value` under `key` and, when the client is connected, delivers it as an update, so
63
43
  * reads, watchers, and `configsUpdated` handlers see it.
64
44
  */
65
- setValue(key: string, value: TestValue): void;
45
+ setValue(key: string, value: NativeValue): void;
66
46
  /**
67
47
  * Removes `key` and, when the client is connected, delivers a full update without it, so reads
68
48
  * fall back to the in-code default value and watchers of `key` receive that default.
@@ -72,7 +52,7 @@ interface TestClient {
72
52
  * Replaces every stored value with `values`, disarms any armed hold or failure, and, when the
73
53
  * client is connected, delivers the new values as a full update.
74
54
  */
75
- replaceValues(values: TestValues): void;
55
+ replaceValues(values: NativeValues): void;
76
56
  /**
77
57
  * Makes the next `initialize` wait until {@link completeInitialization} or
78
58
  * {@link failInitialization} is called, or until the client's timeout elapses.
@@ -117,5 +97,5 @@ declare const createTestClient: (options?: TestClientOptions) => TestClient;
117
97
  */
118
98
  declare const installServerTestClient: (testClient: TestClient) => (() => void);
119
99
  //#endregion
120
- export { ConfigDirectorConnectionError, ConfigDirectorValidationError, type TestClient, type TestClientOptions, type TestJsonValue, type TestValue, type TestValues, createTestClient, installServerTestClient };
100
+ export { ConfigDirectorConnectionError, ConfigDirectorValidationError, type TestClient, type TestClientOptions, type NativeJsonValue as TestJsonValue, type NativeValue as TestValue, type NativeValues as TestValues, createTestClient, installServerTestClient };
121
101
  //# sourceMappingURL=testing.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"testing.d.mts","names":[],"sources":["../../../shared/src/errors.ts","../../../shared/src/testing/values.ts","../../../js-server-sdk/src/testing/TestClient.ts","../../src/server/testing.ts"],"mappings":";;;cAAa,6BAAA,SAAsC,KAAA;EAAA,SACxB,IAAA;EAAA,SACT,MAAA;cAEJ,OAAA,UAAiB,MAAA;AAAA;AAAA,cAQlB,6BAAA,SAAsC,KAAA;EAAA,SACxB,IAAA;cAEb,OAAA;AAAA;;;KCZF,aAAA,sCAAmD,aAAA;EAAA,CAAqB,GAAA,WAAc,aAAA;AAAA;AAAA,KAEtF,SAAA,+BAAwC,aAAA;EAAA,CAAqB,GAAA,WAAc,aAAA;AAAA;AAAA,KAE3E,UAAA,GAAa,MAAA,SAAe,SAAA;;;;ADPxC;;KEYY,iBAAA;EFZ4C;;;;;;EEmBtD,MAAA,GAAS,UAAA;EFfmC;;AAQ9C;;EEYE,OAAA;EFZsD;;;;;EEkBtD,MAAA,GAAS,oBAAA;AAAA;;;;AD3BX;;;;;UCsCiB,UAAA;EDtCiF;;;AAElG;EAFkG,SC2CvF,MAAA,EAAQ,oBAAA;;;;;EAMjB,QAAA,CAAS,GAAA,UAAa,KAAA,EAAO,SAAA;ED/CqE;;AAEpG;;ECmDE,WAAA,CAAY,GAAA;EDnDW;;;;ECyDvB,aAAA,CAAc,MAAA,EAAQ,UAAA;EApDZ;;;;EA0DV,kBAAA;EAnDS;;;;EAyDT,sBAAA;EA9C6B;AAW/B;;;EAyCE,kBAAA;AAAA;;;;;;;;;;;;;;AFtEF;;;;cGUa,gBAAA,GAAoB,OAAA,GAAU,iBAAA,KAAoB,UAAA;;;;;;;;;cAYlD,uBAAA,GAA2B,UAAA,EAAY,UAAA"}
1
+ {"version":3,"file":"testing.d.mts","names":[],"sources":["../../../js-server-sdk/src/testing/TestClient.ts","../../src/server/testing.ts"],"mappings":";;;;AAYA;;KAAY,iBAAA;EAkBmB;;;;;;EAX7B,MAAA,GAAS,YAAA;EAWoB;AAW/B;;;EAjBE,OAAA;EA4B6B;;;;;EAtB7B,MAAA,GAAS,oBAAA;AAAA;;;;;;;;;UAWM,UAAA;EAmCf;;;;EAAA,SA9BS,MAAA,EAAQ,oBAAA;;;ACxBnB;;ED8BE,QAAA,CAAS,GAAA,UAAa,KAAA,EAAO,WAAA;EC5B9B;;;;EDkCC,WAAA,CAAY,GAAA;EClCb;AAUD;;;ED8BE,aAAA,CAAc,MAAA,EAAQ,YAAA;EC9BsC;;;;EDoC5D,kBAAA;;;;;EAMA,sBAAA;;;;;EAMA,kBAAA;AAAA;;;;;;;;;;;;;AAzCF;;;;;cCnBa,gBAAA,GAAoB,OAAA,GAAU,iBAAA,KAAoB,UAAA;;;;;;;;;cAYlD,uBAAA,GAA2B,UAAA,EAAY,UAAA"}
@@ -1,2 +1,2 @@
1
- import{r as e,t}from"./DefaultConfigDirectorClient-BTTja_j3.mjs";import{r as n,t as r}from"./errors-BGpFuqOO.mjs";import i from"node:events";const a=(e,t)=>{if(e.trim().length==0)throw new n(`Invalid config key. The key of a test value cannot be empty.`);return o(e,t)},o=(e,t)=>{switch(typeof t){case`boolean`:return{type:`boolean`,value:t?`true`:`false`};case`number`:return s(e,t);case`string`:return{type:`string`,value:t};case`object`:if(t!==null)return l(e,t,``),{type:`json`,value:JSON.stringify(t)}}throw new n(`Invalid test value for '${e}': ${f(t)}. Use a boolean, a number, a string, a plain object, or an array.`)},s=(e,t)=>{if(!Number.isFinite(t))throw new n(`Invalid test value for '${e}': ${f(t)} is not a finite number.`);if(Number.isInteger(t)){if(!Number.isSafeInteger(t))throw new n(`Invalid test value for '${e}': ${t} is not a safe integer, so the SDK could not read it back exactly.`);return{type:`integer`,value:String(t)}}return{type:`float`,value:c(t)}},c=e=>{let t=String(e),n=t.indexOf(`e-`);if(n<0)return t;let r=t.startsWith(`-`)?`-`:``,[i=``,a=``]=t.slice(r.length,n).split(`.`),o=Number(t.slice(n+2))-i.length;return`${r}0.${`0`.repeat(o)}${i}${a}`},l=(e,t,n)=>{if(!(t===null||typeof t==`boolean`||typeof t==`string`)){if(typeof t==`number`){if(!Number.isFinite(t))throw u(e,n,`${f(t)} is not a finite number`);return}if(Array.isArray(t)){t.forEach((t,r)=>l(e,t,`${n}[${r}]`));return}if(d(t)){for(let[r,i]of Object.entries(t))l(e,i,n?`${n}.${r}`:r);return}throw u(e,n,`${f(t)} cannot be encoded as JSON`)}},u=(e,t,r)=>new n(`Invalid test value for '${e}'${t?` at '${t}'`:``}: ${r}. JSON contents can hold booleans, finite numbers, strings, null, arrays, and plain objects.`),d=e=>{if(typeof e!=`object`||!e)return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null},f=e=>e===null?`null`:typeof e==`function`?`a function`:typeof e==`object`?`a ${e.constructor?.name??`object`} instance`:typeof e==`symbol`?`a symbol`:String(e),p=(e,t)=>{let n=a(e,t);return{id:`test-config:${e}`,key:e,type:n.type,variations:[{name:null,value:n.value}],target:{defaultValue:n.value,rules:[]}}},m={environmentId:`test-environment`,projectId:`test-project`};var h=class{constructor(e,t){this.logger=e,this.emitter=new i,this.configs=new Map,this.pendingDeliveries=[],this.armed=`nothing`,this.connected=!1,this.delivering=!1,this.encodeAll(t).forEach((e,t)=>this.configs.set(t,e))}setValue(e,t){let n=p(e,t);this.configs.set(e,n),this.deliverIfConnected({...m,kind:`delta`,configs:{[e]:n}})}removeValue(e){this.configs.delete(e),this.deliverIfConnected(this.fullUpdate())}replaceValues(e){let t=this.encodeAll(e);this.configs.clear(),t.forEach((e,t)=>this.configs.set(t,e)),this.armed=`nothing`,this.deliverIfConnected(this.fullUpdate())}hold(){this.armed=`hold`}complete(){this.pendingHold?this.pendingHold.complete():this.armed===`hold`&&(this.armed=`nothing`)}fail(){this.pendingHold?this.pendingHold.fail():this.armed=`failure`}connect(e){this.endAttempt();let t=this.armed;switch(this.armed=`nothing`,t){case`failure`:return this.failNow();case`hold`:return this.holdNow(e);default:return this.connectNow(),Promise.resolve(this)}}get isConnected(){return this.connected}on(e,t){this.emitter.on(e,t)}off(e,t){t?this.emitter.off(e,t):this.emitter.removeAllListeners(e)}close(){this.endAttempt()}dispose(){this.close(),this.emitter.removeAllListeners()}endAttempt(){this.connected=!1,this.pendingHold?.end()}connectNow(){this.connected=!0,this.deliver(this.fullUpdate())}holdNow(e){return new Promise((t,n)=>{let r=setTimeout(()=>this.pendingHold?.end(),e),i=()=>{clearTimeout(r),this.pendingHold=void 0};this.pendingHold={end:()=>{i(),t(this)},complete:()=>{i(),this.connectNow(),t(this)},fail:()=>{i();let e=this.fatalError();this.emitter.emit(`connectionError`,e),n(e)}}})}failNow(){let e=this.fatalError();return this.emitter.emit(`connectionError`,e),Promise.reject(e)}fatalError(){return new r(`Connection failed with status: 401. Error: the test client failed this initialization. This is an unrecoverable error, will not attempt to reconnect.`,401)}deliverIfConnected(e){this.connected&&this.deliver(e)}deliver(e){if(this.pendingDeliveries.push(e),!this.delivering){this.delivering=!0;try{let e=this.pendingDeliveries.shift();for(;e;)this.emitCaught(e),e=this.pendingDeliveries.shift()}finally{this.delivering=!1}}}emitCaught(e){try{this.emitter.emit(`configBundleReceived`,e)}catch(e){this.logger.error(`[InMemoryConnection] Error dispatching a config update from the test client: `,e)}}fullUpdate(){return{...m,kind:`full`,configs:Object.fromEntries(this.configs)}}encodeAll(e){let t=new Map;for(let[n,r]of Object.entries(e))t.set(n,p(n,r));return t}};const g={start:()=>{},evaluatedConfig:()=>{},recordInvalidContext:()=>`new-kind-sample`,close:async()=>{}};var _=class{constructor(e,t){this.client=e,this.connection=t}setValue(e,t){this.connection.setValue(e,t)}removeValue(e){this.connection.removeValue(e)}replaceValues(e){this.connection.replaceValues(e)}holdInitialization(){this.connection.hold()}completeInitialization(){this.connection.complete()}failInitialization(){this.connection.fail()}};const v=(n,r)=>{let i=r?.logger??e(),a=new h(i,r?.values??{});return new _(new t(`test-client`,n,{logger:i,connection:{timeout:r?.timeout}},{transport:a,telemetry:g}),a)},y=e=>v({sdkName:`nextjs-sdk`,sdkVersion:`1.10.0`},e),b=e=>{let t=globalThis.__configDirectorServerClient;return globalThis.__configDirectorServerClient=e.client,()=>{globalThis.__configDirectorServerClient=t}};export{r as ConfigDirectorConnectionError,n as ConfigDirectorValidationError,y as createTestClient,b as installServerTestClient};
1
+ import{a as e,i as t,r as n,t as r}from"./DefaultConfigDirectorClient-BplPvnEk.mjs";import{a as i,r as a}from"./native-values-CfqV9hAq.mjs";import o from"node:events";const s={environmentId:`test-environment`,projectId:`test-project`};var c=class{constructor(e,t){this.logger=e,this.emitter=new o,this.configs=new Map,this.pendingDeliveries=[],this.armed=`nothing`,this.connected=!1,this.delivering=!1,this.encodeAll(t).forEach((e,t)=>this.configs.set(t,e))}setValue(e,t){let n=this.encode(e,t);this.configs.set(e,n),this.deliverIfConnected({...s,kind:`delta`,configs:{[e]:n}})}removeValue(e){this.configs.delete(e),this.deliverIfConnected(this.fullUpdate())}replaceValues(e){let t=this.encodeAll(e);this.configs.clear(),t.forEach((e,t)=>this.configs.set(t,e)),this.armed=`nothing`,this.deliverIfConnected(this.fullUpdate())}hold(){this.armed=`hold`}complete(){this.pendingHold?this.pendingHold.complete():this.armed===`hold`&&(this.armed=`nothing`)}fail(){this.pendingHold?this.pendingHold.fail():this.armed=`failure`}connect(e){this.endAttempt();let t=this.armed;switch(this.armed=`nothing`,t){case`failure`:return this.failNow();case`hold`:return this.holdNow(e);default:return this.connectNow(),Promise.resolve(this)}}get isConnected(){return this.connected}on(e,t){this.emitter.on(e,t)}off(e,t){t?this.emitter.off(e,t):this.emitter.removeAllListeners(e)}close(){this.endAttempt()}dispose(){this.close(),this.emitter.removeAllListeners()}endAttempt(){this.connected=!1,this.pendingHold?.end()}connectNow(){this.connected=!0,this.deliver(this.fullUpdate())}holdNow(e){return new Promise((t,n)=>{let r=setTimeout(()=>this.pendingHold?.end(),e),i=()=>{clearTimeout(r),this.pendingHold=void 0};this.pendingHold={end:()=>{i(),t(this)},complete:()=>{i(),this.connectNow(),t(this)},fail:()=>{i();let e=this.fatalError();this.emitter.emit(`connectionError`,e),n(e)}}})}failNow(){let e=this.fatalError();return this.emitter.emit(`connectionError`,e),Promise.reject(e)}fatalError(){return new a(`Connection failed with status: 401. Error: the test client failed this initialization. This is an unrecoverable error, will not attempt to reconnect.`,401)}deliverIfConnected(e){this.connected&&this.deliver(e)}deliver(e){if(this.pendingDeliveries.push(e),!this.delivering){this.delivering=!0;try{let e=this.pendingDeliveries.shift();for(;e;)this.emitCaught(e),e=this.pendingDeliveries.shift()}finally{this.delivering=!1}}}emitCaught(e){try{this.emitter.emit(`configBundleReceived`,e)}catch(e){this.logger.error(`[InMemoryConnection] Error dispatching a config update from the test client: `,e)}}fullUpdate(){return{...s,kind:`full`,configs:Object.fromEntries(this.configs)}}encodeAll(e){let t=new Map;for(let[n,r]of Object.entries(e))t.set(n,this.encode(n,r));return t}encode(t,n){return e(`test-config:${t}`,t,n)}},l=class{constructor(e,t){this.client=e,this.connection=t}setValue(e,t){this.connection.setValue(e,t)}removeValue(e){this.connection.removeValue(e)}replaceValues(e){this.connection.replaceValues(e)}holdInitialization(){this.connection.hold()}completeInitialization(){this.connection.complete()}failInitialization(){this.connection.fail()}};const u=(e,i)=>{let a=i?.logger??t(),o=new c(a,i?.values??{});return new l(new r(`test-client`,e,{logger:a,connection:{timeout:i?.timeout}},{transport:o,telemetry:n}),o)},d=e=>u({sdkName:`nextjs-sdk`,sdkVersion:`1.11.0`},e),f=e=>{let t=globalThis.__configDirectorServerClient;return globalThis.__configDirectorServerClient=e.client,()=>{globalThis.__configDirectorServerClient=t}};export{a as ConfigDirectorConnectionError,i as ConfigDirectorValidationError,d as createTestClient,f as installServerTestClient};
2
2
  //# sourceMappingURL=testing.mjs.map