json-rest-api 1.0.6 → 1.0.8
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/.claude/agents/library-guide-expert.md +29 -0
- package/.claude/agents/rest-api-internals-expert.md +53 -0
- package/CLAUDE.md +139 -1
- package/README.md +2 -5
- package/docTest.js +238 -0
- package/docs/GUIDE/GUIDE_1_Initial_Setup.md +955 -0
- package/docs/GUIDE/GUIDE_2_1_The_Starting_Point.md +54 -0
- package/docs/GUIDE/GUIDE_2_2_Manipulating_And_Searching_Tables.md +750 -0
- package/docs/GUIDE/GUIDE_2_3_BelongsTo_Relationships.md +494 -0
- package/docs/GUIDE/GUIDE_2_4_HasMany_Records.md +398 -0
- package/docs/GUIDE/GUIDE_2_5_HasMany_Polymorphic.md +882 -0
- package/docs/GUIDE/GUIDE_2_6_Many_To_Many.md +709 -0
- package/docs/GUIDE/GUIDE_2_7_Pagination_And_Ordering.md +1233 -0
- package/docs/GUIDE/GUIDE_2_8_Effects_of_PUT_and_PATCH.md +796 -0
- package/{README_X_Relationship_Plugin.md → docs/GUIDE/GUIDE_2_9_Relationships_Urls.md} +1 -4
- package/docs/GUIDE/GUIDE_2_Data_And_Relations.md +66 -0
- package/docs/GUIDE/GUIDE_3_Field_Transformations.md +1246 -0
- package/docs/GUIDE/GUIDE_5_Non-Db_Stores.md +0 -0
- package/docs/GUIDE/GUIDE_7_Hooks_Data_Management_And_Plugins.md +1490 -0
- package/{README_X_SocketIO.md → docs/GUIDE/GUIDE_X_SocketIO.md} +17 -17
- package/docs/GUIDE/index.md +58 -0
- package/docs/GUIDE.md +61 -2238
- package/docs/ONBOARDING/Computed_Properties_And_Sparse_Fields.md +398 -0
- package/docs/README.md +57 -2239
- package/{README_2_Computed_and_hidden_fields.md → docs/README_VARIOUS/GUIDE_2_Computed_and_hidden_fields.md} +22 -17
- package/docs/README_VARIOUS/GUIDE_IN_DOCS.md +2277 -0
- package/{README.ORIG.md → docs/README_VARIOUS/README.ORIG.md} +8 -8
- package/{README_8_Polymorphic_Relationships.md → docs/README_VARIOUS/README_8_Polymorphic_Relationships.md} +1 -1
- package/docs/README_VARIOUS/README_IN_DOCS.ms +2277 -0
- package/{RELATIONSHIPS_ADVANCED.md → docs/README_VARIOUS/RELATIONSHIPS_ADVANCED.md} +3 -3
- package/{correct-schema-format.md → docs/README_VARIOUS/correct-schema-format.md} +13 -13
- package/{pagination.md → docs/README_VARIOUS/pagination.md} +11 -8
- package/docs/assets/css/style.scss +78 -5
- package/docs/index.md +2 -12
- package/helper-reorganization-plan.md +85 -0
- package/helper-usage-analysis.md +94 -0
- package/package.json +5 -4
- package/plugins/core/bulk-operations-plugin.js +2 -2
- package/plugins/core/connectors/express-plugin.js +99 -33
- package/plugins/core/lib/querying/knex-cross-table-search.js +609 -0
- package/plugins/core/lib/querying/knex-json-api-transformers-querying.js +491 -0
- package/plugins/core/lib/querying/knex-pagination-helpers.js +544 -0
- package/plugins/core/lib/{knex-process-includes.js → querying/knex-process-includes.js} +65 -50
- package/plugins/core/lib/querying/knex-query-helpers-base.js +74 -0
- package/plugins/core/lib/{knex-query-helpers.js → querying/knex-query-helpers.js} +416 -180
- package/plugins/core/lib/{knex-relationship-includes.js → querying/knex-relationship-includes.js} +430 -114
- package/plugins/core/lib/querying/knex-window-queries.js +328 -0
- package/plugins/core/lib/querying-writing/compile-schemas.js +328 -0
- package/plugins/core/{utils → lib/querying-writing}/connectors-query-parser.js +62 -57
- package/plugins/core/lib/{database-capabilities.js → querying-writing/database-capabilities.js} +113 -7
- package/plugins/core/lib/querying-writing/database-value-normalizers.js +369 -0
- package/plugins/core/lib/querying-writing/default-data-helpers.js +72 -0
- package/plugins/core/{utils → lib/querying-writing}/field-utils.js +41 -31
- package/plugins/core/{utils → lib/querying-writing}/knex-constants.js +1 -0
- package/plugins/core/lib/{knex-field-helpers.js → querying-writing/knex-field-helpers.js} +190 -57
- package/plugins/core/lib/querying-writing/knex-json-api-transformers.js +162 -0
- package/plugins/core/lib/{payload-validators.js → querying-writing/payload-validators.js} +297 -217
- package/plugins/core/lib/querying-writing/schema-helpers.js +497 -0
- package/plugins/core/lib/querying-writing/scope-validations.js +431 -0
- package/plugins/core/lib/{simplified-helpers.js → querying-writing/simplified-helpers.js} +216 -176
- package/plugins/core/lib/writing/knex-json-api-transformers-writing.js +110 -0
- package/plugins/core/lib/writing/many-to-many-manipulations.js +300 -0
- package/plugins/core/lib/writing/relationship-processor.js +252 -0
- package/plugins/core/rest-api-knex-plugin.js +183 -62
- package/plugins/core/rest-api-plugin-hooks/compile-resource-schemas.js +7 -0
- package/plugins/core/rest-api-plugin-hooks/register-relationship-routes.js +72 -0
- package/plugins/core/rest-api-plugin-hooks/register-scope-routes.js +102 -0
- package/plugins/core/rest-api-plugin-hooks/turn-scope-init-into-vars.js +50 -0
- package/plugins/core/rest-api-plugin-hooks/validate-include-configurations.js +39 -0
- package/plugins/core/rest-api-plugin-methods/add-route.js +23 -0
- package/plugins/core/rest-api-plugin-methods/check-permissions.js +18 -0
- package/plugins/core/rest-api-plugin-methods/common.js +605 -0
- package/plugins/core/rest-api-plugin-methods/delete-relationship.js +115 -0
- package/plugins/core/rest-api-plugin-methods/delete.js +109 -0
- package/plugins/core/rest-api-plugin-methods/enrich-attributes.js +186 -0
- package/plugins/core/rest-api-plugin-methods/get-related.js +295 -0
- package/plugins/core/rest-api-plugin-methods/get-relationship.js +62 -0
- package/plugins/core/rest-api-plugin-methods/get.js +187 -0
- package/plugins/core/rest-api-plugin-methods/patch-relationship.js +56 -0
- package/plugins/core/rest-api-plugin-methods/patch.js +193 -0
- package/plugins/core/rest-api-plugin-methods/post-relationship.js +104 -0
- package/plugins/core/rest-api-plugin-methods/post.js +157 -0
- package/plugins/core/rest-api-plugin-methods/put.js +257 -0
- package/plugins/core/rest-api-plugin-methods/query.js +208 -0
- package/plugins/core/rest-api-plugin.js +108 -2498
- package/plugins/core/socketio-plugin.js +28 -5
- package/plugins/storage/local-storage.js +2 -2
- package/tests/computed-fields.test.js +483 -0
- package/tests/cors.test.js +4 -4
- package/tests/curl.test.js +5 -4
- package/tests/custom-idproperty-relationships.test.js +891 -0
- package/tests/field-getters.test.js +353 -0
- package/tests/field-setters.test.js +310 -0
- package/tests/fixtures/api-configs.js +800 -28
- package/tests/jwt-auth.test.js +0 -2
- package/tests/nested-includes.test.js +1 -1
- package/tests/pagination-cursor-multifield.test.js +514 -0
- package/tests/pagination-enhanced.test.js +12 -9
- package/tests/polymorphic-relationships.test.js +10 -8
- package/tests/polymorphic-simple.test.js +6 -4
- package/tests/positioning-advanced.test.js +12 -12
- package/tests/positioning-extended.test.js +25 -25
- package/tests/positioning-multifilter.test.js +24 -24
- package/tests/positioning.test.js +3 -3
- package/tests/query-limits.test.js +24 -8
- package/tests/relationship-endpoints.test.js +4 -5
- package/tests/relationships.test.js +0 -1
- package/tests/socketio.test.js +12 -1
- package/tests/virtual-fields.test.js +13 -13
- package/PLAN_FOR_WEBSOCKETS.md +0 -398
- package/README_1_Initial_Setup.md +0 -393
- package/README_X_Hooks.md +0 -647
- package/TODO_rest-api-plugin-extras.todo +0 -23
- package/connectors_ideas/express-plugin.js +0 -120
- package/connectors_ideas/http-plugin.js +0 -138
- package/docs/examples/express-plugin.js +0 -366
- package/example.js +0 -301
- package/plugins/core/HELPER_MODULES.md +0 -285
- package/plugins/core/lib/compile-schemas.js +0 -245
- package/plugins/core/lib/database-value-normalizers.js +0 -192
- package/plugins/core/lib/default-data-helpers.js +0 -100
- package/plugins/core/lib/knex-cross-table-search.js +0 -442
- package/plugins/core/lib/knex-json-api-helpers.js +0 -84
- package/plugins/core/lib/knex-json-api-transformers.js +0 -449
- package/plugins/core/lib/knex-pagination-helpers.js +0 -193
- package/plugins/core/lib/knex-window-queries.js +0 -142
- package/plugins/core/lib/many-to-many-manipulations.js +0 -343
- package/plugins/core/lib/relationship-processor.js +0 -278
- package/plugins/core/lib/schema-helpers.js +0 -343
- package/plugins/core/lib/scope-validations.js +0 -252
- package/plugins/core/rest-api-relationships-plugin.js +0 -700
- package/plugins/core/utils/knex-query-helpers-base.js +0 -56
- /package/{README_X_Permissions.md → docs/GUIDE/GUIDE_4_Authentication_And_Permissions.md} +0 -0
- /package/{README_X_Positioning.md → docs/GUIDE/GUIDE_6_Positioning.md} +0 -0
- /package/{README_X_Bulk_Operations.md → docs/GUIDE/GUIDE_X_Bulk_Operations.md} +0 -0
- /package/{README_X_Cors.md → docs/GUIDE/GUIDE_X_Cors.md} +0 -0
- /package/{README_X_Multihome.md → docs/GUIDE/GUIDE_X_Multihome.md} +0 -0
- /package/{README_X_Appendices.md → docs/GUIDE/GUIDE_Y_Appendices.md} +0 -0
- /package/{QUERY_DEPTH_PROTECTION.md → docs/README_VARIOUS/QUERY_DEPTH_PROTECTION.md} +0 -0
- /package/{RELATIONSHIPS.md → docs/README_VARIOUS/RELATIONSHIPS.md} +0 -0
- /package/{WEBSOCKET_IMPLEMENTATION_STATUS.md → docs/README_VARIOUS/WEBSOCKET_IMPLEMENTATION_STATUS.md} +0 -0
- /package/{helper-functions-chart.md → docs/README_VARIOUS/helper-functions-chart.md} +0 -0
- /package/docs/{implementation-hidden-computed-fields.md → README_VARIOUS/implementation-hidden-computed-fields.md} +0 -0
- /package/docs/{include-limits-migration-guide.md → README_VARIOUS/include-limits-migration-guide.md} +0 -0
- /package/{readmeSnippets → docs/README_VARIOUS}/test_put_behavior.js +0 -0
- /package/{readmeSnippets → docs/README_VARIOUS}/test_put_fields_without_defaults.js +0 -0
|
@@ -1,87 +1,105 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module knex-process-includes
|
|
3
|
-
* @description Include processing orchestration for REST API Knex Plugin
|
|
4
|
-
*
|
|
5
|
-
* This module handles the high-level orchestration of relationship includes,
|
|
6
|
-
* coordinating with the relationship include helpers to load related resources
|
|
7
|
-
* efficiently while respecting transactions and sparse fieldsets.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
1
|
import { buildIncludedResources } from './knex-relationship-includes.js';
|
|
11
2
|
|
|
12
3
|
/**
|
|
13
|
-
* Processes the ?include= parameter to load related resources
|
|
14
|
-
*
|
|
15
|
-
* This function handles the JSON:API include parameter, which allows clients to
|
|
16
|
-
* request related resources in a single request. It supports nested includes
|
|
17
|
-
* (like 'comments.user') and uses efficient batch loading to avoid N+1 queries.
|
|
18
|
-
* The function respects database transactions and sparse fieldsets for included
|
|
19
|
-
* resources.
|
|
4
|
+
* Processes the ?include= parameter to load related resources efficiently
|
|
20
5
|
*
|
|
21
6
|
* @param {Object} scope - The scope object for the primary resource
|
|
22
7
|
* @param {Array<Object>} records - The primary records to load includes for
|
|
23
8
|
* @param {Object} deps - Dependencies object containing log, scopes, knex, and context
|
|
24
9
|
* @returns {Promise<Array<Object>>} Array of included resources in JSON:API format
|
|
25
10
|
*
|
|
26
|
-
* @example
|
|
27
|
-
*
|
|
28
|
-
* const articles = [
|
|
11
|
+
* @example
|
|
12
|
+
* // Input: Articles with author relationship
|
|
13
|
+
* const articles = [
|
|
14
|
+
* { id: 1, title: 'First Article', author_id: 10 },
|
|
15
|
+
* { id: 2, title: 'Second Article', author_id: 11 },
|
|
16
|
+
* { id: 3, title: 'Third Article', author_id: 10 } // Same author as article 1
|
|
17
|
+
* ];
|
|
18
|
+
*
|
|
29
19
|
* const deps = {
|
|
30
|
-
* log, scopes, knex,
|
|
31
20
|
* context: {
|
|
32
21
|
* scopeName: 'articles',
|
|
33
22
|
* queryParams: { include: ['author'] },
|
|
34
|
-
* schemaInfo:
|
|
23
|
+
* schemaInfo: { idProperty: 'id' }
|
|
35
24
|
* }
|
|
36
25
|
* };
|
|
26
|
+
*
|
|
37
27
|
* const included = await processIncludes(scope, articles, deps);
|
|
38
|
-
*
|
|
39
|
-
* //
|
|
40
|
-
* //
|
|
28
|
+
*
|
|
29
|
+
* // Output: Deduplicated authors (only 2, not 3)
|
|
30
|
+
* // [
|
|
31
|
+
* // { type: 'users', id: '10', attributes: { name: 'Alice', email: 'alice@example.com' } },
|
|
32
|
+
* // { type: 'users', id: '11', attributes: { name: 'Bob', email: 'bob@example.com' } }
|
|
41
33
|
* // ]
|
|
42
34
|
*
|
|
43
|
-
* @example
|
|
35
|
+
* @example
|
|
36
|
+
* // Input: Nested includes with dot notation
|
|
37
|
+
* const articles = [{ id: 1, title: 'Article', author_id: 10 }];
|
|
38
|
+
*
|
|
44
39
|
* const deps = {
|
|
45
|
-
* log, scopes, knex,
|
|
46
40
|
* context: {
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
41
|
+
* queryParams: {
|
|
42
|
+
* include: ['author', 'comments.user'] // Load author AND comment users
|
|
43
|
+
* }
|
|
50
44
|
* }
|
|
51
45
|
* };
|
|
46
|
+
*
|
|
52
47
|
* const included = await processIncludes(scope, articles, deps);
|
|
53
|
-
* // Loads authors, then comments for each article,
|
|
54
|
-
* // then users for each comment - all optimized to avoid N+1
|
|
55
48
|
*
|
|
56
|
-
*
|
|
49
|
+
* // Output: All related resources in flat array
|
|
50
|
+
* // [
|
|
51
|
+
* // { type: 'users', id: '10', attributes: { name: 'Author' } },
|
|
52
|
+
* // { type: 'comments', id: '1', attributes: { text: 'Great!' } },
|
|
53
|
+
* // { type: 'comments', id: '2', attributes: { text: 'Nice!' } },
|
|
54
|
+
* // { type: 'users', id: '20', attributes: { name: 'Commenter1' } },
|
|
55
|
+
* // { type: 'users', id: '21', attributes: { name: 'Commenter2' } }
|
|
56
|
+
* // ]
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* // Input: With sparse fieldsets limiting included data
|
|
57
60
|
* const deps = {
|
|
58
|
-
* log, scopes, knex,
|
|
59
61
|
* context: {
|
|
60
|
-
* scopeName: 'articles',
|
|
61
62
|
* queryParams: {
|
|
62
63
|
* include: ['author'],
|
|
63
|
-
* fields: {
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
64
|
+
* fields: {
|
|
65
|
+
* users: 'name' // Only include name field for users
|
|
66
|
+
* }
|
|
67
|
+
* }
|
|
67
68
|
* }
|
|
68
69
|
* };
|
|
70
|
+
*
|
|
69
71
|
* const included = await processIncludes(scope, articles, deps);
|
|
70
72
|
*
|
|
71
|
-
*
|
|
72
|
-
* //
|
|
73
|
-
* //
|
|
74
|
-
* //
|
|
75
|
-
* //
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
73
|
+
* // Output: Users with only requested fields
|
|
74
|
+
* // [
|
|
75
|
+
* // { type: 'users', id: '10', attributes: { name: 'Alice' } }
|
|
76
|
+
* // // email field excluded due to sparse fieldset
|
|
77
|
+
* // ]
|
|
78
|
+
*
|
|
79
|
+
* @description
|
|
80
|
+
* Used by:
|
|
81
|
+
* - rest-api-knex-plugin's dataGet method when includes are requested
|
|
82
|
+
* - rest-api-knex-plugin's dataQuery method for collection includes
|
|
83
|
+
* - Called after primary records are fetched but before response assembly
|
|
84
|
+
*
|
|
85
|
+
* Purpose:
|
|
86
|
+
* - Implements JSON:API compound documents with primary data and includes
|
|
87
|
+
* - Prevents N+1 queries by batch loading all related resources
|
|
88
|
+
* - Handles complex nested includes like 'comments.author.company'
|
|
89
|
+
* - Automatically deduplicates included resources
|
|
90
|
+
* - Respects sparse fieldsets on included resources
|
|
91
|
+
*
|
|
92
|
+
* Data flow:
|
|
93
|
+
* 1. Receives primary records and include directives
|
|
94
|
+
* 2. Parses include parameter (comma-separated, possibly nested with dots)
|
|
95
|
+
* 3. Delegates to buildIncludedResources for actual loading
|
|
96
|
+
* 4. Returns flat array of all included resources
|
|
97
|
+
* 5. These resources go into the 'included' section of JSON:API response
|
|
79
98
|
*/
|
|
80
99
|
export const processIncludes = async (scope, records, deps) => {
|
|
81
100
|
try {
|
|
82
101
|
const { log, scopes, knex, context, api } = deps;
|
|
83
102
|
|
|
84
|
-
// Get scopeName from context
|
|
85
103
|
const scopeName = context.scopeName;
|
|
86
104
|
|
|
87
105
|
if (!scopeName) {
|
|
@@ -91,7 +109,6 @@ export const processIncludes = async (scope, records, deps) => {
|
|
|
91
109
|
throw new Error('scopeName is undefined in context');
|
|
92
110
|
}
|
|
93
111
|
|
|
94
|
-
// Get values from context
|
|
95
112
|
const db = context.transaction || knex;
|
|
96
113
|
const queryParams = context.queryParams;
|
|
97
114
|
const idProperty = context.schemaInfo.idProperty;
|
|
@@ -129,7 +146,6 @@ export const processIncludes = async (scope, records, deps) => {
|
|
|
129
146
|
} catch (error) {
|
|
130
147
|
const { log, context } = deps || {};
|
|
131
148
|
|
|
132
|
-
// Log error with context
|
|
133
149
|
if (log) {
|
|
134
150
|
log.error('[PROCESS-INCLUDES] Error processing includes:', {
|
|
135
151
|
scopeName: context?.scopeName,
|
|
@@ -142,7 +158,6 @@ export const processIncludes = async (scope, records, deps) => {
|
|
|
142
158
|
console.error('[PROCESS-INCLUDES] Error processing includes:', error);
|
|
143
159
|
}
|
|
144
160
|
|
|
145
|
-
// Re-throw with enhanced error message
|
|
146
161
|
const enhancedError = new Error(
|
|
147
162
|
`Failed to process includes${context?.scopeName ? ` for scope '${context.scopeName}'` : ''}: ${error.message}`
|
|
148
163
|
);
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds the SELECT clause for a Knex query, handling field selection and table prefixing
|
|
3
|
+
*
|
|
4
|
+
* @param {Object} query - The Knex query builder instance
|
|
5
|
+
* @param {string} tableName - The table name
|
|
6
|
+
* @param {Array<string>|string} fieldsToSelect - Fields to select or '*'
|
|
7
|
+
* @param {boolean} useTablePrefix - Whether to prefix fields with table name
|
|
8
|
+
* @returns {Object} The modified query builder
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* // Input: Basic query without specific fields
|
|
12
|
+
* const query = knex('articles');
|
|
13
|
+
* buildQuerySelection(query, 'articles', '*', false);
|
|
14
|
+
*
|
|
15
|
+
* // Effect on query: No modification, Knex defaults to SELECT *
|
|
16
|
+
* // SQL generated: SELECT * FROM articles
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* // Input: Query with sparse fieldset
|
|
20
|
+
* const query = knex('articles');
|
|
21
|
+
* const fields = ['id', 'title', 'author_id'];
|
|
22
|
+
* buildQuerySelection(query, 'articles', fields, false);
|
|
23
|
+
*
|
|
24
|
+
* // Effect on query: Adds select() with specific fields
|
|
25
|
+
* // SQL generated: SELECT id, title, author_id FROM articles
|
|
26
|
+
* // Response will only include these 3 fields, reducing payload size
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* // Input: Query with joins needing table prefixes
|
|
30
|
+
* const query = knex('articles')
|
|
31
|
+
* .join('users', 'articles.author_id', 'users.id');
|
|
32
|
+
* const fields = ['id', 'title', 'created_at as published'];
|
|
33
|
+
* buildQuerySelection(query, 'articles', fields, true);
|
|
34
|
+
*
|
|
35
|
+
* // Effect on query: Prefixes all fields with table name
|
|
36
|
+
* // SQL generated: SELECT articles.id, articles.title, articles.created_at as published
|
|
37
|
+
* // Prevents "column 'id' is ambiguous" errors since both tables have id
|
|
38
|
+
*
|
|
39
|
+
* @description
|
|
40
|
+
* Used by:
|
|
41
|
+
* - knex-query-helpers.js calls this when building queries with sparse fieldsets
|
|
42
|
+
* - rest-api-knex-plugin uses this in dataQuery to optimize SELECT clauses
|
|
43
|
+
* - Called whenever fields parameter limits which attributes to return
|
|
44
|
+
*
|
|
45
|
+
* Purpose:
|
|
46
|
+
* - Implements JSON:API sparse fieldsets by selecting only requested fields
|
|
47
|
+
* - Prevents ambiguous column errors in queries with joins
|
|
48
|
+
* - Reduces database transfer by not selecting unnecessary columns
|
|
49
|
+
* - Handles field aliases (e.g., "created_at as published")
|
|
50
|
+
*
|
|
51
|
+
* Data flow:
|
|
52
|
+
* 1. Query parser extracts fields parameter (e.g., fields[articles]=title,author)
|
|
53
|
+
* 2. This function adds appropriate SELECT clause to query
|
|
54
|
+
* 3. Database returns only selected columns
|
|
55
|
+
* 4. Smaller result sets improve query performance
|
|
56
|
+
* 5. JSON:API response includes only requested attributes
|
|
57
|
+
*/
|
|
58
|
+
export const buildQuerySelection = (query, tableName, fieldsToSelect, useTablePrefix = false) => {
|
|
59
|
+
if (fieldsToSelect === '*') {
|
|
60
|
+
return useTablePrefix ? query.select(`${tableName}.*`) : query;
|
|
61
|
+
} else {
|
|
62
|
+
const fields = useTablePrefix
|
|
63
|
+
? fieldsToSelect.map(field => {
|
|
64
|
+
// Handle aliased fields (e.g., "user_id as id")
|
|
65
|
+
if (field.includes(' as ')) {
|
|
66
|
+
const [realField, alias] = field.split(' as ');
|
|
67
|
+
return `${tableName}.${realField.trim()} as ${alias.trim()}`;
|
|
68
|
+
}
|
|
69
|
+
return `${tableName}.${field}`;
|
|
70
|
+
})
|
|
71
|
+
: fieldsToSelect;
|
|
72
|
+
return query.select(fields);
|
|
73
|
+
}
|
|
74
|
+
};
|