@expo/entity-database-adapter-knex 0.55.0 → 0.57.0

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 (91) hide show
  1. package/build/src/AuthorizationResultBasedKnexEntityLoader.d.ts +279 -0
  2. package/build/src/AuthorizationResultBasedKnexEntityLoader.js +127 -0
  3. package/build/src/AuthorizationResultBasedKnexEntityLoader.js.map +1 -0
  4. package/build/src/BasePostgresEntityDatabaseAdapter.d.ts +150 -0
  5. package/build/src/BasePostgresEntityDatabaseAdapter.js +119 -0
  6. package/build/src/BasePostgresEntityDatabaseAdapter.js.map +1 -0
  7. package/build/src/BaseSQLQueryBuilder.d.ts +61 -0
  8. package/build/src/BaseSQLQueryBuilder.js +87 -0
  9. package/build/src/BaseSQLQueryBuilder.js.map +1 -0
  10. package/build/src/EnforcingKnexEntityLoader.d.ts +124 -0
  11. package/build/src/EnforcingKnexEntityLoader.js +166 -0
  12. package/build/src/EnforcingKnexEntityLoader.js.map +1 -0
  13. package/build/src/KnexEntityLoaderFactory.d.ts +25 -0
  14. package/build/src/KnexEntityLoaderFactory.js +39 -0
  15. package/build/src/KnexEntityLoaderFactory.js.map +1 -0
  16. package/build/src/PaginationStrategy.d.ts +30 -0
  17. package/build/src/PaginationStrategy.js +35 -0
  18. package/build/src/PaginationStrategy.js.map +1 -0
  19. package/build/src/PostgresEntity.d.ts +25 -0
  20. package/build/src/PostgresEntity.js +39 -0
  21. package/build/src/PostgresEntity.js.map +1 -0
  22. package/build/src/PostgresEntityDatabaseAdapter.d.ts +12 -5
  23. package/build/src/PostgresEntityDatabaseAdapter.js +32 -11
  24. package/build/src/PostgresEntityDatabaseAdapter.js.map +1 -1
  25. package/build/src/PostgresEntityDatabaseAdapterProvider.d.ts +9 -0
  26. package/build/src/PostgresEntityDatabaseAdapterProvider.js +5 -1
  27. package/build/src/PostgresEntityDatabaseAdapterProvider.js.map +1 -1
  28. package/build/src/ReadonlyPostgresEntity.d.ts +25 -0
  29. package/build/src/ReadonlyPostgresEntity.js +39 -0
  30. package/build/src/ReadonlyPostgresEntity.js.map +1 -0
  31. package/build/src/SQLOperator.d.ts +261 -0
  32. package/build/src/SQLOperator.js +464 -0
  33. package/build/src/SQLOperator.js.map +1 -0
  34. package/build/src/index.d.ts +15 -0
  35. package/build/src/index.js +15 -0
  36. package/build/src/index.js.map +1 -1
  37. package/build/src/internal/EntityKnexDataManager.d.ts +147 -0
  38. package/build/src/internal/EntityKnexDataManager.js +453 -0
  39. package/build/src/internal/EntityKnexDataManager.js.map +1 -0
  40. package/build/src/internal/getKnexDataManager.d.ts +3 -0
  41. package/build/src/internal/getKnexDataManager.js +19 -0
  42. package/build/src/internal/getKnexDataManager.js.map +1 -0
  43. package/build/src/internal/getKnexEntityLoaderFactory.d.ts +3 -0
  44. package/build/src/internal/getKnexEntityLoaderFactory.js +11 -0
  45. package/build/src/internal/getKnexEntityLoaderFactory.js.map +1 -0
  46. package/build/src/internal/utilityTypes.d.ts +5 -0
  47. package/build/src/internal/utilityTypes.js +5 -0
  48. package/build/src/internal/utilityTypes.js.map +1 -0
  49. package/build/src/internal/weakMaps.d.ts +9 -0
  50. package/build/src/internal/weakMaps.js +20 -0
  51. package/build/src/internal/weakMaps.js.map +1 -0
  52. package/build/src/knexLoader.d.ts +18 -0
  53. package/build/src/knexLoader.js +31 -0
  54. package/build/src/knexLoader.js.map +1 -0
  55. package/package.json +6 -5
  56. package/src/AuthorizationResultBasedKnexEntityLoader.ts +538 -0
  57. package/src/BasePostgresEntityDatabaseAdapter.ts +317 -0
  58. package/src/BaseSQLQueryBuilder.ts +114 -0
  59. package/src/EnforcingKnexEntityLoader.ts +271 -0
  60. package/src/KnexEntityLoaderFactory.ts +130 -0
  61. package/src/PaginationStrategy.ts +32 -0
  62. package/src/PostgresEntity.ts +118 -0
  63. package/src/PostgresEntityDatabaseAdapter.ts +78 -24
  64. package/src/PostgresEntityDatabaseAdapterProvider.ts +11 -1
  65. package/src/ReadonlyPostgresEntity.ts +115 -0
  66. package/src/SQLOperator.ts +603 -0
  67. package/src/__integration-tests__/EntityCreationUtils-test.ts +25 -31
  68. package/src/__integration-tests__/PostgresEntityIntegration-test.ts +3192 -330
  69. package/src/__integration-tests__/PostgresEntityQueryContextProvider-test.ts +7 -7
  70. package/src/__testfixtures__/PostgresTestEntity.ts +17 -3
  71. package/src/__tests__/AuthorizationResultBasedKnexEntityLoader-test.ts +1167 -0
  72. package/src/__tests__/BasePostgresEntityDatabaseAdapter-test.ts +160 -0
  73. package/src/__tests__/EnforcingKnexEntityLoader-test.ts +384 -0
  74. package/src/__tests__/EntityFields-test.ts +1 -1
  75. package/src/__tests__/PostgresEntity-test.ts +172 -0
  76. package/src/__tests__/ReadonlyEntity-test.ts +32 -0
  77. package/src/__tests__/SQLOperator-test.ts +831 -0
  78. package/src/__tests__/fixtures/StubPostgresDatabaseAdapter.ts +302 -0
  79. package/src/__tests__/fixtures/StubPostgresDatabaseAdapterProvider.ts +17 -0
  80. package/src/__tests__/fixtures/TestEntity.ts +131 -0
  81. package/src/__tests__/fixtures/TestPaginationEntity.ts +107 -0
  82. package/src/__tests__/fixtures/createUnitTestPostgresEntityCompanionProvider.ts +42 -0
  83. package/src/index.ts +15 -0
  84. package/src/internal/EntityKnexDataManager.ts +832 -0
  85. package/src/internal/__tests__/EntityKnexDataManager-test.ts +378 -0
  86. package/src/internal/__tests__/weakMaps-test.ts +25 -0
  87. package/src/internal/getKnexDataManager.ts +43 -0
  88. package/src/internal/getKnexEntityLoaderFactory.ts +60 -0
  89. package/src/internal/utilityTypes.ts +11 -0
  90. package/src/internal/weakMaps.ts +19 -0
  91. package/src/knexLoader.ts +110 -0
