@cosmicdrift/kumiko-types 0.333.0 → 0.334.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
@@ -2,7 +2,7 @@ import type { ZodType } from "zod";
2
2
  import type { ConcurrencyMode } from "./concurrency-mode.js";
3
3
  import type { ConfigScope } from "./config-scope.js";
4
4
  import type { DbConnection } from "./db-connection.js";
5
- import type { FieldDefinition } from "./fields.js";
5
+ import type { FieldDefinition, OptionsQueryPayload } from "./fields.js";
6
6
  import type { EscapeHatchDeclaration, JobContext } from "./handlers.js";
7
7
  import type { PostDeleteHookFn, PostSaveHookFn, PreDeleteHookFn, PreQueryHookFn, PreSaveHookFn } from "./hooks.js";
8
8
  import type { TenantId } from "./identifiers.js";
@@ -46,12 +46,14 @@ export type ConfigKeyDefinition<T extends ConfigKeyType = ConfigKeyType> = {
46
46
  readonly piiEncrypted?: boolean;
47
47
  readonly options?: readonly string[];
48
48
  /** Only on `type: "select"`: loads the options from this query (QN), contract
49
- * `{ rows: { value, label }[] }`, labels shown verbatim. Mutually exclusive with
49
+ * `{ rows: { value, label, description?, group? }[] }`, labels shown verbatim. Mutually exclusive with
50
50
  * `options` and `allowPerRequest`. The write side does not check the value against
51
51
  * the query result; the consuming feature validates it where it uses it. */
52
52
  readonly optionsQuery?: string;
53
- /** Static payload sent with every `optionsQuery` call. Requires `optionsQuery`. */
54
- readonly optionsQueryPayload?: Readonly<Record<string, string | number | boolean>>;
53
+ /** Payload sent with every `optionsQuery` call. Requires `optionsQuery`. `{ field }`
54
+ * names another config key (short name) of the owner feature, resolved on the
55
+ * generated settings screen. */
56
+ readonly optionsQueryPayload?: OptionsQueryPayload;
55
57
  readonly bounds?: ConfigBounds;
56
58
  readonly pattern?: {
57
59
  readonly regex: string;
@@ -68,6 +70,8 @@ export type ConfigKeyDefinition<T extends ConfigKeyType = ConfigKeyType> = {
68
70
  };
69
71
  export type ConfigMask = {
70
72
  readonly title: string;
73
+ /** i18n key for help text shown under the field label. */
74
+ readonly description?: string;
71
75
  readonly icon?: NavIconKey;
72
76
  readonly order?: number;
73
77
  };
package/dist/fields.d.ts CHANGED
@@ -89,6 +89,18 @@ export type TextFieldDef = {
89
89
  readonly filterable?: boolean;
90
90
  readonly encrypted?: boolean;
91
91
  readonly sensitive?: boolean;
92
+ /** Write-only secret (API key): the value is never returned to clients. Reads
93
+ * (list/detail/write responses) show `true` = set, `null` = empty. Writes:
94
+ * `""` or omitted = unchanged, `null` = clear, string = new value.
95
+ * Server-side: executor reads (detail/list in server handlers) and
96
+ * postSave/postQuery hooks see the plaintext; ctx.query, dispatcher.query,
97
+ * agent tools and `_refs` see true/null; ctx.db sees the ciphertext.
98
+ * Known limit: masking runs for entity-bound query handlers with array /
99
+ * {rows} / flat results; an unbound custom query handler that returns
100
+ * executor rows must call maskWriteOnlyFields itself (same scope limit as
101
+ * access.read). Requires `sensitive` (via `find: "secret"`); forbidden with
102
+ * default/searchable/sortable/filterable/lookupable and on screen/form fields. */
103
+ readonly writeOnly?: boolean;
92
104
  /** A later run reads this field's value as an instruction — prompt, rule,
93
105
  * template. Every create/update whose payload writes it requires agent.risk
94
106
  * "high" on the directly-dispatched entry handler; a revert doesn't undo a
@@ -158,6 +170,16 @@ export type BooleanFieldDef = {
158
170
  readonly access?: FieldAccess;
159
171
  };
160
172
  export type SelectOptionTone = "ok" | "warn" | "bad" | "neutral";
173
+ /** One `optionsQueryPayload` entry: a literal, or `{ field }` = the current value of
174
+ * a sibling field of the same form (config keys: another key of the owner feature). */
175
+ export type OptionsQueryPayloadValue = string | number | boolean | {
176
+ readonly field: string;
177
+ };
178
+ export type OptionsQueryPayload = Readonly<Record<string, OptionsQueryPayloadValue>>;
179
+ export declare function isOptionsQueryFieldRef(value: OptionsQueryPayloadValue): value is {
180
+ readonly field: string;
181
+ };
182
+ export declare function optionsQueryFieldRefs(payload: OptionsQueryPayload | undefined): string[];
161
183
  export type SelectFieldDef<TOptions extends readonly string[] = readonly string[]> = {
162
184
  readonly type: "select";
163
185
  readonly description?: string;
@@ -180,13 +202,15 @@ export type SelectFieldDef<TOptions extends readonly string[] = readonly string[
180
202
  readonly optionTones?: {
181
203
  readonly [K in TOptions[number]]?: SelectOptionTone;
182
204
  };
183
- /** Loads the options from this query (QN). Contract: `{ rows: { value, label }[] }`,
184
- * labels are shown verbatim (not translated). `options` must be empty when set.
205
+ /** Loads the options from this query (QN). Contract:
206
+ * `{ rows: { value, label, description?, group? }[] }`, labels are shown verbatim
207
+ * (not translated); description is a muted second line, group a heading. `options` must be empty when set.
185
208
  * Only valid on configEdit/actionForm screen fields and config keys, not on entity
186
209
  * fields: the stored value would not be checked against the query result. */
187
210
  readonly optionsQuery?: string;
188
- /** Static payload sent with every `optionsQuery` call. */
189
- readonly optionsQueryPayload?: Readonly<Record<string, string | number | boolean>>;
211
+ /** Payload sent with every `optionsQuery` call. `{ field }` entries re-load the
212
+ * options when that sibling field changes. */
213
+ readonly optionsQueryPayload?: OptionsQueryPayload;
190
214
  } & ResolvedPiiFlags;
191
215
  export type MultiSelectFieldDef<TOptions extends readonly string[] = readonly string[]> = {
192
216
  readonly type: "multiSelect";
package/dist/fields.js CHANGED
@@ -1,4 +1,12 @@
1
1
  // --- Field Types ---
2
+ export function isOptionsQueryFieldRef(value) {
3
+ return typeof value === "object" && value !== null;
4
+ }
5
+ export function optionsQueryFieldRefs(payload) {
6
+ return Object.values(payload ?? {})
7
+ .filter(isOptionsQueryFieldRef)
8
+ .map((ref) => ref.field);
9
+ }
2
10
  /** Qualified config key a `{ kind: "tenant" }` MoneyCurrencySource resolves
3
11
  * against — the tenant-settings bundle's per-tenant currency. Lives here
4
12
  * (client-safe) rather than framework/engine so renderer code can read it
package/dist/screen.d.ts CHANGED
@@ -735,6 +735,11 @@ export type DashboardScreenPanel = {
735
735
  readonly screen: string;
736
736
  readonly label?: string;
737
737
  readonly visibleWhen?: DashboardPanelVisibility;
738
+ /** Render the embedded form without its own card frame and padding, aligned to
739
+ * the dashboard's page grid like a standalone settings screen. Default false
740
+ * (framed card); set for panels whose body is a settings-list form, where a
741
+ * card inside the page would double the inset. */
742
+ readonly chromeless?: boolean;
738
743
  };
739
744
  export type DashboardPanelDefinition = DashboardStatPanel | DashboardStatGroupPanel | DashboardChartPanel | DashboardListPanel | DashboardFeedPanel | DashboardProgressListPanel | DashboardCustomPanel | DashboardScreenPanel;
740
745
  export type DashboardFilterDefinition = {
@@ -781,6 +786,10 @@ export type DashboardScreenDefinition = {
781
786
  readonly timeRange?: DashboardTimeRangeDefinition;
782
787
  /** Marks the screen as spanning more than the caller's own scope. */
783
788
  readonly scope?: DashboardScopeDefinition;
789
+ /** Show the "Updated at" timestamp in the toolbar. Default true; turn off for
790
+ * dashboards that host forms rather than live metrics, where a load time
791
+ * next to the form reads as stale data. */
792
+ readonly showUpdatedAt?: boolean;
784
793
  readonly slots?: ScreenSlots;
785
794
  readonly access?: AccessRule;
786
795
  };
@@ -1062,6 +1071,12 @@ export type EditLayout = {
1062
1071
  * boot-validator rejects it on entityEdit, see the check for the reason);
1063
1072
  * requires >= 2 sections, each with a title and an `id`. */
1064
1073
  readonly mode?: "single" | "wizard" | "tabs";
1074
+ /** "settings-list" lays each section out as a band with a title column on
1075
+ * the left and one hairline-separated row per field (label + help left,
1076
+ * control right) — the familiar settings pattern, for screens that are a
1077
+ * list of independent preferences rather than one record form. Default
1078
+ * "form" keeps the grid of cells. */
1079
+ readonly variant?: "form" | "settings-list";
1065
1080
  /** Persists in-progress wizard state as a resumable draft instead of
1066
1081
  * discarding it on navigation away. */
1067
1082
  readonly draft?: boolean;
@@ -1424,6 +1439,11 @@ export type ConfigEditScreenDefinition = {
1424
1439
  * ohne es unter der `__config-edit__`-Konvention zu duplizieren.
1425
1440
  * Fehlt ein Eintrag, gilt die Konvention. */
1426
1441
  readonly fieldLabels?: Readonly<Record<string, string>>;
1442
+ /** Per-field help text i18n key (Field-Name → Key), from `mask.description`. */
1443
+ readonly fieldDescriptions?: Readonly<Record<string, string>>;
1444
+ /** Field names whose config key declares `required: true` — drives the
1445
+ * "Not set. Required." origin line, not form validation. */
1446
+ readonly requiredFields?: readonly string[];
1427
1447
  /** i18n-key für den Submit-Button. Default: "kumiko.actions.save". */
1428
1448
  readonly submitLabel?: string;
1429
1449
  readonly slots?: ScreenSlots;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-types",
3
- "version": "0.333.0",
3
+ "version": "0.334.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>",