flagsmith-nodejs 2.2.2 → 2.3.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.
Files changed (56) hide show
  1. package/build/sdk/index.d.ts +5 -17
  2. package/build/sdk/index.js +2 -0
  3. package/build/sdk/types.d.ts +19 -1
  4. package/build/sdk/utils.d.ts +2 -2
  5. package/{es6-example → examples/api-proxy}/.babelrc +0 -0
  6. package/{es6-example → examples/api-proxy}/.eslintrc +0 -0
  7. package/examples/api-proxy/.idea/api-proxy.iml +12 -0
  8. package/examples/api-proxy/.idea/codeStyles/Project.xml +60 -0
  9. package/examples/api-proxy/.idea/codeStyles/codeStyleConfig.xml +5 -0
  10. package/examples/api-proxy/.idea/inspectionProfiles/Project_Default.xml +6 -0
  11. package/examples/api-proxy/.idea/modules.xml +8 -0
  12. package/examples/api-proxy/.idea/vcs.xml +6 -0
  13. package/examples/api-proxy/README.md +12 -0
  14. package/examples/api-proxy/package-lock.json +10895 -0
  15. package/examples/api-proxy/package.json +57 -0
  16. package/examples/api-proxy/src/api/index.js +42 -0
  17. package/{es6-example → examples/api-proxy}/src/index.js +0 -0
  18. package/examples/basic/.babelrc +3 -0
  19. package/examples/basic/.eslintrc +8 -0
  20. package/examples/basic/README.md +10 -0
  21. package/{es6-example → examples/basic}/package-lock.json +25 -39
  22. package/{es6-example → examples/basic}/package.json +1 -1
  23. package/examples/basic/src/api/index.js +33 -0
  24. package/{example/server → examples/basic/src}/index.js +4 -4
  25. package/examples/caching/.babelrc +3 -0
  26. package/examples/caching/.eslintrc +8 -0
  27. package/examples/caching/README.md +9 -0
  28. package/examples/caching/package-lock.json +10782 -0
  29. package/examples/caching/package.json +56 -0
  30. package/{example/server → examples/caching/src}/api/index.js +7 -11
  31. package/examples/caching/src/index.js +29 -0
  32. package/examples/custom-fetch-agent/.babelrc +3 -0
  33. package/examples/custom-fetch-agent/.eslintrc +8 -0
  34. package/examples/custom-fetch-agent/README.md +12 -0
  35. package/examples/custom-fetch-agent/package-lock.json +10782 -0
  36. package/examples/custom-fetch-agent/package.json +56 -0
  37. package/examples/custom-fetch-agent/src/api/index.js +34 -0
  38. package/examples/custom-fetch-agent/src/index.js +29 -0
  39. package/examples/local-evaluation/.babelrc +3 -0
  40. package/examples/local-evaluation/.eslintrc +8 -0
  41. package/examples/local-evaluation/README.md +18 -0
  42. package/examples/local-evaluation/package-lock.json +10782 -0
  43. package/examples/local-evaluation/package.json +56 -0
  44. package/{es6-example → examples/local-evaluation}/src/api/index.js +2 -13
  45. package/examples/local-evaluation/src/index.js +29 -0
  46. package/package.json +1 -1
  47. package/sdk/index.ts +8 -15
  48. package/sdk/types.ts +19 -2
  49. package/sdk/utils.ts +2 -2
  50. package/tests/sdk/flagsmith.test.ts +25 -10
  51. package/es6-example/README.md +0 -62
  52. package/example/LICENSE +0 -0
  53. package/example/Procfile +0 -1
  54. package/example/README.md +0 -15
  55. package/example/package-lock.json +0 -2387
  56. package/example/package.json +0 -27
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "nodejs-es6-boilerplate",
3
+ "version": "1.0.1",
4
+ "description": "Node.js boilerplate with ES6, ESLint, and Prettier",
5
+ "main": "src/index.js",
6
+ "browserslist": [
7
+ "last 2 Chrome versions"
8
+ ],
9
+ "scripts": {
10
+ "test": "echo \"Error: no test specified\" && exit 1",
11
+ "clean": "rm -rf build && mkdir build",
12
+ "build-babel": "babel -d ./build ./src -s",
13
+ "build": "npm run clean && npm run build-babel",
14
+ "dev": "nodemon --exec npm start --ignore ./build",
15
+ "node-cache": "^5.1.2",
16
+ "ssg-node-express": "4.16.4",
17
+ "start": "npm run build && node ./build/index.js",
18
+ "format": "prettier --write \"src/**/*.js\"",
19
+ "format:check": "prettier --list-different \"src/**/*.js\"",
20
+ "lint": "eslint \"src/**/*.js\"",
21
+ "lint:fix": "eslint --fix \"src/**/*.js\""
22
+ },
23
+ "repository": "github:vferdiansyah/nodejs-es6-boilerplate",
24
+ "keywords": [
25
+ "javascript",
26
+ "node",
27
+ "nodejs",
28
+ "es6",
29
+ "eslint",
30
+ "prettier",
31
+ "boilerplate"
32
+ ],
33
+ "author": {
34
+ "name": "Veri Ferdiansyah",
35
+ "email": "veri.ferdi@gmail.com",
36
+ "url": "https://vferdiansyah.github.io"
37
+ },
38
+ "license": "MIT",
39
+ "bugs": "https://github.com/vferdiansyah/nodejs-es6-boilerplate/issues",
40
+ "homepage": "https://github.com/vferdiansyah/nodejs-es6-boilerplate#readme",
41
+ "devDependencies": {
42
+ "@babel/cli": "^7.5.5",
43
+ "@babel/core": "^7.5.5",
44
+ "@babel/preset-env": "^7.5.5",
45
+ "eslint": "^6.2.1",
46
+ "eslint-config-prettier": "^6.1.0",
47
+ "eslint-plugin-prettier": "^3.1.0",
48
+ "express": "^4.18.1",
49
+ "nodemon": "^2.0.19",
50
+ "prettier": "^1.18.2"
51
+ },
52
+ "dependencies": {
53
+ "flagsmith-nodejs": "^2.2.2",
54
+ "node-cache": "^5.1.2"
55
+ }
56
+ }
@@ -1,8 +1,7 @@
1
1
  import {Router} from 'express'