@@ -0,0 +1,453 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.EntityKnexDataManager = void 0;
7
+ const entity_1 = require("@expo/entity");
8
+ const assert_1 = __importDefault(require("assert"));
9
+ const BasePostgresEntityDatabaseAdapter_1 = require("../BasePostgresEntityDatabaseAdapter");
10
+ const PaginationStrategy_1 = require("../PaginationStrategy");
11
+ const SQLOperator_1 = require("../SQLOperator");
12
+ function isDataManagerSearchFieldSQLFragmentFnSpecification(obj) {
13
+ return typeof obj === 'object' && obj !== null && 'fieldConstructor' in obj;
14
+ }
15
+ var PaginationDirection;
16
+ (function (PaginationDirection) {
17
+ PaginationDirection["FORWARD"] = "forward";
18
+ PaginationDirection["BACKWARD"] = "backward";
19
+ })(PaginationDirection || (PaginationDirection = {}));
20
+ const CURSOR_ROW_TABLE_ALIAS = 'cursor_row';
21
+ /**
22
+ * A knex data manager is responsible for handling non-dataloader-based
23
+ * database operations.
24
+ *
25
+ * @internal
26
+ */
27
+ class EntityKnexDataManager {
28
+ entityConfiguration;
29
+ databaseAdapter;
30
+ metricsAdapter;
31
+ entityClassName;
32
+ constructor(entityConfiguration, databaseAdapter, metricsAdapter, entityClassName) {
33
+ this.entityConfiguration = entityConfiguration;
34
+ this.databaseAdapter = databaseAdapter;
35
+ this.metricsAdapter = metricsAdapter;
36
+ this.entityClassName = entityClassName;
37
+ }
38
+ /**
39
+ * Loads many objects matching the conjunction of where clauses constructed from
40
+ * specified field equality operands.
41
+ *
42
+ * @param queryContext - query context in which to perform the load
43
+ * @param fieldEqualityOperands - list of field equality where clause operand specifications
44
+ * @param querySelectionModifiers - limit, offset, and orderBy for the query
45
+ * @returns array of objects matching the query
46
+ */
47
+ async loadManyByFieldEqualityConjunctionAsync(queryContext, fieldEqualityOperands, querySelectionModifiers) {
48
+ EntityKnexDataManager.validateOrderByClauses(querySelectionModifiers.orderBy);
49
+ return await (0, entity_1.timeAndLogLoadEventAsync)(this.metricsAdapter, entity_1.EntityMetricsLoadType.LOAD_MANY_EQUALITY_CONJUNCTION, this.entityClassName, queryContext)(this.databaseAdapter.fetchManyByFieldEqualityConjunctionAsync(queryContext, fieldEqualityOperands, querySelectionModifiers));
50
+ }
51
+ /**
52
+ * Loads many objects matching the raw WHERE clause.
53
+ *
54
+ * @param queryContext - query context in which to perform the load
55
+ * @param rawWhereClause - parameterized SQL WHERE clause with positional binding placeholders or named binding placeholders
56
+ * @param bindings - array of positional bindings or object of named bindings
57
+ * @param querySelectionModifiers - limit, offset, orderBy, and orderByRaw for the query
58
+ * @returns array of objects matching the query
59
+ */
60
+ async loadManyByRawWhereClauseAsync(queryContext, rawWhereClause, bindings, querySelectionModifiers) {
61
+ EntityKnexDataManager.validateOrderByClauses(querySelectionModifiers.orderBy);
62
+ return await (0, entity_1.timeAndLogLoadEventAsync)(this.metricsAdapter, entity_1.EntityMetricsLoadType.LOAD_MANY_RAW, this.entityClassName, queryContext)(this.databaseAdapter.fetchManyByRawWhereClauseAsync(queryContext, rawWhereClause, bindings, querySelectionModifiers));
63
+ }
64
+ async loadManyBySQLFragmentAsync(queryContext, sqlFragment, querySelectionModifiers) {
65
+ EntityKnexDataManager.validateOrderByClauses(querySelectionModifiers.orderBy);
66
+ return await (0, entity_1.timeAndLogLoadEventAsync)(this.metricsAdapter, entity_1.EntityMetricsLoadType.LOAD_MANY_SQL, this.entityClassName, queryContext)(this.databaseAdapter.fetchManyBySQLFragmentAsync(queryContext, sqlFragment, querySelectionModifiers));
67
+ }
68
+ /**
69
+ * Load a page of objects using cursor-based pagination with unified pagination specification.
70
+ *
71
+ * @remarks
72
+ *
73
+ * This method implements cursor-based pagination using the seek method for efficient pagination even on large datasets
74
+ * given appropriate indexes. Cursors are opaque and encode the necessary information to fetch the next page based on the
75
+ * specified pagination strategy (standard, ILIKE search, or trigram search). For this implementation in particular,
76
+ * the cursor encodes the ID of the last entity in the page to ensure correct pagination for all strategies, even in cases
77
+ * where multiple rows have the same value for all fields other than the ID. If the entity referenced by a cursor has been
78
+ * deleted, the load will return an empty page with `hasNextPage: false`.
79
+ *
80
+ * @param queryContext - query context in which to perform the load
81
+ * @param args - pagination arguments including pagination and first/after or last/before
82
+ * @returns connection with edges containing field objects and page info
83
+ */
84
+ async loadPageAsync(queryContext, args) {
85
+ const { where, pagination } = args;
86
+ if (pagination.strategy === PaginationStrategy_1.PaginationStrategy.STANDARD) {
87
+ // Standard pagination
88
+ EntityKnexDataManager.validateOrderByClauses(pagination.orderBy);
89
+ EntityKnexDataManager.validateOrderByClausesHaveConsistentDirection(pagination.orderBy);
90
+ const idField = this.entityConfiguration.idField;
91
+ const augmentedOrderByClauses = this.augmentOrderByIfNecessary(pagination.orderBy, idField);
92
+ const fieldsToUseInPostgresTupleCursor = augmentedOrderByClauses.map((order) => 'fieldName' in order ? order.fieldName : order.fieldFragment);
93
+ // Create strategy for regular pagination
94
+ const strategy = {
95
+ whereClause: where,
96
+ buildOrderBy: (direction) => {
97
+ // For backward pagination, we flip the ORDER BY and NULLS direction to fetch records
98
+ // in reverse order. This allows us to use a simple "less than" cursor comparison
99
+ // instead of complex SQL. We'll reverse the results array later to restore
100
+ // the original requested order.
101
+ // Example: If user wants last 3 items ordered by name ASC, we:
102
+ // 1. Flip to name DESC to get the last items first
103
+ // 2. Apply cursor with < comparison
104
+ // 3. Reverse the final array to present items in name ASC order
105
+ return direction === PaginationDirection.FORWARD
106
+ ? augmentedOrderByClauses
107
+ : augmentedOrderByClauses.map((clause) => ({
108
+ ...clause,
109
+ order: clause.order === BasePostgresEntityDatabaseAdapter_1.OrderByOrdering.ASCENDING
110
+ ? BasePostgresEntityDatabaseAdapter_1.OrderByOrdering.DESCENDING
111
+ : BasePostgresEntityDatabaseAdapter_1.OrderByOrdering.ASCENDING,
112
+ nulls: clause.nulls
113
+ ? EntityKnexDataManager.flipNullsOrderingSpread(clause.nulls)
114
+ : undefined,
115
+ }));
116
+ },
117
+ buildCursorCondition: (decodedCursorId, _direction, orderByClauses) => {
118
+ // all clauses are guaranteed to have the same order due to validation, so we can just look at the first one for effective ordering
119
+ const effectiveOrdering = orderByClauses[0]?.order ?? BasePostgresEntityDatabaseAdapter_1.OrderByOrdering.ASCENDING;
120
+ return this.buildCursorCondition(decodedCursorId, fieldsToUseInPostgresTupleCursor, effectiveOrdering);
121
+ },
122
+ };
123
+ return await this.loadPageInternalAsync(queryContext, args, strategy);
124
+ }
125
+ else {
126
+ // Search pagination (ILIKE or TRIGRAM)
127
+ const search = pagination;
128
+ // Validate search parameters
129
+ (0, assert_1.default)(search.term.length > 0, 'Search term must be a non-empty string');
130
+ (0, assert_1.default)(search.fields.length > 0, 'Search fields must be a non-empty array');
131
+ const { searchWhere, searchOrderByClauses } = this.buildSearchConditionAndOrderBy(search);
132
+ // Combine WHERE conditions: base where + search where
133
+ const whereClause = where && searchWhere ? SQLOperator_1.SQLFragmentHelpers.and(where, searchWhere) : (where ?? searchWhere);
134
+ const fieldsToUseInPostgresTupleCursor = search.strategy === PaginationStrategy_1.PaginationStrategy.TRIGRAM_SEARCH
135
+ ? // For trigram search, cursor includes extra order by fields (if specified) + ID to ensure stable ordering that matches ORDER BY clause
136
+ [...(search.extraOrderByFields ?? []), this.entityConfiguration.idField]
137
+ : // For ILIKE search, cursor includes search fields + ID to ensure stable ordering that matches ORDER BY clause
138
+ [...search.fields, this.entityConfiguration.idField];
139
+ // Create strategy for search pagination
140
+ const strategy = {
141
+ whereClause,
142
+ buildOrderBy: (direction) => {
143
+ return direction === PaginationDirection.FORWARD
144
+ ? searchOrderByClauses
145
+ : searchOrderByClauses.map((clause) => ({
146
+ ...clause,
147
+ order: clause.order === BasePostgresEntityDatabaseAdapter_1.OrderByOrdering.ASCENDING
148
+ ? BasePostgresEntityDatabaseAdapter_1.OrderByOrdering.DESCENDING
149
+ : BasePostgresEntityDatabaseAdapter_1.OrderByOrdering.ASCENDING,
150
+ }));
151
+ },
152
+ buildCursorCondition: (decodedCursorId, direction) => search.strategy === PaginationStrategy_1.PaginationStrategy.TRIGRAM_SEARCH
153
+ ? this.buildTrigramCursorCondition(search, decodedCursorId, direction)
154
+ : this.buildCursorCondition(decodedCursorId, fieldsToUseInPostgresTupleCursor,
155
+ // ILIKE search always orders ASC, so effective ordering matches direction
156
+ direction === PaginationDirection.FORWARD
157
+ ? BasePostgresEntityDatabaseAdapter_1.OrderByOrdering.ASCENDING
158
+ : BasePostgresEntityDatabaseAdapter_1.OrderByOrdering.DESCENDING),
159
+ };
160
+ return await this.loadPageInternalAsync(queryContext, args, strategy);
161
+ }
162
+ }
163
+ getCursorForEntityID(entityID) {
164
+ return this.encodeOpaqueCursor(entityID);
165
+ }
166
+ /**
167
+ * Internal method for loading a page with cursor-based pagination.
168
+ * Shared logic for both regular and search pagination.
169
+ */
170
+ async loadPageInternalAsync(queryContext, args, paginationProvider) {
171
+ const idField = this.entityConfiguration.idField;
172
+ // Validate pagination arguments
173
+ const maxPageSize = this.databaseAdapter.paginationMaxPageSize;
174
+ const isForward = 'first' in args && args.first !== undefined;
175
+ if (isForward) {
176
+ (0, assert_1.default)(Number.isInteger(args.first) && args.first > 0, 'first must be an integer greater than 0');
177
+ if (maxPageSize !== undefined) {
178
+ (0, assert_1.default)(args.first <= maxPageSize, `first must not exceed maximum page size of ${maxPageSize}`);
179
+ }
180
+ }
181
+ else {
182
+ (0, assert_1.default)(Number.isInteger(args.last) && args.last > 0, 'last must be an integer greater than 0');
183
+ if (maxPageSize !== undefined) {
184
+ (0, assert_1.default)(args.last <= maxPageSize, `last must not exceed maximum page size of ${maxPageSize}`);
185
+ }
186
+ }
187
+ const direction = isForward ? PaginationDirection.FORWARD : PaginationDirection.BACKWARD;
188
+ const limit = isForward ? args.first : args.last;
189
+ const cursor = isForward ? args.after : args.before;
190
+ // Decode cursor
191
+ const decodedExternalCursorEntityID = cursor ? this.decodeOpaqueCursor(cursor) : null;
192
+ // Get ordering from strategy
193
+ const orderByClauses = paginationProvider.buildOrderBy(direction);
194
+ // Build WHERE clause with cursor condition
195
+ const baseWhere = paginationProvider.whereClause;
196
+ const cursorCondition = decodedExternalCursorEntityID
197
+ ? paginationProvider.buildCursorCondition(decodedExternalCursorEntityID, direction, orderByClauses)
198
+ : null;
199
+ const whereClause = this.combineWhereConditions(baseWhere, cursorCondition);
200
+ // Determine query modifiers
201
+ const queryModifiers = {
202
+ ...(orderByClauses !== undefined && { orderBy: orderByClauses }),
203
+ limit: limit + 1, // Fetch data with limit + 1 to check for more pages
204
+ };
205
+ const fieldObjects = await (0, entity_1.timeAndLogLoadEventAsync)(this.metricsAdapter, entity_1.EntityMetricsLoadType.LOAD_PAGE, this.entityClassName, queryContext)(this.databaseAdapter.fetchManyBySQLFragmentAsync(queryContext, whereClause, queryModifiers));
206
+ // Process results
207
+ const hasMore = fieldObjects.length > limit;
208
+ const pageFieldObjects = hasMore ? fieldObjects.slice(0, limit) : [...fieldObjects];
209
+ if (direction === PaginationDirection.BACKWARD) {
210
+ // Restore the original requested order by reversing the results.
211
+ // We fetched with flipped ORDER BY for efficient cursor comparison,
212
+ // so now we reverse to match the order the user expects.
213
+ pageFieldObjects.reverse();
214
+ }
215
+ // Build edges with cursors
216
+ const edges = pageFieldObjects.map((fieldObject) => ({
217
+ node: fieldObject,
218
+ cursor: this.encodeOpaqueCursor(fieldObject[idField]),
219
+ }));
220
+ const pageInfo = {
221
+ hasNextPage: direction === PaginationDirection.FORWARD ? hasMore : false,
222
+ hasPreviousPage: direction === PaginationDirection.BACKWARD ? hasMore : false,
223
+ startCursor: edges[0]?.cursor ?? null,
224
+ endCursor: edges[edges.length - 1]?.cursor ?? null,
225
+ };
226
+ return {
227
+ edges,
228
+ pageInfo,
229
+ };
230
+ }
231
+ combineWhereConditions(baseWhere, cursorCondition) {
232
+ const conditions = [baseWhere, cursorCondition].filter((it) => !!it);
233
+ if (conditions.length === 0) {
234
+ return (0, SQLOperator_1.sql) `1 = 1`;
235
+ }
236
+ if (conditions.length === 1) {
237
+ return conditions[0];
238
+ }
239
+ // Wrap baseWhere in parens if combining with cursor condition
240
+ // We know we have exactly 2 conditions at this point
241
+ const [first, second] = conditions;
242
+ return (0, SQLOperator_1.sql) `(${first}) AND ${second}`;
243
+ }
244
+ augmentOrderByIfNecessary(orderBy, idField) {
245
+ const clauses = orderBy ?? [];
246
+ // Always ensure ID is included for stability and cursor correctness. Note that this may add a redundant order by
247
+ // if ID is already included as a fragment, but that is preferable to the risk of incorrect pagination behavior.
248
+ const hasId = clauses.some((spec) => 'fieldName' in spec && spec.fieldName === idField);
249
+ if (!hasId) {
250
+ const lastClauseOrder = clauses.length > 0 ? clauses[clauses.length - 1].order : BasePostgresEntityDatabaseAdapter_1.OrderByOrdering.ASCENDING;
251
+ return [...clauses, { fieldName: idField, order: lastClauseOrder }];
252
+ }
253
+ return clauses;
254
+ }
255
+ static flipNullsOrderingSpread(nulls) {
256
+ return nulls === BasePostgresEntityDatabaseAdapter_1.NullsOrdering.FIRST ? BasePostgresEntityDatabaseAdapter_1.NullsOrdering.LAST : BasePostgresEntityDatabaseAdapter_1.NullsOrdering.FIRST;
257
+ }
258
+ static validateOrderByClauses(orderBy) {
259
+ if (orderBy === undefined) {
260
+ return;
261
+ }
262
+ for (const clause of orderBy) {
263
+ if ('fieldFragment' in clause) {
264
+ const trimmedSql = clause.fieldFragment.sql.trimEnd();
265
+ (0, assert_1.default)(!/\b(ASC|DESC)\s*$/i.test(trimmedSql), 'fieldFragment must not contain ASC or DESC at the end. Use the order property to specify ordering direction.');
266
+ }
267
+ }
268
+ }
269
+ /**
270
+ * Cursor-based pagination uses Postgres tuple comparison (e.g., (a, b) \> (x, y)) which
271
+ * applies a single comparison direction to all columns. Mixed ordering directions would
272
+ * produce incorrect pagination results.
273
+ */
274
+ static validateOrderByClausesHaveConsistentDirection(orderBy) {
275
+ if (orderBy === undefined || orderBy.length <= 1) {
276
+ return;
277
+ }
278
+ const firstOrder = orderBy[0].order;
279
+ (0, assert_1.default)(orderBy.every((clause) => clause.order === firstOrder), 'All orderBy clauses must have the same ordering direction. Mixed ordering directions are not supported with cursor-based pagination.');
280
+ }
281
+ encodeOpaqueCursor(idField) {
282
+ return Buffer.from(JSON.stringify({ id: idField })).toString('base64url');
283
+ }
284
+ decodeOpaqueCursor(cursor) {
285
+ let parsedCursor;
286
+ try {
287
+ const decoded = Buffer.from(cursor, 'base64url').toString();
288
+ parsedCursor = JSON.parse(decoded);
289
+ }
290
+ catch (e) {
291
+ throw new entity_1.EntityDatabaseAdapterPaginationCursorInvalidError(`Failed to decode cursor`, e instanceof Error ? e : undefined);
292
+ }
293
+ if (!('id' in parsedCursor)) {
294
+ throw new entity_1.EntityDatabaseAdapterPaginationCursorInvalidError(`Cursor is missing required 'id' field. Parsed cursor: ${JSON.stringify(parsedCursor)}`);
295
+ }
296
+ return parsedCursor.id;
297
+ }
298
+ resolveSearchFieldToSQLFragment(field, tableAlias) {
299
+ if (field instanceof SQLOperator_1.SQLFragment) {
300
+ return field;
301
+ }
302
+ if (isDataManagerSearchFieldSQLFragmentFnSpecification(field)) {
303
+ return field.fieldConstructor((fieldName) => {
304
+ const dbField = (0, entity_1.getDatabaseFieldForEntityField)(this.entityConfiguration, fieldName);
305
+ return tableAlias
306
+ ? (0, SQLOperator_1.sql) `${(0, SQLOperator_1.unsafeRaw)(tableAlias)}.${(0, SQLOperator_1.identifier)(dbField)}`
307
+ : (0, SQLOperator_1.sql) `${(0, SQLOperator_1.identifier)(dbField)}`;
308
+ });
309
+ }
310
+ const dbField = (0, entity_1.getDatabaseFieldForEntityField)(this.entityConfiguration, field);
311
+ return tableAlias
312
+ ? (0, SQLOperator_1.sql) `${(0, SQLOperator_1.unsafeRaw)(tableAlias)}.${(0, SQLOperator_1.identifier)(dbField)}`
313
+ : (0, SQLOperator_1.sql) `${(0, SQLOperator_1.identifier)(dbField)}`;
314
+ }
315
+ buildCursorCondition(decodedExternalCursorEntityID, fieldsToUseInPostgresTupleCursor, effectiveOrdering) {
316
+ // We build a tuple comparison for fieldsToUseInPostgresTupleCursor fields of the
317
+ // entity identified by the external cursor to ensure correct pagination behavior
318
+ // even in cases where multiple rows have the same value all fields other than id.
319
+ // If the cursor entity has been deleted, the subquery returns no rows and the
320
+ // comparison evaluates to NULL, filtering out all results (empty page).
321
+ const operator = effectiveOrdering === BasePostgresEntityDatabaseAdapter_1.OrderByOrdering.ASCENDING ? '>' : '<';
322
+ const idField = (0, entity_1.getDatabaseFieldForEntityField)(this.entityConfiguration, this.entityConfiguration.idField);
323
+ const tableName = this.entityConfiguration.tableName;
324
+ const postgresCursorFieldIdentifiers = fieldsToUseInPostgresTupleCursor.map((f) => this.resolveSearchFieldToSQLFragment(f));
325
+ // Build left side of comparison (current row's computed values)
326
+ const leftSide = SQLOperator_1.SQLFragment.joinWithCommaSeparator(...postgresCursorFieldIdentifiers);
327
+ // Build right side using subquery to get computed values for cursor entity.
328
+ // For field names, qualify with the cursor row alias. For SQL fragments,
329
+ // use as-is since unqualified column names resolve to the only table in the subquery.
330
+ const postgresCursorRowFieldIdentifiers = fieldsToUseInPostgresTupleCursor.map((f) => this.resolveSearchFieldToSQLFragment(f, CURSOR_ROW_TABLE_ALIAS));
331
+ // Build SELECT fields for subquery
332
+ const rightSideSubquery = (0, SQLOperator_1.sql) `
333
+ SELECT ${SQLOperator_1.SQLFragment.joinWithCommaSeparator(...postgresCursorRowFieldIdentifiers)}
334
+ FROM ${(0, SQLOperator_1.identifier)(tableName)} AS ${(0, SQLOperator_1.unsafeRaw)(CURSOR_ROW_TABLE_ALIAS)}
335
+ WHERE ${(0, SQLOperator_1.unsafeRaw)(CURSOR_ROW_TABLE_ALIAS)}.${(0, SQLOperator_1.identifier)(idField)} = ${decodedExternalCursorEntityID}
336
+ `;
337
+ return (0, SQLOperator_1.sql) `(${leftSide}) ${(0, SQLOperator_1.unsafeRaw)(operator)} (${rightSideSubquery})`;
338
+ }
339
+ buildILikeConditions(search, tableAlias) {
340
+ return search.fields.map((field) => {
341
+ const fieldFragment = this.resolveSearchFieldToSQLFragment(field, tableAlias);
342
+ return (0, SQLOperator_1.sql) `${fieldFragment} ILIKE ${'%' + EntityKnexDataManager.escapeILikePattern(search.term) + '%'}`;
343
+ });
344
+ }
345
+ buildTrigramSimilarityExpressions(search, tableAlias) {
346
+ return search.fields.map((field) => {
347
+ const fieldFragment = this.resolveSearchFieldToSQLFragment(field, tableAlias);
348
+ return (0, SQLOperator_1.sql) `similarity(${fieldFragment}, ${search.term})`;
349
+ });
350
+ }
351
+ buildTrigramExactMatchCaseExpression(search, tableAlias) {
352
+ const ilikeConditions = this.buildILikeConditions(search, tableAlias);
353
+ return (0, SQLOperator_1.sql) `CASE WHEN ${SQLOperator_1.SQLFragmentHelpers.or(...ilikeConditions)} THEN 1 ELSE 0 END`;
354
+ }
355
+ buildTrigramSimilarityGreatestExpression(search, tableAlias) {
356
+ const similarityExprs = this.buildTrigramSimilarityExpressions(search, tableAlias);
357
+ return (0, SQLOperator_1.sql) `GREATEST(${SQLOperator_1.SQLFragment.joinWithCommaSeparator(...similarityExprs)})`;
358
+ }
359
+ buildTrigramCursorCondition(search, decodedExternalCursorEntityID, direction) {
360
+ // For TRIGRAM search, we compute the similarity values using a subquery, similar to normal cursor.
361
+ // If the cursor entity has been deleted, the subquery returns no rows and the
362
+ // comparison evaluates to NULL, filtering out all results (empty page).
363
+ const operator = direction === PaginationDirection.FORWARD ? '<' : '>';
364
+ const idField = (0, entity_1.getDatabaseFieldForEntityField)(this.entityConfiguration, this.entityConfiguration.idField);
365
+ const exactMatchExpr = this.buildTrigramExactMatchCaseExpression(search);
366
+ const similarityExpr = this.buildTrigramSimilarityGreatestExpression(search);
367
+ // Build extra order by fields
368
+ const extraOrderByFields = search.extraOrderByFields;
369
+ const extraFields = extraOrderByFields?.map((f) => this.resolveSearchFieldToSQLFragment(f)) ?? [];
370
+ // Build left side of comparison (current row's computed values)
371
+ const leftSide = SQLOperator_1.SQLFragment.joinWithCommaSeparator(exactMatchExpr, similarityExpr, ...extraFields, (0, SQLOperator_1.sql) `${(0, SQLOperator_1.identifier)(idField)}`);
372
+ // Build right side using subquery to get computed values for cursor entity
373
+ // We need to rebuild the same expressions for the cursor row
374
+ const cursorExactMatchExpr = this.buildTrigramExactMatchCaseExpression(search, CURSOR_ROW_TABLE_ALIAS);
375
+ const cursorSimilarityExpr = this.buildTrigramSimilarityGreatestExpression(search, CURSOR_ROW_TABLE_ALIAS);
376
+ const cursorExtraFields = extraOrderByFields?.map((f) => this.resolveSearchFieldToSQLFragment(f, CURSOR_ROW_TABLE_ALIAS)) ?? [];
377
+ // Build SELECT fields for subquery
378
+ const selectFields = [
379
+ cursorExactMatchExpr,
380
+ cursorSimilarityExpr,
381
+ ...cursorExtraFields,
382
+ (0, SQLOperator_1.sql) `${(0, SQLOperator_1.unsafeRaw)(CURSOR_ROW_TABLE_ALIAS)}.${(0, SQLOperator_1.identifier)(idField)}`,
383
+ ];
384
+ const rightSideSubquery = (0, SQLOperator_1.sql) `
385
+ SELECT ${SQLOperator_1.SQLFragment.joinWithCommaSeparator(...selectFields)}
386
+ FROM ${(0, SQLOperator_1.identifier)(this.entityConfiguration.tableName)} AS ${(0, SQLOperator_1.unsafeRaw)(CURSOR_ROW_TABLE_ALIAS)}
387
+ WHERE ${(0, SQLOperator_1.unsafeRaw)(CURSOR_ROW_TABLE_ALIAS)}.${(0, SQLOperator_1.identifier)(idField)} = ${decodedExternalCursorEntityID}
388
+ `;
389
+ return (0, SQLOperator_1.sql) `(${leftSide}) ${(0, SQLOperator_1.unsafeRaw)(operator)} (${rightSideSubquery})`;
390
+ }
391
+ buildSearchConditionAndOrderBy(search) {
392
+ switch (search.strategy) {
393
+ case PaginationStrategy_1.PaginationStrategy.ILIKE_SEARCH: {
394
+ const conditions = this.buildILikeConditions(search);
395
+ // Order by search fields + ID to match cursor fields
396
+ const searchOrderByClauses = [
397
+ ...search.fields.map((field) => ({
398
+ fieldFragment: this.resolveSearchFieldToSQLFragment(field),
399
+ order: BasePostgresEntityDatabaseAdapter_1.OrderByOrdering.ASCENDING,
400
+ })),
401
+ {
402
+ fieldName: this.entityConfiguration.idField,
403
+ order: BasePostgresEntityDatabaseAdapter_1.OrderByOrdering.ASCENDING,
404
+ },
405
+ ];
406
+ return {
407
+ searchWhere: conditions.length > 0 ? SQLOperator_1.SQLFragmentHelpers.or(...conditions) : (0, SQLOperator_1.sql) `1 = 0`,
408
+ searchOrderByClauses,
409
+ };
410
+ }
411
+ case PaginationStrategy_1.PaginationStrategy.TRIGRAM_SEARCH: {
412
+ // PostgreSQL trigram similarity
413
+ const ilikeConditions = this.buildILikeConditions(search);
414
+ const similarityExprs = this.buildTrigramSimilarityExpressions(search);
415
+ (0, assert_1.default)(search.threshold >= 0 && search.threshold <= 1, `Trigram similarity threshold must be between 0 and 1, got ${search.threshold}`);
416
+ const conditions = similarityExprs.map((expr) => (0, SQLOperator_1.sql) `${expr} > ${search.threshold}`);
417
+ // Combine exact matches (ILIKE) with similarity
418
+ const allConditions = [...ilikeConditions, ...conditions];
419
+ // Build ORDER BY clauses for trigram search:
420
+ // 1. Exact matches first (ILIKE)
421
+ // 2. Then by similarity score
422
+ // 3. Then by extra fields and ID field for stability
423
+ const searchOrderByClauses = [
424
+ {
425
+ fieldFragment: this.buildTrigramExactMatchCaseExpression(search),
426
+ order: BasePostgresEntityDatabaseAdapter_1.OrderByOrdering.DESCENDING,
427
+ },
428
+ {
429
+ fieldFragment: this.buildTrigramSimilarityGreatestExpression(search),
430
+ order: BasePostgresEntityDatabaseAdapter_1.OrderByOrdering.DESCENDING,
431
+ },
432
+ ...(search.extraOrderByFields ?? []).map((field) => ({
433
+ fieldFragment: this.resolveSearchFieldToSQLFragment(field),
434
+ order: BasePostgresEntityDatabaseAdapter_1.OrderByOrdering.DESCENDING,
435
+ })),
436
+ {
437
+ fieldName: this.entityConfiguration.idField,
438
+ order: BasePostgresEntityDatabaseAdapter_1.OrderByOrdering.DESCENDING,
439
+ },
440
+ ];
441
+ return {
442
+ searchWhere: SQLOperator_1.SQLFragmentHelpers.or(...allConditions),
443
+ searchOrderByClauses,
444
+ };
445
+ }
446
+ }
447
+ }
448
+ static escapeILikePattern(term) {
449
+ return term.replace(/[%_\\]/g, '\\$&');
450
+ }
451
+ }
452
+ exports.EntityKnexDataManager = EntityKnexDataManager;
453
+ //# sourceMappingURL=EntityKnexDataManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntityKnexDataManager.js","sourceRoot":"","sources":["../../../src/internal/EntityKnexDataManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { EntityTableDataCoordinator } from '@expo/entity';
2
+ import { EntityKnexDataManager } from './EntityKnexDataManager';
3
+ export declare function getKnexDataManager<TFields extends Record<string, any>, TIDField extends keyof TFields>(tableDataCoordinator: EntityTableDataCoordinator<TFields, TIDField>): EntityKnexDataManager<TFields, TIDField>;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getKnexDataManager = getKnexDataManager;
7
+ const assert_1 = __importDefault(require("assert"));
8
+ const BasePostgresEntityDatabaseAdapter_1 = require("../BasePostgresEntityDatabaseAdapter");
9
+ const EntityKnexDataManager_1 = require("./EntityKnexDataManager");
10
+ const weakMaps_1 = require("./weakMaps");
11
+ const knexDataManagerCache = new WeakMap();
12
+ function getKnexDataManager(tableDataCoordinator) {
13
+ return (0, weakMaps_1.computeIfAbsentInWeakMap)(knexDataManagerCache, tableDataCoordinator, (coordinator) => new EntityKnexDataManager_1.EntityKnexDataManager(coordinator.entityConfiguration, requireBasePostgresAdapter(coordinator.databaseAdapter), coordinator.metricsAdapter, coordinator.entityClassName));
14
+ }
15
+ function requireBasePostgresAdapter(databaseAdapter) {
16
+ (0, assert_1.default)(databaseAdapter instanceof BasePostgresEntityDatabaseAdapter_1.BasePostgresEntityDatabaseAdapter, `Cannot create KnexDataManager for EntityTableDataCoordinator with non-Postgres database adapter.`);
17
+ return databaseAdapter;
18
+ }
19
+ //# sourceMappingURL=getKnexDataManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getKnexDataManager.js","sourceRoot":"","sources":["../../../src/internal/getKnexDataManager.ts"],"names":[],"mappings":";;;;;AAYA,gDAiBC;AA5BD,oDAA4B;AAE5B,4FAAyF;AACzF,mEAAgE;AAChE,yCAAsD;AAEtD,MAAM,oBAAoB,GAAG,IAAI,OAAO,EAGrC,CAAC;AAEJ,SAAgB,kBAAkB,CAIhC,oBAAmE;IAEnE,OAAO,IAAA,mCAAwB,EAC7B,oBAAoB,EACpB,oBAAoB,EACpB,CAAC,WAAW,EAAE,EAAE,CACd,IAAI,6CAAqB,CACvB,WAAW,CAAC,mBAAmB,EAC/B,0BAA0B,CAAC,WAAW,CAAC,eAAe,CAAC,EACvD,WAAW,CAAC,cAAc,EAC1B,WAAW,CAAC,eAAe,CAC5B,CACJ,CAAC;AACJ,CAAC;AAED,SAAS,0BAA0B,CAIjC,eAAyD;IAEzD,IAAA,gBAAM,EACJ,eAAe,YAAY,qEAAiC,EAC5D,kGAAkG,CACnG,CAAC;IACF,OAAO,eAAe,CAAC;AACzB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { EntityPrivacyPolicy, IEntityClass, ReadonlyEntity, ViewerContext } from '@expo/entity';
2
+ import { KnexEntityLoaderFactory } from '../KnexEntityLoaderFactory';
3
+ export declare function getKnexEntityLoaderFactory<TFields extends Record<string, any>, TIDField extends keyof NonNullable<Pick<TFields, TSelectedFields>>, TViewerContext extends ViewerContext, TViewerContext2 extends TViewerContext, TEntity extends ReadonlyEntity<TFields, TIDField, TViewerContext, TSelectedFields>, TPrivacyPolicy extends EntityPrivacyPolicy<TFields, TIDField, TViewerContext, TEntity, TSelectedFields>, TSelectedFields extends keyof TFields = keyof TFields>(entityClass: IEntityClass<TFields, TIDField, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields>, viewerContext: TViewerContext2): KnexEntityLoaderFactory<TFields, TIDField, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields>;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getKnexEntityLoaderFactory = getKnexEntityLoaderFactory;
4
+ const KnexEntityLoaderFactory_1 = require("../KnexEntityLoaderFactory");
5
+ const getKnexDataManager_1 = require("./getKnexDataManager");
6
+ const weakMaps_1 = require("./weakMaps");
7
+ const knexEntityLoaderFactoryCache = new WeakMap();
8
+ function getKnexEntityLoaderFactory(entityClass, viewerContext) {
9
+ return (0, weakMaps_1.computeIfAbsentInWeakMap)(knexEntityLoaderFactoryCache, viewerContext.entityCompanionProvider.getCompanionForEntity(entityClass), (companion) => new KnexEntityLoaderFactory_1.KnexEntityLoaderFactory(companion, (0, getKnexDataManager_1.getKnexDataManager)(companion.tableDataCoordinator), companion.metricsAdapter));
10
+ }
11
+ //# sourceMappingURL=getKnexEntityLoaderFactory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getKnexEntityLoaderFactory.js","sourceRoot":"","sources":["../../../src/internal/getKnexEntityLoaderFactory.ts"],"names":[],"mappings":";;AAiBA,gEA0CC;AAnDD,wEAAqE;AACrE,6DAA0D;AAC1D,yCAAsD;AAEtD,MAAM,4BAA4B,GAAG,IAAI,OAAO,EAG7C,CAAC;AAEJ,SAAgB,0BAA0B,CAexC,WAOC,EACD,aAA8B;IAS9B,OAAO,IAAA,mCAAwB,EAC7B,4BAA4B,EAC5B,aAAa,CAAC,uBAAuB,CAAC,qBAAqB,CAAC,WAAW,CAAC,EACxE,CAAC,SAAS,EAAE,EAAE,CACZ,IAAI,iDAAuB,CACzB,SAAS,EACT,IAAA,uCAAkB,EAAC,SAAS,CAAC,oBAAoB,CAAC,EAClD,SAAS,CAAC,cAAc,CACzB,CACJ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ export type NonNullableKeys<T> = {
2
+ [K in keyof T]: T[K] extends NonNullable<T[K]> ? K : never;
3
+ }[keyof T];
4
+ export type PickNonNullable<T> = Pick<T, NonNullableKeys<T>>;
5
+ export type DistributiveOmit<T, K extends keyof any> = T extends any ? Omit<T, K> : never;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ /* c8 ignore start - types only */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ /* c8 ignore stop - types only */
5
+ //# sourceMappingURL=utilityTypes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utilityTypes.js","sourceRoot":"","sources":["../../../src/internal/utilityTypes.ts"],"names":[],"mappings":";AAAA,kCAAkC;;AAUlC,iCAAiC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * If the specified key is not already associated with a value in this weak map, computes
3
+ * its value using the given mapping function and enters it into this map.
4
+ *
5
+ * @param map - map from which to get the key's value or compute and associate
6
+ * @param key - key for which to get the value or with which the computed value is to be associated
7
+ * @param mappingFunction - function to compute a value for key
8
+ */
9
+ export declare const computeIfAbsentInWeakMap: <K extends WeakKey, V>(map: WeakMap<K, V>, key: K, mappingFunction: (key: K) => V) => V;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.computeIfAbsentInWeakMap = void 0;
4
+ /**
5
+ * If the specified key is not already associated with a value in this weak map, computes
6
+ * its value using the given mapping function and enters it into this map.
7
+ *
8
+ * @param map - map from which to get the key's value or compute and associate
9
+ * @param key - key for which to get the value or with which the computed value is to be associated
10
+ * @param mappingFunction - function to compute a value for key
11
+ */
12
+ const computeIfAbsentInWeakMap = (map, key, mappingFunction) => {
13
+ if (!map.has(key)) {
14
+ const value = mappingFunction(key);
15
+ map.set(key, value);
16
+ }
17
+ return map.get(key);
18
+ };
19
+ exports.computeIfAbsentInWeakMap = computeIfAbsentInWeakMap;
20
+ //# sourceMappingURL=weakMaps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"weakMaps.js","sourceRoot":"","sources":["../../../src/internal/weakMaps.ts"],"names":[],"mappings":";;;AAAA;;;;;;;GAOG;AACI,MAAM,wBAAwB,GAAG,CACtC,GAAkB,EAClB,GAAM,EACN,eAA8B,EAC3B,EAAE;IACL,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QAClB,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;QACnC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACtB,CAAC;IACD,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;AACvB,CAAC,CAAC;AAVW,QAAA,wBAAwB,4BAUnC"}
@@ -0,0 +1,18 @@
1
+ import { EntityPrivacyPolicy, EntityQueryContext, IEntityClass, ReadonlyEntity, ViewerContext } from '@expo/entity';
2
+ import { AuthorizationResultBasedKnexEntityLoader } from './AuthorizationResultBasedKnexEntityLoader';
3
+ import { EnforcingKnexEntityLoader } from './EnforcingKnexEntityLoader';
4
+ /**
5
+ * Vend knex loader for loading entities via non-data-loader methods in a given query context.
6
+ * @param entityClass - entity class to load
7
+ * @param viewerContext - viewer context of loading user
8
+ * @param queryContext - query context in which to perform the load
9
+ */
10
+ export declare function knexLoader<TMFields extends object, TMIDField extends keyof NonNullable<Pick<TMFields, TMSelectedFields>>, TMViewerContext extends ViewerContext, TMViewerContext2 extends TMViewerContext, TMEntity extends ReadonlyEntity<TMFields, TMIDField, TMViewerContext, TMSelectedFields>, TMPrivacyPolicy extends EntityPrivacyPolicy<TMFields, TMIDField, TMViewerContext, TMEntity, TMSelectedFields>, TMSelectedFields extends keyof TMFields = keyof TMFields>(entityClass: IEntityClass<TMFields, TMIDField, TMViewerContext, TMEntity, TMPrivacyPolicy, TMSelectedFields>, viewerContext: TMViewerContext2, queryContext?: EntityQueryContext): EnforcingKnexEntityLoader<TMFields, TMIDField, TMViewerContext, TMEntity, TMPrivacyPolicy, TMSelectedFields>;
11
+ /**
12
+ * Vend knex loader for loading entities via non-data-loader methods in a given query context.
13
+ * Returns authorization results instead of throwing on authorization errors.
14
+ * @param entityClass - entity class to load
15
+ * @param viewerContext - viewer context of loading user
16
+ * @param queryContext - query context in which to perform the load
17
+ */
18
+ export declare function knexLoaderWithAuthorizationResults<TMFields extends object, TMIDField extends keyof NonNullable<Pick<TMFields, TMSelectedFields>>, TMViewerContext extends ViewerContext, TMViewerContext2 extends TMViewerContext, TMEntity extends ReadonlyEntity<TMFields, TMIDField, TMViewerContext, TMSelectedFields>, TMPrivacyPolicy extends EntityPrivacyPolicy<TMFields, TMIDField, TMViewerContext, TMEntity, TMSelectedFields>, TMSelectedFields extends keyof TMFields = keyof TMFields>(entityClass: IEntityClass<TMFields, TMIDField, TMViewerContext, TMEntity, TMPrivacyPolicy, TMSelectedFields>, viewerContext: TMViewerContext2, queryContext?: EntityQueryContext): AuthorizationResultBasedKnexEntityLoader<TMFields, TMIDField, TMViewerContext, TMEntity, TMPrivacyPolicy, TMSelectedFields>;