@configdirector/nextjs-sdk 1.10.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/index.cjs +1 -1
- package/dist/client/index.d.cts +56 -11
- package/dist/client/index.d.cts.map +1 -1
- package/dist/client/index.d.mts +56 -11
- package/dist/client/index.d.mts.map +1 -1
- package/dist/client/index.mjs +1 -1
- package/dist/client/index.mjs.map +1 -1
- package/dist/client/installedTestClient-DQXrptJI.cjs +6 -0
- package/dist/client/installedTestClient-DbyOjKoY.mjs +7 -0
- package/dist/client/installedTestClient-DbyOjKoY.mjs.map +1 -0
- package/dist/client/testing.cjs +1 -1
- package/dist/client/testing.d.cts +5 -14
- package/dist/client/testing.d.cts.map +1 -1
- package/dist/client/testing.d.mts +5 -14
- package/dist/client/testing.d.mts.map +1 -1
- package/dist/client/testing.mjs +1 -1
- package/dist/client/testing.mjs.map +1 -1
- package/dist/client/{types-De4z0tu4.d.mts → types-Daqe9IQD.d.cts} +31 -7
- package/dist/client/types-Daqe9IQD.d.cts.map +1 -0
- package/dist/client/{types-Cz68hQ6f.d.cts → types-HCeqxOKy.d.mts} +31 -7
- package/dist/client/types-HCeqxOKy.d.mts.map +1 -0
- package/dist/server/DefaultConfigDirectorClient-BplPvnEk.mjs +6 -0
- package/dist/server/DefaultConfigDirectorClient-BplPvnEk.mjs.map +1 -0
- package/dist/server/DefaultConfigDirectorClient-oT53aH0F.cjs +5 -0
- package/dist/server/{types-BBEEMV5Y.d.cts → errors-BLPDhdq2.d.mts} +114 -42
- package/dist/server/errors-BLPDhdq2.d.mts.map +1 -0
- package/dist/server/{types-B_mGbQaa.d.mts → errors-DuJpJeVf.d.cts} +114 -42
- package/dist/server/errors-DuJpJeVf.d.cts.map +1 -0
- package/dist/server/index.cjs +1 -1
- package/dist/server/index.d.cts +54 -9
- package/dist/server/index.d.cts.map +1 -1
- package/dist/server/index.d.mts +54 -9
- package/dist/server/index.d.mts.map +1 -1
- package/dist/server/index.mjs +1 -1
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/native-values-CfqV9hAq.mjs +2 -0
- package/dist/server/native-values-CfqV9hAq.mjs.map +1 -0
- package/dist/server/native-values-UCK4hh1Z.cjs +1 -0
- package/dist/server/testing.cjs +1 -1
- package/dist/server/testing.d.cts +5 -25
- package/dist/server/testing.d.cts.map +1 -1
- package/dist/server/testing.d.mts +5 -25
- package/dist/server/testing.d.mts.map +1 -1
- package/dist/server/testing.mjs +1 -1
- package/dist/server/testing.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/client/installedTestClient-CW29YuQC.cjs +0 -6
- package/dist/client/installedTestClient-CpjJvHZD.mjs +0 -7
- package/dist/client/installedTestClient-CpjJvHZD.mjs.map +0 -1
- package/dist/client/types-Cz68hQ6f.d.cts.map +0 -1
- package/dist/client/types-De4z0tu4.d.mts.map +0 -1
- package/dist/server/DefaultConfigDirectorClient-BTTja_j3.mjs +0 -6
- package/dist/server/DefaultConfigDirectorClient-BTTja_j3.mjs.map +0 -1
- package/dist/server/DefaultConfigDirectorClient-CqXqwNpW.cjs +0 -5
- package/dist/server/errors-BGpFuqOO.mjs +0 -2
- package/dist/server/errors-BGpFuqOO.mjs.map +0 -1
- package/dist/server/errors-CCbuIqT8.cjs +0 -1
- package/dist/server/types-BBEEMV5Y.d.cts.map +0 -1
- package/dist/server/types-B_mGbQaa.d.mts.map +0 -1
|
@@ -22,7 +22,7 @@ interface ConfigDirectorLogger {
|
|
|
22
22
|
interface ConfigDirectorLogMessageDecorator {
|
|
23
23
|
decorateMessage(message: string): string;
|
|
24
24
|
}
|
|
25
|
-
type EvaluationReason = "found-match" | "config-state-missing" | "client-not-ready" | "type-mismatch" | "value-missing" | "invalid-number" | "invalid-json" | "invalid-boolean";
|
|
25
|
+
type EvaluationReason = "found-match" | "config-state-missing" | "client-not-ready" | "type-mismatch" | "value-missing" | "invalid-number" | "invalid-json" | "invalid-boolean" | "cached";
|
|
26
26
|
type ConfigEvaluation = {
|
|
27
27
|
key: string;
|
|
28
28
|
value: ConfigValueType;
|
|
@@ -41,9 +41,11 @@ type ConfigDirectorContext = {
|
|
|
41
41
|
* The context's identifier. This should be a value that uniquely identifies the user or other
|
|
42
42
|
* entity among contexts of the same {@link kind}.
|
|
43
43
|
* In the case of anonymous users, you could generate a UUID or alternatively not provide
|
|
44
|
-
* the {@link id}
|
|
45
|
-
*
|
|
46
|
-
*
|
|
44
|
+
* the {@link id}. In a client SDK, ConfigDirector then derives an identifier from an ID the SDK
|
|
45
|
+
* stores for the app install or the website, so it stays the same until the app is uninstalled
|
|
46
|
+
* or the site's data is cleared. However, keep in mind that this value is used for segmenting
|
|
47
|
+
* contexts in percentage rollouts, and changes to the {@link id} could result in the context
|
|
48
|
+
* being assigned to a different percentile.
|
|
47
49
|
*/
|
|
48
50
|
id?: string;
|
|
49
51
|
/**
|
|
@@ -87,9 +89,90 @@ type ConfigDirectorMetaContext = {
|
|
|
87
89
|
appVersion?: string;
|
|
88
90
|
appName?: string;
|
|
89
91
|
};
|
|
90
|
-
type ConnectionMode = "streaming" | "polling";
|
|
92
|
+
type ConnectionMode = "streaming" | "polling" | "offline";
|
|
93
|
+
//#endregion
|
|
94
|
+
//#region ../shared/src/native-values.d.ts
|
|
95
|
+
type NativeJsonValue = boolean | number | string | null | NativeJsonValue[] | {
|
|
96
|
+
[key: string]: NativeJsonValue;
|
|
97
|
+
};
|
|
98
|
+
type NativeValue = boolean | number | string | NativeJsonValue[] | {
|
|
99
|
+
[key: string]: NativeJsonValue;
|
|
100
|
+
};
|
|
101
|
+
type NativeValues = Record<string, NativeValue>;
|
|
91
102
|
//#endregion
|
|
92
103
|
//#region ../js-server-sdk/src/types.d.ts
|
|
104
|
+
/**
|
|
105
|
+
* One value an offline client serves for a config key. The config type follows from the value: a
|
|
106
|
+
* boolean, an integral number (`integer`), any other number (`float`), a string, or a plain object
|
|
107
|
+
* or array (`json`).
|
|
108
|
+
*/
|
|
109
|
+
type OfflineValue = NativeValue;
|
|
110
|
+
/**
|
|
111
|
+
* The values an offline client serves, keyed by config key. See {@link OfflineValue} for how each
|
|
112
|
+
* value's config type is decided. Every context receives the same value.
|
|
113
|
+
*/
|
|
114
|
+
type OfflineValues = NativeValues;
|
|
115
|
+
/**
|
|
116
|
+
* Connection options of the {@link ConfigDirectorClient}
|
|
117
|
+
*/
|
|
118
|
+
type ConnectionOptions = {
|
|
119
|
+
/**
|
|
120
|
+
* The connection mode to be used, one of `streaming` (default), `polling` or `offline`.
|
|
121
|
+
* If set to `streaming`, the connection will remain open and receive updates whenever
|
|
122
|
+
* config state is updated on the ConfigDirector dashboard.
|
|
123
|
+
* When set to `polling`, there will be an initial request to retrieve config state during
|
|
124
|
+
* initialization, and additional requests on a `pollingInterval`.
|
|
125
|
+
* When set to `offline`, the client never connects to ConfigDirector and sends nothing: it serves
|
|
126
|
+
* the values read from {@link file} or given in {@link values} to every context, or the in-code
|
|
127
|
+
* default values when neither is given. No SDK key is needed.
|
|
128
|
+
*
|
|
129
|
+
* Defaults to `streaming`
|
|
130
|
+
*/
|
|
131
|
+
mode?: ConnectionMode;
|
|
132
|
+
/**
|
|
133
|
+
* The path of a JSON file holding the values to serve in `offline` mode, resolved against the
|
|
134
|
+
* process working directory. The file holds one object with a value per config key, such as
|
|
135
|
+
* `{ "new-checkout": true, "max-items": 20 }`; see {@link OfflineValue} for how the config type
|
|
136
|
+
* of each value is decided. A file that is missing, unreadable, not a JSON object, or holding a
|
|
137
|
+
* value such as `null` makes `initialize` reject with a `ConfigDirectorInitializationError`.
|
|
138
|
+
*
|
|
139
|
+
* Only one of `file` and `values` can be given, and only in `offline` mode; otherwise
|
|
140
|
+
* `initialize` rejects.
|
|
141
|
+
*/
|
|
142
|
+
file?: string;
|
|
143
|
+
/**
|
|
144
|
+
* The values to serve in `offline` mode, keyed by config key. A value such as `null` makes
|
|
145
|
+
* `initialize` reject with a `ConfigDirectorInitializationError`.
|
|
146
|
+
*
|
|
147
|
+
* Only one of `file` and `values` can be given, and only in `offline` mode; otherwise
|
|
148
|
+
* `initialize` rejects.
|
|
149
|
+
*/
|
|
150
|
+
values?: OfflineValues;
|
|
151
|
+
/**
|
|
152
|
+
* The polling interval in _seconds_ when the `mode` is set to `polling`. This option has no
|
|
153
|
+
* effect in the other modes.
|
|
154
|
+
*
|
|
155
|
+
* Defaults to 300 seconds (5 minutes). The minimum is 60 seconds. A value below the minimum is
|
|
156
|
+
* raised to the minimum and a warning is logged.
|
|
157
|
+
*/
|
|
158
|
+
pollingInterval?: number;
|
|
159
|
+
/**
|
|
160
|
+
* The timeout, in milliseconds, to be used in initialization and when updating the context.
|
|
161
|
+
* If streaming is enabled, the operation (initialization or context update) may still succeed
|
|
162
|
+
* after it times out if no unrecoverable errors are encountered (like an invalid SDK key).
|
|
163
|
+
* If streaming is disabled, if the operation times out, it will not be retried. This option has
|
|
164
|
+
* no effect in `offline` mode.
|
|
165
|
+
*
|
|
166
|
+
* Defaults to 3,000 milliseconds (3 seconds)
|
|
167
|
+
*/
|
|
168
|
+
timeout?: number;
|
|
169
|
+
/**
|
|
170
|
+
* The base URL to the ConfigDirector SDK server. To be used only when needing to route through a
|
|
171
|
+
* proxy to connect to the ConfigDirector SDK server. Please refer to the docs on how to configure
|
|
172
|
+
* a proxy for the client SDK. This option has no effect in `offline` mode.
|
|
173
|
+
*/
|
|
174
|
+
url?: string;
|
|
175
|
+
};
|
|
93
176
|
/**
|
|
94
177
|
* Configuration options for the {@link ConfigDirectorClient}
|
|
95
178
|
*/
|
|
@@ -101,41 +184,7 @@ type ConfigDirectorClientOptions = {
|
|
|
101
184
|
/**
|
|
102
185
|
* Connection options
|
|
103
186
|
*/
|
|
104
|
-
connection?:
|
|
105
|
-
/**
|
|
106
|
-
* The connection mode to be used, one of `streaming` (default) or `polling`.
|
|
107
|
-
* If set to `streaming`, the connection will remain open and receive updates whenever
|
|
108
|
-
* config state is updated on the ConfigDirector dashboard.
|
|
109
|
-
* When set to `polling`, there will be an initial request to retrieve config state during
|
|
110
|
-
* initialization, and additional requests on a `pollingInterval`.
|
|
111
|
-
*
|
|
112
|
-
* Defaults to `streaming`
|
|
113
|
-
*/
|
|
114
|
-
mode?: ConnectionMode;
|
|
115
|
-
/**
|
|
116
|
-
* The polling interval in _seconds_ when the `mode` is set to `polling`. This option has no
|
|
117
|
-
* effect when the `mode` is set to `streaming`.
|
|
118
|
-
*
|
|
119
|
-
* Defaults to 300 seconds (5 minutes). The minimum is 60 seconds. A value below the minimum is
|
|
120
|
-
* raised to the minimum and a warning is logged.
|
|
121
|
-
*/
|
|
122
|
-
pollingInterval?: number;
|
|
123
|
-
/**
|
|
124
|
-
* The timeout, in milliseconds, to be used in initialization and when updating the context.
|
|
125
|
-
* If streaming is enabled, the operation (initialization or context update) may still succeed
|
|
126
|
-
* after it times out if no unrecoverable errors are encountered (like an invalid SDK key).
|
|
127
|
-
* If streaming is disabled, if the operation times out, it will not be retried.
|
|
128
|
-
*
|
|
129
|
-
* Defaults to 3,000 milliseconds (3 seconds)
|
|
130
|
-
*/
|
|
131
|
-
timeout?: number;
|
|
132
|
-
/**
|
|
133
|
-
* The base URL to the ConfigDirector SDK server. To be used only when needing to route through a
|
|
134
|
-
* proxy to connect to the ConfigDirector SDK server. Please refer to the docs on how to configure
|
|
135
|
-
* a proxy for the client SDK.
|
|
136
|
-
*/
|
|
137
|
-
url?: string;
|
|
138
|
-
};
|
|
187
|
+
connection?: ConnectionOptions;
|
|
139
188
|
/**
|
|
140
189
|
* A logger that implements {@link ConfigDirectorLogger}. It defaults to the ConfigDirector console
|
|
141
190
|
* logger set to 'warn' level.
|
|
@@ -195,6 +244,14 @@ type ConfigDirectorClientOptions = {
|
|
|
195
244
|
*/
|
|
196
245
|
hooks?: ClientHooks;
|
|
197
246
|
};
|
|
247
|
+
/**
|
|
248
|
+
* The options of a client created without an SDK key: the connection mode is `offline`.
|
|
249
|
+
*/
|
|
250
|
+
type OfflineClientOptions = ConfigDirectorClientOptions & {
|
|
251
|
+
connection: ConnectionOptions & {
|
|
252
|
+
mode: "offline";
|
|
253
|
+
};
|
|
254
|
+
};
|
|
198
255
|
type ClientEvents = {
|
|
199
256
|
configsUpdated: {
|
|
200
257
|
keys: string[];
|
|
@@ -301,5 +358,20 @@ interface ConfigDirectorClient {
|
|
|
301
358
|
dispose(): void;
|
|
302
359
|
}
|
|
303
360
|
//#endregion
|
|
304
|
-
|
|
305
|
-
|
|
361
|
+
//#region ../shared/src/errors.d.ts
|
|
362
|
+
declare class ConfigDirectorConnectionError extends Error {
|
|
363
|
+
readonly name: string;
|
|
364
|
+
readonly status?: number;
|
|
365
|
+
constructor(message: string, status?: number);
|
|
366
|
+
}
|
|
367
|
+
declare class ConfigDirectorValidationError extends Error {
|
|
368
|
+
readonly name: string;
|
|
369
|
+
constructor(message: string);
|
|
370
|
+
}
|
|
371
|
+
declare class ConfigDirectorInitializationError extends Error {
|
|
372
|
+
readonly name: string;
|
|
373
|
+
constructor(message: string);
|
|
374
|
+
}
|
|
375
|
+
//#endregion
|
|
376
|
+
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 };
|
|
377
|
+
//# sourceMappingURL=errors-DuJpJeVf.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors-DuJpJeVf.d.cts","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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"}
|
package/dist/server/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./DefaultConfigDirectorClient-
|
|
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.12.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;
|
package/dist/server/index.d.cts
CHANGED
|
@@ -1,22 +1,30 @@
|
|
|
1
|
-
import { a as
|
|
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-DuJpJeVf.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
|
-
|
|
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,12 +75,18 @@ 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">[];
|
|
64
86
|
contextUpdated?: HookHandler<"contextUpdated"> | HookHandler<"contextUpdated">[];
|
|
65
87
|
configEvaluated?: HookHandler<"configEvaluated"> | HookHandler<"configEvaluated">[];
|
|
66
88
|
connectionError?: HookHandler<"connectionError"> | HookHandler<"connectionError">[];
|
|
89
|
+
cachedValuesLoaded?: HookHandler<"cachedValuesLoaded"> | HookHandler<"cachedValuesLoaded">[];
|
|
67
90
|
};
|
|
68
91
|
type ClientConnectAction = "initialization" | "context update" | "network resume";
|
|
69
92
|
type HookHandler<TEvent extends keyof ClientEvents> = (payload: ClientEvents[TEvent]) => void;
|
|
@@ -84,6 +107,7 @@ type ClientEvents = {
|
|
|
84
107
|
connectionError: {
|
|
85
108
|
error: Error;
|
|
86
109
|
};
|
|
110
|
+
cachedValuesLoaded: Record<string, never>;
|
|
87
111
|
};
|
|
88
112
|
//#endregion
|
|
89
113
|
//#region ../shared/src/logger.d.ts
|
|
@@ -102,9 +126,10 @@ declare class DefaultConsoleLogger implements ConfigDirectorLogger {
|
|
|
102
126
|
//#region src/client/types.d.ts
|
|
103
127
|
type ConfigDirectorProviderOptions = {
|
|
104
128
|
/**
|
|
105
|
-
* Your ConfigDirector Client SDK key. This is a public value safe for the browser.
|
|
129
|
+
* Your ConfigDirector Client SDK key. This is a public value safe for the browser. Required
|
|
130
|
+
* unless `mode` is `offline`.
|
|
106
131
|
*/
|
|
107
|
-
sdkKey
|
|
132
|
+
sdkKey?: string;
|
|
108
133
|
appName?: string;
|
|
109
134
|
appVersion?: string;
|
|
110
135
|
/**
|
|
@@ -116,11 +141,23 @@ type ConfigDirectorProviderOptions = {
|
|
|
116
141
|
*/
|
|
117
142
|
timeout?: number;
|
|
118
143
|
/**
|
|
119
|
-
* The connection mode, one of `streaming` or `
|
|
120
|
-
* open and receives config updates as they happen. In `polling` mode configs are fetched once
|
|
121
|
-
* initialization and then again on every `pollingInterval`.
|
|
144
|
+
* The connection mode, one of `streaming`, `polling` or `offline`. In `streaming` mode the connection
|
|
145
|
+
* stays open and receives config updates as they happen. In `polling` mode configs are fetched once
|
|
146
|
+
* during initialization and then again on every `pollingInterval`. In `offline` mode the browser
|
|
147
|
+
* client never connects to ConfigDirector and sends nothing: it serves `values` to every context,
|
|
148
|
+
* or the in-code default values when none are given, and needs no `sdkKey`. Defaults to `streaming`.
|
|
149
|
+
*
|
|
150
|
+
* The server `ConfigDirectorProvider` sets `offline` and `values` for you when `register()` ran in
|
|
151
|
+
* `offline` mode and you give neither prop.
|
|
122
152
|
*/
|
|
123
153
|
mode?: ConnectionMode;
|
|
154
|
+
/**
|
|
155
|
+
* The values to serve in `offline` mode, keyed by config key. The config type of each value follows
|
|
156
|
+
* from the value: a boolean, an integral number (`integer`), any other number (`float`), a string, or
|
|
157
|
+
* a plain object or array (`json`). Can be given only in `offline` mode; otherwise the client fails
|
|
158
|
+
* to initialize.
|
|
159
|
+
*/
|
|
160
|
+
values?: OfflineValues$1;
|
|
124
161
|
/**
|
|
125
162
|
* The polling interval in seconds when `mode` is `polling`. Has no effect in `streaming` mode.
|
|
126
163
|
* Defaults to 60 seconds. A value below the minimum of 30 seconds is raised to 30 seconds and a
|
|
@@ -131,6 +168,14 @@ type ConfigDirectorProviderOptions = {
|
|
|
131
168
|
* Initial user context to evaluate targeting rules against.
|
|
132
169
|
*/
|
|
133
170
|
context?: ConfigDirectorContext;
|
|
171
|
+
/**
|
|
172
|
+
* Holds the browser connection until the provider is given a context, through the `context` prop
|
|
173
|
+
* or through `updateContext` from the `useContext` hook. Until then nothing connects and nothing is
|
|
174
|
+
* sent, `useConfigDirectorStatus` reports `loading`, and the hooks serve `initialConfigs` or the
|
|
175
|
+
* in-code default values. The first context opens one connection carrying it; a page that never
|
|
176
|
+
* gives a context never connects. Defaults to `false`. Has no effect in `offline` mode.
|
|
177
|
+
*/
|
|
178
|
+
deferInitialization?: boolean;
|
|
134
179
|
/**
|
|
135
180
|
* Log level for the console logger. Defaults to "warn".
|
|
136
181
|
*/
|
|
@@ -228,5 +273,5 @@ declare function ConfigDirectorProvider({
|
|
|
228
273
|
//#region src/server/logger.d.ts
|
|
229
274
|
declare const createConsoleLogger: (level: ConfigDirectorLoggingLevel, messageDecorator?: ConfigDirectorLogMessageDecorator) => DefaultConsoleLogger;
|
|
230
275
|
//#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 };
|
|
276
|
+
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
277
|
//# 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":";;;;;
|
|
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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"}
|
package/dist/server/index.d.mts
CHANGED
|
@@ -1,22 +1,30 @@
|
|
|
1
|
-
import { a as
|
|
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-BLPDhdq2.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
|
-
|
|
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,12 +75,18 @@ 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">[];
|
|
64
86
|
contextUpdated?: HookHandler<"contextUpdated"> | HookHandler<"contextUpdated">[];
|
|
65
87
|
configEvaluated?: HookHandler<"configEvaluated"> | HookHandler<"configEvaluated">[];
|
|
66
88
|
connectionError?: HookHandler<"connectionError"> | HookHandler<"connectionError">[];
|
|
89
|
+
cachedValuesLoaded?: HookHandler<"cachedValuesLoaded"> | HookHandler<"cachedValuesLoaded">[];
|
|
67
90
|
};
|
|
68
91
|
type ClientConnectAction = "initialization" | "context update" | "network resume";
|
|
69
92
|
type HookHandler<TEvent extends keyof ClientEvents> = (payload: ClientEvents[TEvent]) => void;
|
|
@@ -84,6 +107,7 @@ type ClientEvents = {
|
|
|
84
107
|
connectionError: {
|
|
85
108
|
error: Error;
|
|
86
109
|
};
|
|
110
|
+
cachedValuesLoaded: Record<string, never>;
|
|
87
111
|
};
|
|
88
112
|
//#endregion
|
|
89
113
|
//#region ../shared/src/logger.d.ts
|
|
@@ -102,9 +126,10 @@ declare class DefaultConsoleLogger implements ConfigDirectorLogger {
|
|
|
102
126
|
//#region src/client/types.d.ts
|
|
103
127
|
type ConfigDirectorProviderOptions = {
|
|
104
128
|
/**
|
|
105
|
-
* Your ConfigDirector Client SDK key. This is a public value safe for the browser.
|
|
129
|
+
* Your ConfigDirector Client SDK key. This is a public value safe for the browser. Required
|
|
130
|
+
* unless `mode` is `offline`.
|
|
106
131
|
*/
|
|
107
|
-
sdkKey
|
|
132
|
+
sdkKey?: string;
|
|
108
133
|
appName?: string;
|
|
109
134
|
appVersion?: string;
|
|
110
135
|
/**
|
|
@@ -116,11 +141,23 @@ type ConfigDirectorProviderOptions = {
|
|
|
116
141
|
*/
|
|
117
142
|
timeout?: number;
|
|
118
143
|
/**
|
|
119
|
-
* The connection mode, one of `streaming` or `
|
|
120
|
-
* open and receives config updates as they happen. In `polling` mode configs are fetched once
|
|
121
|
-
* initialization and then again on every `pollingInterval`.
|
|
144
|
+
* The connection mode, one of `streaming`, `polling` or `offline`. In `streaming` mode the connection
|
|
145
|
+
* stays open and receives config updates as they happen. In `polling` mode configs are fetched once
|
|
146
|
+
* during initialization and then again on every `pollingInterval`. In `offline` mode the browser
|
|
147
|
+
* client never connects to ConfigDirector and sends nothing: it serves `values` to every context,
|
|
148
|
+
* or the in-code default values when none are given, and needs no `sdkKey`. Defaults to `streaming`.
|
|
149
|
+
*
|
|
150
|
+
* The server `ConfigDirectorProvider` sets `offline` and `values` for you when `register()` ran in
|
|
151
|
+
* `offline` mode and you give neither prop.
|
|
122
152
|
*/
|
|
123
153
|
mode?: ConnectionMode;
|
|
154
|
+
/**
|
|
155
|
+
* The values to serve in `offline` mode, keyed by config key. The config type of each value follows
|
|
156
|
+
* from the value: a boolean, an integral number (`integer`), any other number (`float`), a string, or
|
|
157
|
+
* a plain object or array (`json`). Can be given only in `offline` mode; otherwise the client fails
|
|
158
|
+
* to initialize.
|
|
159
|
+
*/
|
|
160
|
+
values?: OfflineValues$1;
|
|
124
161
|
/**
|
|
125
162
|
* The polling interval in seconds when `mode` is `polling`. Has no effect in `streaming` mode.
|
|
126
163
|
* Defaults to 60 seconds. A value below the minimum of 30 seconds is raised to 30 seconds and a
|
|
@@ -131,6 +168,14 @@ type ConfigDirectorProviderOptions = {
|
|
|
131
168
|
* Initial user context to evaluate targeting rules against.
|
|
132
169
|
*/
|
|
133
170
|
context?: ConfigDirectorContext;
|
|
171
|
+
/**
|
|
172
|
+
* Holds the browser connection until the provider is given a context, through the `context` prop
|
|
173
|
+
* or through `updateContext` from the `useContext` hook. Until then nothing connects and nothing is
|
|
174
|
+
* sent, `useConfigDirectorStatus` reports `loading`, and the hooks serve `initialConfigs` or the
|
|
175
|
+
* in-code default values. The first context opens one connection carrying it; a page that never
|
|
176
|
+
* gives a context never connects. Defaults to `false`. Has no effect in `offline` mode.
|
|
177
|
+
*/
|
|
178
|
+
deferInitialization?: boolean;
|
|
134
179
|
/**
|
|
135
180
|
* Log level for the console logger. Defaults to "warn".
|
|
136
181
|
*/
|
|
@@ -228,5 +273,5 @@ declare function ConfigDirectorProvider({
|
|
|
228
273
|
//#region src/server/logger.d.ts
|
|
229
274
|
declare const createConsoleLogger: (level: ConfigDirectorLoggingLevel, messageDecorator?: ConfigDirectorLogMessageDecorator) => DefaultConsoleLogger;
|
|
230
275
|
//#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 };
|
|
276
|
+
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
277
|
//# 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":";;;;;
|
|
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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"}
|
package/dist/server/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{i as e,
|
|
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.12.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
|