@openfeature/flagd-provider 0.4.0 → 0.5.1
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/README.md +32 -16
- package/index.cjs +10 -14
- package/index.js +10 -11
- package/lib/configuration.d.ts +33 -0
- package/lib/flagd-provider.d.ts +10 -13
- package/lib/service/grpc/service.d.ts +17 -12
- package/lib/service/service.d.ts +7 -0
- package/package.json +2 -3
- package/lib/service/Service.d.ts +0 -7
- package/lib/service/http/service.d.ts +0 -16
package/README.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Server-side JavaScript flagd Provider for OpenFeature
|
|
2
2
|
|
|
3
3
|

|
|
4
4
|
|
|
5
|
-
Flagd is a simple
|
|
5
|
+
Flagd is a simple daemon for evaluating feature flags.
|
|
6
|
+
It is designed to conform to OpenFeature schema for flag definitions.
|
|
7
|
+
This repository and package provides the client code for interacting with it via the OpenFeature server-side JavaScript SDK.
|
|
6
8
|
|
|
7
9
|
## Installation
|
|
8
10
|
|
|
@@ -10,29 +12,43 @@ Flagd is a simple command line tool for fetching and presenting feature flags to
|
|
|
10
12
|
$ npm install @openfeature/flagd-provider
|
|
11
13
|
```
|
|
12
14
|
|
|
13
|
-
##
|
|
14
|
-
|
|
15
|
-
Run `nx package providers-flagd` to build the library.
|
|
16
|
-
|
|
17
|
-
> NOTE: [Buf](https://docs.buf.build/installation) must be installed to build locally.
|
|
15
|
+
## Usage
|
|
18
16
|
|
|
19
|
-
|
|
17
|
+
The `FlagdProvider` supports multiple configuration options that determine now the SDK communicates with flagd.
|
|
18
|
+
Options can be defined in the constructor or as environment variables, with constructor options having the highest precedence.
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
### Available options
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
| Option name | Environment variable name | Type | Default |
|
|
23
|
+
| ----------- | ------------------------- | ------- | --------- |
|
|
24
|
+
| host | FLAGD_HOST | string | localhost |
|
|
25
|
+
| port | FLAGD_PORT | number | 8013 |
|
|
26
|
+
| tls | FLAGD_TLS | boolean | false |
|
|
27
|
+
| socketPath | FLAGD_SOCKET_PATH | string | - |
|
|
24
28
|
|
|
25
|
-
|
|
29
|
+
### Example using TCP
|
|
26
30
|
|
|
27
31
|
```
|
|
28
32
|
OpenFeature.setProvider(new FlagdProvider({
|
|
29
|
-
service: 'grpc',
|
|
30
33
|
host: 'localhost',
|
|
31
34
|
port: 8013,
|
|
32
35
|
}))
|
|
33
36
|
```
|
|
34
37
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
### Example using a Unix socket
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
OpenFeature.setProvider(new FlagdProvider({
|
|
42
|
+
socketPath: "/tmp/flagd.socks",
|
|
43
|
+
}))
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Building
|
|
47
|
+
|
|
48
|
+
Run `nx package providers-flagd` to build the library.
|
|
49
|
+
|
|
50
|
+
> NOTE: [Buf](https://docs.buf.build/installation) must be installed to build locally.
|
|
51
|
+
|
|
52
|
+
## Running unit tests
|
|
53
|
+
|
|
54
|
+
Run `nx test providers-flagd` to execute the unit tests via [Jest](https://jestjs.io).
|
package/index.cjs
CHANGED
|
@@ -2,12 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var nodejsSdk = require('@openfeature/nodejs-sdk');
|
|
6
|
-
var axios = require('axios');
|
|
7
|
-
var grpcTransport = require('@protobuf-ts/grpc-transport');
|
|
8
5
|
var grpc = require('@grpc/grpc-js');
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
var jsSdk = require('@openfeature/js-sdk');
|
|
7
|
+
var grpcTransport = require('@protobuf-ts/grpc-transport');
|
|
11
8
|
|
|
12
9
|
function _interopNamespace(e) {
|
|
13
10
|
if (e && e.__esModule) return e;
|
|
@@ -27,7 +24,6 @@ function _interopNamespace(e) {
|
|
|
27
24
|
return Object.freeze(n);
|
|
28
25
|
}
|
|
29
26
|
|
|
30
|
-
var axios__default = /*#__PURE__*/_interopDefaultLegacy(axios);
|
|
31
27
|
var grpc__namespace = /*#__PURE__*/_interopNamespace(grpc);
|
|
32
28
|
|
|
33
29
|
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
@@ -198,9 +194,9 @@ var engineUserAgent = getBuiltIn$3('navigator', 'userAgent') || '';
|
|
|
198
194
|
var global$a = global$c;
|
|
199
195
|
var userAgent = engineUserAgent;
|
|
200
196
|
|
|
201
|
-
var process = global$a.process;
|
|
197
|
+
var process$1 = global$a.process;
|
|
202
198
|
var Deno = global$a.Deno;
|
|
203
|
-
var versions = process && process.versions || Deno && Deno.version;
|
|
199
|
+
var versions = process$1 && process$1.versions || Deno && Deno.version;
|
|
204
200
|
var v8 = versions && versions.v8;
|
|
205
201
|
var match, version;
|
|
206
202
|
|
|
@@ -1078,6 +1074,8 @@ $$2({ target: 'Object', stat: true, arity: 2, forced: Object.assign !== assign }
|
|
|
1078
1074
|
assign: assign
|
|
1079
1075
|
});
|
|
1080
1076
|
|
|
1077
|
+
const DEFAULT_CONFIG={host:"localhost",port:8013,tls:!1};var ENV_VAR;(function(a){a.FLAGD_HOST="FLAGD_HOST",a.FLAGD_PORT="FLAGD_PORT",a.FLAGD_TLS="FLAGD_TLS",a.FLAGD_SOCKET_PATH="FLAGD_SOCKET_PATH";})(ENV_VAR||(ENV_VAR={}));const getEnvVarConfig=()=>{var a;return Object.assign(Object.assign(Object.assign(Object.assign({},process.env[ENV_VAR.FLAGD_HOST]&&{host:process.env[ENV_VAR.FLAGD_HOST]}),+process.env[ENV_VAR.FLAGD_PORT]&&{port:+process.env[ENV_VAR.FLAGD_PORT]}),process.env[ENV_VAR.FLAGD_TLS]&&{tls:"true"===(null===(a=process.env[ENV_VAR.FLAGD_TLS])||void 0===a?void 0:a.toLowerCase())}),process.env[ENV_VAR.FLAGD_SOCKET_PATH]&&{socketPath:process.env[ENV_VAR.FLAGD_SOCKET_PATH]})};function getConfig(a={}){return Object.assign(Object.assign(Object.assign({},DEFAULT_CONFIG),getEnvVarConfig()),a)}
|
|
1078
|
+
|
|
1081
1079
|
/******************************************************************************
|
|
1082
1080
|
Copyright (c) Microsoft Corporation.
|
|
1083
1081
|
|
|
@@ -1103,10 +1101,6 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
1103
1101
|
});
|
|
1104
1102
|
}
|
|
1105
1103
|
|
|
1106
|
-
class HTTPService{constructor(a){this.url=`${a.protocol}://${a.host}:${a.port}`;}resolveBoolean(a,b,c){return __awaiter(this,void 0,void 0,function*(){try{const d=yield axios__default["default"].post(`${this.url}/flags/${encodeURIComponent(a)}/resolve/boolean`,c);return checkResponse(d,"boolean")?{value:d.data.value,reason:d.data.reason,variant:d.data.variant}:{value:b,reason:nodejsSdk.StandardResolutionReasons.ERROR,errorCode:nodejsSdk.ErrorCode.PARSE_ERROR}}catch(a){return {reason:nodejsSdk.StandardResolutionReasons.ERROR,errorCode:getErrorCode(a),value:b}}})}resolveNumber(a,b,c){return __awaiter(this,void 0,void 0,function*(){try{const d=yield axios__default["default"].post(/**
|
|
1107
|
-
* JavaScript numbers are always 64-bit floating point
|
|
1108
|
-
*/`${this.url}/flags/${encodeURIComponent(a)}/resolve/float`,c);return checkResponse(d,"number")?{value:d.data.value,reason:d.data.reason,variant:d.data.variant}:{value:b,reason:nodejsSdk.StandardResolutionReasons.ERROR,errorCode:nodejsSdk.ErrorCode.PARSE_ERROR}}catch(a){return {reason:nodejsSdk.StandardResolutionReasons.ERROR,errorCode:getErrorCode(a),value:b}}})}resolveString(a,b,c){return __awaiter(this,void 0,void 0,function*(){try{const d=yield axios__default["default"].post(`${this.url}/flags/${encodeURIComponent(a)}/resolve/string`,c);return checkResponse(d,"string")?{value:d.data.value,reason:d.data.reason,variant:d.data.variant}:{value:b,reason:nodejsSdk.StandardResolutionReasons.ERROR,errorCode:nodejsSdk.ErrorCode.PARSE_ERROR}}catch(a){return {reason:nodejsSdk.StandardResolutionReasons.ERROR,errorCode:getErrorCode(a),value:b}}})}resolveObject(a,b,c){return __awaiter(this,void 0,void 0,function*(){try{const d=yield axios__default["default"].post(`${this.url}/flags/${encodeURIComponent(a)}/resolve/object`,c);return checkResponse(d,"object")?{value:d.data.value,reason:d.data.reason,variant:d.data.variant}:{value:b,reason:nodejsSdk.StandardResolutionReasons.ERROR,errorCode:nodejsSdk.ErrorCode.PARSE_ERROR}}catch(a){return {reason:nodejsSdk.StandardResolutionReasons.ERROR,errorCode:getErrorCode(a),value:b}}})}}function getErrorCode(a){var b;const c=null===(b=null===a||void 0===a?void 0:a.response)||void 0===b?void 0:b.status;let d=nodejsSdk.StandardResolutionReasons.UNKNOWN;return null!=c&&(404==c?d=nodejsSdk.ErrorCode.FLAG_NOT_FOUND:400==c&&(d=nodejsSdk.ErrorCode.TYPE_MISMATCH)),d}function checkResponse(a,b){return !!(a.data&&typeof a.data.value===b&&"string"==typeof a.data.variant&&"string"==typeof a.data.reason)}
|
|
1109
|
-
|
|
1110
1104
|
var objectDefineProperties = {};
|
|
1111
1105
|
|
|
1112
1106
|
var DESCRIPTORS$1 = descriptors;
|
|
@@ -4806,8 +4800,10 @@ class ResolveObjectResponse$Type extends MessageType{constructor(){super("schema
|
|
|
4806
4800
|
* @generated from protobuf rpc: ResolveObject(schema.v1.ResolveObjectRequest) returns (schema.v1.ResolveObjectResponse);
|
|
4807
4801
|
*/resolveObject(a,b){const c=this.methods[4],d=this._transport.mergeOptions(b);return stackIntercept("unary",this._transport,c,d,a)}}
|
|
4808
4802
|
|
|
4809
|
-
|
|
4803
|
+
const Codes={InvalidArgument:"INVALID_ARGUMENT",NotFound:"NOT_FOUND",DataLoss:"DATA_LOSS",Unavailable:"UNAVAILABLE"};class GRPCService{constructor(a,b){this.onFulfilled=a=>a,this.onRejected=a=>{// map the errors
|
|
4804
|
+
switch(null===a||void 0===a?void 0:a.code){case Codes.DataLoss:throw new jsSdk.ParseError(a.message);case Codes.InvalidArgument:throw new jsSdk.TypeMismatchError(a.message);case Codes.NotFound:throw new jsSdk.FlagNotFoundError(a.message);case Codes.Unavailable:throw new jsSdk.FlagNotFoundError(a.message);default:throw a;}};const{host:c,port:d,tls:e,socketPath:f}=a;this.client=b?b:new ServiceClient(new grpcTransport.GrpcTransport({host:f?`unix://${f}`:`${c}:${d}`,channelCredentials:e?grpc__namespace.credentials.createSsl():grpc__namespace.credentials.createInsecure()}));}resolveBoolean(a,b,c){return __awaiter(this,void 0,void 0,function*(){const{response:d}=yield this.client.resolveBoolean({flagKey:a,context:this.convertContext(b,c)}).then(this.onFulfilled,this.onRejected);return {value:d.value,reason:d.reason,variant:d.variant}})}resolveString(a,b,c){return __awaiter(this,void 0,void 0,function*(){const{response:d}=yield this.client.resolveString({flagKey:a,context:this.convertContext(b,c)}).then(this.onFulfilled,this.onRejected);return {value:d.value,reason:d.reason,variant:d.variant}})}resolveNumber(a,b,c){return __awaiter(this,void 0,void 0,function*(){const{response:d}=yield this.client.resolveFloat({flagKey:a,context:this.convertContext(b,c)}).then(this.onFulfilled,this.onRejected);return {value:d.value,reason:d.reason,variant:d.variant}})}resolveObject(a,b,c){return __awaiter(this,void 0,void 0,function*(){const{response:d}=yield this.client.resolveObject({flagKey:a,context:this.convertContext(b,c)}).then(this.onFulfilled,this.onRejected);if(d.value!==void 0)return {value:Struct.toJson(d.value),reason:d.reason,variant:d.variant};throw new jsSdk.ParseError("Object value undefined or missing.")})}convertContext(a,b){try{// stringify to remove invalid js props
|
|
4805
|
+
return Struct.fromJsonString(JSON.stringify(a))}catch(a){const c=a;throw b.error(`${"Error serializing context."}: ${null===c||void 0===c?void 0:c.message}`),b.error(null===c||void 0===c?void 0:c.stack),new jsSdk.ParseError("Error serializing context.")}}}
|
|
4810
4806
|
|
|
4811
|
-
class FlagdProvider{constructor(a){this.metadata={name:"
|
|
4807
|
+
class FlagdProvider{constructor(a,b){this.metadata={name:"flagd Provider"},this.logRejected=(a,b,c)=>{throw c.error(`Error resolving flag ${b}: ${null===a||void 0===a?void 0:a.message}`),c.error(null===a||void 0===a?void 0:a.stack),a},this._service=b?b:new GRPCService(getConfig(a));}resolveBooleanEvaluation(a,b,c,d){return this._service.resolveBoolean(a,c,d).catch(b=>this.logRejected(b,a,d))}resolveStringEvaluation(a,b,c,d){return this._service.resolveString(a,c,d).catch(b=>this.logRejected(b,a,d))}resolveNumberEvaluation(a,b,c,d){return this._service.resolveNumber(a,c,d).catch(b=>this.logRejected(b,a,d))}resolveObjectEvaluation(a,b,c,d){return this._service.resolveObject(a,c,d).catch(b=>this.logRejected(b,a,d))}}
|
|
4812
4808
|
|
|
4813
4809
|
exports.FlagdProvider = FlagdProvider;
|
package/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { StandardResolutionReasons, ErrorCode } from '@openfeature/nodejs-sdk';
|
|
2
|
-
import axios from 'axios';
|
|
3
|
-
import { GrpcTransport } from '@protobuf-ts/grpc-transport';
|
|
4
1
|
import * as grpc from '@grpc/grpc-js';
|
|
2
|
+
import { FlagNotFoundError, TypeMismatchError, ParseError } from '@openfeature/js-sdk';
|
|
3
|
+
import { GrpcTransport } from '@protobuf-ts/grpc-transport';
|
|
5
4
|
|
|
6
5
|
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
7
6
|
|
|
@@ -171,9 +170,9 @@ var engineUserAgent = getBuiltIn$3('navigator', 'userAgent') || '';
|
|
|
171
170
|
var global$a = global$c;
|
|
172
171
|
var userAgent = engineUserAgent;
|
|
173
172
|
|
|
174
|
-
var process = global$a.process;
|
|
173
|
+
var process$1 = global$a.process;
|
|
175
174
|
var Deno = global$a.Deno;
|
|
176
|
-
var versions = process && process.versions || Deno && Deno.version;
|
|
175
|
+
var versions = process$1 && process$1.versions || Deno && Deno.version;
|
|
177
176
|
var v8 = versions && versions.v8;
|
|
178
177
|
var match, version;
|
|
179
178
|
|
|
@@ -1051,6 +1050,8 @@ $$2({ target: 'Object', stat: true, arity: 2, forced: Object.assign !== assign }
|
|
|
1051
1050
|
assign: assign
|
|
1052
1051
|
});
|
|
1053
1052
|
|
|
1053
|
+
const DEFAULT_CONFIG={host:"localhost",port:8013,tls:!1};var ENV_VAR;(function(a){a.FLAGD_HOST="FLAGD_HOST",a.FLAGD_PORT="FLAGD_PORT",a.FLAGD_TLS="FLAGD_TLS",a.FLAGD_SOCKET_PATH="FLAGD_SOCKET_PATH";})(ENV_VAR||(ENV_VAR={}));const getEnvVarConfig=()=>{var a;return Object.assign(Object.assign(Object.assign(Object.assign({},process.env[ENV_VAR.FLAGD_HOST]&&{host:process.env[ENV_VAR.FLAGD_HOST]}),+process.env[ENV_VAR.FLAGD_PORT]&&{port:+process.env[ENV_VAR.FLAGD_PORT]}),process.env[ENV_VAR.FLAGD_TLS]&&{tls:"true"===(null===(a=process.env[ENV_VAR.FLAGD_TLS])||void 0===a?void 0:a.toLowerCase())}),process.env[ENV_VAR.FLAGD_SOCKET_PATH]&&{socketPath:process.env[ENV_VAR.FLAGD_SOCKET_PATH]})};function getConfig(a={}){return Object.assign(Object.assign(Object.assign({},DEFAULT_CONFIG),getEnvVarConfig()),a)}
|
|
1054
|
+
|
|
1054
1055
|
/******************************************************************************
|
|
1055
1056
|
Copyright (c) Microsoft Corporation.
|
|
1056
1057
|
|
|
@@ -1076,10 +1077,6 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
1076
1077
|
});
|
|
1077
1078
|
}
|
|
1078
1079
|
|
|
1079
|
-
class HTTPService{constructor(a){this.url=`${a.protocol}://${a.host}:${a.port}`;}resolveBoolean(a,b,c){return __awaiter(this,void 0,void 0,function*(){try{const d=yield axios.post(`${this.url}/flags/${encodeURIComponent(a)}/resolve/boolean`,c);return checkResponse(d,"boolean")?{value:d.data.value,reason:d.data.reason,variant:d.data.variant}:{value:b,reason:StandardResolutionReasons.ERROR,errorCode:ErrorCode.PARSE_ERROR}}catch(a){return {reason:StandardResolutionReasons.ERROR,errorCode:getErrorCode(a),value:b}}})}resolveNumber(a,b,c){return __awaiter(this,void 0,void 0,function*(){try{const d=yield axios.post(/**
|
|
1080
|
-
* JavaScript numbers are always 64-bit floating point
|
|
1081
|
-
*/`${this.url}/flags/${encodeURIComponent(a)}/resolve/float`,c);return checkResponse(d,"number")?{value:d.data.value,reason:d.data.reason,variant:d.data.variant}:{value:b,reason:StandardResolutionReasons.ERROR,errorCode:ErrorCode.PARSE_ERROR}}catch(a){return {reason:StandardResolutionReasons.ERROR,errorCode:getErrorCode(a),value:b}}})}resolveString(a,b,c){return __awaiter(this,void 0,void 0,function*(){try{const d=yield axios.post(`${this.url}/flags/${encodeURIComponent(a)}/resolve/string`,c);return checkResponse(d,"string")?{value:d.data.value,reason:d.data.reason,variant:d.data.variant}:{value:b,reason:StandardResolutionReasons.ERROR,errorCode:ErrorCode.PARSE_ERROR}}catch(a){return {reason:StandardResolutionReasons.ERROR,errorCode:getErrorCode(a),value:b}}})}resolveObject(a,b,c){return __awaiter(this,void 0,void 0,function*(){try{const d=yield axios.post(`${this.url}/flags/${encodeURIComponent(a)}/resolve/object`,c);return checkResponse(d,"object")?{value:d.data.value,reason:d.data.reason,variant:d.data.variant}:{value:b,reason:StandardResolutionReasons.ERROR,errorCode:ErrorCode.PARSE_ERROR}}catch(a){return {reason:StandardResolutionReasons.ERROR,errorCode:getErrorCode(a),value:b}}})}}function getErrorCode(a){var b;const c=null===(b=null===a||void 0===a?void 0:a.response)||void 0===b?void 0:b.status;let d=StandardResolutionReasons.UNKNOWN;return null!=c&&(404==c?d=ErrorCode.FLAG_NOT_FOUND:400==c&&(d=ErrorCode.TYPE_MISMATCH)),d}function checkResponse(a,b){return !!(a.data&&typeof a.data.value===b&&"string"==typeof a.data.variant&&"string"==typeof a.data.reason)}
|
|
1082
|
-
|
|
1083
1080
|
var objectDefineProperties = {};
|
|
1084
1081
|
|
|
1085
1082
|
var DESCRIPTORS$1 = descriptors;
|
|
@@ -4779,8 +4776,10 @@ class ResolveObjectResponse$Type extends MessageType{constructor(){super("schema
|
|
|
4779
4776
|
* @generated from protobuf rpc: ResolveObject(schema.v1.ResolveObjectRequest) returns (schema.v1.ResolveObjectResponse);
|
|
4780
4777
|
*/resolveObject(a,b){const c=this.methods[4],d=this._transport.mergeOptions(b);return stackIntercept("unary",this._transport,c,d,a)}}
|
|
4781
4778
|
|
|
4782
|
-
|
|
4779
|
+
const Codes={InvalidArgument:"INVALID_ARGUMENT",NotFound:"NOT_FOUND",DataLoss:"DATA_LOSS",Unavailable:"UNAVAILABLE"};class GRPCService{constructor(a,b){this.onFulfilled=a=>a,this.onRejected=a=>{// map the errors
|
|
4780
|
+
switch(null===a||void 0===a?void 0:a.code){case Codes.DataLoss:throw new ParseError(a.message);case Codes.InvalidArgument:throw new TypeMismatchError(a.message);case Codes.NotFound:throw new FlagNotFoundError(a.message);case Codes.Unavailable:throw new FlagNotFoundError(a.message);default:throw a;}};const{host:c,port:d,tls:e,socketPath:f}=a;this.client=b?b:new ServiceClient(new GrpcTransport({host:f?`unix://${f}`:`${c}:${d}`,channelCredentials:e?grpc.credentials.createSsl():grpc.credentials.createInsecure()}));}resolveBoolean(a,b,c){return __awaiter(this,void 0,void 0,function*(){const{response:d}=yield this.client.resolveBoolean({flagKey:a,context:this.convertContext(b,c)}).then(this.onFulfilled,this.onRejected);return {value:d.value,reason:d.reason,variant:d.variant}})}resolveString(a,b,c){return __awaiter(this,void 0,void 0,function*(){const{response:d}=yield this.client.resolveString({flagKey:a,context:this.convertContext(b,c)}).then(this.onFulfilled,this.onRejected);return {value:d.value,reason:d.reason,variant:d.variant}})}resolveNumber(a,b,c){return __awaiter(this,void 0,void 0,function*(){const{response:d}=yield this.client.resolveFloat({flagKey:a,context:this.convertContext(b,c)}).then(this.onFulfilled,this.onRejected);return {value:d.value,reason:d.reason,variant:d.variant}})}resolveObject(a,b,c){return __awaiter(this,void 0,void 0,function*(){const{response:d}=yield this.client.resolveObject({flagKey:a,context:this.convertContext(b,c)}).then(this.onFulfilled,this.onRejected);if(d.value!==void 0)return {value:Struct.toJson(d.value),reason:d.reason,variant:d.variant};throw new ParseError("Object value undefined or missing.")})}convertContext(a,b){try{// stringify to remove invalid js props
|
|
4781
|
+
return Struct.fromJsonString(JSON.stringify(a))}catch(a){const c=a;throw b.error(`${"Error serializing context."}: ${null===c||void 0===c?void 0:c.message}`),b.error(null===c||void 0===c?void 0:c.stack),new ParseError("Error serializing context.")}}}
|
|
4783
4782
|
|
|
4784
|
-
class FlagdProvider{constructor(a){this.metadata={name:"
|
|
4783
|
+
class FlagdProvider{constructor(a,b){this.metadata={name:"flagd Provider"},this.logRejected=(a,b,c)=>{throw c.error(`Error resolving flag ${b}: ${null===a||void 0===a?void 0:a.message}`),c.error(null===a||void 0===a?void 0:a.stack),a},this._service=b?b:new GRPCService(getConfig(a));}resolveBooleanEvaluation(a,b,c,d){return this._service.resolveBoolean(a,c,d).catch(b=>this.logRejected(b,a,d))}resolveStringEvaluation(a,b,c,d){return this._service.resolveString(a,c,d).catch(b=>this.logRejected(b,a,d))}resolveNumberEvaluation(a,b,c,d){return this._service.resolveNumber(a,c,d).catch(b=>this.logRejected(b,a,d))}resolveObjectEvaluation(a,b,c,d){return this._service.resolveObject(a,c,d).catch(b=>this.logRejected(b,a,d))}}
|
|
4785
4784
|
|
|
4786
4785
|
export { FlagdProvider };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface Config {
|
|
2
|
+
/**
|
|
3
|
+
* The domain name or IP address of flagd.
|
|
4
|
+
*
|
|
5
|
+
* @default localhost
|
|
6
|
+
*/
|
|
7
|
+
host: string;
|
|
8
|
+
/**
|
|
9
|
+
* The port flagd is listen on.
|
|
10
|
+
*
|
|
11
|
+
* @default 8013
|
|
12
|
+
*/
|
|
13
|
+
port: number;
|
|
14
|
+
/**
|
|
15
|
+
* Determines if TLS should be used.
|
|
16
|
+
*
|
|
17
|
+
* @default false
|
|
18
|
+
*/
|
|
19
|
+
tls: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* When set, a unix socket connection is used.
|
|
22
|
+
*
|
|
23
|
+
* @example "/tmp/flagd.socks"
|
|
24
|
+
*/
|
|
25
|
+
socketPath?: string;
|
|
26
|
+
}
|
|
27
|
+
export declare type FlagdProviderOptions = Partial<Config>;
|
|
28
|
+
export declare function getConfig(options?: FlagdProviderOptions): {
|
|
29
|
+
host: string;
|
|
30
|
+
port: number;
|
|
31
|
+
tls: boolean;
|
|
32
|
+
socketPath?: string | undefined;
|
|
33
|
+
};
|
package/lib/flagd-provider.d.ts
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
import { EvaluationContext, Provider, ResolutionDetails } from '@openfeature/
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
host?: string;
|
|
5
|
-
port?: number;
|
|
6
|
-
protocol?: 'http' | 'https';
|
|
7
|
-
}
|
|
1
|
+
import { EvaluationContext, JsonValue, Logger, Provider, ResolutionDetails } from '@openfeature/js-sdk';
|
|
2
|
+
import { FlagdProviderOptions } from './configuration';
|
|
3
|
+
import { Service } from './service/service';
|
|
8
4
|
export declare class FlagdProvider implements Provider {
|
|
9
5
|
metadata: {
|
|
10
6
|
name: string;
|
|
11
7
|
};
|
|
12
|
-
private readonly
|
|
13
|
-
constructor(options?: FlagdProviderOptions);
|
|
14
|
-
resolveBooleanEvaluation(flagKey: string,
|
|
15
|
-
resolveStringEvaluation(flagKey: string,
|
|
16
|
-
resolveNumberEvaluation(flagKey: string,
|
|
17
|
-
resolveObjectEvaluation<
|
|
8
|
+
private readonly _service;
|
|
9
|
+
constructor(options?: FlagdProviderOptions, service?: Service);
|
|
10
|
+
resolveBooleanEvaluation(flagKey: string, _: boolean, transformedContext: EvaluationContext, logger: Logger): Promise<ResolutionDetails<boolean>>;
|
|
11
|
+
resolveStringEvaluation(flagKey: string, _: string, transformedContext: EvaluationContext, logger: Logger): Promise<ResolutionDetails<string>>;
|
|
12
|
+
resolveNumberEvaluation(flagKey: string, _: number, transformedContext: EvaluationContext, logger: Logger): Promise<ResolutionDetails<number>>;
|
|
13
|
+
resolveObjectEvaluation<T extends JsonValue>(flagKey: string, _: T, transformedContext: EvaluationContext, logger: Logger): Promise<ResolutionDetails<T>>;
|
|
14
|
+
logRejected: (err: Error, flagKey: string, logger: Logger) => never;
|
|
18
15
|
}
|
|
@@ -1,16 +1,21 @@
|
|
|
1
|
-
import { EvaluationContext, ResolutionDetails } from '@openfeature/
|
|
1
|
+
import { EvaluationContext, JsonValue, Logger, ResolutionDetails } from '@openfeature/js-sdk';
|
|
2
2
|
import { ServiceClient } from '../../../proto/ts/schema/v1/schema.client';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
import { Config } from '../../configuration';
|
|
4
|
+
import { Service } from '../service';
|
|
5
|
+
export declare const Codes: {
|
|
6
|
+
readonly InvalidArgument: "INVALID_ARGUMENT";
|
|
7
|
+
readonly NotFound: "NOT_FOUND";
|
|
8
|
+
readonly DataLoss: "DATA_LOSS";
|
|
9
|
+
readonly Unavailable: "UNAVAILABLE";
|
|
10
|
+
};
|
|
8
11
|
export declare class GRPCService implements Service {
|
|
9
12
|
client: ServiceClient;
|
|
10
|
-
constructor(
|
|
11
|
-
resolveBoolean(flagKey: string,
|
|
12
|
-
resolveString(flagKey: string,
|
|
13
|
-
resolveNumber(flagKey: string,
|
|
14
|
-
resolveObject<T extends
|
|
13
|
+
constructor(config: Config, client?: ServiceClient);
|
|
14
|
+
resolveBoolean(flagKey: string, context: EvaluationContext, logger: Logger): Promise<ResolutionDetails<boolean>>;
|
|
15
|
+
resolveString(flagKey: string, context: EvaluationContext, logger: Logger): Promise<ResolutionDetails<string>>;
|
|
16
|
+
resolveNumber(flagKey: string, context: EvaluationContext, logger: Logger): Promise<ResolutionDetails<number>>;
|
|
17
|
+
resolveObject<T extends JsonValue>(flagKey: string, context: EvaluationContext, logger: Logger): Promise<ResolutionDetails<T>>;
|
|
18
|
+
private convertContext;
|
|
19
|
+
private onFulfilled;
|
|
20
|
+
private onRejected;
|
|
15
21
|
}
|
|
16
|
-
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { EvaluationContext, JsonValue, Logger, ResolutionDetails } from '@openfeature/js-sdk';
|
|
2
|
+
export interface Service {
|
|
3
|
+
resolveBoolean(flagKey: string, context: EvaluationContext, logger: Logger): Promise<ResolutionDetails<boolean>>;
|
|
4
|
+
resolveString(flagKey: string, context: EvaluationContext, logger: Logger): Promise<ResolutionDetails<string>>;
|
|
5
|
+
resolveNumber(flagKey: string, context: EvaluationContext, logger: Logger): Promise<ResolutionDetails<number>>;
|
|
6
|
+
resolveObject<T extends JsonValue>(flagKey: string, context: EvaluationContext, logger: Logger): Promise<ResolutionDetails<T>>;
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openfeature/flagd-provider",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"publish-if-not-exists": "cp $NPM_CONFIG_USERCONFIG .npmrc && if [ \"$(npm show $npm_package_name@$npm_package_version version)\" = \"$(npm run current-version -s)\" ]; then echo 'already published, skipping'; else npm publish --access public; fi",
|
|
7
7
|
"current-version": "echo $npm_package_version"
|
|
8
8
|
},
|
|
9
9
|
"peerDependencies": {
|
|
10
|
-
"@openfeature/
|
|
10
|
+
"@openfeature/js-sdk": "^0.4.0"
|
|
11
11
|
},
|
|
12
12
|
"module": "./index.js",
|
|
13
13
|
"main": "./index.cjs",
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"axios": "^0.27.2",
|
|
24
23
|
"@protobuf-ts/grpc-transport": "^2.7.0",
|
|
25
24
|
"@grpc/grpc-js": "^1.6.7"
|
|
26
25
|
}
|
package/lib/service/Service.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { EvaluationContext, ResolutionDetails } from '@openfeature/nodejs-sdk';
|
|
2
|
-
export interface Service {
|
|
3
|
-
resolveBoolean(flagKey: string, defaultValue: boolean, context: EvaluationContext): Promise<ResolutionDetails<boolean>>;
|
|
4
|
-
resolveString(flagKey: string, defaultValue: string, context: EvaluationContext): Promise<ResolutionDetails<string>>;
|
|
5
|
-
resolveNumber(flagKey: string, defaultValue: number, context: EvaluationContext): Promise<ResolutionDetails<number>>;
|
|
6
|
-
resolveObject<T extends object>(flagKey: string, defaultValue: T, context: EvaluationContext): Promise<ResolutionDetails<T>>;
|
|
7
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { EvaluationContext, ResolutionDetails } from '@openfeature/nodejs-sdk';
|
|
2
|
-
import { Service } from '../Service';
|
|
3
|
-
interface HTTPServiceOptions {
|
|
4
|
-
host: string;
|
|
5
|
-
port: number;
|
|
6
|
-
protocol: string;
|
|
7
|
-
}
|
|
8
|
-
export declare class HTTPService implements Service {
|
|
9
|
-
private url;
|
|
10
|
-
constructor(options: HTTPServiceOptions);
|
|
11
|
-
resolveBoolean(flagKey: string, defaultValue: boolean, context: EvaluationContext): Promise<ResolutionDetails<boolean>>;
|
|
12
|
-
resolveNumber(flagKey: string, defaultValue: number, context: EvaluationContext): Promise<ResolutionDetails<number>>;
|
|
13
|
-
resolveString(flagKey: string, defaultValue: string, context: EvaluationContext): Promise<ResolutionDetails<string>>;
|
|
14
|
-
resolveObject<T extends object>(flagKey: string, defaultValue: T, context: EvaluationContext): Promise<ResolutionDetails<T>>;
|
|
15
|
-
}
|
|
16
|
-
export {};
|