just-another-http-api 1.4.0 → 1.4.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/api.js CHANGED
@@ -163,6 +163,7 @@ function handleResponse ( reply, response, method, path ) {
163
163
  }
164
164
 
165
165
  setResponseHeaders ( reply, response );
166
+ setResponseCookies ( reply, response );
166
167
  handleSpecialResponseTypes ( reply, response, method, path );
167
168
  }
168
169
 
@@ -174,6 +175,16 @@ function setResponseHeaders ( reply, response ) {
174
175
  }
175
176
  }
176
177
 
178
+ function setResponseCookies ( reply, response ) {
179
+ if (response.cookies) {
180
+ Object.entries(response.cookies).forEach(([name, cookieVal]) => {
181
+ if (cookieVal && 'value' in cookieVal) {
182
+ reply.setCookie(name, cookieVal.value, cookieVal.options || {});
183
+ }
184
+ });
185
+ }
186
+ }
187
+
177
188
  function handleSpecialResponseTypes ( reply, response, method, path ) {
178
189
  if ( response.redirect ) {
179
190
  reply.redirect ( 301, response.redirect.url );
package/config/default.js CHANGED
@@ -4,4 +4,4 @@ module.exports = {
4
4
  host: process.env.REDIS_HOST || 'localhost',
5
5
  prefix: process.env.REDIS_PREFIX || 'api:'
6
6
  }
7
- };
7
+ };
@@ -0,0 +1,51 @@
1
+ module.exports = [ {
2
+ languageOptions: {
3
+ ecmaVersion: 2021,
4
+ sourceType: 'module',
5
+ parserOptions: {
6
+ ecmaFeatures: {
7
+ jsx: true
8
+ }
9
+ }
10
+ },
11
+ rules: {
12
+ 'max-len': 'off',
13
+ 'semi': [ 'error', 'always' ],
14
+ 'no-underscore-dangle': 'off',
15
+ 'class-methods-use-this': 'off',
16
+ 'no-param-reassign': 'off',
17
+ 'no-restricted-syntax': 'warn',
18
+ 'no-continue': 'warn',
19
+ 'consistent-return': 'warn',
20
+ 'guard-for-in': 'warn',
21
+ 'import/no-commonjs': 'off',
22
+ 'import/no-dynamic-require': 'off',
23
+ 'new-cap': 'warn',
24
+ 'no-nested-ternary': 'off',
25
+ 'prefer-const': 'error',
26
+ 'newline-before-return': [ 'error', 'always' ],
27
+ 'quotes': [ 'error', 'single' ],
28
+ 'no-multiple-empty-lines': [ 'error', { max: 1 } ],
29
+ 'space-before-function-paren': [ 'error', 'always' ],
30
+ 'func-call-spacing': [ 'error', 'always' ],
31
+ 'block-spacing': [ 'error', 'always' ],
32
+ 'space-in-parens': [ 'error', 'always' ],
33
+ 'object-curly-spacing': [ 'error', 'always' ],
34
+ 'no-spaced-func': 'off',
35
+ 'space-unary-ops': [ 'error', { 'words': true, 'nonwords': false, 'overrides': { 'new': false, '++': false } } ],
36
+ 'arrow-spacing': [ 'error', { 'before': true, 'after': true } ],
37
+ 'indent': [ 'error', 4, { 'SwitchCase': 1 } ],
38
+ 'key-spacing': [ 'error', { 'beforeColon': false, 'afterColon': true } ],
39
+ 'computed-property-spacing': [ 'error', 'always' ],
40
+ 'array-bracket-spacing': [ 'error', 'never' ],
41
+ 'comma-spacing': [ 'error', { 'before': false, 'after': true } ],
42
+ 'brace-style': [ 'error', 'stroustrup' ],
43
+ 'space-infix-ops': 'error',
44
+ 'keyword-spacing': [ 'error', { overrides: {
45
+ if: { after: true },
46
+ for: { after: true },
47
+ while: { after: true }
48
+ } } ],
49
+ 'array-bracket-spacing': [ 'error', 'always' ],
50
+ },
51
+ } ];
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "just-another-http-api",
3
- "version": "1.4.0",
3
+ "version": "1.4.2",
4
4
  "description": "A framework built on top of fastify aimed at removing the need for any network or server configuration. ",
5
5
  "homepage": "https://github.com/OllieEdge/just-another-http-api#readme",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "https://github.com/OllieEdge/just-another-http-api.git"
