@tstdl/base 0.93.87 → 0.93.90
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/ai/genkit/helpers.d.ts +3 -1
- package/ai/genkit/helpers.js +3 -3
- package/api/server/gateway.d.ts +3 -0
- package/api/server/gateway.js +15 -4
- package/api/server/middlewares/catch-error.middleware.js +2 -4
- package/api/server/middlewares/cors.middleware.js +2 -3
- package/api/server/middlewares/csrf.middleware.d.ts +41 -0
- package/api/server/middlewares/csrf.middleware.js +108 -0
- package/api/server/middlewares/index.d.ts +1 -0
- package/api/server/middlewares/index.js +1 -0
- package/api/server/module.d.ts +8 -2
- package/api/server/module.js +14 -8
- package/api/server/tests/csrf.middleware.test.js +91 -0
- package/audit/drizzle/{0000_bored_stick.sql → 0000_lumpy_thunderball.sql} +3 -3
- package/audit/drizzle/meta/0000_snapshot.json +4 -4
- package/audit/drizzle/meta/_journal.json +2 -9
- package/audit/module.d.ts +4 -1
- package/audit/module.js +3 -2
- package/audit/schemas.d.ts +1 -1
- package/audit/types.d.ts +1 -1
- package/audit/types.js +1 -1
- package/authentication/client/authentication.service.d.ts +14 -1
- package/authentication/client/authentication.service.js +82 -23
- package/authentication/client/http-client.middleware.d.ts +6 -0
- package/authentication/client/http-client.middleware.js +36 -0
- package/authentication/client/module.js +8 -2
- package/authentication/models/service-account.model.d.ts +2 -2
- package/authentication/models/service-account.model.js +10 -5
- package/authentication/models/subject.model.d.ts +20 -5
- package/authentication/models/subject.model.js +34 -29
- package/authentication/models/system-account.model.d.ts +3 -2
- package/authentication/models/system-account.model.js +11 -5
- package/authentication/models/user.model.d.ts +2 -11
- package/authentication/models/user.model.js +5 -16
- package/authentication/server/authentication-api-request-token.provider.d.ts +0 -2
- package/authentication/server/authentication-api-request-token.provider.js +3 -11
- package/authentication/server/authentication.api-controller.d.ts +1 -2
- package/authentication/server/authentication.api-controller.js +8 -9
- package/authentication/server/authentication.audit.d.ts +3 -2
- package/authentication/server/authentication.service.d.ts +27 -1
- package/authentication/server/authentication.service.js +67 -18
- package/authentication/server/drizzle/{0000_normal_paper_doll.sql → 0000_soft_tag.sql} +25 -32
- package/authentication/server/drizzle/meta/0000_snapshot.json +180 -205
- package/authentication/server/drizzle/meta/_journal.json +2 -2
- package/authentication/server/helper.js +9 -2
- package/authentication/server/module.d.ts +4 -1
- package/authentication/server/module.js +9 -5
- package/authentication/server/schemas.d.ts +2 -1
- package/authentication/server/schemas.js +2 -2
- package/authentication/server/subject.service.d.ts +17 -11
- package/authentication/server/subject.service.js +86 -84
- package/authentication/tests/authentication-ancillary.service.test.d.ts +1 -0
- package/authentication/tests/authentication-ancillary.service.test.js +13 -0
- package/authentication/tests/authentication-secret-requirements.validator.test.d.ts +1 -0
- package/authentication/tests/authentication-secret-requirements.validator.test.js +29 -0
- package/authentication/tests/authentication.api-controller.test.d.ts +1 -0
- package/authentication/tests/authentication.api-controller.test.js +88 -0
- package/authentication/tests/authentication.api-request-token.provider.test.d.ts +1 -0
- package/authentication/tests/authentication.api-request-token.provider.test.js +48 -0
- package/authentication/tests/authentication.client-middleware.test.d.ts +1 -0
- package/authentication/tests/authentication.client-middleware.test.js +23 -0
- package/authentication/tests/authentication.client-service.test.d.ts +1 -0
- package/authentication/tests/authentication.client-service.test.js +70 -0
- package/authentication/tests/authentication.service.test.d.ts +1 -0
- package/authentication/tests/authentication.service.test.js +186 -0
- package/authentication/tests/authentication.test-ancillary-service.d.ts +9 -0
- package/authentication/tests/authentication.test-ancillary-service.js +27 -0
- package/authentication/tests/helper.test.d.ts +1 -0
- package/authentication/tests/helper.test.js +107 -0
- package/authentication/tests/secret-requirements.error.test.d.ts +1 -0
- package/authentication/tests/secret-requirements.error.test.js +14 -0
- package/authentication/tests/subject.service.test.d.ts +1 -0
- package/authentication/tests/subject.service.test.js +140 -0
- package/circuit-breaker/postgres/drizzle/meta/0000_snapshot.json +1 -1
- package/circuit-breaker/postgres/drizzle/meta/_journal.json +2 -2
- package/circuit-breaker/postgres/module.d.ts +7 -1
- package/circuit-breaker/postgres/module.js +8 -6
- package/circuit-breaker/tests/circuit-breaker.test.js +2 -22
- package/document-management/api/document-management.api.js +2 -6
- package/document-management/server/services/document-validation.service.js +6 -5
- package/document-management/server/services/document-workflow.service.js +5 -5
- package/document-management/service-models/document-folders.view-model.d.ts +5 -2
- package/document-management/service-models/document-folders.view-model.js +42 -9
- package/document-management/service-models/enriched/enriched-document-management-data.view.js +1 -1
- package/examples/document-management/main.js +4 -4
- package/http/client/adapters/undici.adapter.d.ts +7 -5
- package/http/client/adapters/undici.adapter.js +13 -10
- package/http/client/module.d.ts +3 -1
- package/http/client/module.js +8 -9
- package/http/server/http-server.d.ts +2 -0
- package/http/server/node/module.d.ts +6 -2
- package/http/server/node/module.js +6 -4
- package/http/server/node/node-http-server.d.ts +2 -0
- package/http/server/node/node-http-server.js +7 -0
- package/http/types.d.ts +1 -1
- package/key-value-store/postgres/module.d.ts +7 -1
- package/key-value-store/postgres/module.js +7 -3
- package/lock/postgres/lock.js +0 -1
- package/lock/postgres/module.d.ts +7 -1
- package/lock/postgres/module.js +9 -5
- package/logger/formatter.d.ts +2 -0
- package/logger/formatters/json.js +2 -2
- package/logger/formatters/pretty-print.js +8 -10
- package/logger/logger.d.ts +1 -1
- package/logger/logger.js +15 -12
- package/message-bus/local/module.d.ts +5 -2
- package/message-bus/local/module.js +5 -4
- package/module/module.d.ts +2 -1
- package/module/module.js +3 -0
- package/module/modules/web-server.module.d.ts +11 -6
- package/module/modules/web-server.module.js +15 -10
- package/orm/decorators.d.ts +24 -1
- package/orm/decorators.js +40 -4
- package/orm/query/base.d.ts +17 -17
- package/orm/query/base.js +1 -1
- package/orm/repository.types.d.ts +45 -1
- package/orm/schemas/tsvector.js +1 -1
- package/orm/server/drizzle/schema-converter.d.ts +3 -1
- package/orm/server/drizzle/schema-converter.js +120 -14
- package/orm/server/index.d.ts +1 -0
- package/orm/server/index.js +1 -0
- package/orm/server/module.d.ts +4 -2
- package/orm/server/module.js +6 -5
- package/orm/server/query-converter.d.ts +6 -3
- package/orm/server/query-converter.js +32 -20
- package/orm/server/repository-config.d.ts +8 -0
- package/orm/server/repository-config.js +8 -0
- package/orm/server/repository.d.ts +117 -43
- package/orm/server/repository.js +757 -253
- package/orm/server/transaction.d.ts +4 -2
- package/orm/server/transaction.js +14 -5
- package/orm/server/transactional.d.ts +6 -2
- package/orm/server/transactional.js +39 -9
- package/orm/server/types.d.ts +2 -0
- package/orm/sqls/case-when.d.ts +3 -3
- package/orm/sqls/case-when.js +2 -2
- package/orm/sqls/sqls.d.ts +31 -5
- package/orm/sqls/sqls.js +69 -6
- package/orm/tests/data-types.test.d.ts +1 -0
- package/orm/tests/data-types.test.js +39 -0
- package/orm/tests/decorators.test.d.ts +1 -0
- package/orm/tests/decorators.test.js +77 -0
- package/orm/tests/encryption.test.d.ts +1 -0
- package/orm/tests/encryption.test.js +34 -0
- package/orm/tests/query-complex.test.d.ts +1 -0
- package/orm/tests/query-complex.test.js +203 -0
- package/orm/tests/query-converter-complex.test.d.ts +1 -0
- package/orm/tests/query-converter-complex.test.js +126 -0
- package/orm/tests/query-converter.test.d.ts +1 -0
- package/orm/tests/query-converter.test.js +123 -0
- package/orm/tests/repository-advanced.test.d.ts +1 -0
- package/orm/tests/repository-advanced.test.js +232 -0
- package/orm/tests/repository-attributes.test.d.ts +1 -0
- package/orm/tests/repository-attributes.test.js +99 -0
- package/orm/tests/repository-comprehensive.test.d.ts +1 -0
- package/orm/tests/repository-comprehensive.test.js +187 -0
- package/orm/tests/repository-coverage.test.d.ts +1 -0
- package/orm/tests/repository-coverage.test.js +303 -0
- package/orm/tests/repository-cti-complex.test.d.ts +1 -0
- package/orm/tests/repository-cti-complex.test.js +170 -0
- package/orm/tests/repository-cti-embedded.test.d.ts +1 -0
- package/orm/tests/repository-cti-embedded.test.js +188 -0
- package/orm/tests/repository-cti-extensive.test.d.ts +1 -0
- package/orm/tests/repository-cti-extensive.test.js +308 -0
- package/orm/tests/repository-cti-mapping.test.d.ts +1 -0
- package/orm/tests/repository-cti-mapping.test.js +121 -0
- package/orm/tests/repository-cti-search.test.d.ts +1 -0
- package/orm/tests/repository-cti-search.test.js +152 -0
- package/orm/tests/repository-cti-soft-delete.test.d.ts +1 -0
- package/orm/tests/repository-cti-soft-delete.test.js +115 -0
- package/orm/tests/repository-cti-transactions.test.d.ts +1 -0
- package/orm/tests/repository-cti-transactions.test.js +126 -0
- package/orm/tests/repository-cti-upsert-many.test.d.ts +1 -0
- package/orm/tests/repository-cti-upsert-many.test.js +127 -0
- package/orm/tests/repository-cti.test.d.ts +1 -0
- package/orm/tests/repository-cti.test.js +456 -0
- package/orm/tests/repository-edge-cases.test.d.ts +1 -0
- package/orm/tests/repository-edge-cases.test.js +216 -0
- package/orm/tests/repository-expiration.test.d.ts +1 -0
- package/orm/tests/repository-expiration.test.js +153 -0
- package/orm/tests/repository-extra-coverage.test.d.ts +1 -0
- package/orm/tests/repository-extra-coverage.test.js +546 -0
- package/orm/tests/repository-mapping.test.d.ts +1 -0
- package/orm/tests/repository-mapping.test.js +71 -0
- package/orm/tests/repository-regression.test.d.ts +1 -0
- package/orm/tests/repository-regression.test.js +330 -0
- package/orm/tests/repository-search-coverage.test.d.ts +1 -0
- package/orm/tests/repository-search-coverage.test.js +129 -0
- package/orm/tests/repository-search.test.d.ts +1 -0
- package/orm/tests/repository-search.test.js +116 -0
- package/orm/tests/repository-soft-delete.test.d.ts +1 -0
- package/orm/tests/repository-soft-delete.test.js +143 -0
- package/orm/tests/repository-transactions-nested.test.d.ts +1 -0
- package/orm/tests/repository-transactions-nested.test.js +202 -0
- package/orm/tests/repository-types.test.d.ts +1 -0
- package/orm/tests/repository-types.test.js +218 -0
- package/orm/tests/schema-converter.test.d.ts +1 -0
- package/orm/tests/schema-converter.test.js +81 -0
- package/orm/tests/schema-generation.test.d.ts +1 -0
- package/orm/tests/schema-generation.test.js +127 -0
- package/orm/tests/sql-helpers.test.d.ts +1 -0
- package/orm/tests/sql-helpers.test.js +67 -0
- package/orm/tests/transaction-safety.test.d.ts +1 -0
- package/orm/tests/transaction-safety.test.js +81 -0
- package/orm/tests/transactional.test.d.ts +1 -0
- package/orm/tests/transactional.test.js +224 -0
- package/orm/tests/utils.test.d.ts +1 -0
- package/orm/tests/utils.test.js +70 -0
- package/orm/utils.d.ts +7 -0
- package/orm/utils.js +26 -6
- package/package.json +12 -7
- package/pool/pool.js +1 -1
- package/rate-limit/index.d.ts +2 -0
- package/rate-limit/index.js +2 -0
- package/rate-limit/postgres/drizzle/0000_watery_rage.sql +7 -0
- package/{queue → rate-limit}/postgres/drizzle/meta/0000_snapshot.json +14 -39
- package/rate-limit/postgres/drizzle/meta/_journal.json +13 -0
- package/{queue → rate-limit}/postgres/drizzle.config.js +1 -1
- package/rate-limit/postgres/index.d.ts +4 -0
- package/rate-limit/postgres/index.js +4 -0
- package/rate-limit/postgres/module.d.ts +12 -0
- package/rate-limit/postgres/module.js +28 -0
- package/rate-limit/postgres/postgres-rate-limiter.d.ts +9 -0
- package/rate-limit/postgres/postgres-rate-limiter.js +56 -0
- package/rate-limit/postgres/rate-limit.model.d.ts +8 -0
- package/rate-limit/postgres/rate-limit.model.js +35 -0
- package/rate-limit/postgres/rate-limiter.provider.d.ts +6 -0
- package/rate-limit/postgres/rate-limiter.provider.js +21 -0
- package/rate-limit/postgres/schemas.d.ts +3 -0
- package/rate-limit/postgres/schemas.js +4 -0
- package/rate-limit/provider.d.ts +9 -0
- package/rate-limit/provider.js +2 -0
- package/rate-limit/rate-limiter.d.ts +35 -0
- package/rate-limit/rate-limiter.js +3 -0
- package/rate-limit/tests/postgres-rate-limiter.test.d.ts +1 -0
- package/rate-limit/tests/postgres-rate-limiter.test.js +92 -0
- package/signals/implementation/configure.d.ts +3 -0
- package/signals/implementation/configure.js +3 -0
- package/sse/data-stream-source.d.ts +1 -1
- package/sse/data-stream-source.js +6 -6
- package/task-queue/enqueue-batch.d.ts +17 -0
- package/task-queue/enqueue-batch.js +24 -0
- package/{queue → task-queue}/index.d.ts +1 -1
- package/{queue → task-queue}/index.js +1 -1
- package/task-queue/postgres/drizzle/0000_thin_black_panther.sql +74 -0
- package/task-queue/postgres/drizzle/meta/0000_snapshot.json +592 -0
- package/task-queue/postgres/drizzle/meta/_journal.json +13 -0
- package/task-queue/postgres/drizzle.config.d.ts +2 -0
- package/task-queue/postgres/drizzle.config.js +11 -0
- package/task-queue/postgres/index.d.ts +4 -0
- package/task-queue/postgres/index.js +4 -0
- package/task-queue/postgres/module.d.ts +12 -0
- package/task-queue/postgres/module.js +28 -0
- package/task-queue/postgres/schemas.d.ts +16 -0
- package/task-queue/postgres/schemas.js +8 -0
- package/task-queue/postgres/task-queue.d.ts +83 -0
- package/task-queue/postgres/task-queue.js +1054 -0
- package/task-queue/postgres/task-queue.provider.d.ts +7 -0
- package/{queue/postgres/queue.provider.js → task-queue/postgres/task-queue.provider.js} +8 -8
- package/task-queue/postgres/task.model.d.ts +39 -0
- package/task-queue/postgres/task.model.js +178 -0
- package/{queue → task-queue}/provider.d.ts +3 -3
- package/task-queue/provider.js +2 -0
- package/{queue → task-queue}/task-context.d.ts +7 -7
- package/{queue → task-queue}/task-context.js +8 -8
- package/{queue/queue.d.ts → task-queue/task-queue.d.ts} +128 -59
- package/task-queue/task-queue.js +200 -0
- package/task-queue/tests/complex.test.d.ts +1 -0
- package/task-queue/tests/complex.test.js +299 -0
- package/task-queue/tests/dependencies.test.d.ts +1 -0
- package/task-queue/tests/dependencies.test.js +174 -0
- package/task-queue/tests/queue.test.d.ts +1 -0
- package/task-queue/tests/queue.test.js +334 -0
- package/task-queue/tests/worker.test.d.ts +1 -0
- package/task-queue/tests/worker.test.js +163 -0
- package/test1.js +1 -1
- package/test4.js +2 -2
- package/unit-test/index.d.ts +1 -0
- package/unit-test/index.js +1 -0
- package/unit-test/integration-setup.d.ts +55 -0
- package/unit-test/integration-setup.js +182 -0
- package/utils/patterns.d.ts +3 -0
- package/utils/patterns.js +6 -1
- package/audit/drizzle/0001_previous_network.sql +0 -2
- package/audit/drizzle/meta/0001_snapshot.json +0 -195
- package/queue/enqueue-batch.d.ts +0 -17
- package/queue/enqueue-batch.js +0 -18
- package/queue/postgres/drizzle/0000_zippy_moondragon.sql +0 -11
- package/queue/postgres/drizzle/0001_certain_wild_pack.sql +0 -2
- package/queue/postgres/drizzle/0002_dear_meggan.sql +0 -2
- package/queue/postgres/drizzle/0003_tricky_venom.sql +0 -30
- package/queue/postgres/drizzle/meta/0001_snapshot.json +0 -103
- package/queue/postgres/drizzle/meta/0002_snapshot.json +0 -90
- package/queue/postgres/drizzle/meta/0003_snapshot.json +0 -288
- package/queue/postgres/drizzle/meta/_journal.json +0 -34
- package/queue/postgres/index.d.ts +0 -4
- package/queue/postgres/index.js +0 -4
- package/queue/postgres/module.d.ts +0 -9
- package/queue/postgres/module.js +0 -29
- package/queue/postgres/queue.d.ts +0 -60
- package/queue/postgres/queue.js +0 -681
- package/queue/postgres/queue.provider.d.ts +0 -7
- package/queue/postgres/schemas.d.ts +0 -14
- package/queue/postgres/schemas.js +0 -6
- package/queue/postgres/task.model.d.ts +0 -24
- package/queue/postgres/task.model.js +0 -115
- package/queue/provider.js +0 -2
- package/queue/queue.js +0 -131
- package/queue/tests/queue.test.js +0 -623
- package/test3.d.ts +0 -1
- package/test3.js +0 -47
- /package/{queue/tests/queue.test.d.ts → api/server/tests/csrf.middleware.test.d.ts} +0 -0
- /package/circuit-breaker/postgres/drizzle/{0000_hard_shocker.sql → 0000_cooing_korath.sql} +0 -0
- /package/{queue → rate-limit}/postgres/drizzle.config.d.ts +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { sql, SQL } from 'drizzle-orm';
|
|
1
|
+
import { eq, sql, SQL } from 'drizzle-orm';
|
|
2
2
|
import { toCamelCase, toSnakeCase } from 'drizzle-orm/casing';
|
|
3
3
|
import { boolean, check, doublePrecision, foreignKey, index, integer, jsonb, numeric, pgSchema, primaryKey, text, unique, uniqueIndex, uuid } from 'drizzle-orm/pg-core';
|
|
4
4
|
import { match, P } from 'ts-pattern';
|
|
@@ -12,6 +12,7 @@ import { decodeText, encodeUtf8 } from '../../../utils/encoding.js';
|
|
|
12
12
|
import { enumValues } from '../../../utils/enum.js';
|
|
13
13
|
import { memoize, memoizeSingle } from '../../../utils/function/memoize.js';
|
|
14
14
|
import { typeExtends } from '../../../utils/index.js';
|
|
15
|
+
import { merge } from '../../../utils/merge.js';
|
|
15
16
|
import { compileDereferencer } from '../../../utils/object/dereference.js';
|
|
16
17
|
import { fromEntries, mapObjectKeysToSnakeCase, objectEntries } from '../../../utils/object/object.js';
|
|
17
18
|
import { assertDefined, assertDefinedPass, isArray, isDefined, isNotNull, isNotNullOrUndefined, isNull, isString, isUndefined } from '../../../utils/type-guards.js';
|
|
@@ -20,13 +21,19 @@ import { bytea, numericDate, timestamp, tsvector } from '../../data-types/index.
|
|
|
20
21
|
import { TenantBaseEntity, TenantEntity } from '../../entity.js';
|
|
21
22
|
import { getEnumName } from '../../enums.js';
|
|
22
23
|
import { JsonSchema, NumericDateSchema, NumericSchema, TimestampSchema, TsVectorSchema, UuidSchema } from '../../schemas/index.js';
|
|
24
|
+
import { getInheritanceMetadata, isChildEntity } from '../../utils.js';
|
|
23
25
|
import { decryptBytes, encryptBytes } from '../encryption.js';
|
|
24
26
|
import { convertQuery, resolveTargetColumn, resolveTargetColumns } from '../query-converter.js';
|
|
25
27
|
const getDbSchema = memoizeSingle(pgSchema);
|
|
26
28
|
export const getDrizzleTableFromType = memoize(_getDrizzleTableFromType);
|
|
27
29
|
const columnDefinitionsSymbol = Symbol('columnDefinitions');
|
|
30
|
+
const allColumnDefinitionsSymbol = Symbol('allColumnDefinitions');
|
|
28
31
|
const columnDefinitionsMapSymbol = Symbol('columnDefinitionsMap');
|
|
29
32
|
export function getColumnDefinitions(table) {
|
|
33
|
+
return table[allColumnDefinitionsSymbol]
|
|
34
|
+
?? table[columnDefinitionsSymbol];
|
|
35
|
+
}
|
|
36
|
+
export function getTableColumnDefinitions(table) {
|
|
30
37
|
return table[columnDefinitionsSymbol];
|
|
31
38
|
}
|
|
32
39
|
export function getColumnDefinitionsMap(table) {
|
|
@@ -38,10 +45,23 @@ export function _getDrizzleTableFromType(type, fallbackSchemaName) {
|
|
|
38
45
|
const schema = assertDefinedPass(mergedTableReflectionData.schema ?? fallbackSchemaName, 'Table schema not provided');
|
|
39
46
|
const tableName = getTableName(type);
|
|
40
47
|
const dbSchema = getDbSchema(schema);
|
|
41
|
-
const
|
|
42
|
-
const
|
|
48
|
+
const inheritanceMetadata = getInheritanceMetadata(type);
|
|
49
|
+
const allColumnDefinitions = getPostgresColumnEntries(type, dbSchema, tableName, undefined, '', { filterInherited: false }, type);
|
|
50
|
+
const columnDefinitions = allColumnDefinitions.filter((cd) => !isChildEntity(type)
|
|
51
|
+
|| !cd.inherited
|
|
52
|
+
|| (cd.objectPath.path == 'id')
|
|
53
|
+
|| (cd.objectPath.path == 'tenantId')
|
|
54
|
+
|| (cd.objectPath.path == inheritanceMetadata?.discriminatorColumn));
|
|
55
|
+
if (isDefined(inheritanceMetadata)) {
|
|
56
|
+
const discriminatorColumnName = inheritanceMetadata.discriminatorColumn;
|
|
57
|
+
const hasDiscriminator = columnDefinitions.some((cd) => (cd.name == discriminatorColumnName) || (cd.reflectionData?.name == discriminatorColumnName) || (cd.objectPath.path == discriminatorColumnName));
|
|
58
|
+
if (!hasDiscriminator) {
|
|
59
|
+
throw new Error(`Discriminator column "${discriminatorColumnName}" not found on entity "${type.name}". Inheritance requires the discriminator column to be defined as a property.`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const columnDefinitionsMap = new Map(allColumnDefinitions.map((column) => [column.objectPath.path, column]));
|
|
43
63
|
function getColumn(table, propertyName) {
|
|
44
|
-
return resolveTargetColumn(propertyName, table, columnDefinitionsMap);
|
|
64
|
+
return resolveTargetColumn(propertyName, table, columnDefinitionsMap, { ignorePgTable: true });
|
|
45
65
|
}
|
|
46
66
|
function buildIndex(table, data, columnName) {
|
|
47
67
|
const resolvedColumns = resolveValueOrProvider(data.columns ?? [columnName], table);
|
|
@@ -79,6 +99,17 @@ export function _getDrizzleTableFromType(type, fallbackSchemaName) {
|
|
|
79
99
|
}
|
|
80
100
|
return builder;
|
|
81
101
|
}
|
|
102
|
+
function buildInheritanceCompositeUniqueConstraint(table) {
|
|
103
|
+
const inheritanceMetadata = mergedTableReflectionData.inheritance;
|
|
104
|
+
const discriminatorColumn = inheritanceMetadata.discriminatorColumn;
|
|
105
|
+
const hasTenantId = isDefined(table['tenantId']);
|
|
106
|
+
const columns = [
|
|
107
|
+
...(hasTenantId ? [table['tenantId']] : []),
|
|
108
|
+
table[discriminatorColumn],
|
|
109
|
+
table['id'],
|
|
110
|
+
];
|
|
111
|
+
return unique(getUniqueName(tableName, columns)).on(...columns);
|
|
112
|
+
}
|
|
82
113
|
function buildPrimaryKey(table) {
|
|
83
114
|
const columns = primaryKeyColumnDefinitions
|
|
84
115
|
.toSorted(compareByValueSelectionToOrder(['tenantId', 'id', orderRest], (columnDefinition) => columnDefinition.name))
|
|
@@ -88,6 +119,34 @@ export function _getDrizzleTableFromType(type, fallbackSchemaName) {
|
|
|
88
119
|
columns,
|
|
89
120
|
});
|
|
90
121
|
}
|
|
122
|
+
function buildInheritanceConstraints(table) {
|
|
123
|
+
const constraints = [];
|
|
124
|
+
const childEntityMetadata = tableReflectionDatas[0]?.childEntity;
|
|
125
|
+
const discriminatorColumn = inheritanceMetadata?.discriminatorColumn;
|
|
126
|
+
if (isDefined(mergedTableReflectionData.inheritance)) {
|
|
127
|
+
constraints.push(buildInheritanceCompositeUniqueConstraint(table));
|
|
128
|
+
}
|
|
129
|
+
if (isDefined(inheritanceMetadata) && isDefined(childEntityMetadata)) {
|
|
130
|
+
const hasTenantId = isDefined(table['tenantId']);
|
|
131
|
+
constraints.push(check(getIdentifier(tableName, discriminatorColumn, 'check'), eq(table[discriminatorColumn], sql.raw(`'${childEntityMetadata.discriminatorValue}'`))), foreignKey({
|
|
132
|
+
name: getForeignKeyName(tableName, getTableName(reflectionRegistry.getMetadata(type).parent), [...(hasTenantId ? ['tenantId'] : []), discriminatorColumn, 'id']),
|
|
133
|
+
columns: [
|
|
134
|
+
...(hasTenantId ? [table['tenantId']] : []),
|
|
135
|
+
table[discriminatorColumn],
|
|
136
|
+
table['id'],
|
|
137
|
+
],
|
|
138
|
+
foreignColumns: (() => {
|
|
139
|
+
const parentTable = getDrizzleTableFromType(reflectionRegistry.getMetadata(type).parent, schema);
|
|
140
|
+
return [
|
|
141
|
+
...(hasTenantId ? [parentTable['tenantId']] : []),
|
|
142
|
+
parentTable[discriminatorColumn],
|
|
143
|
+
parentTable.id,
|
|
144
|
+
];
|
|
145
|
+
})(),
|
|
146
|
+
}).onDelete('cascade'));
|
|
147
|
+
}
|
|
148
|
+
return constraints;
|
|
149
|
+
}
|
|
91
150
|
function buildParadeCast(columnSql, paradeOptions) {
|
|
92
151
|
const { tokenizer, alias } = paradeOptions;
|
|
93
152
|
const { type, parameters: rawParameters = [], filters = {} } = isString(tokenizer) ? { type: tokenizer, parameters: [], filters: undefined } : (tokenizer ?? {});
|
|
@@ -161,11 +220,12 @@ export function _getDrizzleTableFromType(type, fallbackSchemaName) {
|
|
|
161
220
|
});
|
|
162
221
|
return builder;
|
|
163
222
|
}
|
|
164
|
-
const primaryKeyColumnDefinitions = columnDefinitions.filter((columnDefinition) => columnDefinition.reflectionData?.primaryKey == true);
|
|
223
|
+
const primaryKeyColumnDefinitions = columnDefinitions.filter((columnDefinition) => (columnDefinition.reflectionData?.primaryKey == true) || (columnDefinition.objectPath.path == 'id' && columnDefinition.reflectionData?.primaryKey != false));
|
|
165
224
|
const skipPrimaryKey = primaryKeyColumnDefinitions.length > 1;
|
|
166
225
|
const columnEntries = columnDefinitions.map((entry) => [entry.name, entry.buildType({ skipPrimaryKey })]);
|
|
167
226
|
const drizzleSchema = dbSchema.table(tableName, fromEntries(columnEntries), (drizzleTable) => {
|
|
168
227
|
const table = drizzleTable;
|
|
228
|
+
table[columnDefinitionsMapSymbol] = columnDefinitionsMap;
|
|
169
229
|
const indexes = tableReflectionDatas.flatMap((tableReflectionData) => tableReflectionData.index).filter(isDefined).map((data) => buildIndex(table, data));
|
|
170
230
|
const bm25Index = buildParadeIndex(table);
|
|
171
231
|
const checks = tableReflectionDatas.flatMap((tableReflectionData) => tableReflectionData.checks).filter(isDefined).map((data) => check(data.name, data.builder(table)));
|
|
@@ -173,6 +233,7 @@ export function _getDrizzleTableFromType(type, fallbackSchemaName) {
|
|
|
173
233
|
...((primaryKeyColumnDefinitions.length > 1)
|
|
174
234
|
? [buildPrimaryKey(table)]
|
|
175
235
|
: []),
|
|
236
|
+
...buildInheritanceConstraints(table),
|
|
176
237
|
...(columnDefinitions.map((columnDefinition) => {
|
|
177
238
|
const indexData = columnDefinition.reflectionData?.index;
|
|
178
239
|
if (isUndefined(indexData)) {
|
|
@@ -193,7 +254,8 @@ export function _getDrizzleTableFromType(type, fallbackSchemaName) {
|
|
|
193
254
|
}),
|
|
194
255
|
...tableReflectionDatas.flatMap((tableReflectionData) => {
|
|
195
256
|
return tableReflectionData.foreignKeys?.map((foreignKeyData) => {
|
|
196
|
-
const
|
|
257
|
+
const foreignKeyTarget = foreignKeyData.target();
|
|
258
|
+
const foreignTable = getDrizzleTableFromType(foreignKeyTarget, dbSchema.schemaName);
|
|
197
259
|
return foreignKey({
|
|
198
260
|
name: foreignKeyData.options?.name ?? getForeignKeyName(tableName, getTableName(foreignKeyData.target()), foreignKeyData.columns, { naming: foreignKeyData.options?.naming }),
|
|
199
261
|
columns: foreignKeyData.columns.map((column) => getColumn(table, column)),
|
|
@@ -215,7 +277,14 @@ export function _getDrizzleTableFromType(type, fallbackSchemaName) {
|
|
|
215
277
|
];
|
|
216
278
|
});
|
|
217
279
|
drizzleSchema[columnDefinitionsSymbol] = columnDefinitions;
|
|
280
|
+
drizzleSchema[allColumnDefinitionsSymbol] = allColumnDefinitions;
|
|
218
281
|
drizzleSchema[columnDefinitionsMapSymbol] = columnDefinitionsMap;
|
|
282
|
+
// Patch the table reference for own columns
|
|
283
|
+
for (const def of allColumnDefinitions) {
|
|
284
|
+
if (isUndefined(def.table)) {
|
|
285
|
+
def.table = drizzleSchema;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
219
288
|
return drizzleSchema;
|
|
220
289
|
}
|
|
221
290
|
function unwrapSchema(schema) {
|
|
@@ -237,21 +306,54 @@ function unwrapSchema(schema) {
|
|
|
237
306
|
}
|
|
238
307
|
return { schema: currentSchema, nullable, array };
|
|
239
308
|
}
|
|
240
|
-
function
|
|
309
|
+
export function isTableOwning(type) {
|
|
310
|
+
const ormData = reflectionRegistry.getMetadata(type)?.data.tryGet('orm');
|
|
311
|
+
return isDefined(ormData?.inheritance) || isDefined(ormData?.childEntity) || isDefined(ormData?.name);
|
|
312
|
+
}
|
|
313
|
+
function getPostgresColumnEntries(type, dbSchema, tableName, path = new JsonPath({ dollar: false }), prefix = '', options = {}, rootType = type) {
|
|
241
314
|
const metadata = reflectionRegistry.getMetadata(type);
|
|
242
315
|
assertDefined(metadata, `Type ${type.name} does not have reflection metadata (path: ${path.toString()}).`);
|
|
243
316
|
const objectSchema = getObjectSchema(type);
|
|
244
|
-
const
|
|
245
|
-
|
|
317
|
+
const inheritanceMetadata = getInheritanceMetadata(type);
|
|
318
|
+
const discriminatorColumn = inheritanceMetadata?.discriminatorColumn;
|
|
319
|
+
const entries = objectEntries(objectSchema.properties)
|
|
320
|
+
.toSorted(compareByValueSelectionToOrder(['id', orderRest, 'metadata'], (item) => item[0]))
|
|
321
|
+
.flatMap(([property, schema]) => {
|
|
322
|
+
const propertyMetadata = metadata.properties.get(property);
|
|
323
|
+
const inherited = (options.inherited == true) || (propertyMetadata?.inherited == true);
|
|
324
|
+
if ((options.filterInherited == true) && inherited && (property != 'id') && (property != discriminatorColumn)) {
|
|
325
|
+
return [];
|
|
326
|
+
}
|
|
327
|
+
const objectPath = path.add(property);
|
|
328
|
+
let columnReflectionData = propertyMetadata?.data.tryGet('orm');
|
|
329
|
+
const rootOrmTableData = reflectionRegistry.getMetadata(rootType)?.data.tryGet('orm');
|
|
330
|
+
const override = rootOrmTableData?.propertyOverrides?.[objectPath.path];
|
|
331
|
+
if (isDefined(override)) {
|
|
332
|
+
columnReflectionData = merge(columnReflectionData, override);
|
|
333
|
+
}
|
|
246
334
|
const columnName = columnReflectionData?.name ?? toSnakeCase(property);
|
|
335
|
+
let table = options.table;
|
|
336
|
+
if (isUndefined(table) && (property != 'id') && (property != discriminatorColumn)) {
|
|
337
|
+
let currentParent = metadata.parent;
|
|
338
|
+
let highestTableOwningParentWithProperty;
|
|
339
|
+
while (isNotNull(currentParent)) {
|
|
340
|
+
const parentMetadata = reflectionRegistry.getMetadata(currentParent);
|
|
341
|
+
const hasProperty = parentMetadata?.properties.has(property);
|
|
342
|
+
if (hasProperty && isTableOwning(currentParent)) {
|
|
343
|
+
highestTableOwningParentWithProperty = currentParent;
|
|
344
|
+
}
|
|
345
|
+
currentParent = parentMetadata?.parent ?? null;
|
|
346
|
+
}
|
|
347
|
+
if (isDefined(highestTableOwningParentWithProperty)) {
|
|
348
|
+
table = getDrizzleTableFromType(highestTableOwningParentWithProperty, dbSchema.schemaName);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
247
351
|
if ((schema instanceof ObjectSchema) && !(schema instanceof JsonSchema)) {
|
|
248
|
-
const propertyMetadata = reflectionRegistry.getMetadata(type)?.properties.get(property);
|
|
249
352
|
assertDefined(propertyMetadata, `Property "${property}" of type "${type.name}" does not have reflection metadata (path: ${path.toString()}).`);
|
|
250
353
|
const propertyPrefix = columnReflectionData?.embedded?.prefix;
|
|
251
354
|
const nestedPrefix = [prefix, isNull(propertyPrefix) ? '' : propertyPrefix ?? `${columnName}_`].join('');
|
|
252
|
-
return getPostgresColumnEntries(columnReflectionData?.embedded?.type ?? propertyMetadata.type, dbSchema, tableName, path.add(property), nestedPrefix);
|
|
355
|
+
return getPostgresColumnEntries(columnReflectionData?.embedded?.type ?? propertyMetadata.type, dbSchema, tableName, path.add(property), nestedPrefix, { ...options, inherited, table }, rootType);
|
|
253
356
|
}
|
|
254
|
-
const objectPath = path.add(property);
|
|
255
357
|
const encrypted = columnReflectionData?.encrypted == true;
|
|
256
358
|
const toDatabase = encrypted
|
|
257
359
|
? async (value, context) => {
|
|
@@ -270,6 +372,8 @@ function getPostgresColumnEntries(type, dbSchema, tableName, path = new JsonPath
|
|
|
270
372
|
name: toCamelCase(prefixedColumnName),
|
|
271
373
|
objectPath,
|
|
272
374
|
reflectionData: columnReflectionData,
|
|
375
|
+
inherited,
|
|
376
|
+
table: table, // Will be patched later if undefined
|
|
273
377
|
buildType: (options) => getPostgresColumn(tableName, toSnakeCase(prefixedColumnName), dbSchema, schema, columnReflectionData ?? {}, options, { type, property }),
|
|
274
378
|
dereferenceObjectPath: compileDereferencer(objectPath, { optional: true }),
|
|
275
379
|
toDatabase,
|
|
@@ -290,7 +394,7 @@ function getPostgresColumn(tableName, columnName, dbSchema, propertySchema, refl
|
|
|
290
394
|
if (isDefined(reflectionData.unique)) {
|
|
291
395
|
column = column.unique(reflectionData.unique.options?.name ?? getUniqueName(tableName, [columnName], { naming: reflectionData.unique.options?.naming }), isString(reflectionData.unique.options?.nulls) ? { nulls: reflectionData.unique.options.nulls } : undefined);
|
|
292
396
|
}
|
|
293
|
-
if ((reflectionData.primaryKey == true) && (options.skipPrimaryKey != true)) {
|
|
397
|
+
if (((reflectionData.primaryKey == true) || (context.property == 'id' && reflectionData.primaryKey != false)) && (options.skipPrimaryKey != true)) {
|
|
294
398
|
column = column.primaryKey();
|
|
295
399
|
}
|
|
296
400
|
for (const { target, targetColumn, excludeTenant } of reflectionData.references ?? []) {
|
|
@@ -313,6 +417,9 @@ function getPostgresBaseColumn(columnName, dbSchema, schema, reflectionData, con
|
|
|
313
417
|
if (reflectionData.encrypted) {
|
|
314
418
|
return bytea(columnName);
|
|
315
419
|
}
|
|
420
|
+
if (isDefined(reflectionData.tsVector)) {
|
|
421
|
+
return tsvector(columnName);
|
|
422
|
+
}
|
|
316
423
|
return match(schema)
|
|
317
424
|
.with(P.instanceOf(UuidSchema), (s) => {
|
|
318
425
|
let column = uuid(columnName);
|
|
@@ -375,7 +482,6 @@ function getForeignKeyName(tableName, foreignTableName, columnsOrBaseName, optio
|
|
|
375
482
|
}
|
|
376
483
|
throw new Error(`Identifier "${identifier}" for table "${tableName}" is too long. Maximum length is 63 characters.`);
|
|
377
484
|
}
|
|
378
|
-
console.log(tableName, foreignTableName, columnsOrBaseName, 'Foreign key name:', identifier);
|
|
379
485
|
return identifier;
|
|
380
486
|
}
|
|
381
487
|
function getTableName(type) {
|
package/orm/server/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export * from './database-schema.js';
|
|
|
8
8
|
export * from './database.js';
|
|
9
9
|
export * from './module.js';
|
|
10
10
|
export * from './query-converter.js';
|
|
11
|
+
export * from './repository-config.js';
|
|
11
12
|
export * from './repository.js';
|
|
12
13
|
export * from './transaction.js';
|
|
13
14
|
export * from './transactional.js';
|
package/orm/server/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export * from './database-schema.js';
|
|
|
8
8
|
export * from './database.js';
|
|
9
9
|
export * from './module.js';
|
|
10
10
|
export * from './query-converter.js';
|
|
11
|
+
export * from './repository-config.js';
|
|
11
12
|
export * from './repository.js';
|
|
12
13
|
export * from './transaction.js';
|
|
13
14
|
export * from './transactional.js';
|
package/orm/server/module.d.ts
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* via dependency injection.
|
|
6
6
|
*/
|
|
7
7
|
import type { PoolConfig } from 'pg';
|
|
8
|
-
import {
|
|
8
|
+
import { Injector } from '../../injector/injector.js';
|
|
9
|
+
import { EntityRepositoryConfig } from './repository-config.js';
|
|
9
10
|
/**
|
|
10
11
|
* Configuration class for the database connection.
|
|
11
12
|
*/
|
|
@@ -23,6 +24,7 @@ export type OrmModuleOptions = {
|
|
|
23
24
|
* Configures the ORM module by registering necessary providers in the dependency injector.
|
|
24
25
|
* @param options - Configuration options including connection details, repository settings, and the encryption secret.
|
|
25
26
|
*/
|
|
26
|
-
export declare function configureOrm(options
|
|
27
|
+
export declare function configureOrm({ injector, ...options }?: OrmModuleOptions & {
|
|
27
28
|
encryptionSecret?: Uint8Array;
|
|
29
|
+
injector?: Injector;
|
|
28
30
|
}): void;
|
package/orm/server/module.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Injector } from '../../injector/injector.js';
|
|
2
2
|
import { isDefined } from '../../utils/type-guards.js';
|
|
3
|
-
import { EntityRepositoryConfig } from './repository.js';
|
|
3
|
+
import { EntityRepositoryConfig } from './repository-config.js';
|
|
4
4
|
import { ENCRYPTION_SECRET } from './tokens.js';
|
|
5
5
|
/**
|
|
6
6
|
* Configuration class for the database connection.
|
|
@@ -12,14 +12,15 @@ export class DatabaseConfig {
|
|
|
12
12
|
* Configures the ORM module by registering necessary providers in the dependency injector.
|
|
13
13
|
* @param options - Configuration options including connection details, repository settings, and the encryption secret.
|
|
14
14
|
*/
|
|
15
|
-
export function configureOrm(options) {
|
|
15
|
+
export function configureOrm({ injector, ...options } = {}) {
|
|
16
|
+
const targetInjector = injector ?? Injector;
|
|
16
17
|
if (isDefined(options.connection)) {
|
|
17
|
-
|
|
18
|
+
targetInjector.register(DatabaseConfig, { useValue: { connection: options.connection } });
|
|
18
19
|
}
|
|
19
20
|
if (isDefined(options.repositoryConfig)) {
|
|
20
|
-
|
|
21
|
+
targetInjector.register(EntityRepositoryConfig, { useValue: options.repositoryConfig });
|
|
21
22
|
}
|
|
22
23
|
if (isDefined(options.encryptionSecret)) {
|
|
23
|
-
|
|
24
|
+
targetInjector.register(ENCRYPTION_SECRET, { useValue: options.encryptionSecret });
|
|
24
25
|
}
|
|
25
26
|
}
|
|
@@ -3,20 +3,23 @@ import type { BaseEntity } from '../entity.js';
|
|
|
3
3
|
import type { Query, TsVectorParser, TsVectorWeight } from '../query/index.js';
|
|
4
4
|
import type { TargetColumn } from '../repository.types.js';
|
|
5
5
|
import type { ColumnDefinition, ExtraConfigColumnsFromType, PgTableFromType } from './types.js';
|
|
6
|
+
export type ResolveTargetColumnOptions = {
|
|
7
|
+
ignorePgTable?: boolean;
|
|
8
|
+
};
|
|
6
9
|
/**
|
|
7
10
|
* Resolves a target to a Drizzle PgColumn or SQLWrapper.
|
|
8
11
|
* @param target The target to resolve.
|
|
9
12
|
* @param table The Drizzle table object.
|
|
10
13
|
* @param columnDefinitionsMap A map from property names to column definitions.
|
|
11
14
|
*/
|
|
12
|
-
export declare function resolveTargetColumn<T extends BaseEntity>(target: TargetColumn<T> | ColumnDefinition, table: PgTableFromType | ExtraConfigColumnsFromType, columnDefinitionsMap: Map<string, ColumnDefinition
|
|
15
|
+
export declare function resolveTargetColumn<T extends BaseEntity>(target: TargetColumn<T> | ColumnDefinition, table: PgTableFromType | ExtraConfigColumnsFromType, columnDefinitionsMap: Map<string, ColumnDefinition>, { ignorePgTable }?: ResolveTargetColumnOptions): SQLWrapper;
|
|
13
16
|
/**
|
|
14
17
|
* Resolves multiple targets to a Drizzle PgColumn or SQLWrapper.
|
|
15
18
|
* @param targets The targets to resolve.
|
|
16
19
|
* @param table The Drizzle table object.
|
|
17
20
|
* @param columnDefinitionsMap A map from property names to column definitions.
|
|
18
21
|
*/
|
|
19
|
-
export declare function resolveTargetColumns<T extends BaseEntity>(targets: readonly (TargetColumn<T> | ColumnDefinition)[], table: PgTableFromType | ExtraConfigColumnsFromType, columnDefinitionsMap: Map<string, ColumnDefinition
|
|
22
|
+
export declare function resolveTargetColumns<T extends BaseEntity>(targets: readonly (TargetColumn<T> | ColumnDefinition)[], table: PgTableFromType | ExtraConfigColumnsFromType, columnDefinitionsMap: Map<string, ColumnDefinition>, options?: ResolveTargetColumnOptions): SQLWrapper[];
|
|
20
23
|
/**
|
|
21
24
|
* Converts a query object into a Drizzle SQL condition.
|
|
22
25
|
* Recursively handles nested logical operators and maps property names to database columns.
|
|
@@ -29,6 +32,6 @@ export declare function resolveTargetColumns<T extends BaseEntity>(targets: read
|
|
|
29
32
|
* @throws {Error} If a property cannot be mapped to a column.
|
|
30
33
|
* @throws {Error} If an unsupported query type is encountered.
|
|
31
34
|
*/
|
|
32
|
-
export declare function convertQuery(query: Query, table: PgTableFromType, columnDefinitionsMap: Map<string, ColumnDefinition
|
|
35
|
+
export declare function convertQuery(query: Query, table: PgTableFromType, columnDefinitionsMap: Map<string, ColumnDefinition>, options?: ResolveTargetColumnOptions): SQL;
|
|
33
36
|
export declare function getTsQuery(text: string | SQL, language: string | SQL, parser: TsVectorParser): SQL;
|
|
34
37
|
export declare function getTsVector(fields: readonly (SQLWrapper | readonly [field: SQLWrapper, weight?: TsVectorWeight])[], language: string | SQL): SQL;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
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 { hasOwnProperty, mapObject, mapObjectKeysToSnakeCase, objectEntries } from '../../utils/object/object.js';
|
|
4
|
+
import { fromEntries, hasOwnProperty, mapObject, mapObjectKeysToSnakeCase, objectEntries } from '../../utils/object/object.js';
|
|
5
5
|
import { toSnakeCase } from '../../utils/string/index.js';
|
|
6
|
-
import { assert, assertDefinedPass, isArray, isDefined, isPrimitive, isRegExp, isString, isUndefined } from '../../utils/type-guards.js';
|
|
6
|
+
import { assert, assertDefinedPass, isArray, isDefined, isFunction, isObject, isPrimitive, isRegExp, isString, isUndefined } from '../../utils/type-guards.js';
|
|
7
7
|
import { array, isSimilar, isStrictWordSimilar, isWordSimilar, jsonbBuildObject, phraseToTsQuery, plainToTsQuery, setweight, similarity, strictWordSimilarity, toTsQuery, toTsVector, websearchToTsQuery, wordSimilarity } from '../sqls/index.js';
|
|
8
8
|
const sqlTrue = sql `true`;
|
|
9
9
|
/**
|
|
@@ -12,13 +12,16 @@ const sqlTrue = sql `true`;
|
|
|
12
12
|
* @param table The Drizzle table object.
|
|
13
13
|
* @param columnDefinitionsMap A map from property names to column definitions.
|
|
14
14
|
*/
|
|
15
|
-
export function resolveTargetColumn(target, table, columnDefinitionsMap) {
|
|
15
|
+
export function resolveTargetColumn(target, table, columnDefinitionsMap, { ignorePgTable = false } = {}) {
|
|
16
16
|
if ((target instanceof SQL) || (target instanceof SQL.Aliased) || (target instanceof Column)) {
|
|
17
17
|
return target;
|
|
18
18
|
}
|
|
19
19
|
const columnDef = isString(target)
|
|
20
20
|
? assertDefinedPass(columnDefinitionsMap.get(target), `Could not map property ${target} to column.`)
|
|
21
21
|
: target; // eslint-disable-line @typescript-eslint/no-unnecessary-type-assertion
|
|
22
|
+
if (isDefined(columnDef.table) && !ignorePgTable) {
|
|
23
|
+
return columnDef.table[columnDef.name];
|
|
24
|
+
}
|
|
22
25
|
return table[columnDef.name];
|
|
23
26
|
}
|
|
24
27
|
/**
|
|
@@ -27,8 +30,8 @@ export function resolveTargetColumn(target, table, columnDefinitionsMap) {
|
|
|
27
30
|
* @param table The Drizzle table object.
|
|
28
31
|
* @param columnDefinitionsMap A map from property names to column definitions.
|
|
29
32
|
*/
|
|
30
|
-
export function resolveTargetColumns(targets, table, columnDefinitionsMap) {
|
|
31
|
-
return targets.map((target) => resolveTargetColumn(target, table, columnDefinitionsMap));
|
|
33
|
+
export function resolveTargetColumns(targets, table, columnDefinitionsMap, options) {
|
|
34
|
+
return targets.map((target) => resolveTargetColumn(target, table, columnDefinitionsMap, options));
|
|
32
35
|
}
|
|
33
36
|
/**
|
|
34
37
|
* Converts a query object into a Drizzle SQL condition.
|
|
@@ -42,7 +45,7 @@ export function resolveTargetColumns(targets, table, columnDefinitionsMap) {
|
|
|
42
45
|
* @throws {Error} If a property cannot be mapped to a column.
|
|
43
46
|
* @throws {Error} If an unsupported query type is encountered.
|
|
44
47
|
*/
|
|
45
|
-
export function convertQuery(query, table, columnDefinitionsMap) {
|
|
48
|
+
export function convertQuery(query, table, columnDefinitionsMap, options) {
|
|
46
49
|
if (query instanceof SQL) {
|
|
47
50
|
return query;
|
|
48
51
|
}
|
|
@@ -57,7 +60,7 @@ export function convertQuery(query, table, columnDefinitionsMap) {
|
|
|
57
60
|
for (const [property, value] of queryEntries) {
|
|
58
61
|
switch (property) {
|
|
59
62
|
case '$and': {
|
|
60
|
-
const subQueries = value.map((item) => convertQuery(item, table, columnDefinitionsMap));
|
|
63
|
+
const subQueries = value.map((item) => convertQuery(item, table, columnDefinitionsMap, options));
|
|
61
64
|
const andCondition = and(...subQueries);
|
|
62
65
|
if (isDefined(andCondition)) {
|
|
63
66
|
conditions.push(andCondition);
|
|
@@ -65,7 +68,7 @@ export function convertQuery(query, table, columnDefinitionsMap) {
|
|
|
65
68
|
break;
|
|
66
69
|
}
|
|
67
70
|
case '$or': {
|
|
68
|
-
const subQueries = value.map((item) => convertQuery(item, table, columnDefinitionsMap));
|
|
71
|
+
const subQueries = value.map((item) => convertQuery(item, table, columnDefinitionsMap, options));
|
|
69
72
|
const orCondition = or(...subQueries);
|
|
70
73
|
if (isDefined(orCondition)) {
|
|
71
74
|
conditions.push(orCondition);
|
|
@@ -73,7 +76,7 @@ export function convertQuery(query, table, columnDefinitionsMap) {
|
|
|
73
76
|
break;
|
|
74
77
|
}
|
|
75
78
|
case '$nor': {
|
|
76
|
-
const subQueries = value.map((item) => convertQuery(item, table, columnDefinitionsMap));
|
|
79
|
+
const subQueries = value.map((item) => convertQuery(item, table, columnDefinitionsMap, options));
|
|
77
80
|
const orCondition = or(...subQueries);
|
|
78
81
|
if (isDefined(orCondition)) {
|
|
79
82
|
const norCondition = not(orCondition);
|
|
@@ -86,7 +89,7 @@ export function convertQuery(query, table, columnDefinitionsMap) {
|
|
|
86
89
|
const fields = assertDefinedPass(tsvectorQuery.fields, '`fields` is required for tsvector search.');
|
|
87
90
|
const convertedFields = fields.map((target) => {
|
|
88
91
|
const [field, weight] = isArray(target) ? target : [target, undefined];
|
|
89
|
-
const sqlField = resolveTargetColumn(field, table, columnDefinitionsMap);
|
|
92
|
+
const sqlField = resolveTargetColumn(field, table, columnDefinitionsMap, options);
|
|
90
93
|
if (isDefined(weight)) {
|
|
91
94
|
return [sqlField, weight];
|
|
92
95
|
}
|
|
@@ -100,7 +103,7 @@ export function convertQuery(query, table, columnDefinitionsMap) {
|
|
|
100
103
|
case '$trigram': {
|
|
101
104
|
const trigramQuery = value;
|
|
102
105
|
const fields = isArray(trigramQuery.fields) ? trigramQuery.fields : [trigramQuery.fields];
|
|
103
|
-
const convertedFields = fields.map((target) => resolveTargetColumn(target, table, columnDefinitionsMap));
|
|
106
|
+
const convertedFields = fields.map((target) => resolveTargetColumn(target, table, columnDefinitionsMap, options));
|
|
104
107
|
const searchExpression = sql `(${sql.join(convertedFields, sql ` || ' ' || `)})`;
|
|
105
108
|
if (isDefined(trigramQuery.threshold)) {
|
|
106
109
|
const similarityFn = getTrigramSimilarityFunction(trigramQuery.type);
|
|
@@ -117,7 +120,7 @@ export function convertQuery(query, table, columnDefinitionsMap) {
|
|
|
117
120
|
if (hasOwnProperty(paradeQuery, 'fields')) {
|
|
118
121
|
const { fields, query: searchQuery, conjunction, distance, prefix, transpositionCostOne } = paradeQuery;
|
|
119
122
|
const operator = (conjunction == true) ? sql `&&&` : sql `|||`;
|
|
120
|
-
const convertedFields = fields.map((target) => resolveTargetColumn(target, table, columnDefinitionsMap));
|
|
123
|
+
const convertedFields = fields.map((target) => resolveTargetColumn(target, table, columnDefinitionsMap, options));
|
|
121
124
|
const searchExpression = sql `(${sql.join(convertedFields, sql ` || ' ' || `)})`;
|
|
122
125
|
const casts = [];
|
|
123
126
|
if (isDefined(distance) && (distance > 0)) {
|
|
@@ -133,14 +136,22 @@ export function convertQuery(query, table, columnDefinitionsMap) {
|
|
|
133
136
|
conditions.push(condition);
|
|
134
137
|
}
|
|
135
138
|
else {
|
|
136
|
-
const convertedParadeQuery = convertParadeSpecialQuery(paradeQuery, table, columnDefinitionsMap);
|
|
139
|
+
const convertedParadeQuery = convertParadeSpecialQuery(paradeQuery, table, columnDefinitionsMap, options);
|
|
137
140
|
conditions.push(sql `${table.id} @@@ ${convertedParadeQuery}::pdb.query`);
|
|
138
141
|
}
|
|
139
142
|
break;
|
|
140
143
|
}
|
|
141
144
|
default: {
|
|
142
|
-
const columnDef =
|
|
143
|
-
|
|
145
|
+
const columnDef = columnDefinitionsMap.get(property);
|
|
146
|
+
if (isUndefined(columnDef)) {
|
|
147
|
+
if (isObject(value) && !isArray(value) && !isSQLWrapper(value)) {
|
|
148
|
+
const subQuery = fromEntries(objectEntries(value).map(([key, val]) => [`${property}.${key}`, val]));
|
|
149
|
+
conditions.push(convertQuery(subQuery, table, columnDefinitionsMap, options));
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
throw new Error(`Could not map property ${property} to column.`);
|
|
153
|
+
}
|
|
154
|
+
const column = resolveTargetColumn(columnDef, table, columnDefinitionsMap, options);
|
|
144
155
|
const condition = getCondition(property, value, column, table, columnDefinitionsMap);
|
|
145
156
|
conditions.push(condition);
|
|
146
157
|
break;
|
|
@@ -252,7 +263,7 @@ function getCondition(property, value, column, table, columnDefinitionsMap) {
|
|
|
252
263
|
}
|
|
253
264
|
if (hasOwnProperty(value, '$parade')) {
|
|
254
265
|
const queryValue = value.$parade;
|
|
255
|
-
if (isDefined(queryValue.match)) {
|
|
266
|
+
if (isDefined(queryValue.match) && isUndefined(queryValue.match.tokenizer)) {
|
|
256
267
|
const { value: matchValue, conjunctionMode, ...options } = queryValue.match;
|
|
257
268
|
const operator = (conjunctionMode == true) ? sql `&&&` : sql `|||`;
|
|
258
269
|
const casts = buildParadeCasts(options);
|
|
@@ -354,7 +365,7 @@ function convertParadeComparisonQuery(query) {
|
|
|
354
365
|
/**
|
|
355
366
|
* Converts a ParadeSpecialQueryObject into a Drizzle SQL object representing the JSONB structure.
|
|
356
367
|
*/
|
|
357
|
-
function convertParadeSpecialQuery(query, table, columnDefinitionsMap) {
|
|
368
|
+
function convertParadeSpecialQuery(query, table, columnDefinitionsMap, options) {
|
|
358
369
|
const entries = objectEntries(query);
|
|
359
370
|
assert(entries.length == 1, 'ParadeDB special query object must have exactly one key.');
|
|
360
371
|
const [key, queryValue] = entries[0];
|
|
@@ -363,10 +374,10 @@ function convertParadeSpecialQuery(query, table, columnDefinitionsMap) {
|
|
|
363
374
|
.with('all', 'empty', () => sql `null`)
|
|
364
375
|
.with('moreLikeThis', () => {
|
|
365
376
|
const { fields, document, ...properties } = mapObjectKeysToSnakeCase(queryValue);
|
|
366
|
-
const resolvedFields = fields.map((field) => resolveTargetColumn(field, table, columnDefinitionsMap));
|
|
377
|
+
const resolvedFields = fields.map((field) => resolveTargetColumn(field, table, columnDefinitionsMap, options));
|
|
367
378
|
const columnNames = resolvedFields.map((field) => (field instanceof Column) ? sql `${field.name}` : field);
|
|
368
379
|
const fieldsArraySql = (columnNames.length > 0) ? array(columnNames) : undefined;
|
|
369
|
-
const documentJson = isDefined(document) ? JSON.stringify(mapObject(document, (key, value) => [resolveTargetColumn(key, table, columnDefinitionsMap).name, value])) : undefined;
|
|
380
|
+
const documentJson = isDefined(document) ? JSON.stringify(mapObject(document, (key, value) => [resolveTargetColumn(key, table, columnDefinitionsMap, options).name, value])) : undefined;
|
|
370
381
|
return jsonbBuildObject({
|
|
371
382
|
...properties,
|
|
372
383
|
fields: fieldsArraySql,
|
|
@@ -414,7 +425,8 @@ export function getTsQuery(text, language, parser) {
|
|
|
414
425
|
export function getTsVector(fields, language) {
|
|
415
426
|
const sqlFields = fields.map((fieldWithWeight) => {
|
|
416
427
|
const [field, weight] = isArray(fieldWithWeight) ? fieldWithWeight : [fieldWithWeight, undefined];
|
|
417
|
-
const
|
|
428
|
+
const isTsVector = (field instanceof Column) && (field.getSQLType() == 'tsvector');
|
|
429
|
+
const vector = isTsVector ? sql `${field}` : toTsVector(language, field);
|
|
418
430
|
if (isDefined(weight)) {
|
|
419
431
|
return setweight(vector, weight);
|
|
420
432
|
}
|