@cosmicdrift/kumiko-types 0.329.0 → 0.330.2

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.
@@ -0,0 +1,25 @@
1
+ export type AggregateMeasure = {
2
+ readonly fn: "count";
3
+ } | {
4
+ readonly fn: "countDistinct" | "sum" | "avg";
5
+ readonly field: string;
6
+ };
7
+ export type AggregateTimeBucket = "hour" | "day";
8
+ export type AggregateDimension = {
9
+ readonly field: string;
10
+ } | {
11
+ readonly field: string;
12
+ readonly bucket: AggregateTimeBucket;
13
+ readonly timeZone: string;
14
+ };
15
+ export type AggregateSpec = {
16
+ readonly measure: AggregateMeasure;
17
+ readonly groupBy?: readonly AggregateDimension[];
18
+ readonly orderByValue?: "asc" | "desc";
19
+ readonly limit?: number;
20
+ };
21
+ export type AggregateKey = string | number | boolean | null;
22
+ export type AggregateRow = {
23
+ readonly keys: readonly AggregateKey[];
24
+ readonly value: number | null;
25
+ };
@@ -0,0 +1 @@
1
+ export {};
package/dist/screen.d.ts CHANGED
@@ -113,7 +113,15 @@ export type ListColumnSpec = string | {
113
113
  * `md` breakpoint (tables keep it). For columns that only make sense
114
114
  * next to the others, like a sort key. */
115
115
  readonly hideOnNarrow?: boolean;
116
+ /** Dashboard list panels only. "bar": field holds a 0..1 fraction, drawn
117
+ * as bar + percent. "badge": field holds a label, drawn as a pill whose
118
+ * tone comes from `badgeToneField`. Other list renderers ignore it. */
119
+ readonly display?: ListColumnDisplay;
120
+ /** Row field naming the badge tone; only with `display: "badge"`. */
121
+ readonly badgeToneField?: string;
116
122
  };
123
+ export type ListColumnDisplay = "bar" | "badge";
124
+ export type ListBadgeTone = "positive" | "warn" | "negative" | "neutral";
117
125
  export type ListPaginationMode = "pages" | "infinite" | false;
118
126
  export type ListSortDir = "asc" | "desc";
119
127
  export type ListSortSpec = {
@@ -322,6 +330,8 @@ export type EntityListScreenDefinition = {
322
330
  * app); exempts it from the nav-area boot check. */
323
331
  readonly dormant?: boolean;
324
332
  readonly entity: string;
333
+ /** Short screen id (same feature) the create button opens instead of the entity's default edit screen. */
334
+ readonly createScreen?: string;
325
335
  readonly columns: readonly ListColumnSpec[];
326
336
  readonly rowRenderer?: PlatformComponent;
327
337
  readonly cardRenderer?: PlatformComponent;
@@ -487,6 +497,8 @@ export type ProjectionDetailScreenDefinition = {
487
497
  * app); exempts it from the nav-area boot check. */
488
498
  readonly dormant?: boolean;
489
499
  readonly query: string;
500
+ /** Query output field whose value titles the page header (breadcrumb) when no `header` is set. */
501
+ readonly recordTitleField?: string;
490
502
  /** Query-payload key for the row-id. Default "id". */
491
503
  readonly idParam?: string;
492
504
  /** The server determines the shown row from the caller's session/context
@@ -530,20 +542,39 @@ export type ProjectionDetailScreenDefinition = {
530
542
  * Set "form" to opt back into the disabled-Input look (fw#2245). */
531
543
  readonly valueDisplay?: "form" | "text";
532
544
  };
