json-rest-api 1.0.13 → 1.0.15

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 (118) hide show
  1. package/connectors_ideas/fastify.js +66 -68
  2. package/connectors_ideas/koa-plugin.js +50 -51
  3. package/eslint.config.js +13 -0
  4. package/examples/url-override-example.js +63 -63
  5. package/index.js +13 -13
  6. package/lib/enhanced-logger.js +51 -51
  7. package/lib/error-formatter.js +61 -61
  8. package/lib/rest-api-errors.js +28 -28
  9. package/package.json +9 -5
  10. package/plugins/core/bulk-operations-plugin.js +142 -145
  11. package/plugins/core/connectors/express-plugin.js +210 -217
  12. package/plugins/core/connectors/lib/busboy-detector.js +84 -84
  13. package/plugins/core/connectors/lib/formidable-detector.js +50 -50
  14. package/plugins/core/connectors/lib/request-helpers.js +74 -74
  15. package/plugins/core/file-handling-plugin.js +125 -125
  16. package/plugins/core/lib/anyapi/anyapi-registry.js +254 -254
  17. package/plugins/core/lib/anyapi/query/anyapi-query-adapter.js +287 -287
  18. package/plugins/core/lib/anyapi/schema-utils.js +101 -101
  19. package/plugins/core/lib/anyapi/utils/descriptor-helpers.js +41 -41
  20. package/plugins/core/lib/dbTablesOperations.js +134 -135
  21. package/plugins/core/lib/fractional-positioning.js +74 -76
  22. package/plugins/core/lib/querying/knex-cross-table-search.js +320 -320
  23. package/plugins/core/lib/querying/knex-json-api-transformers-querying.js +144 -144
  24. package/plugins/core/lib/querying/knex-pagination-helpers.js +164 -164
  25. package/plugins/core/lib/querying/knex-process-includes.js +50 -50
  26. package/plugins/core/lib/querying/knex-query-helpers-base.js +31 -31
  27. package/plugins/core/lib/querying/knex-query-helpers.js +451 -452
  28. package/plugins/core/lib/querying/knex-relationship-includes.js +1160 -1170
  29. package/plugins/core/lib/querying/knex-window-queries.js +89 -89
  30. package/plugins/core/lib/querying/url-helpers.js +35 -35
  31. package/plugins/core/lib/querying-writing/compile-schemas.js +97 -98
  32. package/plugins/core/lib/querying-writing/connectors-query-parser.js +31 -31
  33. package/plugins/core/lib/querying-writing/database-capabilities.js +94 -94
  34. package/plugins/core/lib/querying-writing/database-value-normalizers.js +76 -76
  35. package/plugins/core/lib/querying-writing/default-data-helpers.js +27 -27
  36. package/plugins/core/lib/querying-writing/field-utils.js +44 -42
  37. package/plugins/core/lib/querying-writing/knex-constants.js +15 -16
  38. package/plugins/core/lib/querying-writing/knex-field-helpers.js +117 -115
  39. package/plugins/core/lib/querying-writing/knex-json-api-transformers.js +41 -41
  40. package/plugins/core/lib/querying-writing/payload-validators.js +275 -275
  41. package/plugins/core/lib/querying-writing/schema-helpers.js +129 -129
  42. package/plugins/core/lib/querying-writing/scope-validations.js +143 -146
  43. package/plugins/core/lib/querying-writing/simplified-helpers.js +133 -129
  44. package/plugins/core/lib/storage/storage-adapter.js +68 -68
  45. package/plugins/core/lib/writing/knex-json-api-transformers-writing.js +31 -31
  46. package/plugins/core/lib/writing/many-to-many-manipulations.js +81 -81
  47. package/plugins/core/lib/writing/relationship-processor.js +58 -58
  48. package/plugins/core/rest-api-access.js +8 -8
  49. package/plugins/core/rest-api-anyapi-knex-plugin.js +920 -920
  50. package/plugins/core/rest-api-cors-plugin.js +170 -171
  51. package/plugins/core/rest-api-knex-plugin.js +482 -493
  52. package/plugins/core/rest-api-multihome-plugin.js +247 -251
  53. package/plugins/core/rest-api-plugin-hooks/compile-resource-schemas.js +5 -5
  54. package/plugins/core/rest-api-plugin-hooks/register-relationship-routes.js +20 -21
  55. package/plugins/core/rest-api-plugin-hooks/register-scope-routes.js +44 -44
  56. package/plugins/core/rest-api-plugin-hooks/turn-scope-init-into-vars.js +23 -23
  57. package/plugins/core/rest-api-plugin-hooks/validate-include-configurations.js +15 -15
  58. package/plugins/core/rest-api-plugin-methods/add-route.js +9 -9
  59. package/plugins/core/rest-api-plugin-methods/check-permissions.js +5 -6
  60. package/plugins/core/rest-api-plugin-methods/common.js +295 -297
  61. package/plugins/core/rest-api-plugin-methods/delete-relationship.js +35 -37
  62. package/plugins/core/rest-api-plugin-methods/delete.js +57 -59
  63. package/plugins/core/rest-api-plugin-methods/enrich-attributes.js +172 -171
  64. package/plugins/core/rest-api-plugin-methods/get-related.js +96 -96
  65. package/plugins/core/rest-api-plugin-methods/get-relationship.js +16 -18
  66. package/plugins/core/rest-api-plugin-methods/get.js +86 -86
  67. package/plugins/core/rest-api-plugin-methods/patch-relationship.js +16 -17
  68. package/plugins/core/rest-api-plugin-methods/patch.js +63 -64
  69. package/plugins/core/rest-api-plugin-methods/post-relationship.js +54 -55
  70. package/plugins/core/rest-api-plugin-methods/post.js +61 -62
  71. package/plugins/core/rest-api-plugin-methods/put.js +86 -87
  72. package/plugins/core/rest-api-plugin-methods/query.js +88 -88
  73. package/plugins/core/rest-api-plugin-methods/release.js +5 -6
  74. package/plugins/core/rest-api-plugin.js +76 -78
  75. package/plugins/core/rest-api-positioning-plugin.js +251 -252
  76. package/plugins/core/socketio-plugin.js +240 -236
  77. package/plugins/storage/local-storage.js +103 -103
  78. package/plugins/storage/s3-storage.js +41 -42
  79. package/quickTest.js +37 -37
  80. package/scripts/debug-anyapi-review-filter.mjs +18 -18
  81. package/scripts/inspect-anyapi-descriptor-country.mjs +10 -10
  82. package/scripts/inspect-anyapi-descriptor.mjs +10 -10
  83. package/scripts/run-docs.js +112 -113
  84. package/test-debug.js +28 -28
  85. package/tests/TEST_TEMPLATE.test.js +51 -51
  86. package/tests/anyapi-basic.test.js +42 -42
  87. package/tests/anyapi-cursor-pagination.test.js +48 -48
  88. package/tests/bulk-operations.test.js +208 -208
  89. package/tests/computed-fields.test.js +204 -204
  90. package/tests/cors.test.js +412 -413
  91. package/tests/curl.test.js +275 -276
  92. package/tests/custom-idproperty-relationships.test.js +266 -266
  93. package/tests/field-getters.test.js +132 -132
  94. package/tests/field-setters.test.js +110 -110
  95. package/tests/fixtures/api-configs.js +699 -699
  96. package/tests/helpers/storage-mode.js +32 -32
  97. package/tests/helpers/test-utils.js +76 -76
  98. package/tests/include-depth-validation.test.js +76 -76
  99. package/tests/includes.test.js +145 -145
  100. package/tests/multihome.test.js +175 -175
  101. package/tests/nested-includes.test.js +255 -255
  102. package/tests/pagination-cursor-multifield.test.js +164 -164
  103. package/tests/pagination-enhanced.test.js +225 -225
  104. package/tests/polymorphic-relationships.test.js +96 -96
  105. package/tests/polymorphic-simple.test.js +44 -44
  106. package/tests/positioning-advanced.test.js +226 -226
  107. package/tests/positioning-extended.test.js +399 -399
  108. package/tests/positioning-multifilter.test.js +204 -204
  109. package/tests/positioning.test.js +266 -266
  110. package/tests/queries.test.js +184 -184
  111. package/tests/query-limits.test.js +154 -155
  112. package/tests/relationship-endpoints.test.js +127 -127
  113. package/tests/relationships.test.js +178 -179
  114. package/tests/rest-api-access.test.js +86 -86
  115. package/tests/rest-api.test.js +103 -103
  116. package/tests/searchschema-merge.test.js +93 -93
  117. package/tests/socketio.test.js +326 -326
  118. package/tests/virtual-fields.test.js +164 -164
