@tstdl/base 0.93.21 → 0.93.23

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 (61) hide show
  1. package/application/application.js +3 -3
  2. package/authentication/server/module.d.ts +1 -1
  3. package/authentication/server/module.js +1 -6
  4. package/document-management/api/document-management.api.d.ts +0 -4
  5. package/document-management/service-models/document.service-model.d.ts +0 -2
  6. package/injector/injector.js +22 -22
  7. package/injector/resolve-chain.d.ts +7 -5
  8. package/injector/resolve-chain.js +16 -14
  9. package/logger/manager.js +3 -3
  10. package/orm/data-types/bytea.d.ts +4 -14
  11. package/orm/data-types/bytea.js +2 -2
  12. package/orm/data-types/common.d.ts +18 -0
  13. package/orm/data-types/common.js +11 -0
  14. package/orm/data-types/index.d.ts +1 -0
  15. package/orm/data-types/index.js +1 -0
  16. package/orm/data-types/numeric-date.d.ts +4 -15
  17. package/orm/data-types/numeric-date.js +2 -2
  18. package/orm/data-types/timestamp.d.ts +4 -15
  19. package/orm/data-types/timestamp.js +2 -2
  20. package/orm/data-types/tsvector.d.ts +3 -13
  21. package/orm/data-types/tsvector.js +2 -2
  22. package/orm/decorators.d.ts +16 -54
  23. package/orm/decorators.js +24 -37
  24. package/orm/entity.d.ts +6 -9
  25. package/orm/entity.js +1 -2
  26. package/orm/query.d.ts +199 -61
  27. package/orm/query.js +2 -2
  28. package/orm/repository.types.d.ts +38 -9
  29. package/orm/server/drizzle/schema-converter.js +40 -118
  30. package/orm/server/query-converter.d.ts +21 -7
  31. package/orm/server/query-converter.js +194 -38
  32. package/orm/server/repository.d.ts +39 -22
  33. package/orm/server/repository.js +141 -71
  34. package/orm/server/types.d.ts +10 -2
  35. package/orm/sqls.d.ts +14 -16
  36. package/orm/sqls.js +34 -17
  37. package/package.json +2 -2
  38. package/test/drizzle/0000_nervous_iron_monger.sql +9 -0
  39. package/test/drizzle/meta/0000_snapshot.json +27 -7
  40. package/test/drizzle/meta/_journal.json +2 -44
  41. package/test/test.model.js +2 -6
  42. package/test1.js +18 -5
  43. package/test6.js +23 -35
  44. package/types/types.d.ts +8 -5
  45. package/utils/equals.js +2 -2
  46. package/utils/format-error.js +2 -2
  47. package/utils/helpers.js +3 -2
  48. package/utils/object/object.d.ts +4 -4
  49. package/test/drizzle/0000_sudden_sphinx.sql +0 -9
  50. package/test/drizzle/0001_organic_rhodey.sql +0 -2
  51. package/test/drizzle/0002_nice_squadron_supreme.sql +0 -1
  52. package/test/drizzle/0003_serious_mockingbird.sql +0 -1
  53. package/test/drizzle/0004_complete_pixie.sql +0 -1
  54. package/test/drizzle/0005_bumpy_sabra.sql +0 -1
  55. package/test/drizzle/0006_overrated_post.sql +0 -6
  56. package/test/drizzle/meta/0001_snapshot.json +0 -79
  57. package/test/drizzle/meta/0002_snapshot.json +0 -63
  58. package/test/drizzle/meta/0003_snapshot.json +0 -73
  59. package/test/drizzle/meta/0004_snapshot.json +0 -89
  60. package/test/drizzle/meta/0005_snapshot.json +0 -104
  61. package/test/drizzle/meta/0006_snapshot.json +0 -104
