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
|
@@ -1,72 +1,71 @@
|
|
|
1
|
-
|
|
2
|
-
import { parseJsonApiQuery } from "../lib/querying-writing/connectors-query-parser.js";
|
|
1
|
+
import { parseJsonApiQuery } from '../lib/querying-writing/connectors-query-parser.js'
|
|
3
2
|
|
|
4
3
|
export default async function registerRelationshipRoutes ({ context, api, log }) {
|
|
5
|
-
const { scopeName } = context
|
|
6
|
-
const basePath = api.scopes[scopeName].vars.transport?.mountPath || ''
|
|
7
|
-
const scopePath = `${basePath}/${scopeName}
|
|
4
|
+
const { scopeName } = context
|
|
5
|
+
const basePath = api.scopes[scopeName].vars.transport?.mountPath || ''
|
|
6
|
+
const scopePath = `${basePath}/${scopeName}`
|
|
8
7
|
|
|
9
8
|
// Helper to create route handlers
|
|
10
9
|
const createRouteHandler = (methodName) => {
|
|
11
10
|
return async ({ params, body, queryString }) => {
|
|
12
|
-
const scope = api.scopes[scopeName]
|
|
13
|
-
|
|
11
|
+
const scope = api.scopes[scopeName]
|
|
12
|
+
|
|
14
13
|
const methodParams = {
|
|
15
14
|
id: params.id,
|
|
16
15
|
relationshipName: params.relationshipName,
|
|
17
16
|
isTransport: true
|
|
18
|
-
}
|
|
17
|
+
}
|
|
19
18
|
|
|
20
19
|
// Add query params for getRelated
|
|
21
20
|
if (methodName === 'getRelated' && queryString) {
|
|
22
|
-
methodParams.queryParams = parseJsonApiQuery(queryString)
|
|
21
|
+
methodParams.queryParams = parseJsonApiQuery(queryString)
|
|
23
22
|
}
|
|
24
23
|
|
|
25
24
|
// Add body data for write operations
|
|
26
25
|
if (body && body.data !== undefined) {
|
|
27
|
-
methodParams.relationshipData = body.data
|
|
26
|
+
methodParams.relationshipData = body.data
|
|
28
27
|
}
|
|
29
28
|
|
|
30
|
-
return await scope[methodName](methodParams)
|
|
31
|
-
}
|
|
32
|
-
}
|
|
29
|
+
return await scope[methodName](methodParams)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
33
32
|
|
|
34
33
|
// Register relationship routes
|
|
35
|
-
|
|
34
|
+
|
|
36
35
|
// GET /api/{scope}/{id}/relationships/{relationshipName}
|
|
37
36
|
await api.addRoute({
|
|
38
37
|
method: 'GET',
|
|
39
38
|
path: `${scopePath}/:id/relationships/:relationshipName`,
|
|
40
39
|
handler: createRouteHandler('getRelationship')
|
|
41
|
-
})
|
|
40
|
+
})
|
|
42
41
|
|
|
43
42
|
// GET /api/{scope}/{id}/{relationshipName}
|
|
44
43
|
await api.addRoute({
|
|
45
44
|
method: 'GET',
|
|
46
45
|
path: `${scopePath}/:id/:relationshipName`,
|
|
47
46
|
handler: createRouteHandler('getRelated')
|
|
48
|
-
})
|
|
47
|
+
})
|
|
49
48
|
|
|
50
49
|
// POST /api/{scope}/{id}/relationships/{relationshipName}
|
|
51
50
|
await api.addRoute({
|
|
52
51
|
method: 'POST',
|
|
53
52
|
path: `${scopePath}/:id/relationships/:relationshipName`,
|
|
54
53
|
handler: createRouteHandler('postRelationship')
|
|
55
|
-
})
|
|
54
|
+
})
|
|
56
55
|
|
|
57
56
|
// PATCH /api/{scope}/{id}/relationships/{relationshipName}
|
|
58
57
|
await api.addRoute({
|
|
59
58
|
method: 'PATCH',
|
|
60
59
|
path: `${scopePath}/:id/relationships/:relationshipName`,
|
|
61
60
|
handler: createRouteHandler('patchRelationship')
|
|
62
|
-
})
|
|
61
|
+
})
|
|
63
62
|
|
|
64
63
|
// DELETE /api/{scope}/{id}/relationships/{relationshipName}
|
|
65
64
|
await api.addRoute({
|
|
66
65
|
method: 'DELETE',
|
|
67
66
|
path: `${scopePath}/:id/relationships/:relationshipName`,
|
|
68
67
|
handler: createRouteHandler('deleteRelationship')
|
|
69
|
-
})
|
|
68
|
+
})
|
|
70
69
|
|
|
71
|
-
log.trace(`Registered relationship routes for scope: ${scopeName}`)
|
|
72
|
-
}
|
|
70
|
+
log.trace(`Registered relationship routes for scope: ${scopeName}`)
|
|
71
|
+
}
|
|
@@ -1,102 +1,102 @@
|
|
|
1
|
-
import { RestApiResourceError } from '../../../lib/rest-api-errors.js'
|
|
2
|
-
import { parseJsonApiQuery } from '../lib/querying-writing/connectors-query-parser.js'
|
|
1
|
+
import { RestApiResourceError } from '../../../lib/rest-api-errors.js'
|
|
2
|
+
import { parseJsonApiQuery } from '../lib/querying-writing/connectors-query-parser.js'
|
|
3
|
+
|
|
4
|
+
export default async function registerScopeRoutes ({ context, api, vars, log }) {
|
|
5
|
+
const { scopeName } = context
|
|
6
|
+
const basePath = vars.transport?.mountPath || ''
|
|
3
7
|
|
|
4
|
-
export default async function registerScopeRoutes({ context, api, vars, log }) {
|
|
5
|
-
const { scopeName } = context;
|
|
6
|
-
const basePath = vars.transport?.mountPath || '';
|
|
7
|
-
|
|
8
8
|
// Helper to create route handlers
|
|
9
9
|
const createRouteHandler = (scopeName, methodName) => {
|
|
10
10
|
return async ({ queryString, headers, params, body, context }) => {
|
|
11
|
-
const scope = api.scopes[scopeName]
|
|
11
|
+
const scope = api.scopes[scopeName]
|
|
12
12
|
if (!scope) {
|
|
13
13
|
throw new RestApiResourceError(
|
|
14
14
|
`Scope '${scopeName}' not found`,
|
|
15
|
-
{
|
|
15
|
+
{
|
|
16
16
|
subtype: 'not_found',
|
|
17
17
|
resourceType: 'scope',
|
|
18
18
|
resourceId: scopeName
|
|
19
19
|
}
|
|
20
|
-
)
|
|
20
|
+
)
|
|
21
21
|
}
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
// Build parameters for the scope method
|
|
24
|
-
const methodParams = {}
|
|
25
|
-
|
|
24
|
+
const methodParams = {}
|
|
25
|
+
|
|
26
26
|
// Add ID for single-resource operations
|
|
27
27
|
if (['get', 'put', 'patch', 'delete'].includes(methodName)) {
|
|
28
|
-
methodParams.id = params.id
|
|
28
|
+
methodParams.id = params.id
|
|
29
29
|
}
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
// Parse query parameters for read operations
|
|
32
32
|
if (['query', 'get'].includes(methodName)) {
|
|
33
|
-
methodParams.queryParams = parseJsonApiQuery(queryString)
|
|
34
|
-
methodParams.isTransport = true
|
|
33
|
+
methodParams.queryParams = parseJsonApiQuery(queryString)
|
|
34
|
+
methodParams.isTransport = true
|
|
35
35
|
}
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
// Add body for write operations
|
|
38
38
|
if (['post', 'put', 'patch'].includes(methodName)) {
|
|
39
|
-
methodParams.inputRecord = body
|
|
40
|
-
methodParams.isTransport = true
|
|
41
|
-
|
|
39
|
+
methodParams.inputRecord = body
|
|
40
|
+
methodParams.isTransport = true
|
|
41
|
+
|
|
42
42
|
// Add query params for includes/fields on write operations
|
|
43
43
|
if (queryString) {
|
|
44
|
-
methodParams.queryParams = parseJsonApiQuery(queryString)
|
|
44
|
+
methodParams.queryParams = parseJsonApiQuery(queryString)
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
// Call the scope method
|
|
49
|
-
const result = await scope[methodName](methodParams, context)
|
|
50
|
-
|
|
49
|
+
const result = await scope[methodName](methodParams, context)
|
|
50
|
+
|
|
51
51
|
// Return the result (transport plugin handles response formatting)
|
|
52
|
-
return result
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const scopePath = `${basePath}/${scopeName}
|
|
57
|
-
|
|
52
|
+
return result
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const scopePath = `${basePath}/${scopeName}`
|
|
57
|
+
|
|
58
58
|
// Register routes for each HTTP method
|
|
59
59
|
// GET /api/{scope} - Query collection
|
|
60
60
|
await api.addRoute({
|
|
61
61
|
method: 'GET',
|
|
62
62
|
path: scopePath,
|
|
63
63
|
handler: createRouteHandler(scopeName, 'query')
|
|
64
|
-
})
|
|
65
|
-
|
|
64
|
+
})
|
|
65
|
+
|
|
66
66
|
// GET /api/{scope}/{id} - Get single resource
|
|
67
67
|
await api.addRoute({
|
|
68
68
|
method: 'GET',
|
|
69
69
|
path: `${scopePath}/:id`,
|
|
70
70
|
handler: createRouteHandler(scopeName, 'get')
|
|
71
|
-
})
|
|
72
|
-
|
|
71
|
+
})
|
|
72
|
+
|
|
73
73
|
// POST /api/{scope} - Create resource
|
|
74
74
|
await api.addRoute({
|
|
75
75
|
method: 'POST',
|
|
76
76
|
path: scopePath,
|
|
77
77
|
handler: createRouteHandler(scopeName, 'post')
|
|
78
|
-
})
|
|
79
|
-
|
|
78
|
+
})
|
|
79
|
+
|
|
80
80
|
// PUT /api/{scope}/{id} - Replace resource
|
|
81
81
|
await api.addRoute({
|
|
82
82
|
method: 'PUT',
|
|
83
83
|
path: `${scopePath}/:id`,
|
|
84
84
|
handler: createRouteHandler(scopeName, 'put')
|
|
85
|
-
})
|
|
86
|
-
|
|
85
|
+
})
|
|
86
|
+
|
|
87
87
|
// PATCH /api/{scope}/{id} - Update resource
|
|
88
88
|
await api.addRoute({
|
|
89
89
|
method: 'PATCH',
|
|
90
90
|
path: `${scopePath}/:id`,
|
|
91
91
|
handler: createRouteHandler(scopeName, 'patch')
|
|
92
|
-
})
|
|
93
|
-
|
|
92
|
+
})
|
|
93
|
+
|
|
94
94
|
// DELETE /api/{scope}/{id} - Delete resource
|
|
95
95
|
await api.addRoute({
|
|
96
96
|
method: 'DELETE',
|
|
97
97
|
path: `${scopePath}/:id`,
|
|
98
98
|
handler: createRouteHandler(scopeName, 'delete')
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
log.info(`Routes registered for scope '${scopeName}'`)
|
|
102
|
-
}
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
log.info(`Routes registered for scope '${scopeName}'`)
|
|
102
|
+
}
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
export default async function turnScopeInitIntoVars({ context, scopes, vars: apiVars }) {
|
|
1
|
+
export default async function turnScopeInitIntoVars ({ context, scopes, vars: apiVars }) {
|
|
2
2
|
// Refer to the scope's vars
|
|
3
|
-
const scope = scopes[context.scopeName]
|
|
4
|
-
const scopeOptions = scope?.scopeOptions || context.scopeOptions || {}
|
|
5
|
-
const vars = scope?.vars || apiVars
|
|
3
|
+
const scope = scopes[context.scopeName]
|
|
4
|
+
const scopeOptions = scope?.scopeOptions || context.scopeOptions || {}
|
|
5
|
+
const vars = scope?.vars || apiVars
|
|
6
6
|
|
|
7
7
|
// The scope-specific ones
|
|
8
|
-
vars.sortableFields = scopeOptions.sortableFields || []
|
|
9
|
-
vars.defaultSort = scopeOptions.defaultSort || null
|
|
8
|
+
vars.sortableFields = scopeOptions.sortableFields || []
|
|
9
|
+
vars.defaultSort = scopeOptions.defaultSort || null
|
|
10
10
|
|
|
11
11
|
// The general ones that are also set at api level, but overrideable
|
|
12
|
-
if (typeof scopeOptions.queryDefaultLimit !== 'undefined') vars.queryDefaultLimit = scopeOptions.queryDefaultLimit
|
|
13
|
-
if (typeof scopeOptions.queryMaxLimit !== 'undefined') vars.queryMaxLimit = scopeOptions.queryMaxLimit
|
|
14
|
-
if (typeof scopeOptions.includeDepthLimit !== 'undefined') vars.includeDepthLimit = scopeOptions.includeDepthLimit
|
|
15
|
-
if (typeof scopeOptions.enablePaginationCounts !== 'undefined') vars.enablePaginationCounts = scopeOptions.enablePaginationCounts
|
|
16
|
-
|
|
12
|
+
if (typeof scopeOptions.queryDefaultLimit !== 'undefined') vars.queryDefaultLimit = scopeOptions.queryDefaultLimit
|
|
13
|
+
if (typeof scopeOptions.queryMaxLimit !== 'undefined') vars.queryMaxLimit = scopeOptions.queryMaxLimit
|
|
14
|
+
if (typeof scopeOptions.includeDepthLimit !== 'undefined') vars.includeDepthLimit = scopeOptions.includeDepthLimit
|
|
15
|
+
if (typeof scopeOptions.enablePaginationCounts !== 'undefined') vars.enablePaginationCounts = scopeOptions.enablePaginationCounts
|
|
16
|
+
|
|
17
17
|
// Set simplified settings as scope vars
|
|
18
|
-
if (typeof scopeOptions.simplifiedApi !== 'undefined') vars.simplifiedApi = scopeOptions.simplifiedApi
|
|
19
|
-
if (typeof scopeOptions.simplifiedTransport !== 'undefined') vars.simplifiedTransport = scopeOptions.simplifiedTransport
|
|
20
|
-
|
|
18
|
+
if (typeof scopeOptions.simplifiedApi !== 'undefined') vars.simplifiedApi = scopeOptions.simplifiedApi
|
|
19
|
+
if (typeof scopeOptions.simplifiedTransport !== 'undefined') vars.simplifiedTransport = scopeOptions.simplifiedTransport
|
|
20
|
+
|
|
21
21
|
// Set returnRecord settings as scope vars
|
|
22
|
-
if (typeof scopeOptions.returnRecordApi !== 'undefined') vars.returnRecordApi = scopeOptions.returnRecordApi
|
|
23
|
-
if (typeof scopeOptions.returnRecordTransport !== 'undefined') vars.returnRecordTransport = scopeOptions.returnRecordTransport
|
|
24
|
-
|
|
22
|
+
if (typeof scopeOptions.returnRecordApi !== 'undefined') vars.returnRecordApi = scopeOptions.returnRecordApi
|
|
23
|
+
if (typeof scopeOptions.returnRecordTransport !== 'undefined') vars.returnRecordTransport = scopeOptions.returnRecordTransport
|
|
24
|
+
|
|
25
25
|
// Set idProperty as scope var
|
|
26
|
-
if (typeof scopeOptions.idProperty !== 'undefined') vars.idProperty = scopeOptions.idProperty
|
|
26
|
+
if (typeof scopeOptions.idProperty !== 'undefined') vars.idProperty = scopeOptions.idProperty
|
|
27
27
|
|
|
28
28
|
// Add validation for query limits
|
|
29
29
|
if (vars.queryDefaultLimit && vars.queryMaxLimit) {
|
|
@@ -31,10 +31,10 @@ export default async function turnScopeInitIntoVars({ context, scopes, vars: api
|
|
|
31
31
|
throw new Error(
|
|
32
32
|
`Invalid scope '${context.scopeName}' configuration: ` +
|
|
33
33
|
`queryDefaultLimit (${vars.queryDefaultLimit}) cannot exceed queryMaxLimit (${vars.queryMaxLimit})`
|
|
34
|
-
)
|
|
34
|
+
)
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
-
|
|
37
|
+
|
|
38
38
|
// Validate relationship include limits at scope creation time
|
|
39
39
|
Object.entries(scopeOptions.relationships || {}).forEach(([relName, relDef]) => {
|
|
40
40
|
if (relDef.include?.limit && vars.queryMaxLimit) {
|
|
@@ -42,8 +42,8 @@ export default async function turnScopeInitIntoVars({ context, scopes, vars: api
|
|
|
42
42
|
throw new Error(
|
|
43
43
|
`Invalid relationship '${context.scopeName}.${relName}' configuration: ` +
|
|
44
44
|
`include.limit (${relDef.include.limit}) cannot exceed queryMaxLimit (${vars.queryMaxLimit})`
|
|
45
|
-
)
|
|
45
|
+
)
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
|
-
})
|
|
49
|
-
}
|
|
48
|
+
})
|
|
49
|
+
}
|
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
export default async function validateIncludeConfigurations({ context, scopes, log }) {
|
|
2
|
-
const { scopeName } = context
|
|
3
|
-
const scope = scopes[scopeName]
|
|
4
|
-
const relationships = scope.vars.schemaInfo?.schemaRelationships
|
|
5
|
-
|
|
6
|
-
if (!relationships) return
|
|
7
|
-
|
|
1
|
+
export default async function validateIncludeConfigurations ({ context, scopes, log }) {
|
|
2
|
+
const { scopeName } = context
|
|
3
|
+
const scope = scopes[scopeName]
|
|
4
|
+
const relationships = scope.vars.schemaInfo?.schemaRelationships
|
|
5
|
+
|
|
6
|
+
if (!relationships) return
|
|
7
|
+
|
|
8
8
|
// Check each relationship for include configuration
|
|
9
9
|
for (const [relName, relDef] of Object.entries(relationships)) {
|
|
10
10
|
if (relDef.include?.strategy === 'window') {
|
|
11
11
|
// This relationship requires window functions
|
|
12
12
|
// We'll validate this at query time since the database might not be connected yet
|
|
13
|
-
log.debug(`Relationship ${scopeName}.${relName} configured for window function includes`)
|
|
13
|
+
log.debug(`Relationship ${scopeName}.${relName} configured for window function includes`)
|
|
14
14
|
}
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
// Validate include configuration
|
|
17
17
|
if (relDef.include?.limit) {
|
|
18
18
|
if (typeof relDef.include.limit !== 'number') {
|
|
19
19
|
throw new Error(
|
|
20
20
|
`Invalid include limit for ${scopeName}.${relName}: limit must be a number`
|
|
21
|
-
)
|
|
21
|
+
)
|
|
22
22
|
}
|
|
23
23
|
// Check against queryMaxLimit if available
|
|
24
|
-
const maxLimit = scope.vars?.queryMaxLimit
|
|
24
|
+
const maxLimit = scope.vars?.queryMaxLimit
|
|
25
25
|
if (maxLimit && relDef.include.limit > maxLimit) {
|
|
26
26
|
throw new Error(
|
|
27
27
|
`Invalid include limit for ${scopeName}.${relName}: ` +
|
|
28
28
|
`limit (${relDef.include.limit}) exceeds queryMaxLimit (${maxLimit})`
|
|
29
|
-
)
|
|
29
|
+
)
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
if (relDef.include?.orderBy && !Array.isArray(relDef.include.orderBy)) {
|
|
34
34
|
throw new Error(
|
|
35
35
|
`Invalid include orderBy for ${scopeName}.${relName}: orderBy must be an array`
|
|
36
|
-
)
|
|
36
|
+
)
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
-
}
|
|
39
|
+
}
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { ValidationError } from 'hooked-api'
|
|
1
|
+
import { ValidationError } from 'hooked-api'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* addRoute
|
|
5
5
|
* Registers a new route with the transport layer
|
|
6
6
|
*/
|
|
7
7
|
export default async ({ params, context, runHooks }) => {
|
|
8
|
-
const { method, path, handler } = params
|
|
9
|
-
|
|
8
|
+
const { method, path, handler } = params
|
|
9
|
+
|
|
10
10
|
// Validate route configuration
|
|
11
11
|
if (!method || !path || !handler) {
|
|
12
|
-
throw new ValidationError('Route requires method, path, and handler')
|
|
12
|
+
throw new ValidationError('Route requires method, path, and handler')
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
// debugger
|
|
16
16
|
// Create context for enrichAttributes hooks
|
|
17
17
|
Object.assign(context, params)
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
// Run the addRoute hook to notify transport plugins
|
|
20
|
-
await runHooks('addRoute')
|
|
21
|
-
|
|
22
|
-
return { registered: true, method, path }
|
|
23
|
-
}
|
|
20
|
+
await runHooks('addRoute')
|
|
21
|
+
|
|
22
|
+
return { registered: true, method, path }
|
|
23
|
+
}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* checkPermissions
|
|
3
3
|
* Check if ther are permissions to access a resource.
|
|
4
|
-
*
|
|
4
|
+
*
|
|
5
5
|
*/
|
|
6
|
-
export default async function checkPermissionsMethod({ context, params, runHooks, scopeName, scopes, helpers }) {
|
|
7
|
-
|
|
6
|
+
export default async function checkPermissionsMethod ({ context, params, runHooks, scopeName, scopes, helpers }) {
|
|
8
7
|
Object.assign(context, {
|
|
9
8
|
method: params.method,
|
|
10
9
|
originalContext: params.originalContext,
|
|
11
10
|
})
|
|
12
|
-
|
|
13
|
-
await runHooks('checkPermissions')
|
|
14
|
-
}
|
|
11
|
+
|
|
12
|
+
await runHooks('checkPermissions')
|
|
13
|
+
}
|