json-rest-api 1.0.14 → 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.
- package/connectors_ideas/fastify.js +66 -68
- package/connectors_ideas/koa-plugin.js +50 -51
- package/eslint.config.js +11 -2
- package/examples/url-override-example.js +63 -63
- package/index.js +13 -13
- package/lib/enhanced-logger.js +51 -51
- package/lib/error-formatter.js +61 -61
- package/lib/rest-api-errors.js +28 -28
- package/package.json +1 -1
- package/plugins/core/bulk-operations-plugin.js +142 -145
- package/plugins/core/connectors/express-plugin.js +210 -217
- package/plugins/core/connectors/lib/busboy-detector.js +84 -84
- package/plugins/core/connectors/lib/formidable-detector.js +50 -50
- package/plugins/core/connectors/lib/request-helpers.js +74 -74
- package/plugins/core/file-handling-plugin.js +125 -125
- package/plugins/core/lib/anyapi/anyapi-registry.js +254 -254
- package/plugins/core/lib/anyapi/query/anyapi-query-adapter.js +287 -287
- package/plugins/core/lib/anyapi/schema-utils.js +101 -101
- package/plugins/core/lib/anyapi/utils/descriptor-helpers.js +41 -41
- package/plugins/core/lib/dbTablesOperations.js +134 -135
- package/plugins/core/lib/fractional-positioning.js +74 -76
- package/plugins/core/lib/querying/knex-cross-table-search.js +320 -320
- package/plugins/core/lib/querying/knex-json-api-transformers-querying.js +144 -144
- package/plugins/core/lib/querying/knex-pagination-helpers.js +164 -164
- package/plugins/core/lib/querying/knex-process-includes.js +50 -50
- package/plugins/core/lib/querying/knex-query-helpers-base.js +31 -31
- package/plugins/core/lib/querying/knex-query-helpers.js +451 -452
- package/plugins/core/lib/querying/knex-relationship-includes.js +1160 -1170
- package/plugins/core/lib/querying/knex-window-queries.js +89 -89
- package/plugins/core/lib/querying/url-helpers.js +35 -35
- package/plugins/core/lib/querying-writing/compile-schemas.js +97 -98
- package/plugins/core/lib/querying-writing/connectors-query-parser.js +31 -31
- package/plugins/core/lib/querying-writing/database-capabilities.js +94 -94
- package/plugins/core/lib/querying-writing/database-value-normalizers.js +76 -76
- package/plugins/core/lib/querying-writing/default-data-helpers.js +27 -27
- package/plugins/core/lib/querying-writing/field-utils.js +44 -42
- package/plugins/core/lib/querying-writing/knex-constants.js +15 -16
- package/plugins/core/lib/querying-writing/knex-field-helpers.js +117 -115
- package/plugins/core/lib/querying-writing/knex-json-api-transformers.js +41 -41
- package/plugins/core/lib/querying-writing/payload-validators.js +275 -275
- package/plugins/core/lib/querying-writing/schema-helpers.js +129 -129
- package/plugins/core/lib/querying-writing/scope-validations.js +143 -146
- package/plugins/core/lib/querying-writing/simplified-helpers.js +133 -129
- package/plugins/core/lib/storage/storage-adapter.js +68 -68
- package/plugins/core/lib/writing/knex-json-api-transformers-writing.js +31 -31
- package/plugins/core/lib/writing/many-to-many-manipulations.js +81 -81
- package/plugins/core/lib/writing/relationship-processor.js +58 -58
- package/plugins/core/rest-api-access.js +8 -8
- package/plugins/core/rest-api-anyapi-knex-plugin.js +920 -920
- package/plugins/core/rest-api-cors-plugin.js +170 -171
- package/plugins/core/rest-api-knex-plugin.js +482 -493
- package/plugins/core/rest-api-multihome-plugin.js +247 -251
- package/plugins/core/rest-api-plugin-hooks/compile-resource-schemas.js +5 -5
- package/plugins/core/rest-api-plugin-hooks/register-relationship-routes.js +20 -21
- package/plugins/core/rest-api-plugin-hooks/register-scope-routes.js +44 -44
- package/plugins/core/rest-api-plugin-hooks/turn-scope-init-into-vars.js +23 -23
- package/plugins/core/rest-api-plugin-hooks/validate-include-configurations.js +15 -15
- package/plugins/core/rest-api-plugin-methods/add-route.js +9 -9
- package/plugins/core/rest-api-plugin-methods/check-permissions.js +5 -6
- package/plugins/core/rest-api-plugin-methods/common.js +295 -297
- package/plugins/core/rest-api-plugin-methods/delete-relationship.js +35 -37
- package/plugins/core/rest-api-plugin-methods/delete.js +57 -59
- package/plugins/core/rest-api-plugin-methods/enrich-attributes.js +172 -171
- package/plugins/core/rest-api-plugin-methods/get-related.js +96 -96
- package/plugins/core/rest-api-plugin-methods/get-relationship.js +16 -18
- package/plugins/core/rest-api-plugin-methods/get.js +86 -86
- package/plugins/core/rest-api-plugin-methods/patch-relationship.js +16 -17
- package/plugins/core/rest-api-plugin-methods/patch.js +63 -64
- package/plugins/core/rest-api-plugin-methods/post-relationship.js +54 -55
- package/plugins/core/rest-api-plugin-methods/post.js +61 -62
- package/plugins/core/rest-api-plugin-methods/put.js +86 -87
- package/plugins/core/rest-api-plugin-methods/query.js +88 -88
- package/plugins/core/rest-api-plugin-methods/release.js +5 -6
- package/plugins/core/rest-api-plugin.js +76 -78
- package/plugins/core/rest-api-positioning-plugin.js +251 -252
- package/plugins/core/socketio-plugin.js +240 -236
- package/plugins/storage/local-storage.js +103 -103
- package/plugins/storage/s3-storage.js +41 -42
- package/quickTest.js +37 -37
- package/scripts/debug-anyapi-review-filter.mjs +18 -18
- package/scripts/inspect-anyapi-descriptor-country.mjs +10 -10
- package/scripts/inspect-anyapi-descriptor.mjs +10 -10
- package/scripts/run-docs.js +112 -113
- package/test-debug.js +28 -28
- package/tests/TEST_TEMPLATE.test.js +51 -51
- package/tests/anyapi-basic.test.js +42 -42
- package/tests/anyapi-cursor-pagination.test.js +48 -48
- package/tests/bulk-operations.test.js +208 -208
- package/tests/computed-fields.test.js +204 -204
- package/tests/cors.test.js +412 -413
- package/tests/curl.test.js +275 -276
- package/tests/custom-idproperty-relationships.test.js +266 -266
- package/tests/field-getters.test.js +132 -132
- package/tests/field-setters.test.js +110 -110
- package/tests/fixtures/api-configs.js +699 -699
- package/tests/helpers/storage-mode.js +32 -32
- package/tests/helpers/test-utils.js +76 -76
- package/tests/include-depth-validation.test.js +76 -76
- package/tests/includes.test.js +145 -145
- package/tests/multihome.test.js +175 -175
- package/tests/nested-includes.test.js +255 -255
- package/tests/pagination-cursor-multifield.test.js +164 -164
- package/tests/pagination-enhanced.test.js +225 -225
- package/tests/polymorphic-relationships.test.js +96 -96
- package/tests/polymorphic-simple.test.js +44 -44
- package/tests/positioning-advanced.test.js +226 -226
- package/tests/positioning-extended.test.js +399 -399
- package/tests/positioning-multifilter.test.js +204 -204
- package/tests/positioning.test.js +266 -266
- package/tests/queries.test.js +184 -184
- package/tests/query-limits.test.js +154 -155
- package/tests/relationship-endpoints.test.js +127 -127
- package/tests/relationships.test.js +178 -179
- package/tests/rest-api-access.test.js +86 -86
- package/tests/rest-api.test.js +103 -103
- package/tests/searchschema-merge.test.js +93 -93
- package/tests/socketio.test.js +326 -326
- 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
|
+
}
|