8
+ "url": "git+https://github.com/OllieEdge/just-another-http-api.git"
9
9
  },
10
10
  "main": "api.js",
11
11
  "scripts": {
@@ -25,23 +25,24 @@
25
25
  "author": "Oliver Edgington <oliver@edgington.com> (https://github.com/OllieEdge)",
26
26
  "license": "MIT",
27
27
  "dependencies": {
28
- "@aws-sdk/lib-storage": "^3.454.0",
28
+ "@aws-sdk/lib-storage": "^3.569.0",
29
29
  "@fastify/caching": "^8.3.0",
30
30
  "@fastify/cookie": "^9.4.0",
31
- "@fastify/cors": "^8.4.1",
31
+ "@fastify/cors": "^9.0.1",
32
32
  "@fastify/jwt": "^7.2.3",
33
- "@fastify/redis": "^6.1.1",
34
- "@fastify/websocket": "^8.2.0",
33
+ "@fastify/redis": "^6.2.0",
34
+ "@fastify/websocket": "^10.0.1",
35
35
  "abstract-cache": "^1.0.1",
36
36
  "abstract-cache-redis": "^2.0.0",
37
- "fastify": "^4.24.3",
37
+ "eip-cloud-services": "^1.2.3",
38
+ "fastify": "^4.27.0",
38
39
  "fastify-multer": "^2.0.3",
39
40
  "recursive-readdir": "^2.2.3"
40
41
  },
41
42
  "devDependencies": {
42
43
  "chai": "^4.3.10",
43
44
  "chai-as-promised": "^7.1.1",
44
- "eip-cloud-services": "^1.1.0",
45
- "mocha": "^10.2.0"
45
+ "eslint": "^9.2.0",
46
+ "mocha": "^10.4.0"
46
47
  }
47
48
  }
@@ -11,6 +11,7 @@ class WebsocketGroup {
11
11
  this.connections = new Map ();
12
12
  this.messageReceivedHandler = messageReceivedHandler || ( async () => {} );
13
13
  this.connectionClosedHandler = connectionClosedHandler;
14
+ this.pingConnections = setInterval ( this.#pingConnections.bind ( this ), 30000 );
14
15
  }
15
16
 
16
17
  async initialize () {
@@ -31,17 +32,30 @@ class WebsocketGroup {
31
32
 
32
33
  #broadcastMessageToClients ( message ) {
33
34
  this.connections.forEach ( conn => {
34
- conn.socket.send ( typeof message === 'string' ? message : JSON.stringify ( message ) );
35
+ conn.send ( typeof message === 'string' ? message : JSON.stringify ( message ) );
35
36
  } );
36
37
  }
37
38
 
38
39
  #handleIndividualMessage ( individualMessage ) {
39
40
  const { connectionId, message } = JSON.parse ( individualMessage );
40
41
  if(this.connections.has(connectionId)) {
41
- this.connections.get(connectionId).socket.send(message);
42
+ this.connections.get(connectionId).send(message);
42
43
  }
43
44
  }
44
45
 
46
+ #pingConnections () {
47
+ this.connections.forEach ( ( connection, connectionId ) => {
48
+ if(!connection.isAlive) {
49
+ this.connections.delete ( connectionId );
50
+ this.#clean(connectionId);
51
+ }
52
+ else{
53
+ connection.isAlive = false;
54
+ connection.ping ();
55
+ }
56
+ } );
57
+ }
58
+
45
59
  getConnections () {
46
60
  return this.connections;
47
61
  }
@@ -55,9 +69,10 @@ class WebsocketGroup {
55
69
  }
56
70
 