2
- import Flagsmith from 'flagsmith-nodejs'
2
+ import Flagsmith from '../../../../build'
3
3
 
4
4
  const environmentKey = '';
5
- import nodecache from "node-cache";
6
5
 
7
6
  if (!environmentKey) {
8
7
  throw new Error(
@@ -11,19 +10,9 @@ if (!environmentKey) {
11
10
  }
12
11
  const flagsmith = new Flagsmith({
13
12
  environmentKey,
14
- enableLocalEvaluation: true,
15
- cache: new nodecache({
16
- stdTTL: 10,
17
- checkperiod: 10,
18
- }),
13
+ enableLocalEvaluation: true
19
14
  });
20
15
 
21
-
22
- // solicitor
23
-
24
- // read only
25
- // sra authorisation date
26
-
27
16
  const api = () => {
28
17
  const api = Router();
29
18
 
@@ -0,0 +1,29 @@
1
+ import http from 'http'
2
+ import express from 'express'
3
+ import bodyParser from 'body-parser'
4
+ import api from './api'
5
+ const PORT = process.env.PORT || 3000;
6
+ const app = express();
7
+
8
+ app.server = http.createServer(app);
9
+
10
+ //Apply middleware
11
+ // parse various different custom JSON types as JSON
12
+ app.use(bodyParser.json());
13
+
14
+ // api router
15
+ app.use('/api', api());
16
+
17
+ app.server.listen(PORT);
18
+ console.log('Server started on port ' + PORT);
19
+ console.log();
20
+ console.log('Go to http://localhost:' + PORT + '/api');
21
+ console.log('To get an example response for getFlags');
22
+ console.log();
23
+ console.log('Go to http://localhost:' + PORT + '/api/flagsmith_sample_user');
24
+ console.log('To get an example feature state for a user');
25
+ console.log();
26
+ console.log('Go to http://localhost:' + PORT + '/api/flagsmith_sample_user/segments');
27
+ console.log('To get the segments which the user belongs to');
28
+
29
+ module.exports = app;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flagsmith-nodejs",
3
- "version": "2.2.2",
3
+ "version": "2.3.0",
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/index.js",
6
6
  "repository": {
package/sdk/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { RequestInit } from "node-fetch";
1
2
  import { getEnvironmentFeatureStates, getIdentityFeatureStates } from '../flagsmith-engine';
2
3
  import { EnvironmentModel } from '../flagsmith-engine/environments/models';
3
4
  import { buildEnvironmentModel } from '../flagsmith-engine/environments/util';
@@ -12,22 +13,24 @@ import { EnvironmentDataPollingManager } from './polling_manager';
12
13
  import { generateIdentitiesData, retryFetch } from './utils';
13
14
  import { SegmentModel } from '../flagsmith-engine/segments/models';
14
15
  import { getIdentitySegments } from '../flagsmith-engine/segments/evaluators';
15
- import { FlagsmithCache } from './types';
16
+ import { FlagsmithCache, FlagsmithConfig } from './types';
16
17
 
17
18
  export { AnalyticsProcessor } from './analytics';
18
19
  export { FlagsmithAPIError, FlagsmithClientError } from './errors';
19
20
 
20
21
  export { DefaultFlag, Flags } from './models';
21
22
  export { EnvironmentDataPollingManager } from './polling_manager';
22
- export { FlagsmithCache } from './types';
23
+ export { FlagsmithCache, FlagsmithConfig } from './types';
23
24
 
24
25
  const DEFAULT_API_URL = 'https://edge.api.flagsmith.com/api/v1/';
25
26
 
27
+
26
28
  export class Flagsmith {
27
29
  environmentKey?: string;
28
30
  apiUrl: string = DEFAULT_API_URL;
29
31
  customHeaders?: { [key: string]: any };
30
32
  requestTimeoutSeconds?: number;
33
+ agent: RequestInit['agent'];
31
34
  requestTimeoutMs?: number;
32
35
  enableLocalEvaluation?: boolean = false;
33
36
  environmentRefreshIntervalSeconds: number = 60;
@@ -76,19 +79,8 @@ export class Flagsmith {
76
79
  flags cannot be retrieved from the API or a non existent feature is
77
80
  requested
78
81
  */
79
- constructor(data: {
80
- environmentKey: string;
81
- apiUrl?: string;
82
- customHeaders?: { [key: string]: any };
83
- requestTimeoutSeconds?: number;
84
- enableLocalEvaluation?: boolean;
85
- environmentRefreshIntervalSeconds?: number;
86
- retries?: number;
87
- enableAnalytics?: boolean;
88
- defaultFlagHandler?: (featureName: string) => DefaultFlag;
89
- cache?: FlagsmithCache,
90
- onEnvironmentChange?: (error: Error | null, result: EnvironmentModel) => void,
91
- }) {
82
+ constructor(data: FlagsmithConfig) {
83
+ this.agent = data.agent;
92
84
  this.environmentKey = data.environmentKey;
93
85
  this.apiUrl = data.apiUrl || this.apiUrl;
94
86
  this.customHeaders = data.customHeaders;
@@ -276,6 +268,7 @@ export class Flagsmith {
276
268
  const data = await retryFetch(
277
269
  url,
278
270
  {
271
+ agent: this.agent,
279
272
  method: method,
280
273
  timeout: this.requestTimeoutMs || undefined,
281
274
  body: JSON.stringify(body),
package/sdk/types.ts CHANGED
@@ -1,8 +1,25 @@
1
- import { Flags } from "./models";
1
+ import { DefaultFlag, Flags } from "./models";
2
+ import { EnvironmentModel } from "../flagsmith-engine";
3
+ import { RequestInit } from "node-fetch";
2
4
 
3
5
  export interface FlagsmithCache {
4
6
  get(key: string): Promise<Flags|undefined> | undefined;
5
7
  set(key: string, value: Flags, ttl: string | number): boolean | Promise<boolean>;
6
8
  has(key: string): boolean | Promise<boolean>;
7
9
  [key: string]: any;
8
- }
10
+ }
11
+
12
+ export interface FlagsmithConfig {
13
+ environmentKey: string;
14
+ apiUrl?: string;
15
+ agent?:RequestInit['agent'];
16
+ customHeaders?: { [key: string]: any };
17
+ requestTimeoutSeconds?: number;
18
+ enableLocalEvaluation?: boolean;
19
+ environmentRefreshIntervalSeconds?: number;
20
+ retries?: number;
21
+ enableAnalytics?: boolean;
22
+ defaultFlagHandler?: (featureName: string) => DefaultFlag;
23
+ cache?: FlagsmithCache,
24
+ onEnvironmentChange?: (error: Error | null, result: EnvironmentModel) => void,
25
+ }
package/sdk/utils.ts CHANGED
@@ -1,4 +1,4 @@
1
- import fetch, { Response } from 'node-fetch';
1
+ import fetch, { RequestInit, Response } from 'node-fetch';
2
2
  // @ts-ignore
3
3
  if (typeof fetch.default !== 'undefined') fetch = fetch.default;
4
4
 
@@ -18,7 +18,7 @@ export const delay = (ms: number) =>
18
18
 
19
19
  export const retryFetch = (
20
20
  url: string,
21
- fetchOptions: any,
21
+ fetchOptions: RequestInit,
22
22
  retries = 3,
23
23
  timeout?: number // set an overall timeout for this function
24
24
  ): Promise<Response> => {
@@ -1,10 +1,12 @@
1
1
  import Flagsmith from '../../sdk';
2
2
  import { EnvironmentDataPollingManager } from '../../sdk/polling_manager';
3
- import fetch from 'node-fetch';
3
+ import fetch, {RequestInit} from 'node-fetch';
4
4
  import { environmentJSON, environmentModel, flagsJSON, flagsmith, identitiesJSON } from './utils';
5
5
  import { DefaultFlag } from '../../sdk/models';
6
- import { delay } from '../../sdk/utils';
6
+ import {delay, retryFetch} from '../../sdk/utils';
7
+ import * as utils from '../../sdk/utils';
7
8
  import { EnvironmentModel } from '../../flagsmith-engine/environments/models';
9
+ import https from 'https'
8
10
 
9
11
  jest.mock('node-fetch');
10
12
  jest.mock('../../sdk/polling_manager');
@@ -56,6 +58,26 @@ test('test_update_environment_sets_environment', async () => {
56
58
  expect(flg.environment).toStrictEqual(model);
57
59
  });
58
60
 
61
+ test('test_set_agent_options', async () => {
62
+ const agent = new https.Agent({})
63
+
64
+ // @ts-ignore
65
+ fetch.mockImplementation((url:string, options:RequestInit)=>{
66
+ if(options.agent!==agent) {
67
+ throw new Error("Agent has not been set on retry fetch")
68
+ }
69
+ return Promise.resolve(new Response(environmentJSON()))
70
+ });
71
+
72
+ const flg = flagsmith({
73
+ agent
74
+ });
75
+
76
+ await flg.updateEnvironment();
77
+ expect(flg.environment).toBeDefined();
78
+
79
+ });
80
+
59
81
  test('test_get_identity_segments', async () => {
60
82
  // @ts-ignore
61
83
  fetch.mockReturnValue(Promise.resolve(new Response(environmentJSON())));
@@ -81,11 +103,6 @@ test('test_get_identity_segments_empty_without_local_eval', async () => {
81
103
  expect(segments.length).toBe(0);
82
104
  });
83
105
 
84
-
85
-
86
-
87
-
88
-
89
106
  test('test_update_environment_uses_req_when_inited', async () => {
90
107
  // @ts-ignore
91
108
  fetch.mockReturnValue(Promise.resolve(new Response(environmentJSON())));
@@ -160,8 +177,6 @@ test('test_default_flag_used_after_multiple_API_errors', async () => {
160
177
  expect(flag.value).toBe(defaultFlag.value);
161
178
  });
162
179
 
163
-
164
-
165
180
  test('test_throws_when_no_identity_flags_returned_due_to_error', async () => {
166
181
  // @ts-ignore
167
182
  fetch.mockReturnValue(Promise.resolve(new Response('bad data')));
@@ -215,4 +230,4 @@ test('test onEnvironmentChange is called after error', async () => {
215
230
  await delay(200);
216
231
 
217
232
  expect(callbackSpy).toBeCalled();
218
- });
233
+ });
@@ -1,62 +0,0 @@
1
- # Nodejs-ES6-Boilerplate
2
- [![Made in Indonesia](https://made-in-indonesia.github.io/made-in-indonesia.svg)](https://github.com/made-in-indonesia/made-in-indonesia)
3
-
4
- A Node.js boilerplate with ES6, ESLint, and Prettier
5
-
6
- ## Background
7
-
8
- I created this boilerplate because I have several coding interviews that needs to be done using JavaScript.
9
-
10
- ## Scripts
11
-
12
- ```bash
13
- # Run the project without nodemon
14
- npm run start
15
-
16
- # Build the project
17
- npm run build
18
-
19
- # Clean build
20
- npm run clean
21
-
22
- # Check the lint errors
23
- npm run lint
24
-
25
- # Fix the lint errors
26
- npm run lint:fix
27
-
28
- # Run prettier
29
- npm run format
30
-
31
- # Check prettier errors
32
- npm run format:check
33
- ```
34
-
35
- ## Usage
36
-
37
- 1. Clone the repository and init new git project
38
-
39
- ```bash
40
- $ git clone git@github.com:vferdiansyah/nodejs-es6-boilerplate.git ./your/project/folder
41
- $ cd ./your/project/folder
42
- $ rm -rf .git
43
- $ git init
44
- ```
45
-
46
- 2. Change project specific information in the following places
47
-
48
- - [package.json](./package.json)
49
- - [README.md](./README.md)
50
-
51
- 3. Install dependencies
52
-
53
- ```bash
54
- $ npm i
55
- ```
56
-
57
- 4. Start coding
58
-
59
- ## License
60
-
61
- Copyright (c) 2020 Veri Ferdiansyah
62
- Licensed under the MIT license.
package/example/LICENSE DELETED
File without changes
package/example/Procfile DELETED
@@ -1 +0,0 @@
1
- web: npm start
package/example/README.md DELETED
@@ -1,15 +0,0 @@
1
- # Flagsmith example
2
-
3
- ## Getting Started
4
-
5
- # Run
6
-
7
- `$ npm start`
8
-
9
- # Nodemon (Restart server on changes)
10
-
11
- `npm run dev`
12
-
13
- # The project
14
-
15
- - `/server/api` contains a simple express api that interacts with Flagsmith