@openfeature/flagd-provider 0.8.2 → 0.9.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/README.md CHANGED
@@ -13,7 +13,7 @@ $ npm install @openfeature/flagd-provider
13
13
  Required peer dependencies
14
14
 
15
15
  ```
16
- $ npm install @openfeature/js-sdk
16
+ $ npm install @openfeature/server-sdk
17
17
  ```
18
18
 
19
19
  ## Usage
package/index.cjs.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./src/index";
@@ -0,0 +1 @@
1
+ exports._default = require('./index.cjs.js').default;
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var jsSdk = require('@openfeature/js-sdk');
5
+ var serverSdk = require('@openfeature/server-sdk');
6
6
  var grpcJs = require('@grpc/grpc-js');
7
7
  var lruCache = require('lru-cache');
8
8
  var util$6 = require('util');
@@ -3695,9 +3695,14 @@ Reader$1.prototype.bytes = function read_bytes() {
3695
3695
  this.pos += length;
3696
3696
  if (Array.isArray(this.buf)) // plain array
3697
3697
  return this.buf.slice(start, end);
3698
- return start === end // fix for IE 10/Win8 and others' subarray returning array of size 1
3699
- ? new this.buf.constructor(0)
3700
- : this._slice.call(this.buf, start, end);
3698
+
3699
+ if (start === end) { // fix for IE 10/Win8 and others' subarray returning array of size 1
3700
+ var nativeBuffer = util$2.Buffer;
3701
+ return nativeBuffer
3702
+ ? nativeBuffer.alloc(0)
3703
+ : new this.buf.constructor(0);
3704
+ }
3705
+ return this._slice.call(this.buf, start, end);
3701
3706
  };
3702
3707
 
