flagsmith-nodejs 4.0.0 → 5.0.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.
@@ -1,3 +1,4 @@
1
1
  export { AnalyticsProcessor, FlagsmithAPIError, FlagsmithClientError, EnvironmentDataPollingManager, FlagsmithCache, DefaultFlag, Flags, Flagsmith, } from './sdk/index.js';
2
+ export { BaseOfflineHandler, LocalFileHandler, } from './sdk/offline_handlers.js';
2
3
  export { FlagsmithConfig } from './sdk/types.js';
3
4
  export { EnvironmentModel, FeatureStateModel, IdentityModel, TraitModel, SegmentModel, OrganisationModel } from './flagsmith-engine/index.js';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.OrganisationModel = exports.SegmentModel = exports.TraitModel = exports.IdentityModel = exports.FeatureStateModel = exports.EnvironmentModel = exports.Flagsmith = exports.Flags = exports.DefaultFlag = exports.EnvironmentDataPollingManager = exports.FlagsmithClientError = exports.FlagsmithAPIError = exports.AnalyticsProcessor = void 0;
3
+ exports.OrganisationModel = exports.SegmentModel = exports.TraitModel = exports.IdentityModel = exports.FeatureStateModel = exports.EnvironmentModel = exports.LocalFileHandler = exports.BaseOfflineHandler = exports.Flagsmith = exports.Flags = exports.DefaultFlag = exports.EnvironmentDataPollingManager = exports.FlagsmithClientError = exports.FlagsmithAPIError = exports.AnalyticsProcessor = void 0;
4
4
  var index_js_1 = require("./sdk/index.js");
5
5
  Object.defineProperty(exports, "AnalyticsProcessor", { enumerable: true, get: function () { return index_js_1.AnalyticsProcessor; } });
6
6
  Object.defineProperty(exports, "FlagsmithAPIError", { enumerable: true, get: function () { return index_js_1.FlagsmithAPIError; } });
