@cosmicdrift/kumiko-types 0.372.0 → 0.374.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/handlers.d.ts +6 -2
- package/dist/handlers.js +35 -1
- package/dist/rate-limit-types.d.ts +5 -0
- package/dist/screen.d.ts +173 -6
- package/dist/screen.js +3 -0
- package/package.json +1 -1
package/dist/handlers.d.ts
CHANGED
|
@@ -513,7 +513,8 @@ export type EntityRef = {
|
|
|
513
513
|
export type HandlerRef = {
|
|
514
514
|
readonly name: string;
|
|
515
515
|
};
|
|
516
|
-
export
|
|
516
|
+
export declare const RATE_LIMIT_PERS: readonly ["user", "tenant", "ip", "user+handler", "tenant+handler", "ip+handler"];
|
|
517
|
+
export type RateLimitPer = (typeof RATE_LIMIT_PERS)[number];
|
|
517
518
|
export type RateLimitOption = {
|
|
518
519
|
readonly per: RateLimitPer;
|
|
519
520
|
readonly limit: number;
|
|
@@ -531,11 +532,14 @@ export type PayloadRateLimitOption = {
|
|
|
531
532
|
readonly cost?: number;
|
|
532
533
|
readonly normalize?: PayloadBucketNormalization;
|
|
533
534
|
};
|
|
535
|
+
export declare function isRateLimitOption(value: unknown): value is RateLimitOption;
|
|
536
|
+
export type RateLimitOptions = readonly [RateLimitOption, ...RateLimitOption[]];
|
|
534
537
|
export type RateLimitDisabled = {
|
|
535
538
|
readonly disabled: true;
|
|
536
539
|
readonly reason: string;
|
|
537
540
|
};
|
|
538
|
-
export type RateLimitDeclaration = RateLimitOption | RateLimitDisabled;
|
|
541
|
+
export type RateLimitDeclaration = RateLimitOption | RateLimitOptions | RateLimitDisabled;
|
|
542
|
+
export declare function declaredRateLimitOptions(declaration: RateLimitDeclaration | undefined): readonly RateLimitOption[];
|
|
539
543
|
export declare function isRateLimitDisabled(v: RateLimitDeclaration | undefined): v is RateLimitDisabled;
|
|
540
544
|
export type AgentRisk = "low" | "mid" | "high";
|
|
541
545
|
/** Per-handler hints for the AI-agent manifest. `expose` overrides the
|
package/dist/handlers.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isOneOf, propertyOf } from "./type-guards.js";
|
|
1
2
|
export const ESCAPE_HATCH_GRANTS = ["systemIdentity", "globalWrites", "unsafeRaw"];
|
|
2
3
|
export function isEscapeHatchGrant(value) {
|
|
3
4
|
return ESCAPE_HATCH_GRANTS.some((grant) => grant === value);
|
|
@@ -98,8 +99,41 @@ export function normalizeEventPiiSubject(spec) {
|
|
|
98
99
|
return { kind: "self" };
|
|
99
100
|
return { kind: "user", ownerField: spec.personal.of, whenAbsent: spec.personal.whenAbsent };
|
|
100
101
|
}
|
|
102
|
+
// --- Handler Definitions (stored in feature/registry) ---
|
|
103
|
+
// Per-handler rate limit. Bucket key derived from `per`:
|
|
104
|
+
// "user" → userId
|
|
105
|
+
// "tenant" → tenantId
|
|
106
|
+
// "ip" → request IP
|
|
107
|
+
// "user+handler" → userId + handlerName
|
|
108
|
+
// "tenant+handler" → tenantId + handlerName
|
|
109
|
+
// "ip+handler" → IP + handlerName (anonymous endpoints)
|
|
110
|
+
// `cost` is the tokens this handler-call deducts. Default 1 — bump for
|
|
111
|
+
// expensive operations (bulk export, bulk import).
|
|
112
|
+
export const RATE_LIMIT_PERS = [
|
|
113
|
+
"user",
|
|
114
|
+
"tenant",
|
|
115
|
+
"ip",
|
|
116
|
+
"user+handler",
|
|
117
|
+
"tenant+handler",
|
|
118
|
+
"ip+handler",
|
|
119
|
+
];
|
|
120
|
+
export function isRateLimitOption(value) {
|
|
121
|
+
const cost = propertyOf(value, "cost");
|
|
122
|
+
return (isOneOf(RATE_LIMIT_PERS, propertyOf(value, "per")) &&
|
|
123
|
+
typeof propertyOf(value, "limit") === "number" &&
|
|
124
|
+
typeof propertyOf(value, "windowSeconds") === "number" &&
|
|
125
|
+
(cost === undefined || typeof cost === "number"));
|
|
126
|
+
}
|
|
127
|
+
export function declaredRateLimitOptions(declaration) {
|
|
128
|
+
if (declaration === undefined || isRateLimitDisabled(declaration))
|
|
129
|
+
return [];
|
|
130
|
+
return isRateLimitOptionList(declaration) ? declaration : [declaration];
|
|
131
|
+
}
|
|
132
|
+
function isRateLimitOptionList(declaration) {
|
|
133
|
+
return Array.isArray(declaration);
|
|
134
|
+
}
|
|
101
135
|
export function isRateLimitDisabled(v) {
|
|
102
|
-
return v !== undefined && "disabled" in v && v.disabled === true;
|
|
136
|
+
return v !== undefined && !Array.isArray(v) && "disabled" in v && v.disabled === true;
|
|
103
137
|
}
|
|
104
138
|
// Marker set by defineEntityQueryHandler on both of its verbs. A string, not
|
|
105
139
|
// a Symbol(), for the same reason as PAGED_QUERY_HANDLER_BRAND: a symlinked
|
|
@@ -13,8 +13,13 @@ export type RateLimitConfig = {
|
|
|
13
13
|
readonly windowSeconds: number;
|
|
14
14
|
readonly cost?: number;
|
|
15
15
|
};
|
|
16
|
+
export type RateLimitBucketRequest = {
|
|
17
|
+
readonly bucket: string;
|
|
18
|
+
readonly config: RateLimitConfig;
|
|
19
|
+
};
|
|
16
20
|
export type RateLimitResolver = {
|
|
17
21
|
check(bucket: string, config: RateLimitConfig): Promise<RateLimitDecision>;
|
|
18
22
|
enforce(bucket: string, config: RateLimitConfig): Promise<RateLimitDecision>;
|
|
23
|
+
enforceAll(requests: readonly RateLimitBucketRequest[]): Promise<readonly RateLimitDecision[]>;
|
|
19
24
|
peek(bucket: string, config: Omit<RateLimitConfig, "cost">): Promise<RateLimitDecision>;
|
|
20
25
|
};
|
package/dist/screen.d.ts
CHANGED
|
@@ -167,7 +167,7 @@ export type RowActionDisplay = "button" | "link" | "icon" | "responsive";
|
|
|
167
167
|
* the rest in a kebab menu — except actions with an explicit `display`, which
|
|
168
168
|
* stay inline. `"inline"`: every action inline, no kebab. */
|
|
169
169
|
export type RowActionMode = "adaptive" | "inline";
|
|
170
|
-
export type RowAction = RowActionWriteHandler | RowActionNavigate | RowActionDrawer;
|
|
170
|
+
export type RowAction = RowActionWriteHandler | RowActionNavigate | RowActionDrawer | RowActionClientAction;
|
|
171
171
|
export type RowActionWriteHandler = {
|
|
172
172
|
/** Default für RowActions ohne explizit gesetzten `kind` —
|
|
173
173
|
* Backwards-kompatible Form. Kann auch explizit gesetzt werden. */
|
|
@@ -293,6 +293,37 @@ export type RowActionDrawer = {
|
|
|
293
293
|
/** Line under the drawer heading (i18n key or a bare `{name}` template),
|
|
294
294
|
* resolved like `title`. */
|
|
295
295
|
readonly subtitle?: string;
|
|
296
|
+
/** Clicking the row opens this drawer with that row's `params`. At most one
|
|
297
|
+
* `rowClick` action (navigate or drawer) per list; rejected on
|
|
298
|
+
* projectionDetail header actions, like navigate's. */
|
|
299
|
+
readonly rowClick?: boolean;
|
|
300
|
+
};
|
|
301
|
+
export type RowActionClientAction = {
|
|
302
|
+
readonly kind: "clientAction";
|
|
303
|
+
readonly id: string;
|
|
304
|
+
readonly label: string;
|
|
305
|
+
/** Registered client handler name, `<feature>:<kebab>`, e.g.
|
|
306
|
+
* "auth-email-password:request-password-reset". Resolved when the action is
|
|
307
|
+
* triggered; a name no client feature registered shows an error toast. */
|
|
308
|
+
readonly action: string;
|
|
309
|
+
/** Payload handed to the handler, picked from the row (or the shown record).
|
|
310
|
+
* Default `{ id: row.id }`, like a writeHandler. */
|
|
311
|
+
readonly payload?: RowFieldExtractor;
|
|
312
|
+
/** i18n key for the confirm dialog description. */
|
|
313
|
+
readonly confirm?: string;
|
|
314
|
+
/** i18n key for the confirm button, default `label`. */
|
|
315
|
+
readonly confirmLabel?: string;
|
|
316
|
+
/** Conditional visibility per row. */
|
|
317
|
+
readonly visible?: FieldCondition;
|
|
318
|
+
/** Visual style. "danger" forces a confirm dialog, like a writeHandler. */
|
|
319
|
+
readonly style?: "primary" | "secondary" | "danger";
|
|
320
|
+
/** Overrides the id-based default icon, see `RowActionWriteHandler.icon`. */
|
|
321
|
+
readonly icon?: IconKey;
|
|
322
|
+
/** Inline render form in the row-action column — see `RowActionDisplay`. */
|
|
323
|
+
readonly display?: RowActionDisplay;
|
|
324
|
+
/** i18n key of the toast shown after the handler reported `{ ok: true }`
|
|
325
|
+
* (default `kumiko.clientAction.success`). */
|
|
326
|
+
readonly successMessage?: string;
|
|
296
327
|
};
|
|
297
328
|
export type ToolbarAction = {
|
|
298
329
|
readonly kind: "navigate";
|
|
@@ -692,18 +723,30 @@ export type DashboardDateParam = {
|
|
|
692
723
|
readonly kind: "date";
|
|
693
724
|
readonly atMs: number;
|
|
694
725
|
};
|
|
726
|
+
/** Epoch ms, rendered relative to now ("5 minutes ago", "in 30 seconds") in the
|
|
727
|
+
* user locale; the text keeps ticking while it is on screen. */
|
|
728
|
+
export type DashboardRelativeTimeParam = {
|
|
729
|
+
readonly kind: "relativeTime";
|
|
730
|
+
readonly atMs: number;
|
|
731
|
+
};
|
|
695
732
|
/** Nested DashboardI18nText params resolve first (e.g. a duration "{years} {months}"
|
|
696
733
|
* with one plural key each); numbers stay raw so plural rules can read `count`. */
|
|
697
|
-
export type DashboardTextParam = string | number | DashboardI18nText | DashboardMoneyParam | DashboardDateParam;
|
|
734
|
+
export type DashboardTextParam = string | number | DashboardI18nText | DashboardMoneyParam | DashboardDateParam | DashboardRelativeTimeParam;
|
|
698
735
|
/** Plain string is displayed as-is; DashboardI18nText is translated by the renderer. */
|
|
699
736
|
export type DashboardText = string | DashboardI18nText;
|
|
700
737
|
/** Chart/stat values are minor units, formatted with the user locale. */
|
|
701
|
-
export type
|
|
738
|
+
export type DashboardCurrencyFormat = {
|
|
702
739
|
readonly kind: "currency";
|
|
703
740
|
readonly currency: string;
|
|
704
741
|
/** Defaults to the currency's own decimals. */
|
|
705
742
|
readonly fractionDigits?: number;
|
|
706
743
|
};
|
|
744
|
+
/** The stat value is an epoch ms timestamp, shown relative to now and kept current. */
|
|
745
|
+
export type DashboardRelativeTimeFormat = {
|
|
746
|
+
readonly kind: "relativeTime";
|
|
747
|
+
};
|
|
748
|
+
/** Stat panels take both formats; chart panels only the currency one. */
|
|
749
|
+
export type DashboardValueFormat = DashboardCurrencyFormat | DashboardRelativeTimeFormat;
|
|
707
750
|
export type DashboardPanelQueryOptions = {
|
|
708
751
|
/** Static, author-set query parameters merged on top of the screen's
|
|
709
752
|
* dynamic filterParams — lets a panel pin a value (e.g. a status facet)
|
|
@@ -737,7 +780,8 @@ export type DashboardStatPanel = DashboardPanelQueryOptions & DashboardPanelGate
|
|
|
737
780
|
readonly valueField: string;
|
|
738
781
|
readonly subField?: string;
|
|
739
782
|
readonly toneField?: string;
|
|
740
|
-
/** Formats a numeric value as currency (minor units)
|
|
783
|
+
/** Formats a numeric value as currency (minor units) or, with `relativeTime`, as
|
|
784
|
+
* a ticking "5 minutes ago" from epoch ms; ignored for string values. The sparkline is not formatted. */
|
|
741
785
|
readonly valueFormat?: DashboardValueFormat;
|
|
742
786
|
/** Fixed tone when `toneField` is unset or yields none; not applied while the value is 0. */
|
|
743
787
|
readonly tone?: DashboardStatTone;
|
|
@@ -802,7 +846,9 @@ export type DashboardChartPanel = DashboardPanelQueryOptions & DashboardPanelEmp
|
|
|
802
846
|
readonly seriesColors?: Readonly<Record<string, string>>;
|
|
803
847
|
/** Formats values as currency (minor units): y ticks, legend totals and tooltips on
|
|
804
848
|
* stacked-bars/segment-bars/stacked-area, only the y ticks on timeseries. */
|
|
805
|
-
readonly valueFormat?:
|
|
849
|
+
readonly valueFormat?: DashboardCurrencyFormat;
|
|
850
|
+
/** i18n key of a unit label. Only for chart "timeseries": shown once above the y ticks instead of on every tick. */
|
|
851
|
+
readonly unit?: string;
|
|
806
852
|
/** Only for chart "stacked-area": fixed width per bucket, plot scrolls horizontally. */
|
|
807
853
|
readonly scrollable?: boolean;
|
|
808
854
|
/** Only for chart "stacked-area": marker `kind` -> look. Markers without a
|
|
@@ -849,6 +895,7 @@ export type DashboardFeedPanel = DashboardPanelQueryOptions & DashboardPanelEmpt
|
|
|
849
895
|
readonly label: string;
|
|
850
896
|
readonly query: string;
|
|
851
897
|
};
|
|
898
|
+
export type DashboardProgressTone = "default" | "danger";
|
|
852
899
|
export type DashboardProgressListPanel = DashboardPanelQueryOptions & DashboardPanelEmptyState & DashboardPanelGate & {
|
|
853
900
|
readonly kind: "progress-list";
|
|
854
901
|
readonly id: string;
|
|
@@ -860,6 +907,32 @@ export type DashboardCustomPanel = {
|
|
|
860
907
|
readonly id: string;
|
|
861
908
|
readonly component: PlatformComponent;
|
|
862
909
|
};
|
|
910
|
+
export type DashboardTextBlock = {
|
|
911
|
+
readonly kind: "heading";
|
|
912
|
+
readonly text: string;
|
|
913
|
+
} | {
|
|
914
|
+
readonly kind: "paragraph";
|
|
915
|
+
readonly text: string;
|
|
916
|
+
/** Default "muted", like body copy inside panels. */
|
|
917
|
+
readonly emphasis?: "muted" | "strong";
|
|
918
|
+
} | {
|
|
919
|
+
readonly kind: "list";
|
|
920
|
+
readonly items: readonly string[];
|
|
921
|
+
} | {
|
|
922
|
+
readonly kind: "code";
|
|
923
|
+
readonly code: string;
|
|
924
|
+
} | {
|
|
925
|
+
readonly kind: "hint";
|
|
926
|
+
readonly text: string;
|
|
927
|
+
};
|
|
928
|
+
export type DashboardTextPanel = DashboardPanelGate & {
|
|
929
|
+
readonly kind: "text";
|
|
930
|
+
readonly id: string;
|
|
931
|
+
/** Panel title (i18n key). */
|
|
932
|
+
readonly label?: string;
|
|
933
|
+
readonly span?: DashboardPanelSpan;
|
|
934
|
+
readonly blocks: readonly DashboardTextBlock[];
|
|
935
|
+
};
|
|
863
936
|
export type DashboardPanelVisibility = {
|
|
864
937
|
readonly query: string;
|
|
865
938
|
readonly field: string;
|
|
@@ -872,13 +945,17 @@ export type DashboardScreenPanel = {
|
|
|
872
945
|
readonly screen: string;
|
|
873
946
|
readonly label?: string;
|
|
874
947
|
readonly visibleWhen?: DashboardPanelVisibility;
|
|
948
|
+
/** Same-feature short id or cross-feature QN `<feature>:screen:<id>` embedded in this
|
|
949
|
+
* panel's place when `visibleWhen` is unmet or its query fails (nothing while it loads).
|
|
950
|
+
* Needs `visibleWhen`; the target must not have a `visibleWhen` of its own. */
|
|
951
|
+
readonly fallback?: string;
|
|
875
952
|
/** Render the embedded form without its own card frame and padding, aligned to
|
|
876
953
|
* the dashboard's page grid like a standalone settings screen. Default false
|
|
877
954
|
* (framed card); set for panels whose body is a settings-list form, where a
|
|
878
955
|
* card inside the page would double the inset. */
|
|
879
956
|
readonly chromeless?: boolean;
|
|
880
957
|
};
|
|
881
|
-
export type DashboardPanelDefinition = DashboardStatPanel | DashboardStatGroupPanel | DashboardChartPanel | DashboardListPanel | DashboardFeedPanel | DashboardProgressListPanel | DashboardCustomPanel | DashboardScreenPanel;
|
|
958
|
+
export type DashboardPanelDefinition = DashboardStatPanel | DashboardStatGroupPanel | DashboardChartPanel | DashboardListPanel | DashboardFeedPanel | DashboardProgressListPanel | DashboardTextPanel | DashboardCustomPanel | DashboardScreenPanel;
|
|
882
959
|
export type DashboardFilterDefinition = {
|
|
883
960
|
readonly id: string;
|
|
884
961
|
readonly label: string;
|
|
@@ -906,6 +983,30 @@ export type DashboardScopeDefinition = {
|
|
|
906
983
|
readonly badge: string;
|
|
907
984
|
readonly notice?: string;
|
|
908
985
|
};
|
|
986
|
+
/** Minimum polling interval of `DashboardScreenDefinition.refresh`; shorter values are rejected
|
|
987
|
+
* at boot (`seconds`) or raised at runtime (`field`). */
|
|
988
|
+
export declare const DASHBOARD_MIN_REFRESH_SECONDS = 5;
|
|
989
|
+
export type DashboardRecordBinding = {
|
|
990
|
+
/** URL search param carrying the record id. Without it the dashboard shows a
|
|
991
|
+
* hint instead of its panels and runs no query. */
|
|
992
|
+
readonly param: string;
|
|
993
|
+
/** Key of the id in each panel query payload. Default: `param`. */
|
|
994
|
+
readonly payloadKey?: string;
|
|
995
|
+
/** Optional query for the record row (QN). It receives `{ [payloadKey]: id }`
|
|
996
|
+
* and returns a flat row; `actions` take that row as their input and
|
|
997
|
+
* `refresh.field` and `titleField` read from it. */
|
|
998
|
+
readonly query?: string;
|
|
999
|
+
/** Field of the record row shown as the page title. Needs `query`. */
|
|
1000
|
+
readonly titleField?: string;
|
|
1001
|
+
};
|
|
1002
|
+
/** Polling of the record and all panel queries, never faster than
|
|
1003
|
+
* DASHBOARD_MIN_REFRESH_SECONDS. `field` reads the seconds from the record row
|
|
1004
|
+
* (needs `record.query`), so a monitor can be polled at its own check interval. */
|
|
1005
|
+
export type DashboardRefresh = {
|
|
1006
|
+
readonly seconds: number;
|
|
1007
|
+
} | {
|
|
1008
|
+
readonly field: string;
|
|
1009
|
+
};
|
|
909
1010
|
export type DashboardScreenDefinition = {
|
|
910
1011
|
readonly id: string;
|
|
911
1012
|
readonly type: "dashboard";
|
|
@@ -921,6 +1022,14 @@ export type DashboardScreenDefinition = {
|
|
|
921
1022
|
/** Same-feature short id or cross-feature QN `<feature>:screen:<id>` shown when `visibleWhen` is unmet (default: standard notice). */
|
|
922
1023
|
readonly fallback?: string;
|
|
923
1024
|
readonly panels: readonly DashboardPanelDefinition[];
|
|
1025
|
+
/** Binds the dashboard to one record via a URL search param, see DashboardRecordBinding. */
|
|
1026
|
+
readonly record?: DashboardRecordBinding;
|
|
1027
|
+
/** Header actions on the bound record (writeHandler, navigate, clientAction).
|
|
1028
|
+
* The row is the `record.query` row, or `{ id, [payloadKey]: id }` without a
|
|
1029
|
+
* query. After a success the record and all panels refetch. Needs `record`;
|
|
1030
|
+
* no drawer, redirect or rowClick. */
|
|
1031
|
+
readonly actions?: readonly RowAction[];
|
|
1032
|
+
readonly refresh?: DashboardRefresh;
|
|
924
1033
|
readonly filter?: DashboardFilterDefinition;
|
|
925
1034
|
/** Segmented control in the toolbar; the value lives in URL search param
|
|
926
1035
|
* `id` and is merged into EVERY panel query (also ignoreScreenFilter ones). */
|
|
@@ -953,6 +1062,21 @@ export type EditFieldSpec = string | {
|
|
|
953
1062
|
* `multiline` routes to a textarea (no icon slot), and other input
|
|
954
1063
|
* kinds (select, combobox, date, …) silently ignore the key. */
|
|
955
1064
|
readonly icon?: FieldIconKey;
|
|
1065
|
+
/** Input placeholder (i18n key, falls back to the literal). Only for
|
|
1066
|
+
* single-line text, number and textarea inputs; other kinds ignore it. */
|
|
1067
|
+
readonly placeholder?: string;
|
|
1068
|
+
/** Static text shown before the input (i18n key, falls back to the
|
|
1069
|
+
* literal), or `{ field }` for the current form value of another field
|
|
1070
|
+
* (a hidden field carrying e.g. a base domain). Only for single-line
|
|
1071
|
+
* text and number inputs; other kinds ignore it. */
|
|
1072
|
+
readonly prefix?: FieldAffix;
|
|
1073
|
+
/** Same as `prefix`, shown after the input. */
|
|
1074
|
+
readonly suffix?: FieldAffix;
|
|
1075
|
+
/** Button beside the input that runs a query and writes one scalar of
|
|
1076
|
+
* its result into this field. Also offered on a readOnly field, where
|
|
1077
|
+
* the value can only come from the suggestion. Only for single-line
|
|
1078
|
+
* text and number inputs; other kinds ignore it. */
|
|
1079
|
+
readonly fillAction?: FieldFillAction;
|
|
956
1080
|
/** Marks this field as a reference lookup instead of a plain value —
|
|
957
1081
|
* for projectionDetail fields, which have no `EntityDefinition` to
|
|
958
1082
|
* carry a real `reference` field type. Same target convention as
|
|
@@ -971,6 +1095,20 @@ export type EditFieldSpec = string | {
|
|
|
971
1095
|
* field `default`, it is not applied server-side. */
|
|
972
1096
|
readonly prefill?: EditFieldPrefill;
|
|
973
1097
|
};
|
|
1098
|
+
export type FieldAffix = string | {
|
|
1099
|
+
readonly field: string;
|
|
1100
|
+
};
|
|
1101
|
+
export type FieldFillAction = {
|
|
1102
|
+
/** i18n key (falls back to the literal) of the button label. */
|
|
1103
|
+
readonly label: string;
|
|
1104
|
+
/** Qualified query name, run with the current form values picked by `params`. */
|
|
1105
|
+
readonly query: string;
|
|
1106
|
+
/** Key in the query result written into the field; the value must be a
|
|
1107
|
+
* string or a number, anything else counts as a failed fill. */
|
|
1108
|
+
readonly field: string;
|
|
1109
|
+
/** Form fields sent as the query payload (none: an empty payload). */
|
|
1110
|
+
readonly params?: RowFieldExtractor;
|
|
1111
|
+
};
|
|
974
1112
|
export type EmbeddedListEditSpec = {
|
|
975
1113
|
/** Sub-fields shown as read-only cells; every other cell stays editable. */
|
|
976
1114
|
readonly readOnlyCells?: readonly string[];
|
|
@@ -1469,6 +1607,20 @@ export type ActionFormScreenDefinition = {
|
|
|
1469
1607
|
* the handler creates a child record but the target screen is the
|
|
1470
1608
|
* parent's detail screen (fw#2670). */
|
|
1471
1609
|
readonly redirect?: string | ActionFormRedirect;
|
|
1610
|
+
/** Links shown in the success box after a successful submit while the
|
|
1611
|
+
* screen stays put. Targets resolve like `redirect` (the id comes from the
|
|
1612
|
+
* handler's success payload); a link without a string id is hidden.
|
|
1613
|
+
* Mutually exclusive with `redirect`. */
|
|
1614
|
+
readonly successLinks?: readonly ActionFormSuccessLink[];
|
|
1615
|
+
/** Reset the form to its initial values after a successful submit (prefill
|
|
1616
|
+
* kept, typed values cleared). Only applies while the screen stays put,
|
|
1617
|
+
* i.e. without `redirect`. */
|
|
1618
|
+
readonly resetOnSuccess?: boolean;
|
|
1619
|
+
/** Load the initial values from a query. The record id comes from the route
|
|
1620
|
+
* (or the drawer row id) and is sent as `{ [idParam]: id }`; the result,
|
|
1621
|
+
* picked to `fields`, becomes the initial values. Turns URL prefill off:
|
|
1622
|
+
* search params never reach the form. */
|
|
1623
|
+
readonly load?: ActionFormLoad;
|
|
1472
1624
|
/** Target of the Cancel button. Default: `redirect` (historical
|
|
1473
1625
|
* behavior — Cancel and the submit-redirect then land in the same
|
|
1474
1626
|
* place). `false` = no Cancel button; correct for single-action
|
|
@@ -1519,6 +1671,21 @@ export type ActionFormRedirect = {
|
|
|
1519
1671
|
* Boot rejects other targets and unknown section ids. */
|
|
1520
1672
|
readonly tab?: string;
|
|
1521
1673
|
};
|
|
1674
|
+
export type ActionFormLoad = {
|
|
1675
|
+
/** Query QN that returns the record. */
|
|
1676
|
+
readonly query: string;
|
|
1677
|
+
/** Payload key carrying the record id (default "id"). */
|
|
1678
|
+
readonly idParam?: string;
|
|
1679
|
+
};
|
|
1680
|
+
/** A redirect target rendered as a link in the success box. */
|
|
1681
|
+
export type ActionFormSuccessLink = Omit<ActionFormRedirect, "idFrom"> & {
|
|
1682
|
+
/** Success-payload field carrying the navigation id. Required for a record
|
|
1683
|
+
* target (`entityEdit`, `projectionDetail`); omit it for a list, dashboard
|
|
1684
|
+
* or form target, which opens without an id. */
|
|
1685
|
+
readonly idFrom?: string;
|
|
1686
|
+
/** Link text (i18n key). */
|
|
1687
|
+
readonly label: string;
|
|
1688
|
+
};
|
|
1522
1689
|
/** Author-declared field shown once after a mint-form submit — API token,
|
|
1523
1690
|
* recovery codes, similar one-time secrets. */
|
|
1524
1691
|
export type SecretRevealField = {
|
package/dist/screen.js
CHANGED
|
@@ -8,6 +8,9 @@ export function metricField(metric) {
|
|
|
8
8
|
// `visibleWhen` only on a top-level stat; the boot validator rejects it on a
|
|
9
9
|
// stat-group child (gate the whole group instead).
|
|
10
10
|
export const DASHBOARD_STAT_TONES = ["default", "positive", "ok", "warn", "negative"];
|
|
11
|
+
/** Minimum polling interval of `DashboardScreenDefinition.refresh`; shorter values are rejected
|
|
12
|
+
* at boot (`seconds`) or raised at runtime (`field`). */
|
|
13
|
+
export const DASHBOARD_MIN_REFRESH_SECONDS = 5;
|
|
11
14
|
/** Group key of a field value; `collapsedWhen` and row values both go through it. */
|
|
12
15
|
export function relatedListGroupKey(value) {
|
|
13
16
|
return value === undefined || value === null ? "" : String(value);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-types",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.374.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>",
|