3703
3708
  /**
@@ -5833,43 +5838,19 @@ class GRPCService {
5833
5838
  this._streamConnectAttempt = 0;
5834
5839
  this._stream = undefined;
5835
5840
  this._streamConnectBackoff = BASE_EVENT_STREAM_RETRY_BACKOFF_MS;
5836
- this.objectParser = (struct) => {
5837
- if (struct) {
5838
- return struct;
5839
- }
5840
- return {};
5841
- };
5842
- this.booleanParser = (value) => {
5843
- if (value) {
5844
- return value;
5845
- }
5846
- return false;
5847
- };
5848
- this.stringParser = (value) => {
5849
- if (value) {
5850
- return value;
5851
- }
5852
- return '';
5853
- };
5854
- this.numberParser = (value) => {
5855
- if (value) {
5856
- return value;
5857
- }
5858
- return 0;
5859
- };
5860
5841
  this.onRejected = (err) => {
5861
5842
  // map the errors
5862
5843
  switch (err === null || err === void 0 ? void 0 : err.code) {
5863
5844
  case grpcJs.status.DATA_LOSS:
5864
- throw new jsSdk.ParseError(err.details);
5845
+ throw new serverSdk.ParseError(err.details);
5865
5846
  case grpcJs.status.INVALID_ARGUMENT:
5866
- throw new jsSdk.TypeMismatchError(err.details);
5847
+ throw new serverSdk.TypeMismatchError(err.details);
5867
5848
  case grpcJs.status.NOT_FOUND:
5868
- throw new jsSdk.FlagNotFoundError(err.details);
5849
+ throw new serverSdk.FlagNotFoundError(err.details);
5869
5850
  case grpcJs.status.UNAVAILABLE:
5870
- throw new jsSdk.FlagNotFoundError(err.details);
5851
+ throw new serverSdk.FlagNotFoundError(err.details);
5871
5852
  default:
5872
- throw new jsSdk.GeneralError(err === null || err === void 0 ? void 0 : err.details);
5853
+ throw new serverSdk.GeneralError(err === null || err === void 0 ? void 0 : err.details);
5873
5854
  }
5874
5855
  };
5875
5856
  const { host, port, tls, socketPath } = config;
@@ -5895,22 +5876,22 @@ class GRPCService {
5895
5876
  }
5896
5877
  resolveBoolean(flagKey, context, logger) {
5897
5878
  return __awaiter(this, void 0, void 0, function* () {
5898
- return this.resolve(this._client.resolveBoolean, flagKey, context, logger, this.booleanParser);
5879
+ return this.resolve(this._client.resolveBoolean, flagKey, context, logger);
5899
5880
  });
5900
5881
  }
5901
5882
  resolveString(flagKey, context, logger) {
5902
5883
  return __awaiter(this, void 0, void 0, function* () {
5903
- return this.resolve(this._client.resolveString, flagKey, context, logger, this.stringParser);
5884
+ return this.resolve(this._client.resolveString, flagKey, context, logger);
5904
5885
  });
5905
5886
  }
5906
5887
  resolveNumber(flagKey, context, logger) {
5907
5888
  return __awaiter(this, void 0, void 0, function* () {
5908
- return this.resolve(this._client.resolveFloat, flagKey, context, logger, this.numberParser);
5889
+ return this.resolve(this._client.resolveFloat, flagKey, context, logger);
5909
5890
  });
5910
5891
  }
5911
5892
  resolveObject(flagKey, context, logger) {
5912
5893
  return __awaiter(this, void 0, void 0, function* () {
5913
- return this.resolve(this._client.resolveObject, flagKey, context, logger, this.objectParser);
5894
+ return this.resolve(this._client.resolveObject, flagKey, context, logger);
5914
5895
  });
5915
5896
  }
5916
5897
  connectStream(connectCallback, changedCallback, disconnectCallback) {
@@ -5980,7 +5961,9 @@ class GRPCService {
5980
5961
  this._streamConnectAttempt++;
5981
5962
  setTimeout(() => {
5982
5963
  this._streamConnectBackoff = this._streamConnectBackoff * 2;
5983
- this.connectStream(connectCallback, changedCallback, disconnectCallback);
5964
+ this.connectStream(connectCallback, changedCallback, disconnectCallback).catch(() => {
5965
+ // empty catch to avoid unhandled promise rejection
5966
+ });
5984
5967
  }, this._streamConnectBackoff);
5985
5968
  }
5986
5969
  else {
@@ -5992,18 +5975,18 @@ class GRPCService {
5992
5975
  }
5993
5976
  handleClose() {
5994
5977
  var _a, _b;
5995
- (_a = this.logger) === null || _a === void 0 ? void 0 : _a.info(`${FlagdProvider.name}: streaming connection closed gracefully`);
5978
+ (_a = this.logger) === null || _a === void 0 ? void 0 : _a.info(`${FlagdProvider.name}: streaming connection closed`);
5996
5979
  (_b = this._cache) === null || _b === void 0 ? void 0 : _b.clear();
5997
5980
  this._streamAlive = false;
5998
5981
  }
5999
- resolve(promise, flagKey, context, logger, parser) {
5982
+ resolve(promise, flagKey, context, logger) {
6000
5983
  var _a, _b;
6001
5984
  return __awaiter(this, void 0, void 0, function* () {
6002
5985
  const resolver = util$6.promisify(promise);
6003
5986
  if (this._cacheActive) {
6004
5987
  const cached = (_a = this._cache) === null || _a === void 0 ? void 0 : _a.get(flagKey);
6005
5988
  if (cached) {
6006
- return Object.assign(Object.assign({}, cached), { reason: jsSdk.StandardResolutionReasons.CACHED });
5989
+ return Object.assign(Object.assign({}, cached), { reason: serverSdk.StandardResolutionReasons.CACHED });
6007
5990
  }
6008
5991
  }
6009
5992
  // invoke the passed resolver method
@@ -6011,14 +5994,13 @@ class GRPCService {
6011
5994
  .call(this._client, { flagKey, context })
6012
5995
  .then((resolved) => resolved, this.onRejected);
6013
5996
  const resolved = {
6014
- // invoke the parser method if passed
6015
- value: parser.call(this, response.value),
5997
+ value: response.value,
6016
5998
  reason: response.reason,
6017
5999
  variant: response.variant,
6018
6000
  flagMetadata: response.metadata,
6019
6001
  };
6020
6002
  logger.debug(`${FlagdProvider.name}: resolved flag with key: ${resolved.value}, variant: ${response.variant}, reason: ${response.reason}`);
6021
- if (this._cacheActive && response.reason === jsSdk.StandardResolutionReasons.STATIC) {
6003
+ if (this._cacheActive && response.reason === serverSdk.StandardResolutionReasons.STATIC) {
6022
6004
  // cache this static value
6023
6005
  (_b = this._cache) === null || _b === void 0 ? void 0 : _b.set(flagKey, resolved);
6024
6006
  }
@@ -6046,8 +6028,9 @@ class FlagdProvider {
6046
6028
  this.metadata = {
6047
6029
  name: 'flagd Provider',
6048
6030
  };
6049
- this._status = jsSdk.ProviderStatus.NOT_READY;
6050
- this._events = new jsSdk.OpenFeatureEventEmitter();
6031
+ this.runsOn = 'server';
6032
+ this._status = serverSdk.ProviderStatus.NOT_READY;
6033
+ this._events = new serverSdk.OpenFeatureEventEmitter();
6051
6034
  this.logRejected = (err, flagKey, logger) => {
6052
6035
  logger.error(`Error resolving flag ${flagKey}: ${err === null || err === void 0 ? void 0 : err.message}`);
6053
6036
  logger.error(err === null || err === void 0 ? void 0 : err.stack);
@@ -6061,11 +6044,11 @@ class FlagdProvider {
6061
6044
  .then(() => {
6062
6045
  var _a;
6063
6046
  (_a = this.logger) === null || _a === void 0 ? void 0 : _a.debug(`${this.metadata.name}: ready`);
6064
- this._status = jsSdk.ProviderStatus.READY;
6047
+ this._status = serverSdk.ProviderStatus.READY;
6065
6048
  })
6066
6049
  .catch((err) => {
6067
6050
  var _a;
6068
- this._status = jsSdk.ProviderStatus.ERROR;
6051
+ this._status = serverSdk.ProviderStatus.ERROR;
6069
6052
  (_a = this.logger) === null || _a === void 0 ? void 0 : _a.error(`${this.metadata.name}: error during initialization: ${err.message}, ${err.stack}`);
6070
6053
  throw err;
6071
6054
  });
@@ -6096,13 +6079,13 @@ class FlagdProvider {
6096
6079
  .catch((err) => this.logRejected(err, flagKey, logger));
6097
6080
  }
6098
6081
  setReady() {
6099
- this._status = jsSdk.ProviderStatus.READY;
6082
+ this._status = serverSdk.ProviderStatus.READY;
6100
6083
  }
6101
6084
  setError() {
6102
- this._status = jsSdk.ProviderStatus.ERROR;
6085
+ this._status = serverSdk.ProviderStatus.ERROR;
6103
6086
  }
6104
6087
  emitChanged(flagsChanged) {
6105
- this._events.emit(jsSdk.ProviderEvents.ConfigurationChanged, { flagsChanged });
6088
+ this._events.emit(serverSdk.ProviderEvents.ConfigurationChanged, { flagsChanged });
6106
6089
  }
6107
6090
  }
6108
6091
 
package/index.cjs.mjs ADDED
@@ -0,0 +1,2 @@
1
+ export * from './index.cjs.js';
2
+ export { _default as default } from './index.cjs.default.js';
@@ -1,4 +1,4 @@
1
- import { GeneralError, FlagNotFoundError, TypeMismatchError, ParseError, StandardResolutionReasons, ProviderStatus, OpenFeatureEventEmitter, ProviderEvents } from '@openfeature/js-sdk';
1
+ import { GeneralError, FlagNotFoundError, TypeMismatchError, ParseError, StandardResolutionReasons, ProviderStatus, OpenFeatureEventEmitter, ProviderEvents } from '@openfeature/server-sdk';
2
2
  import { makeGenericClientConstructor, status, credentials } from '@grpc/grpc-js';
3
3
  import { LRUCache } from 'lru-cache';
4
4
  import { promisify } from 'util';
@@ -3691,9 +3691,14 @@ Reader$1.prototype.bytes = function read_bytes() {
3691
3691
  this.pos += length;
3692
3692
  if (Array.isArray(this.buf)) // plain array
3693
3693
  return this.buf.slice(start, end);
3694
- return start === end // fix for IE 10/Win8 and others' subarray returning array of size 1
3695
- ? new this.buf.constructor(0)
3696
- : this._slice.call(this.buf, start, end);
3694
+
3695
+ if (start === end) { // fix for IE 10/Win8 and others' subarray returning array of size 1
3696
+ var nativeBuffer = util$2.Buffer;
3697
+ return nativeBuffer
3698
+ ? nativeBuffer.alloc(0)
3699
+ : new this.buf.constructor(0);
3700
+ }
3701
+ return this._slice.call(this.buf, start, end);
3697
3702
  };
3698
3703
 
3699
3704
  /**
@@ -5829,30 +5834,6 @@ class GRPCService {
5829
5834
  this._streamConnectAttempt = 0;
5830
5835
  this._stream = undefined;
5831
5836
  this._streamConnectBackoff = BASE_EVENT_STREAM_RETRY_BACKOFF_MS;
5832
- this.objectParser = (struct) => {
5833
- if (struct) {
5834
- return struct;
5835
- }
5836
- return {};
5837
- };
5838
- this.booleanParser = (value) => {
5839
- if (value) {
5840
- return value;
5841
- }
5842
- return false;
5843
- };
5844
- this.stringParser = (value) => {
5845
- if (value) {
5846
- return value;
5847
- }
5848
- return '';
5849
- };
5850
- this.numberParser = (value) => {
5851
- if (value) {
5852
- return value;
5853
- }
5854
- return 0;
5855
- };
5856
5837
  this.onRejected = (err) => {
5857
5838
  // map the errors
5858
5839
  switch (err === null || err === void 0 ? void 0 : err.code) {
@@ -5891,22 +5872,22 @@ class GRPCService {
5891
5872
  }
5892
5873
  resolveBoolean(flagKey, context, logger) {
5893
5874
  return __awaiter(this, void 0, void 0, function* () {
5894
- return this.resolve(this._client.resolveBoolean, flagKey, context, logger, this.booleanParser);
5875
+ return this.resolve(this._client.resolveBoolean, flagKey, context, logger);
5895
5876
  });
5896
5877
  }
5897
5878
  resolveString(flagKey, context, logger) {
5898
5879
  return __awaiter(this, void 0, void 0, function* () {
5899
- return this.resolve(this._client.resolveString, flagKey, context, logger, this.stringParser);
5880
+ return this.resolve(this._client.resolveString, flagKey, context, logger);
5900
5881
  });
5901
5882
  }
5902
5883
  resolveNumber(flagKey, context, logger) {
5903
5884
  return __awaiter(this, void 0, void 0, function* () {
5904
- return this.resolve(this._client.resolveFloat, flagKey, context, logger, this.numberParser);
5885
+ return this.resolve(this._client.resolveFloat, flagKey, context, logger);
5905
5886
  });
5906
5887
  }
5907
5888
  resolveObject(flagKey, context, logger) {
5908
5889
  return __awaiter(this, void 0, void 0, function* () {
5909
- return this.resolve(this._client.resolveObject, flagKey, context, logger, this.objectParser);
5890
+ return this.resolve(this._client.resolveObject, flagKey, context, logger);
5910
5891
  });
5911
5892
  }
5912
5893
  connectStream(connectCallback, changedCallback, disconnectCallback) {
@@ -5976,7 +5957,9 @@ class GRPCService {
5976
5957
  this._streamConnectAttempt++;
5977
5958
  setTimeout(() => {
5978
5959
  this._streamConnectBackoff = this._streamConnectBackoff * 2;
5979
- this.connectStream(connectCallback, changedCallback, disconnectCallback);
5960
+ this.connectStream(connectCallback, changedCallback, disconnectCallback).catch(() => {
5961
+ // empty catch to avoid unhandled promise rejection
5962
+ });
5980
5963
  }, this._streamConnectBackoff);
5981
5964
  }
5982
5965
  else {
@@ -5988,11 +5971,11 @@ class GRPCService {
5988
5971
  }
5989
5972
  handleClose() {
5990
5973
  var _a, _b;
5991
- (_a = this.logger) === null || _a === void 0 ? void 0 : _a.info(`${FlagdProvider.name}: streaming connection closed gracefully`);
5974
+ (_a = this.logger) === null || _a === void 0 ? void 0 : _a.info(`${FlagdProvider.name}: streaming connection closed`);
5992
5975
  (_b = this._cache) === null || _b === void 0 ? void 0 : _b.clear();
5993
5976
  this._streamAlive = false;
5994
5977
  }
5995
- resolve(promise, flagKey, context, logger, parser) {
5978
+ resolve(promise, flagKey, context, logger) {
5996
5979
  var _a, _b;
5997
5980
  return __awaiter(this, void 0, void 0, function* () {
5998
5981
  const resolver = promisify(promise);
@@ -6007,8 +5990,7 @@ class GRPCService {
6007
5990
  .call(this._client, { flagKey, context })
6008
5991
  .then((resolved) => resolved, this.onRejected);
6009
5992
  const resolved = {
6010
- // invoke the parser method if passed
6011
- value: parser.call(this, response.value),
5993
+ value: response.value,
6012
5994
  reason: response.reason,
6013
5995
  variant: response.variant,
6014
5996
  flagMetadata: response.metadata,
@@ -6042,6 +6024,7 @@ class FlagdProvider {
6042
6024
  this.metadata = {
6043
6025
  name: 'flagd Provider',
6044
6026
  };
6027
+ this.runsOn = 'server';
6045
6028
  this._status = ProviderStatus.NOT_READY;
6046
6029
  this._events = new OpenFeatureEventEmitter();
6047
6030
  this.logRejected = (err, flagKey, logger) => {
package/package.json CHANGED
@@ -1,27 +1,27 @@
1
1
  {
2
2
  "name": "@openfeature/flagd-provider",
3
- "version": "0.8.2",
3
+ "version": "0.9.0",
4
4
  "scripts": {
5
5
  "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",
6
6
  "current-version": "echo $npm_package_version"
7
7
  },
8
8
  "peerDependencies": {
9
9
  "@grpc/grpc-js": "^1.6.0",
10
- "@openfeature/js-sdk": ">=1.3.0"
10
+ "@openfeature/server-sdk": ">=1.6.0"
11
11
  },
12
- "module": "./index.js",
13
- "main": "./index.cjs",
14
- "type": "module",
15
- "types": "./src/index.d.ts",
16
12
  "exports": {
13
+ "./package.json": "./package.json",
17
14
  ".": {
18
- "types": "./src/index.d.ts",
19
- "import": "./index.js",
20
- "require": "./index.cjs"
15
+ "module": "./index.esm.js",
16
+ "import": "./index.cjs.mjs",
17
+ "default": "./index.cjs.js"
21
18
  }
22
19
  },
20
+ "module": "./index.esm.js",
21
+ "main": "./index.cjs.js",
23
22
  "dependencies": {
24
23
  "@protobuf-ts/runtime-rpc": "2.9.0",
25
- "lru-cache": "10.0.0"
24
+ "lru-cache": "10.0.1",
25
+ "util": "0.12.5"
26
26
  }
27
27
  }
@@ -0,0 +1,9 @@
1
+ declare const _default: {
2
+ displayName: string;
3
+ clearMocks: boolean;
4
+ setupFiles: string[];
5
+ preset: string;
6
+ verbose: boolean;
7
+ silent: boolean;
8
+ };
9
+ export default _default;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,4 @@
1
- import { EvaluationContext, JsonValue, Logger, OpenFeatureEventEmitter, Provider, ProviderStatus, ResolutionDetails } from '@openfeature/js-sdk';
1
+ import { EvaluationContext, JsonValue, Logger, OpenFeatureEventEmitter, Provider, ProviderStatus, ResolutionDetails } from '@openfeature/server-sdk';
2
2
  import { FlagdProviderOptions } from './configuration';
3
3
  import { Service } from './service/service';
4
4
  export declare class FlagdProvider implements Provider {
@@ -6,6 +6,7 @@ export declare class FlagdProvider implements Provider {
6
6
  metadata: {
7
7
  name: string;
8
8
  };
9
+ readonly runsOn = "server";
9
10
  get status(): ProviderStatus;
10
11
  get events(): OpenFeatureEventEmitter;
11
12
  private readonly _service;
@@ -1,4 +1,4 @@
1
- import { EvaluationContext, JsonValue, Logger, ResolutionDetails } from '@openfeature/js-sdk';
1
+ import { EvaluationContext, JsonValue, Logger, ResolutionDetails } from '@openfeature/server-sdk';
2
2
  import { ServiceClient } from '../../../proto/ts/schema/v1/schema';
3
3
  import { Config } from '../../configuration';
4
4
  import { Service } from '../service';
@@ -41,10 +41,6 @@ export declare class GRPCService implements Service {
41
41
  private handleFlagsChanged;
42
42
  private handleError;
43
43
  private handleClose;
44
- private objectParser;
45
- private booleanParser;
46
- private stringParser;
47
- private numberParser;
48
44
  private resolve;
49
45
  private onRejected;
50
46
  }
@@ -1,4 +1,4 @@
1
- import { EvaluationContext, JsonValue, Logger, ResolutionDetails } from '@openfeature/js-sdk';
1
+ import { EvaluationContext, JsonValue, Logger, ResolutionDetails } from '@openfeature/server-sdk';
2
2
  export interface Service {
3
3
  connect(reconnectCallback: () => void, changedCallback: (flagsChanged: string[]) => void, disconnectCallback: () => void): Promise<void>;
4
4
  disconnect(): Promise<void>;
@@ -2,6 +2,13 @@
2
2
  import { CallOptions, ChannelCredentials, Client, ClientOptions, ClientReadableStream, ClientUnaryCall, handleServerStreamingCall, handleUnaryCall, Metadata, ServiceError, UntypedServiceImplementation } from "@grpc/grpc-js";
3
3
  import _m0 from "protobufjs/minimal";
4
4
  export declare const protobufPackage = "schema.v1";
5
+ /**
6
+ * Flag evaluation API
7
+ *
8
+ * This proto forms the basis of a flag-evaluation API.
9
+ * It supports single and bulk evaluation RPCs, and flags of various types, as well as establishing a stream for getting notifications about changes in a flag definition.
10
+ * It supports the inclusion of a "context" with each evaluation, which may contain arbitraty attributes relevant to flag evaluation.
11
+ */
5
12
  /** Request body for bulk flag evaluation, used by the ResolveAll rpc. */
6
13
  export interface ResolveAllRequest {
7
14
  /** Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context */
@@ -2,6 +2,12 @@
2
2
  import { CallOptions, ChannelCredentials, Client, ClientOptions, ClientReadableStream, ClientUnaryCall, handleServerStreamingCall, handleUnaryCall, Metadata, ServiceError, UntypedServiceImplementation } from "@grpc/grpc-js";
3
3
  import _m0 from "protobufjs/minimal";
4
4
  export declare const protobufPackage = "sync.v1";
5
+ /**
6
+ * Flag definition sync API
7
+ *
8
+ * This proto defines a simple API to synchronize a feature flag definition.
9
+ * It supports establishing a stream for getting notifications about changes in a flag definition.
10
+ */
5
11
  /**
6
12
  * SyncState conveys the state of the payload. These states are related to flagd isync.go type definitions but
7
13
  * contains extras to optimize grpc use case. Refer - https://github.com/open-feature/flagd/blob/main/pkg/sync/isync.go