@cosmicdrift/kumiko-framework 0.367.0 → 0.369.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -7
- package/README.md +1 -1
- package/agents/examples/access-control.md +2 -2
- package/agents/examples/anonymous-access-multitenant.md +2 -2
- package/agents/examples/anonymous-access.md +3 -3
- package/agents/examples/apex-landing.md +1 -1
- package/agents/examples/apex-surface-auth.md +6 -7
- package/agents/examples/api-worker-split.md +7 -8
- package/agents/examples/auth-claims.md +2 -1
- package/agents/examples/auth-foundation-providers.md +3 -3
- package/agents/examples/auth-mfa.md +3 -4
- package/agents/examples/basic-entity.md +3 -4
- package/agents/examples/chat-channels.md +4 -4
- package/agents/examples/compliance-profiles-demo.md +2 -3
- package/agents/examples/cross-feature-events.md +4 -4
- package/agents/examples/crypto-shredding-hr.md +14 -9
- package/agents/examples/currencies-global.md +3 -4
- package/agents/examples/currencies-per-tenant.md +3 -4
- package/agents/examples/custom-fields-basic.md +2 -3
- package/agents/examples/custom-handlers.md +3 -5
- package/agents/examples/dashboard-stats.md +2 -3
- package/agents/examples/delivery-notifications.md +5 -6
- package/agents/examples/e2e-generator.md +1 -1
- package/agents/examples/embedded-entity-form.md +2 -3
- package/agents/examples/embedded.md +2 -3
- package/agents/examples/encrypted-tenant-config.md +5 -6
- package/agents/examples/error-contract.md +3 -4
- package/agents/examples/event-sourcing.md +19 -23
- package/agents/examples/feature-toggles.md +4 -4
- package/agents/examples/field-access.md +3 -4
- package/agents/examples/files-post-processing.md +12 -13
- package/agents/examples/golden-path.md +208 -0
- package/agents/examples/idempotency.md +2 -2
- package/agents/examples/inbound-mail-triage.md +7 -7
- package/agents/examples/lane-routing.md +3 -3
- package/agents/examples/ledger-banking.md +2 -3
- package/agents/examples/ledger-invoicing.md +2 -3
- package/agents/examples/legal-pages.md +1 -1
- package/agents/examples/lifecycle-hooks.md +3 -3
- package/agents/examples/managed-config.md +3 -4
- package/agents/examples/managed-pages.md +2 -2
- package/agents/examples/notes-history-basic.md +4 -5
- package/agents/examples/ownership.md +3 -5
- package/agents/examples/pdf-audit-export.md +2 -3
- package/agents/examples/pipeline-basics.md +2 -2
- package/agents/examples/public-share-token.md +3 -3
- package/agents/examples/rate-limiting.md +2 -1
- package/agents/examples/realtime-sse.md +2 -3
- package/agents/examples/record-detail-layout.md +1 -1
- package/agents/examples/reference-data.md +3 -3
- package/agents/examples/relations.md +2 -2
- package/agents/examples/screens-nav.md +1 -1
- package/agents/examples/search.md +2 -2
- package/agents/examples/secrets-demo.md +8 -8
- package/agents/examples/security-baseline.md +2 -2
- package/agents/examples/session-revocation.md +7 -8
- package/agents/examples/state-machine.md +181 -165
- package/agents/examples/tags-basic.md +2 -3
- package/agents/examples/tenant-isolation.md +2 -3
- package/agents/examples/tenant-settings.md +2 -2
- package/agents/examples/tier-admin.md +3 -4
- package/agents/examples/timezones.md +3 -3
- package/agents/examples/user-data-rights.md +12 -8
- package/agents/examples/user-profile.md +3 -3
- package/agents/examples/webhook-step.md +2 -3
- package/agents/examples/wizard-form.md +4 -5
- package/agents/examples/workflow-engine.md +7 -3
- package/agents/examples/writeform-section.md +1 -1
- package/agents/examples.md +1 -0
- package/agents/features.md +4 -4
- package/dist/consumer-cli.js +2 -3
- package/dist/crypto/index.d.ts +1 -1
- package/dist/crypto/index.js +1 -1
- package/dist/crypto/owner-transition-rekey.js +2 -0
- package/dist/crypto/pg-kms-adapter.js +1 -1
- package/dist/crypto/subject-resolver.d.ts +2 -0
- package/dist/crypto/subject-resolver.js +30 -15
- package/dist/db/bun-db-deprecated.d.ts +10 -0
- package/dist/{bun-db/index.js → db/bun-db-deprecated.js} +4 -3
- package/dist/db/config-seed.js +1 -1
- package/dist/db/connection.d.ts +23 -5
- package/dist/db/connection.js +10 -5
- package/dist/db/dialect.js +1 -1
- package/dist/db/entity-field-encryption.d.ts +5 -0
- package/dist/db/entity-field-encryption.js +29 -0
- package/dist/db/entity-table-meta.js +6 -5
- package/dist/db/event-store-executor-read.js +26 -5
- package/dist/db/index.d.ts +4 -4
- package/dist/db/index.js +1 -1
- package/dist/db/migrate-runner.js +1 -1
- package/dist/db/queries/backfill-pii.js +16 -9
- package/dist/db/queries/ddl.js +1 -1
- package/dist/db/queries/event-store.d.ts +2 -0
- package/dist/db/queries/event-store.js +26 -0
- package/dist/db/queries/test-stack.js +1 -1
- package/dist/db/query.d.ts +105 -1
- package/dist/db/query.js +1450 -3
- package/dist/{stack/table-helpers.d.ts → db/table-push.d.ts} +5 -15
- package/dist/{stack/table-helpers.js → db/table-push.js} +6 -46
- package/dist/db/tenant-db.d.ts +11 -0
- package/dist/db/tenant-db.js +51 -12
- package/dist/derivatives/derivatives-context.d.ts +1 -1
- package/dist/derivatives/derivatives-context.js +1 -1
- package/dist/engine/boot-validator/gdpr-storage.js +3 -3
- package/dist/engine/boot-validator/pii-retention.js +3 -3
- package/dist/engine/boot-validator/record-owned.js +3 -3
- package/dist/engine/boot-validator/screens.js +37 -1
- package/dist/engine/bridge-stub.d.ts +4 -0
- package/dist/engine/bridge-stub.js +62 -0
- package/dist/engine/build-config-feature-schema.js +197 -65
- package/dist/engine/event-helpers.d.ts +2 -1
- package/dist/engine/event-helpers.js +1 -0
- package/dist/engine/extension-selector-plugins.d.ts +3 -0
- package/dist/engine/extension-selector-plugins.js +14 -0
- package/dist/engine/feature-config-events-jobs.d.ts +2 -0
- package/dist/engine/feature-config-events-jobs.js +3 -2
- package/dist/engine/index.d.ts +1 -0
- package/dist/engine/index.js +1 -0
- package/dist/es-ops/operations-schema.js +1 -1
- package/dist/event-store/admin-api.js +1 -1
- package/dist/event-store/archive.js +1 -1
- package/dist/event-store/errors.d.ts +2 -1
- package/dist/event-store/errors.js +6 -2
- package/dist/event-store/event-store.js +17 -9
- package/dist/event-store/events-schema.js +1 -1
- package/dist/event-store/rebuild-dead-letter.js +3 -3
- package/dist/event-store/snapshot.js +1 -1
- package/dist/event-store/upcaster-dead-letter.js +3 -3
- package/dist/files/create-file-ref-from-bytes.js +1 -1
- package/dist/files/file-routes.js +1 -1
- package/dist/i18n/settings-hub-keys.js +1 -2
- package/dist/internal/stack-support.d.ts +12 -0
- package/dist/internal/stack-support.js +12 -0
- package/dist/internal/testing.d.ts +4 -0
- package/dist/internal/testing.js +5 -0
- package/dist/jobs/job-runner.js +23 -11
- package/dist/migrations/pending-rebuilds.js +1 -1
- package/dist/migrations/pii-event-backfill.js +2 -2
- package/dist/pipeline/dispatch-shared.js +43 -23
- package/dist/pipeline/dispatch-write.js +6 -2
- package/dist/pipeline/dispatcher-utils.js +6 -2
- package/dist/pipeline/event-consumer-state.js +1 -1
- package/dist/pipeline/projection-rebuild.d.ts +1 -0
- package/dist/pipeline/projection-rebuild.js +1 -1
- package/dist/pipeline/projection-state.js +1 -1
- package/dist/pipeline/system-hooks.js +1 -1
- package/dist/schema-cli.js +3 -3
- package/dist/search/purge-subject.js +20 -10
- package/dist/seeding/index.d.ts +1 -0
- package/dist/seeding/index.js +1 -0
- package/dist/stack/index.d.ts +10 -9
- package/dist/stack/index.js +11 -19
- package/dist/testing/e2e-generator.d.ts +5 -49
- package/dist/testing/e2e-generator.js +5 -382
- package/dist/testing/handler-context.d.ts +5 -4
- package/dist/testing/handler-context.js +5 -69
- package/dist/testing/index.d.ts +10 -26
- package/dist/testing/index.js +10 -34
- package/dist/testing/real-providers.d.ts +5 -3
- package/dist/testing/real-providers.js +5 -21
- package/dist/upgrade-cli.js +6 -4
- package/package.json +37 -9
- package/src/changes.json +64 -0
- package/src/scripts/codemod/README.md +43 -0
- package/src/scripts/codemod/codemod-support.ts +276 -0
- package/src/scripts/codemod/db-factory.ts +810 -0
- package/src/scripts/codemod/feature-factory.ts +429 -0
- package/src/scripts/codemod/s3-imports.ts +274 -0
- package/src/scripts/codemod/tenant-db-options.ts +454 -0
- package/src/scripts/codemod/testing-move-targets.ts +161 -0
- package/src/scripts/codemod/testing-move.ts +520 -0
- package/dist/bun-db/connection.d.ts +0 -17
- package/dist/bun-db/connection.js +0 -40
- package/dist/bun-db/index.d.ts +0 -4
- package/dist/bun-db/query.d.ts +0 -106
- package/dist/bun-db/query.js +0 -1457
- package/dist/db/api.d.ts +0 -19
- package/dist/db/api.js +0 -23
- package/dist/db/bun-provider.d.ts +0 -2
- package/dist/db/bun-provider.js +0 -28
- package/dist/db/postgres-provider.d.ts +0 -2
- package/dist/db/postgres-provider.js +0 -21
- package/dist/db/query-api.d.ts +0 -2
- package/dist/db/query-api.js +0 -6
- package/dist/stack/db.d.ts +0 -22
- package/dist/stack/db.js +0 -67
- package/dist/stack/drain-event-consumers.d.ts +0 -4
- package/dist/stack/drain-event-consumers.js +0 -51
- package/dist/stack/drain-jobs.d.ts +0 -22
- package/dist/stack/drain-jobs.js +0 -141
- package/dist/stack/event-collector.d.ts +0 -9
- package/dist/stack/event-collector.js +0 -12
- package/dist/stack/push-entity-projection-tables.d.ts +0 -24
- package/dist/stack/push-entity-projection-tables.js +0 -74
- package/dist/stack/redis.d.ts +0 -17
- package/dist/stack/redis.js +0 -52
- package/dist/stack/request-helper.d.ts +0 -35
- package/dist/stack/request-helper.js +0 -144
- package/dist/stack/test-stack.d.ts +0 -192
- package/dist/stack/test-stack.js +0 -429
- package/dist/testing/access-assertions.d.ts +0 -2
- package/dist/testing/access-assertions.js +0 -13
- package/dist/testing/assertions.d.ts +0 -10
- package/dist/testing/assertions.js +0 -22
- package/dist/testing/boot-validator-fixture.d.ts +0 -3
- package/dist/testing/boot-validator-fixture.js +0 -101
- package/dist/testing/closed-connection-error.d.ts +0 -7
- package/dist/testing/closed-connection-error.js +0 -46
- package/dist/testing/db-cleanup.d.ts +0 -9
- package/dist/testing/db-cleanup.js +0 -31
- package/dist/testing/expect-error.d.ts +0 -2
- package/dist/testing/expect-error.js +0 -22
- package/dist/testing/file-provider-contract.d.ts +0 -2
- package/dist/testing/file-provider-contract.js +0 -102
- package/dist/testing/http-cookies.d.ts +0 -7
- package/dist/testing/http-cookies.js +0 -47
- package/dist/testing/late-bound.d.ts +0 -9
- package/dist/testing/late-bound.js +0 -31
- package/dist/testing/manual-clock.d.ts +0 -14
- package/dist/testing/manual-clock.js +0 -12
- package/dist/testing/multipart-helper.d.ts +0 -22
- package/dist/testing/multipart-helper.js +0 -77
- package/dist/testing/mutable-master-key-provider.d.ts +0 -7
- package/dist/testing/mutable-master-key-provider.js +0 -35
- package/dist/testing/observability-recorder.d.ts +0 -9
- package/dist/testing/observability-recorder.js +0 -29
- package/dist/testing/seed.d.ts +0 -9
- package/dist/testing/seed.js +0 -21
- package/dist/testing/shared-entities.d.ts +0 -286
- package/dist/testing/shared-entities.js +0 -56
- package/dist/testing/utils.d.ts +0 -1
- package/dist/testing/utils.js +0 -1
- package/dist/testing/wait-for.d.ts +0 -20
- package/dist/testing/wait-for.js +0 -47
- package/dist/testing/without-ambient-temporal.d.ts +0 -5
- package/dist/testing/without-ambient-temporal.js +0 -17
- package/dist/testing/zip-fixture.d.ts +0 -1
- package/dist/testing/zip-fixture.js +0 -33
- /package/dist/{stack/test-users.d.ts → seeding/seed-users.d.ts} +0 -0
- /package/dist/{stack/test-users.js → seeding/seed-users.js} +0 -0
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
// 2. projection ({@link PiiBackfillOptions.resolveOwnerFromProjection}) —
|
|
36
36
|
// pre-owner-field-addition events don't carry it; read it from the
|
|
37
37
|
// entity's current projection row instead.
|
|
38
|
-
// 2b. whenAbsent — the payload again, now falling back to the tenant key
|
|
39
|
-
// fields that declare it.
|
|
38
|
+
// 2b. whenAbsent — the payload again, now falling back to the tenant key (or
|
|
39
|
+
// the row's own record key for whenAbsent: "self") for fields that declare it.
|
|
40
40
|
// 3. erase ({@link PiiBackfillOptions.eraseUnresolvableSubjects}) — still
|
|
41
41
|
// unresolvable (hard-deleted aggregate, no projection) → PII_ERASED_SENTINEL.
|
|
42
42
|
// Stages 2 and 3 are opt-in and off by default; without them an
|
|
@@ -48,13 +48,16 @@
|
|
|
48
48
|
// owner change made before owner transitions re-keyed the value). An owner
|
|
49
49
|
// cleared again (owner → none) is not recoverable from the projection: such
|
|
50
50
|
// values stay tenant-keyed, unlike the live path that keeps the last owner.
|
|
51
|
+
// For whenAbsent: "self" fields the same stage moves tenant-keyed ciphertext
|
|
52
|
+
// of a still-ownerless row under its record key (written before the field
|
|
53
|
+
// declared "self"); a later owner assignment keeps the created event
|
|
54
|
+
// record-keyed, like the tenant-keyed case.
|
|
51
55
|
//
|
|
52
56
|
// Snapshots of touched aggregates are dropped per batch (they may cache
|
|
53
57
|
// plaintext); the next snapshotting load recreates them. AFTER a run, rebuild the
|
|
54
58
|
// affected projections — applyEntityEvent materializes ciphertext AND the
|
|
55
59
|
// blind-index columns, which keeps equality lookups (login by email) alive.
|
|
56
60
|
import { isOneOf } from "@cosmicdrift/kumiko-types/type-guards";
|
|
57
|
-
import { asRawClient } from "../../bun-db/index.js";
|
|
58
61
|
import { quoteIdent } from "../../crypto/ciphertext-pattern.js";
|
|
59
62
|
import { configuredEventPiiCatalog } from "../../crypto/event-pii.js";
|
|
60
63
|
import { isLocalKeyKmsAdapter, KeyErasedError, KeyNotFoundError, } from "../../crypto/kms-adapter.js";
|
|
@@ -62,6 +65,7 @@ import { isPlainUserOwnedField } from "../../crypto/owner-transition-rekey.js";
|
|
|
62
65
|
import { configuredPiiSubjectKms, decryptPiiValueForSubject, encryptPiiValueForSubject, isPiiCiphertext, PII_ERASED_SENTINEL, piiCiphertextSubject, } from "../../crypto/pii-field-encryption.js";
|
|
63
66
|
import { collectPiiEncryptedFields, nonEmptyString, resolveEventSubject, resolveSubjectForField, SubjectResolutionError, } from "../../crypto/subject-resolver.js";
|
|
64
67
|
import { resolveTableName } from "../entity-table-meta.js";
|
|
68
|
+
import { asRawClient } from "../query.js";
|
|
65
69
|
import { tableExists } from "../schema-inspection.js";
|
|
66
70
|
import { toSnakeCase } from "../table-builder.js";
|
|
67
71
|
import { toPostgresArrayLiteral } from "./postgres-array-literal.js";
|
|
@@ -479,7 +483,7 @@ async function rekeyTenantKeyedValue(deps, target) {
|
|
|
479
483
|
return { kind: "unchanged" };
|
|
480
484
|
const keyedUnder = ciphertextSubjectOrNull(ciphertext);
|
|
481
485
|
const userSubject = keyedUnder?.kind === "tenant" && keyedUnder.tenantId === target.tenantId
|
|
482
|
-
?
|
|
486
|
+
? rekeyTargetOfTenantKeyedValue(target)
|
|
483
487
|
: keyedUnder?.kind === "user"
|
|
484
488
|
? currentProjectionOwnerIfOther(target, keyedUnder.userId)
|
|
485
489
|
: null;
|
|
@@ -505,12 +509,15 @@ async function rekeyTenantKeyedValue(deps, target) {
|
|
|
505
509
|
throw e;
|
|
506
510
|
}
|
|
507
511
|
}
|
|
508
|
-
// Strict chain (payload, then projection)
|
|
509
|
-
|
|
512
|
+
// Strict chain (payload, then projection) names the owner; an ownerless row of a
|
|
513
|
+
// whenAbsent: "self" field falls through to its record key. A whenAbsent: "tenant"
|
|
514
|
+
// result is the key the value already sits under — nothing to move.
|
|
515
|
+
function rekeyTargetOfTenantKeyedValue(target) {
|
|
510
516
|
const resolution = resolveOwnerSubject(target.entity, target.field, target.subjectSource, target.ownerFallback, target.projectionOwnerRow, target.tenantId, target.aggregateType);
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
517
|
+
if (resolution.kind !== "resolved")
|
|
518
|
+
return null;
|
|
519
|
+
const { subject } = resolution;
|
|
520
|
+
return subject.kind === "user" || subject.kind === "record" ? subject : null;
|
|
514
521
|
}
|
|
515
522
|
// A value keyed under a previous owner moves to the owner the row has now. The
|
|
516
523
|
// projection of the event's own tenant is authoritative here: the payload of
|
package/dist/db/queries/ddl.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { asRawClient } from "../query.js";
|
|
2
2
|
import { quoteTableIdent } from "./table-ops.js";
|
|
3
|
-
// Generic DDL helpers used on the prod-boot path (
|
|
3
|
+
// Generic DDL helpers used on the prod-boot path (db/table-push.ts's
|
|
4
4
|
// unsafePushTables, event-consumer-state.ts's multi-instance backfill) —
|
|
5
5
|
// split out of queries/test-stack.ts so a prod-boot import doesn't point at
|
|
6
6
|
// a module named for test-only concerns (truncate/create/drop-database).
|
|
@@ -24,6 +24,8 @@ export type SubsequentEventInsertRow = {
|
|
|
24
24
|
readonly id: string | bigint;
|
|
25
25
|
readonly created_at: Date | string;
|
|
26
26
|
};
|
|
27
|
+
export type FirstEventInsertParams = Omit<SubsequentEventInsertParams, "expectedVersion">;
|
|
28
|
+
export declare function insertFirstEventRow(db: AnyDb, params: FirstEventInsertParams): Promise<SubsequentEventInsertRow | undefined>;
|
|
27
29
|
/** INSERT … SELECT … WHERE EXISTS predecessor — stays raw (typed builder can't express this). */
|
|
28
30
|
export declare function insertSubsequentEventRow(db: AnyDb, params: SubsequentEventInsertParams): Promise<SubsequentEventInsertRow | undefined>;
|
|
29
31
|
export declare function selectStreamMaxVersion(db: AnyDb, aggregateId: string, tenantId: string): Promise<number>;
|
|
@@ -135,6 +135,31 @@ function duplicateIdempotencyKeyErrorOr(e) {
|
|
|
135
135
|
}
|
|
136
136
|
return e;
|
|
137
137
|
}
|
|
138
|
+
// ON CONFLICT on the version index only: a lost race returns no row instead of
|
|
139
|
+
// a 23505, which would abort the caller's transaction (25P02) and make the
|
|
140
|
+
// current stream version unreadable. The idempotency index still raises 23505.
|
|
141
|
+
export async function insertFirstEventRow(db, params) {
|
|
142
|
+
const rows = await asRawClient(db).unsafe(`INSERT INTO "kumiko_events" (
|
|
143
|
+
aggregate_id, aggregate_type, tenant_id, version,
|
|
144
|
+
type, event_version, payload, metadata, created_by, created_at
|
|
145
|
+
)
|
|
146
|
+
VALUES ($1::uuid, $2, $3::uuid, $4, $5, $6, $7::jsonb, $8::jsonb, $9,
|
|
147
|
+
COALESCE($10::timestamptz, now()))
|
|
148
|
+
ON CONFLICT (tenant_id, aggregate_id, version) DO NOTHING
|
|
149
|
+
RETURNING id, created_at`, [
|
|
150
|
+
params.aggregateId,
|
|
151
|
+
params.aggregateType,
|
|
152
|
+
params.tenantId,
|
|
153
|
+
params.newVersion,
|
|
154
|
+
params.type,
|
|
155
|
+
params.eventVersion,
|
|
156
|
+
params.payload,
|
|
157
|
+
params.metadata,
|
|
158
|
+
params.createdBy,
|
|
159
|
+
params.createdAt ?? null,
|
|
160
|
+
]);
|
|
161
|
+
return rows[0];
|
|
162
|
+
}
|
|
138
163
|
/** INSERT … SELECT … WHERE EXISTS predecessor — stays raw (typed builder can't express this). */
|
|
139
164
|
export async function insertSubsequentEventRow(db, params) {
|
|
140
165
|
const rows = await asRawClient(db).unsafe(`INSERT INTO "kumiko_events" (
|
|
@@ -150,6 +175,7 @@ export async function insertSubsequentEventRow(db, params) {
|
|
|
150
175
|
AND version = $10
|
|
151
176
|
AND tenant_id = $3::uuid
|
|
152
177
|
)
|
|
178
|
+
ON CONFLICT (tenant_id, aggregate_id, version) DO NOTHING
|
|
153
179
|
RETURNING id, created_at`, [
|
|
154
180
|
params.aggregateId,
|
|
155
181
|
params.aggregateType,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { asRawClient } from "../query.js";
|
|
2
2
|
import { quoteTableIdent } from "./table-ops.js";
|
|
3
3
|
// Re-exported for back-compat — the generic DDL helpers moved to ./ddl so
|
|
4
|
-
// the prod-boot path (
|
|
4
|
+
// the prod-boot path (db/table-push.ts, pipeline/event-consumer-state.ts)
|
|
5
5
|
// doesn't import from a module named for test-only concerns.
|
|
6
6
|
export { alterTableAddColumn, createIndexIfNotExists, executeDdlStatement } from "./ddl.js";
|
|
7
7
|
export async function truncateTablesRestartIdentity(db, tableNames) {
|
package/dist/db/query.d.ts
CHANGED
|
@@ -1 +1,105 @@
|
|
|
1
|
-
|
|
1
|
+
import type { AggregateRow, AggregateSpec } from "@cosmicdrift/kumiko-types/aggregate-types";
|
|
2
|
+
import type { DbRunner, DbTx } from "@cosmicdrift/kumiko-types/db-connection";
|
|
3
|
+
import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
4
|
+
import type { SelectOptions, WhereObject } from "@cosmicdrift/kumiko-types/where-clause-types";
|
|
5
|
+
import type { EntityTableMeta } from "./entity-table-meta.js";
|
|
6
|
+
import { type NotExecutorOnly } from "./table-builder.js";
|
|
7
|
+
import { asEntityTableMeta, requireEntityTableMeta } from "./table-introspection.js";
|
|
8
|
+
export { asEntityTableMeta, requireEntityTableMeta };
|
|
9
|
+
export type ReservedClient = {
|
|
10
|
+
unsafe: RawClient["unsafe"];
|
|
11
|
+
release: () => unknown;
|
|
12
|
+
};
|
|
13
|
+
export type RawClient = {
|
|
14
|
+
unsafe: <TRow = unknown>(sql: string, params?: readonly unknown[]) => Promise<readonly TRow[]>;
|
|
15
|
+
begin?: <T>(fn: (tx: DbTx) => Promise<T>) => Promise<T>;
|
|
16
|
+
savepoint?: <T>(fn: (sp: unknown) => Promise<T>) => Promise<T>;
|
|
17
|
+
release?: unknown;
|
|
18
|
+
reserve?: () => Promise<ReservedClient>;
|
|
19
|
+
};
|
|
20
|
+
export type RawClientWithBegin = RawClient & {
|
|
21
|
+
begin: NonNullable<RawClient["begin"]>;
|
|
22
|
+
};
|
|
23
|
+
export declare function hasBegin(client: RawClient): client is RawClientWithBegin;
|
|
24
|
+
export declare function asRawClient(db: unknown): RawClient;
|
|
25
|
+
export declare function runnerCanBeginTransaction(db: unknown): boolean;
|
|
26
|
+
export declare function runInSavepoint<T>(tx: unknown, fn: (sp: unknown) => Promise<T>): Promise<T>;
|
|
27
|
+
export declare function runInSavepointIfSupported<T>(db: unknown, fn: (sp: DbRunner) => Promise<T>): Promise<T>;
|
|
28
|
+
export type AnyDb = DbRunner | unknown;
|
|
29
|
+
export type { JsonTextMatch, OrderByClause, SelectOptions, WhereObject, WhereOperator, WhereValue, } from "@cosmicdrift/kumiko-types/where-clause-types";
|
|
30
|
+
type TableLike = EntityTableMeta | any;
|
|
31
|
+
type WritableTable = EntityTableMeta & NotExecutorOnly;
|
|
32
|
+
export type TableInfo = {
|
|
33
|
+
readonly name: string;
|
|
34
|
+
readonly columnOf: (field: string) => string;
|
|
35
|
+
readonly pgTypeOf: (column: string) => string | undefined;
|
|
36
|
+
readonly bigintJsModeOf: (column: string) => "number" | "bigint" | undefined;
|
|
37
|
+
readonly fieldOf: (column: string) => string;
|
|
38
|
+
readonly hasColumn: (fieldOrColumn: string) => boolean;
|
|
39
|
+
};
|
|
40
|
+
export declare function extractTableInfo(table: TableLike): TableInfo;
|
|
41
|
+
export declare function coerceRow<TOut = Record<string, unknown>>(row: Record<string, unknown>, info: TableInfo): TOut;
|
|
42
|
+
export declare function instantToTimestamptzParam(instant: Temporal.Instant): string;
|
|
43
|
+
export declare function isClosedConnectionError(err: unknown): boolean;
|
|
44
|
+
export declare function describeClosedConnectionFailure(raw: unknown, err: unknown, attempts: number): Record<string, unknown> | undefined;
|
|
45
|
+
export declare function unsafeReadRetrying<TRow>(db: AnyDb, sqlText: string, params: readonly unknown[]): Promise<readonly TRow[]>;
|
|
46
|
+
export declare function selectMany<TRow = any>(db: AnyDb, table: TableLike, where?: WhereObject, options?: SelectOptions): Promise<readonly TRow[]>;
|
|
47
|
+
export declare function fetchOne<TRow = any>(db: AnyDb, table: TableLike, where: WhereObject): Promise<TRow | undefined>;
|
|
48
|
+
export type JoinColumnPair = {
|
|
49
|
+
readonly left: string;
|
|
50
|
+
readonly right: string;
|
|
51
|
+
};
|
|
52
|
+
export type InnerJoinSpec = {
|
|
53
|
+
readonly left: TableLike;
|
|
54
|
+
readonly right: TableLike;
|
|
55
|
+
readonly on: readonly [JoinColumnPair, ...JoinColumnPair[]];
|
|
56
|
+
readonly leftWhere?: WhereObject;
|
|
57
|
+
readonly rightWhere?: WhereObject;
|
|
58
|
+
/** Fields to return per side; default: all columns of `left`, none of `right`. */
|
|
59
|
+
readonly leftFields?: readonly string[];
|
|
60
|
+
readonly rightFields?: readonly string[];
|
|
61
|
+
readonly limit?: number;
|
|
62
|
+
};
|
|
63
|
+
export type InnerJoinRow<TLeft, TRight> = {
|
|
64
|
+
readonly left: TLeft;
|
|
65
|
+
readonly right: TRight;
|
|
66
|
+
};
|
|
67
|
+
export declare function selectInnerJoin<TLeft = Record<string, unknown>, TRight = Record<string, unknown>>(db: AnyDb, spec: InnerJoinSpec): Promise<readonly InnerJoinRow<TLeft, TRight>[]>;
|
|
68
|
+
export declare function insertMany<TRow = any>(db: AnyDb, table: WritableTable, rows: ReadonlyArray<Record<string, unknown>>): Promise<readonly TRow[]>;
|
|
69
|
+
export declare function insertOne<TRow = any>(db: AnyDb, table: WritableTable, values: Record<string, unknown>): Promise<TRow | undefined>;
|
|
70
|
+
export declare function updateMany<TRow = any>(db: AnyDb, table: WritableTable, set: Record<string, unknown>, where: WhereObject): Promise<readonly TRow[]>;
|
|
71
|
+
export declare function deleteMany(db: AnyDb, table: WritableTable, where: WhereObject): Promise<void>;
|
|
72
|
+
export declare function resolveConflictColumns(table: TableLike, info: TableInfo, conflictKeys: readonly string[] | undefined): readonly string[];
|
|
73
|
+
export type UpsertOnConflictOptions = {
|
|
74
|
+
readonly conflictKeys: readonly string[];
|
|
75
|
+
/** Columns to set on conflict. Default: EXCLUDED for every inserted non-key column. */
|
|
76
|
+
readonly update?: Record<string, unknown>;
|
|
77
|
+
};
|
|
78
|
+
export type DeleteManyBatchedOptions = {
|
|
79
|
+
readonly limit: number;
|
|
80
|
+
readonly maxBatches?: number;
|
|
81
|
+
/** Row id field for the LIMIT subquery. Default `id`. */
|
|
82
|
+
readonly idColumn?: string;
|
|
83
|
+
};
|
|
84
|
+
export type DeleteManyBatchedResult = {
|
|
85
|
+
readonly deleted: number;
|
|
86
|
+
readonly batches: number;
|
|
87
|
+
};
|
|
88
|
+
export declare function countWhere(db: AnyDb, table: TableLike, where?: WhereObject): Promise<number>;
|
|
89
|
+
export declare function isTimestamptzType(pgType: string | undefined): boolean;
|
|
90
|
+
export declare function aggregateWhere(db: AnyDb, table: TableLike, spec: AggregateSpec, where?: WhereObject): Promise<readonly AggregateRow[]>;
|
|
91
|
+
export declare function upsertOnConflict<TRow = any>(db: AnyDb, table: WritableTable, values: Record<string, unknown>, options: UpsertOnConflictOptions): Promise<TRow | undefined>;
|
|
92
|
+
export declare function upsertByPk<TRow = any>(db: AnyDb, table: WritableTable, values: Record<string, unknown>, updateOnConflict?: Record<string, unknown>): Promise<TRow | undefined>;
|
|
93
|
+
export type InsertOnConflictDoNothingOptions = {
|
|
94
|
+
readonly conflictKeys?: readonly string[];
|
|
95
|
+
};
|
|
96
|
+
export declare function insertOnConflictDoNothing<TRow = any>(db: AnyDb, table: WritableTable, values: Record<string, unknown>, options?: InsertOnConflictDoNothingOptions): Promise<TRow | undefined>;
|
|
97
|
+
export type IncrementCounterOptions = {
|
|
98
|
+
readonly conflictKeys?: readonly string[];
|
|
99
|
+
/** Extra SET clauses on conflict (e.g. lastUpdatedAt: sql\`NOW()\`). */
|
|
100
|
+
readonly set?: Record<string, unknown>;
|
|
101
|
+
};
|
|
102
|
+
export declare function incrementCounter<TRow = any>(db: AnyDb, table: WritableTable, values: Record<string, unknown>, increments: Record<string, number>, options?: IncrementCounterOptions): Promise<TRow | undefined>;
|
|
103
|
+
export declare function deleteManyBatched(db: AnyDb, table: WritableTable, where: WhereObject, options: DeleteManyBatchedOptions): Promise<DeleteManyBatchedResult>;
|
|
104
|
+
export declare function transaction<T>(db: AnyDb, fn: (tx: DbTx) => Promise<T>): Promise<T>;
|
|
105
|
+
export declare function runInNewTransaction<T>(db: unknown, fn: (tx: DbRunner) => Promise<T>): Promise<T>;
|