@cosmicdrift/kumiko-types 0.386.0 → 0.388.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.
@@ -0,0 +1,19 @@
1
+ import * as z from "zod";
2
+ import { isPlainObject } from "./type-guards.js";
3
+ export const MAX_LIST_AGGREGATE_MEASURES = 20;
4
+ export const LIST_AGGREGATE_MEASURE_KINDS = ["sum", "avg", "count", "min", "max"];
5
+ export const listAggregatePayloadSchema = z.object({
6
+ groupBy: z.string().optional(),
7
+ measures: z
8
+ .array(z.object({ field: z.string(), kind: z.enum(LIST_AGGREGATE_MEASURE_KINDS) }))
9
+ .max(MAX_LIST_AGGREGATE_MEASURES)
10
+ .default([]),
11
+ });
12
+ const LIST_AGGREGATE_RESULT_KEYS = ["groups", "truncated", "searchTruncated"];
13
+ // Closed key set: a row that merely has a `groups` field (jsonb column) must not
14
+ // be mistaken for an aggregate and skip the row-level read filter.
15
+ export function isListAggregateResult(value) {
16
+ return (isPlainObject(value) &&
17
+ Array.isArray(value["groups"]) &&
18
+ Object.keys(value).every((key) => LIST_AGGREGATE_RESULT_KEYS.includes(key)));
19
+ }
@@ -55,7 +55,7 @@ export type ActionFormScreenDefinition = {
55
55
  * validator).
56
56
  *
57
57
  * A `money` field here must name its own currency source: this screen
