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.
- package/connectors_ideas/fastify.js +66 -68
- package/connectors_ideas/koa-plugin.js +50 -51
- package/eslint.config.js +13 -0
- 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 +9 -5
- 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,13 +1,13 @@
|
|
|
1
|
-
import { buildIncludedResources } from './knex-relationship-includes.js'
|
|
1
|
+
import { buildIncludedResources } from './knex-relationship-includes.js'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Processes the ?include= parameter to load related resources efficiently
|
|
5
|
-
*
|
|
5
|
+
*
|
|
6
6
|
* @param {Object} scope - The scope object for the primary resource
|
|
7
7
|
* @param {Array<Object>} records - The primary records to load includes for
|
|
8
8
|
* @param {Object} deps - Dependencies object containing log, scopes, knex, and context
|
|
9
9
|
* @returns {Promise<Array<Object>>} Array of included resources in JSON:API format
|
|
10
|
-
*
|
|
10
|
+
*
|
|
11
11
|
* @example
|
|
12
12
|
* // Input: Articles with author relationship
|
|
13
13
|
* const articles = [
|
|
@@ -15,37 +15,37 @@ import { buildIncludedResources } from './knex-relationship-includes.js';
|
|
|
15
15
|
* { id: 2, title: 'Second Article', author_id: 11 },
|
|
16
16
|
* { id: 3, title: 'Third Article', author_id: 10 } // Same author as article 1
|
|
17
17
|
* ];
|
|
18
|
-
*
|
|
18
|
+
*
|
|
19
19
|
* const deps = {
|
|
20
|
-
* context: {
|
|
20
|
+
* context: {
|
|
21
21
|
* scopeName: 'articles',
|
|
22
22
|
* queryParams: { include: ['author'] },
|
|
23
23
|
* schemaInfo: { idProperty: 'id' }
|
|
24
24
|
* }
|
|
25
25
|
* };
|
|
26
|
-
*
|
|
26
|
+
*
|
|
27
27
|
* const included = await processIncludes(scope, articles, deps);
|
|
28
|
-
*
|
|
28
|
+
*
|
|
29
29
|
* // Output: Deduplicated authors (only 2, not 3)
|
|
30
30
|
* // [
|
|
31
31
|
* // { type: 'users', id: '10', attributes: { name: 'Alice', email: 'alice@example.com' } },
|
|
32
32
|
* // { type: 'users', id: '11', attributes: { name: 'Bob', email: 'bob@example.com' } }
|
|
33
33
|
* // ]
|
|
34
|
-
*
|
|
34
|
+
*
|
|
35
35
|
* @example
|
|
36
36
|
* // Input: Nested includes with dot notation
|
|
37
37
|
* const articles = [{ id: 1, title: 'Article', author_id: 10 }];
|
|
38
|
-
*
|
|
38
|
+
*
|
|
39
39
|
* const deps = {
|
|
40
40
|
* context: {
|
|
41
|
-
* queryParams: {
|
|
41
|
+
* queryParams: {
|
|
42
42
|
* include: ['author', 'comments.user'] // Load author AND comment users
|
|
43
43
|
* }
|
|
44
44
|
* }
|
|
45
45
|
* };
|
|
46
|
-
*
|
|
46
|
+
*
|
|
47
47
|
* const included = await processIncludes(scope, articles, deps);
|
|
48
|
-
*
|
|
48
|
+
*
|
|
49
49
|
* // Output: All related resources in flat array
|
|
50
50
|
* // [
|
|
51
51
|
* // { type: 'users', id: '10', attributes: { name: 'Author' } },
|
|
@@ -54,41 +54,41 @@ import { buildIncludedResources } from './knex-relationship-includes.js';
|
|
|
54
54
|
* // { type: 'users', id: '20', attributes: { name: 'Commenter1' } },
|
|
55
55
|
* // { type: 'users', id: '21', attributes: { name: 'Commenter2' } }
|
|
56
56
|
* // ]
|
|
57
|
-
*
|
|
57
|
+
*
|
|
58
58
|
* @example
|
|
59
59
|
* // Input: With sparse fieldsets limiting included data
|
|
60
60
|
* const deps = {
|
|
61
61
|
* context: {
|
|
62
|
-
* queryParams: {
|
|
62
|
+
* queryParams: {
|
|
63
63
|
* include: ['author'],
|
|
64
|
-
* fields: {
|
|
64
|
+
* fields: {
|
|
65
65
|
* users: 'name' // Only include name field for users
|
|
66
66
|
* }
|
|
67
67
|
* }
|
|
68
68
|
* }
|
|
69
69
|
* };
|
|
70
|
-
*
|
|
70
|
+
*
|
|
71
71
|
* const included = await processIncludes(scope, articles, deps);
|
|
72
|
-
*
|
|
72
|
+
*
|
|
73
73
|
* // Output: Users with only requested fields
|
|
74
74
|
* // [
|
|
75
75
|
* // { type: 'users', id: '10', attributes: { name: 'Alice' } }
|
|
76
76
|
* // // email field excluded due to sparse fieldset
|
|
77
77
|
* // ]
|
|
78
|
-
*
|
|
78
|
+
*
|
|
79
79
|
* @description
|
|
80
80
|
* Used by:
|
|
81
81
|
* - rest-api-knex-plugin's dataGet method when includes are requested
|
|
82
82
|
* - rest-api-knex-plugin's dataQuery method for collection includes
|
|
83
83
|
* - Called after primary records are fetched but before response assembly
|
|
84
|
-
*
|
|
84
|
+
*
|
|
85
85
|
* Purpose:
|
|
86
86
|
* - Implements JSON:API compound documents with primary data and includes
|
|
87
87
|
* - Prevents N+1 queries by batch loading all related resources
|
|
88
88
|
* - Handles complex nested includes like 'comments.author.company'
|
|
89
89
|
* - Automatically deduplicates included resources
|
|
90
90
|
* - Respects sparse fieldsets on included resources
|
|
91
|
-
*
|
|
91
|
+
*
|
|
92
92
|
* Data flow:
|
|
93
93
|
* 1. Receives primary records and include directives
|
|
94
94
|
* 2. Parses include parameter (comma-separated, possibly nested with dots)
|
|
@@ -98,27 +98,27 @@ import { buildIncludedResources } from './knex-relationship-includes.js';
|
|
|
98
98
|
*/
|
|
99
99
|
export const processIncludes = async (scope, records, deps) => {
|
|
100
100
|
try {
|
|
101
|
-
const { log, scopes, knex, context, api } = deps
|
|
102
|
-
|
|
103
|
-
const scopeName = context.scopeName
|
|
104
|
-
|
|
101
|
+
const { log, scopes, knex, context, api } = deps
|
|
102
|
+
|
|
103
|
+
const scopeName = context.scopeName
|
|
104
|
+
|
|
105
105
|
if (!scopeName) {
|
|
106
|
-
log.error('[PROCESS-INCLUDES] scopeName is undefined in context!', {
|
|
106
|
+
log.error('[PROCESS-INCLUDES] scopeName is undefined in context!', {
|
|
107
107
|
contextKeys: Object.keys(context || {})
|
|
108
|
-
})
|
|
109
|
-
throw new Error('scopeName is undefined in context')
|
|
108
|
+
})
|
|
109
|
+
throw new Error('scopeName is undefined in context')
|
|
110
110
|
}
|
|
111
|
-
|
|
112
|
-
const db = context.transaction || knex
|
|
113
|
-
const queryParams = context.queryParams
|
|
114
|
-
const idProperty = context.schemaInfo.idProperty
|
|
115
|
-
|
|
111
|
+
|
|
112
|
+
const db = context.transaction || knex
|
|
113
|
+
const queryParams = context.queryParams
|
|
114
|
+
const idProperty = context.schemaInfo.idProperty
|
|
115
|
+
|
|
116
116
|
if (!queryParams.include) {
|
|
117
|
-
return []
|
|
117
|
+
return []
|
|
118
118
|
}
|
|
119
|
-
|
|
120
|
-
log.debug('[PROCESS-INCLUDES] Processing includes:', queryParams.include)
|
|
121
|
-
|
|
119
|
+
|
|
120
|
+
log.debug('[PROCESS-INCLUDES] Processing includes:', queryParams.include)
|
|
121
|
+
|
|
122
122
|
const includeResult = await buildIncludedResources(
|
|
123
123
|
{
|
|
124
124
|
records,
|
|
@@ -135,17 +135,17 @@ export const processIncludes = async (scope, records, deps) => {
|
|
|
135
135
|
capabilities: api?.knex?.capabilities
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
|
-
)
|
|
139
|
-
|
|
138
|
+
)
|
|
139
|
+
|
|
140
140
|
log.debug('[PROCESS-INCLUDES] Include result:', {
|
|
141
141
|
includedCount: includeResult.included.length,
|
|
142
142
|
types: [...new Set(includeResult.included.map(r => r.type))]
|
|
143
|
-
})
|
|
144
|
-
|
|
145
|
-
return includeResult.included
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
return includeResult.included
|
|
146
146
|
} catch (error) {
|
|
147
|
-
const { log, context } = deps || {}
|
|
148
|
-
|
|
147
|
+
const { log, context } = deps || {}
|
|
148
|
+
|
|
149
149
|
if (log) {
|
|
150
150
|
log.error('[PROCESS-INCLUDES] Error processing includes:', {
|
|
151
151
|
scopeName: context?.scopeName,
|
|
@@ -153,15 +153,15 @@ export const processIncludes = async (scope, records, deps) => {
|
|
|
153
153
|
includeParam: context?.queryParams?.include,
|
|
154
154
|
error: error.message,
|
|
155
155
|
stack: error.stack
|
|
156
|
-
})
|
|
156
|
+
})
|
|
157
157
|
} else {
|
|
158
|
-
console.error('[PROCESS-INCLUDES] Error processing includes:', error)
|
|
158
|
+
console.error('[PROCESS-INCLUDES] Error processing includes:', error)
|
|
159
159
|
}
|
|
160
|
-
|
|
160
|
+
|
|
161
161
|
const enhancedError = new Error(
|
|
162
162
|
`Failed to process includes${context?.scopeName ? ` for scope '${context.scopeName}'` : ''}: ${error.message}`
|
|
163
|
-
)
|
|
164
|
-
enhancedError.originalError = error
|
|
165
|
-
throw enhancedError
|
|
163
|
+
)
|
|
164
|
+
enhancedError.originalError = error
|
|
165
|
+
throw enhancedError
|
|
166
166
|
}
|
|
167
|
-
}
|
|
167
|
+
}
|
|
@@ -1,53 +1,53 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Builds the SELECT clause for a Knex query, handling field selection and table prefixing
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* @param {Object} query - The Knex query builder instance
|
|
5
5
|
* @param {string} tableName - The table name
|
|
6
6
|
* @param {Array<string>|string} fieldsToSelect - Fields to select or '*'
|
|
7
7
|
* @param {boolean} useTablePrefix - Whether to prefix fields with table name
|
|
8
8
|
* @returns {Object} The modified query builder
|
|
9
|
-
*
|
|
9
|
+
*
|
|
10
10
|
* @example
|
|
11
11
|
* // Input: Basic query without specific fields
|
|
12
12
|
* const query = knex('articles');
|
|
13
13
|
* buildQuerySelection(query, 'articles', '*', false);
|
|
14
|
-
*
|
|
14
|
+
*
|
|
15
15
|
* // Effect on query: No modification, Knex defaults to SELECT *
|
|
16
16
|
* // SQL generated: SELECT * FROM articles
|
|
17
|
-
*
|
|
17
|
+
*
|
|
18
18
|
* @example
|
|
19
19
|
* // Input: Query with sparse fieldset
|
|
20
20
|
* const query = knex('articles');
|
|
21
21
|
* const fields = ['id', 'title', 'author_id'];
|
|
22
22
|
* buildQuerySelection(query, 'articles', fields, false);
|
|
23
|
-
*
|
|
23
|
+
*
|
|
24
24
|
* // Effect on query: Adds select() with specific fields
|
|
25
25
|
* // SQL generated: SELECT id, title, author_id FROM articles
|
|
26
26
|
* // Response will only include these 3 fields, reducing payload size
|
|
27
|
-
*
|
|
27
|
+
*
|
|
28
28
|
* @example
|
|
29
29
|
* // Input: Query with joins needing table prefixes
|
|
30
30
|
* const query = knex('articles')
|
|
31
31
|
* .join('users', 'articles.author_id', 'users.id');
|
|
32
32
|
* const fields = ['id', 'title', 'created_at as published'];
|
|
33
33
|
* buildQuerySelection(query, 'articles', fields, true);
|
|
34
|
-
*
|
|
34
|
+
*
|
|
35
35
|
* // Effect on query: Prefixes all fields with table name
|
|
36
36
|
* // SQL generated: SELECT articles.id, articles.title, articles.created_at as published
|
|
37
37
|
* // Prevents "column 'id' is ambiguous" errors since both tables have id
|
|
38
|
-
*
|
|
38
|
+
*
|
|
39
39
|
* @description
|
|
40
40
|
* Used by:
|
|
41
41
|
* - knex-query-helpers.js calls this when building queries with sparse fieldsets
|
|
42
42
|
* - rest-api-knex-plugin uses this in dataQuery to optimize SELECT clauses
|
|
43
43
|
* - Called whenever fields parameter limits which attributes to return
|
|
44
|
-
*
|
|
44
|
+
*
|
|
45
45
|
* Purpose:
|
|
46
46
|
* - Implements JSON:API sparse fieldsets by selecting only requested fields
|
|
47
47
|
* - Prevents ambiguous column errors in queries with joins
|
|
48
48
|
* - Reduces database transfer by not selecting unnecessary columns
|
|
49
49
|
* - Handles field aliases (e.g., "created_at as published")
|
|
50
|
-
*
|
|
50
|
+
*
|
|
51
51
|
* Data flow:
|
|
52
52
|
* 1. Query parser extracts fields parameter (e.g., fields[articles]=title,author)
|
|
53
53
|
* 2. This function adds appropriate SELECT clause to query
|
|
@@ -60,50 +60,50 @@ export const buildQuerySelection = (
|
|
|
60
60
|
tableName,
|
|
61
61
|
fieldsToSelect,
|
|
62
62
|
useTablePrefix = false,
|
|
63
|
-
options = {}
|
|
63
|
+
options = {}
|
|
64
64
|
) => {
|
|
65
|
-
const translateColumn = options.translateColumn
|
|
65
|
+
const translateColumn = options.translateColumn
|
|
66
66
|
|
|
67
67
|
const applyTranslation = (field, aliasForField) => {
|
|
68
68
|
if (translateColumn) {
|
|
69
|
-
const translated = translateColumn(field, aliasForField)
|
|
69
|
+
const translated = translateColumn(field, aliasForField)
|
|
70
70
|
if (translated) {
|
|
71
|
-
return translated
|
|
71
|
+
return translated
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
if (aliasForField) {
|
|
76
|
-
return `${aliasForField}.${field}
|
|
76
|
+
return `${aliasForField}.${field}`
|
|
77
77
|
}
|
|
78
|
-
return field
|
|
79
|
-
}
|
|
78
|
+
return field
|
|
79
|
+
}
|
|
80
80
|
|
|
81
|
-
const targetAlias = useTablePrefix ? tableName : null
|
|
81
|
+
const targetAlias = useTablePrefix ? tableName : null
|
|
82
82
|
|
|
83
83
|
if (fieldsToSelect === '*') {
|
|
84
|
-
const translated = translateColumn ? translateColumn('*', targetAlias) : null
|
|
84
|
+
const translated = translateColumn ? translateColumn('*', targetAlias) : null
|
|
85
85
|
if (translated) {
|
|
86
|
-
return query.select(translated)
|
|
86
|
+
return query.select(translated)
|
|
87
87
|
}
|
|
88
|
-
return useTablePrefix ? query.select(`${tableName}.*`) : query
|
|
88
|
+
return useTablePrefix ? query.select(`${tableName}.*`) : query
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
const fieldsArray = Array.isArray(fieldsToSelect)
|
|
92
92
|
? fieldsToSelect
|
|
93
|
-
: Array.from(fieldsToSelect || [])
|
|
93
|
+
: Array.from(fieldsToSelect || [])
|
|
94
94
|
|
|
95
95
|
const translatedFields = fieldsArray.map((field) => {
|
|
96
|
-
if (typeof field !== 'string') return field
|
|
96
|
+
if (typeof field !== 'string') return field
|
|
97
97
|
|
|
98
|
-
const aliasMatch = field.match(/\s+as\s+/i)
|
|
98
|
+
const aliasMatch = field.match(/\s+as\s+/i)
|
|
99
99
|
if (aliasMatch) {
|
|
100
|
-
const [source, alias] = field.split(/\s+as\s+/i)
|
|
101
|
-
const translatedSource = applyTranslation(source.trim(), targetAlias)
|
|
102
|
-
return `${translatedSource} as ${alias.trim()}
|
|
100
|
+
const [source, alias] = field.split(/\s+as\s+/i)
|
|
101
|
+
const translatedSource = applyTranslation(source.trim(), targetAlias)
|
|
102
|
+
return `${translatedSource} as ${alias.trim()}`
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
return applyTranslation(field.trim(), targetAlias)
|
|
106
|
-
})
|
|
105
|
+
return applyTranslation(field.trim(), targetAlias)
|
|
106
|
+
})
|
|
107
107
|
|
|
108
|
-
return query.select(translatedFields)
|
|
109
|
-
}
|
|
108
|
+
return query.select(translatedFields)
|
|
109
|
+
}
|