@configdirector/nextjs-sdk 1.9.2 → 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 +7 -15
  13. package/dist/client/testing.d.cts.map +1 -1
  14. package/dist/client/testing.d.mts +7 -15
  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-fL7X5zwg.d.cts → types-2Z0rA7lF.d.cts} +57 -16
  19. package/dist/client/types-2Z0rA7lF.d.cts.map +1 -0
  20. package/dist/client/{types-DA2VZKNX.d.mts → types-6a1uEkD0.d.mts} +57 -16
  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-DnzM2ukj.d.cts → errors-EfmnEmll.d.cts} +130 -47
  26. package/dist/server/errors-EfmnEmll.d.cts.map +1 -0
  27. package/dist/server/{types-qIeNbtNf.d.mts → errors-r1MHQ8L5.d.mts} +130 -47
  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 +8 -26
  41. package/dist/server/testing.d.cts.map +1 -1
  42. package/dist/server/testing.d.mts +8 -26
  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-CDdDsfVQ.mjs +0 -7
  48. package/dist/client/installedTestClient-CDdDsfVQ.mjs.map +0 -1
  49. package/dist/client/installedTestClient-DH7rRR-J.cjs +0 -6
  50. package/dist/client/types-DA2VZKNX.d.mts.map +0 -1
  51. package/dist/client/types-fL7X5zwg.d.cts.map +0 -1
  52. package/dist/server/DefaultConfigDirectorClient-BZwAj0iJ.cjs +0 -5
  53. package/dist/server/DefaultConfigDirectorClient-DyFVzSHP.mjs +0 -6
  54. package/dist/server/DefaultConfigDirectorClient-DyFVzSHP.mjs.map +0 -1
  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-DnzM2ukj.d.cts.map +0 -1
  59. package/dist/server/types-qIeNbtNf.d.mts.map +0 -1
@@ -32,27 +32,40 @@ type ConfigEvaluation = {
32
32
  context?: ConfigDirectorContext;
33
33
  };
34
34
  /**
35
- * The user's context to be sent to ConfigDirector. This context will be used for targeting
36
- * rules evaluation.
35
+ * The context to be sent to ConfigDirector: the user or other entity, such as a device or an
36
+ * organization, that configs are evaluated for. This context will be used for targeting rules
37
+ * evaluation.
37
38
  */
