@cosmicdrift/kumiko-types 0.373.0 → 0.377.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/feature.d.ts +3 -1
- package/dist/fields.d.ts +3 -2
- package/dist/handlers.d.ts +33 -1
- package/dist/nav-icon.js +1 -1
- package/dist/screen.d.ts +191 -11
- package/dist/screen.js +3 -0
- package/dist/target-ref.js +1 -1
- package/package.json +1 -1
- package/src/changes.json +20 -0
package/dist/feature.d.ts
CHANGED
|
@@ -116,10 +116,12 @@ export type BootCheckContext = {
|
|
|
116
116
|
};
|
|
117
117
|
export type BootCheckFn = (ctx: BootCheckContext) => void;
|
|
118
118
|
/** runProdApp options a stack can depend on; runProdApp checks the set at boot. */
|
|
119
|
-
export type BootOptionName = "mail" | "kmsMode" | "fileStorage" | "billing" | "demoMode" | "seeds" | "signals" | "rateLimit";
|
|
119
|
+
export type BootOptionName = "mail" | "kmsMode" | "fileStorage" | "billing" | "featureToggles" | "demoMode" | "seeds" | "signals" | "rateLimit";
|
|
120
120
|
export type StackBootRequirement = {
|
|
121
121
|
readonly stack: string;
|
|
122
122
|
readonly options: readonly BootOptionName[];
|
|
123
|
+
/** `"warn"`: a missing option logs a boot warning instead of aborting. Default `"error"`. */
|
|
124
|
+
readonly severity?: "error" | "warn";
|
|
123
125
|
};
|
|
124
126
|
export type FeatureDefinition = {
|
|
125
127
|
readonly name: string;
|
package/dist/fields.d.ts
CHANGED
|
@@ -119,8 +119,9 @@ export type TextFieldDef = {
|
|
|
119
119
|
* "high" on the directly-dispatched entry handler; a revert doesn't undo a
|
|
120
120
|
* run that already read the compromised value. See irreversible-operation-gate. */
|
|
121
121
|
readonly readAsInstruction?: boolean;
|
|
122
|
-
/** "password" is a pure render hint (masked input) — no storage semantics.
|
|
123
|
-
|
|
122
|
+
/** "password" is a pure render hint (masked input) — no storage semantics.
|
|
123
|
+
* "month" stores `YYYY-MM`: month picker in the form, format enforced on write. */
|
|
124
|
+
readonly format?: "email" | "url" | "phone" | "password" | "month";
|
|
124
125
|
readonly default?: string;
|
|
125
126
|
readonly access?: FieldAccess;
|
|
126
127
|
/** Mehrzeiliger Text — DefaultInput rendert dann ein <textarea> statt
|
package/dist/handlers.d.ts
CHANGED
|
@@ -230,6 +230,9 @@ type SharedContextFields = {
|
|
|
230
230
|
* absent for r.systemScope() handlers and without a db.
|
|
231
231
|
*/
|
|
232
232
|
readonly forTenant?: (tenantId: TenantId) => TenantWriteTarget;
|
|
233
|
+
/** Mints the per-request `ctx.config`; set by the boot (`addConfigAccessorFactory`) from the effective `configResolver`, overriding an app-supplied value. */
|
|
234
|
+
readonly configAccessorFactory?: ConfigAccessorFactory;
|
|
235
|
+
/** @deprecated Use `configAccessorFactory`; the underscore name is removed in the next major. */
|
|
233
236
|
readonly _configAccessorFactory?: ConfigAccessorFactory;
|
|
234
237
|
readonly configEncryption?: import("./envelope-cipher-types.ts").EnvelopeCipher;
|
|
235
238
|
readonly rateLimit?: import("./rate-limit-types.ts").RateLimitResolver;
|
|
@@ -290,7 +293,18 @@ export type AppContext = SharedContextFields & {
|
|
|
290
293
|
};
|
|
291
294
|
export type HandlerContext<TMap extends object = KumikoEventTypeMap> = SharedContextFields & {
|
|
292
295
|
readonly db: TenantDb;
|
|
296
|
+
/**
|
|
297
|
+
* Same tenant scoping as `db`, but never bound to the handler's tx: writes through it survive
|
|
298
|
+
* a rollback. `undefined` only in the denial phases (member-resolution, before-transaction)
|
|
299
|
+
* and in platform-metering tenant mode; narrow with `hasOutsideTransactionDb(ctx)` or take it
|
|
300
|
+
* via `requireOutsideTransactionDb(ctx)` (`@cosmicdrift/kumiko-framework/db`). For
|
|
301
|
+
* r.systemScope() handlers it is a fail-closed Proxy; use `systemDb.outsideTransaction`.
|
|
302
|
+
*/
|
|
293
303
|
readonly dbOutsideTransaction: TenantDb | undefined;
|
|
304
|
+
/**
|
|
305
|
+
* @deprecated Use `runInOwnTransaction(ctx.dbOutsideTransaction, fn)` from
|
|
306
|
+
* `@cosmicdrift/kumiko-framework/db`; removed in the next major.
|
|
307
|
+
*/
|
|
294
308
|
readonly outsideTransaction?: <T>(fn: (db: TenantDb) => Promise<T>) => Promise<T>;
|
|
295
309
|
readonly systemDb?: UncheckedSystemDb;
|
|
296
310
|
readonly registry: Registry;
|
|
@@ -320,8 +334,21 @@ export type HandlerContext<TMap extends object = KumikoEventTypeMap> = SharedCon
|
|
|
320
334
|
readonly write: (qn: string, payload: unknown) => Promise<WriteResult>;
|
|
321
335
|
readonly writeAs: (user: SessionUser, qn: string, payload: unknown) => Promise<WriteResult>;
|
|
322
336
|
readonly hasFeature: (featureName: string) => Promise<boolean>;
|
|
337
|
+
/**
|
|
338
|
+
* Default append: a typed domain event on one aggregate stream in the current tx. The runtime
|
|
339
|
+
* bumps the stream version and fires matching projections in the same transaction. A version
|
|
340
|
+
* conflict throws and poisons the transaction.
|
|
341
|
+
*/
|
|
323
342
|
readonly appendEvent: AppendEventFn<TMap>;
|
|
343
|
+
/**
|
|
344
|
+
* Untyped append (`payload: unknown`) with the same runtime as `appendEvent`. Only for
|
|
345
|
+
* migrations and upcasters, where the event type is not knowable at compile time.
|
|
346
|
+
*/
|
|
324
347
|
readonly unsafeAppendEvent: UnsafeAppendEventFn;
|
|
348
|
+
/**
|
|
349
|
+
* Optimistic append: runs in a savepoint and returns a version conflict as a result instead of
|
|
350
|
+
* throwing, so the handler can continue after losing a race on the same aggregate stream.
|
|
351
|
+
*/
|
|
325
352
|
readonly tryAppendEvent: TryAppendEventFn;
|
|
326
353
|
readonly fetchForWriting: (args: FetchForWritingArgs) => Promise<AggregateStreamHandle>;
|
|
327
354
|
readonly loadAggregate: (aggregateId: string, options?: {
|
|
@@ -375,8 +402,13 @@ export type JobContext = SharedContextFields & {
|
|
|
375
402
|
readonly triggerName?: string;
|
|
376
403
|
readonly triggerEvent?: JobTriggerEvent;
|
|
377
404
|
readonly _tenantId?: TenantId;
|
|
378
|
-
readonly _userId?: string | undefined;
|
|
379
405
|
};
|
|
406
|
+
/**
|
|
407
|
+
* What a provider plugin (`build`, `capabilitiesFor`, ...) may read. Both write/query handlers
|
|
408
|
+
* and jobs can produce one (`providerPluginContextFromHandler`, `providerPluginContextFromJob`),
|
|
409
|
+
* so a plugin never depends on a request-bound field.
|
|
410
|
+
*/
|
|
411
|
+
export type ProviderPluginContext = Pick<HandlerContext, "db" | "dbOutsideTransaction" | "systemDb" | "registry" | "user" | "log" | "triggeredBy" | "config" | "secrets">;
|
|
380
412
|
export type WriteHandlerFn<TPayload = unknown, TData = unknown> = (event: WriteEvent<TPayload>, context: HandlerContext) => Promise<WriteResult<TData>>;
|
|
381
413
|
export type QueryHandlerFn<TPayload = unknown, TResult = unknown> = (query: QueryEvent<TPayload>, context: HandlerContext) => Promise<TResult>;
|
|
382
414
|
export type StreamHandlerFn<TPayload = unknown, TChunk = unknown> = (query: QueryEvent<TPayload>, context: HandlerContext) => AsyncGenerator<TChunk>;
|
package/dist/nav-icon.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// r.nav()/r.screen()/config-mask/button call site instead of a silent
|
|
5
5
|
// missing-icon at runtime.
|
|
6
6
|
//
|
|
7
|
-
// The renderer
|
|
7
|
+
// The renderer/web NAV_ICONS map (packages/renderer/src/web/icons.tsx) is
|
|
8
8
|
// checked against this same union via `satisfies`, so the two can't drift —
|
|
9
9
|
// add a key here only together with its lucide-react entry there, and vice
|
|
10
10
|
// versa.
|
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. */
|
|
@@ -200,7 +200,7 @@ export type RowActionWriteHandler = {
|
|
|
200
200
|
readonly style?: "primary" | "secondary" | "danger";
|
|
201
201
|
/** Overrides the id-based default icon (see ACTION_ICON_BY_ID in
|
|
202
202
|
* kumiko-renderer) — closed IconKey vocabulary into the ICONS registry
|
|
203
|
-
* (renderer
|
|
203
|
+
* (renderer/web), analogous to EditFieldSpec.icon. */
|
|
204
204
|
readonly icon?: IconKey;
|
|
205
205
|
/** Inline render form in the row-action column — see `RowActionDisplay`. */
|
|
206
206
|
readonly display?: RowActionDisplay;
|
|
@@ -244,7 +244,7 @@ export type RowActionNavigateBase = {
|
|
|
244
244
|
readonly rowClick?: boolean;
|
|
245
245
|
/** Overrides the id-based default icon (see ACTION_ICON_BY_ID in
|
|
246
246
|
* kumiko-renderer) — closed IconKey vocabulary into the ICONS registry
|
|
247
|
-
* (renderer
|
|
247
|
+
* (renderer/web), analogous to EditFieldSpec.icon. */
|
|
248
248
|
readonly icon?: IconKey;
|
|
249
249
|
/** Inline render form in the row-action column — see `RowActionDisplay`. */
|
|
250
250
|
readonly display?: RowActionDisplay;
|
|
@@ -282,7 +282,7 @@ export type RowActionDrawer = {
|
|
|
282
282
|
readonly style?: "primary" | "secondary" | "danger";
|
|
283
283
|
/** Overrides the id-based default icon (see ACTION_ICON_BY_ID in
|
|
284
284
|
* kumiko-renderer) — closed IconKey vocabulary into the ICONS registry
|
|
285
|
-
* (renderer
|
|
285
|
+
* (renderer/web), analogous to EditFieldSpec.icon. */
|
|
286
286
|
readonly icon?: IconKey;
|
|
287
287
|
/** Inline render form in the row-action column — see `RowActionDisplay`. */
|
|
288
288
|
readonly display?: RowActionDisplay;
|
|
@@ -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). */
|
|
@@ -947,12 +1056,27 @@ export type EditFieldSpec = string | {
|
|
|
947
1056
|
* rendering are unchanged. */
|
|
948
1057
|
readonly submit?: false;
|
|
949
1058
|
/** Prefix icon on the input — closed FieldIconKey vocabulary into
|
|
950
|
-
* the FIELD_ICONS registry (renderer
|
|
1059
|
+
* the FIELD_ICONS registry (renderer/web), analogous to
|
|
951
1060
|
* `ScreenNavSugar.icon` / NavIconKey. Only takes effect for
|
|
952
1061
|
* single-line `type: "text"` and `"number"` — a `text` field with
|
|
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[];
|
|
@@ -1013,7 +1151,7 @@ export type EditFieldsSection = {
|
|
|
1013
1151
|
readonly columns?: number;
|
|
1014
1152
|
}[];
|
|
1015
1153
|
/** Rendered left of the section title, `text-muted-foreground` — closed
|
|
1016
|
-
* IconKey vocabulary into the ICONS registry (renderer
|
|
1154
|
+
* IconKey vocabulary into the ICONS registry (renderer/web), analogous
|
|
1017
1155
|
* to EditFieldSpec.icon. No title → no icon, and no heuristic derives
|
|
1018
1156
|
* one from the title (titles are free i18n strings). */
|
|
1019
1157
|
readonly icon?: IconKey;
|
|
@@ -1469,6 +1607,24 @@ 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
|
+
/** Key figures from the handler's success payload, shown in the success box
|
|
1616
|
+
* while the screen stays put (e.g. charged/skipped/failed of a batch run).
|
|
1617
|
+
* Mutually exclusive with `redirect`. */
|
|
1618
|
+
readonly successFacts?: readonly ActionFormSuccessFact[];
|
|
1619
|
+
/** Reset the form to its initial values after a successful submit (prefill
|
|
1620
|
+
* kept, typed values cleared). Only applies while the screen stays put,
|
|
1621
|
+
* i.e. without `redirect`. */
|
|
1622
|
+
readonly resetOnSuccess?: boolean;
|
|
1623
|
+
/** Load the initial values from a query. The record id comes from the route
|
|
1624
|
+
* (or the drawer row id) and is sent as `{ [idParam]: id }`; the result,
|
|
1625
|
+
* picked to `fields`, becomes the initial values. Turns URL prefill off:
|
|
1626
|
+
* search params never reach the form. */
|
|
1627
|
+
readonly load?: ActionFormLoad;
|
|
1472
1628
|
/** Target of the Cancel button. Default: `redirect` (historical
|
|
1473
1629
|
* behavior — Cancel and the submit-redirect then land in the same
|
|
1474
1630
|
* place). `false` = no Cancel button; correct for single-action
|
|
@@ -1519,6 +1675,30 @@ export type ActionFormRedirect = {
|
|
|
1519
1675
|
* Boot rejects other targets and unknown section ids. */
|
|
1520
1676
|
readonly tab?: string;
|
|
1521
1677
|
};
|
|
1678
|
+
export type ActionFormLoad = {
|
|
1679
|
+
/** Query QN that returns the record. */
|
|
1680
|
+
readonly query: string;
|
|
1681
|
+
/** Payload key carrying the record id (default "id"). */
|
|
1682
|
+
readonly idParam?: string;
|
|
1683
|
+
};
|
|
1684
|
+
/** One key figure of the success box, read from the handler's success payload. */
|
|
1685
|
+
export type ActionFormSuccessFact = {
|
|
1686
|
+
/** Flat field name in the handler's success payload. A number or string is
|
|
1687
|
+
* shown as one value, an array a comma-separated list (numbers, strings and
|
|
1688
|
+
* `{ label }` objects). A missing field hides the fact. */
|
|
1689
|
+
readonly field: string;
|
|
1690
|
+
/** Label (i18n key). */
|
|
1691
|
+
readonly label: string;
|
|
1692
|
+
};
|
|
1693
|
+
/** A redirect target rendered as a link in the success box. */
|
|
1694
|
+
export type ActionFormSuccessLink = Omit<ActionFormRedirect, "idFrom"> & {
|
|
1695
|
+
/** Success-payload field carrying the navigation id. Required for a record
|
|
1696
|
+
* target (`entityEdit`, `projectionDetail`); omit it for a list, dashboard
|
|
1697
|
+
* or form target, which opens without an id. */
|
|
1698
|
+
readonly idFrom?: string;
|
|
1699
|
+
/** Link text (i18n key). */
|
|
1700
|
+
readonly label: string;
|
|
1701
|
+
};
|
|
1522
1702
|
/** Author-declared field shown once after a mint-form submit — API token,
|
|
1523
1703
|
* recovery codes, similar one-time secrets. */
|
|
1524
1704
|
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/dist/target-ref.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// TargetRef — runtime-Repräsentation eines typed buildTarget-Outputs.
|
|
2
|
-
// Wird vom Visual-Tree-Component (renderer
|
|
2
|
+
// Wird vom Visual-Tree-Component (renderer/web) an einen Target-Resolver
|
|
3
3
|
// dispatcht; der Resolver findet die Editor-Maske via featureId.
|
|
4
4
|
//
|
|
5
5
|
// **Compile-time-Safety:** TargetRef wird niemals hand-getippt. Stattdessen
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-types",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.377.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/changes.json
CHANGED
|
@@ -1,4 +1,24 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.377.0",
|
|
4
|
+
"type": "improvement",
|
|
5
|
+
"title": "outsideTransaction deprecated, ProviderPluginContext added",
|
|
6
|
+
"detail": "HandlerContext.outsideTransaction is marked deprecated; use runInOwnTransaction(ctx.dbOutsideTransaction, fn). ProviderPluginContext is a Pick of HandlerContext for provider plugins. SharedContextFields gains configAccessorFactory; _configAccessorFactory stays as a deprecated alias. dbOutsideTransaction stays TenantDb | undefined (undefined only in the member-resolution and before-transaction denial phases and in platform-metering tenant mode); hasOutsideTransactionDb(ctx) narrows it and requireOutsideTransactionDb(ctx) throws when it is missing.",
|
|
7
|
+
"migration": "Replace ctx.outsideTransaction(fn) with runInOwnTransaction(ctx.dbOutsideTransaction, fn). Read configAccessorFactory instead of _configAccessorFactory."
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"version": "0.377.0",
|
|
11
|
+
"type": "breaking",
|
|
12
|
+
"title": "JobContext._userId removed",
|
|
13
|
+
"detail": "The job runner never set JobContext._userId; only user-data-rights read it, falling back to SYSTEM_USER_ID. Hand-built JobContext objects that still set it fail to type-check, and code that read it must use SYSTEM_USER_ID or the job's system user.",
|
|
14
|
+
"migration": "Drop _userId from hand-built JobContext objects (tests, job helpers) and replace reads of ctx._userId with SYSTEM_USER_ID. Known hits - money-horse data-export integration test, offlot-app channel-text generate-texts.job.ts."
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"version": "0.376.0",
|
|
18
|
+
"type": "improvement",
|
|
19
|
+
"title": "StackBootRequirement severity and the featureToggles option name",
|
|
20
|
+
"detail": "StackBootRequirement takes severity \"warn\" for requirements that only log, and BootOptionName lists featureToggles."
|
|
21
|
+
},
|
|
2
22
|
{
|
|
3
23
|
"version": "0.370.0",
|
|
4
24
|
"type": "breaking",
|