@@ -9,6 +9,9 @@ Object.defineProperty(exports, "EnvironmentDataPollingManager", { enumerable: tr
9
9
  Object.defineProperty(exports, "DefaultFlag", { enumerable: true, get: function () { return index_js_1.DefaultFlag; } });
10
10
  Object.defineProperty(exports, "Flags", { enumerable: true, get: function () { return index_js_1.Flags; } });
11
11
  Object.defineProperty(exports, "Flagsmith", { enumerable: true, get: function () { return index_js_1.Flagsmith; } });
12
+ var offline_handlers_js_1 = require("./sdk/offline_handlers.js");
13
+ Object.defineProperty(exports, "BaseOfflineHandler", { enumerable: true, get: function () { return offline_handlers_js_1.BaseOfflineHandler; } });
14
+ Object.defineProperty(exports, "LocalFileHandler", { enumerable: true, get: function () { return offline_handlers_js_1.LocalFileHandler; } });
12
15
  var index_js_2 = require("./flagsmith-engine/index.js");
13
16
  Object.defineProperty(exports, "EnvironmentModel", { enumerable: true, get: function () { return index_js_2.EnvironmentModel; } });
14
17
  Object.defineProperty(exports, "FeatureStateModel", { enumerable: true, get: function () { return index_js_2.FeatureStateModel; } });
@@ -117,10 +117,6 @@ class Flagsmith {
117
117
  this.environment = this.offlineHandler.getEnvironment();
118
118
  }
119
119
  if (!!data.cache) {
120
- const missingMethods = ['has', 'get', 'set'].filter(method => data.cache && !data.cache[method]);
121
- if (missingMethods.length > 0) {
122
- throw new Error(`Please implement the following methods in your cache: ${missingMethods.join(', ')}`);
123
- }
124
120
  this.cache = data.cache;
125
121
  }
126
122
  if (!this.offlineMode) {
@@ -37,7 +37,7 @@ class Flag extends BaseFlag {
37
37
  static fromAPIFlag(flagData) {
38
38
  return new Flag({
39
39
  enabled: flagData['enabled'],
40
- value: flagData['feature_state_value'] || flagData['value'],
40
+ value: flagData['feature_state_value'] ?? flagData['value'],
41
41
  featureId: flagData['feature']['id'],
42
42
  featureName: flagData['feature']['name']
43
43
  });
@@ -4,11 +4,21 @@ import { Dispatcher } from 'undici-types';
4
4
  import { Logger } from 'pino';
5
5
  import { BaseOfflineHandler } from './offline_handlers.js';
6
6
  export type IFlagsmithValue<T = string | number | boolean | null> = T;
7
+ /**
8
+ * Stores and retrieves {@link Flags} from a cache.
9
+ */
7
10
  export interface FlagsmithCache {
8
- get(key: string): Promise<Flags | undefined> | undefined;
9
- set(key: string, value: Flags, ttl?: string | number): boolean | Promise<boolean>;
10
- has(key: string): boolean | Promise<boolean>;
11
- [key: string]: any;
11
+ /**
12
+ * Retrieve the cached {@link Flags} for the given environment or identity, or `undefined` if no cached value exists.
13
+ * @param key An environment ID or identity identifier, which is used as the cache key.
14
+ */
15
+ get(key: string): Promise<Flags | undefined>;
16
+ /**
17
+ * Persist an environment or identity's {@link Flags} in the cache.
18
+ * @param key An environment ID or identity identifier, which is used as the cache key.
19
+ * @param value The {@link Flags} to be stored in the cache.
20
+ */
21
+ set(key: string, value: Flags): Promise<void>;
12
22
  }
13
23
  export type Fetch = typeof fetch;
14
24
  export interface FlagsmithConfig {
@@ -1,3 +1,4 @@
1
1
  export { AnalyticsProcessor, FlagsmithAPIError, FlagsmithClientError, EnvironmentDataPollingManager, FlagsmithCache, DefaultFlag, Flags, Flagsmith, } from './sdk/index.js';
2
+ export { BaseOfflineHandler, LocalFileHandler, } from './sdk/offline_handlers.js';
2
3
  export { FlagsmithConfig } from './sdk/types.js';
3
4
  export { EnvironmentModel, FeatureStateModel, IdentityModel, TraitModel, SegmentModel, OrganisationModel } from './flagsmith-engine/index.js';
@@ -1,2 +1,3 @@
1
1
  export { AnalyticsProcessor, FlagsmithAPIError, FlagsmithClientError, EnvironmentDataPollingManager, DefaultFlag, Flags, Flagsmith, } from './sdk/index.js';
2
+ export { BaseOfflineHandler, LocalFileHandler, } from './sdk/offline_handlers.js';
2
3
  export { EnvironmentModel, FeatureStateModel, IdentityModel, TraitModel, SegmentModel, OrganisationModel } from './flagsmith-engine/index.js';
@@ -108,10 +108,6 @@ export class Flagsmith {
108
108
  this.environment = this.offlineHandler.getEnvironment();
109
109
  }
110
110
  if (!!data.cache) {
111
- const missingMethods = ['has', 'get', 'set'].filter(method => data.cache && !data.cache[method]);
112
- if (missingMethods.length > 0) {
113
- throw new Error(`Please implement the following methods in your cache: ${missingMethods.join(', ')}`);
114
- }
115
111
  this.cache = data.cache;
116
112
  }
117
113
  if (!this.offlineMode) {
@@ -32,7 +32,7 @@ export class Flag extends BaseFlag {
32
32
  static fromAPIFlag(flagData) {
33
33
  return new Flag({
34
34
  enabled: flagData['enabled'],
35
- value: flagData['feature_state_value'] || flagData['value'],
35
+ value: flagData['feature_state_value'] ?? flagData['value'],
36
36
  featureId: flagData['feature']['id'],
37
37
  featureName: flagData['feature']['name']
38
38
  });
@@ -4,11 +4,21 @@ import { Dispatcher } from 'undici-types';
4
4
  import { Logger } from 'pino';
5
5
  import { BaseOfflineHandler } from './offline_handlers.js';
6
6
  export type IFlagsmithValue<T = string | number | boolean | null> = T;
7
+ /**
8
+ * Stores and retrieves {@link Flags} from a cache.
9
+ */
7
10
  export interface FlagsmithCache {
8
- get(key: string): Promise<Flags | undefined> | undefined;
9
- set(key: string, value: Flags, ttl?: string | number): boolean | Promise<boolean>;
10
- has(key: string): boolean | Promise<boolean>;
11
- [key: string]: any;
11
+ /**
12
+ * Retrieve the cached {@link Flags} for the given environment or identity, or `undefined` if no cached value exists.
13
+ * @param key An environment ID or identity identifier, which is used as the cache key.
14
+ */
15
+ get(key: string): Promise<Flags | undefined>;
16
+ /**
17
+ * Persist an environment or identity's {@link Flags} in the cache.
18
+ * @param key An environment ID or identity identifier, which is used as the cache key.
19
+ * @param value The {@link Flags} to be stored in the cache.
20
+ */
21
+ set(key: string, value: Flags): Promise<void>;
12
22
  }
13
23
  export type Fetch = typeof fetch;
14
24
  export interface FlagsmithConfig {
package/index.ts CHANGED
@@ -9,6 +9,11 @@ export {
9
9
  Flagsmith,
10
10
  } from './sdk/index.js';
11
11
 
12
+ export {
13
+ BaseOfflineHandler,
14
+ LocalFileHandler,
15
+ } from './sdk/offline_handlers.js';
16
+
12
17
  export {
13
18
  FlagsmithConfig
14
19
  } from './sdk/types.js'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flagsmith-nodejs",
3
- "version": "4.0.0",
3
+ "version": "5.0.1",
4
4
  "description": "Flagsmith lets you manage features flags and remote config across web, mobile and server side applications. Deliver true Continuous Integration. Get builds out faster. Control who has access to new features.",
5
5
  "main": "./build/cjs/index.js",
6
6
  "type": "module",
package/sdk/index.ts CHANGED
@@ -128,17 +128,6 @@ export class Flagsmith {
128
128
  }
129
129
 
130
130
  if (!!data.cache) {
131
- const missingMethods: string[] = ['has', 'get', 'set'].filter(
132
- method => data.cache && !data.cache[method]
133
- );
134
-
135
- if (missingMethods.length > 0) {
136
- throw new Error(
137
- `Please implement the following methods in your cache: ${missingMethods.join(
138
- ', '
139
- )}`
140
- );
141
- }
142
131
  this.cache = data.cache;
143
132
  }
144
133
 
package/sdk/models.ts CHANGED
@@ -54,7 +54,7 @@ export class Flag extends BaseFlag {
54
54
  static fromAPIFlag(flagData: any): Flag {
55
55
  return new Flag({
56
56
  enabled: flagData['enabled'],
57
- value: flagData['feature_state_value'] || flagData['value'],
57
+ value: flagData['feature_state_value'] ?? flagData['value'],
58
58
  featureId: flagData['feature']['id'],
59
59
  featureName: flagData['feature']['name']
60
60
  });
package/sdk/types.ts CHANGED
@@ -5,11 +5,24 @@ import { Logger } from 'pino';
5
5
  import { BaseOfflineHandler } from './offline_handlers.js';
6
6
 
7
7
  export type IFlagsmithValue<T = string | number | boolean | null> = T;
8
+
9
+
10
+ /**
11
+ * Stores and retrieves {@link Flags} from a cache.
12
+ */
8
13
  export interface FlagsmithCache {
9
- get(key: string): Promise<Flags | undefined> | undefined;
10
- set(key: string, value: Flags, ttl?: string | number): boolean | Promise<boolean>;
11
- has(key: string): boolean | Promise<boolean>;
12
- [key: string]: any;
14
+ /**
15
+ * Retrieve the cached {@link Flags} for the given environment or identity, or `undefined` if no cached value exists.
16
+ * @param key An environment ID or identity identifier, which is used as the cache key.
17
+ */
18
+ get(key: string): Promise<Flags | undefined>;
19
+
20
+ /**
21
+ * Persist an environment or identity's {@link Flags} in the cache.
22
+ * @param key An environment ID or identity identifier, which is used as the cache key.
23
+ * @param value The {@link Flags} to be stored in the cache.
24
+ */
25
+ set(key: string, value: Flags): Promise<void>;
13
26
  }
14
27
 
15
28
  export type Fetch = typeof fetch
@@ -4,15 +4,6 @@ beforeEach(() => {
4
4
  vi.clearAllMocks();
5
5
  });
6
6
 
7
- test('test_wrong_cache_interface_throws_an_error', async () => {
8
- const cache = {
9
- set: () => { },
10
- get: () => { },
11
- };
12
-
13
- expect(() => { const flg = flagsmith({ cache }); }).toThrow();
14
- });
15
-
16
7
  test('test_empty_cache_not_read_but_populated', async () => {
17
8
  fetch.mockResolvedValue(new Response(flagsJSON));
18
9
 
@@ -23,7 +14,7 @@ test('test_empty_cache_not_read_but_populated', async () => {
23
14
  const allFlags = (await flg.getEnvironmentFlags()).allFlags();
24
15
 
25
16
  expect(set).toBeCalled();
26
- expect(await cache.has('flags')).toBe(true);
17
+ expect(await cache.get('flags')).toBeTruthy();
27
18
 
28
19
  expect(fetch).toBeCalledTimes(1);
29
20
  expect(allFlags[0].enabled).toBe(true);
@@ -42,7 +33,7 @@ test('test_api_not_called_when_cache_present', async () => {
42
33
  const allFlags = await (await flg.getEnvironmentFlags()).allFlags();
43
34
 
44
35
  expect(set).toBeCalled();
45
- expect(await cache.has('flags')).toBe(true);
36
+ expect(await cache.get('flags')).toBeTruthy();
46
37
 
47
38
  expect(fetch).toBeCalledTimes(1);
48
39
  expect(allFlags[0].enabled).toBe(true);
@@ -97,7 +88,7 @@ test('test_cache_used_for_identity_flags', async () => {
97
88
  const identityFlags = (await flg.getIdentityFlags(identifier, traits)).allFlags();
98
89
 
99
90
  expect(set).toBeCalled();
100
- expect(await cache.has('flags-identifier')).toBe(true);
91
+ expect(await cache.get('flags-identifier')).toBeTruthy();
101
92
 
102
93
  expect(fetch).toBeCalledTimes(1);
103
94
 
@@ -124,7 +115,7 @@ test('test_cache_used_for_identity_flags_local_evaluation', async () => {
124
115
  const identityFlags = (await flg.getIdentityFlags(identifier, traits)).allFlags();
125
116
 
126
117
  expect(set).toBeCalled();
127
- expect(await cache.has('flags-identifier')).toBe(true);
118
+ expect(await cache.get('flags-identifier')).toBeTruthy();
128
119
 
129
120
  expect(fetch).toBeCalledTimes(1);
130
121
 
@@ -10,17 +10,12 @@ const DATA_DIR = __dirname + '/data/';
10
10
  export class TestCache implements FlagsmithCache {
11
11
  cache: Record<string, Flags> = {};
12
12
 
13
- async get(name: string): Promise<Flags> {
13
+ async get(name: string): Promise<Flags | undefined> {
14
14
  return this.cache[name];
15
15
  }
16
16
 
17
- async has(name: string): Promise<boolean> {
18
- return !!this.cache[name];
19
- }
20
-
21
- async set(name: string, value: Flags, ttl: number|string) {
17
+ async set(name: string, value: Flags) {
22
18
  this.cache[name] = value;
23
- return true
24
19
  }
25
20
  }
26
21