@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
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { sql } from 'drizzle-orm';
|
|
11
|
+
import { beforeAll, describe, expect, test } from 'vitest';
|
|
12
|
+
import { Injector, runInInjectionContext } from '../../injector/index.js';
|
|
13
|
+
import { Integer, StringProperty } from '../../schema/index.js';
|
|
14
|
+
import { Table } from '../decorators.js';
|
|
15
|
+
import { Entity } from '../entity.js';
|
|
16
|
+
import { configureOrm, Database } from '../server/index.js';
|
|
17
|
+
import { injectRepository } from '../server/repository.js';
|
|
18
|
+
describe('ORM Query Complex (Integration)', () => {
|
|
19
|
+
let injector;
|
|
20
|
+
let db;
|
|
21
|
+
const schema = 'test_orm_query_complex';
|
|
22
|
+
let QueryEntity = class QueryEntity extends Entity {
|
|
23
|
+
tag;
|
|
24
|
+
score;
|
|
25
|
+
status;
|
|
26
|
+
};
|
|
27
|
+
__decorate([
|
|
28
|
+
StringProperty(),
|
|
29
|
+
__metadata("design:type", String)
|
|
30
|
+
], QueryEntity.prototype, "tag", void 0);
|
|
31
|
+
__decorate([
|
|
32
|
+
Integer(),
|
|
33
|
+
__metadata("design:type", Number)
|
|
34
|
+
], QueryEntity.prototype, "score", void 0);
|
|
35
|
+
__decorate([
|
|
36
|
+
StringProperty(),
|
|
37
|
+
__metadata("design:type", String)
|
|
38
|
+
], QueryEntity.prototype, "status", void 0);
|
|
39
|
+
QueryEntity = __decorate([
|
|
40
|
+
Table('query_entities', { schema })
|
|
41
|
+
], QueryEntity);
|
|
42
|
+
beforeAll(async () => {
|
|
43
|
+
injector = new Injector('Test');
|
|
44
|
+
configureOrm({
|
|
45
|
+
repositoryConfig: { schema },
|
|
46
|
+
connection: {
|
|
47
|
+
host: '127.0.0.1', port: 5432, user: 'tstdl', password: 'wf7rq6glrk5jykne', database: 'tstdl',
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
db = injector.resolve(Database);
|
|
51
|
+
await db.execute(sql `CREATE SCHEMA IF NOT EXISTS ${sql.identifier(schema)}`);
|
|
52
|
+
await db.execute(sql `DROP TABLE IF EXISTS ${sql.identifier(schema)}.${sql.identifier('query_entities')} CASCADE`);
|
|
53
|
+
await db.execute(sql `
|
|
54
|
+
CREATE TABLE ${sql.identifier(schema)}.${sql.identifier('query_entities')} (
|
|
55
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
56
|
+
tag TEXT NOT NULL,
|
|
57
|
+
score INTEGER NOT NULL,
|
|
58
|
+
status TEXT NOT NULL,
|
|
59
|
+
revision INTEGER NOT NULL,
|
|
60
|
+
revision_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
61
|
+
create_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
62
|
+
delete_timestamp TIMESTAMP WITH TIME ZONE,
|
|
63
|
+
attributes JSONB NOT NULL DEFAULT '{}'
|
|
64
|
+
)
|
|
65
|
+
`);
|
|
66
|
+
});
|
|
67
|
+
test('should support nested AND/OR logic', async () => {
|
|
68
|
+
await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('query_entities')} CASCADE`);
|
|
69
|
+
await runInInjectionContext(injector, async () => {
|
|
70
|
+
const repo = injectRepository(QueryEntity);
|
|
71
|
+
await repo.insertMany([
|
|
72
|
+
Object.assign(new QueryEntity(), { tag: 'A', score: 10, status: 'active' }),
|
|
73
|
+
Object.assign(new QueryEntity(), { tag: 'A', score: 20, status: 'inactive' }),
|
|
74
|
+
Object.assign(new QueryEntity(), { tag: 'B', score: 10, status: 'active' }),
|
|
75
|
+
Object.assign(new QueryEntity(), { tag: 'B', score: 20, status: 'inactive' }),
|
|
76
|
+
]);
|
|
77
|
+
// (Tag A AND Active) OR (Tag B AND Inactive)
|
|
78
|
+
const results = await repo.loadManyByQuery({
|
|
79
|
+
$or: [
|
|
80
|
+
{ $and: [{ tag: 'A' }, { status: 'active' }] },
|
|
81
|
+
{ $and: [{ tag: 'B' }, { status: 'inactive' }] },
|
|
82
|
+
],
|
|
83
|
+
});
|
|
84
|
+
expect(results).toHaveLength(2);
|
|
85
|
+
expect(results.some((r) => r.tag === 'A' && r.status === 'active')).toBe(true);
|
|
86
|
+
expect(results.some((r) => r.tag === 'B' && r.status === 'inactive')).toBe(true);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
test('should support implicit AND', async () => {
|
|
90
|
+
await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('query_entities')} CASCADE`);
|
|
91
|
+
await runInInjectionContext(injector, async () => {
|
|
92
|
+
const repo = injectRepository(QueryEntity);
|
|
93
|
+
await repo.insert(Object.assign(new QueryEntity(), { tag: 'A', score: 10, status: 'active' }));
|
|
94
|
+
const results = await repo.loadManyByQuery({
|
|
95
|
+
tag: 'A',
|
|
96
|
+
score: 10,
|
|
97
|
+
status: 'active',
|
|
98
|
+
});
|
|
99
|
+
expect(results).toHaveLength(1);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
test('should support NOT operator', async () => {
|
|
103
|
+
await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('query_entities')} CASCADE`);
|
|
104
|
+
await runInInjectionContext(injector, async () => {
|
|
105
|
+
const repo = injectRepository(QueryEntity);
|
|
106
|
+
await repo.insertMany([
|
|
107
|
+
Object.assign(new QueryEntity(), { tag: 'A', score: 10, status: 'active' }),
|
|
108
|
+
Object.assign(new QueryEntity(), { tag: 'B', score: 20, status: 'inactive' }),
|
|
109
|
+
]);
|
|
110
|
+
const results = await repo.loadManyByQuery({
|
|
111
|
+
tag: { $not: { $eq: 'A' } },
|
|
112
|
+
});
|
|
113
|
+
expect(results).toHaveLength(1);
|
|
114
|
+
expect(results[0].tag).toBe('B');
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
test('should support IN operator with empty array (should match nothing)', async () => {
|
|
118
|
+
await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('query_entities')} CASCADE`);
|
|
119
|
+
await runInInjectionContext(injector, async () => {
|
|
120
|
+
const repo = injectRepository(QueryEntity);
|
|
121
|
+
await repo.insert(Object.assign(new QueryEntity(), { tag: 'A', score: 10, status: 'active' }));
|
|
122
|
+
const results = await repo.loadManyByQuery({
|
|
123
|
+
tag: { $in: [] },
|
|
124
|
+
});
|
|
125
|
+
expect(results).toHaveLength(0);
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
test('should support NOT IN operator with empty array (should match everything)', async () => {
|
|
129
|
+
await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('query_entities')} CASCADE`);
|
|
130
|
+
await runInInjectionContext(injector, async () => {
|
|
131
|
+
const repo = injectRepository(QueryEntity);
|
|
132
|
+
await repo.insert(Object.assign(new QueryEntity(), { tag: 'A', score: 10, status: 'active' }));
|
|
133
|
+
const results = await repo.loadManyByQuery({
|
|
134
|
+
tag: { $nin: [] },
|
|
135
|
+
});
|
|
136
|
+
expect(results).toHaveLength(1);
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
test('should support REGEX operator', async () => {
|
|
140
|
+
await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('query_entities')} CASCADE`);
|
|
141
|
+
await runInInjectionContext(injector, async () => {
|
|
142
|
+
const repo = injectRepository(QueryEntity);
|
|
143
|
+
await repo.insertMany([
|
|
144
|
+
Object.assign(new QueryEntity(), { tag: 'apple', score: 10, status: '' }),
|
|
145
|
+
Object.assign(new QueryEntity(), { tag: 'banana', score: 10, status: '' }),
|
|
146
|
+
Object.assign(new QueryEntity(), { tag: 'apricot', score: 10, status: '' }),
|
|
147
|
+
]);
|
|
148
|
+
const results = await repo.loadManyByQuery({
|
|
149
|
+
tag: { $regex: '^ap' },
|
|
150
|
+
});
|
|
151
|
+
expect(results).toHaveLength(2); // apple, apricot
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
test('should support complex combination of logic and comparison', async () => {
|
|
155
|
+
await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('query_entities')} CASCADE`);
|
|
156
|
+
await runInInjectionContext(injector, async () => {
|
|
157
|
+
const repo = injectRepository(QueryEntity);
|
|
158
|
+
await repo.insertMany([
|
|
159
|
+
Object.assign(new QueryEntity(), { tag: 'A', score: 5, status: 'ok' }),
|
|
160
|
+
Object.assign(new QueryEntity(), { tag: 'A', score: 15, status: 'ok' }),
|
|
161
|
+
Object.assign(new QueryEntity(), { tag: 'A', score: 25, status: 'fail' }),
|
|
162
|
+
Object.assign(new QueryEntity(), { tag: 'B', score: 5, status: 'ok' }),
|
|
163
|
+
]);
|
|
164
|
+
// Tag A AND (Score > 10 AND Score < 20) AND Status != fail
|
|
165
|
+
const results = await repo.loadManyByQuery({
|
|
166
|
+
tag: 'A',
|
|
167
|
+
$and: [{ score: { $gt: 10 } }, { score: { $lt: 20 } }],
|
|
168
|
+
status: { $neq: 'fail' },
|
|
169
|
+
});
|
|
170
|
+
expect(results).toHaveLength(1);
|
|
171
|
+
expect(results[0].score).toBe(15);
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
test('should support NULL check', async () => {
|
|
175
|
+
await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('query_entities')} CASCADE`);
|
|
176
|
+
await runInInjectionContext(injector, async () => {
|
|
177
|
+
const repo = injectRepository(QueryEntity);
|
|
178
|
+
// Manually insert null status (violates NOT NULL usually, but let's assume nullable if we could change schema,
|
|
179
|
+
// but Entity defines it as string. We can query for null even if no rows can be null (result 0) OR if we use a nullable column).
|
|
180
|
+
// 'attributes' is JSONB and can be queried.
|
|
181
|
+
// But query-converter maps properties.
|
|
182
|
+
// Let's use a non-existent value for $eq which is different from null.
|
|
183
|
+
// But checking $eq: null generates IS NULL.
|
|
184
|
+
// Since our columns are NOT NULL, it should return empty.
|
|
185
|
+
await repo.insert(Object.assign(new QueryEntity(), { tag: 'A', score: 10, status: 'active' }));
|
|
186
|
+
const results = await repo.loadManyByQuery({
|
|
187
|
+
status: { $eq: null },
|
|
188
|
+
});
|
|
189
|
+
expect(results).toHaveLength(0);
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
test('should support NOT NULL check', async () => {
|
|
193
|
+
await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('query_entities')} CASCADE`);
|
|
194
|
+
await runInInjectionContext(injector, async () => {
|
|
195
|
+
const repo = injectRepository(QueryEntity);
|
|
196
|
+
await repo.insert(Object.assign(new QueryEntity(), { tag: 'A', score: 10, status: 'active' }));
|
|
197
|
+
const results = await repo.loadManyByQuery({
|
|
198
|
+
status: { $neq: null },
|
|
199
|
+
});
|
|
200
|
+
expect(results).toHaveLength(1);
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { describe, expect, test } from 'vitest';
|
|
11
|
+
import { sql } from 'drizzle-orm';
|
|
12
|
+
import { PgDialect } from 'drizzle-orm/pg-core';
|
|
13
|
+
import { StringProperty, Integer } from '../../schema/index.js';
|
|
14
|
+
import { Entity } from '../entity.js';
|
|
15
|
+
import { Column, Table } from '../decorators.js';
|
|
16
|
+
import { getDrizzleTableFromType, getColumnDefinitionsMap } from '../server/drizzle/schema-converter.js';
|
|
17
|
+
import { convertQuery } from '../server/query-converter.js';
|
|
18
|
+
describe('ORM Query Converter Complex', () => {
|
|
19
|
+
const dialect = new PgDialect();
|
|
20
|
+
let ComplexItem = class ComplexItem extends Entity {
|
|
21
|
+
name;
|
|
22
|
+
description;
|
|
23
|
+
value;
|
|
24
|
+
};
|
|
25
|
+
__decorate([
|
|
26
|
+
StringProperty(),
|
|
27
|
+
__metadata("design:type", String)
|
|
28
|
+
], ComplexItem.prototype, "name", void 0);
|
|
29
|
+
__decorate([
|
|
30
|
+
StringProperty(),
|
|
31
|
+
__metadata("design:type", String)
|
|
32
|
+
], ComplexItem.prototype, "description", void 0);
|
|
33
|
+
__decorate([
|
|
34
|
+
Integer(),
|
|
35
|
+
__metadata("design:type", Number)
|
|
36
|
+
], ComplexItem.prototype, "value", void 0);
|
|
37
|
+
ComplexItem = __decorate([
|
|
38
|
+
Table('complex_items', { schema: 'test' })
|
|
39
|
+
], ComplexItem);
|
|
40
|
+
const table = getDrizzleTableFromType(ComplexItem);
|
|
41
|
+
const colMap = getColumnDefinitionsMap(table);
|
|
42
|
+
test('should handle $tsvector with explicit weights', () => {
|
|
43
|
+
const q = {
|
|
44
|
+
$tsvector: {
|
|
45
|
+
fields: [['name', 'A'], ['description', 'B']],
|
|
46
|
+
query: 'search term',
|
|
47
|
+
language: 'english',
|
|
48
|
+
parser: 'websearch',
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
const condition = convertQuery(q, table, colMap);
|
|
52
|
+
const sqlStr = dialect.sqlToQuery(condition).sql;
|
|
53
|
+
expect(sqlStr).toContain('setweight(to_tsvector($1, "test"."complex_items"."name"), \'A\')');
|
|
54
|
+
expect(sqlStr).toContain('setweight(to_tsvector($2, "test"."complex_items"."description"), \'B\')');
|
|
55
|
+
expect(sqlStr).toContain('websearch_to_tsquery($3, $4)');
|
|
56
|
+
});
|
|
57
|
+
test('should handle ParadeDB $parade match with tokenizer', () => {
|
|
58
|
+
const q = {
|
|
59
|
+
name: {
|
|
60
|
+
$parade: {
|
|
61
|
+
match: {
|
|
62
|
+
value: 'test',
|
|
63
|
+
tokenizer: { type: 'ngram', min_gram: 3, max_gram: 3 },
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
const condition = convertQuery(q, table, colMap);
|
|
69
|
+
const sqlStr = dialect.sqlToQuery(condition).sql;
|
|
70
|
+
// Tokenizer is supported via JSON object syntax
|
|
71
|
+
expect(sqlStr).toContain('"test"."complex_items"."name" @@@ jsonb_build_object(\'match\', jsonb_build_object(\'value\', $1, \'tokenizer\', jsonb_build_object(\'type\', $2, \'min_gram\', $3, \'max_gram\', $4)))::pdb.query');
|
|
72
|
+
});
|
|
73
|
+
test('should handle ParadeDB $parade range', () => {
|
|
74
|
+
const q = {
|
|
75
|
+
value: {
|
|
76
|
+
$parade: {
|
|
77
|
+
range: {
|
|
78
|
+
lowerBound: { included: 10 },
|
|
79
|
+
upperBound: { excluded: 20 },
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
const condition = convertQuery(q, table, colMap);
|
|
85
|
+
const sqlStr = dialect.sqlToQuery(condition).sql;
|
|
86
|
+
// This should fall back to convertParadeComparisonQuery with recursive jsonb build
|
|
87
|
+
expect(sqlStr).toContain('"test"."complex_items"."value" @@@ jsonb_build_object(\'range\', jsonb_build_object(\'lower_bound\', jsonb_build_object(\'included\', $1), \'upper_bound\', jsonb_build_object(\'excluded\', $2)))::pdb.query');
|
|
88
|
+
});
|
|
89
|
+
test('should handle ParadeDB $parade phrasePrefix', () => {
|
|
90
|
+
const q = {
|
|
91
|
+
name: {
|
|
92
|
+
$parade: {
|
|
93
|
+
phrasePrefix: { phrases: ['hello', 'wor'], maxExpansions: 10 },
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
const condition = convertQuery(q, table, colMap);
|
|
98
|
+
const sqlStr = dialect.sqlToQuery(condition).sql;
|
|
99
|
+
expect(sqlStr).toContain('"test"."complex_items"."name" @@@ jsonb_build_object(\'phrase_prefix\', jsonb_build_object(\'phrases\', jsonb_build_array($1, $2), \'max_expansions\', $3))::pdb.query');
|
|
100
|
+
});
|
|
101
|
+
test('should handle ParadeDB $parade regexPhrase', () => {
|
|
102
|
+
const q = {
|
|
103
|
+
name: {
|
|
104
|
+
$parade: {
|
|
105
|
+
regexPhrase: { regexes: ['he.*', 'wo.*'], slop: 1 },
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
const condition = convertQuery(q, table, colMap);
|
|
110
|
+
const sqlStr = dialect.sqlToQuery(condition).sql;
|
|
111
|
+
expect(sqlStr).toContain('"test"."complex_items"."name" @@@ jsonb_build_object(\'regex_phrase\', jsonb_build_object(\'regexes\', jsonb_build_array($1, $2), \'slop\', $3))::pdb.query');
|
|
112
|
+
});
|
|
113
|
+
test('should handle ParadeDB top-level moreLikeThis', () => {
|
|
114
|
+
const q = {
|
|
115
|
+
$parade: {
|
|
116
|
+
moreLikeThis: {
|
|
117
|
+
keyValue: '123',
|
|
118
|
+
fields: ['name', 'description'],
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
const condition = convertQuery(q, table, colMap);
|
|
123
|
+
const sqlStr = dialect.sqlToQuery(condition).sql;
|
|
124
|
+
expect(sqlStr).toContain('"test"."complex_items"."id" @@@ jsonb_build_object(\'more_like_this\', jsonb_build_object(\'key_value\', $1, \'fields\', ARRAY[$2, $3]))::pdb.query');
|
|
125
|
+
});
|
|
126
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { describe, expect, test } from 'vitest';
|
|
11
|
+
import { eq, sql } from 'drizzle-orm';
|
|
12
|
+
import { getTableConfig, PgDialect } from 'drizzle-orm/pg-core';
|
|
13
|
+
import { StringProperty } from '../../schema/index.js';
|
|
14
|
+
import { Entity } from '../entity.js';
|
|
15
|
+
import { Column, Inheritance, ChildEntity, Table } from '../decorators.js';
|
|
16
|
+
import { getDrizzleTableFromType, getColumnDefinitionsMap } from '../server/drizzle/schema-converter.js';
|
|
17
|
+
import { convertQuery } from '../server/query-converter.js';
|
|
18
|
+
describe('ORM Query Converter (CTI)', () => {
|
|
19
|
+
test('should resolve columns to correct table in joined query', () => {
|
|
20
|
+
let BaseUser = class BaseUser extends Entity {
|
|
21
|
+
type;
|
|
22
|
+
name;
|
|
23
|
+
};
|
|
24
|
+
__decorate([
|
|
25
|
+
StringProperty(),
|
|
26
|
+
Column({ name: 'type' }),
|
|
27
|
+
__metadata("design:type", String)
|
|
28
|
+
], BaseUser.prototype, "type", void 0);
|
|
29
|
+
__decorate([
|
|
30
|
+
StringProperty(),
|
|
31
|
+
Column({ name: 'name' }),
|
|
32
|
+
__metadata("design:type", String)
|
|
33
|
+
], BaseUser.prototype, "name", void 0);
|
|
34
|
+
BaseUser = __decorate([
|
|
35
|
+
Table('users', { schema: 'test' }),
|
|
36
|
+
Inheritance({ strategy: 'joined', discriminatorColumn: 'type' })
|
|
37
|
+
], BaseUser);
|
|
38
|
+
let Admin = class Admin extends BaseUser {
|
|
39
|
+
role;
|
|
40
|
+
};
|
|
41
|
+
__decorate([
|
|
42
|
+
StringProperty(),
|
|
43
|
+
Column({ name: 'role' }),
|
|
44
|
+
__metadata("design:type", String)
|
|
45
|
+
], Admin.prototype, "role", void 0);
|
|
46
|
+
Admin = __decorate([
|
|
47
|
+
Table('admins', { schema: 'test' }),
|
|
48
|
+
ChildEntity('admin')
|
|
49
|
+
], Admin);
|
|
50
|
+
const parentTable = getDrizzleTableFromType(BaseUser);
|
|
51
|
+
const childTable = getDrizzleTableFromType(Admin);
|
|
52
|
+
const columnDefinitionsMap = getColumnDefinitionsMap(childTable);
|
|
53
|
+
const dialect = new PgDialect();
|
|
54
|
+
// Query on child property
|
|
55
|
+
const query1 = { role: 'super' };
|
|
56
|
+
const sql1 = convertQuery(query1, childTable, columnDefinitionsMap);
|
|
57
|
+
const sqlString1 = dialect.sqlToQuery(sql1).sql;
|
|
58
|
+
expect(sqlString1).toContain('"admins"."role" = $1');
|
|
59
|
+
// Query on parent property
|
|
60
|
+
const query2 = { name: 'admin' };
|
|
61
|
+
const sql2 = convertQuery(query2, childTable, columnDefinitionsMap);
|
|
62
|
+
const sqlString2 = dialect.sqlToQuery(sql2).sql;
|
|
63
|
+
expect(sqlString2).toContain('"users"."name" = $1');
|
|
64
|
+
expect(sqlString2).not.toContain('"admins"."name"');
|
|
65
|
+
});
|
|
66
|
+
test('should handle $regex with flags', () => {
|
|
67
|
+
let Item = class Item extends Entity {
|
|
68
|
+
name;
|
|
69
|
+
};
|
|
70
|
+
__decorate([
|
|
71
|
+
StringProperty(),
|
|
72
|
+
__metadata("design:type", String)
|
|
73
|
+
], Item.prototype, "name", void 0);
|
|
74
|
+
Item = __decorate([
|
|
75
|
+
Table('items', { schema: 'test' })
|
|
76
|
+
], Item);
|
|
77
|
+
const table = getDrizzleTableFromType(Item);
|
|
78
|
+
const colMap = getColumnDefinitionsMap(table);
|
|
79
|
+
const dialect = new PgDialect();
|
|
80
|
+
const q = convertQuery({ name: { $regex: { pattern: '^test', flags: 'i' } } }, table, colMap);
|
|
81
|
+
const sqlStr = dialect.sqlToQuery(q).sql;
|
|
82
|
+
expect(sqlStr).toContain('"items"."name" ~* $1');
|
|
83
|
+
});
|
|
84
|
+
test('should handle $nin (not in)', () => {
|
|
85
|
+
let Item = class Item extends Entity {
|
|
86
|
+
name;
|
|
87
|
+
};
|
|
88
|
+
__decorate([
|
|
89
|
+
StringProperty(),
|
|
90
|
+
__metadata("design:type", String)
|
|
91
|
+
], Item.prototype, "name", void 0);
|
|
92
|
+
Item = __decorate([
|
|
93
|
+
Table('items', { schema: 'test' })
|
|
94
|
+
], Item);
|
|
95
|
+
const table = getDrizzleTableFromType(Item);
|
|
96
|
+
const colMap = getColumnDefinitionsMap(table);
|
|
97
|
+
const dialect = new PgDialect();
|
|
98
|
+
const q = convertQuery({ name: { $nin: ['a', 'b'] } }, table, colMap);
|
|
99
|
+
const sqlStr = dialect.sqlToQuery(q).sql;
|
|
100
|
+
expect(sqlStr.toLowerCase()).toContain('"items"."name" not in ($1, $2)');
|
|
101
|
+
});
|
|
102
|
+
test('should handle logical $nor', () => {
|
|
103
|
+
let Item = class Item extends Entity {
|
|
104
|
+
name;
|
|
105
|
+
};
|
|
106
|
+
__decorate([
|
|
107
|
+
StringProperty(),
|
|
108
|
+
__metadata("design:type", String)
|
|
109
|
+
], Item.prototype, "name", void 0);
|
|
110
|
+
Item = __decorate([
|
|
111
|
+
Table('items', { schema: 'test' })
|
|
112
|
+
], Item);
|
|
113
|
+
const table = getDrizzleTableFromType(Item);
|
|
114
|
+
const colMap = getColumnDefinitionsMap(table);
|
|
115
|
+
const dialect = new PgDialect();
|
|
116
|
+
const q = convertQuery({ $nor: [{ name: 'a' }, { name: 'b' }] }, table, colMap);
|
|
117
|
+
const sqlStr = dialect.sqlToQuery(q).sql.toLowerCase();
|
|
118
|
+
expect(sqlStr).toContain('not');
|
|
119
|
+
expect(sqlStr).toContain('"items"."name" = $1');
|
|
120
|
+
expect(sqlStr).toContain('"items"."name" = $2');
|
|
121
|
+
expect(sqlStr).toContain('or');
|
|
122
|
+
});
|
|
123
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|