@atono-io/server-sdk 1.4.0-rc.2
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/cjs/index.js +19696 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/package.json +1 -0
- package/dist/esm/index.js +19687 -0
- package/dist/esm/index.js.map +7 -0
- package/dist/esm/package.json +1 -0
- package/dist/types.d.ts +314 -0
- package/package.json +34 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type": "module"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import { Provider } from '@openfeature/server-sdk';
|
|
2
|
+
import { AxiosInstance } from 'axios';
|
|
3
|
+
import { BaseHook, HookContext, EvaluationDetails as EvaluationDetails$1, FlagValue, StandardResolutionReasons, ErrorCode } from '@openfeature/core';
|
|
4
|
+
|
|
5
|
+
type LocationContext$1 = {
|
|
6
|
+
continent: string;
|
|
7
|
+
subcontinent?: string;
|
|
8
|
+
country?: string;
|
|
9
|
+
region?: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
type BaseEvaluationContext = {
|
|
13
|
+
customer?: string;
|
|
14
|
+
};
|
|
15
|
+
type EvaluationContextPart = {
|
|
16
|
+
[key: string]: any;
|
|
17
|
+
};
|
|
18
|
+
type EvaluationContext = BaseEvaluationContext & EvaluationContextPart;
|
|
19
|
+
|
|
20
|
+
declare enum LogLevels {
|
|
21
|
+
DEBUG = "DEBUG",
|
|
22
|
+
ERROR = "ERROR",
|
|
23
|
+
FATAL = "FATAL",
|
|
24
|
+
INFO = "INFO",
|
|
25
|
+
TRACE = "TRACE",
|
|
26
|
+
WARN = "WARN"
|
|
27
|
+
}
|
|
28
|
+
type ConcreteLogger = new (category: string) => Logger;
|
|
29
|
+
type LoggerListener = (entry: StructuredLog) => void;
|
|
30
|
+
type LogElement = Record<string, any> | Error;
|
|
31
|
+
type LoggerConfig = {
|
|
32
|
+
/**
|
|
33
|
+
* Log level threshold to display.
|
|
34
|
+
*
|
|
35
|
+
* Default: 'INFO'
|
|
36
|
+
*/
|
|
37
|
+
level?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Implementation of the logger. This SDK provides two implementations out of the box:
|
|
40
|
+
*
|
|
41
|
+
* - ConsoleLogger: Logs to the console.
|
|
42
|
+
*
|
|
43
|
+
* - NoopLogger: Does not output any log events, but can still be used to listen to structured log events.
|
|
44
|
+
*
|
|
45
|
+
* Default: ConsoleLogger
|
|
46
|
+
*/
|
|
47
|
+
implementation?: ConcreteLogger;
|
|
48
|
+
/**
|
|
49
|
+
* Hook to listen to structured log events. A log event listener is a function that takes a log entry as an
|
|
50
|
+
* argument and returns nothing.
|
|
51
|
+
*
|
|
52
|
+
* See {@link StructuredLog}
|
|
53
|
+
*
|
|
54
|
+
* Default: undefined
|
|
55
|
+
*/
|
|
56
|
+
onLogEvent?: LoggerListener;
|
|
57
|
+
};
|
|
58
|
+
type StructuredLog = Record<string, any> & {
|
|
59
|
+
/**
|
|
60
|
+
* The category of the log indicates it source within the SDK.
|
|
61
|
+
*/
|
|
62
|
+
category: string;
|
|
63
|
+
/**
|
|
64
|
+
* The level of the log.
|
|
65
|
+
*/
|
|
66
|
+
level: LogLevels;
|
|
67
|
+
/**
|
|
68
|
+
* The message of the log.
|
|
69
|
+
*/
|
|
70
|
+
message?: string;
|
|
71
|
+
/**
|
|
72
|
+
* The timestamp when the log was emitted.
|
|
73
|
+
*/
|
|
74
|
+
timestamp: Date;
|
|
75
|
+
};
|
|
76
|
+
declare abstract class Logger {
|
|
77
|
+
protected constructor(category: string);
|
|
78
|
+
protected abstract outputLogEntry(entry: StructuredLog): void;
|
|
79
|
+
static configure(config: LoggerConfig): void;
|
|
80
|
+
static getLogger(category: string): Logger;
|
|
81
|
+
trace(message: any, context?: LogElement): void;
|
|
82
|
+
debug(message: any, context?: LogElement): void;
|
|
83
|
+
info(message: any, context?: LogElement): void;
|
|
84
|
+
warn(message: any, context?: LogElement): void;
|
|
85
|
+
error(message: any, context?: LogElement): void;
|
|
86
|
+
fatal(message: any, context?: LogElement): void;
|
|
87
|
+
}
|
|
88
|
+
declare class NoopLogger extends Logger {
|
|
89
|
+
constructor(category: string);
|
|
90
|
+
protected outputLogEntry(_entry: StructuredLog): void;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
type EvaluationContextParams = {
|
|
94
|
+
[key: string]: any;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* A component that contributes a specific field (or fields) to an evaluation context.
|
|
98
|
+
* Register components with {@link EvaluationContextProvider} at construction time.
|
|
99
|
+
*/
|
|
100
|
+
interface IEvaluationContextProvider<TCtxPart extends EvaluationContextPart = object, TCtxParam extends EvaluationContextParams = object> {
|
|
101
|
+
/**
|
|
102
|
+
* Called during `EvaluationContextProvider.getContext()`. Implementations should
|
|
103
|
+
* mutate `ctx` directly to add their contribution (e.g. `ctx.location = ...`).
|
|
104
|
+
*/
|
|
105
|
+
getContext(params: Partial<TCtxParam>): Promise<Partial<TCtxPart>>;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Assembles a per-request evaluation context from a set of registered components.
|
|
110
|
+
*
|
|
111
|
+
* Usage:
|
|
112
|
+
* ```ts
|
|
113
|
+
* const provider = new EvaluationContextProvider().registerProviderComponent(locationService);
|
|
114
|
+
*
|
|
115
|
+
* const ctx = await provider.getContext({ ip: req.ip, customer: 'cust-123' });
|
|
116
|
+
* const enabled = await featureFlags.getBooleanValue('my-flag', false, ctx);
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
declare class EvaluationContextProvider<TContext extends BaseEvaluationContext = BaseEvaluationContext, TParams extends BaseEvaluationContext = BaseEvaluationContext> implements IEvaluationContextProvider<TContext, TParams> {
|
|
120
|
+
private readonly logger;
|
|
121
|
+
private readonly components;
|
|
122
|
+
constructor(baseProvider: IEvaluationContextProvider<TContext, TParams>);
|
|
123
|
+
/**
|
|
124
|
+
* Resolves a full evaluation context for the given request parameters.
|
|
125
|
+
* Each registered component is given the opportunity to enrich the context.
|
|
126
|
+
* The `ip` field is consumed by components and is not included in the returned context.
|
|
127
|
+
* All other fields in `params` (e.g. `customer`) are included verbatim.
|
|
128
|
+
*/
|
|
129
|
+
getContext(params?: Partial<TParams>): Promise<Partial<TContext>>;
|
|
130
|
+
registerProviderComponent<TCompCtxPart extends EvaluationContextPart, TCompCtxParam extends EvaluationContextParams>(component: IEvaluationContextProvider<TCompCtxPart, TCompCtxParam>): EvaluationContextProvider<Partial<TContext & TCompCtxPart>, Partial<TParams & TCompCtxParam>>;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
interface IClosable {
|
|
134
|
+
close(): void;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
type onUpdateHandler = () => void;
|
|
138
|
+
interface FlagEvaluationReporter extends BaseHook, IClosable {
|
|
139
|
+
startExporter(): void;
|
|
140
|
+
stopExporter(): void;
|
|
141
|
+
updateFlagIdsByKeyMap(flagIdsByKey: Map<string, string>): void;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
type FlagEvaluationReporterConfig = {};
|
|
145
|
+
type EvaluationEvent = {
|
|
146
|
+
timestamp: Date;
|
|
147
|
+
flagId: string;
|
|
148
|
+
outcome: EvaluationDetails$1<FlagValue>;
|
|
149
|
+
context: EvaluationContext;
|
|
150
|
+
};
|
|
151
|
+
declare class FlagEvaluationPublisher implements FlagEvaluationReporter {
|
|
152
|
+
private readonly httpClient;
|
|
153
|
+
private readonly config;
|
|
154
|
+
private readonly logger;
|
|
155
|
+
private evaluationEvents;
|
|
156
|
+
private exporterJob?;
|
|
157
|
+
private ongoingHttpRequest?;
|
|
158
|
+
private flagIdsByKey;
|
|
159
|
+
constructor(httpClient: AxiosInstance, config?: FlagEvaluationReporterConfig);
|
|
160
|
+
after(hookContext: Readonly<HookContext>, evaluationDetails: EvaluationDetails$1<FlagValue>): void;
|
|
161
|
+
startExporter(): void;
|
|
162
|
+
stopExporter(): void;
|
|
163
|
+
updateFlagIdsByKeyMap(flagIdsByKey: Map<string, string>): void;
|
|
164
|
+
close(): void;
|
|
165
|
+
protected exportEvaluationEventsChunk(): Promise<EvaluationEvent[]>;
|
|
166
|
+
protected postMetrics(chunk: EvaluationEvent[]): Promise<void>;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
type PrimitiveValue = null | boolean | string | number;
|
|
170
|
+
type JsonObject = {
|
|
171
|
+
[key: string]: JsonValue;
|
|
172
|
+
};
|
|
173
|
+
type JsonArray = JsonValue[];
|
|
174
|
+
type JsonValue = PrimitiveValue | JsonObject | JsonArray;
|
|
175
|
+
type ResolutionReason = keyof typeof StandardResolutionReasons | (string & Record<never, never>);
|
|
176
|
+
type FlagMetadata = Record<string, string | number | boolean>;
|
|
177
|
+
type ResolutionDetails<U> = {
|
|
178
|
+
value: U;
|
|
179
|
+
variant?: string;
|
|
180
|
+
flagMetadata?: FlagMetadata;
|
|
181
|
+
reason?: ResolutionReason;
|
|
182
|
+
errorCode?: ErrorCode;
|
|
183
|
+
errorMessage?: string;
|
|
184
|
+
};
|
|
185
|
+
type EvaluationDetails<T extends JsonValue> = {
|
|
186
|
+
flagKey: string;
|
|
187
|
+
flagMetadata: Readonly<FlagMetadata>;
|
|
188
|
+
} & ResolutionDetails<T>;
|
|
189
|
+
|
|
190
|
+
interface FeatureFlagsClientAPI {
|
|
191
|
+
getBooleanValue(flagKey: string, defaultValue: boolean, context?: EvaluationContext): Promise<boolean>;
|
|
192
|
+
getBooleanDetails(flagKey: string, defaultValue: boolean, context?: EvaluationContext): Promise<EvaluationDetails<boolean>>;
|
|
193
|
+
registerUpdateListener(handler: onUpdateHandler): void;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
type FeatureFlagsClientConfig = {};
|
|
197
|
+
|
|
198
|
+
type FeatureFlagsPollingProviderConfig = {
|
|
199
|
+
/**
|
|
200
|
+
* Whether the SDK should attempt to regularly poll the Atono service for feature flags definition updates. If this
|
|
201
|
+
* option is disabled, the SDK will still attempt to get an initial set of flag configurations from the Atono
|
|
202
|
+
* service, and will retry until it has successfully retrieved this initial set, but will not attempt to refresh
|
|
203
|
+
* them again.
|
|
204
|
+
*
|
|
205
|
+
* Default: true
|
|
206
|
+
*/
|
|
207
|
+
autoSync?: boolean;
|
|
208
|
+
/**
|
|
209
|
+
* The frequency in milliseconds that the SDK should attempt to regularly poll the Atono service for feature flags
|
|
210
|
+
* definition updates. If `autoSync` is disabled, this option is ignored.
|
|
211
|
+
*
|
|
212
|
+
* Default: 5000
|
|
213
|
+
*/
|
|
214
|
+
syncInterval?: number;
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
type FeatureFlagsConfig = FeatureFlagsClientConfig & FeatureFlagsPollingProviderConfig;
|
|
218
|
+
|
|
219
|
+
type LocationContext = {
|
|
220
|
+
location: LocationContext$1;
|
|
221
|
+
};
|
|
222
|
+
type LocationParams = {
|
|
223
|
+
clientIp: string;
|
|
224
|
+
};
|
|
225
|
+
interface LocationService extends IEvaluationContextProvider<LocationContext, LocationParams> {
|
|
226
|
+
getContext(params: Partial<LocationParams>): Promise<Partial<LocationContext>>;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
declare class NoopLocationService implements LocationService {
|
|
230
|
+
getLocation(_ip?: string): Promise<undefined>;
|
|
231
|
+
getContext: (_param: Partial<LocationParams>) => Promise<{}>;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
interface UsageReporterAPI extends IClosable {
|
|
235
|
+
record(usageKey: string, context?: EvaluationContext): void;
|
|
236
|
+
startPublisher(): void;
|
|
237
|
+
stopPublisher(): void;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
type UsageReporterConfig = {};
|
|
241
|
+
|
|
242
|
+
type SdkConfig = {
|
|
243
|
+
/**
|
|
244
|
+
* Overrides the base URL to the Atono API. This may be used to point the SDK to a local replica of the Atono
|
|
245
|
+
* service for resilience.
|
|
246
|
+
*
|
|
247
|
+
* Default: 'https://api.atono.io'
|
|
248
|
+
*/
|
|
249
|
+
apiBaseUrl?: string;
|
|
250
|
+
/**
|
|
251
|
+
* Configurations for the feature flags module.
|
|
252
|
+
*/
|
|
253
|
+
featureFlags?: FeatureFlagsConfig & {
|
|
254
|
+
/**
|
|
255
|
+
* Whether the SDK should publish flag evaluation events back to Atono. This allows the Atono app to suggest
|
|
256
|
+
* flag slicing values that are based on actual evaluations.
|
|
257
|
+
*
|
|
258
|
+
* Default: true
|
|
259
|
+
*/
|
|
260
|
+
publishEvaluations?: boolean;
|
|
261
|
+
};
|
|
262
|
+
/**
|
|
263
|
+
* Configurations for the HTTP client.
|
|
264
|
+
*/
|
|
265
|
+
httpClient?: {
|
|
266
|
+
/**
|
|
267
|
+
* The number of milliseconds to wait before timing out HTTP requests.
|
|
268
|
+
*
|
|
269
|
+
* Default: 2000
|
|
270
|
+
*/
|
|
271
|
+
timeout?: number;
|
|
272
|
+
};
|
|
273
|
+
/**
|
|
274
|
+
* Configuration for the location service used by the evaluation context provider.
|
|
275
|
+
* Provide a custom implementation class to replace the default IP-based location service.
|
|
276
|
+
*/
|
|
277
|
+
location?: {
|
|
278
|
+
/**
|
|
279
|
+
* Change the implementation of the location service. The location service is used by the
|
|
280
|
+
* evaluation context provider to resolve the user's geographic location from an IP address.
|
|
281
|
+
*
|
|
282
|
+
* This SDK provides two implementations out of the box:
|
|
283
|
+
*
|
|
284
|
+
* - IpBasedLocationService (default): Calls the Atono API with the provided IP to determine location.
|
|
285
|
+
*
|
|
286
|
+
* - NoopLocationService: Disables location resolution. Location-based flag slices will be ignored.
|
|
287
|
+
*/
|
|
288
|
+
implementation?: new (httpClient: AxiosInstance) => LocationService;
|
|
289
|
+
};
|
|
290
|
+
/**
|
|
291
|
+
* Configurations for the SDK logger.
|
|
292
|
+
*/
|
|
293
|
+
log?: LoggerConfig;
|
|
294
|
+
/**
|
|
295
|
+
* Configure the usage module.
|
|
296
|
+
*/
|
|
297
|
+
usage?: UsageReporterConfig;
|
|
298
|
+
};
|
|
299
|
+
declare class Atono {
|
|
300
|
+
static fromEnvironmentKey(environmentKey: string, config?: SdkConfig): Atono;
|
|
301
|
+
getFeatureFlags(): Promise<FeatureFlagsClientAPI>;
|
|
302
|
+
getOpenFeatureProvider(): Promise<Provider>;
|
|
303
|
+
getLocationService(): LocationService;
|
|
304
|
+
getDefaultEvaluationContextProvider(): EvaluationContextProvider<BaseEvaluationContext & LocationContext, BaseEvaluationContext & LocationParams>;
|
|
305
|
+
getUsageReporter(): UsageReporterAPI;
|
|
306
|
+
/**
|
|
307
|
+
* It is important to stop all SDK processes that rely on timers here. Otherwise, they remain
|
|
308
|
+
* in memory and pollute the heap of our client's code.
|
|
309
|
+
*/
|
|
310
|
+
close(): void;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export { Atono, EvaluationContextProvider, FlagEvaluationPublisher, LogLevels, NoopLocationService, NoopLogger };
|
|
314
|
+
export type { BaseEvaluationContext, EvaluationContext, EvaluationContextParams, EvaluationContextPart, EvaluationDetails, FeatureFlagsClientAPI, FeatureFlagsConfig, IEvaluationContextProvider, LocationContext, LoggerConfig, LoggerListener, SdkConfig, StructuredLog, UsageReporterAPI, UsageReporterConfig };
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@atono-io/server-sdk",
|
|
3
|
+
"version": "1.4.0-rc.2",
|
|
4
|
+
"description": "",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
"types": "./dist/types.d.ts",
|
|
8
|
+
"import": "./dist/esm/index.js",
|
|
9
|
+
"require": "./dist/cjs/index.js",
|
|
10
|
+
"default": "./dist/cjs/index.js"
|
|
11
|
+
},
|
|
12
|
+
"types": "./dist/types.d.ts",
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "rm -rf dist && npm run build:commonjs && npm run build:esm && npm run build:rollup-types",
|
|
15
|
+
"build:commonjs": "esbuild src/index.ts --bundle --sourcemap --target=es2022 --platform=node --format=cjs --outfile=./dist/cjs/index.js --analyze && echo '{\"type\": \"commonjs\"}' > dist/cjs/package.json",
|
|
16
|
+
"build:esm": "esbuild src/index.ts --bundle --sourcemap --target=es2022 --platform=node --format=esm --outfile=./dist/esm/index.js --analyze && echo '{\"type\": \"module\"}' > dist/esm/package.json",
|
|
17
|
+
"build:rollup-types": "rollup -c ../../rollup.config.js",
|
|
18
|
+
"package-publish": "npm run build && npm pack && npm publish --access public --tag ${NPM_RELEASE_TAG:-latest}"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [],
|
|
21
|
+
"author": "Atono Inc.",
|
|
22
|
+
"license": "ISC",
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@openfeature/core": "^1.2.0",
|
|
25
|
+
"@openfeature/server-sdk": "1.14.0",
|
|
26
|
+
"@types/object-hash": "^3.0.6",
|
|
27
|
+
"axios": "^1.15.2",
|
|
28
|
+
"json-logic-js": "^2.0.2",
|
|
29
|
+
"object-hash": "^3.0.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/json-logic-js": "^2.0.7"
|
|
33
|
+
}
|
|
34
|
+
}
|