@tstdl/base 0.93.181 → 0.93.183
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/api/server/api-request-token.provider.js +1 -1
- package/api/server/gateway.js +8 -3
- package/authentication/authentication.api.d.ts +13 -40
- package/authentication/authentication.api.js +5 -14
- package/authentication/client/authentication.service.d.ts +6 -14
- package/authentication/client/authentication.service.js +22 -4
- package/authentication/client/module.d.ts +1 -1
- package/authentication/client/module.js +4 -4
- package/authentication/models/index.d.ts +1 -0
- package/authentication/models/index.js +1 -0
- package/authentication/models/totp-results.model.d.ts +11 -0
- package/authentication/models/totp-results.model.js +37 -0
- package/authentication/server/authentication.api-controller.d.ts +3 -3
- package/authentication/server/authentication.api-controller.js +31 -4
- package/authentication/server/authentication.service.d.ts +5 -14
- package/authentication/server/authentication.service.js +6 -4
- package/core.d.ts +0 -5
- package/core.js +0 -8
- package/document-management/api/document-management.api.d.ts +2 -2
- package/document-management/service-models/document.service-model.d.ts +1 -1
- package/examples/config.d.ts +25 -0
- package/examples/config.js +26 -0
- package/notification/server/module.d.ts +1 -1
- package/notification/server/module.js +1 -1
- package/package.json +5 -5
- package/signals/api.d.ts +5 -1
- package/signals/api.js +3 -1
- package/signals/implementation/api.d.ts +13 -5
- package/signals/implementation/api.js +7 -1
- package/signals/implementation/asserts.d.ts +2 -2
- package/signals/implementation/asserts.js +3 -3
- package/signals/implementation/computed.d.ts +7 -34
- package/signals/implementation/computed.js +14 -83
- package/signals/implementation/configure.js +6 -2
- package/signals/implementation/effect.d.ts +65 -46
- package/signals/implementation/effect.js +97 -62
- package/signals/implementation/index.d.ts +2 -4
- package/signals/implementation/index.js +2 -4
- package/signals/implementation/linked_signal.d.ts +36 -0
- package/signals/implementation/linked_signal.js +34 -0
- package/signals/implementation/primitive/computed.d.ts +55 -0
- package/signals/implementation/primitive/computed.js +107 -0
- package/signals/implementation/primitive/effect.d.ts +26 -0
- package/signals/implementation/primitive/effect.js +31 -0
- package/signals/implementation/{equality.d.ts → primitive/equality.d.ts} +1 -1
- package/signals/implementation/{equality.js → primitive/equality.js} +1 -1
- package/signals/implementation/primitive/errors.d.ts +10 -0
- package/signals/implementation/{errors.js → primitive/errors.js} +3 -4
- package/signals/implementation/primitive/formatter.d.ts +19 -0
- package/signals/implementation/primitive/formatter.js +136 -0
- package/signals/implementation/{graph.d.ts → primitive/graph.d.ts} +68 -36
- package/signals/implementation/primitive/graph.js +386 -0
- package/signals/implementation/primitive/linked_signal.d.ts +46 -0
- package/signals/implementation/primitive/linked_signal.js +110 -0
- package/signals/implementation/primitive/signal.d.ts +31 -0
- package/signals/implementation/primitive/signal.js +80 -0
- package/signals/implementation/primitive/untracked.d.ts +12 -0
- package/signals/implementation/primitive/untracked.js +23 -0
- package/signals/implementation/{watch.d.ts → primitive/watch.d.ts} +1 -2
- package/signals/implementation/{watch.js → primitive/watch.js} +22 -16
- package/signals/implementation/resource/api.d.ts +275 -0
- package/signals/implementation/resource/api.js +26 -0
- package/signals/implementation/resource/debounce.d.ts +13 -0
- package/signals/implementation/resource/debounce.js +113 -0
- package/signals/implementation/resource/from_snapshots.d.ts +16 -0
- package/signals/implementation/resource/from_snapshots.js +44 -0
- package/signals/implementation/resource/index.d.ts +11 -0
- package/signals/implementation/resource/index.js +11 -0
- package/signals/implementation/resource/resource.d.ts +110 -0
- package/signals/implementation/resource/resource.js +402 -0
- package/signals/implementation/root_effect_scheduler.d.ts +50 -0
- package/signals/implementation/root_effect_scheduler.js +66 -0
- package/signals/implementation/signal.d.ts +42 -18
- package/signals/implementation/signal.js +29 -49
- package/signals/implementation/to-observable.d.ts +12 -5
- package/signals/implementation/to-observable.js +12 -2
- package/signals/implementation/to-signal.d.ts +9 -18
- package/signals/implementation/to-signal.js +46 -13
- package/signals/implementation/untracked.d.ts +1 -1
- package/signals/implementation/untracked.js +3 -11
- package/signals/operators/debounce.d.ts +8 -0
- package/signals/operators/debounce.js +19 -0
- package/signals/operators/derive-async.js +43 -15
- package/signals/operators/index.d.ts +2 -0
- package/signals/operators/index.js +2 -0
- package/signals/operators/throttle.d.ts +8 -0
- package/signals/operators/throttle.js +31 -0
- package/ai/genkit/tests/multi-region.test.d.ts +0 -2
- package/ai/genkit/tests/multi-region.test.js +0 -179
- package/ai/genkit/tests/token-limit-fallback.test.d.ts +0 -2
- package/ai/genkit/tests/token-limit-fallback.test.js +0 -209
- package/ai/prompts/tests/prompt-builder.test.d.ts +0 -1
- package/ai/prompts/tests/prompt-builder.test.js +0 -22
- package/ai/tests/instructions-formatter.test.d.ts +0 -1
- package/ai/tests/instructions-formatter.test.js +0 -116
- package/ai/tests/steering.test.d.ts +0 -1
- package/ai/tests/steering.test.js +0 -37
- package/api/client/tests/api-client.test.d.ts +0 -1
- package/api/client/tests/api-client.test.js +0 -194
- package/api/server/tests/csrf.middleware.test.d.ts +0 -1
- package/api/server/tests/csrf.middleware.test.js +0 -91
- package/authentication/tests/authentication-password-requirements.validator.test.d.ts +0 -1
- package/authentication/tests/authentication-password-requirements.validator.test.js +0 -29
- package/authentication/tests/authentication.api-controller.test.d.ts +0 -1
- package/authentication/tests/authentication.api-controller.test.js +0 -156
- package/authentication/tests/authentication.api-request-token.provider.test.d.ts +0 -1
- package/authentication/tests/authentication.api-request-token.provider.test.js +0 -48
- package/authentication/tests/authentication.client-error-handling.test.d.ts +0 -1
- package/authentication/tests/authentication.client-error-handling.test.js +0 -123
- package/authentication/tests/authentication.client-middleware.test.d.ts +0 -1
- package/authentication/tests/authentication.client-middleware.test.js +0 -118
- package/authentication/tests/authentication.client-service-methods.test.d.ts +0 -1
- package/authentication/tests/authentication.client-service-methods.test.js +0 -177
- package/authentication/tests/authentication.client-service-refresh.test.d.ts +0 -1
- package/authentication/tests/authentication.client-service-refresh.test.js +0 -153
- package/authentication/tests/authentication.client-service.test.d.ts +0 -1
- package/authentication/tests/authentication.client-service.test.js +0 -76
- package/authentication/tests/authentication.refresh-busy-loop.test.d.ts +0 -1
- package/authentication/tests/authentication.refresh-busy-loop.test.js +0 -84
- package/authentication/tests/authentication.service.test.d.ts +0 -1
- package/authentication/tests/authentication.service.test.js +0 -167
- package/authentication/tests/authentication.test-ancillary-service.d.ts +0 -9
- package/authentication/tests/authentication.test-ancillary-service.js +0 -27
- package/authentication/tests/brute-force-protection.test.d.ts +0 -1
- package/authentication/tests/brute-force-protection.test.js +0 -211
- package/authentication/tests/helper.test.d.ts +0 -1
- package/authentication/tests/helper.test.js +0 -122
- package/authentication/tests/password-requirements.error.test.d.ts +0 -1
- package/authentication/tests/password-requirements.error.test.js +0 -14
- package/authentication/tests/remember.api.test.d.ts +0 -1
- package/authentication/tests/remember.api.test.js +0 -117
- package/authentication/tests/remember.service.test.d.ts +0 -1
- package/authentication/tests/remember.service.test.js +0 -83
- package/authentication/tests/subject.service.test.d.ts +0 -1
- package/authentication/tests/subject.service.test.js +0 -140
- package/authentication/tests/suspended-subject.test.d.ts +0 -1
- package/authentication/tests/suspended-subject.test.js +0 -120
- package/authentication/tests/totp.enrollment.test.d.ts +0 -1
- package/authentication/tests/totp.enrollment.test.js +0 -123
- package/authentication/tests/totp.login.test.d.ts +0 -1
- package/authentication/tests/totp.login.test.js +0 -213
- package/authentication/tests/totp.recovery-codes.test.d.ts +0 -1
- package/authentication/tests/totp.recovery-codes.test.js +0 -97
- package/authentication/tests/totp.status.test.d.ts +0 -1
- package/authentication/tests/totp.status.test.js +0 -72
- package/cancellation/tests/coverage.test.d.ts +0 -1
- package/cancellation/tests/coverage.test.js +0 -49
- package/cancellation/tests/leak.test.d.ts +0 -1
- package/cancellation/tests/leak.test.js +0 -35
- package/cancellation/tests/token.test.d.ts +0 -1
- package/cancellation/tests/token.test.js +0 -136
- package/circuit-breaker/tests/circuit-breaker.test.d.ts +0 -1
- package/circuit-breaker/tests/circuit-breaker.test.js +0 -116
- package/cryptography/tests/cryptography.test.d.ts +0 -1
- package/cryptography/tests/cryptography.test.js +0 -175
- package/cryptography/tests/jwt.test.d.ts +0 -1
- package/cryptography/tests/jwt.test.js +0 -54
- package/cryptography/tests/modern.test.d.ts +0 -1
- package/cryptography/tests/modern.test.js +0 -105
- package/cryptography/tests/module.test.d.ts +0 -1
- package/cryptography/tests/module.test.js +0 -100
- package/cryptography/tests/totp.test.d.ts +0 -1
- package/cryptography/tests/totp.test.js +0 -108
- package/document-management/tests/ai-config-hierarchy.test.d.ts +0 -1
- package/document-management/tests/ai-config-hierarchy.test.js +0 -59
- package/document-management/tests/ai-config-integration.test.d.ts +0 -1
- package/document-management/tests/ai-config-integration.test.js +0 -125
- package/document-management/tests/ai-config-merge.test.d.ts +0 -1
- package/document-management/tests/ai-config-merge.test.js +0 -46
- package/document-management/tests/document-management-ai-overrides.test.d.ts +0 -1
- package/document-management/tests/document-management-ai-overrides.test.js +0 -63
- package/document-management/tests/document-management-core.test.d.ts +0 -1
- package/document-management/tests/document-management-core.test.js +0 -157
- package/document-management/tests/document-management.api.test.d.ts +0 -1
- package/document-management/tests/document-management.api.test.js +0 -101
- package/document-management/tests/document-statistics.service.test.d.ts +0 -1
- package/document-management/tests/document-statistics.service.test.js +0 -498
- package/document-management/tests/document-validation-ai-overrides.test.d.ts +0 -1
- package/document-management/tests/document-validation-ai-overrides.test.js +0 -87
- package/document-management/tests/document.service.test.d.ts +0 -1
- package/document-management/tests/document.service.test.js +0 -143
- package/document-management/tests/enum-helpers.test.d.ts +0 -1
- package/document-management/tests/enum-helpers.test.js +0 -452
- package/document-management/tests/helper.d.ts +0 -24
- package/document-management/tests/helper.js +0 -39
- package/errors/tests/format.test.d.ts +0 -1
- package/errors/tests/format.test.js +0 -84
- package/http/tests/server-timing.test.d.ts +0 -1
- package/http/tests/server-timing.test.js +0 -42
- package/injector/tests/advanced.test.d.ts +0 -1
- package/injector/tests/advanced.test.js +0 -116
- package/injector/tests/async-init.test.d.ts +0 -1
- package/injector/tests/async-init.test.js +0 -77
- package/injector/tests/basic.test.d.ts +0 -1
- package/injector/tests/basic.test.js +0 -114
- package/injector/tests/hierarchical.test.d.ts +0 -1
- package/injector/tests/hierarchical.test.js +0 -59
- package/injector/tests/leak.test.d.ts +0 -1
- package/injector/tests/leak.test.js +0 -45
- package/injector/tests/lifecycles.test.d.ts +0 -1
- package/injector/tests/lifecycles.test.js +0 -109
- package/logger/tests/pretty-print.test.d.ts +0 -1
- package/logger/tests/pretty-print.test.js +0 -60
- package/notification/tests/notification-api.test.d.ts +0 -1
- package/notification/tests/notification-api.test.js +0 -124
- package/notification/tests/notification-client.test.d.ts +0 -1
- package/notification/tests/notification-client.test.js +0 -101
- package/notification/tests/notification-flow.test.d.ts +0 -1
- package/notification/tests/notification-flow.test.js +0 -296
- package/notification/tests/notification-sse.service.test.d.ts +0 -1
- package/notification/tests/notification-sse.service.test.js +0 -43
- package/notification/tests/notification-type.service.test.d.ts +0 -1
- package/notification/tests/notification-type.service.test.js +0 -41
- package/object-storage/s3/tests/s3.object-storage.integration.test.d.ts +0 -1
- package/object-storage/s3/tests/s3.object-storage.integration.test.js +0 -303
- package/orm/tests/build-jsonb.test.d.ts +0 -1
- package/orm/tests/build-jsonb.test.js +0 -39
- package/orm/tests/data-types.test.d.ts +0 -1
- package/orm/tests/data-types.test.js +0 -39
- package/orm/tests/database-extension.test.d.ts +0 -1
- package/orm/tests/database-extension.test.js +0 -63
- package/orm/tests/database-migration.test.d.ts +0 -1
- package/orm/tests/database-migration.test.js +0 -83
- package/orm/tests/decorators.test.d.ts +0 -1
- package/orm/tests/decorators.test.js +0 -77
- package/orm/tests/encryption.test.d.ts +0 -1
- package/orm/tests/encryption.test.js +0 -31
- package/orm/tests/query-complex.test.d.ts +0 -1
- package/orm/tests/query-complex.test.js +0 -172
- package/orm/tests/query-converter-complex.test.d.ts +0 -1
- package/orm/tests/query-converter-complex.test.js +0 -131
- package/orm/tests/query-converter.test.d.ts +0 -1
- package/orm/tests/query-converter.test.js +0 -123
- package/orm/tests/repository-advanced.test.d.ts +0 -1
- package/orm/tests/repository-advanced.test.js +0 -189
- package/orm/tests/repository-attributes.test.d.ts +0 -1
- package/orm/tests/repository-attributes.test.js +0 -83
- package/orm/tests/repository-compound-primary-key.test.d.ts +0 -2
- package/orm/tests/repository-compound-primary-key.test.js +0 -226
- package/orm/tests/repository-comprehensive.test.d.ts +0 -1
- package/orm/tests/repository-comprehensive.test.js +0 -162
- package/orm/tests/repository-coverage.test.d.ts +0 -2
- package/orm/tests/repository-coverage.test.js +0 -242
- package/orm/tests/repository-cti-complex.test.d.ts +0 -1
- package/orm/tests/repository-cti-complex.test.js +0 -151
- package/orm/tests/repository-cti-embedded.test.d.ts +0 -1
- package/orm/tests/repository-cti-embedded.test.js +0 -178
- package/orm/tests/repository-cti-extensive.test.d.ts +0 -2
- package/orm/tests/repository-cti-extensive.test.js +0 -279
- package/orm/tests/repository-cti-mapping.test.d.ts +0 -2
- package/orm/tests/repository-cti-mapping.test.js +0 -108
- package/orm/tests/repository-cti-search.test.d.ts +0 -1
- package/orm/tests/repository-cti-search.test.js +0 -141
- package/orm/tests/repository-cti-soft-delete.test.d.ts +0 -2
- package/orm/tests/repository-cti-soft-delete.test.js +0 -103
- package/orm/tests/repository-cti-transactions.test.d.ts +0 -1
- package/orm/tests/repository-cti-transactions.test.js +0 -112
- package/orm/tests/repository-cti-upsert-many.test.d.ts +0 -2
- package/orm/tests/repository-cti-upsert-many.test.js +0 -115
- package/orm/tests/repository-cti.test.d.ts +0 -2
- package/orm/tests/repository-cti.test.js +0 -390
- package/orm/tests/repository-edge-cases.test.d.ts +0 -1
- package/orm/tests/repository-edge-cases.test.js +0 -178
- package/orm/tests/repository-expiration.test.d.ts +0 -2
- package/orm/tests/repository-expiration.test.js +0 -140
- package/orm/tests/repository-extra-coverage.test.d.ts +0 -2
- package/orm/tests/repository-extra-coverage.test.js +0 -402
- package/orm/tests/repository-mapping.test.d.ts +0 -2
- package/orm/tests/repository-mapping.test.js +0 -65
- package/orm/tests/repository-regression.test.d.ts +0 -1
- package/orm/tests/repository-regression.test.js +0 -288
- package/orm/tests/repository-search-coverage.test.d.ts +0 -1
- package/orm/tests/repository-search-coverage.test.js +0 -107
- package/orm/tests/repository-search.test.d.ts +0 -1
- package/orm/tests/repository-search.test.js +0 -105
- package/orm/tests/repository-soft-delete.test.d.ts +0 -1
- package/orm/tests/repository-soft-delete.test.js +0 -118
- package/orm/tests/repository-transactions-nested.test.d.ts +0 -1
- package/orm/tests/repository-transactions-nested.test.js +0 -178
- package/orm/tests/repository-types.test.d.ts +0 -1
- package/orm/tests/repository-types.test.js +0 -184
- package/orm/tests/repository-undelete.test.d.ts +0 -2
- package/orm/tests/repository-undelete.test.js +0 -201
- package/orm/tests/schema-converter.test.d.ts +0 -1
- package/orm/tests/schema-converter.test.js +0 -82
- package/orm/tests/schema-generation.test.d.ts +0 -2
- package/orm/tests/schema-generation.test.js +0 -174
- package/orm/tests/sql-helpers.test.d.ts +0 -1
- package/orm/tests/sql-helpers.test.js +0 -67
- package/orm/tests/transaction-safety.test.d.ts +0 -1
- package/orm/tests/transaction-safety.test.js +0 -81
- package/orm/tests/transactional.test.d.ts +0 -1
- package/orm/tests/transactional.test.js +0 -215
- package/orm/tests/utils.test.d.ts +0 -1
- package/orm/tests/utils.test.js +0 -70
- package/pdf/tests/utils.test.d.ts +0 -1
- package/pdf/tests/utils.test.js +0 -187
- package/process/tests/spawn.test.d.ts +0 -1
- package/process/tests/spawn.test.js +0 -182
- package/rate-limit/tests/postgres-rate-limiter.test.d.ts +0 -1
- package/rate-limit/tests/postgres-rate-limiter.test.js +0 -84
- package/renderer/tests/renderer.test.d.ts +0 -1
- package/renderer/tests/renderer.test.js +0 -88
- package/rpc/tests/rpc.integration.test.d.ts +0 -1
- package/rpc/tests/rpc.integration.test.js +0 -615
- package/signals/implementation/errors.d.ts +0 -2
- package/signals/implementation/graph.js +0 -312
- package/signals/implementation/writable-signal.d.ts +0 -48
- package/signals/implementation/writable-signal.js +0 -32
- package/task-queue/tests/coverage-branch.test.d.ts +0 -1
- package/task-queue/tests/coverage-branch.test.js +0 -395
- package/task-queue/tests/coverage-enhancement.test.d.ts +0 -1
- package/task-queue/tests/coverage-enhancement.test.js +0 -150
- package/task-queue/tests/dag.test.d.ts +0 -1
- package/task-queue/tests/dag.test.js +0 -188
- package/task-queue/tests/dependencies.test.d.ts +0 -1
- package/task-queue/tests/dependencies.test.js +0 -296
- package/task-queue/tests/enqueue-batch.test.d.ts +0 -1
- package/task-queue/tests/enqueue-batch.test.js +0 -125
- package/task-queue/tests/enqueue-item.test.d.ts +0 -1
- package/task-queue/tests/enqueue-item.test.js +0 -12
- package/task-queue/tests/fan-out-spawning.test.d.ts +0 -1
- package/task-queue/tests/fan-out-spawning.test.js +0 -94
- package/task-queue/tests/idempotent-replacement.test.d.ts +0 -1
- package/task-queue/tests/idempotent-replacement.test.js +0 -114
- package/task-queue/tests/missing-idempotent-tasks.test.d.ts +0 -1
- package/task-queue/tests/missing-idempotent-tasks.test.js +0 -39
- package/task-queue/tests/optimization-edge-cases.test.d.ts +0 -1
- package/task-queue/tests/optimization-edge-cases.test.js +0 -124
- package/task-queue/tests/queue-generic.test.d.ts +0 -1
- package/task-queue/tests/queue-generic.test.js +0 -8
- package/task-queue/tests/queue.test.d.ts +0 -1
- package/task-queue/tests/queue.test.js +0 -756
- package/task-queue/tests/shutdown.test.d.ts +0 -1
- package/task-queue/tests/shutdown.test.js +0 -41
- package/task-queue/tests/task-context.test.d.ts +0 -1
- package/task-queue/tests/task-context.test.js +0 -7
- package/task-queue/tests/task-union.test.d.ts +0 -1
- package/task-queue/tests/task-union.test.js +0 -18
- package/task-queue/tests/transactions.test.d.ts +0 -1
- package/task-queue/tests/transactions.test.js +0 -47
- package/task-queue/tests/typing.test.d.ts +0 -1
- package/task-queue/tests/typing.test.js +0 -9
- package/task-queue/tests/worker.test.d.ts +0 -1
- package/task-queue/tests/worker.test.js +0 -258
- package/task-queue/tests/zombie-parent.test.d.ts +0 -1
- package/task-queue/tests/zombie-parent.test.js +0 -45
- package/task-queue/tests/zombie-recovery.test.d.ts +0 -1
- package/task-queue/tests/zombie-recovery.test.js +0 -51
- package/utils/tests/backoff.test.d.ts +0 -1
- package/utils/tests/backoff.test.js +0 -41
- package/utils/tests/retry-with-backoff.test.d.ts +0 -1
- package/utils/tests/retry-with-backoff.test.js +0 -49
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
/** biome-ignore-all lint/nursery/noExcessiveClassesPerFile: <explanation> */
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
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;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
-
};
|
|
11
|
-
import { getTableConfig } from 'drizzle-orm/pg-core';
|
|
12
|
-
import { describe, expect, test } from 'vitest';
|
|
13
|
-
import { StringProperty } from '../../schema/index.js';
|
|
14
|
-
import { ChildEntity, Column, Inheritance, ParadeIndex, Table } from '../decorators.js';
|
|
15
|
-
import { Entity, TenantEntity } from '../entity.js';
|
|
16
|
-
import { getDrizzleTableFromType } from '../server/drizzle/schema-converter.js';
|
|
17
|
-
describe('ORM Schema Generation (CTI)', () => {
|
|
18
|
-
test('should generate correct parent table with discriminator and unique constraint', () => {
|
|
19
|
-
let BaseUser = class BaseUser extends Entity {
|
|
20
|
-
type;
|
|
21
|
-
name;
|
|
22
|
-
};
|
|
23
|
-
__decorate([
|
|
24
|
-
StringProperty(),
|
|
25
|
-
Column({ name: 'type' }),
|
|
26
|
-
__metadata("design:type", String)
|
|
27
|
-
], BaseUser.prototype, "type", void 0);
|
|
28
|
-
__decorate([
|
|
29
|
-
StringProperty(),
|
|
30
|
-
Column({ name: 'name' }),
|
|
31
|
-
__metadata("design:type", String)
|
|
32
|
-
], BaseUser.prototype, "name", void 0);
|
|
33
|
-
BaseUser = __decorate([
|
|
34
|
-
Table('users', { schema: 'test' }),
|
|
35
|
-
Inheritance({ strategy: 'joined', discriminatorColumn: 'type' })
|
|
36
|
-
], BaseUser);
|
|
37
|
-
const table = getDrizzleTableFromType(BaseUser);
|
|
38
|
-
const config = getTableConfig(table);
|
|
39
|
-
// Check columns
|
|
40
|
-
const columnNames = config.columns.map(c => c.name);
|
|
41
|
-
expect(columnNames).toContain('id');
|
|
42
|
-
expect(columnNames).toContain('type');
|
|
43
|
-
expect(columnNames).toContain('name');
|
|
44
|
-
// Check unique constraint
|
|
45
|
-
const uniqueConstraints = config.uniqueConstraints;
|
|
46
|
-
const hasCompositeUnique = uniqueConstraints.some(uc => uc.columns.map(c => c.name).sort().join(',') === 'id,type');
|
|
47
|
-
expect(hasCompositeUnique).toBe(true);
|
|
48
|
-
});
|
|
49
|
-
test('should generate correct child table with only own columns and constraints', () => {
|
|
50
|
-
let BaseUser = class BaseUser extends Entity {
|
|
51
|
-
type;
|
|
52
|
-
name;
|
|
53
|
-
};
|
|
54
|
-
__decorate([
|
|
55
|
-
StringProperty(),
|
|
56
|
-
Column({ name: 'type' }),
|
|
57
|
-
__metadata("design:type", String)
|
|
58
|
-
], BaseUser.prototype, "type", void 0);
|
|
59
|
-
__decorate([
|
|
60
|
-
StringProperty(),
|
|
61
|
-
Column({ name: 'name' }),
|
|
62
|
-
__metadata("design:type", String)
|
|
63
|
-
], BaseUser.prototype, "name", void 0);
|
|
64
|
-
BaseUser = __decorate([
|
|
65
|
-
Table('users', { schema: 'test' }),
|
|
66
|
-
Inheritance({ strategy: 'joined', discriminatorColumn: 'type' })
|
|
67
|
-
], BaseUser);
|
|
68
|
-
let Admin = class Admin extends BaseUser {
|
|
69
|
-
role;
|
|
70
|
-
};
|
|
71
|
-
__decorate([
|
|
72
|
-
StringProperty(),
|
|
73
|
-
Column({ name: 'role' }),
|
|
74
|
-
__metadata("design:type", String)
|
|
75
|
-
], Admin.prototype, "role", void 0);
|
|
76
|
-
Admin = __decorate([
|
|
77
|
-
Table('admins', { schema: 'test' }),
|
|
78
|
-
ChildEntity('admin')
|
|
79
|
-
], Admin);
|
|
80
|
-
const table = getDrizzleTableFromType(Admin);
|
|
81
|
-
const config = getTableConfig(table);
|
|
82
|
-
// Check columns: should have id, type, role but NOT name
|
|
83
|
-
const columnNames = config.columns.map(c => c.name);
|
|
84
|
-
expect(columnNames).toContain('id');
|
|
85
|
-
expect(columnNames).toContain('type');
|
|
86
|
-
expect(columnNames).toContain('role');
|
|
87
|
-
expect(columnNames).not.toContain('name');
|
|
88
|
-
expect(columnNames).not.toContain('create_timestamp'); // from Entity
|
|
89
|
-
// Check check constraint
|
|
90
|
-
expect(config.checks.length).toBeGreaterThan(0);
|
|
91
|
-
const typeCheck = config.checks.find(c => c.name.includes('type_check') || c.name.includes('check'));
|
|
92
|
-
expect(typeCheck).toBeDefined();
|
|
93
|
-
// Check foreign key
|
|
94
|
-
expect(config.foreignKeys.length).toBeGreaterThan(0);
|
|
95
|
-
const compositeFk = config.foreignKeys.find(fk => fk.reference().columns.length === 2);
|
|
96
|
-
expect(compositeFk).toBeDefined();
|
|
97
|
-
expect(compositeFk?.reference().columns.map(c => c.name).sort()).toEqual(['id', 'type']);
|
|
98
|
-
});
|
|
99
|
-
test('should generate correct parent and child table for TenantEntity with joined inheritance', () => {
|
|
100
|
-
let BaseTenantUser = class BaseTenantUser extends TenantEntity {
|
|
101
|
-
type;
|
|
102
|
-
};
|
|
103
|
-
__decorate([
|
|
104
|
-
StringProperty(),
|
|
105
|
-
Column({ name: 'type' }),
|
|
106
|
-
__metadata("design:type", String)
|
|
107
|
-
], BaseTenantUser.prototype, "type", void 0);
|
|
108
|
-
BaseTenantUser = __decorate([
|
|
109
|
-
Table('tenant_users', { schema: 'test' }),
|
|
110
|
-
Inheritance({ strategy: 'joined', discriminatorColumn: 'type' })
|
|
111
|
-
], BaseTenantUser);
|
|
112
|
-
let TenantAdmin = class TenantAdmin extends BaseTenantUser {
|
|
113
|
-
role;
|
|
114
|
-
};
|
|
115
|
-
__decorate([
|
|
116
|
-
StringProperty(),
|
|
117
|
-
__metadata("design:type", String)
|
|
118
|
-
], TenantAdmin.prototype, "role", void 0);
|
|
119
|
-
TenantAdmin = __decorate([
|
|
120
|
-
Table('tenant_admins', { schema: 'test' }),
|
|
121
|
-
ChildEntity('admin')
|
|
122
|
-
], TenantAdmin);
|
|
123
|
-
// Test Parent Table
|
|
124
|
-
const parentTable = getDrizzleTableFromType(BaseTenantUser);
|
|
125
|
-
const parentConfig = getTableConfig(parentTable);
|
|
126
|
-
const parentUnique = parentConfig.uniqueConstraints.find((uc) => uc.columns.some((c) => c.name === 'type'));
|
|
127
|
-
expect(parentUnique).toBeDefined();
|
|
128
|
-
// Should be tenant_id, type, id (no duplicates)
|
|
129
|
-
expect(parentUnique.columns.map((c) => c.name)).toEqual(['tenant_id', 'type', 'id']);
|
|
130
|
-
// UNIQUE identifier should use snake_case column names
|
|
131
|
-
expect(parentUnique.name).toBe('tenant_users_tenant_id_type_id_unique');
|
|
132
|
-
// Test Child Table
|
|
133
|
-
const childTable = getDrizzleTableFromType(TenantAdmin);
|
|
134
|
-
const childConfig = getTableConfig(childTable);
|
|
135
|
-
// Child should have tenant_id and id from parent PK, plus type discriminator
|
|
136
|
-
const childColumnNames = childConfig.columns.map((c) => c.name);
|
|
137
|
-
expect(childColumnNames).toContain('tenant_id');
|
|
138
|
-
expect(childColumnNames).toContain('id');
|
|
139
|
-
expect(childColumnNames).toContain('type');
|
|
140
|
-
// Child Foreign Key should link correctly with all 3 columns
|
|
141
|
-
const childFk = childConfig.foreignKeys.find((fk) => fk.reference().columns.length === 3);
|
|
142
|
-
expect(childFk).toBeDefined();
|
|
143
|
-
expect(childFk.reference().columns.map((c) => c.name)).toEqual(['tenant_id', 'type', 'id']);
|
|
144
|
-
});
|
|
145
|
-
test('should generate BM25 index with correct config', () => {
|
|
146
|
-
let SearchableItem = class SearchableItem extends Entity {
|
|
147
|
-
title;
|
|
148
|
-
body;
|
|
149
|
-
};
|
|
150
|
-
__decorate([
|
|
151
|
-
StringProperty(),
|
|
152
|
-
__metadata("design:type", String)
|
|
153
|
-
], SearchableItem.prototype, "title", void 0);
|
|
154
|
-
__decorate([
|
|
155
|
-
StringProperty(),
|
|
156
|
-
__metadata("design:type", String)
|
|
157
|
-
], SearchableItem.prototype, "body", void 0);
|
|
158
|
-
SearchableItem = __decorate([
|
|
159
|
-
Table('searchable', { schema: 'test' }),
|
|
160
|
-
ParadeIndex({
|
|
161
|
-
columns: ['title', ['body', { tokenizer: 'simple' }]],
|
|
162
|
-
naming: 'abbreviated-table',
|
|
163
|
-
})
|
|
164
|
-
], SearchableItem);
|
|
165
|
-
const table = getDrizzleTableFromType(SearchableItem);
|
|
166
|
-
const config = getTableConfig(table);
|
|
167
|
-
// console.log('Indexes:', JSON.stringify(config.indexes, null, 2));
|
|
168
|
-
const paradeIdx = config.indexes.find(i => i.config.using === 'bm25' || i.config.method === 'bm25');
|
|
169
|
-
expect(paradeIdx).toBeDefined();
|
|
170
|
-
const extraConfig = paradeIdx.config.with;
|
|
171
|
-
expect(extraConfig).toBeDefined();
|
|
172
|
-
expect(extraConfig.key_field).toBe(`'id'`);
|
|
173
|
-
});
|
|
174
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'vitest';
|
|
2
|
-
import { sql, Column, Table as DrizzleTable } from 'drizzle-orm';
|
|
3
|
-
import { PgDialect, pgTable, text, integer } from 'drizzle-orm/pg-core';
|
|
4
|
-
import { exclusiveColumn, enumerationCaseWhen, interval, coalesce, numNulls, numNonNulls, greatest, least } from '../sqls/sqls.js';
|
|
5
|
-
import { defineEnum } from '../../enumeration/index.js';
|
|
6
|
-
describe('ORM SQL Helpers', () => {
|
|
7
|
-
const dialect = new PgDialect();
|
|
8
|
-
const TestEnum = defineEnum('TestEnum', { A: 'a', B: 'b' });
|
|
9
|
-
const testTable = pgTable('test', {
|
|
10
|
-
id: text('id').primaryKey(),
|
|
11
|
-
type: text('type'),
|
|
12
|
-
colA: text('col_a'),
|
|
13
|
-
colB: text('col_b'),
|
|
14
|
-
val: integer('val')
|
|
15
|
-
});
|
|
16
|
-
test('exclusiveColumn should generate correct CASE statement', () => {
|
|
17
|
-
const query = exclusiveColumn(TestEnum, testTable.type, {
|
|
18
|
-
[TestEnum.A]: testTable.colA,
|
|
19
|
-
[TestEnum.B]: testTable.colB,
|
|
20
|
-
});
|
|
21
|
-
const sqlStr = dialect.sqlToQuery(query).sql.toLowerCase();
|
|
22
|
-
expect(sqlStr).toContain('case "test"."type"');
|
|
23
|
-
expect(sqlStr).toContain("when 'a'");
|
|
24
|
-
expect(sqlStr).toContain("col_a\" is not null");
|
|
25
|
-
expect(sqlStr).toContain("col_b\" is null");
|
|
26
|
-
expect(sqlStr).toContain("when 'b'");
|
|
27
|
-
expect(sqlStr).toContain("col_b\" is not null");
|
|
28
|
-
expect(sqlStr).toContain("col_a\" is null");
|
|
29
|
-
expect(sqlStr).toContain('else false end');
|
|
30
|
-
});
|
|
31
|
-
test('enumerationCaseWhen should map enum values to conditions', () => {
|
|
32
|
-
const query = enumerationCaseWhen(TestEnum, testTable.type, {
|
|
33
|
-
[TestEnum.A]: true,
|
|
34
|
-
[TestEnum.B]: sql `"val" > 10`
|
|
35
|
-
});
|
|
36
|
-
const sqlStr = dialect.sqlToQuery(query).sql;
|
|
37
|
-
expect(sqlStr).toContain('WHEN \'a\'');
|
|
38
|
-
expect(sqlStr).toContain('THEN TRUE');
|
|
39
|
-
expect(sqlStr).toContain('WHEN \'b\'');
|
|
40
|
-
expect(sqlStr).toContain('"val" > 10');
|
|
41
|
-
});
|
|
42
|
-
test('interval should generate postgres interval syntax', () => {
|
|
43
|
-
const i = interval(5, 'days');
|
|
44
|
-
const sqlStr = dialect.sqlToQuery(i).sql;
|
|
45
|
-
expect(sqlStr).toContain("|| ' days')::interval");
|
|
46
|
-
});
|
|
47
|
-
test('coalesce should join multiple columns', () => {
|
|
48
|
-
const c = coalesce(testTable.colA, testTable.colB, sql `'default'`);
|
|
49
|
-
const sqlStr = dialect.sqlToQuery(c).sql;
|
|
50
|
-
expect(sqlStr).toContain('coalesce(');
|
|
51
|
-
expect(sqlStr).toContain('"test"."col_a"');
|
|
52
|
-
expect(sqlStr).toContain('"test"."col_b"');
|
|
53
|
-
expect(sqlStr).toContain("'default'");
|
|
54
|
-
});
|
|
55
|
-
test('numNulls and numNonNulls', () => {
|
|
56
|
-
const n = numNulls(testTable.colA, testTable.colB);
|
|
57
|
-
expect(dialect.sqlToQuery(n).sql).toContain('num_nulls(');
|
|
58
|
-
const nn = numNonNulls(testTable.colA, testTable.colB);
|
|
59
|
-
expect(dialect.sqlToQuery(nn).sql).toContain('num_nonnulls(');
|
|
60
|
-
});
|
|
61
|
-
test('greatest and least', () => {
|
|
62
|
-
const g = greatest(testTable.val, 100);
|
|
63
|
-
expect(dialect.sqlToQuery(g).sql).toContain('greatest(');
|
|
64
|
-
const l = least(testTable.val, sql `0`);
|
|
65
|
-
expect(dialect.sqlToQuery(l).sql).toContain('least(');
|
|
66
|
-
});
|
|
67
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,81 +0,0 @@
|
|
|
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 { Injector, Singleton, runInInjectionContext } from '../../injector/index.js';
|
|
11
|
-
import { StringProperty } from '../../schema/index.js';
|
|
12
|
-
import { dropTables, setupIntegrationTest } from '../../testing/index.js';
|
|
13
|
-
import { sql } from 'drizzle-orm';
|
|
14
|
-
import { beforeAll, describe, expect, test } from 'vitest';
|
|
15
|
-
import { Entity, Table } from '../index.js';
|
|
16
|
-
import { Database, Transactional, injectRepository } from '../server/index.js';
|
|
17
|
-
describe('Transaction Safety (Integration)', () => {
|
|
18
|
-
let injector;
|
|
19
|
-
let database;
|
|
20
|
-
const schema = 'test_orm_tx';
|
|
21
|
-
let TxEntity = class TxEntity extends Entity {
|
|
22
|
-
val;
|
|
23
|
-
};
|
|
24
|
-
__decorate([
|
|
25
|
-
StringProperty(),
|
|
26
|
-
__metadata("design:type", String)
|
|
27
|
-
], TxEntity.prototype, "val", void 0);
|
|
28
|
-
TxEntity = __decorate([
|
|
29
|
-
Table('tx_test', { schema })
|
|
30
|
-
], TxEntity);
|
|
31
|
-
let TxService = class TxService extends Transactional {
|
|
32
|
-
repo = injectRepository(TxEntity);
|
|
33
|
-
async successOp() {
|
|
34
|
-
await this.transaction(async (tx) => {
|
|
35
|
-
await this.repo.withTransaction(tx).insert({ val: 'success' });
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
async failOp() {
|
|
39
|
-
return await this.transaction(async (tx) => {
|
|
40
|
-
await this.repo.withTransaction(tx).insert({ val: 'should_rollback' });
|
|
41
|
-
throw new Error('Planned Failure');
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
TxService = __decorate([
|
|
46
|
-
Singleton()
|
|
47
|
-
], TxService);
|
|
48
|
-
beforeAll(async () => {
|
|
49
|
-
({ injector, database } = await setupIntegrationTest({ orm: { schema } }));
|
|
50
|
-
await dropTables(database, schema, ['tx_test']);
|
|
51
|
-
await database.execute(sql `
|
|
52
|
-
CREATE TABLE ${sql.identifier(schema)}.${sql.identifier('tx_test')} (
|
|
53
|
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
54
|
-
val TEXT NOT NULL,
|
|
55
|
-
revision INTEGER NOT NULL,
|
|
56
|
-
revision_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
57
|
-
create_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
58
|
-
delete_timestamp TIMESTAMP WITH TIME ZONE,
|
|
59
|
-
attributes JSONB NOT NULL DEFAULT '{}'
|
|
60
|
-
)
|
|
61
|
-
`);
|
|
62
|
-
});
|
|
63
|
-
test('should rollback changes on error', async () => {
|
|
64
|
-
await runInInjectionContext(injector, async () => {
|
|
65
|
-
const service = injector.resolve(TxService);
|
|
66
|
-
const startCount = await service.repo.count();
|
|
67
|
-
await expect(service.failOp()).rejects.toThrow('Planned Failure');
|
|
68
|
-
const endCount = await service.repo.count();
|
|
69
|
-
expect(endCount).toBe(startCount);
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
test('should commit changes on success', async () => {
|
|
73
|
-
await runInInjectionContext(injector, async () => {
|
|
74
|
-
const service = injector.resolve(TxService);
|
|
75
|
-
const startCount = await service.repo.count();
|
|
76
|
-
await service.successOp();
|
|
77
|
-
const endCount = await service.repo.count();
|
|
78
|
-
expect(endCount).toBe(startCount + 1);
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,215 +0,0 @@
|
|
|
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 { Injector, runInInjectionContext, Singleton } from '../../injector/index.js';
|
|
12
|
-
import { StringProperty } from '../../schema/index.js';
|
|
13
|
-
import { setupIntegrationTest } from '../../testing/index.js';
|
|
14
|
-
import { beforeAll, describe, expect, test } from 'vitest';
|
|
15
|
-
import { Table } from '../decorators.js';
|
|
16
|
-
import { Entity } from '../entity.js';
|
|
17
|
-
import { Database } from '../server/index.js';
|
|
18
|
-
import { getRepository } from '../server/repository.js';
|
|
19
|
-
import { Transactional } from '../server/transactional.js';
|
|
20
|
-
describe('ORM Transactional (Integration)', () => {
|
|
21
|
-
let injector;
|
|
22
|
-
let db;
|
|
23
|
-
const schema = 'test_orm_transactional';
|
|
24
|
-
let TransactionalItem = class TransactionalItem extends Entity {
|
|
25
|
-
name;
|
|
26
|
-
};
|
|
27
|
-
__decorate([
|
|
28
|
-
StringProperty(),
|
|
29
|
-
__metadata("design:type", String)
|
|
30
|
-
], TransactionalItem.prototype, "name", void 0);
|
|
31
|
-
TransactionalItem = __decorate([
|
|
32
|
-
Table('transactional_items', { schema })
|
|
33
|
-
], TransactionalItem);
|
|
34
|
-
let TransactionalService = class TransactionalService extends Transactional {
|
|
35
|
-
repository = getRepository(TransactionalItem);
|
|
36
|
-
async create(name) {
|
|
37
|
-
const repo = injector.resolve(this.repository).withSession(this.session);
|
|
38
|
-
const item = new TransactionalItem();
|
|
39
|
-
item.name = name;
|
|
40
|
-
return await repo.insert(item);
|
|
41
|
-
}
|
|
42
|
-
async count() {
|
|
43
|
-
const repo = injector.resolve(this.repository).withSession(this.session);
|
|
44
|
-
return await repo.count();
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
TransactionalService = __decorate([
|
|
48
|
-
Singleton()
|
|
49
|
-
], TransactionalService);
|
|
50
|
-
beforeAll(async () => {
|
|
51
|
-
const encryptionSecret = new Uint8Array(32).fill(1);
|
|
52
|
-
const context = await setupIntegrationTest({ orm: { schema, encryptionSecret } });
|
|
53
|
-
injector = context.injector;
|
|
54
|
-
db = context.database;
|
|
55
|
-
await db.execute(sql `CREATE SCHEMA IF NOT EXISTS ${sql.identifier(schema)}`);
|
|
56
|
-
await db.execute(sql `DROP TABLE IF EXISTS ${sql.identifier(schema)}.${sql.identifier('transactional_items')} CASCADE`);
|
|
57
|
-
await db.execute(sql `
|
|
58
|
-
CREATE TABLE ${sql.identifier(schema)}.${sql.identifier('transactional_items')} (
|
|
59
|
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
60
|
-
name TEXT NOT NULL,
|
|
61
|
-
revision INTEGER NOT NULL,
|
|
62
|
-
revision_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
63
|
-
create_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
64
|
-
delete_timestamp TIMESTAMP WITH TIME ZONE,
|
|
65
|
-
attributes JSONB NOT NULL DEFAULT '{}'
|
|
66
|
-
)
|
|
67
|
-
`);
|
|
68
|
-
injector.register(TransactionalService, { useClass: TransactionalService });
|
|
69
|
-
});
|
|
70
|
-
test('should handle nested transactions (savepoints by default)', async () => {
|
|
71
|
-
await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('transactional_items')} CASCADE`);
|
|
72
|
-
await runInInjectionContext(injector, async () => {
|
|
73
|
-
const service = injector.resolve(TransactionalService);
|
|
74
|
-
await service.transaction(async (tx1) => {
|
|
75
|
-
await service.withTransaction(tx1).create('Outer');
|
|
76
|
-
await service.withTransaction(tx1).transaction(async (tx2) => {
|
|
77
|
-
// Default behavior: create new transaction (savepoint)
|
|
78
|
-
expect(tx1).not.toBe(tx2);
|
|
79
|
-
await service.withTransaction(tx2).create('Inner');
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
const count = await service.count();
|
|
83
|
-
expect(count).toBe(2);
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
test('should handle nested transactions with rollback (savepoints by default)', async () => {
|
|
87
|
-
await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('transactional_items')} CASCADE`);
|
|
88
|
-
await runInInjectionContext(injector, async () => {
|
|
89
|
-
const service = injector.resolve(TransactionalService);
|
|
90
|
-
await service.transaction(async (tx1) => {
|
|
91
|
-
await service.withTransaction(tx1).create('Outer');
|
|
92
|
-
try {
|
|
93
|
-
await service.withTransaction(tx1).transaction(async (tx2) => {
|
|
94
|
-
await service.withTransaction(tx2).create('Inner');
|
|
95
|
-
throw new Error('Fail Inner');
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
catch (e) {
|
|
99
|
-
expect(e.message).toBe('Fail Inner');
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
// Should roll back only inner (savepoint), keeping Outer
|
|
103
|
-
const count = await service.count();
|
|
104
|
-
expect(count).toBe(1);
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
test('should handle independent transactions (savepoints) with useExisting: false', async () => {
|
|
108
|
-
await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('transactional_items')} CASCADE`);
|
|
109
|
-
await runInInjectionContext(injector, async () => {
|
|
110
|
-
const service = injector.resolve(TransactionalService);
|
|
111
|
-
await service.transaction(async (tx1) => {
|
|
112
|
-
await service.withTransaction(tx1).create('Outer');
|
|
113
|
-
await service.withTransaction(tx1).transaction(async (tx2) => {
|
|
114
|
-
expect(tx1).not.toBe(tx2); // Should be different wrapper (savepoint)
|
|
115
|
-
await service.withTransaction(tx2).create('Inner');
|
|
116
|
-
}, { useExisting: false });
|
|
117
|
-
});
|
|
118
|
-
const count = await service.count();
|
|
119
|
-
expect(count).toBe(2);
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
test('should rollback only inner transaction when useExisting: false', async () => {
|
|
123
|
-
await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('transactional_items')} CASCADE`);
|
|
124
|
-
await runInInjectionContext(injector, async () => {
|
|
125
|
-
const service = injector.resolve(TransactionalService);
|
|
126
|
-
await service.transaction(async (tx1) => {
|
|
127
|
-
await service.withTransaction(tx1).create('Outer');
|
|
128
|
-
try {
|
|
129
|
-
await service.withTransaction(tx1).transaction(async (tx2) => {
|
|
130
|
-
await service.withTransaction(tx2).create('Inner');
|
|
131
|
-
throw new Error('Fail Inner');
|
|
132
|
-
}, { useExisting: false });
|
|
133
|
-
}
|
|
134
|
-
catch {
|
|
135
|
-
// Swallow error to allow outer to continue
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
const count = await service.count();
|
|
139
|
-
// Outer should exist, Inner should be rolled back (savepoint behavior)
|
|
140
|
-
expect(count).toBe(1);
|
|
141
|
-
const repo = injector.resolve(service.repository);
|
|
142
|
-
const items = await repo.loadAll();
|
|
143
|
-
expect(items[0].name).toBe('Outer');
|
|
144
|
-
});
|
|
145
|
-
});
|
|
146
|
-
test('should reuse existing transaction when useExisting: true', async () => {
|
|
147
|
-
await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('transactional_items')} CASCADE`);
|
|
148
|
-
await runInInjectionContext(injector, async () => {
|
|
149
|
-
const service = injector.resolve(TransactionalService);
|
|
150
|
-
await service.transaction(async (tx1) => {
|
|
151
|
-
await service.withTransaction(tx1).transaction(async (tx2) => {
|
|
152
|
-
expect(tx1).toBe(tx2);
|
|
153
|
-
}, { useExisting: true });
|
|
154
|
-
});
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
test('should defer afterCommit of nested transaction until root commits', async () => {
|
|
158
|
-
await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('transactional_items')} CASCADE`);
|
|
159
|
-
await runInInjectionContext(injector, async () => {
|
|
160
|
-
const service = injector.resolve(TransactionalService);
|
|
161
|
-
let innerCommitted = false;
|
|
162
|
-
let outerCommitted = false;
|
|
163
|
-
await service.transaction(async (tx1) => {
|
|
164
|
-
tx1.afterCommit.register(() => { outerCommitted = true; });
|
|
165
|
-
await service.withTransaction(tx1).transaction(async (tx2) => {
|
|
166
|
-
tx2.afterCommit.register(() => { innerCommitted = true; });
|
|
167
|
-
await service.withTransaction(tx2).create('Inner');
|
|
168
|
-
});
|
|
169
|
-
// Inner transaction finished, but should not have triggered hooks yet
|
|
170
|
-
expect(innerCommitted).toBe(false);
|
|
171
|
-
});
|
|
172
|
-
expect(outerCommitted).toBe(true);
|
|
173
|
-
expect(innerCommitted).toBe(true);
|
|
174
|
-
});
|
|
175
|
-
});
|
|
176
|
-
test('should NOT trigger afterCommit if outer transaction rolls back', async () => {
|
|
177
|
-
await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('transactional_items')} CASCADE`);
|
|
178
|
-
await runInInjectionContext(injector, async () => {
|
|
179
|
-
const service = injector.resolve(TransactionalService);
|
|
180
|
-
let innerCommitted = false;
|
|
181
|
-
try {
|
|
182
|
-
await service.transaction(async (tx1) => {
|
|
183
|
-
await service.withTransaction(tx1).transaction(async (tx2) => {
|
|
184
|
-
tx2.afterCommit.register(() => { innerCommitted = true; });
|
|
185
|
-
await service.withTransaction(tx2).create('Inner');
|
|
186
|
-
});
|
|
187
|
-
// Inner committed successfully.
|
|
188
|
-
// Now rollback outer.
|
|
189
|
-
throw new Error('Rollback Outer');
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
catch {
|
|
193
|
-
// Ignore
|
|
194
|
-
}
|
|
195
|
-
// Hook should not have fired
|
|
196
|
-
expect(innerCommitted).toBe(false);
|
|
197
|
-
});
|
|
198
|
-
});
|
|
199
|
-
test('should support withManualCommit', async () => {
|
|
200
|
-
await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('transactional_items')} CASCADE`);
|
|
201
|
-
await runInInjectionContext(injector, async () => {
|
|
202
|
-
const service = injector.resolve(TransactionalService);
|
|
203
|
-
await service.transaction(async (tx) => {
|
|
204
|
-
tx.withManualCommit();
|
|
205
|
-
await service.create('Manual');
|
|
206
|
-
// If we don't commit, it would hang if we tried to exit?
|
|
207
|
-
// Or if we check DB outside, it's locked?
|
|
208
|
-
// We just verify it works when we DO commit.
|
|
209
|
-
await tx.commit();
|
|
210
|
-
});
|
|
211
|
-
const count = await service.count();
|
|
212
|
-
expect(count).toBe(1);
|
|
213
|
-
});
|
|
214
|
-
});
|
|
215
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/orm/tests/utils.test.js
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
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 { Entity } from '../entity.js';
|
|
12
|
-
import { Column, Inheritance, ChildEntity } from '../decorators.js';
|
|
13
|
-
import { getOwnProperties } from '../utils.js';
|
|
14
|
-
describe('ORM Utils', () => {
|
|
15
|
-
describe('getOwnProperties', () => {
|
|
16
|
-
test('should return only own properties and primary key for child entity', () => {
|
|
17
|
-
let Vehicle = class Vehicle extends Entity {
|
|
18
|
-
type;
|
|
19
|
-
model;
|
|
20
|
-
};
|
|
21
|
-
__decorate([
|
|
22
|
-
Column({}),
|
|
23
|
-
__metadata("design:type", String)
|
|
24
|
-
], Vehicle.prototype, "type", void 0);
|
|
25
|
-
__decorate([
|
|
26
|
-
Column({ name: 'model' }),
|
|
27
|
-
__metadata("design:type", String)
|
|
28
|
-
], Vehicle.prototype, "model", void 0);
|
|
29
|
-
Vehicle = __decorate([
|
|
30
|
-
Inheritance({ strategy: 'joined', discriminatorColumn: 'type' })
|
|
31
|
-
], Vehicle);
|
|
32
|
-
let Car = class Car extends Vehicle {
|
|
33
|
-
doors;
|
|
34
|
-
};
|
|
35
|
-
__decorate([
|
|
36
|
-
Column({ name: 'doors' }),
|
|
37
|
-
__metadata("design:type", Number)
|
|
38
|
-
], Car.prototype, "doors", void 0);
|
|
39
|
-
Car = __decorate([
|
|
40
|
-
ChildEntity('car')
|
|
41
|
-
], Car);
|
|
42
|
-
const ownProps = getOwnProperties(Car);
|
|
43
|
-
const propKeys = ownProps.map(p => p.key);
|
|
44
|
-
expect(propKeys).toContain('id'); // Inherited PK is required
|
|
45
|
-
expect(propKeys).toContain('doors'); // Own property
|
|
46
|
-
expect(propKeys).not.toContain('model'); // Inherited property should be excluded
|
|
47
|
-
});
|
|
48
|
-
test('should return all properties for base entity', () => {
|
|
49
|
-
let Vehicle = class Vehicle extends Entity {
|
|
50
|
-
type;
|
|
51
|
-
model;
|
|
52
|
-
};
|
|
53
|
-
__decorate([
|
|
54
|
-
Column({}),
|
|
55
|
-
__metadata("design:type", String)
|
|
56
|
-
], Vehicle.prototype, "type", void 0);
|
|
57
|
-
__decorate([
|
|
58
|
-
Column({ name: 'model' }),
|
|
59
|
-
__metadata("design:type", String)
|
|
60
|
-
], Vehicle.prototype, "model", void 0);
|
|
61
|
-
Vehicle = __decorate([
|
|
62
|
-
Inheritance({ strategy: 'joined', discriminatorColumn: 'type' })
|
|
63
|
-
], Vehicle);
|
|
64
|
-
const ownProps = getOwnProperties(Vehicle);
|
|
65
|
-
const propKeys = ownProps.map(p => p.key);
|
|
66
|
-
expect(propKeys).toContain('id');
|
|
67
|
-
expect(propKeys).toContain('model');
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|