@cosmicdrift/kumiko-types 0.393.0 → 0.395.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 +1 -0
- package/dist/define-handler.d.ts +7 -5
- package/dist/feature-registrar.d.ts +2 -2
- package/dist/feature.d.ts +2 -0
- package/dist/fields.d.ts +7 -9
- package/dist/handlers.d.ts +17 -4
- package/dist/kebab-case.d.ts +1 -0
- package/dist/kebab-case.js +14 -0
- package/dist/nav.d.ts +1 -1
- package/dist/screen-action-form.d.ts +3 -2
- package/dist/screen-custom-config.d.ts +4 -3
- package/dist/screen-dashboard.d.ts +2 -1
- package/dist/screen-entity-edit.d.ts +2 -1
- package/dist/screen-entity-list.d.ts +9 -3
- package/dist/screen-fallback.d.ts +16 -0
- package/dist/screen-fallback.js +16 -0
- package/dist/screen-projection.d.ts +3 -2
- package/dist/screen.d.ts +2 -0
- package/dist/screen.js +1 -0
- package/package.json +9 -1
package/dist/config.d.ts
CHANGED
|
@@ -144,6 +144,7 @@ export type JobHandlerFn = (payload: Record<string, unknown>, context: JobContex
|
|
|
144
144
|
export type JobTrigger = {
|
|
145
145
|
readonly on: import("./handlers.ts").NameOrRef | readonly import("./handlers.ts").NameOrRef[];
|
|
146
146
|
readonly where?: Readonly<Record<string, string | number | boolean>>;
|
|
147
|
+
readonly catchUp?: boolean;
|
|
147
148
|
} | {
|
|
148
149
|
readonly cron: string;
|
|
149
150
|
readonly tz?: string;
|
package/dist/define-handler.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type * as z from "zod";
|
|
2
2
|
import type { ZodType } from "zod";
|
|
3
3
|
import type { KumikoEventTypeMap } from "./event-type-map.ts";
|
|
4
|
-
import type { AccessRule, AgentHandlerHints, BeforeTransactionPhase, EscapeHatchDeclaration, HandlerContext, PayloadRateLimitOption, PreparedWriteEvent, PreTransactionReservation, QueryEvent, RateLimitDeclaration, WriteHandlerTransactionMode, WriteResult } from "./handlers.ts";
|
|
4
|
+
import type { AccessRule, AgentHandlerHints, BeforeTransactionPhase, BeforeTransactionWhenNested, EscapeHatchDeclaration, HandlerContext, PayloadRateLimitOption, PreparedOrSkipped, PreparedWriteEvent, PreTransactionReservation, QueryEvent, RateLimitDeclaration, WriteHandlerTransactionMode, WriteResult } from "./handlers.ts";
|
|
5
5
|
import type { PipelineDef } from "./step.ts";
|
|
6
|
-
export type WriteHandlerDefinition<TName extends string = string, TSchema extends ZodType = ZodType, TData = unknown, TMap extends object = KumikoEventTypeMap, TPrepared = undefined> = {
|
|
6
|
+
export type WriteHandlerDefinition<TName extends string = string, TSchema extends ZodType = ZodType, TData = unknown, TMap extends object = KumikoEventTypeMap, TPrepared = undefined, TWhenNested extends BeforeTransactionWhenNested | undefined = undefined> = {
|
|
7
7
|
readonly name: TName;
|
|
8
8
|
readonly schema: TSchema;
|
|
9
9
|
readonly access: AccessRule;
|
|
@@ -20,12 +20,13 @@ export type WriteHandlerDefinition<TName extends string = string, TSchema extend
|
|
|
20
20
|
readonly escapeHatch?: EscapeHatchDeclaration;
|
|
21
21
|
readonly reserveBeforeTransaction?: PreTransactionReservation;
|
|
22
22
|
readonly beforeTransaction?: BeforeTransactionPhase<z.infer<TSchema>, TPrepared>;
|
|
23
|
+
readonly beforeTransactionWhenNested?: TWhenNested;
|
|
23
24
|
readonly tenantlessAnonymous?: boolean;
|
|
24
25
|
readonly transaction?: WriteHandlerTransactionMode;
|
|
25
|
-
readonly handler: (event: PreparedWriteEvent<z.infer<TSchema>, TPrepared
|
|
26
|
+
readonly handler: (event: PreparedWriteEvent<z.infer<TSchema>, PreparedOrSkipped<TPrepared, TWhenNested>>, context: HandlerContext<TMap>) => Promise<WriteResult<TData>>;
|
|
26
27
|
readonly perform?: PipelineDef<z.infer<TSchema>, TData>;
|
|
27
28
|
};
|
|
28
|
-
export type WriteHandlerInput<TName extends string = string, TSchema extends ZodType = ZodType, TData = unknown, TMap extends object = KumikoEventTypeMap, TPrepared = undefined> = {
|
|
29
|
+
export type WriteHandlerInput<TName extends string = string, TSchema extends ZodType = ZodType, TData = unknown, TMap extends object = KumikoEventTypeMap, TPrepared = undefined, TWhenNested extends BeforeTransactionWhenNested | undefined = undefined> = {
|
|
29
30
|
readonly name: TName;
|
|
30
31
|
readonly schema: TSchema;
|
|
31
32
|
readonly access: AccessRule;
|
|
@@ -40,10 +41,11 @@ export type WriteHandlerInput<TName extends string = string, TSchema extends Zod
|
|
|
40
41
|
readonly escapeHatch?: EscapeHatchDeclaration;
|
|
41
42
|
readonly reserveBeforeTransaction?: PreTransactionReservation;
|
|
42
43
|
readonly beforeTransaction?: BeforeTransactionPhase<z.infer<TSchema>, TPrepared>;
|
|
44
|
+
readonly beforeTransactionWhenNested?: TWhenNested;
|
|
43
45
|
readonly tenantlessAnonymous?: boolean;
|
|
44
46
|
readonly transaction?: WriteHandlerTransactionMode;
|
|
45
47
|
} & ({
|
|
46
|
-
readonly handler: (event: PreparedWriteEvent<z.infer<TSchema>, TPrepared
|
|
48
|
+
readonly handler: (event: PreparedWriteEvent<z.infer<TSchema>, PreparedOrSkipped<TPrepared, TWhenNested>>, context: HandlerContext<TMap>) => Promise<WriteResult<TData>>;
|
|
47
49
|
readonly perform?: never;
|
|
48
50
|
} | {
|
|
49
51
|
readonly perform: PipelineDef<z.infer<TSchema>, TData>;
|
|
@@ -8,7 +8,7 @@ import type { KumikoEventTypeMap } from "./event-type-map.ts";
|
|
|
8
8
|
import type { ExtensionOptionsArgs, ExtensionOptionsFor } from "./extension-options-map.ts";
|
|
9
9
|
import type { BootCheckFn, MetricOptions, SecretKeyHandle, SecretNamespaceHandle, SecretNamespaceOptions, SecretOptions, StoreTableOptions, UiHints } from "./feature.ts";
|
|
10
10
|
import type { EntityDefinition } from "./fields.ts";
|
|
11
|
-
import type { AccessRule, AuthClaimsFn, ClaimKeyHandle, ClaimKeyType, DeclarativeEventMigration, EntityRef, EscapeHatchDeclaration, EventDef, EventPiiStance, EventUpcastFn, HandlerRef, NameOrRef, QualifiedEventName, RateLimitDeclaration, StreamHandlerFn } from "./handlers.ts";
|
|
11
|
+
import type { AccessRule, AuthClaimsFn, BeforeTransactionWhenNested, ClaimKeyHandle, ClaimKeyType, DeclarativeEventMigration, EntityRef, EscapeHatchDeclaration, EventDef, EventPiiStance, EventUpcastFn, HandlerRef, NameOrRef, QualifiedEventName, RateLimitDeclaration, StreamHandlerFn } from "./handlers.ts";
|
|
12
12
|
import type { HookPhase, PostDeleteHookFn, PostQueryHookFn, PostSaveHookFn, PreDeleteHookFn, PreSaveHookFn, SearchPayloadContributorFn, ValidationHookFn } from "./hooks.ts";
|
|
13
13
|
import type { HttpRouteDefinition } from "./http-route.ts";
|
|
14
14
|
import type { ContentCollectionDefinition, NavDefinition } from "./nav.ts";
|
|
@@ -109,7 +109,7 @@ export type FeatureRegistrar<TFeature extends string = string> = {
|
|
|
109
109
|
/**
|
|
110
110
|
* @example r.writeHandler({ name: "note:archive", schema, handler, access: { roles: ["User"] } });
|
|
111
111
|
*/
|
|
112
|
-
writeHandler<TName extends string, TSchema extends ZodType, TPrepared = undefined>(def: WriteHandlerDefinition<TName, TSchema, unknown, KumikoEventTypeMap, TPrepared>): HandlerRef;
|
|
112
|
+
writeHandler<TName extends string, TSchema extends ZodType, TPrepared = undefined, TWhenNested extends BeforeTransactionWhenNested | undefined = undefined>(def: WriteHandlerDefinition<TName, TSchema, unknown, KumikoEventTypeMap, TPrepared, TWhenNested>): HandlerRef;
|
|
113
113
|
/**
|
|
114
114
|
* @example r.queryHandler({ name: "note:list", schema, handler, access: { roles: ["User"] } });
|
|
115
115
|
*/
|
package/dist/feature.d.ts
CHANGED
|
@@ -201,6 +201,8 @@ export type Registry = {
|
|
|
201
201
|
readonly features: ReadonlyMap<string, FeatureDefinition>;
|
|
202
202
|
getFeature(name: string): FeatureDefinition | undefined;
|
|
203
203
|
getEntity(name: string): EntityDefinition | undefined;
|
|
204
|
+
getReadModelEntity(name: string): EntityDefinition | undefined;
|
|
205
|
+
getReadModelEntityOwner(name: string): string | undefined;
|
|
204
206
|
getAllEntities(): ReadonlyMap<string, EntityDefinition>;
|
|
205
207
|
getWriteHandler(name: string): WriteHandlerDef | undefined;
|
|
206
208
|
getQueryHandler(name: string): QueryHandlerDef | undefined;
|
package/dist/fields.d.ts
CHANGED
|
@@ -858,15 +858,13 @@ export type EntityDefinition<F extends FieldsMap = FieldsMap, T extends EntityTe
|
|
|
858
858
|
readonly derivedFields?: DerivedFieldsMap;
|
|
859
859
|
/** Optional free-text semantics for the AI agent manifest — see TextFieldDef.description. */
|
|
860
860
|
readonly description?: string;
|
|
861
|
-
/**
|
|
862
|
-
*
|
|
863
|
-
|
|
864
|
-
*
|
|
865
|
-
* An entity reachable from a transfer's root — the root itself, or any
|
|
866
|
-
* entity whose `parentRef` names the root's type — that is NOT declared
|
|
867
|
-
* `transferable: true` makes the whole transfer fail with a named error
|
|
868
|
-
* instead of silently leaving that entity's rows behind.
|
|
869
|
-
*/
|
|
861
|
+
/** Opts the rows into `tenant-handover`, a grant-legitimated move from an anonymous tenant to the
|
|
862
|
+
* signed-up account's tenant. An entity reachable from a transfer's root (the root, or one whose
|
|
863
|
+
* `parentRef` names the root's type) without `transferable: true` fails the whole transfer with
|
|
864
|
+
* a named error instead of silently leaving its rows behind. */
|
|
870
865
|
readonly transferable?: boolean;
|
|
866
|
+
/** Attached files are readable only through the record's detail query: the files feature's
|
|
867
|
+
* privilegedRoles do not bypass it, the uploader check stays. */
|
|
868
|
+
readonly attachedFileAccess?: "record-only";
|
|
871
869
|
};
|
|
872
870
|
export {};
|
package/dist/handlers.d.ts
CHANGED
|
@@ -132,6 +132,7 @@ export type JobTriggerEvent = {
|
|
|
132
132
|
};
|
|
133
133
|
export type JobRunnerRef = {
|
|
134
134
|
handleEvent(eventName: string, payload: Record<string, unknown>, user?: SessionUser, triggerEvent?: JobTriggerEvent): Promise<void>;
|
|
135
|
+
handleCatchUpEvent?(jobName: string, eventName: string, payload: Record<string, unknown>, user: SessionUser, triggerEvent: JobTriggerEvent): Promise<void>;
|
|
135
136
|
dispatch?(jobName: string, payload: Record<string, unknown>, meta?: {
|
|
136
137
|
readonly priority?: number;
|
|
137
138
|
readonly jobId?: string;
|
|
@@ -261,10 +262,11 @@ export type AppContext = SharedContextFields & {
|
|
|
261
262
|
readonly tenantId: TenantId;
|
|
262
263
|
} | null;
|
|
263
264
|
/** For job-handler calls triggered by an event
|
|
264
|
-
* (`r.job` with `trigger: { on: ... }`): the name of the
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
*
|
|
265
|
+
* (`r.job` with `trigger: { on: ... }`): the qualified name of the event
|
|
266
|
+
* that fired the trigger, e.g. `inbound-mail-foundation:event:inbound-message-received`.
|
|
267
|
+
* For multi-trigger jobs (`on: [...]`), this is the only way for the
|
|
268
|
+
* handler to know which trigger fired. Cron and manual jobs leave the
|
|
269
|
+
* field undefined. */
|
|
268
270
|
readonly triggerName?: string;
|
|
269
271
|
/** Optional Geo→zone adapter. When set (via buildServer context or
|
|
270
272
|
* `runProdApp`/`runDevApp` `extraContext`), the dispatcher passes it to
|
|
@@ -550,6 +552,12 @@ export type BeforeTransactionResult<TPrepared = unknown> = {
|
|
|
550
552
|
export type BeforeTransactionPhase<TPayload = unknown, TPrepared = unknown> = (event: WriteEvent<TPayload>, ctx: BeforeTransactionContext) => Promise<BeforeTransactionResult<TPrepared>>;
|
|
551
553
|
/** `perCommand`: the handler runs without a transaction of its own. */
|
|
552
554
|
export type WriteHandlerTransactionMode = "perCommand";
|
|
555
|
+
/** `skip`: run as a nested write without the `beforeTransaction` phase. */
|
|
556
|
+
export type BeforeTransactionWhenNested = "skip";
|
|
557
|
+
/** The `prepared` type a handler sees: with `beforeTransactionWhenNested: "skip"` a nested run leaves it undefined. */
|
|
558
|
+
export type PreparedOrSkipped<TPrepared, TWhenNested> = [TWhenNested] extends [
|
|
559
|
+
BeforeTransactionWhenNested
|
|
560
|
+
] ? TPrepared | undefined : TPrepared;
|
|
553
561
|
export type WriteHandlerDef = {
|
|
554
562
|
readonly name: string;
|
|
555
563
|
readonly schema: ZodType;
|
|
@@ -579,6 +587,11 @@ export type WriteHandlerDef = {
|
|
|
579
587
|
* `ctx.tenants.writeTarget` is available but read-only here: its db denies writes for the own and a
|
|
580
588
|
* foreign tenant alike (a foreign tenant stays gated by the SystemAdmin check). */
|
|
581
589
|
readonly beforeTransaction?: BeforeTransactionPhase;
|
|
590
|
+
/** `"skip"`: a nested ctx.dispatch.write of this handler runs without the beforeTransaction phase
|
|
591
|
+
* (`event.prepared` is undefined) and without a reservation, so the handler does that work inside
|
|
592
|
+
* its own transaction. Top-level commands still run the phase. Requires beforeTransaction; not
|
|
593
|
+
* combinable with reserveBeforeTransaction or transaction: "perCommand". */
|
|
594
|
+
readonly beforeTransactionWhenNested?: BeforeTransactionWhenNested;
|
|
582
595
|
/** `"perCommand"`: the handler runs without a transaction of its own. Every ctx.dispatch.write/writeAs it
|
|
583
596
|
* issues runs as its own top-level command with its own transaction and afterCommit hooks;
|
|
584
597
|
* ctx.db writes and event appends throw. It cannot run as a nested write or inside a
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function toKebab(input: string): string;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Convert camelCase or dot.separated strings to kebab-case.
|
|
2
|
+
// "task.create" → "task-create"
|
|
3
|
+
// "ticketAssigned" → "ticket-assigned"
|
|
4
|
+
// "billing-period.create" → "billing-period-create"
|
|
5
|
+
// "monthlyReport" → "monthly-report"
|
|
6
|
+
// Already kebab-case → unchanged
|
|
7
|
+
// Colons are preserved: "task:create" → "task:create"
|
|
8
|
+
export function toKebab(input) {
|
|
9
|
+
return input
|
|
10
|
+
.replace(/\./g, "-") // dots → dashes
|
|
11
|
+
.replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2") // consecutive uppercase: SSEBroadcast → SSE-Broadcast
|
|
12
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1-$2") // camelCase boundaries: ticketAssigned → ticket-Assigned
|
|
13
|
+
.toLowerCase();
|
|
14
|
+
}
|
package/dist/nav.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export type NavDefinition = {
|
|
|
18
18
|
readonly workspaces?: readonly string[];
|
|
19
19
|
};
|
|
20
20
|
/** Client editor format for r.contentCollection() — not template body storage formats. */
|
|
21
|
-
export type ContentEditorFormat = "plain" | "
|
|
21
|
+
export type ContentEditorFormat = "plain" | "document";
|
|
22
22
|
export type ContentCollectionDefinition = {
|
|
23
23
|
readonly id: string;
|
|
24
24
|
readonly kind: string;
|
|
@@ -4,6 +4,7 @@ import type { IconKey } from "./nav-icon.ts";
|
|
|
4
4
|
import type { ScreenNavSugar, ScreenSlots } from "./screen.ts";
|
|
5
5
|
import type { ScreenVisibility } from "./screen-dashboard.ts";
|
|
6
6
|
import type { EditLayout } from "./screen-entity-edit.ts";
|
|
7
|
+
import type { ScreenFallback } from "./screen-fallback.ts";
|
|
7
8
|
/** A form field computed from other fields of the same form. `listSum` adds one
|
|
8
9
|
* numeric cell over all rows of an embedded list field; its `whenEmpty`
|
|
9
10
|
* fallback applies while the list has no rows (it must not be a `listSum`). */
|
|
@@ -37,7 +38,7 @@ export type ActionFormScreenDefinition = {
|
|
|
37
38
|
/** UI-only gate, also on direct URL access; handlers still enforce access. Unmet or failed renders `fallback`. */
|
|
38
39
|
readonly visibleWhen?: ScreenVisibility;
|
|
39
40
|
/** Same-feature short id or cross-feature QN `<feature>:screen:<id>` shown when `visibleWhen` is unmet (default: standard notice). */
|
|
40
|
-
readonly fallback?:
|
|
41
|
+
readonly fallback?: ScreenFallback;
|
|
41
42
|
/** Derived by buildAppSchema — see EntityEditScreenDefinition.urlPrefillFields. */
|
|
42
43
|
readonly urlPrefillFields?: readonly string[];
|
|
43
44
|
/** Derived by buildAppSchema from the `excludedFields` of the called `handler`; the form
|
|
@@ -274,7 +275,7 @@ export type SecretMintScreenDefinition = {
|
|
|
274
275
|
/** UI-only gate, also on direct URL access; handlers still enforce access. Unmet or failed renders `fallback`. */
|
|
275
276
|
readonly visibleWhen?: ScreenVisibility;
|
|
276
277
|
/** Same-feature short id or cross-feature QN `<feature>:screen:<id>` shown when `visibleWhen` is unmet (default: standard notice). */
|
|
277
|
-
readonly fallback?:
|
|
278
|
+
readonly fallback?: ScreenFallback;
|
|
278
279
|
/** Derived by buildAppSchema — see EntityEditScreenDefinition.urlPrefillFields. */
|
|
279
280
|
readonly urlPrefillFields?: readonly string[];
|
|
280
281
|
/** Submit is enabled without edits: values seeded from navigate `params` count as the
|
|
@@ -3,6 +3,7 @@ import type { AccessRule, AgentScreenHints } from "./handlers.ts";
|
|
|
3
3
|
import type { PlatformComponent, ScreenNavSugar, ScreenSlots } from "./screen.ts";
|
|
4
4
|
import type { ScreenVisibility } from "./screen-dashboard.ts";
|
|
5
5
|
import type { EditLayout } from "./screen-entity-edit.ts";
|
|
6
|
+
import type { ScreenFallback } from "./screen-fallback.ts";
|
|
6
7
|
export type CustomScreenRoute = {
|
|
7
8
|
readonly path: string;
|
|
8
9
|
readonly component: PlatformComponent;
|
|
@@ -32,7 +33,7 @@ export type CustomScreenDefinition = {
|
|
|
32
33
|
/** UI-only gate, also on direct URL access; handlers still enforce access. Unmet or failed renders `fallback`. */
|
|
33
34
|
readonly visibleWhen?: ScreenVisibility;
|
|
34
35
|
/** Same-feature short id or cross-feature QN `<feature>:screen:<id>` shown when `visibleWhen` is unmet (default: standard notice). */
|
|
35
|
-
readonly fallback?:
|
|
36
|
+
readonly fallback?: ScreenFallback;
|
|
36
37
|
};
|
|
37
38
|
export type ConfigEditScreenDefinition = {
|
|
38
39
|
readonly id: string;
|
|
@@ -50,7 +51,7 @@ export type ConfigEditScreenDefinition = {
|
|
|
50
51
|
/** UI-only gate, also on direct URL access; handlers still enforce access. Unmet or failed renders `fallback`. */
|
|
51
52
|
readonly visibleWhen?: ScreenVisibility;
|
|
52
53
|
/** Same-feature short id or cross-feature QN `<feature>:screen:<id>` shown when `visibleWhen` is unmet (default: standard notice). */
|
|
53
|
-
readonly fallback?:
|
|
54
|
+
readonly fallback?: ScreenFallback;
|
|
54
55
|
/** scope for config:write:set calls. Must match the scope declaration of
|
|
55
56
|
* the keys referenced in `configKeys` — the boot validator checks that
|
|
56
57
|
* against the registry. */
|
|
@@ -103,7 +104,7 @@ export type SecretsEditScreenDefinition = {
|
|
|
103
104
|
/** UI-only gate, also on direct URL access; handlers still enforce access. Unmet or failed renders `fallback`. */
|
|
104
105
|
readonly visibleWhen?: ScreenVisibility;
|
|
105
106
|
/** Same-feature short id or cross-feature QN `<feature>:screen:<id>` shown when `visibleWhen` is unmet (default: standard notice). */
|
|
106
|
-
readonly fallback?:
|
|
107
|
+
readonly fallback?: ScreenFallback;
|
|
107
108
|
/** field id -> qualified secret name (`<feature>:secret:<kebab>`). */
|
|
108
109
|
readonly secretKeys: Readonly<Record<string, string>>;
|
|
109
110
|
/** field id -> i18n key for the label. */
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AccessRule, AgentScreenHints } from "./handlers.ts";
|
|
2
2
|
import type { PlatformComponent, ScreenNavSugar, ScreenSlots } from "./screen.ts";
|
|
3
3
|
import type { ListColumnSpec, RowAction } from "./screen-entity-list.ts";
|
|
4
|
+
import type { ScreenFallback } from "./screen-fallback.ts";
|
|
4
5
|
/** Text a query handler can send untranslated: the renderer translates it. */
|
|
5
6
|
export type DashboardI18nText = {
|
|
6
7
|
readonly i18nKey: string;
|
|
@@ -331,7 +332,7 @@ export type DashboardScreenDefinition = {
|
|
|
331
332
|
/** UI-only gate, also on direct URL access; handlers still enforce access. Unmet or failed renders `fallback`. */
|
|
332
333
|
readonly visibleWhen?: ScreenVisibility;
|
|
333
334
|
/** Same-feature short id or cross-feature QN `<feature>:screen:<id>` shown when `visibleWhen` is unmet (default: standard notice). */
|
|
334
|
-
readonly fallback?:
|
|
335
|
+
readonly fallback?: ScreenFallback;
|
|
335
336
|
readonly panels: readonly DashboardPanelDefinition[];
|
|
336
337
|
/** Binds the dashboard to one record via a URL search param, see DashboardRecordBinding. */
|
|
337
338
|
readonly record?: DashboardRecordBinding;
|
|
@@ -6,6 +6,7 @@ import type { FieldRenderer, PlatformComponent, ScreenNavSugar, ScreenSlots } fr
|
|
|
6
6
|
import type { ActionFormRedirect } from "./screen-action-form.ts";
|
|
7
7
|
import type { ScreenVisibility } from "./screen-dashboard.ts";
|
|
8
8
|
import type { ListColumnSpec, ListSortSpec, RelatedListToolbarAction, RowAction, RowActionMode, RowFieldExtractor } from "./screen-entity-list.ts";
|
|
9
|
+
import type { ScreenFallback } from "./screen-fallback.ts";
|
|
9
10
|
import type { ListBulkAction } from "./screen-list-bulk.ts";
|
|
10
11
|
import type { ListTableGrouping, ListTableOptions } from "./screen-list-table.ts";
|
|
11
12
|
import type { ListFacetSpec } from "./screen-projection.ts";
|
|
@@ -391,7 +392,7 @@ export type EntityEditScreenDefinition = {
|
|
|
391
392
|
/** UI-only gate, also on direct URL access; handlers still enforce access. Unmet or failed renders `fallback`. */
|
|
392
393
|
readonly visibleWhen?: ScreenVisibility;
|
|
393
394
|
/** Same-feature short id or cross-feature QN `<feature>:screen:<id>` shown when `visibleWhen` is unmet (default: standard notice). */
|
|
394
|
-
readonly fallback?:
|
|
395
|
+
readonly fallback?: ScreenFallback;
|
|
395
396
|
/** Derived by buildAppSchema from the navigate `params` targeting this
|
|
396
397
|
* screen — the only URL query keys the create form prefills. An authored
|
|
397
398
|
* value is overwritten. */
|
|
@@ -3,9 +3,10 @@ import type { AccessRule, AgentScreenHints } from "./handlers.ts";
|
|
|
3
3
|
import type { IconKey } from "./nav-icon.ts";
|
|
4
4
|
import type { FieldRenderer, PlatformComponent, ScreenNavSugar, ScreenSlots } from "./screen.ts";
|
|
5
5
|
import type { ActionFormRedirect } from "./screen-action-form.ts";
|
|
6
|
-
import type { ScreenVisibility } from "./screen-dashboard.ts";
|
|
6
|
+
import type { DashboardPanelVisibility, ScreenVisibility } from "./screen-dashboard.ts";
|
|
7
7
|
import type { ListEmptyStateSpec } from "./screen-entity-edit.ts";
|
|
8
8
|
import type { EntityListExpandableRow } from "./screen-expandable-row.ts";
|
|
9
|
+
import type { ScreenFallback } from "./screen-fallback.ts";
|
|
9
10
|
import type { ListBulkAction } from "./screen-list-bulk.ts";
|
|
10
11
|
import type { ListColumnPin, ListTableOptions } from "./screen-list-table.ts";
|
|
11
12
|
export type ListColumnSpec = string | {
|
|
@@ -274,7 +275,7 @@ export type RowActionClientAction = {
|
|
|
274
275
|
* (default `kumiko.clientAction.success`). */
|
|
275
276
|
readonly successMessage?: string;
|
|
276
277
|
};
|
|
277
|
-
export type ToolbarAction = {
|
|
278
|
+
export type ToolbarAction = ({
|
|
278
279
|
readonly kind: "navigate";
|
|
279
280
|
readonly id: string;
|
|
280
281
|
readonly label: string;
|
|
@@ -319,6 +320,11 @@ export type ToolbarAction = {
|
|
|
319
320
|
readonly title?: string;
|
|
320
321
|
/** Line under the drawer heading (i18n key). */
|
|
321
322
|
readonly subtitle?: string;
|
|
323
|
+
}) & {
|
|
324
|
+
/** Shown only while the query's `field` equals `eq` (live, empty payload). Hidden while the
|
|
325
|
+
* query loads and when it fails. Named like the screen and panel gates because it is
|
|
326
|
+
* query-based; a list toolbar has no record to evaluate a row condition against. */
|
|
327
|
+
readonly visibleWhen?: DashboardPanelVisibility;
|
|
322
328
|
};
|
|
323
329
|
export type RelatedListToolbarAction = (Extract<ToolbarAction, {
|
|
324
330
|
readonly kind: "navigate";
|
|
@@ -390,7 +396,7 @@ export type EntityListScreenDefinition = {
|
|
|
390
396
|
/** UI-only gate, also on direct URL access; handlers still enforce access. Unmet or failed renders `fallback`. */
|
|
391
397
|
readonly visibleWhen?: ScreenVisibility;
|
|
392
398
|
/** Same-feature short id or cross-feature QN `<feature>:screen:<id>` shown when `visibleWhen` is unmet (default: standard notice). */
|
|
393
|
-
readonly fallback?:
|
|
399
|
+
readonly fallback?: ScreenFallback;
|
|
394
400
|
readonly entity: string;
|
|
395
401
|
/** Short screen id (same feature) the create button opens instead of the entity's default edit screen. */
|
|
396
402
|
readonly createScreen?: string;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Why a screen gate is not open. `hidden`: the gate query answered but the condition is unmet
|
|
2
|
+
* (also a missing route id with `idParam`); `forbidden`/`notFound`: the gate query failed with
|
|
3
|
+
* HTTP 403/404; `error`: any other failure. */
|
|
4
|
+
export type ScreenFallbackReason = "hidden" | "forbidden" | "notFound" | "error";
|
|
5
|
+
/** Per-reason fallback screens (same-feature short id or cross-feature QN). A reason without an
|
|
6
|
+
* entry gets the default notice. At least one key is required. */
|
|
7
|
+
export type ScreenFallbackByReason = {
|
|
8
|
+
readonly [Reason in ScreenFallbackReason]?: string;
|
|
9
|
+
};
|
|
10
|
+
/** Screen-level `fallback`: one screen for every reason, or one per reason. */
|
|
11
|
+
export type ScreenFallback = string | ScreenFallbackByReason;
|
|
12
|
+
export declare const SCREEN_FALLBACK_REASONS: readonly ScreenFallbackReason[];
|
|
13
|
+
/** The fallback screen for one reason, or undefined when the map has no entry for it. */
|
|
14
|
+
export declare function fallbackTargetFor(fallback: ScreenFallback, reason: ScreenFallbackReason): string | undefined;
|
|
15
|
+
/** Every screen a fallback can render, in reason order. */
|
|
16
|
+
export declare function fallbackTargets(fallback: ScreenFallback): readonly string[];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const SCREEN_FALLBACK_REASONS = [
|
|
2
|
+
"hidden",
|
|
3
|
+
"forbidden",
|
|
4
|
+
"notFound",
|
|
5
|
+
"error",
|
|
6
|
+
];
|
|
7
|
+
/** The fallback screen for one reason, or undefined when the map has no entry for it. */
|
|
8
|
+
export function fallbackTargetFor(fallback, reason) {
|
|
9
|
+
return typeof fallback === "string" ? fallback : fallback[reason];
|
|
10
|
+
}
|
|
11
|
+
/** Every screen a fallback can render, in reason order. */
|
|
12
|
+
export function fallbackTargets(fallback) {
|
|
13
|
+
if (typeof fallback === "string")
|
|
14
|
+
return [fallback];
|
|
15
|
+
return SCREEN_FALLBACK_REASONS.flatMap((reason) => fallback[reason] ?? []);
|
|
16
|
+
}
|
|
@@ -5,6 +5,7 @@ import type { FormatSpec, PlatformComponent, ScreenNavSugar, ScreenSlots } from
|
|
|
5
5
|
import type { DashboardStatTone, ScreenVisibility } from "./screen-dashboard.ts";
|
|
6
6
|
import type { EditLayout, ListEmptyStateSpec } from "./screen-entity-edit.ts";
|
|
7
7
|
import type { ListColumnSpec, ListPaginationMode, ListSortSpec, RowAction, RowActionMode, RowFieldExtractor, ScreenFilter, ToolbarAction } from "./screen-entity-list.ts";
|
|
8
|
+
import type { ScreenFallback } from "./screen-fallback.ts";
|
|
8
9
|
import type { ListBulkAction } from "./screen-list-bulk.ts";
|
|
9
10
|
import type { ListTableOptions } from "./screen-list-table.ts";
|
|
10
11
|
export type ListFacetSpec = {
|
|
@@ -66,7 +67,7 @@ export type ProjectionListScreenDefinition = {
|
|
|
66
67
|
/** UI-only gate, also on direct URL access; handlers still enforce access. Unmet or failed renders `fallback`. */
|
|
67
68
|
readonly visibleWhen?: ScreenVisibility;
|
|
68
69
|
/** Same-feature short id or cross-feature QN `<feature>:screen:<id>` shown when `visibleWhen` is unmet (default: standard notice). */
|
|
69
|
-
readonly fallback?:
|
|
70
|
+
readonly fallback?: ScreenFallback;
|
|
70
71
|
readonly query: string;
|
|
71
72
|
readonly columns: readonly ListColumnSpec[];
|
|
72
73
|
readonly rowRenderer?: PlatformComponent;
|
|
@@ -176,7 +177,7 @@ export type ProjectionDetailScreenDefinition = {
|
|
|
176
177
|
/** UI-only gate, also on direct URL access; handlers still enforce access. Unmet or failed renders `fallback`. */
|
|
177
178
|
readonly visibleWhen?: ScreenVisibility;
|
|
178
179
|
/** Same-feature short id or cross-feature QN `<feature>:screen:<id>` shown when `visibleWhen` is unmet (default: standard notice). */
|
|
179
|
-
readonly fallback?:
|
|
180
|
+
readonly fallback?: ScreenFallback;
|
|
180
181
|
readonly query: string;
|
|
181
182
|
/** Query output field whose value titles the page header (breadcrumb) when no `header` is set. */
|
|
182
183
|
readonly recordTitleField?: string;
|
package/dist/screen.d.ts
CHANGED
|
@@ -123,6 +123,8 @@ export type { EditExtensionSection, EditFieldGroup, EditFieldPrefill, EditFieldS
|
|
|
123
123
|
export { relatedListGroupHeaderLabel, relatedListGroupKey } from "./screen-entity-edit.ts";
|
|
124
124
|
export type { EntityListFacetConfig, EntityListFacetExtraOption, EntityListScreenDefinition, ListBadgeTone, ListColumnDisplay, ListColumnSpec, ListPaginationMode, ListSortDir, ListSortSpec, RelatedListToolbarAction, RowAction, RowActionClientAction, RowActionDisplay, RowActionDrawer, RowActionMode, RowActionNavigate, RowActionNavigateBase, RowActionWriteHandler, RowFieldExtractor, ScreenFilter, ScreenFilterOp, ToolbarAction, } from "./screen-entity-list.ts";
|
|
125
125
|
export type { EntityListExpandableRow, ExpandableRowGrouping } from "./screen-expandable-row.ts";
|
|
126
|
+
export type { ScreenFallback, ScreenFallbackByReason, ScreenFallbackReason, } from "./screen-fallback.ts";
|
|
127
|
+
export { fallbackTargetFor, fallbackTargets, SCREEN_FALLBACK_REASONS } from "./screen-fallback.ts";
|
|
126
128
|
export type { ListBulkAction } from "./screen-list-bulk.ts";
|
|
127
129
|
export { LIST_BULK_ACTION_KEYS, MAX_BULK_SELECTION } from "./screen-list-bulk.ts";
|
|
128
130
|
export type { BundledListsOptions, ListColumnPin, ListTableDensity, ListTableExportOptions, ListTableGrouping, ListTableOptions, ListTableTotal, } from "./screen-list-table.ts";
|
package/dist/screen.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { DASHBOARD_MIN_REFRESH_SECONDS, DASHBOARD_STAT_TONES } from "./screen-dashboard.js";
|
|
2
2
|
export { relatedListGroupHeaderLabel, relatedListGroupKey } from "./screen-entity-edit.js";
|
|
3
|
+
export { fallbackTargetFor, fallbackTargets, SCREEN_FALLBACK_REASONS } from "./screen-fallback.js";
|
|
3
4
|
export { LIST_BULK_ACTION_KEYS, MAX_BULK_SELECTION } from "./screen-list-bulk.js";
|
|
4
5
|
export { DEFAULT_EXPORT_MAX_ROWS, LIST_COLUMN_PINS, LIST_TABLE_DENSITIES, LIST_TABLE_DENSITY_KEYS, LIST_TABLE_EXPORT_KEYS, LIST_TABLE_GROUPING_KEYS, LIST_TABLE_OPTION_KEYS, LIST_TABLE_TOTAL_KEYS, MAX_EXPORT_MAX_ROWS, } from "./screen-list-table.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-types",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.395.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": "MIT",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -22,6 +22,10 @@
|
|
|
22
22
|
"types": "./dist/index.d.ts",
|
|
23
23
|
"default": "./dist/index.js"
|
|
24
24
|
},
|
|
25
|
+
"./kebab-case": {
|
|
26
|
+
"types": "./dist/kebab-case.d.ts",
|
|
27
|
+
"default": "./dist/kebab-case.js"
|
|
28
|
+
},
|
|
25
29
|
"./identifiers": {
|
|
26
30
|
"types": "./dist/identifiers.d.ts",
|
|
27
31
|
"default": "./dist/identifiers.js"
|
|
@@ -313,6 +317,10 @@
|
|
|
313
317
|
"types": "./dist/index.d.ts",
|
|
314
318
|
"default": "./dist/index.js"
|
|
315
319
|
},
|
|
320
|
+
"./kebab-case": {
|
|
321
|
+
"types": "./dist/kebab-case.d.ts",
|
|
322
|
+
"default": "./dist/kebab-case.js"
|
|
323
|
+
},
|
|
316
324
|
"./identifiers": {
|
|
317
325
|
"types": "./dist/identifiers.d.ts",
|
|
318
326
|
"default": "./dist/identifiers.js"
|