@cosmicdrift/kumiko-types 0.184.0 → 0.186.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-types",
3
- "version": "0.184.0",
3
+ "version": "0.186.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/fields.ts CHANGED
@@ -400,13 +400,31 @@ type EmbeddedSubFieldBase = {
400
400
  * could describe. */
401
401
  export type EmbeddedSubFieldDef =
402
402
  | (EmbeddedSubFieldBase & {
403
- readonly type: "text" | "number" | "boolean" | "date" | "money";
403
+ readonly type: "text" | "number" | "boolean" | "date" | "money" | "timestamp";
404
404
  })
405
405
  | (EmbeddedSubFieldBase & {
406
406
  readonly type: "decimal";
407
407
  readonly scale: number;
408
+ })
409
+ | (EmbeddedSubFieldBase & {
410
+ readonly type: "select";
411
+ readonly options: readonly string[];
412
+ })
413
+ | (EmbeddedSubFieldBase & {
414
+ readonly type: "reference";
415
+ readonly entity: string;
416
+ readonly labelField?: string;
408
417
  });
409
418
 
419
+ /** A cell computed from other cells of the same row. `from` names the
420
+ * sub-fields the operation reads (order matters for `subtract`). Purely
421
+ * renderer metadata — the derived value is still validated like any other
422
+ * value of its declared sub-field type in `schema`. */
423
+ export type EmbeddedDerivedCellDef = {
424
+ readonly op: "multiply" | "sum" | "subtract";
425
+ readonly from: readonly string[];
426
+ };
427
+
410
428
  export type EmbeddedFieldDef = {
411
429
  readonly type: "embedded";
412
430
  readonly required?: boolean;
@@ -424,6 +442,21 @@ export type EmbeddedFieldDef = {
424
442
  * the head — an embedded array is rewritten whole on every change and has
425
443
  * no per-row history. */
426
444
  readonly multiple?: boolean;
445
+ /** Minimum row count for an embedded list. Only valid with `multiple: true`. */
446
+ readonly minItems?: number;
447
+ /** Maximum row count for an embedded list. Only valid with `multiple: true`. */
448
+ readonly maxItems?: number;
449
+ /** Renderer metadata: sub-field name → how to compute its cell from other
450
+ * sub-fields of the same row. Only valid with `multiple: true`. */
451
+ readonly derived?: Readonly<Record<string, EmbeddedDerivedCellDef>>;
452
+ /** Renderer metadata: numeric sub-field names to sum in a totals row. Only
453
+ * valid with `multiple: true`. */
454
+ readonly totals?: readonly string[];
455
+ /** Maps an embedded-list subfield name to a sibling top-level money field
456
+ * name — the sum of that subfield across all rows must equal the sibling
457
+ * field's amount. Validated both client- and server-side (schema-builder
458
+ * superRefine). Only meaningful with `multiple: true`. */
459
+ readonly totalsMatch?: Readonly<Record<string, string>>;
427
460
  } & PiiAnnotations;
428
461
 
429
462
  // Free-form jsonb — keys/shape NOT validated at write-time. Use for:
package/src/handlers.ts CHANGED
@@ -338,6 +338,9 @@ export type AppContext = SharedContextFields & {
338
338
  // type-map (runtime-pluggable events) uses `unsafeAppendEvent`.
339
339
  export type HandlerContext<TMap extends object = KumikoEventTypeMap> = SharedContextFields & {
340
340
  readonly db: TenantDb;
341
+ // Same tenant scoping as `db`, but never bound to the handler's tx: writes
342
+ // through it survive a rollback, for side effects that already happened outside the DB.
343
+ readonly dbOutsideTransaction: TenantDb;
341
344
  readonly registry: Registry;
342
345
  /** Aktiver SessionUser des Handler-Aufrufs — Convenience-Alias zu
343
346
  * `event.user`. Existiert weil Handler intuitiv `ctx.user.tenantId`
@@ -501,6 +504,20 @@ export type HandlerContext<TMap extends object = KumikoEventTypeMap> = SharedCon
501
504
  // Feature code can call ctx.metrics.inc(...) / ctx.tracer.startSpan(...)
502
505
  // without null-checks.
503
506
  readonly metrics: MetricsHandle;
507
+
508
+ // For shared/library code invoked from many features' HandlerContext
509
+ // (e.g. a helper package called by several consumer features): binds to
510
+ // `featureName` instead of the dispatching handler's own feature, so the
511
+ // library counts under one stable kumiko_<featureName>_x name instead of
512
+ // splintering per caller. `featureName` accepts the same kebab-case form
513
+ // used as the feature's own name at defineFeature() — normalized to
514
+ // snake_case internally before resolving the metric name.
515
+ //
516
+ // Unlike ctx.metrics, an unregistered metric name here is a silent
517
+ // no-op, not a throw (framework#1844) — this handle is meant for
518
+ // error/catch-path counters in shared code, where a missing registration
519
+ // must not turn an already-swallowed error into a thrown one.
520
+ readonly metricsFor: (featureName: string) => MetricsHandle;
504
521
  readonly tracer: Tracer;
505
522
 
506
523
  // Time + TZ helper. Feature code MUST go through this instead of