@cosmicdrift/kumiko-types 0.327.0 → 0.328.1
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/dist/action-icon.d.ts +3 -0
- package/dist/action-icon.js +51 -0
- package/{src/agent-exposure.ts → dist/agent-exposure.d.ts} +8 -15
- package/dist/agent-exposure.js +16 -0
- package/dist/concurrency-mode.d.ts +1 -0
- package/dist/config-scope.d.ts +1 -0
- package/dist/config-scope.js +1 -0
- package/dist/config.d.ts +234 -0
- package/dist/config.js +1 -0
- package/dist/cursor-types.d.ts +16 -0
- package/dist/cursor-types.js +1 -0
- package/dist/db-connection.d.ts +14 -0
- package/dist/db-connection.js +1 -0
- package/dist/define-handler.d.ts +58 -0
- package/dist/define-handler.js +1 -0
- package/dist/derivatives-types.d.ts +53 -0
- package/dist/derivatives-types.js +3 -0
- package/dist/entity-cache.d.ts +16 -0
- package/dist/entity-cache.js +1 -0
- package/dist/entity-handlers.d.ts +54 -0
- package/dist/entity-handlers.js +1 -0
- package/dist/entity-table-meta-types.d.ts +44 -0
- package/dist/entity-table-meta-types.js +6 -0
- package/dist/envelope-cipher-types.d.ts +5 -0
- package/dist/envelope-cipher-types.js +1 -0
- package/dist/event-store-executor-types.d.ts +86 -0
- package/dist/event-store-executor-types.js +1 -0
- package/dist/event-store-types.d.ts +37 -0
- package/dist/event-store-types.js +7 -0
- package/dist/event-type-map.d.ts +8 -0
- package/{src/event-type-map.ts → dist/event-type-map.js} +1 -16
- package/dist/executor-brand.d.ts +8 -0
- package/dist/executor-brand.js +1 -0
- package/dist/extension-options-map.d.ts +9 -0
- package/dist/extension-options-map.js +4 -0
- package/dist/feature.d.ts +518 -0
- package/dist/feature.js +1 -0
- package/dist/field-icon.d.ts +1 -0
- package/dist/field-icon.js +1 -0
- package/dist/fields.d.ts +729 -0
- package/dist/fields.js +50 -0
- package/dist/file-handle-types.d.ts +12 -0
- package/dist/file-handle-types.js +1 -0
- package/dist/file-provider-resolver-types.d.ts +3 -0
- package/dist/file-provider-resolver-types.js +1 -0
- package/dist/file-storage-provider-types.d.ts +17 -0
- package/dist/file-storage-provider-types.js +1 -0
- package/dist/geo-tz.d.ts +17 -0
- package/{src/geo-tz.ts → dist/geo-tz.js} +1 -20
- package/dist/handlers.d.ts +493 -0
- package/dist/handlers.js +49 -0
- package/dist/hook-phase.d.ts +1 -0
- package/dist/hook-phase.js +1 -0
- package/dist/hooks.d.ts +75 -0
- package/dist/hooks.js +1 -0
- package/dist/http-route.d.ts +52 -0
- package/dist/http-route.js +13 -0
- package/dist/identifiers.d.ts +8 -0
- package/{src/identifiers.ts → dist/identifiers.js} +7 -24
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/kms-adapter-types.d.ts +68 -0
- package/dist/kms-adapter-types.js +49 -0
- package/dist/logger.d.ts +7 -0
- package/dist/logger.js +1 -0
- package/dist/multi-stream-apply-context-types.d.ts +18 -0
- package/dist/multi-stream-apply-context-types.js +1 -0
- package/dist/nav-icon.d.ts +3 -0
- package/dist/nav-icon.js +100 -0
- package/dist/nav.d.ts +39 -0
- package/dist/nav.js +1 -0
- package/dist/observability/index.d.ts +3 -0
- package/dist/observability/index.js +2 -0
- package/dist/observability/metric.d.ts +34 -0
- package/dist/observability/metric.js +3 -0
- package/dist/observability/provider.d.ts +24 -0
- package/dist/observability/provider.js +4 -0
- package/dist/observability/span.d.ts +32 -0
- package/dist/observability/span.js +4 -0
- package/dist/ownership.d.ts +33 -0
- package/dist/ownership.js +5 -0
- package/dist/projection.d.ts +38 -0
- package/dist/projection.js +1 -0
- package/dist/rate-limit-types.d.ts +19 -0
- package/dist/rate-limit-types.js +1 -0
- package/dist/relations.d.ts +25 -0
- package/dist/relations.js +1 -0
- package/dist/schema-table-types.d.ts +15 -0
- package/{src/schema-table-types.ts → dist/schema-table-types.js} +0 -20
- package/dist/screen.d.ts +1265 -0
- package/dist/screen.js +3 -0
- package/dist/search-adapter.d.ts +32 -0
- package/dist/search-adapter.js +1 -0
- package/dist/secrets-types.d.ts +52 -0
- package/dist/secrets-types.js +30 -0
- package/dist/snapshot-types.d.ts +13 -0
- package/dist/snapshot-types.js +1 -0
- package/dist/step.d.ts +304 -0
- package/dist/step.js +11 -0
- package/dist/target-ref.d.ts +5 -0
- package/{src/target-ref.ts → dist/target-ref.js} +1 -6
- package/dist/tenancy-brand.d.ts +6 -0
- package/dist/tenancy-brand.js +1 -0
- package/dist/tenant-db-types.d.ts +67 -0
- package/dist/tenant-db-types.js +5 -0
- package/dist/tree-node.d.ts +26 -0
- package/dist/tree-node.js +22 -0
- package/dist/tz-context.d.ts +48 -0
- package/dist/tz-context.js +6 -0
- package/dist/websocket-route.d.ts +46 -0
- package/dist/websocket-route.js +10 -0
- package/dist/where-clause-types.d.ts +20 -0
- package/dist/where-clause-types.js +1 -0
- package/dist/workspace.d.ts +10 -0
- package/dist/workspace.js +1 -0
- package/dist/write-error-info-types.d.ts +12 -0
- package/dist/write-error-info-types.js +1 -0
- package/package.json +372 -124
- package/src/changes.json +18 -0
- package/src/__tests__/handlers.test.ts +0 -40
- package/src/__tests__/plural-forms.test.ts +0 -18
- package/src/action-icon.ts +0 -57
- package/src/concurrency-mode.ts +0 -5
- package/src/config-scope.ts +0 -5
- package/src/config.ts +0 -563
- package/src/cursor-types.ts +0 -18
- package/src/db-connection.ts +0 -25
- package/src/define-handler.ts +0 -138
- package/src/derivatives-types.ts +0 -106
- package/src/entity-cache.ts +0 -35
- package/src/entity-handlers.ts +0 -68
- package/src/entity-table-meta-types.ts +0 -101
- package/src/envelope-cipher-types.ts +0 -6
- package/src/event-store-executor-types.ts +0 -163
- package/src/event-store-types.ts +0 -85
- package/src/executor-brand.ts +0 -19
- package/src/extension-options-map.ts +0 -21
- package/src/feature.ts +0 -1141
- package/src/field-icon.ts +0 -23
- package/src/fields.ts +0 -1114
- package/src/file-handle-types.ts +0 -20
- package/src/file-provider-resolver-types.ts +0 -7
- package/src/file-storage-provider-types.ts +0 -54
- package/src/handlers.ts +0 -1246
- package/src/hook-phase.ts +0 -2
- package/src/hooks.ts +0 -170
- package/src/http-route.ts +0 -78
- package/src/kms-adapter-types.ts +0 -128
- package/src/logger.ts +0 -7
- package/src/multi-stream-apply-context-types.ts +0 -52
- package/src/nav-icon.ts +0 -105
- package/src/nav.ts +0 -139
- package/src/observability/index.ts +0 -28
- package/src/observability/metric.ts +0 -56
- package/src/observability/provider.ts +0 -32
- package/src/observability/span.ts +0 -58
- package/src/ownership.ts +0 -83
- package/src/projection.ts +0 -170
- package/src/rate-limit-types.ts +0 -32
- package/src/relations.ts +0 -52
- package/src/screen.ts +0 -1593
- package/src/search-adapter.ts +0 -45
- package/src/secrets-types.ts +0 -182
- package/src/snapshot-types.ts +0 -36
- package/src/step.ts +0 -390
- package/src/tenancy-brand.ts +0 -9
- package/src/tenant-db-types.ts +0 -116
- package/src/tree-node.ts +0 -134
- package/src/tz-context.ts +0 -63
- package/src/websocket-route.ts +0 -68
- package/src/where-clause-types.ts +0 -31
- package/src/workspace.ts +0 -42
- package/src/write-error-info-types.ts +0 -20
- /package/{src/index.ts → dist/concurrency-mode.js} +0 -0
package/dist/fields.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// --- Field Types ---
|
|
2
|
+
/** Qualified config key a `{ kind: "tenant" }` MoneyCurrencySource resolves
|
|
3
|
+
* against — the tenant-settings bundle's per-tenant currency. Lives here
|
|
4
|
+
* (client-safe) rather than framework/engine so renderer code can read it
|
|
5
|
+
* without a runtime-only import (kumiko-framework#2937). */
|
|
6
|
+
export const TENANT_CURRENCY_CONFIG_KEY = "tenant-settings:config:currency";
|
|
7
|
+
// Exhaustive catalogue of `FieldDefinition["type"]` values, derived from a
|
|
8
|
+
// `Record` so an added/removed union member fails to compile here instead of
|
|
9
|
+
// silently drifting out of sync with the runtime validator that consults
|
|
10
|
+
// this list (feature-ast's pattern-change-schema). Plain array, not a Set —
|
|
11
|
+
// same rationale as NO_WIDGET_FIELD_TYPES (guard-types-class-free.test.ts).
|
|
12
|
+
const FIELD_TYPE_NAME_FLAGS = {
|
|
13
|
+
text: true,
|
|
14
|
+
longText: true,
|
|
15
|
+
boolean: true,
|
|
16
|
+
select: true,
|
|
17
|
+
multiSelect: true,
|
|
18
|
+
number: true,
|
|
19
|
+
bigInt: true,
|
|
20
|
+
decimal: true,
|
|
21
|
+
money: true,
|
|
22
|
+
reference: true,
|
|
23
|
+
embedded: true,
|
|
24
|
+
jsonb: true,
|
|
25
|
+
date: true,
|
|
26
|
+
timestamp: true,
|
|
27
|
+
tz: true,
|
|
28
|
+
locatedTimestamp: true,
|
|
29
|
+
file: true,
|
|
30
|
+
image: true,
|
|
31
|
+
files: true,
|
|
32
|
+
images: true,
|
|
33
|
+
};
|
|
34
|
+
export const FIELD_TYPE_NAMES = Object.keys(FIELD_TYPE_NAME_FLAGS);
|
|
35
|
+
// Field types with no bound, editable widget on the auto-wired entityEdit
|
|
36
|
+
// path (render-field.tsx renders a read-only banner instead) — shared by
|
|
37
|
+
// the boot validator (packages/framework/src/engine/boot-validator/screens.ts)
|
|
38
|
+
// and the client-side required-field check (packages/renderer/src/app/form-schema.ts).
|
|
39
|
+
// Embedded LIST fields (`multiple: true`) are the one exception — they get
|
|
40
|
+
// their own EmbeddedListField grid widget (#1838) — callers must check that
|
|
41
|
+
// separately, this array alone doesn't distinguish plain embedded from embedded lists.
|
|
42
|
+
// A plain array, not a Set: kumiko-types stays free of module-scope runtime
|
|
43
|
+
// identity (guard-types-class-free.test.ts) since a consumer may resolve two
|
|
44
|
+
// copies of this package.
|
|
45
|
+
export const NO_WIDGET_FIELD_TYPES = [
|
|
46
|
+
"jsonb",
|
|
47
|
+
"embedded",
|
|
48
|
+
"files",
|
|
49
|
+
"images",
|
|
50
|
+
];
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type FileHandle = {
|
|
2
|
+
readonly key: string;
|
|
3
|
+
read(): Promise<Uint8Array>;
|
|
4
|
+
write(data: Uint8Array, mimeType?: string): Promise<void>;
|
|
5
|
+
delete(): Promise<void>;
|
|
6
|
+
exists(): Promise<boolean>;
|
|
7
|
+
derive(suffix: string): FileHandle;
|
|
8
|
+
};
|
|
9
|
+
export type FileContext = {
|
|
10
|
+
ref(key: string): FileHandle;
|
|
11
|
+
list(prefix: string): Promise<readonly string[]>;
|
|
12
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type SignedUrlOptions = {
|
|
2
|
+
readonly contentDisposition?: string;
|
|
3
|
+
};
|
|
4
|
+
export type WriteStreamOptions = {
|
|
5
|
+
readonly mimeType?: string;
|
|
6
|
+
readonly contentLength?: number;
|
|
7
|
+
};
|
|
8
|
+
export type FileStorageProvider = {
|
|
9
|
+
write(key: string, data: Uint8Array, mimeType?: string): Promise<void>;
|
|
10
|
+
writeStream(key: string, source: AsyncIterable<Uint8Array>, options?: WriteStreamOptions): Promise<void>;
|
|
11
|
+
read(key: string): Promise<Uint8Array>;
|
|
12
|
+
readStream(key: string): AsyncIterable<Uint8Array>;
|
|
13
|
+
delete(key: string): Promise<void>;
|
|
14
|
+
exists(key: string): Promise<boolean>;
|
|
15
|
+
list(prefix: string): Promise<readonly string[]>;
|
|
16
|
+
getSignedUrl?(key: string, expiresInSeconds: number, options?: SignedUrlOptions): Promise<string>;
|
|
17
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/geo-tz.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type GeoCoordinates = {
|
|
2
|
+
readonly latitude: number;
|
|
3
|
+
readonly longitude: number;
|
|
4
|
+
};
|
|
5
|
+
export type GeoAddress = {
|
|
6
|
+
readonly street?: string;
|
|
7
|
+
readonly city?: string;
|
|
8
|
+
readonly region?: string;
|
|
9
|
+
readonly postalCode?: string;
|
|
10
|
+
readonly country?: string;
|
|
11
|
+
};
|
|
12
|
+
export type GeoTzProvider = {
|
|
13
|
+
/** Geo-coordinates → IANA zone (offline lat/lng → tz). */
|
|
14
|
+
readonly fromCoordinates: (coords: GeoCoordinates) => string | Promise<string>;
|
|
15
|
+
/** Optional: postal address → IANA zone (geocoding API provider). */
|
|
16
|
+
readonly fromAddress?: (address: GeoAddress) => string | Promise<string>;
|
|
17
|
+
};
|
|
@@ -10,23 +10,4 @@
|
|
|
10
10
|
// zone, online). This split keeps the interface compatible with both
|
|
11
11
|
// provider classes instead of forcing an address shape the offline case
|
|
12
12
|
// can't serve at all.
|
|
13
|
-
|
|
14
|
-
export type GeoCoordinates = {
|
|
15
|
-
readonly latitude: number;
|
|
16
|
-
readonly longitude: number;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export type GeoAddress = {
|
|
20
|
-
readonly street?: string;
|
|
21
|
-
readonly city?: string;
|
|
22
|
-
readonly region?: string;
|
|
23
|
-
readonly postalCode?: string;
|
|
24
|
-
readonly country?: string;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export type GeoTzProvider = {
|
|
28
|
-
/** Geo-coordinates → IANA zone (offline lat/lng → tz). */
|
|
29
|
-
readonly fromCoordinates: (coords: GeoCoordinates) => string | Promise<string>;
|
|
30
|
-
/** Optional: postal address → IANA zone (geocoding API provider). */
|
|
31
|
-
readonly fromAddress?: (address: GeoAddress) => string | Promise<string>;
|
|
32
|
-
};
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
import type { Redis } from "ioredis";
|
|
2
|
+
import type { ZodType } from "zod";
|
|
3
|
+
import type { ConfigAccessor, ConfigAccessorFactory, ConfigResolver } from "./config.js";
|
|
4
|
+
import type { DbConnection } from "./db-connection.js";
|
|
5
|
+
import type { DerivativesContext } from "./derivatives-types.js";
|
|
6
|
+
import type { EntityCache } from "./entity-cache.js";
|
|
7
|
+
import type { EventMetadata, WriteOrigin } from "./event-store-types.js";
|
|
8
|
+
import type { KumikoEventTypeMap } from "./event-type-map.js";
|
|
9
|
+
import type { FileContext } from "./file-handle-types.js";
|
|
10
|
+
import type { FileProviderResolver } from "./file-provider-resolver-types.js";
|
|
11
|
+
import type { GeoTzProvider } from "./geo-tz.js";
|
|
12
|
+
import type { Logger } from "./logger.js";
|
|
13
|
+
import type { Meter, MetricsHandle, Tracer } from "./observability/index.js";
|
|
14
|
+
import type { SearchAdapter } from "./search-adapter.js";
|
|
15
|
+
import type { TenantDb } from "./tenant-db-types.js";
|
|
16
|
+
import type { TzContext } from "./tz-context.js";
|
|
17
|
+
export type OpenToAllPersonalData = "tenant-members";
|
|
18
|
+
export type OpenToAllDeclaration = {
|
|
19
|
+
readonly reason: string;
|
|
20
|
+
readonly personalData?: OpenToAllPersonalData;
|
|
21
|
+
};
|
|
22
|
+
export type OpenToAllAccessRule = {
|
|
23
|
+
readonly openToAll: OpenToAllDeclaration;
|
|
24
|
+
};
|
|
25
|
+
export type RoleAccessPersonalData = "public-intake";
|
|
26
|
+
export type RoleAccessRule = {
|
|
27
|
+
readonly roles: readonly string[];
|
|
28
|
+
readonly personalData?: RoleAccessPersonalData;
|
|
29
|
+
};
|
|
30
|
+
export type AccessRule = RoleAccessRule | OpenToAllAccessRule;
|
|
31
|
+
export type EscapeHatchDeclaration = {
|
|
32
|
+
readonly reason: string;
|
|
33
|
+
};
|
|
34
|
+
export declare function isOpenToAllGranted(rule: AccessRule): boolean;
|
|
35
|
+
export declare function isUiAccessGranted(access: AccessRule | undefined, userRoles: readonly string[] | undefined): boolean;
|
|
36
|
+
export type SessionUserOrigin = "member-resolution";
|
|
37
|
+
export type SessionUser = {
|
|
38
|
+
readonly id: string;
|
|
39
|
+
readonly tenantId: TenantId;
|
|
40
|
+
readonly roles: readonly string[];
|
|
41
|
+
readonly timezone?: string;
|
|
42
|
+
readonly locale?: string;
|
|
43
|
+
readonly claims?: Readonly<Record<string, unknown>>;
|
|
44
|
+
readonly sid?: string;
|
|
45
|
+
readonly pat?: {
|
|
46
|
+
readonly tokenId: string;
|
|
47
|
+
readonly scopes: readonly string[];
|
|
48
|
+
readonly allowedQns: readonly string[];
|
|
49
|
+
};
|
|
50
|
+
readonly origin?: SessionUserOrigin;
|
|
51
|
+
};
|
|
52
|
+
export type ClaimKeyType = "string" | "number" | "boolean" | "string[]" | "object";
|
|
53
|
+
export type ClaimKeyJsType<T extends ClaimKeyType> = T extends "string" ? string : T extends "number" ? number : T extends "boolean" ? boolean : T extends "string[]" ? readonly string[] : T extends "object" ? Readonly<Record<string, unknown>> : never;
|
|
54
|
+
export type ClaimKeyDefinition = {
|
|
55
|
+
readonly shortName: string;
|
|
56
|
+
readonly qualifiedName: string;
|
|
57
|
+
readonly type: ClaimKeyType;
|
|
58
|
+
};
|
|
59
|
+
export type ClaimKeyHandle<T extends ClaimKeyType = ClaimKeyType> = {
|
|
60
|
+
readonly name: string;
|
|
61
|
+
readonly type: T;
|
|
62
|
+
};
|
|
63
|
+
export type AuthClaimsContext = {
|
|
64
|
+
readonly db: import("./tenant-db-types.js").TenantDb;
|
|
65
|
+
readonly queryAs: (user: SessionUser, qn: string, payload: unknown) => Promise<unknown>;
|
|
66
|
+
readonly config?: ConfigAccessor;
|
|
67
|
+
};
|
|
68
|
+
export type AuthClaimsFn = (user: SessionUser, ctx: AuthClaimsContext) => Promise<Record<string, unknown>>;
|
|
69
|
+
export type AuthClaimsHookDef = {
|
|
70
|
+
readonly featureName: string;
|
|
71
|
+
readonly fn: AuthClaimsFn;
|
|
72
|
+
readonly declaredKeys?: ReadonlySet<string>;
|
|
73
|
+
};
|
|
74
|
+
export type ActiveMembershipRejection = "not_a_member" | "principal_blocked" | "tenant_teardown";
|
|
75
|
+
export type ActiveMembership = {
|
|
76
|
+
readonly tenantId: TenantId;
|
|
77
|
+
readonly roles: readonly string[];
|
|
78
|
+
readonly tenantName?: string;
|
|
79
|
+
readonly tenantKey?: string;
|
|
80
|
+
};
|
|
81
|
+
export type ActiveMembershipResult = {
|
|
82
|
+
readonly kind: "active";
|
|
83
|
+
readonly membership: ActiveMembership;
|
|
84
|
+
} | {
|
|
85
|
+
readonly kind: "rejected";
|
|
86
|
+
readonly reason: ActiveMembershipRejection;
|
|
87
|
+
};
|
|
88
|
+
export type WriteEvent<TPayload = unknown> = {
|
|
89
|
+
readonly type: string;
|
|
90
|
+
readonly payload: TPayload;
|
|
91
|
+
readonly user: SessionUser;
|
|
92
|
+
};
|
|
93
|
+
export type QueryEvent<TPayload = unknown> = {
|
|
94
|
+
readonly type: string;
|
|
95
|
+
readonly payload: TPayload;
|
|
96
|
+
readonly user: SessionUser;
|
|
97
|
+
};
|
|
98
|
+
import type { WriteFailure } from "./write-error-info-types.js";
|
|
99
|
+
export type WriteResult<TData = unknown> = {
|
|
100
|
+
readonly isSuccess: true;
|
|
101
|
+
readonly data: TData;
|
|
102
|
+
} | WriteFailure;
|
|
103
|
+
import type { Registry } from "./feature.js";
|
|
104
|
+
import type { TenantId } from "./identifiers.js";
|
|
105
|
+
import type { UncheckedSystemDb } from "./tenant-db-types.js";
|
|
106
|
+
export type MemberReader = (userId: string, qn: string, payload: unknown) => Promise<unknown>;
|
|
107
|
+
export type JobTriggerEvent = {
|
|
108
|
+
readonly id: string;
|
|
109
|
+
readonly headers: NonNullable<EventMetadata["headers"]>;
|
|
110
|
+
};
|
|
111
|
+
export type JobRunnerRef = {
|
|
112
|
+
handleEvent(eventName: string, payload: Record<string, unknown>, user?: SessionUser, triggerEvent?: JobTriggerEvent): Promise<void>;
|
|
113
|
+
};
|
|
114
|
+
export type DispatchWriteRef = {
|
|
115
|
+
readonly write: (user: SessionUser, qn: string, payload: unknown, inheritedOrigin?: WriteOrigin) => Promise<WriteResult>;
|
|
116
|
+
readonly queryAs: (user: SessionUser, qn: string, payload: unknown, inheritedOrigin?: WriteOrigin) => Promise<unknown>;
|
|
117
|
+
readonly createMemberReader: (tenantId: TenantId) => MemberReader;
|
|
118
|
+
};
|
|
119
|
+
export type NotifyPriority = "critical" | "normal" | "low";
|
|
120
|
+
export type NotifyOptions = {
|
|
121
|
+
readonly to?: string | readonly string[] | {
|
|
122
|
+
readonly tenant: TenantId;
|
|
123
|
+
};
|
|
124
|
+
readonly route?: Readonly<Record<string, string>>;
|
|
125
|
+
readonly data?: Readonly<Record<string, unknown>>;
|
|
126
|
+
readonly priority?: NotifyPriority;
|
|
127
|
+
readonly idempotencyKey?: string;
|
|
128
|
+
readonly recipientId?: string;
|
|
129
|
+
};
|
|
130
|
+
export type NotifyFn = (notificationType: string, options: NotifyOptions) => Promise<void>;
|
|
131
|
+
export type NotifyFactory = (user: SessionUser, tenantId: TenantId) => NotifyFn;
|
|
132
|
+
export type EscapeHatchKind = "unsafe-raw" | "acknowledge-cross-tenant" | "global-write" | "identity-switch" | "unsafe-all-tenants";
|
|
133
|
+
export type EscapeHatchTarget = {
|
|
134
|
+
readonly id: string;
|
|
135
|
+
readonly tenantId: TenantId;
|
|
136
|
+
};
|
|
137
|
+
export type EscapeHatchUseEvent = {
|
|
138
|
+
readonly handler: string;
|
|
139
|
+
readonly kind: EscapeHatchKind;
|
|
140
|
+
readonly reason: string;
|
|
141
|
+
readonly tenantId: TenantId;
|
|
142
|
+
readonly actor: string;
|
|
143
|
+
readonly target?: EscapeHatchTarget;
|
|
144
|
+
};
|
|
145
|
+
export type EscapeHatchAuditSink = (event: EscapeHatchUseEvent) => Promise<void>;
|
|
146
|
+
export type EscapeHatchReporter = (kind: EscapeHatchKind, reason: string, target?: EscapeHatchTarget) => void;
|
|
147
|
+
type SharedContextFields = {
|
|
148
|
+
readonly redis?: Redis;
|
|
149
|
+
readonly jobRunner?: JobRunnerRef;
|
|
150
|
+
readonly configResolver?: ConfigResolver;
|
|
151
|
+
readonly config?: ConfigAccessor;
|
|
152
|
+
readonly _configAccessorFactory?: ConfigAccessorFactory;
|
|
153
|
+
readonly configEncryption?: import("./envelope-cipher-types.js").EnvelopeCipher;
|
|
154
|
+
readonly rateLimit?: import("./rate-limit-types.js").RateLimitResolver;
|
|
155
|
+
readonly searchAdapter?: SearchAdapter;
|
|
156
|
+
readonly files?: FileContext;
|
|
157
|
+
readonly derivatives?: DerivativesContext;
|
|
158
|
+
readonly _fileProviderResolver?: FileProviderResolver;
|
|
159
|
+
readonly entityCache?: EntityCache;
|
|
160
|
+
readonly notify?: NotifyFn;
|
|
161
|
+
readonly _notifyFactory?: NotifyFactory;
|
|
162
|
+
readonly _escapeHatchAuditSink?: EscapeHatchAuditSink;
|
|
163
|
+
readonly secrets?: import("./secrets-types.js").SecretsContext;
|
|
164
|
+
readonly masterKeyProvider?: import("./secrets-types.js").MasterKeyProvider;
|
|
165
|
+
readonly kms?: import("./kms-adapter-types.js").KmsAdapter;
|
|
166
|
+
readonly tracer?: Tracer;
|
|
167
|
+
readonly meter?: Meter;
|
|
168
|
+
readonly signal?: AbortSignal;
|
|
169
|
+
readonly effectiveFeatures?: (tenantId: TenantId) => ReadonlySet<string>;
|
|
170
|
+
readonly scheduleAfterCommit?: (hook: () => Promise<void>) => void;
|
|
171
|
+
readonly queryAsMember?: MemberReader;
|
|
172
|
+
};
|
|
173
|
+
export type AppContext = SharedContextFields & {
|
|
174
|
+
readonly db?: DbConnection | TenantDb;
|
|
175
|
+
readonly systemDb?: UncheckedSystemDb;
|
|
176
|
+
readonly registry?: Registry;
|
|
177
|
+
readonly systemUser?: SessionUser;
|
|
178
|
+
readonly log?: Logger;
|
|
179
|
+
readonly triggeredBy?: {
|
|
180
|
+
readonly id: string;
|
|
181
|
+
readonly tenantId: TenantId;
|
|
182
|
+
} | null;
|
|
183
|
+
/** Bei Job-Handler-Aufrufen die aus einem Event-Trigger heraus laufen
|
|
184
|
+
* (r.job mit `trigger: { on: ... }`): der Name des Handlers der das
|
|
185
|
+
* Event ausgelöst hat. Bei Multi-Trigger-Jobs (`on: [...]`) ist das
|
|
186
|
+
* die einzige Möglichkeit für den Handler zu wissen WELCHER Trigger
|
|
187
|
+
* gefeuert hat. Cron- und manual-Jobs lassen das Feld undefined. */
|
|
188
|
+
readonly triggerName?: string;
|
|
189
|
+
readonly _userId?: string | undefined;
|
|
190
|
+
readonly _handlerType?: string | undefined;
|
|
191
|
+
/** Optionaler Geo→Zone-Adapter. Wenn gesetzt (via buildServer-context oder
|
|
192
|
+
* runProdApp/runDevApp extraContext), reicht der Dispatcher ihn an
|
|
193
|
+
* ctx.tz.fromCoordinates / fromAddress weiter. Ohne Provider werfen diese. */
|
|
194
|
+
readonly geoTzProvider?: GeoTzProvider;
|
|
195
|
+
/** Tenant des aktuellen Pipeline-Calls. Wird vom Dispatcher beim Bauen
|
|
196
|
+
* des HandlerContext aus `user.tenantId` gespiegelt, damit lifecycle-
|
|
197
|
+
* pipeline + system-hooks den Wert ohne Zugriff auf user-Object haben.
|
|
198
|
+
* Sprint-8a Tier-Composition: `effectiveFeatures(ctx._tenantId)`-call
|
|
199
|
+
* in den hook-filter-Stellen. */
|
|
200
|
+
readonly _tenantId?: TenantId;
|
|
201
|
+
/** Boot-configured default locale (BCP-47). Last fallback in ctx.locale's
|
|
202
|
+
* Request-Locale → Boot-Default chain (dispatch-shared.ts) — used when
|
|
203
|
+
* the request carries no X-Locale header and no usable Accept-Language.
|
|
204
|
+
* Absent falls back to "en". */
|
|
205
|
+
readonly defaultLocale?: string;
|
|
206
|
+
};
|
|
207
|
+
export type HandlerContext<TMap extends object = KumikoEventTypeMap> = SharedContextFields & {
|
|
208
|
+
readonly db: TenantDb;
|
|
209
|
+
readonly dbOutsideTransaction: TenantDb | undefined;
|
|
210
|
+
readonly systemDb?: UncheckedSystemDb;
|
|
211
|
+
readonly registry: Registry;
|
|
212
|
+
/** Aktiver SessionUser des Handler-Aufrufs — Convenience-Alias zu
|
|
213
|
+
* `event.user`. Existiert weil Handler intuitiv `ctx.user.tenantId`
|
|
214
|
+
* schreiben (Context = "kennt seinen User") und der Pfad sonst nur
|
|
215
|
+
* über `event.user` läuft, was typo-anfällig ist und stillschweigend
|
|
216
|
+
* zu `internal_error` führt wenn der falsche Pfad gewählt wird.
|
|
217
|
+
* Identisch zum event.user-Wert; Identity-Switches nutzen
|
|
218
|
+
* weiterhin queryAs/writeAs. */
|
|
219
|
+
readonly user: SessionUser;
|
|
220
|
+
readonly systemUser?: SessionUser;
|
|
221
|
+
readonly log?: Logger;
|
|
222
|
+
readonly triggeredBy?: {
|
|
223
|
+
readonly id: string;
|
|
224
|
+
readonly tenantId: TenantId;
|
|
225
|
+
} | null;
|
|
226
|
+
readonly _userId?: string | undefined;
|
|
227
|
+
readonly _handlerType?: string | undefined;
|
|
228
|
+
readonly includeDeleted?: boolean;
|
|
229
|
+
readonly runPreSave?: (handlerName: string, changes: Record<string, unknown>, previous: Readonly<Record<string, unknown>>, isNew: boolean) => Promise<Record<string, unknown>>;
|
|
230
|
+
readonly query: (qn: string, payload: unknown) => Promise<unknown>;
|
|
231
|
+
readonly queryAs: (user: SessionUser, qn: string, payload: unknown) => Promise<unknown>;
|
|
232
|
+
readonly write: (qn: string, payload: unknown) => Promise<WriteResult>;
|
|
233
|
+
readonly writeAs: (user: SessionUser, qn: string, payload: unknown) => Promise<WriteResult>;
|
|
234
|
+
readonly hasFeature: (featureName: string) => Promise<boolean>;
|
|
235
|
+
readonly appendEvent: AppendEventFn<TMap>;
|
|
236
|
+
readonly unsafeAppendEvent: UnsafeAppendEventFn;
|
|
237
|
+
readonly tryAppendEvent: TryAppendEventFn;
|
|
238
|
+
readonly fetchForWriting: (args: FetchForWritingArgs) => Promise<AggregateStreamHandle>;
|
|
239
|
+
readonly loadAggregate: (aggregateId: string, options?: {
|
|
240
|
+
readonly asOf?: Temporal.Instant;
|
|
241
|
+
}) => Promise<readonly import("./event-store-types.js").StoredEvent[]>;
|
|
242
|
+
readonly archiveStream: (aggregateId: string, args: {
|
|
243
|
+
readonly aggregateType: string;
|
|
244
|
+
readonly reason?: string;
|
|
245
|
+
}) => Promise<void>;
|
|
246
|
+
readonly restoreStream: (aggregateId: string) => Promise<void>;
|
|
247
|
+
readonly isStreamArchived: (aggregateId: string) => Promise<boolean>;
|
|
248
|
+
readonly snapshotAggregate: (args: {
|
|
249
|
+
readonly aggregateId: string;
|
|
250
|
+
readonly aggregateType: string;
|
|
251
|
+
readonly version: number;
|
|
252
|
+
readonly state: Record<string, unknown>;
|
|
253
|
+
readonly snapshotVersion?: number;
|
|
254
|
+
}) => Promise<void>;
|
|
255
|
+
readonly loadAggregateWithSnapshot: <TState extends Record<string, unknown>>(aggregateId: string, reducer: import("./snapshot-types.js").SnapshotReducer<TState>, initial: TState, options?: Omit<import("./snapshot-types.js").LoadAggregateWithSnapshotOptions, "upcastEvent">) => Promise<import("./snapshot-types.js").LoadAggregateWithSnapshotResult<TState>>;
|
|
256
|
+
readonly queryProjection: <T = Record<string, unknown>>(qualifiedName: string, options?: {
|
|
257
|
+
readonly unsafeAllTenants?: boolean;
|
|
258
|
+
}) => Promise<readonly T[]>;
|
|
259
|
+
readonly metrics: MetricsHandle;
|
|
260
|
+
readonly metricsFor: (featureName: string) => MetricsHandle;
|
|
261
|
+
readonly tracer: Tracer;
|
|
262
|
+
readonly tz: TzContext;
|
|
263
|
+
readonly locale: string;
|
|
264
|
+
readonly resolveAuthClaims: (user: SessionUser) => Promise<Record<string, unknown>>;
|
|
265
|
+
readonly resolveActiveMembership: (userId: string, tenantId: TenantId) => Promise<ActiveMembershipResult>;
|
|
266
|
+
readonly queryAsMember: MemberReader;
|
|
267
|
+
};
|
|
268
|
+
export type JobContext = SharedContextFields & {
|
|
269
|
+
readonly db: TenantDb;
|
|
270
|
+
readonly registry: Registry;
|
|
271
|
+
readonly systemUser: SessionUser;
|
|
272
|
+
readonly log: Logger;
|
|
273
|
+
readonly triggeredBy: {
|
|
274
|
+
readonly id: string;
|
|
275
|
+
readonly tenantId: TenantId;
|
|
276
|
+
} | null;
|
|
277
|
+
readonly attempt: number;
|
|
278
|
+
readonly finalAttempt: boolean;
|
|
279
|
+
readonly systemDb?: UncheckedSystemDb;
|
|
280
|
+
readonly write: (qn: string, payload: unknown) => Promise<WriteResult>;
|
|
281
|
+
readonly writeAs: (user: SessionUser, qn: string, payload: unknown) => Promise<WriteResult>;
|
|
282
|
+
readonly queryAs: (user: SessionUser, qn: string, payload: unknown) => Promise<unknown>;
|
|
283
|
+
readonly queryAsMember: MemberReader;
|
|
284
|
+
readonly triggerName?: string;
|
|
285
|
+
readonly triggerEvent?: JobTriggerEvent;
|
|
286
|
+
readonly _tenantId?: TenantId;
|
|
287
|
+
readonly _userId?: string | undefined;
|
|
288
|
+
};
|
|
289
|
+
export type WriteHandlerFn<TPayload = unknown, TData = unknown> = (event: WriteEvent<TPayload>, context: HandlerContext) => Promise<WriteResult<TData>>;
|
|
290
|
+
export type QueryHandlerFn<TPayload = unknown, TResult = unknown> = (query: QueryEvent<TPayload>, context: HandlerContext) => Promise<TResult>;
|
|
291
|
+
export type StreamHandlerFn<TPayload = unknown, TChunk = unknown> = (query: QueryEvent<TPayload>, context: HandlerContext) => AsyncGenerator<TChunk>;
|
|
292
|
+
/**
|
|
293
|
+
* Compile-time mirror of `engine/qualified-name.ts:toKebab` for camelCase
|
|
294
|
+
* → kebab-case. Drives the literal-type of `EventDef.name`, so that
|
|
295
|
+
* `r.defineEvent("foo", schema)` inside `defineFeature("driverOrders")`
|
|
296
|
+
* carries `name: "driver-orders:event:foo"` as a literal — strict-mode
|
|
297
|
+
* for `ctx.appendEvent({ type: eventDef.name, ... })` lights up.
|
|
298
|
+
*
|
|
299
|
+
* Algorithm mirrors the runtime regex pipeline:
|
|
300
|
+
* 1. `.` → `-` (dot acts as word-boundary)
|
|
301
|
+
* 2. Insert `-` between `[A-Z]+` and `[A-Z][a-z]` (so `SSEFoo` →
|
|
302
|
+
* `SSE-Foo`, splitting an uppercase run before a camel-hump)
|
|
303
|
+
* 3. Insert `-` between `[a-z0-9]` and `[A-Z]` (camelCase boundary,
|
|
304
|
+
* so `ticketAssigned` → `ticket-Assigned`)
|
|
305
|
+
* 4. lowercase everything
|
|
306
|
+
*
|
|
307
|
+
* Implemented as a state machine with one-char lookahead. State:
|
|
308
|
+
* - "start" — at start of string, or right after a dot-boundary
|
|
309
|
+
* - "upper" — last emitted char came from an uppercase letter
|
|
310
|
+
* - "post-letter" — last emitted char was a lowercase letter or digit
|
|
311
|
+
*
|
|
312
|
+
* Sync vs runtime is verified by `engine/__tests__/camel-to-kebab.test-d.ts`
|
|
313
|
+
* — the type-tests cross-check identical inputs against `toKebab()`.
|
|
314
|
+
*/
|
|
315
|
+
export type CamelToKebab<S extends string> = CamelToKebabImpl<S, "start", "">;
|
|
316
|
+
type CamelToKebabImpl<S extends string, Prev extends "start" | "upper" | "post-letter", Acc extends string> = S extends `${infer C}${infer Rest}` ? CharKind<C> extends "upper" ? Prev extends "start" ? CamelToKebabImpl<Rest, "upper", `${Acc}${Lowercase<C>}`> : Prev extends "post-letter" ? CamelToKebabImpl<Rest, "upper", `${Acc}-${Lowercase<C>}`> : Rest extends `${infer Next}${string}` ? CharKind<Next> extends "lower" ? CamelToKebabImpl<Rest, "upper", `${Acc}-${Lowercase<C>}`> : CamelToKebabImpl<Rest, "upper", `${Acc}${Lowercase<C>}`> : `${Acc}${Lowercase<C>}` : CharKind<C> extends "lower" ? CamelToKebabImpl<Rest, "post-letter", `${Acc}${C}`> : C extends "." ? CamelToKebabImpl<Rest, "start", `${Acc}-`> : CamelToKebabImpl<Rest, "post-letter", `${Acc}${C}`> : Acc;
|
|
317
|
+
/**
|
|
318
|
+
* Three-way classification used by `CamelToKebab`:
|
|
319
|
+
* - "lower" — a lowercase letter (a-z and Unicode lowercase)
|
|
320
|
+
* - "upper" — an uppercase letter (A-Z and Unicode uppercase)
|
|
321
|
+
* - "non-letter" — digit, dot, dash, etc. (Lowercase==Uppercase for them)
|
|
322
|
+
*/
|
|
323
|
+
type CharKind<C extends string> = C extends Lowercase<C> ? (C extends Uppercase<C> ? "non-letter" : "lower") : "upper";
|
|
324
|
+
/**
|
|
325
|
+
* Builds the qualified event-name from feature + inner-name in the same
|
|
326
|
+
* shape the runtime emits via `qn(toKebab(feature), "event", toKebab(inner))`.
|
|
327
|
+
*/
|
|
328
|
+
export type QualifiedEventName<TFeature extends string, TInner extends string> = `${CamelToKebab<TFeature>}:event:${CamelToKebab<TInner>}`;
|
|
329
|
+
export type EventPiiAbsentSubject = "plaintext" | "tenant";
|
|
330
|
+
export type EventPiiSubject = {
|
|
331
|
+
readonly personal: {
|
|
332
|
+
readonly of: string;
|
|
333
|
+
readonly whenAbsent?: EventPiiAbsentSubject;
|
|
334
|
+
};
|
|
335
|
+
} | {
|
|
336
|
+
readonly personal: "tenant";
|
|
337
|
+
} | {
|
|
338
|
+
readonly personal: "self";
|
|
339
|
+
} | {
|
|
340
|
+
/** @deprecated use `{ personal: { of: "<ownerField>" } }` instead. */
|
|
341
|
+
readonly subjectField: string;
|
|
342
|
+
};
|
|
343
|
+
export type EventPiiFields = Readonly<Record<string, EventPiiSubject>>;
|
|
344
|
+
export type NormalizedEventPiiSubject = {
|
|
345
|
+
readonly kind: "user";
|
|
346
|
+
readonly ownerField: string;
|
|
347
|
+
readonly whenAbsent: EventPiiAbsentSubject | undefined;
|
|
348
|
+
} | {
|
|
349
|
+
readonly kind: "tenant";
|
|
350
|
+
} | {
|
|
351
|
+
readonly kind: "self";
|
|
352
|
+
};
|
|
353
|
+
export declare function normalizeEventPiiSubject(spec: EventPiiSubject): NormalizedEventPiiSubject;
|
|
354
|
+
export type EventPiiStance = EventPiiFields | "none";
|
|
355
|
+
export type EventDef<TPayload = unknown, TName extends string = string> = {
|
|
356
|
+
readonly name: TName;
|
|
357
|
+
readonly schema: ZodType<TPayload>;
|
|
358
|
+
readonly version: number;
|
|
359
|
+
readonly piiFields?: EventPiiStance;
|
|
360
|
+
};
|
|
361
|
+
export type AppendEventArgs = {
|
|
362
|
+
readonly aggregateId: string;
|
|
363
|
+
readonly aggregateType: string;
|
|
364
|
+
readonly type: string;
|
|
365
|
+
readonly payload: unknown;
|
|
366
|
+
readonly headers?: Readonly<Record<string, string | number | boolean>>;
|
|
367
|
+
};
|
|
368
|
+
export type TypedAppendEventArgs<TMap extends object, K extends keyof TMap> = {
|
|
369
|
+
readonly aggregateId: string;
|
|
370
|
+
readonly aggregateType: string;
|
|
371
|
+
readonly type: K;
|
|
372
|
+
readonly payload: TMap[K];
|
|
373
|
+
readonly headers?: Readonly<Record<string, string | number | boolean>>;
|
|
374
|
+
};
|
|
375
|
+
export type AppendEventFn<TMap extends object = KumikoEventTypeMap> = <K extends keyof TMap>(args: TypedAppendEventArgs<TMap, K>) => Promise<void>;
|
|
376
|
+
export type UnsafeAppendEventFn = (args: AppendEventArgs) => Promise<void>;
|
|
377
|
+
export type TryAppendEventResult = {
|
|
378
|
+
readonly ok: true;
|
|
379
|
+
readonly event: import("./event-store-types.js").StoredEvent;
|
|
380
|
+
} | {
|
|
381
|
+
readonly ok: false;
|
|
382
|
+
readonly conflict: import("./event-store-types.js").VersionConflict;
|
|
383
|
+
};
|
|
384
|
+
export type TryAppendEventFn = (args: AppendEventArgs) => Promise<TryAppendEventResult>;
|
|
385
|
+
export type FetchForWritingArgs = {
|
|
386
|
+
readonly aggregateId: string;
|
|
387
|
+
readonly aggregateType: string;
|
|
388
|
+
readonly expectedVersion?: number;
|
|
389
|
+
};
|
|
390
|
+
export type AggregateStreamHandle = {
|
|
391
|
+
readonly events: readonly import("./event-store-types.js").StoredEvent[];
|
|
392
|
+
readonly version: number;
|
|
393
|
+
readonly appendOne: (args: {
|
|
394
|
+
readonly type: string;
|
|
395
|
+
readonly payload: unknown;
|
|
396
|
+
}) => Promise<void>;
|
|
397
|
+
readonly hasEvent: (type: string) => boolean;
|
|
398
|
+
};
|
|
399
|
+
export type EventUpcastCtx = {
|
|
400
|
+
readonly db: import("./db-connection.js").DbRunner;
|
|
401
|
+
readonly tenantId: import("./identifiers.js").TenantId;
|
|
402
|
+
};
|
|
403
|
+
export type EventUpcastFn = (payload: unknown, ctx: EventUpcastCtx) => unknown | Promise<unknown>;
|
|
404
|
+
export type DeclarativeEventMigration = {
|
|
405
|
+
readonly rename?: Readonly<Record<string, string>>;
|
|
406
|
+
readonly default?: Readonly<Record<string, unknown>>;
|
|
407
|
+
readonly map?: Readonly<Record<string, (value: unknown) => unknown>>;
|
|
408
|
+
};
|
|
409
|
+
export type EventMigrationDef = {
|
|
410
|
+
readonly eventName: string;
|
|
411
|
+
readonly fromVersion: number;
|
|
412
|
+
readonly toVersion: number;
|
|
413
|
+
readonly transform: EventUpcastFn;
|
|
414
|
+
};
|
|
415
|
+
export type NameOrRef = string | {
|
|
416
|
+
readonly name: string;
|
|
417
|
+
};
|
|
418
|
+
export type EntityRef = {
|
|
419
|
+
readonly name: string;
|
|
420
|
+
readonly table: string;
|
|
421
|
+
};
|
|
422
|
+
export type HandlerRef = {
|
|
423
|
+
readonly name: string;
|
|
424
|
+
};
|
|
425
|
+
export type RateLimitPer = "user" | "tenant" | "ip" | "user+handler" | "tenant+handler" | "ip+handler";
|
|
426
|
+
export type RateLimitOption = {
|
|
427
|
+
readonly per: RateLimitPer;
|
|
428
|
+
readonly limit: number;
|
|
429
|
+
readonly windowSeconds: number;
|
|
430
|
+
readonly cost?: number;
|
|
431
|
+
};
|
|
432
|
+
export type RateLimitDisabled = {
|
|
433
|
+
readonly disabled: true;
|
|
434
|
+
readonly reason: string;
|
|
435
|
+
};
|
|
436
|
+
export type RateLimitDeclaration = RateLimitOption | RateLimitDisabled;
|
|
437
|
+
export declare function isRateLimitDisabled(v: RateLimitDeclaration | undefined): v is RateLimitDisabled;
|
|
438
|
+
export type AgentRisk = "low" | "mid" | "high";
|
|
439
|
+
/** Per-handler hints for the AI-agent manifest. `expose` overrides the
|
|
440
|
+
* default derived from `description`; `risk` overrides the per-kind default. */
|
|
441
|
+
export type AgentHandlerHints = {
|
|
442
|
+
readonly expose?: boolean;
|
|
443
|
+
readonly risk?: AgentRisk;
|
|
444
|
+
};
|
|
445
|
+
export type AgentExposure = {
|
|
446
|
+
readonly expose: boolean;
|
|
447
|
+
readonly risk: AgentRisk;
|
|
448
|
+
};
|
|
449
|
+
export type WriteHandlerDef = {
|
|
450
|
+
readonly name: string;
|
|
451
|
+
readonly schema: ZodType;
|
|
452
|
+
readonly handler: WriteHandlerFn;
|
|
453
|
+
readonly access: AccessRule;
|
|
454
|
+
readonly description?: string;
|
|
455
|
+
readonly agent?: AgentHandlerHints;
|
|
456
|
+
readonly unsafeSkipTransitionGuard?: boolean;
|
|
457
|
+
readonly rateLimit?: RateLimitDeclaration;
|
|
458
|
+
readonly escapeHatch?: EscapeHatchDeclaration;
|
|
459
|
+
readonly perform?: import("./step.js").PipelineDef;
|
|
460
|
+
};
|
|
461
|
+
export declare const ENTITY_CONVENTION_QUERY_BRAND = "__kumikoEntityConventionQuery";
|
|
462
|
+
export type QueryHandlerDef = {
|
|
463
|
+
readonly name: string;
|
|
464
|
+
readonly schema: ZodType;
|
|
465
|
+
readonly handler: QueryHandlerFn;
|
|
466
|
+
/** Set only by defineEntityQueryHandler, which wires the parent-ref
|
|
467
|
+
* read-gate. The boot-validator requires it on a `parentRef` entity's
|
|
468
|
+
* list/detail handler — see boot-validator/parent-ref.ts. */
|
|
469
|
+
readonly [ENTITY_CONVENTION_QUERY_BRAND]?: true;
|
|
470
|
+
readonly access: AccessRule;
|
|
471
|
+
readonly description?: string;
|
|
472
|
+
readonly agent?: AgentHandlerHints;
|
|
473
|
+
readonly rateLimit?: RateLimitDeclaration;
|
|
474
|
+
/** Zod schema of the handler's actual return value — the paged envelope
|
|
475
|
+
* `{ rows, nextCursor, total? }` for a `definePagedQueryHandler`, or the
|
|
476
|
+
* flat record (optionally `.nullable()`) for a plain query handler.
|
|
477
|
+
* Optional and purely additive: absent on every existing handler, and
|
|
478
|
+
* the boot-validator skips any column-reference check that would need
|
|
479
|
+
* it (screens.ts projectionList/relatedList `columns`, projectionDetail
|
|
480
|
+
* `header`/`metrics`, dashboard `valueField`/`subField`/etc.) rather
|
|
481
|
+
* than requiring it retroactively. See fw#2493. */
|
|
482
|
+
readonly outputSchema?: ZodType;
|
|
483
|
+
readonly escapeHatch?: EscapeHatchDeclaration;
|
|
484
|
+
};
|
|
485
|
+
export type StreamHandlerDef = {
|
|
486
|
+
readonly name: string;
|
|
487
|
+
readonly schema: ZodType;
|
|
488
|
+
readonly handler: StreamHandlerFn;
|
|
489
|
+
readonly access: AccessRule;
|
|
490
|
+
readonly rateLimit?: RateLimitDeclaration;
|
|
491
|
+
readonly escapeHatch?: EscapeHatchDeclaration;
|
|
492
|
+
};
|
|
493
|
+
export {};
|