533
- export type DashboardStatPanel = {
545
+ export type DashboardPanelQueryOptions = {
546
+ /** Static, author-set query parameters merged on top of the screen's
547
+ * dynamic filterParams — lets a panel pin a value (e.g. a status facet)
548
+ * the screen-wide filter doesn't cover, without needing its own query.
549
+ * The panel wins over the screen filter and the time range. */
550
+ readonly params?: Readonly<Record<string, unknown>>;
551
+ /** The screen `filter` value is NOT merged into this panel's query (a tenant
552
+ * picker must not hit sources without a tenant column). The screen
553
+ * `timeRange` still is. */
554
+ readonly ignoreScreenFilter?: boolean;
555
+ };
556
+ export type DashboardPanelSpan = "half" | "full";
557
+ export type DashboardPanelEmptyState = {
558
+ readonly span?: DashboardPanelSpan;
559
+ readonly emptyLabel?: string;
560
+ /** Second line under `emptyLabel`. */
561
+ readonly emptyHint?: string;
562
+ };
563
+ export type DashboardStatPanel = DashboardPanelQueryOptions & {
534
564
  readonly kind: "stat";
535
- /** Stable id — kebab-case, eindeutig im Panel-Set. */
565
+ /** Stable id: kebab-case, unique within the panel set. */
536
566
  readonly id: string;
537
567
  /** Anzeige-Text (i18n-Key). */
538
568
  readonly label: string;
539
569
  readonly query: string;
540
- /** Static, author-set query parameters merged on top of the screen's
541
- * dynamic filterParams — lets a panel pin a value (e.g. a status facet)
542
- * the screen-wide filter doesn't cover, without needing its own query. */
543
- readonly params?: Readonly<Record<string, unknown>>;
544
570
  readonly valueField: string;
545
571
  readonly subField?: string;
546
572
  readonly toneField?: string;
573
+ /** Fixed tone when `toneField` is unset or yields none; not applied while the value is 0. */
574
+ readonly tone?: "default" | "positive" | "warn" | "negative";
575
+ /** Record field holding `{ atMs, value | null }[]` (MetricResult.points),
576
+ * drawn as a sparkline next to the value. */
577
+ readonly sparklineField?: string;
547
578
  /** Optionaler Delta-Chip (z.B. "↓23 %") neben dem Label. Nur wenn BEIDE
548
579
  * Felder gesetzt sind UND der Query-Handler sie liefert, rendert der Chip
549
580
  * — sonst bleibt die Kachel wie ohne Delta. `deltaToneField` fällt auf
@@ -564,15 +595,20 @@ export type DashboardStatPanel = {
564
595
  * Icon) — ohne icon wird der Wert still verworfen. */
565
596
  readonly accentColor?: string;
566
597
  };
567
- export type DashboardChartPanel = {
598
+ export type DashboardChartKind = "timeseries" | "stacked-bars" | "segment-bars" | "stacked-area";
599
+ export type DashboardChartTone = "positive" | "negative" | "active" | "neutral";
600
+ export type DashboardChartPanel = DashboardPanelQueryOptions & DashboardPanelEmptyState & {
568
601
  readonly kind: "chart";
569
602
  readonly id: string;
570
603
  readonly label: string;
571
- /** v1: geglättete Zeitreihe. Weitere Chart-Formen additiv. */
572
- readonly chart: "timeseries";
604
+ readonly chart: DashboardChartKind;
573
605
  readonly query: string;
606
+ /** i18n key under the title, e.g. "7 days, by creation day". */
607
+ readonly subtitle?: string;
608
+ /** Series/segment key -> tone; unmapped keys fall back to a palette. */
609
+ readonly seriesTones?: Readonly<Record<string, DashboardChartTone>>;
574
610
  };
575
- export type DashboardListPanel = {
611
+ export type DashboardListPanel = DashboardPanelQueryOptions & DashboardPanelEmptyState & {
576
612
  readonly kind: "list";
577
613
  readonly id: string;
578
614
  readonly label: string;
@@ -582,17 +618,16 @@ export type DashboardListPanel = {
582
618
  export type DashboardStatGroupPanel = {
583
619
  readonly kind: "stat-group";
584
620
  readonly id: string;
585
- readonly label: string;
621
+ readonly label?: string;
586
622
  readonly stats: readonly DashboardStatPanel[];
587
623
  };
588
- export type DashboardFeedPanel = {
624
+ export type DashboardFeedPanel = DashboardPanelQueryOptions & DashboardPanelEmptyState & {
589
625
  readonly kind: "feed";
590
626
  readonly id: string;
591
627
  readonly label: string;
592
628
  readonly query: string;
593
- readonly emptyLabel?: string;
594
629
  };
595
- export type DashboardProgressListPanel = {
630
+ export type DashboardProgressListPanel = DashboardPanelQueryOptions & DashboardPanelEmptyState & {
596
631
  readonly kind: "progress-list";
597
632
  readonly id: string;
598
633
  readonly label: string;
@@ -631,6 +666,19 @@ export type DashboardFilterDefinition = {
631
666
  /** Query-Result-Contract: `{ rows: { value: string; label: string }[] }`. */
632
667
  readonly optionsQuery?: string;
633
668
  };
669
+ export type DashboardTimeRangeDefinition = {
670
+ readonly id: string;
671
+ /** `label` is an i18n key. */
672
+ readonly options: readonly {
673
+ readonly value: string;
674
+ readonly label: string;
675
+ }[];
676
+ readonly default: string;
677
+ };
678
+ export type DashboardScopeDefinition = {
679
+ readonly badge: string;
680
+ readonly notice?: string;
681
+ };
634
682
  export type DashboardScreenDefinition = {
635
683
  readonly id: string;
636
684
  readonly type: "dashboard";
@@ -643,6 +691,11 @@ export type DashboardScreenDefinition = {
643
691
  readonly dormant?: boolean;
644
692
  readonly panels: readonly DashboardPanelDefinition[];
645
693
  readonly filter?: DashboardFilterDefinition;
694
+ /** Segmented control in the toolbar; the value lives in URL search param
695
+ * `id` and is merged into EVERY panel query (also ignoreScreenFilter ones). */
696
+ readonly timeRange?: DashboardTimeRangeDefinition;
697
+ /** Marks the screen as spanning more than the caller's own scope. */
698
+ readonly scope?: DashboardScopeDefinition;
646
699
  readonly slots?: ScreenSlots;
647
700
  readonly access?: AccessRule;
648
701
  };
@@ -905,6 +958,8 @@ export type EntityEditScreenDefinition = {
905
958
  * value is overwritten. */
906
959
  readonly urlPrefillFields?: readonly string[];
907
960
  readonly entity: string;
961
+ /** Entity field whose value names the loaded record in the header breadcrumb (edit mode only). */
962
+ readonly recordTitleField?: string;
908
963
  readonly layout: EditLayout;
909
964
  /** Optionaler i18n-Key (oder Roh-String) für den Submit-Button. Default
910
965
  * `kumiko.actions.save`. Lässt den Auto-Edit-Screen domain-spezifische
@@ -1179,6 +1234,9 @@ export type CustomScreenDefinition = {
1179
1234
  export type ConfigEditScreenDefinition = {
1180
1235
  readonly id: string;
1181
1236
  readonly type: "configEdit";
1237
+ /** Default true: the form fills the shell content height with a pinned
1238
+ * footer. `false` restores the card layout with the footer in the flow. */
1239
+ readonly fillHeight?: boolean;
1182
1240
  readonly nav?: ScreenNavSugar;
1183
1241
  readonly detailFor?: string;
1184
1242
  readonly description?: string;
@@ -1,3 +1,4 @@
1
+ import type { AggregateRow, AggregateSpec } from "./aggregate-types.js";
1
2
  import type { DbRunner } from "./db-connection.js";
2
3
  import type { EntityTableMeta } from "./entity-table-meta-types.js";
3
4
  import type { ExecutorOnly, NotExecutorOnly } from "./executor-brand.js";
@@ -44,6 +45,7 @@ export type TenantDb = {
44
45
  selectMany<T = Record<string, unknown>>(table: SchemaTable | EntityTableMeta, where?: WhereObject, options?: SelectOptions): Promise<readonly T[]>;
45
46
  fetchOne<T = Record<string, unknown>>(table: SchemaTable | EntityTableMeta, where: WhereObject): Promise<T | undefined>;
46
47
  count(table: SchemaTable | EntityTableMeta, where?: WhereObject): Promise<number>;
48
+ aggregate(table: SchemaTable | EntityTableMeta, spec: AggregateSpec, where?: WhereObject): Promise<readonly AggregateRow[]>;
47
49
  insertOne<T = Record<string, unknown>>(table: WritableTable, values: Record<string, unknown>): Promise<T | undefined>;
48
50
  updateMany<T = Record<string, unknown>>(table: WritableTable, set: Record<string, unknown>, where: WhereObject): Promise<readonly T[]>;
49
51
  deleteMany(table: WritableTable, where: WhereObject): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-types",
3
- "version": "0.329.0",
3
+ "version": "0.330.2",
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>",
@@ -138,6 +138,10 @@
138
138
  "types": "./dist/where-clause-types.d.ts",
139
139
  "default": "./dist/where-clause-types.js"
140
140
  },
141
+ "./aggregate-types": {
142
+ "types": "./dist/aggregate-types.d.ts",
143
+ "default": "./dist/aggregate-types.js"
144
+ },
141
145
  "./tenant-db-types": {
142
146
  "types": "./dist/tenant-db-types.d.ts",
143
147
  "default": "./dist/tenant-db-types.js"
@@ -393,6 +397,10 @@
393
397
  "types": "./dist/where-clause-types.d.ts",
394
398
  "default": "./dist/where-clause-types.js"
395
399
  },
400
+ "./aggregate-types": {
401
+ "types": "./dist/aggregate-types.d.ts",
402
+ "default": "./dist/aggregate-types.js"
403
+ },
396
404
  "./tenant-db-types": {
397
405
  "types": "./dist/tenant-db-types.d.ts",
398
406
  "default": "./dist/tenant-db-types.js"