@@ -8,30 +8,30 @@
8
8
  * @param {Object} req - The request object (Node.js http.IncomingMessage or Express Request)
9
9
  * @returns {string} The client IP address
10
10
  */
11
- export function getClientIP(req) {
11
+ export function getClientIP (req) {
12
12
  // Check X-Forwarded-For header (comma-separated list, first is original client)
13
- const xForwardedFor = req.headers['x-forwarded-for'];
13
+ const xForwardedFor = req.headers['x-forwarded-for']
14
14
  if (xForwardedFor) {
15
- return xForwardedFor.split(',')[0].trim();
15
+ return xForwardedFor.split(',')[0].trim()
16
16
  }
17
-
17
+
18
18
  // Check X-Real-IP header (single IP)
19
- const xRealIP = req.headers['x-real-ip'];
19
+ const xRealIP = req.headers['x-real-ip']
20
20
  if (xRealIP) {
21
- return xRealIP;
21
+ return xRealIP
22
22
  }
23
-
23
+
24
24
  // Check Cloudflare's CF-Connecting-IP
25
- const cfConnectingIP = req.headers['cf-connecting-ip'];
25
+ const cfConnectingIP = req.headers['cf-connecting-ip']
26
26
  if (cfConnectingIP) {
27
- return cfConnectingIP;
27
+ return cfConnectingIP
28
28
  }
29
-
29
+
30
30
  // Fall back to direct connection
31
- return req.connection?.remoteAddress ||
32
- req.socket?.remoteAddress ||
31
+ return req.connection?.remoteAddress ||
32
+ req.socket?.remoteAddress ||
33
33
  req.ip || // Express specific
34
- 'unknown';
34
+ 'unknown'
35
35
  }
36
36
 
37
37
  /**
@@ -39,30 +39,30 @@ export function getClientIP(req) {
39
39
  * @param {Object} req - The request object
40
40
  * @returns {boolean} True if the request is secure
41
41
  */
42
- export function isSecure(req) {
42
+ export function isSecure (req) {
43
43
  // Express-specific property
44
44
  if (req.secure !== undefined) {
45
- return req.secure;
45
+ return req.secure
46
46
  }
47
-
47
+
48
48
  // Check X-Forwarded-Proto header (used by proxies)
49
- const xForwardedProto = req.headers['x-forwarded-proto'];
49
+ const xForwardedProto = req.headers['x-forwarded-proto']
50
50
  if (xForwardedProto) {
51
- return xForwardedProto === 'https';
51
+ return xForwardedProto === 'https'
52
52
  }
53
-
53
+
54
54
  // Check if connection is encrypted (Node.js)
55
55
  if (req.connection?.encrypted) {
56
- return true;
56
+ return true
57
57
  }
58
-
58
+
59
59
  // Check protocol directly
60
60
  if (req.protocol === 'https') {
61
- return true;
61
+ return true
62
62
  }
63
-
63
+
64
64
  // Default to false
65
- return false;
65
+ return false
66
66
  }
67
67
 
68
68
  /**
@@ -70,53 +70,53 @@ export function isSecure(req) {
70
70
  * @param {Object} req - The request object
71
71
  * @returns {string} The hostname
72
72
  */
73
- export function getHostname(req) {
73
+ export function getHostname (req) {
74
74
  // Express-specific property
75
75
  if (req.hostname) {
76
- return req.hostname;
76
+ return req.hostname
77
77
  }
78
-
78
+
79
79
  // Check Host header
80
- const hostHeader = req.headers.host;
80
+ const hostHeader = req.headers.host
81
81
  if (hostHeader) {
82
82
  // Remove port if present
83
- const colonIndex = hostHeader.indexOf(':');
84
- return colonIndex === -1 ? hostHeader : hostHeader.substring(0, colonIndex);
83
+ const colonIndex = hostHeader.indexOf(':')
84
+ return colonIndex === -1 ? hostHeader : hostHeader.substring(0, colonIndex)
85
85
  }
86
-
86
+
87
87
  // Fall back
88
- return 'localhost';
88
+ return 'localhost'
89
89
  }
90
90
 
91
91
  /**
92
92
  * Get the port from the request
93
- * @param {Object} req - The request object
93
+ * @param {Object} req - The request object
94
94
  * @returns {number|null} The port number or null
95
95
  */
96
- export function getPort(req) {
96
+ export function getPort (req) {
97
97
  // Check Host header for port
98
- const hostHeader = req.headers.host;
98
+ const hostHeader = req.headers.host
99
99
  if (hostHeader) {
100
- const colonIndex = hostHeader.indexOf(':');
100
+ const colonIndex = hostHeader.indexOf(':')
101
101
  if (colonIndex !== -1) {
102
- const port = parseInt(hostHeader.substring(colonIndex + 1), 10);
102
+ const port = parseInt(hostHeader.substring(colonIndex + 1), 10)
103
103
  if (!isNaN(port)) {
104
- return port;
104
+ return port
105
105
  }
106
106
  }
107
107
  }
108
-
108
+
109
109
  // Check connection local port
110
110
  if (req.connection?.localPort) {
111
- return req.connection.localPort;
111
+ return req.connection.localPort
112
112
  }
113
-
113
+
114
114
  if (req.socket?.localPort) {
115
- return req.socket.localPort;
115
+ return req.socket.localPort
116
116
  }
117
-
117
+
118
118
  // Default ports based on protocol
119
- return isSecure(req) ? 443 : 80;
119
+ return isSecure(req) ? 443 : 80
120
120
  }
121
121
 
122
122
  /**
@@ -124,30 +124,30 @@ export function getPort(req) {
124
124
  * @param {string} cookieString - The cookie header value
125
125
  * @returns {Object} Parsed cookies as key-value pairs
126
126
  */
127
- export function parseCookies(cookieString) {
128
- const cookies = {};
129
-
127
+ export function parseCookies (cookieString) {
128
+ const cookies = {}
129
+
130
130
  if (!cookieString || typeof cookieString !== 'string') {
131
- return cookies;
131
+ return cookies
132
132
  }
133
-
133
+
134
134
  // Split by semicolons and parse each cookie
135
135
  cookieString.split(';').forEach(cookie => {
136
- const trimmedCookie = cookie.trim();
136
+ const trimmedCookie = cookie.trim()
137
137
  if (trimmedCookie) {
138
- const eqIndex = trimmedCookie.indexOf('=');
138
+ const eqIndex = trimmedCookie.indexOf('=')
139
139
  if (eqIndex !== -1) {
140
- const name = trimmedCookie.substring(0, eqIndex).trim();
141
- const value = trimmedCookie.substring(eqIndex + 1).trim();
140
+ const name = trimmedCookie.substring(0, eqIndex).trim()
141
+ const value = trimmedCookie.substring(eqIndex + 1).trim()
142
142
  if (name) {
143
143
  // Remove quotes if present
144
- cookies[name] = value.replace(/^"(.*)"$/, '$1');
144
+ cookies[name] = value.replace(/^"(.*)"$/, '$1')
145
145
  }
146
146
  }
147
147
  }
148
- });
149
-
150
- return cookies;
148
+ })
149
+
150
+ return cookies
151
151
  }
152
152
 
153
153
  /**
@@ -155,26 +155,26 @@ export function parseCookies(cookieString) {
155
155
  * @param {Object} req - The request object
156
156
  * @returns {string|null} The extracted token or null
157
157
  */
158
- export function extractToken(req) {
158
+ export function extractToken (req) {
159
159
  // Check Authorization header for Bearer token
160
- const authHeader = req.headers.authorization || req.headers.Authorization;
160
+ const authHeader = req.headers.authorization || req.headers.Authorization
161
161
  if (authHeader && typeof authHeader === 'string') {
162
- const bearerMatch = authHeader.match(/^Bearer\s+(.+)$/i);
162
+ const bearerMatch = authHeader.match(/^Bearer\s+(.+)$/i)
163
163
  if (bearerMatch) {
164
- return bearerMatch[1];
164
+ return bearerMatch[1]
165
165
  }
166
166
  }
167
167
 
168
168
  // Check cookies for session token (Auth.js pattern)
169
- const cookies = parseCookies(req.headers.cookie || '');
169
+ const cookies = parseCookies(req.headers.cookie || '')
170
170
  if (cookies['__Secure-authjs.session-token']) {
171
- return cookies['__Secure-authjs.session-token'];
171
+ return cookies['__Secure-authjs.session-token']
172
172
  }
173
173
  if (cookies['authjs.session-token']) {
174
- return cookies['authjs.session-token'];
174
+ return cookies['authjs.session-token']
175
175
  }
176
176
 
177
- return null;
177
+ return null
178
178
  }
179
179
 
180
180
  /**
@@ -184,7 +184,7 @@ export function extractToken(req) {
184
184
  * @param {string} source - The source plugin ('http' or 'express')
185
185
  * @returns {Object} The context object
186
186
  */
187
- export function createContext(req, res, source) {
187
+ export function createContext (req, res, source) {
188
188
  const context = {
189
189
  source,
190
190
  auth: {
@@ -206,17 +206,17 @@ export function createContext(req, res, source) {
206
206
  raw: { req, res },
207
207
  handled: false,
208
208
  rejection: null
209
- };
210
-
209
+ }
210
+
211
211
  // Add reject function
212
212
  context.reject = (status, message, details = {}) => {
213
- context.handled = true;
213
+ context.handled = true
214
214
  context.rejection = {
215
215
  status,
216
216
  message,
217
217
  ...details
218
- };
219
- };
220
-
221
- return context;
222
- }
218
+ }
219
+ }
220
+
221
+ return context
222
+ }