58
- * has no entity whose `defaultCurrency` it could inherit (fw#2839). */
58
+ * has no entity whose `defaultCurrency` it could inherit. */
59
59
  readonly fields: Readonly<Record<string, FormFieldDefinition>>;
60
60
  /** Fields computed from other fields, shown read-only and recomputed on every
61
61
  * change. A `listSum` over an empty list without `whenEmpty` leaves the field
@@ -109,7 +109,7 @@ export type ActionFormScreenDefinition = {
109
109
  * The object form additionally names the success-payload field the
110
110
  * navigation id comes from (`ActionFormRedirect.idFrom`) — needed when
111
111
  * the handler creates a child record but the target screen is the
112
- * parent's detail screen (fw#2670). */
112
+ * parent's detail screen. */
113
113
  readonly redirect?: string | ActionFormRedirect;
114
114
  /** Links shown in the success box after a successful submit while the
115
115
  * screen stays put. Targets resolve like `redirect` (the id comes from the
@@ -164,7 +164,7 @@ export type ActionFormFooterAction = {
164
164
  * id. The write-handler reports the id of what it wrote (`data.id`); when
165
165
  * that record is a child and the target screen shows its parent, the
166
166
  * parent id has to be read from a different field instead of forcing the
167
- * handler to misreport its own result (fw#2670). */
167
+ * handler to misreport its own result. */
168
168
  export type ActionFormRedirect = {
169
169
  /** Same target forms as the string `redirect`: short screen ID
170
170
  * (same-feature) or a fully-qualified cross-feature screen QN. */
@@ -21,14 +21,13 @@ export type CustomScreenDefinition = {
21
21
  readonly access?: AccessRule;
22
22
  /** This screen is registered without a self-owned `r.nav()` entry by
23
23
  * design — an app opts in by navving it explicitly (e.g. a settings-area
24
- * self-service screen). `createKumikoApp`'s boot diagnostic
25
- * (kumiko-framework#2025) skips dormant screens instead of flagging
26
- * every consumer that doesn't mount the client plugin as a false
27
- * positive (kumiko-framework#2034). Only set this on screens the
28
- * feature itself never navs — a screen the feature DOES nav still needs
29
- * its client plugin mounted by every consumer, and should keep
30
- * triggering the diagnostic if it's missing. Also gates the
31
- * boot-validator's nav-area check, same as `dormant` on other screens. */
24
+ * self-service screen). `createKumikoApp`'s boot diagnostic skips dormant
25
+ * screens instead of flagging every consumer that doesn't mount the client
26
+ * plugin as a false positive. Only set this on screens the feature itself
27
+ * never navs — a screen the feature DOES nav still needs its client plugin
28
+ * mounted by every consumer, and should keep triggering the diagnostic if
29
+ * it's missing. Also gates the boot-validator's nav-area check, same as
30
+ * `dormant` on other screens. */
32
31
  readonly dormant?: boolean;
33
32
  /** UI-only gate, also on direct URL access; handlers still enforce access. Unmet or failed renders `fallback`. */
34
33
  readonly visibleWhen?: DashboardPanelVisibility;
@@ -149,7 +149,7 @@ export type EditExtensionSection = {
149
149
  * surrounding form's Save button should activate for its dirty state.
150
150
  * Omit/false for extensions that persist through their own dispatcher
151
151
  * writes (e.g. notes-history NotesSection) — otherwise a read-only form
152
- * shows a Save button that does nothing (fw#2359). */
152
+ * shows a Save button that does nothing. */
153
153
  readonly contributesToFormSubmit?: boolean;
154
154
  /** Overrides the host-derived entity name passed to the mounted component.
155
155
  * Required on `projectionDetail` (which has no real entity — the host
@@ -105,7 +105,7 @@ export type RowActionWriteHandler = {
105
105
  readonly kind?: "writeHandler";
106
106
  /** Stable id per screen — kebab-case, unique within the action set. */
107
107
  readonly id: string;
108
- /** Anzeige-Text (i18n-Key). */
108
+ /** Display text (i18n key). */
109
109
  readonly label: string;
110
110
  /** Qualified name of the server handler, e.g.
111
111
  * "publicstatus:write:maintenance:start". Dispatched via
@@ -188,7 +188,7 @@ export type RowActionNavigate = RowActionNavigateBase & ({
188
188
  readonly screen: string;
189
189
  readonly entity?: never;
190
190
  } | {
191
- /** Entity name instead of screen id (fw#2228) — resolves at boot time to
191
+ /** Entity name instead of screen id — resolves at boot time to
192
192
  * the screen that declares `detailFor: "<entity>"` (see ObjectTarget/
193
193
  * resolveTarget in @cosmicdrift/kumiko-renderer's nav.tsx). */
194
194
  readonly entity: string;
@@ -86,7 +86,7 @@ export type ProjectionListScreenDefinition = {
86
86
  * param present). Same type serves author and wire schema (no separate
87
87
  * client-facing screen type exists), so this stays structurally
88
88
  * writable — validateProjectionListScreens rejects any hand-authored
89
- * value at boot (fw#2165). */
89
+ * value at boot. */
90
90
  readonly sortable?: boolean;
91
91
  /** Derived by buildAppSchema from the query handler's Zod schema (`cursor`
92
92
  * or `offset` param present). See `sortable` doc for why this is
@@ -212,6 +212,6 @@ export type ProjectionDetailScreenDefinition = {
212
212
  /** How head fields render. Default "text" — plain text instead of a
213
213
  * disabled Input, since every field on this screen type is forced
214
214
  * readOnly anyway (there is no write path, see the shim doc above).
215
- * Set "form" to opt back into the disabled-Input look (fw#2245). */
215
+ * Set "form" to opt back into the disabled-Input look. */
216
216
  readonly valueDisplay?: "form" | "text";
217
217
  };
package/dist/screen.d.ts CHANGED
@@ -91,7 +91,7 @@ export type ScreenSlots = {
91
91
  readonly sidebar?: PlatformComponent;
92
92
  readonly footer?: PlatformComponent;
93
93
  /** entityEdit wizard: marks `footer` as the sticky-footer primary action
94
- * (fw#1918's pinned `max-sm:fixed` group on mobile) instead of the
94
+ * (pinned `max-sm:fixed` group on mobile) instead of the
95
95
  * non-sticky secondary bucket it falls into by default alongside
96
96
  * Back/Cancel. Set this when `footer` renders the screen's actual
97
97
  * submit-type action (e.g. a custom "Publish" button standing in for, or
package/dist/step.d.ts CHANGED
@@ -39,7 +39,7 @@ export type PipelineCtx<TPayload = unknown, TMap extends object = KumikoEventTyp
39
39
  */
40
40
  readonly retryAttempt?: number;
41
41
  /**
42
- * Q7 Snapshot-at-Start fingerprint of the workflow definition that
42
+ * Snapshot-at-Start fingerprint of the workflow definition that
43
43
  * started this run. Propagated into every suspension event payload so
44
44
  * the resume-loop can detect library-upgrades that changed the closure
45
45
  * source and surface them as a typed failure instead of running a
@@ -1,16 +1,13 @@
1
- // TargetRef — runtime-Repräsentation eines typed buildTarget-Outputs.
2
- // Wird vom Visual-Tree-Component (renderer/web) an einen Target-Resolver
3
- // dispatcht; der Resolver findet die Editor-Maske via featureId.
1
+ // TargetRef — runtime representation of a typed buildTarget output.
2
+ // It is dispatched by the Visual Tree component (renderer/web) to a target
3
+ // resolver, which finds the editor form via featureId.
4
4
  //
5
- // **Compile-time-Safety:** TargetRef wird niemals hand-getippt. Stattdessen
6
- // erzeugt der typed buildTarget-Builder (engine/build-target.ts) einen
7
- // TargetRef, dessen action + args gegen die treeActions-Map des Ziel-
8
- // Features validiert sind.
5
+ // **Compile-time safety:** TargetRef is never written by hand. Instead, the
6
+ // typed buildTarget builder (engine/build-target.ts) creates a TargetRef whose
7
+ // action + args are validated against the target feature's treeActions map.
9
8
  //
10
- // **Runtime:** args sind hier untyped (Record<string, unknown>), weil
11
- // TargetRef die erased-runtime-Version ist. Der Resolver kennt das
12
- // Ziel-Feature und kann args entsprechend casten — ähnlich wie Event-
13
- // Payloads im Event-Store.
14
- //
15
- // Siehe docs/plans/architecture/visual-tree.md A5.
9
+ // **Runtime:** args are untyped here (Record<string, unknown>) because
10
+ // TargetRef is the erased runtime version. The resolver knows the target
11
+ // feature and can cast args accordingly, similar to event payloads in the
12
+ // event store.
16
13
  export {};
package/dist/tree-node.js CHANGED
@@ -1,22 +1,22 @@
1
- // TreeNode — single Knoten im Client-navProvider-Tree. Provider liefern
2
- // entweder statische readonly TreeNode[] oder dynamische TreeChildrenSubscribe.
1
+ // TreeNode — a single node in the client nav-provider tree. Providers return
2
+ // either static readonly TreeNode[] or dynamic TreeChildrenSubscribe.
3
3
  //
4
- // **Mental-Modell** (VS-Code-Explorer):
4
+ // **Mental model** (VS Code Explorer):
5
5
  // [icon] [label] [...hover-actions]
6
- // optional ein target zum Klicken (öffnet Editor-Maske via
7
- // Target-Resolver) und optional children als nested tree.
6
+ // An optional target makes the node clickable (opening an editor form via
7
+ // the target resolver), and optional children form a nested tree.
8
8
  //
9
- // **State** markiert Visual-Modus für Skeleton-Pattern:
10
- // - "filled" (default) — schwarz, Knoten hat Inhalt
11
- // - "stub" — hellgrau, existing aber leer (Designer-Stub-File)
12
- // - "empty" — Platzhalter für "+ create"-Affordance
13
- // - "loading" — Children werden gerade aufgelöst
14
- // - "error" — Provider hat Fehler emittiert
15
- // Provider die kein Skeleton-Pattern brauchen müssen state nicht setzen.
9
+ // **State** selects the visual mode for the skeleton pattern:
10
+ // - "filled" (default) — black; the node has content
11
+ // - "stub" — light gray; existing but empty (designer stub file)
12
+ // - "empty" — placeholder for the "+ create" affordance
13
+ // - "loading" — children are currently being resolved
14
+ // - "error" — the provider emitted an error
15
+ // Providers that do not need the skeleton pattern can omit state.
16
16
  //
17
- // **Subscribe-Form** für dynamic Children: Provider erhält emit(),
18
- // gibt unsubscribe() zurück. Initial-Emit synchron oder async, weitere
19
- // Emits beliebig oft (z.B. wenn Entity-Row neu erscheint via SSE).
20
- // Spielt natürlich mit existing SSE-Frame: ein Provider kann intern
21
- // auf Entity-Update-Events abonnieren und bei Änderung emit() aufrufen.
17
+ // **Subscribe form** for dynamic children: the provider receives emit()
18
+ // and returns unsubscribe(). The initial emit may be synchronous or async;
19
+ // further emits may occur arbitrarily often (for example, when an entity row
20
+ // appears through SSE). This works with the existing SSE frame: a provider
21
+ // can subscribe internally to entity-update events and call emit() on change.
22
22
  export {};
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-types",
3
- "version": "0.386.0",
3
+ "version": "0.388.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
- "license": "BUSL-1.1",
5
+ "license": "MIT",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
7
7
  "repository": {
8
8
  "type": "git",
@@ -154,6 +154,10 @@
154
154
  "types": "./dist/aggregate-types.d.ts",
155
155
  "default": "./dist/aggregate-types.js"
156
156
  },
157
+ "./list-aggregate-types": {
158
+ "types": "./dist/list-aggregate-types.d.ts",
159
+ "default": "./dist/list-aggregate-types.js"
160
+ },
157
161
  "./tenant-db-types": {
158
162
  "types": "./dist/tenant-db-types.d.ts",
159
163
  "default": "./dist/tenant-db-types.js"
@@ -281,7 +285,7 @@
281
285
  },
282
286
  "devDependencies": {
283
287
  "hono": "^4.13.1",
284
- "postgres": "npm:@bender0oo0/postgres@3.4.9-kumiko.1",
288
+ "postgres": "npm:@bender0oo0/postgres@3.4.9-kumiko.2",
285
289
  "temporal-polyfill": "^0.3.2",
286
290
  "zod": "^4.4.3",
287
291
  "ioredis": "^5.10.1"
@@ -433,6 +437,10 @@
433
437
  "types": "./dist/aggregate-types.d.ts",
434
438
  "default": "./dist/aggregate-types.js"
435
439
  },
440
+ "./list-aggregate-types": {
441
+ "types": "./dist/list-aggregate-types.d.ts",
442
+ "default": "./dist/list-aggregate-types.js"
443
+ },
436
444
  "./tenant-db-types": {
437
445
  "types": "./dist/tenant-db-types.d.ts",
438
446
  "default": "./dist/tenant-db-types.js"