@@ -1,10 +1,35 @@
1
- import { and, eq, gt, gte, inArray, isNotNull, isNull, isSQLWrapper, lt, lte, ne, not, notInArray, or, SQL, sql } from 'drizzle-orm';
1
+ import { and, Column, eq, gt, gte, inArray, isNotNull, isNull, isSQLWrapper, lt, lte, ne, not, notInArray, or, SQL, sql } from 'drizzle-orm';
2
2
  import { match } from 'ts-pattern';
3
3
  import { NotSupportedError } from '../../errors/not-supported.error.js';
4
+ import { toArray } from '../../utils/array/index.js';
4
5
  import { hasOwnProperty, objectEntries } from '../../utils/object/object.js';
5
- import { assertDefinedPass, isDefined, isPrimitive, isRegExp, isString, isUndefined } from '../../utils/type-guards.js';
6
- import { isSimilar, phraseToTsQuery, plainToTsQuery, setweight, toTsQuery, toTsVector, websearchToTsQuery } from '../sqls.js';
6
+ import { assert, assertDefinedPass, isArray, isDefined, isPrimitive, isRegExp, isString, isUndefined } from '../../utils/type-guards.js';
7
+ import { isSimilar, isStrictWordSimilar, isWordSimilar, phraseToTsQuery, plainToTsQuery, setweight, similarity, strictWordSimilarity, toTsQuery, toTsVector, websearchToTsQuery, wordSimilarity } from '../sqls.js';
7
8
  const sqlTrue = sql `true`;
