@cosmicdrift/kumiko-types 0.353.0 → 0.354.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/dist/config.d.ts CHANGED
@@ -173,6 +173,9 @@ export type JobDefinition = {
173
173
  readonly messageKey: string;
174
174
  readonly subjectFields?: readonly string[] | undefined;
175
175
  } | undefined;
176
+ readonly tenantVisibleRun?: {
177
+ readonly subjectFields?: readonly string[] | undefined;
178
+ } | undefined;
176
179
  };
177
180
  export type NotificationRecipientFn = (result: import("./hooks.js").SaveContext) => string | readonly string[] | {
178
181
  readonly tenant: string;
@@ -13,4 +13,7 @@ export type CursorResult<T> = {
13
13
  /** Optional total row count — only present when the caller sets
14
14
  * `totalCount: true` on the query. */
15
15
  total?: number;
16
+ /** Set when the search backend returned as many candidates as it can in one
17
+ * response, so matches beyond that may be missing from `rows`. */
18
+ searchTruncated?: true;
16
19
  };
@@ -9,13 +9,11 @@ export type EntityHandlerOptions = {
9
9
  * otherwise tenant-scoped entity. Every use reports an
10
10
  * `acknowledge-cross-tenant` escape-hatch audit event. On write handlers
11
11
  * update/delete/restore address the target row's own tenant stream.
12
- * `access` stays the only caller gate. Unlike `escapeHatch` on a
12
+ * `access` stays the only caller gate, except that a write handler's
13
+ * `access` must be SystemAdmin-only. Unlike `escapeHatch` on a
13
14
  * hand-written handler this does NOT grant `ctx.db.unsafeRaw`,
14
15
  * `db.global()` writes or identity switches. */
15
16
  readonly escapeHatch?: EscapeHatchDeclaration;
16
- /** @deprecated Use `escapeHatch: { reason }` — removed in a future release;
17
- * run `scripts/codemod/migrate-cross-tenant.ts`. */
18
- readonly crossTenant?: boolean;
19
17
  };
20
18
  /** Options for the generic create/update handlers. */
21
19
  export type EntityWriteHandlerOptions = EntityHandlerOptions & {
@@ -1,3 +1,4 @@
1
+ /// <reference types="temporal-polyfill/global" preserve="true" />
1
2
  import type { EntityRelations } from "./relations.js";
2
3
  import type { EntityTenancy } from "./tenancy-brand.js";
3
4
  export type PgType = "uuid" | "text" | "boolean" | "integer" | "double precision" | "bigint" | "serial" | "bigserial" | "jsonb" | "timestamptz" | "timestamptz(3)" | "date" | `numeric(${number},${number})`;
@@ -1,3 +1,4 @@
1
+ /// <reference types="temporal-polyfill/global" preserve="true" />
1
2
  // Plain-data types for EntityTableMeta — split from the runtime
2
3
  // (deriveEntityTableMeta, resolveTableName, defineUnmanagedTable) in
3
4
  // entity-table-meta.ts. Prep step for the types-only package extraction
@@ -1,3 +1,4 @@
1
+ /// <reference types="temporal-polyfill/global" preserve="true" />
1
2
  import type { TenantId } from "./identifiers.js";
2
3
  export interface VersionConflict extends Error {
3
4
  readonly aggregateId: string;
package/dist/fields.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ /// <reference types="temporal-polyfill/global" preserve="true" />
1
2
  import type { VariantSpec } from "./derivatives-types.js";
2
3
  import type { OwnershipMap } from "./ownership.js";
3
4
  import type { EntityTenancy } from "./tenancy-brand.js";
@@ -186,6 +187,24 @@ export declare function isOptionsQueryFieldRef(value: OptionsQueryPayloadValue):
186
187
  readonly field: string;
187
188
  };
188
189
  export declare function optionsQueryFieldRefs(payload: OptionsQueryPayload | undefined): string[];
190
+ export type FieldCondition = boolean | {
191
+ readonly field: string;
192
+ readonly eq: unknown;
193
+ } | {
194
+ readonly field: string;
195
+ readonly ne: unknown;
196
+ } | {
197
+ readonly field: string;
198
+ readonly in: readonly unknown[];
199
+ } | {
200
+ readonly field: string;
201
+ readonly notIn: readonly unknown[];
202
+ };
203
+ /** Options of a select field that are only available while `when` holds for the row values. */
204
+ export type SelectConditionalOptions<TOption extends string = string> = {
205
+ readonly options: readonly TOption[];
206
+ readonly when: Exclude<FieldCondition, boolean>;
207
+ };
189
208
  export type SelectFieldDef<TOptions extends readonly string[] = readonly string[]> = {
190
209
  readonly type: "select";
191
210
  readonly description?: string;
@@ -225,6 +244,10 @@ export type SelectFieldDef<TOptions extends readonly string[] = readonly string[
225
244
  * are ignored. Static `options` stay authoritative, and the write path must enforce
226
245
  * the same rule (see `withTierOptionGate`), the renderer only mirrors it. */
227
246
  readonly optionsAvailabilityQuery?: string;
247
+ /** Options that are only available while `when` holds for the row values; options
248
+ * in no rule are always available. The write path enforces it, the renderer only
249
+ * filters. Only valid on entity fields. */
250
+ readonly conditionalOptions?: readonly SelectConditionalOptions<TOptions[number]>[];
228
251
  } & ResolvedPiiFlags;
229
252
  export type MultiSelectFieldDef<TOptions extends readonly string[] = readonly string[]> = {
230
253
  readonly type: "multiSelect";
@@ -407,6 +430,12 @@ export type ReferenceFieldDef = {
407
430
  * the read-only display resolves a stored value against these rows and
408
431
  * falls back to the raw id for one it does not find. */
409
432
  readonly optionsQuery?: string;
433
+ /** tenant-handover opt-out: rows of THIS entity that point at a handed-over
434
+ * row through this field stay in the source tenant instead of travelling
435
+ * with it (or failing the claim with `entity_not_transferable`). The
436
+ * reference then deliberately crosses the tenant boundary after the
437
+ * handover. Use it for an entity that must not move with its host. */
438
+ readonly handover?: "stay";
410
439
  } & ResolvedPiiFlags;
411
440
  export type DefaultCurrency = "EUR" | "USD" | "GBP" | "CHF" | "JPY" | "SEK" | "NOK" | "DKK" | "PLN" | "CZK" | "CAD" | "AUD" | "NZD" | "CNY" | "INR";
412
441
  type EmbeddedSubFieldBase = {
package/dist/fields.js CHANGED
@@ -1,3 +1,4 @@
1
+ /// <reference types="temporal-polyfill/global" preserve="true" />
1
2
  // --- Field Types ---
2
3
  export const SELECT_OPTION_TONES = ["ok", "warn", "bad", "neutral"];
3
4
  export function isOptionsQueryFieldRef(value) {
@@ -1,3 +1,4 @@
1
+ /// <reference types="temporal-polyfill/global" preserve="true" />
1
2
  import type { Redis } from "ioredis";
2
3
  import type { ZodType } from "zod";
3
4
  import type { CacheSyncBus } from "./cache-sync-types.js";
@@ -254,6 +255,7 @@ export type AppContext = SharedContextFields & {
254
255
  export type HandlerContext<TMap extends object = KumikoEventTypeMap> = SharedContextFields & {
255
256
  readonly db: TenantDb;
256
257
  readonly dbOutsideTransaction: TenantDb | undefined;
258
+ readonly outsideTransaction?: <T>(fn: (db: TenantDb) => Promise<T>) => Promise<T>;
257
259
  readonly systemDb?: UncheckedSystemDb;
258
260
  readonly registry: Registry;
259
261
  /** Aktiver SessionUser des Handler-Aufrufs — Convenience-Alias zu
@@ -50,8 +50,10 @@ export type HttpRouteDefinition = {
50
50
  /** URL-Pfad (Hono-Pattern, z.B. "/feed.xml" oder "/og/:tenantId.png"). */
51
51
  readonly path: string;
52
52
  /** true = public, no session required. false = mounted behind the
53
- * session auth chain (no anonymous fallthrough, PAT rate limit,
54
- * origin + CSRF guards) — a request without a session gets 401. The
53
+ * session auth chain (global IP rate limit when configured, PII
54
+ * ciphertext tripwire, no anonymous fallthrough, origin + CSRF guards;
55
+ * PATs are rejected). requestId, body limit and observability are the
56
+ * `/api/*` chain only. A request without a session gets 401. The
55
57
  * handler reads the caller via getUser(c). */
56
58
  readonly anonymous: boolean;
57
59
  /** Hono-Handler. Bekommt Hono-Context + Framework-Deps; returnt
@@ -1,3 +1,4 @@
1
+ /// <reference types="temporal-polyfill/global" preserve="true" />
1
2
  import type { DerivativesContext } from "./derivatives-types.js";
2
3
  import type { StoredEvent } from "./event-store-types.js";
3
4
  import type { KumikoEventTypeMap } from "./event-type-map.js";
@@ -1,3 +1,4 @@
1
+ /// <reference types="temporal-polyfill/global" preserve="true" />
1
2
  import type { Temporal } from "./temporal.js";
2
3
  export type RateLimitDecision = {
3
4
  readonly allowed: boolean;
package/dist/screen.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { FieldIconKey } from "./field-icon.js";
2
- import type { FieldDefinition, FormFieldDefinition, SelectOptionTone } from "./fields.js";
2
+ import type { FieldCondition, FieldDefinition, FormFieldDefinition, SelectOptionTone } from "./fields.js";
3
3
  import type { AccessRule, AgentScreenHints } from "./handlers.js";
4
4
  import type { IconKey, NavIconKey } from "./nav-icon.js";
5
5
  export type { FieldIconKey } from "./field-icon.js";
@@ -62,19 +62,7 @@ export type FormatSpec = {
62
62
  } & FieldFormatRegistry[K];
63
63
  }[keyof FieldFormatRegistry];
64
64
  export type FieldRenderer = PlatformComponent | string | FormatSpec;
65
- export type FieldCondition = boolean | {
66
- readonly field: string;
67
- readonly eq: unknown;
68
- } | {
69
- readonly field: string;
70
- readonly ne: unknown;
71
- } | {
72
- readonly field: string;
73
- readonly in: readonly unknown[];
74
- } | {
75
- readonly field: string;
76
- readonly notIn: readonly unknown[];
77
- };
65
+ export type { FieldCondition } from "./fields.js";
78
66
  export type ListColumnSpec = string | {
79
67
  readonly field: string;
80
68
  readonly renderer?: FieldRenderer;
@@ -88,6 +76,12 @@ export type ListColumnSpec = string | {
88
76
  * label; without one it is rejected at boot as an unknown field. `field`
89
77
  * is then just a stable column key (pick any unique slug). */
90
78
  readonly label?: string;
79
+ /** Marks a column on a query-backed list (projectionList, relatedList,
80
+ * dashboard list, expandableRow) as drawn by a renderer rather than read
81
+ * from a row field. Without it, a query that declares an `outputSchema`
82
+ * must return `field`; a `label` alone does not exempt the column, since
83
+ * nearly every column carries one. */
84
+ readonly virtual?: boolean;
91
85
  /** Marks this column as a reference lookup instead of a plain value —
92
86
  * for projectionList/relatedList columns, which have no
93
87
  * `EntityDefinition` to carry a real `reference` field type. Same
@@ -406,6 +400,8 @@ export type EntityListScreenDefinition = {
406
400
  readonly entity: string;
407
401
  /** Short screen id (same feature) the create button opens instead of the entity's default edit screen. */
408
402
  readonly createScreen?: string;
403
+ /** Set by the role projection when `createScreen` is not reachable for the role: the renderer then shows no create button instead of falling back to the entity's edit screen. Not for app authors. */
404
+ readonly createUnavailable?: boolean;
409
405
  readonly columns: readonly ListColumnSpec[];
410
406
  readonly rowRenderer?: PlatformComponent;
411
407
  readonly cardRenderer?: PlatformComponent;
@@ -747,6 +743,8 @@ export type DashboardChartTone = "positive" | "negative" | "active" | "neutral";
747
743
  export type DashboardChartMarkerKind = {
748
744
  readonly tone?: DashboardChartTone;
749
745
  readonly color?: string;
746
+ /** i18n key; with `markerLegend: "legend"` the chart legend lists the markers of this kind under it. */
747
+ readonly label?: string;
750
748
  };
751
749
  /** One option of a stacked-area range switch. Without `months` the option
752
750
  * shows every bucket; with it, a window of that many months anchored at
@@ -787,6 +785,15 @@ export type DashboardChartPanel = DashboardPanelQueryOptions & DashboardPanelEmp
787
785
  readonly ranges?: DashboardChartRanges;
788
786
  /** Only for chart "stacked-area": scrubber under the plot to drag the visible window; starts at today. */
789
787
  readonly brush?: boolean;
788
+ /** Only for chart "stacked-area": date format of axis and marker labels.
789
+ * Default automatic: day and month below 18 visible months, month and year above. */
790
+ readonly dateFormat?: "day" | "month";
791
+ /** Only for chart "stacked-area": window the uncontrolled chart starts in.
792
+ * "from-today" starts at today even when `ranges.default` is set. Default "default-range". */
793
+ readonly initialWindow?: "default-range" | "from-today";
794
+ /** Only for chart "stacked-area": "legend" drops the numbered marker list; pins become
795
+ * plain dots with a tooltip and the legend lists marker kinds (see `markerKinds[].label`). Default "list". */
796
+ readonly markerLegend?: "list" | "legend";
790
797
  };
791
798
  export type DashboardListPanel = DashboardPanelQueryOptions & DashboardPanelEmptyState & DashboardPanelGate & {
792
799
  readonly kind: "list";
@@ -1046,7 +1053,9 @@ export type EditRelatedListSection = {
1046
1053
  * of a bespoke child-rows handler. Mutually exclusive with `parentParam`
1047
1054
  * (the boot-validator rejects both). `field` must be a real field on the
1048
1055
  * entity behind `query`, and that query's Zod schema must accept
1049
- * `filter` (same requirement `filter`/`facets` already have). */
1056
+ * `filter` (same requirement `filter`/`facets` already have). The filter is
1057
+ * client-supplied: any caller may omit it, so the bound query must authorize
1058
+ * the ENTIRE row set it can return, not just the parent's children. */
1050
1059
  readonly parentFilter?: {
1051
1060
  readonly field: string;
1052
1061
  };
@@ -1313,6 +1322,10 @@ export type ActionFormScreenDefinition = {
1313
1322
  readonly fallback?: string;
1314
1323
  /** Derived by buildAppSchema — see EntityEditScreenDefinition.urlPrefillFields. */
1315
1324
  readonly urlPrefillFields?: readonly string[];
1325
+ /** Submit is enabled without edits: values seeded from navigate `params` count as the
1326
+ * user's intent. Every required field the layout hides with `visible: false` must hold a
1327
+ * value, otherwise submit stays disabled (boot-checked against navigate `params`). */
1328
+ readonly submitPrefilled?: boolean;
1316
1329
  /** Write-Handler-QN der bei Submit gerufen wird. Form-Object landet
1317
1330
  * 1:1 als payload — Handler-Schema (Zod) validiert weiter. */
1318
1331
  readonly handler: string;
@@ -1481,6 +1494,10 @@ export type SecretMintScreenDefinition = {
1481
1494
  readonly fallback?: string;
1482
1495
  /** Derived by buildAppSchema — see EntityEditScreenDefinition.urlPrefillFields. */
1483
1496
  readonly urlPrefillFields?: readonly string[];
1497
+ /** Submit is enabled without edits: values seeded from navigate `params` count as the
1498
+ * user's intent. Every required field the layout hides with `visible: false` must hold a
1499
+ * value, otherwise submit stays disabled (boot-checked against navigate `params`). */
1500
+ readonly submitPrefilled?: boolean;
1484
1501
  /** Write-handler QN dispatched on submit. */
1485
1502
  readonly handler: string;
1486
1503
  readonly fields: Readonly<Record<string, FormFieldDefinition>>;
@@ -1,3 +1,4 @@
1
+ /// <reference types="temporal-polyfill/global" preserve="true" />
1
2
  import type { TenantId } from "./identifiers.js";
2
3
  declare const SecretBrand: unique symbol;
3
4
  export type Secret<T = string> = {
@@ -1,3 +1,4 @@
1
+ /// <reference types="temporal-polyfill/global" preserve="true" />
1
2
  // Envelope Encryption types. Separating DEK (per-value) from KEK (central)
2
3
  // is what makes key rotation cheap: on rotation we only re-wrap the small
3
4
  // encryptedDek, never touch the ciphertext.
@@ -1,11 +1,16 @@
1
1
  import type { TargetRef } from "./target-ref.js";
2
2
  export type TreeNodeState = "filled" | "stub" | "empty" | "loading" | "error";
3
- export type TreeAction = {
3
+ type TreeActionBase = {
4
4
  readonly icon: string;
5
5
  readonly label: string;
6
- readonly screen?: string;
7
- readonly target?: TargetRef;
8
6
  };
7
+ export type TreeAction = TreeActionBase & ({
8
+ readonly screen: string;
9
+ readonly target?: never;
10
+ } | {
11
+ readonly target: TargetRef;
12
+ readonly screen?: never;
13
+ });
9
14
  export type TreeNode = {
10
15
  readonly label: string;
11
16
  readonly icon?: string;
@@ -24,3 +29,4 @@ export type TreeActionsHandle<TFeature extends string, TActions extends Record<s
24
29
  readonly id: TFeature;
25
30
  readonly treeActions: TActions;
26
31
  };
32
+ export {};
@@ -1,3 +1,4 @@
1
+ /// <reference types="temporal-polyfill/global" preserve="true" />
1
2
  import type { GeoAddress, GeoCoordinates, GeoTzProvider } from "./geo-tz.js";
2
3
  export type LocatedTimestampJson = {
3
4
  /** Wall-clock ISO without offset, e.g. "2026-04-03T10:00:00" */
@@ -1,3 +1,4 @@
1
+ /// <reference types="temporal-polyfill/global" preserve="true" />
1
2
  // TzContext — the type contract for ctx.tz (pure types; the factory lives in
2
3
  // @cosmicdrift/kumiko-framework, time/tz-context.ts).
3
4
  //
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-types",
3
- "version": "0.353.0",
3
+ "version": "0.354.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>",
@@ -276,7 +276,7 @@
276
276
  },
277
277
  "peerDependencies": {
278
278
  "hono": "^4.13.1",
279
- "postgres": "npm:@bender0oo0/postgres@3.4.9-kumiko.1",
279
+ "postgres": "^3.4.9-0",
280
280
  "temporal-polyfill": "^0.3.2",
281
281
  "zod": "^4.4.3",
282
282
  "ioredis": "^5.10.1"