57
71
  addNewConnection ( connection, connectionId = crypto.randomUUID () ) {
72
+ connection.isAlive = true;
58
73
  this.connections.set ( connectionId, connection );
59
74
 
60
- connection.socket.on ( 'message', async message => {
75
+ connection.on ( 'message', async message => {
61
76
  const userMessage = {
62
77
  groupName: this.groupName,
63
78
  connectionId,
@@ -66,12 +81,16 @@ class WebsocketGroup {
66
81
  await redis.publish ( `${this.groupName}_messageReceived`, JSON.stringify ( userMessage ) );
67
82
  } );
68
83
 
69
- connection.socket.on ( 'close', () => {
84
+ connection.on ( 'close', () => {
70
85
  this.connections.delete ( connectionId );
71
86
  this.#clean(connectionId);
72
87
  } );
88
+
89
+ connection.on ( 'pong', () => {
90
+ connection.isAlive = true;
91
+ } );
73
92
 
74
- connection.socket.on ( 'error', error => {
93
+ connection.on ( 'error', error => {
75
94
  console.error ( 'WebSocket error:', error );
76
95
  this.connections.delete ( connectionId );
77
96
  this.#clean(connectionId);
@@ -92,6 +111,7 @@ class WebsocketGroup {
92
111
  }
93
112
 
94
113
  if ( this.connections.size === 0 ) {
114
+ clearInterval ( this.pingConnections );
95
115
  this.connections.clear ();
96
116
  await redis.unsubscribe ( `${this.groupName}_individualMessage` );
97
117
  await redis.unsubscribe ( `${this.groupName}_broadcast` );
package/.eslintrc DELETED
@@ -1,148 +0,0 @@
1
- {
2
- "parserOptions": {
3
- "ecmaVersion": 12,
4
- "sourceType": "module",
5
- "ecmaFeatures": {
6
- "jsx": true
7
- }
8
- },
9
- "env": {
10
- "commonjs": true,
11
- "node": true
12
- },
13
- "globals": {
14
- "__lib": "readonly",
15
- "__routes": "readonly",
16
- "__base": "readonly",
17
- "__utils": "readonly"
18
- },
19
- "rules": {
20
- "max-len": [
21
- "off",
22
- 120
23
- ],
24
- "semi": [
25
- "error",
26
- "always"
27
- ],
28
- "no-underscore-dangle": 0,
29
- "class-methods-use-this": 0,
30
- "no-param-reassign": 0,
31
- "no-restricted-syntax": 1,
32
- "no-continue": 1,
33
- "consistent-return": 1,
34
- "guard-for-in": 1,
35
- "import/no-commonjs": 0,
36
- "import/no-dynamic-require": 0,
37
- "new-cap": 1,
38
- "no-nested-ternary": 0,
39
- "prefer-const": "error",
40
- "newline-before-return": "error",
41
- "quotes": [
42
- "error",
43
- "single"
44
- ],
45
- "no-multiple-empty-lines": [
46
- "error",
47
- {
48
- "max": 1
49
- }
50
- ],
51
- "space-before-function-paren": [
52
- "error",
53
- "always"
54
- ],
55
- "func-call-spacing": [
56
- "error",
57
- "always"
58
- ],
59
- "block-spacing": [
60
- "error",
61
- "always"
62
- ],
63
- "space-in-parens": [
64
- "error",
65
- "always"
66
- ],
67
- "object-curly-spacing": [
68
- "error",
69
- "always"
70
- ],
71
- "no-spaced-func": 0,
72
- "space-unary-ops": [
73
- "error",
74
- {
75
- "words": true,
76
- "nonwords": false,
77
- "overrides": {
78
- "new": false,
79
- "++": false
80
- }
81
- }
82
- ],
83
- "arrow-spacing": [
84
- "error",
85
- {
86
- "before": true,
87
- "after": true
88
- }
89
- ],
90
- "indent": [
91
- "error",
92
- 4,
93
- {
94
- "SwitchCase": 1
95
- }
96
- ],
97
- "key-spacing": [
98
- "error",
99
- {
100
- "beforeColon": false,
101
- "afterColon": true
102
- }
103
- ],
104
- "computed-property-spacing": [
105
- "error",
106
- "always"
107
- ],
108
- "array-bracket-spacing": [
109
- "error",
110
- "always"
111
- ],
112
- "comma-spacing": [
113
- "error",
114
- {
115
- "before": false,
116
- "after": true
117
- }
118
- ],
119
- "brace-style": [
120
- "error",
121
- "stroustrup"
122
- ],
123
- "space-infix-ops": [
124
- "error",
125
- {
126
- "int32Hint": true
127
- }
128
- ],
129
- "keyword-spacing": [
130
- "error",
131
- {
132
- "overrides": {
133
- "if": {
134
- "after": true
135
- },
136
- "for": {
137
- "after": true
138
- },
139
- "while": {
140
- "after": true
141
- }
142
- }
143
- }
144
- ],
145
- "no-octal-escape": 0,
146
- "no-octal": 0
147
- }
148
- }