9
+ /**
10
+ * Resolves a target to a Drizzle PgColumn or SQLWrapper.
11
+ * @param target The target to resolve.
12
+ * @param table The Drizzle table object.
13
+ * @param columnDefinitionsMap A map from property names to column definitions.
14
+ */
15
+ export function resolveTargetColumn(target, table, columnDefinitionsMap) {
16
+ if ((target instanceof SQL) || (target instanceof SQL.Aliased) || (target instanceof Column)) {
17
+ return target;
18
+ }
19
+ const columnDef = isString(target)
20
+ ? assertDefinedPass(columnDefinitionsMap.get(target), `Could not map property ${target} to column.`)
21
+ : target; // eslint-disable-line @typescript-eslint/no-unnecessary-type-assertion
22
+ return table[columnDef.name];
23
+ }
24
+ /**
25
+ * Resolves multiple targets to a Drizzle PgColumn or SQLWrapper.
26
+ * @param targets The targets to resolve.
27
+ * @param table The Drizzle table object.
28
+ * @param columnDefinitionsMap A map from property names to column definitions.
29
+ */
30
+ export function resolveTargetColumns(targets, table, columnDefinitionsMap) {
31
+ return targets.map((target) => resolveTargetColumn(target, table, columnDefinitionsMap));
32
+ }
8
33
  /**
9
34
  * Converts a query object into a Drizzle SQL condition.
10
35
  * Recursively handles nested logical operators and maps property names to database columns.
@@ -56,21 +81,41 @@ export function convertQuery(query, table, columnDefinitionsMap) {
56
81
  }
57
82
  break;
58
83
  }
59
- case '$fts': {
60
- const ftsQuery = value;
61
- const method = ftsQuery.method ?? 'vector';
62
- const sqlValue = match(method)
63
- .with('vector', () => {
64
- const tsquery = getTsQuery(ftsQuery.text, ftsQuery.vector?.language ?? 'simple', ftsQuery.vector?.parser ?? 'raw');
65
- const tsvector = getTsVector(ftsQuery.fields, ftsQuery.vector?.language ?? 'simple', table, columnDefinitionsMap, ftsQuery.vector?.weights);
66
- return sql `${tsvector} @@ ${tsquery}`;
67
- })
68
- .with('trigram', () => {
69
- const searchExpression = getColumnConcatenation(ftsQuery.fields, table, columnDefinitionsMap);
70
- return isSimilar(searchExpression, ftsQuery.text);
71
- })
72
- .exhaustive();
73
- conditions.push(sqlValue);
84
+ case '$tsvector': {
85
+ const tsvectorQuery = value.$tsvector;
86
+ const fields = assertDefinedPass(tsvectorQuery.fields, '`fields` is required for tsvector search.');
87
+ const convertedFields = fields.map((target) => {
88
+ const [field, weight] = isArray(target) ? target : [target, undefined];
89
+ const sqlField = resolveTargetColumn(field, table, columnDefinitionsMap);
90
+ if (isDefined(weight)) {
91
+ return [sqlField, weight];
92
+ }
93
+ return sqlField;
94
+ });
95
+ const tsquery = getTsQuery(tsvectorQuery.query, tsvectorQuery.language ?? 'simple', tsvectorQuery.parser ?? 'raw');
96
+ const tsvector = getTsVector(convertedFields, tsvectorQuery.language ?? 'simple');
97
+ conditions.push(sql `${tsvector} @@ ${tsquery}`);
98
+ break;
99
+ }
100
+ case '$trigram': {
101
+ const trigramQuery = value.$trigram;
102
+ const fields = isArray(trigramQuery.fields) ? trigramQuery.fields : [trigramQuery.fields];
103
+ const convertedFields = fields.map((target) => resolveTargetColumn(target, table, columnDefinitionsMap));
104
+ const searchExpression = sql `(${sql.join(convertedFields, sql ` || ' ' || `)})`;
105
+ if (isDefined(trigramQuery.threshold)) {
106
+ const similarityFn = getTrigramSimilarityFunction(trigramQuery.type);
107
+ conditions.push(sql `${similarityFn(trigramQuery.query, searchExpression)} > ${trigramQuery.threshold}`);
108
+ }
109
+ else {
110
+ const isSimilarOperator = getTrigramIsSimilarOperator(trigramQuery.type);
111
+ conditions.push(isSimilarOperator(trigramQuery.query, searchExpression));
112
+ }
113
+ break;
114
+ }
115
+ case '$parade': {
116
+ const paradeQuery = value.$parade;
117
+ const convertedParadeQuery = convertParadeDbQuery(paradeQuery, table, columnDefinitionsMap);
118
+ conditions.push(sql `${table.id} @@@ ${convertedParadeQuery}`);
74
119
  break;
75
120
  }
76
121
  default: {
@@ -167,18 +212,53 @@ function getCondition(property, value, column, table, columnDefinitionsMap) {
167
212
  const operator = (regexp.flags?.includes('i') ?? false) ? sql.raw('~*') : sql.raw('~');
168
213
  return sql `${column} ${operator} ${regexp.value}`;
169
214
  }
170
- if (hasOwnProperty(value, '$fts')) {
171
- const queryValue = value.$fts;
172
- const { query, method = 'vector', language = 'simple', parser = 'plain' } = isString(queryValue)
215
+ if (hasOwnProperty(value, '$tsvector')) {
216
+ const queryValue = value.$tsvector;
217
+ const { query, language = 'simple', parser = 'plain' } = isString(queryValue)
173
218
  ? { query: queryValue }
174
219
  : queryValue;
175
- if (method == 'similarity') {
176
- return isSimilar(column, query);
177
- }
178
220
  const tsquery = getTsQuery(query, language, parser);
179
221
  const tsvector = toTsVector(language, column);
180
222
  return sql `${tsvector} @@ ${tsquery}`;
181
223
  }
224
+ if (hasOwnProperty(value, '$trigram')) {
225
+ const queryValue = value.$trigram;
226
+ const { query, type, threshold } = isString(queryValue) ? { query: queryValue } : queryValue;
227
+ if (isDefined(threshold)) {
228
+ const similarityFn = getTrigramSimilarityFunction(type);
229
+ return sql `${similarityFn(column, query)} > ${threshold}`;
230
+ }
231
+ return isSimilar(column, query);
232
+ }
233
+ if (hasOwnProperty(value, '$match')) {
234
+ const queryValue = value.$match;
235
+ const { query, distance, prefix, conjunctionMode } = isString(queryValue) ? { query: queryValue } : queryValue;
236
+ const parts = [sql `field => ${column.name}`, sql `value => ${query}`];
237
+ if (isDefined(distance)) {
238
+ parts.push(sql `distance => ${distance}`);
239
+ }
240
+ if (isDefined(prefix)) {
241
+ parts.push(sql `prefix => ${prefix}`);
242
+ }
243
+ if (isDefined(conjunctionMode)) {
244
+ parts.push(sql `conjunction_mode => ${conjunctionMode}`);
245
+ }
246
+ const searchFn = sql `paradedb.match(${sql.join(parts, sql.raw(', '))})`;
247
+ return sql `${table.id} @@@ ${searchFn}`;
248
+ }
249
+ if (hasOwnProperty(value, '$tantivy')) {
250
+ const queryValue = value.$tantivy;
251
+ const { query, lenient, conjunctionMode } = isString(queryValue) ? { query: queryValue } : queryValue;
252
+ const parts = [sql `${query}`];
253
+ if (isDefined(lenient)) {
254
+ parts.push(sql `lenient => ${lenient}`);
255
+ }
256
+ if (isDefined(conjunctionMode)) {
257
+ parts.push(sql `conjunction_mode => ${conjunctionMode}`);
258
+ }
259
+ const searchFn = sql `paradedb.parse(${sql.join(parts, sql.raw(', '))})`;
260
+ return sql `${table.id} @@@ ${searchFn}`;
261
+ }
182
262
  if (hasOwnProperty(value, '$geoShape')) {
183
263
  throw new NotSupportedError('$geoShape is not supported.');
184
264
  }
@@ -187,6 +267,90 @@ function getCondition(property, value, column, table, columnDefinitionsMap) {
187
267
  }
188
268
  throw new Error(`Unsupported query type "${property}".`);
189
269
  }
270
+ function getTrigramSimilarityFunction(type = 'phrase') {
271
+ return match(type)
272
+ .with('phrase', () => similarity)
273
+ .with('word', () => wordSimilarity)
274
+ .with('strict-word', () => strictWordSimilarity)
275
+ .exhaustive();
276
+ }
277
+ function getTrigramIsSimilarOperator(type = 'phrase') {
278
+ return match(type)
279
+ .with('phrase', () => isSimilar)
280
+ .with('word', () => isWordSimilar)
281
+ .with('strict-word', () => isStrictWordSimilar)
282
+ .exhaustive();
283
+ }
284
+ /**
285
+ * Recursively converts a ParadeDbQueryObject into a Drizzle SQL object representing the JSONB structure.
286
+ */
287
+ function convertParadeDbQuery(query, table, columnDefinitionsMap) {
288
+ const entries = objectEntries(query);
289
+ assert(entries.length == 1, 'ParadeDB query object must have exactly one key.');
290
+ const [key, queryValue] = entries[0];
291
+ const buildObject = (properties) => {
292
+ const chunks = [];
293
+ for (const [propKey, propValue] of properties) {
294
+ chunks.push(sql `'${sql.raw(propKey)}', ${propValue}`);
295
+ }
296
+ return sql `jsonb_build_object(${sql.join(chunks, sql `, `)})`;
297
+ };
298
+ const convertRecursive = (subQuery) => {
299
+ return convertParadeDbQuery(subQuery, table, columnDefinitionsMap);
300
+ };
301
+ const innerSql = match(key)
302
+ .with('all', 'empty', () => sql `null`)
303
+ .with('term', 'fuzzy_term', 'regex', 'phrase', 'match', 'parse_with_field', 'exists', 'range', 'phrase_prefix', 'regex_phrase', 'range_term', 'range_intersects', 'range_contains', 'range_within', (_) => {
304
+ const properties = [];
305
+ for (const [propKey, propValue] of objectEntries(queryValue)) {
306
+ if (propKey == 'field') {
307
+ const column = resolveTargetColumn(propValue, table, columnDefinitionsMap);
308
+ properties.push([propKey, column.name]);
309
+ }
310
+ else {
311
+ properties.push([propKey, propValue]);
312
+ }
313
+ }
314
+ return buildObject(properties);
315
+ })
316
+ .with('parse', 'more_like_this', () => buildObject(objectEntries(queryValue)))
317
+ .with('boolean', () => {
318
+ const properties = [];
319
+ for (const [propKey, propValue] of objectEntries(queryValue)) {
320
+ const subQueries = toArray(propValue ?? []).map(convertRecursive);
321
+ properties.push([propKey, sql `jsonb_build_array(${sql.join(subQueries, sql `, `)})`]);
322
+ }
323
+ return buildObject(properties);
324
+ })
325
+ .with('boost', 'const_score', () => {
326
+ const properties = [];
327
+ for (const [propKey, propValue] of objectEntries(queryValue)) {
328
+ if (propKey == 'query') {
329
+ properties.push([propKey, convertRecursive(propValue)]);
330
+ }
331
+ else {
332
+ properties.push([propKey, propValue]);
333
+ }
334
+ }
335
+ return buildObject(properties);
336
+ })
337
+ .with('disjunction_max', 'term_set', (_k) => {
338
+ const properties = [];
339
+ const subqueryArrayKey = (key == 'disjunction_max') ? 'disjuncts' : 'terms';
340
+ for (const [propKey, propValue] of objectEntries(queryValue)) {
341
+ if (propKey == subqueryArrayKey) {
342
+ const subQueries = propValue.map(convertRecursive);
343
+ properties.push([propKey, sql `jsonb_build_array(${sql.join(subQueries, sql `, `)})`]);
344
+ }
345
+ else {
346
+ properties.push([propKey, propValue]);
347
+ }
348
+ }
349
+ return buildObject(properties);
350
+ })
351
+ .exhaustive();
352
+ return buildObject([[key, innerSql]]);
353
+ }
190
354
  export function getTsQuery(text, language, parser) {
191
355
  switch (parser) {
192
356
  case 'raw':
@@ -201,23 +365,15 @@ export function getTsQuery(text, language, parser) {
201
365
  throw new NotSupportedError(`Unsupported text search parser: ${parser}`);
202
366
  }
203
367
  }
204
- export function getTsVector(fields, language, table, columnDefinitionsMap, weights) {
205
- const tsvector = sql.join(fields.map((field) => {
206
- const columnDef = assertDefinedPass(columnDefinitionsMap.get(field), `Could not map property ${field} to column.`);
207
- const column = table[columnDef.name];
208
- const vector = toTsVector(language, column);
209
- const weight = weights?.[field];
368
+ export function getTsVector(fields, language) {
369
+ const sqlFields = fields.map((fieldWithWeight) => {
370
+ const [field, weight] = isArray(fieldWithWeight) ? fieldWithWeight : [fieldWithWeight, undefined];
371
+ const vector = toTsVector(language, field);
210
372
  if (isDefined(weight)) {
211
373
  return setweight(vector, weight);
212
374
  }
213
375
  return vector;
214
- }), sql ` || `);
215
- return tsvector;
216
- }
217
- export function getColumnConcatenation(fields, table, columnDefinitionsMap) {
218
- const columns = fields.map((field) => {
219
- const columnDef = assertDefinedPass(columnDefinitionsMap.get(field), `Could not map property ${field} to column.`);
220
- return table[columnDef.name];
221
376
  });
222
- return sql `(${sql.join(columns, sql ` || ' ' || `)})`;
377
+ const mergedTsVector = sql.join(sqlFields, sql ` || `);
378
+ return mergedTsVector;
223
379
  }
@@ -1,10 +1,10 @@
1
- import { SQL } from 'drizzle-orm';
1
+ import { SQL, type SQLWrapper } from 'drizzle-orm';
2
2
  import type { PgColumn, PgInsertValue, PgSelectBuilder, PgUpdateSetSource, SelectedFields } from 'drizzle-orm/pg-core';
3
3
  import { afterResolve, resolveArgumentType, type Resolvable } from '../../injector/interfaces.js';
4
- import type { DeepPartial, Function, OneOrMany, Paths, Record, Type, UntaggedDeep } from '../../types/index.js';
5
- import { Entity, type EntityMetadataAttributes, type EntityType, type EntityWithoutMetadata } from '../entity.js';
6
- import type { FullTextSearchQuery, Query } from '../query.js';
7
- import type { EntityMetadataUpdate, EntityUpdate, LoadManyOptions, LoadOptions, NewEntity, Order, SearchOptions, SearchResult, TargetColumn, TargetColumnPaths } from '../repository.types.js';
4
+ import type { DeepPartial, Function, OneOrMany, Record, Type } from '../../types/index.js';
5
+ import { Entity, type BaseEntity, type EntityMetadataAttributes, type EntityType } from '../entity.js';
6
+ import type { ParadeDbSearchQuery, Query, TrigramSearchQuery, TsVectorSearchQuery } from '../query.js';
7
+ import type { EntityMetadataUpdate, EntityUpdate, LoadManyOptions, LoadOptions, NewEntity, Order, SearchOptions, SearchResult, TargetColumn, TargetColumnPath } from '../repository.types.js';
8
8
  import type { Database } from './database.js';
9
9
  import type { PgTransaction } from './transaction.js';
10
10
  import { Transactional } from './transactional.js';
@@ -26,8 +26,8 @@ type EntityRepositoryContext = {
26
26
  encryptionSecret: Uint8Array<ArrayBuffer> | undefined;
27
27
  transformContext: TransformContext | Promise<TransformContext> | undefined;
28
28
  };
29
- type InferSelect<T extends Entity | EntityWithoutMetadata = Entity | EntityWithoutMetadata> = PgTableFromType<EntityType<T>>['$inferSelect'];
30
- export declare class EntityRepository<T extends Entity | EntityWithoutMetadata = EntityWithoutMetadata> extends Transactional<EntityRepositoryContext> implements Resolvable<EntityType<T>> {
29
+ type InferSelect<T extends BaseEntity = BaseEntity> = PgTableFromType<EntityType<T>>['$inferSelect'];
30
+ export declare class EntityRepository<T extends BaseEntity = BaseEntity> extends Transactional<EntityRepositoryContext> implements Resolvable<EntityType<T>> {
31
31
  #private;
32
32
  readonly type: EntityType<T>;
33
33
  readonly typeName: string;
@@ -40,16 +40,22 @@ export declare class EntityRepository<T extends Entity | EntityWithoutMetadata =
40
40
  [afterResolve](): void;
41
41
  private expirationLoop;
42
42
  protected getTransactionalContextData(): EntityRepositoryContext;
43
- vectorSearch(options: SearchOptions<T>): Promise<SearchResult<T>[]>;
44
- trigramSearch(options: SearchOptions<T>): Promise<SearchResult<T>[]>;
43
+ protected tsVectorSearch(options: SearchOptions<T> & {
44
+ query: TsVectorSearchQuery<T>;
45
+ }): Promise<SearchResult<T>[]>;
46
+ protected trigramSearch(options: SearchOptions<T> & {
47
+ query: TrigramSearchQuery<T>;
48
+ }): Promise<SearchResult<T>[]>;
49
+ protected paradeDbSearch(options: SearchOptions<T> & {
50
+ query: ParadeDbSearchQuery<T>;
51
+ }): Promise<SearchResult<T>[]>;
45
52
  /**
46
53
  * Performs a full-text search and returns entities ranked by relevance.
47
- * This method is a convenience wrapper around `loadManyByQuery` with the `$fts` operator.
48
- * @param query The search query using the `$fts` operator.
49
- * @param options Search options including ranking, and highlighting configuration.
54
+ * This method dispatches to the appropriate search implementation based on the `method` option.
55
+ * @param options Search options including method, query text, ranking, and highlighting configuration.
50
56
  * @returns A promise that resolves to an array of search results, including the entity, score, and optional highlight.
51
57
  */
52
- search(_query: FullTextSearchQuery<T>['$fts'], _options?: SearchOptions<T>): Promise<SearchResult<T>[]>;
58
+ search(options: SearchOptions<T>): Promise<SearchResult<T>[]>;
53
59
  /**
54
60
  * Loads a single entity by its ID.
55
61
  * Throws `NotFoundError` if the entity is not found.
@@ -175,14 +181,14 @@ export declare class EntityRepository<T extends Entity | EntityWithoutMetadata =
175
181
  * @param entity The entity to insert.
176
182
  * @returns A promise that resolves to the inserted or existing entity.
177
183
  */
178
- insertIfNotExists(target: OneOrMany<Paths<UntaggedDeep<T>>>, entity: NewEntity<T>): Promise<T | undefined>;
184
+ insertIfNotExists(target: OneOrMany<TargetColumnPath<T>>, entity: NewEntity<T>): Promise<T | undefined>;
179
185
  /**
180
186
  * Inserts many entities if they do not already exist based on the target columns.
181
187
  * @param target The column(s) to use for conflict detection.
182
188
  * @param entities The entities to insert.
183
189
  * @returns A promise that resolves to the inserted or existing entities.
184
190
  */
185
- insertManyIfNotExists(target: OneOrMany<Paths<UntaggedDeep<T>>>, entities: NewEntity<T>[]): Promise<T[]>;
191
+ insertManyIfNotExists(target: OneOrMany<TargetColumnPath<T>>, entities: NewEntity<T>[]): Promise<T[]>;
186
192
  /**
187
193
  * Inserts an entity or updates it if a conflict occurs based on the target columns.
188
194
  * @param target The column(s) to use for conflict detection.
@@ -190,7 +196,7 @@ export declare class EntityRepository<T extends Entity | EntityWithoutMetadata =
190
196
  * @param update Optional update to apply if a conflict occurs. Defaults to the inserted entity's values.
191
197
  * @returns A promise that resolves to the inserted or updated entity.
192
198
  */
193
- upsert(target: OneOrMany<Paths<UntaggedDeep<T>>>, entity: NewEntity<T>, update?: EntityUpdate<T>): Promise<T>;
199
+ upsert(target: OneOrMany<TargetColumnPath<T>>, entity: NewEntity<T>, update?: EntityUpdate<T>): Promise<T>;
194
200
  /**
195
201
  * Inserts multiple entities or updates them if a conflict occurs based on the target columns.
196
202
  * @param target The column(s) to use for conflict detection.
@@ -198,7 +204,7 @@ export declare class EntityRepository<T extends Entity | EntityWithoutMetadata =
198
204
  * @param update Optional update to apply if a conflict occurs. Defaults to the inserted entity's values.
199
205
  * @returns A promise that resolves to an array of the inserted or updated entities.
200
206
  */
201
- upsertMany(target: OneOrMany<Paths<UntaggedDeep<T>>>, entities: NewEntity<T>[], update?: EntityUpdate<T>): Promise<T[]>;
207
+ upsertMany(target: OneOrMany<TargetColumnPath<T>>, entities: NewEntity<T>[], update?: EntityUpdate<T>): Promise<T[]>;
202
208
  /**
203
209
  * Updates an entity by its ID.
204
210
  * Throws `NotFoundError` if the entity is not found.
@@ -337,13 +343,23 @@ export declare class EntityRepository<T extends Entity | EntityWithoutMetadata =
337
343
  * @returns A promise that resolves to an array of the hard deleted entities.
338
344
  */
339
345
  hardDeleteManyByQuery(query: Query<T>): Promise<T[]>;
346
+ /**
347
+ * Resolves a target column from an object path or column definition to a Drizzle SQL wrapper.
348
+ * @param target The object path or column definition.
349
+ */
350
+ resolveTargetColumn(target: TargetColumn<T> | ColumnDefinition): SQLWrapper;
351
+ /**
352
+ * Resolves multiple target columns from object paths or column definitions to Drizzle SQL wrappers.
353
+ * @param targets The object paths or column definitions.
354
+ */
355
+ resolveTargetColumns(targets: readonly (TargetColumn<T> | ColumnDefinition)[]): SQLWrapper[];
340
356
  /**
341
357
  * Retrieves the Drizzle PgColumn for a given object path or column definition.
342
358
  * @param pathOrColumn The object path or column definition.
343
359
  * @returns The corresponding PgColumn.
344
360
  */
345
- getColumn(pathOrColumn: TargetColumnPaths<T> | ColumnDefinition): PgColumn;
346
- getColumns(pathOrColumns: (TargetColumnPaths<T> | ColumnDefinition)[]): PgColumn[];
361
+ getColumn(pathOrColumn: TargetColumnPath<T> | ColumnDefinition): PgColumn;
362
+ getColumns(pathOrColumns: readonly (TargetColumnPath<T> | ColumnDefinition)[]): PgColumn[];
347
363
  /**
348
364
  * Converts an Order object to an array of Drizzle SQL order expressions.
349
365
  * @param order The order object.
@@ -459,6 +475,7 @@ export declare class EntityRepository<T extends Entity | EntityWithoutMetadata =
459
475
  protected _mapUpdate(update: EntityUpdate<T>, transformContext: TransformContext): Promise<PgUpdateSetSource<PgTableFromType>>;
460
476
  protected _getMetadataUpdate(update?: EntityUpdate<T>): PgUpdateSetSource<PgTableFromType<EntityType<Entity>>> | undefined;
461
477
  protected getTransformContext(): Promise<TransformContext>;
478
+ protected _mapSearchResults(rowsPromise: Promise<Record[]>, scoreColumnName: string, highlightColumnName: string, scoreTransformer?: (rawScore: any) => number | undefined): Promise<SearchResult<T>[]>;
462
479
  }
463
480
  /**
464
481
  * Injects an EntityRepository instance for the specified entity type.
@@ -466,19 +483,19 @@ export declare class EntityRepository<T extends Entity | EntityWithoutMetadata =
466
483
  * @param type The entity type.
467
484
  * @returns An EntityRepository instance for the specified type.
468
485
  */
469
- export declare function injectRepository<T extends Entity | EntityWithoutMetadata>(type: EntityType<T>, session?: Database | PgTransaction | null): EntityRepository<T>;
486
+ export declare function injectRepository<T extends BaseEntity>(type: EntityType<T>, session?: Database | PgTransaction | null): EntityRepository<T>;
470
487
  /**
471
488
  * Injects an EntityRepository instance for the specified entity type.
472
489
  * @template T The entity type.
473
490
  * @param type The entity type.
474
491
  * @returns An EntityRepository instance for the specified type.
475
492
  */
476
- export declare function injectRepositoryAsync<T extends Entity | EntityWithoutMetadata>(type: EntityType<T>, session?: Database | PgTransaction | null): Promise<EntityRepository<T>>;
493
+ export declare function injectRepositoryAsync<T extends BaseEntity>(type: EntityType<T>, session?: Database | PgTransaction | null): Promise<EntityRepository<T>>;
477
494
  /**
478
495
  * Gets or creates a singleton EntityRepository class for the specified entity type.
479
496
  * @template T The entity type.
480
497
  * @param type The entity type.
481
498
  * @returns A singleton EntityRepository class for the specified type.
482
499
  */
483
- export declare function getRepository<T extends Entity | EntityWithoutMetadata>(type: EntityType<T>): Type<EntityRepository<T>>;
500
+ export declare function getRepository<T extends BaseEntity>(type: EntityType<T>): Type<EntityRepository<T>>;
484
501
  export {};