38
39
  type ConfigDirectorContext = {
39
40
  /**
40
- * The user's identifier. This should be a value that uniquely identifies an application
41
- * user.
41
+ * The context's identifier. This should be a value that uniquely identifies the user or other
42
+ * entity among contexts of the same {@link kind}.
42
43
  * In the case of anonymous users, you could generate a UUID or alternatively not provide
43
44
  * the {@link id} and the SDK will generate a random UUID. However, keep in mind that this
44
- * value is used for segmenting users in percentage rollouts, and changes to the {@link id}
45
- * could result in the user being assigned to a different percentile.
45
+ * value is used for segmenting contexts in percentage rollouts, and changes to the {@link id}
46
+ * could result in the context being assigned to a different percentile.
46
47
  */
47
48
  id?: string;
48
49
  /**
49
- * The user's display name. This will be shown in the ConfigDirector dashboard and may be
50
+ * The kind of entity this context represents, such as `user`, `device`, `organization`,
51
+ * `tenant` or `listing`. You can use any other kind that fits your application. A kind has 1
52
+ * to 64 characters, using only lowercase letters (`a`-`z`), digits, `-` and `_`. It is used
53
+ * exactly as given, without trimming or changing its case.
54
+ *
55
+ * A context with an invalid kind is ignored as a whole: the SDK logs an error and evaluates
56
+ * as if no context had been provided.
57
+ *
58
+ * @default "user"
59
+ */
60
+ kind?: string;
61
+ /**
62
+ * The context's display name. This will be shown in the ConfigDirector dashboard and may be
50
63
  * used for targeting rules.
51
64
  */
52
65
  name?: string;
53
66
  /**
54
- * Any arbitrary traits for the current user. They will be shown in the ConfigDirector
55
- * dashboard and may be used for targeting rules.
67
+ * Any arbitrary traits for the context. They will be shown in the ConfigDirector dashboard
68
+ * and may be used for targeting rules.
56
69
  */
57
70
  traits?: {
58
71
  [key: string]: unknown;
@@ -74,9 +87,90 @@ type ConfigDirectorMetaContext = {
74
87
  appVersion?: string;
75
88
  appName?: string;
76
89
  };
77
- type ConnectionMode = "streaming" | "polling";
90
+ type ConnectionMode = "streaming" | "polling" | "offline";
91
+ //#endregion
92
+ //#region ../shared/src/native-values.d.ts
93
+ type NativeJsonValue = boolean | number | string | null | NativeJsonValue[] | {
94
+ [key: string]: NativeJsonValue;
95
+ };
96
+ type NativeValue = boolean | number | string | NativeJsonValue[] | {
97
+ [key: string]: NativeJsonValue;
98
+ };
99
+ type NativeValues = Record<string, NativeValue>;
78
100
  //#endregion
79
101
  //#region ../js-server-sdk/src/types.d.ts
102
+ /**
103
+ * One value an offline client serves for a config key. The config type follows from the value: a
104
+ * boolean, an integral number (`integer`), any other number (`float`), a string, or a plain object
105
+ * or array (`json`).
106
+ */
107
+ type OfflineValue = NativeValue;
108
+ /**
109
+ * The values an offline client serves, keyed by config key. See {@link OfflineValue} for how each
110
+ * value's config type is decided. Every context receives the same value.
111
+ */
112
+ type OfflineValues = NativeValues;
113
+ /**
114
+ * Connection options of the {@link ConfigDirectorClient}
115
+ */
116
+ type ConnectionOptions = {
117
+ /**
118
+ * The connection mode to be used, one of `streaming` (default), `polling` or `offline`.
119
+ * If set to `streaming`, the connection will remain open and receive updates whenever
120
+ * config state is updated on the ConfigDirector dashboard.
121
+ * When set to `polling`, there will be an initial request to retrieve config state during
122
+ * initialization, and additional requests on a `pollingInterval`.
123
+ * When set to `offline`, the client never connects to ConfigDirector and sends nothing: it serves
124
+ * the values read from {@link file} or given in {@link values} to every context, or the in-code
125
+ * default values when neither is given. No SDK key is needed.
126
+ *
127
+ * Defaults to `streaming`
128
+ */
129
+ mode?: ConnectionMode;
130
+ /**
131
+ * The path of a JSON file holding the values to serve in `offline` mode, resolved against the
132
+ * process working directory. The file holds one object with a value per config key, such as
133
+ * `{ "new-checkout": true, "max-items": 20 }`; see {@link OfflineValue} for how the config type
134
+ * of each value is decided. A file that is missing, unreadable, not a JSON object, or holding a
135
+ * value such as `null` makes `initialize` reject with a `ConfigDirectorInitializationError`.
136
+ *
137
+ * Only one of `file` and `values` can be given, and only in `offline` mode; otherwise
138
+ * `initialize` rejects.
139
+ */
140
+ file?: string;
141
+ /**
142
+ * The values to serve in `offline` mode, keyed by config key. A value such as `null` makes
143
+ * `initialize` reject with a `ConfigDirectorInitializationError`.
144
+ *
145
+ * Only one of `file` and `values` can be given, and only in `offline` mode; otherwise
146
+ * `initialize` rejects.
147
+ */
148
+ values?: OfflineValues;
149
+ /**
150
+ * The polling interval in _seconds_ when the `mode` is set to `polling`. This option has no
151
+ * effect in the other modes.
152
+ *
153
+ * Defaults to 300 seconds (5 minutes). The minimum is 60 seconds. A value below the minimum is
154
+ * raised to the minimum and a warning is logged.
155
+ */
156
+ pollingInterval?: number;
157
+ /**
158
+ * The timeout, in milliseconds, to be used in initialization and when updating the context.
159
+ * If streaming is enabled, the operation (initialization or context update) may still succeed
160
+ * after it times out if no unrecoverable errors are encountered (like an invalid SDK key).
161
+ * If streaming is disabled, if the operation times out, it will not be retried. This option has
162
+ * no effect in `offline` mode.
163
+ *
164
+ * Defaults to 3,000 milliseconds (3 seconds)
165
+ */
166
+ timeout?: number;
167
+ /**
168
+ * The base URL to the ConfigDirector SDK server. To be used only when needing to route through a
169
+ * proxy to connect to the ConfigDirector SDK server. Please refer to the docs on how to configure
170
+ * a proxy for the client SDK. This option has no effect in `offline` mode.
171
+ */
172
+ url?: string;
173
+ };
80
174
  /**
81
175
  * Configuration options for the {@link ConfigDirectorClient}
82
176
  */
@@ -88,41 +182,7 @@ type ConfigDirectorClientOptions = {
88
182
  /**
89
183
  * Connection options
90
184
  */
91
- connection?: {
92
- /**
93
- * The connection mode to be used, one of `streaming` (default) or `polling`.
94
- * If set to `streaming`, the connection will remain open and receive updates whenever
95
- * config state is updated on the ConfigDirector dashboard.
96
- * When set to `polling`, there will be an initial request to retrieve config state during
97
- * initialization, and additional requests on a `pollingInterval`.
98
- *
99
- * Defaults to `streaming`
100
- */
101
- mode?: ConnectionMode;
102
- /**
103
- * The polling interval in _seconds_ when the `mode` is set to `polling`. This option has no
104
- * effect when the `mode` is set to `streaming`.
105
- *
106
- * Defaults to 300 seconds (5 minutes). The minimum is 60 seconds. A value below the minimum is
107
- * raised to the minimum and a warning is logged.
108
- */
109
- pollingInterval?: number;
110
- /**
111
- * The timeout, in milliseconds, to be used in initialization and when updating the context.
112
- * If streaming is enabled, the operation (initialization or context update) may still succeed
113
- * after it times out if no unrecoverable errors are encountered (like an invalid SDK key).
114
- * If streaming is disabled, if the operation times out, it will not be retried.
115
- *
116
- * Defaults to 3,000 milliseconds (3 seconds)
117
- */
118
- timeout?: number;
119
- /**
120
- * The base URL to the ConfigDirector SDK server. To be used only when needing to route through a
121
- * proxy to connect to the ConfigDirector SDK server. Please refer to the docs on how to configure
122
- * a proxy for the client SDK.
123
- */
124
- url?: string;
125
- };
185
+ connection?: ConnectionOptions;
126
186
  /**
127
187
  * A logger that implements {@link ConfigDirectorLogger}. It defaults to the ConfigDirector console
128
188
  * logger set to 'warn' level.
@@ -182,6 +242,14 @@ type ConfigDirectorClientOptions = {
182
242
  */
183
243
  hooks?: ClientHooks;
184
244
  };
245
+ /**
246
+ * The options of a client created without an SDK key: the connection mode is `offline`.
247
+ */
248
+ type OfflineClientOptions = ConfigDirectorClientOptions & {
249
+ connection: ConnectionOptions & {
250
+ mode: "offline";
251
+ };
252
+ };
185
253
  type ClientEvents = {
186
254
  configsUpdated: {
187
255
  keys: string[];
@@ -288,5 +356,20 @@ interface ConfigDirectorClient {
288
356
  dispose(): void;
289
357
  }
290
358
  //#endregion
291
- export { ConfigDirectorLogger as a, ConfigEvaluation as c, ConnectionMode as d, ConfigDirectorLogMessageDecorator as i, ConfigState as l, ConfigDirectorClientOptions as n, ConfigDirectorLoggingLevel as o, ConfigDirectorContext as r, ConfigDirectorMetaContext as s, ConfigDirectorClient as t, ConfigValueType as u };
292
- //# sourceMappingURL=types-qIeNbtNf.d.mts.map
359
+ //#region ../shared/src/errors.d.ts
360
+ declare class ConfigDirectorConnectionError extends Error {
361
+ readonly name: string;
362
+ readonly status?: number;
363
+ constructor(message: string, status?: number);
364
+ }
365
+ declare class ConfigDirectorValidationError extends Error {
366
+ readonly name: string;
367
+ constructor(message: string);
368
+ }
369
+ declare class ConfigDirectorInitializationError extends Error {
370
+ readonly name: string;
371
+ constructor(message: string);
372
+ }
373
+ //#endregion
374
+ export { ConfigEvaluation as _, ConfigDirectorClientOptions as a, ConnectionMode as b, OfflineValues as c, NativeValues as d, ConfigDirectorContext as f, ConfigDirectorMetaContext as g, ConfigDirectorLoggingLevel as h, ConfigDirectorClient as i, NativeJsonValue as l, ConfigDirectorLogger as m, ConfigDirectorInitializationError as n, OfflineClientOptions as o, ConfigDirectorLogMessageDecorator as p, ConfigDirectorValidationError as r, OfflineValue as s, ConfigDirectorConnectionError as t, NativeValue as u, ConfigState as v, ConfigValueType as y };
375
+ //# sourceMappingURL=errors-r1MHQ8L5.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-r1MHQ8L5.d.mts","names":[],"sources":["../../../shared/src/types.ts","../../../shared/src/native-values.ts","../../../js-server-sdk/src/types.ts","../../../shared/src/errors.ts"],"mappings":"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"}
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./DefaultConfigDirectorClient-BZwAj0iJ.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-BZwAj0iJ.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.9.2`},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-DnzM2ukj.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;;;KC0FhF,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;;;cCtGf,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-qIeNbtNf.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;;;KC0FhF,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;;;cCtGf,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-DyFVzSHP.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.9.2`},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,QAAe,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}});