@cosmicdrift/kumiko-types 0.198.0 → 0.199.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/package.json +1 -1
- package/src/feature.ts +4 -0
- package/src/handlers.ts +13 -0
- package/src/tenant-db-types.ts +13 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-types",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.199.0",
|
|
4
4
|
"description": "Framework-Type-Definitions für Kumiko — FeatureDefinition, BootCheck-Types und die reinen Engine-Types. Erlaubt Downstream-Konsumenten, gegen die Type-Contracts zu bauen, ohne das ganze Framework-Package zu importieren. Enthaelt keine identitaets-sensitiven Runtime-Werte mehr (Error-Klassen leben seit #1629 in kumiko-framework, Brand-Symbole nutzen Symbol.for) und ist deshalb eine plain dependency, keine peerDependency.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
package/src/feature.ts
CHANGED
|
@@ -932,6 +932,10 @@ export type Registry = {
|
|
|
932
932
|
): readonly SearchPayloadContributorFn[];
|
|
933
933
|
getHandlerEntity(qualifiedHandler: string): string | undefined;
|
|
934
934
|
isHandlerSystemScoped(qualifiedHandler: string): boolean;
|
|
935
|
+
// Job counterpart to isHandlerSystemScoped — a job's owning feature is
|
|
936
|
+
// tracked separately (jobFeatureMap) since jobs aren't write/query/stream
|
|
937
|
+
// handlers and don't populate handlerFeatureMap.
|
|
938
|
+
isJobSystemScoped(qualifiedJobName: string): boolean;
|
|
935
939
|
getHandlerFeature(qualifiedHandler: string): string | undefined;
|
|
936
940
|
// True iff at least one registered handler declares a `rateLimit`
|
|
937
941
|
// option. Pre-computed at registry-build so the boot path can skip
|
package/src/handlers.ts
CHANGED
|
@@ -177,6 +177,7 @@ export type WriteResult<TData = unknown> =
|
|
|
177
177
|
// Forward import: Registry is in feature.ts (circular type import — fine in TS)
|
|
178
178
|
import type { Registry } from "./feature";
|
|
179
179
|
import type { TenantId } from "./identifiers";
|
|
180
|
+
import type { UncheckedSystemDb } from "./tenant-db-types";
|
|
180
181
|
|
|
181
182
|
// Minimal interface for job event triggers (framework-owned, concrete type in jobs/)
|
|
182
183
|
export type JobRunnerRef = {
|
|
@@ -358,6 +359,9 @@ export type HandlerContext<TMap extends object = KumikoEventTypeMap> = SharedCon
|
|
|
358
359
|
// outside the DB. `undefined` when the pipeline has no outside-tx source
|
|
359
360
|
// for this dispatch (see dispatch-shared.ts) — callers must check before use.
|
|
360
361
|
readonly dbOutsideTransaction: TenantDb | undefined;
|
|
362
|
+
// Only present for r.systemScope() handlers, bound to the same `db` as above.
|
|
363
|
+
// Non-system handlers never receive this — reach for `db` instead.
|
|
364
|
+
readonly systemDb?: UncheckedSystemDb;
|
|
361
365
|
readonly registry: Registry;
|
|
362
366
|
/** Aktiver SessionUser des Handler-Aufrufs — Convenience-Alias zu
|
|
363
367
|
* `event.user`. Existiert weil Handler intuitiv `ctx.user.tenantId`
|
|
@@ -573,6 +577,15 @@ export type JobContext = SharedContextFields & {
|
|
|
573
577
|
readonly systemUser: SessionUser;
|
|
574
578
|
readonly log: Logger;
|
|
575
579
|
readonly triggeredBy: { readonly id: string; readonly tenantId: TenantId } | null;
|
|
580
|
+
// Only present for jobs whose owning feature declares r.systemScope(),
|
|
581
|
+
// mirroring HandlerContext.systemDb (dispatch-shared.ts buildHandlerContext).
|
|
582
|
+
// assertTenantMatch()/acknowledgeCrossTenant() return a TenantDb, not the
|
|
583
|
+
// raw DbConnection above — job code that needs a DbRunner for a helper
|
|
584
|
+
// like reindexEntity() reaches through `.raw` on that TenantDb. `.raw`
|
|
585
|
+
// bypasses tenant filtering entirely, so it's only safe to hand to a
|
|
586
|
+
// helper that filters by tenantId itself (as reindexEntity does) — never
|
|
587
|
+
// pass it to code that trusts the connection to already be scoped.
|
|
588
|
+
readonly systemDb?: UncheckedSystemDb;
|
|
576
589
|
readonly write: (qn: string, payload: unknown) => Promise<WriteResult>;
|
|
577
590
|
readonly queryAs: (user: SessionUser, qn: string, payload: unknown) => Promise<unknown>;
|
|
578
591
|
// Multi-trigger jobs (`on: [...]`) use this to tell which trigger fired —
|
package/src/tenant-db-types.ts
CHANGED
|
@@ -56,3 +56,16 @@ export type TenantDb = {
|
|
|
56
56
|
): Promise<readonly T[]>;
|
|
57
57
|
deleteMany(table: WritableTable, where: WhereObject): Promise<void>;
|
|
58
58
|
};
|
|
59
|
+
|
|
60
|
+
// Symbol.for (global registry) so the brand identity matches even if kumiko-types
|
|
61
|
+
// resolves to two independent copies (workspace symlink vs. published npm) — a plain
|
|
62
|
+
// `Symbol()` per copy would make each resolution's `UncheckedSystemDb` structurally
|
|
63
|
+
// incompatible with the other, per the kumiko.secret precedent in secrets-types.ts.
|
|
64
|
+
export const SYSTEM_SCOPE_CHECK_BRAND: unique symbol = Symbol.for("kumiko.system-scope-check");
|
|
65
|
+
|
|
66
|
+
export type UncheckedSystemDb = {
|
|
67
|
+
readonly [SYSTEM_SCOPE_CHECK_BRAND]: true;
|
|
68
|
+
assertTenantMatch(tenantId: TenantId): TenantDb;
|
|
69
|
+
assertRowsTenant<T>(rows: readonly T[], tenantField: keyof T): readonly T[];
|
|
70
|
+
acknowledgeCrossTenant(reason: string): TenantDb;
|
|
71
|
+
};
|