@cosmicdrift/kumiko-types 0.351.0 → 0.353.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/agent-exposure.d.ts +2 -2
- package/dist/entity-handlers.d.ts +3 -0
- package/dist/fields.d.ts +13 -1
- package/dist/fields.js +1 -0
- package/dist/handlers.d.ts +22 -8
- package/dist/kms-adapter-types.d.ts +1 -0
- package/dist/kms-adapter-types.js +3 -0
- package/dist/screen.d.ts +18 -13
- package/package.json +1 -1
- package/src/changes.json +13 -0
package/dist/agent-exposure.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentExposure, AgentHandlerHints } from "./handlers.js";
|
|
1
|
+
import type { AgentExposure, AgentHandlerHints, AgentScreenHints } from "./handlers.js";
|
|
2
2
|
/** Fail-closed: a handler without a `description` stays invisible to the agent
|
|
3
3
|
* unless it opts in explicitly. `kind` is a parameter because write and query
|
|
4
4
|
* handler definitions are structurally indistinguishable at runtime. */
|
|
@@ -11,5 +11,5 @@ export declare function resolveAgentExposure(def: {
|
|
|
11
11
|
* Reusing `resolveAgentExposure`'s fail-closed default here would silently
|
|
12
12
|
* drop every screen without a description from the agent's view. */
|
|
13
13
|
export declare function isAgentVisibleScreen(screen: {
|
|
14
|
-
readonly agent?:
|
|
14
|
+
readonly agent?: AgentScreenHints;
|
|
15
15
|
}): boolean;
|
|
@@ -43,6 +43,9 @@ export type RegisterEntityCrudOptions = {
|
|
|
43
43
|
* manifest exposes only the verbs described here (fail-closed, same rule as
|
|
44
44
|
* hand-written handlers). Falls back to `write.description`/`read.description`. */
|
|
45
45
|
readonly descriptions?: Partial<Record<EntityCrudVerb, string>>;
|
|
46
|
+
/** Per-verb agent hints; win over `write.agent`/`read.agent`, so one irreversible
|
|
47
|
+
* verb (e.g. a hard delete) can be `risk: "high"` without raising create/update. */
|
|
48
|
+
readonly agents?: Partial<Record<EntityCrudVerb, AgentHandlerHints>>;
|
|
46
49
|
/** Per-verb `excludeFields` for the generic create/update handlers — see
|
|
47
50
|
* EntityWriteHandlerOptions. */
|
|
48
51
|
readonly excludeFields?: Partial<Record<"create" | "update", readonly string[]>>;
|
package/dist/fields.d.ts
CHANGED
|
@@ -80,6 +80,9 @@ export type TextFieldDef = {
|
|
|
80
80
|
* the i18n label is what users see. */
|
|
81
81
|
readonly description?: string;
|
|
82
82
|
readonly maxLength?: number;
|
|
83
|
+
/** Lower bound enforced by the generated write schema, so short input is
|
|
84
|
+
* rejected by validation instead of reaching the handler. */
|
|
85
|
+
readonly minLength?: number;
|
|
83
86
|
readonly required?: boolean;
|
|
84
87
|
readonly searchable?: boolean;
|
|
85
88
|
readonly sortable?: boolean;
|
|
@@ -171,7 +174,8 @@ export type BooleanFieldDef = {
|
|
|
171
174
|
readonly default?: boolean;
|
|
172
175
|
readonly access?: FieldAccess;
|
|
173
176
|
};
|
|
174
|
-
export
|
|
177
|
+
export declare const SELECT_OPTION_TONES: readonly ["ok", "warn", "bad", "neutral"];
|
|
178
|
+
export type SelectOptionTone = (typeof SELECT_OPTION_TONES)[number];
|
|
175
179
|
/** One `optionsQueryPayload` entry: a literal, or `{ field }` = the current value of
|
|
176
180
|
* a sibling field of the same form (config keys: another key of the owner feature). */
|
|
177
181
|
export type OptionsQueryPayloadValue = string | number | boolean | {
|
|
@@ -213,6 +217,14 @@ export type SelectFieldDef<TOptions extends readonly string[] = readonly string[
|
|
|
213
217
|
/** Payload sent with every `optionsQuery` call. `{ field }` entries re-load the
|
|
214
218
|
* options when that sibling field changes. */
|
|
215
219
|
readonly optionsQueryPayload?: OptionsQueryPayload;
|
|
220
|
+
/** Marks static options as unavailable per tenant (e.g. by tier). Contract:
|
|
221
|
+
* `{ rows: { value: string; disabled?: boolean; hint?: string }[] }`. The renderer
|
|
222
|
+
* loads it (with `optionsQueryPayload` resolved like for `optionsQuery`, `{}` when
|
|
223
|
+
* absent) and merges it onto `options`: `disabled` disables the option, `hint` becomes
|
|
224
|
+
* its description. The currently stored value always stays enabled; unknown values
|
|
225
|
+
* are ignored. Static `options` stay authoritative, and the write path must enforce
|
|
226
|
+
* the same rule (see `withTierOptionGate`), the renderer only mirrors it. */
|
|
227
|
+
readonly optionsAvailabilityQuery?: string;
|
|
216
228
|
} & ResolvedPiiFlags;
|
|
217
229
|
export type MultiSelectFieldDef<TOptions extends readonly string[] = readonly string[]> = {
|
|
218
230
|
readonly type: "multiSelect";
|
package/dist/fields.js
CHANGED
package/dist/handlers.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { Redis } from "ioredis";
|
|
|
2
2
|
import type { ZodType } from "zod";
|
|
3
3
|
import type { CacheSyncBus } from "./cache-sync-types.js";
|
|
4
4
|
import type { ConfigAccessor, ConfigAccessorFactory, ConfigResolver } from "./config.js";
|
|
5
|
-
import type { DbConnection } from "./db-connection.js";
|
|
5
|
+
import type { DbConnection, DbTx } from "./db-connection.js";
|
|
6
6
|
import type { DerivativesContext } from "./derivatives-types.js";
|
|
7
7
|
import type { EntityCache } from "./entity-cache.js";
|
|
8
8
|
import type { EventMetadata, WriteOrigin } from "./event-store-types.js";
|
|
@@ -404,7 +404,7 @@ export type EventDef<TPayload = unknown, TName extends string = string> = {
|
|
|
404
404
|
readonly name: TName;
|
|
405
405
|
readonly schema: ZodType<TPayload>;
|
|
406
406
|
readonly version: number;
|
|
407
|
-
readonly piiFields
|
|
407
|
+
readonly piiFields: EventPiiStance;
|
|
408
408
|
};
|
|
409
409
|
export type AppendEventArgs = {
|
|
410
410
|
readonly aggregateId: string;
|
|
@@ -499,18 +499,32 @@ export type AgentHandlerHints = {
|
|
|
499
499
|
readonly expose?: boolean;
|
|
500
500
|
readonly risk?: AgentRisk;
|
|
501
501
|
};
|
|
502
|
+
/** Screens only read `expose`; `risk` ranks handler tool calls, so it is not offered here. */
|
|
503
|
+
export type AgentScreenHints = Pick<AgentHandlerHints, "expose">;
|
|
502
504
|
export type AgentExposure = {
|
|
503
505
|
readonly expose: boolean;
|
|
504
506
|
readonly risk: AgentRisk;
|
|
505
507
|
};
|
|
506
508
|
/** Undoes a reservation made before the handler transaction. */
|
|
507
509
|
export type ReservationRelease = () => Promise<void>;
|
|
508
|
-
/**
|
|
509
|
-
*
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
510
|
+
/** The dispatcher's own open handler transaction: a reservation must settle on it, not on
|
|
511
|
+
* HandlerContext, whose db is fail-closed for r.systemScope() handlers. */
|
|
512
|
+
export type ReservationConfirmContext = {
|
|
513
|
+
readonly tx: DbTx;
|
|
514
|
+
readonly tenantId: TenantId;
|
|
515
|
+
};
|
|
516
|
+
/** A reservation that also settles inside the handler transaction. `confirmInTransaction` runs
|
|
517
|
+
* after the handler succeeded and before COMMIT; a throw fails the write and rolls it back. */
|
|
518
|
+
export type ReservationHandle = {
|
|
519
|
+
readonly release: ReservationRelease;
|
|
520
|
+
readonly confirmInTransaction: (confirm: ReservationConfirmContext) => Promise<void>;
|
|
521
|
+
};
|
|
522
|
+
/** Runs in the dispatcher after every pre-handler gate (feature, rate limit, access, schema,
|
|
523
|
+
* validation, field roles) passed but before the handler transaction opens, so it must commit
|
|
524
|
+
* its own short write instead of holding a second connection while the transaction is open.
|
|
525
|
+
* The returned release (or handle.release) runs when the transaction does not commit (failure
|
|
526
|
+
* result, throw, rollback, failed commit). Throwing a KumikoError rejects the write. */
|
|
527
|
+
export type PreTransactionReservation = (event: WriteEvent, ctx: HandlerContext) => Promise<ReservationRelease | ReservationHandle | undefined>;
|
|
514
528
|
export type WriteHandlerDef = {
|
|
515
529
|
readonly name: string;
|
|
516
530
|
readonly schema: ZodType;
|
|
@@ -13,6 +13,7 @@ export type SubjectId = {
|
|
|
13
13
|
export type SubjectKey = string;
|
|
14
14
|
export declare function subjectKeyForUser(userId: string): SubjectKey;
|
|
15
15
|
export declare function subjectKeyForTenant(tenantId: TenantId): SubjectKey;
|
|
16
|
+
export declare const PII_ERASED_SENTINEL = "[[erased]]";
|
|
16
17
|
export declare const RECORD_ENTITY_PATTERN: RegExp;
|
|
17
18
|
export declare function subjectKeyForRecord(entity: string, id: string): SubjectKey;
|
|
18
19
|
export declare function subjectIdToKey(subject: SubjectId): SubjectKey;
|
|
@@ -4,6 +4,9 @@ export function subjectKeyForUser(userId) {
|
|
|
4
4
|
export function subjectKeyForTenant(tenantId) {
|
|
5
5
|
return `tenant:${tenantId}`;
|
|
6
6
|
}
|
|
7
|
+
// Stands in for a PII value whose subject key was erased; clients map it to a
|
|
8
|
+
// translated label instead of showing it.
|
|
9
|
+
export const PII_ERASED_SENTINEL = "[[erased]]";
|
|
7
10
|
// Registry entity names are identifier-shaped; a free-form aggregate_type
|
|
8
11
|
// (events-schema.ts is a plain text column) could otherwise mint a record
|
|
9
12
|
// key that subjectIdSchema (forget-subject.write.ts) later refuses to
|
package/dist/screen.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { FieldIconKey } from "./field-icon.js";
|
|
2
2
|
import type { FieldDefinition, FormFieldDefinition, SelectOptionTone } from "./fields.js";
|
|
3
|
-
import type { AccessRule,
|
|
3
|
+
import type { AccessRule, AgentScreenHints } from "./handlers.js";
|
|
4
4
|
import type { IconKey, NavIconKey } from "./nav-icon.js";
|
|
5
5
|
export type { FieldIconKey } from "./field-icon.js";
|
|
6
6
|
export type PlatformComponent = {
|
|
@@ -395,7 +395,7 @@ export type EntityListScreenDefinition = {
|
|
|
395
395
|
readonly nav?: ScreenNavSugar;
|
|
396
396
|
readonly detailFor?: string;
|
|
397
397
|
readonly description?: string;
|
|
398
|
-
readonly agent?:
|
|
398
|
+
readonly agent?: AgentScreenHints;
|
|
399
399
|
/** Screen has no nav entry by design (opened via link or navved by the
|
|
400
400
|
* app); exempts it from the nav-area boot check. */
|
|
401
401
|
readonly dormant?: boolean;
|
|
@@ -504,7 +504,7 @@ export type ProjectionListScreenDefinition = {
|
|
|
504
504
|
readonly nav?: ScreenNavSugar;
|
|
505
505
|
readonly detailFor?: string;
|
|
506
506
|
readonly description?: string;
|
|
507
|
-
readonly agent?:
|
|
507
|
+
readonly agent?: AgentScreenHints;
|
|
508
508
|
/** Screen has no nav entry by design (opened via link or navved by the
|
|
509
509
|
* app); exempts it from the nav-area boot check. */
|
|
510
510
|
readonly dormant?: boolean;
|
|
@@ -598,7 +598,7 @@ export type ProjectionDetailScreenDefinition = {
|
|
|
598
598
|
readonly nav?: ScreenNavSugar;
|
|
599
599
|
readonly detailFor?: string;
|
|
600
600
|
readonly description?: string;
|
|
601
|
-
readonly agent?:
|
|
601
|
+
readonly agent?: AgentScreenHints;
|
|
602
602
|
/** Screen has no nav entry by design (opened via link or navved by the
|
|
603
603
|
* app); exempts it from the nav-area boot check. */
|
|
604
604
|
readonly dormant?: boolean;
|
|
@@ -734,7 +734,10 @@ export type DashboardStatPanel = DashboardPanelQueryOptions & DashboardPanelGate
|
|
|
734
734
|
/** Static CSS color value (e.g. "var(--color-debt)") for the icon chip,
|
|
735
735
|
* passed straight to the tile without a registry lookup. Applies ONLY when
|
|
736
736
|
* `icon` is set (StatCard renders the chip only together with an icon);
|
|
737
|
-
* without an icon the value is silently dropped.
|
|
737
|
+
* without an icon the value is silently dropped. Without `accentColor` the
|
|
738
|
+
* chip follows the tone, including a `toneField` value delivered per result.
|
|
739
|
+
* An accent that should change with the result (e.g. by sign) goes through
|
|
740
|
+
* `toneField`; leave `accentColor` unset then. */
|
|
738
741
|
readonly accentColor?: string;
|
|
739
742
|
};
|
|
740
743
|
export type DashboardChartKind = "timeseries" | "stacked-bars" | "segment-bars" | "stacked-area";
|
|
@@ -782,6 +785,8 @@ export type DashboardChartPanel = DashboardPanelQueryOptions & DashboardPanelEmp
|
|
|
782
785
|
readonly legendTotals?: boolean;
|
|
783
786
|
/** Only for chart "stacked-area": range switch in the panel header. */
|
|
784
787
|
readonly ranges?: DashboardChartRanges;
|
|
788
|
+
/** Only for chart "stacked-area": scrubber under the plot to drag the visible window; starts at today. */
|
|
789
|
+
readonly brush?: boolean;
|
|
785
790
|
};
|
|
786
791
|
export type DashboardListPanel = DashboardPanelQueryOptions & DashboardPanelEmptyState & DashboardPanelGate & {
|
|
787
792
|
readonly kind: "list";
|
|
@@ -796,6 +801,7 @@ export type DashboardStatGroupPanel = DashboardPanelGate & {
|
|
|
796
801
|
readonly label?: string;
|
|
797
802
|
/** i18n key, a line under `label`; the boot validator requires `label`. */
|
|
798
803
|
readonly subtitle?: string;
|
|
804
|
+
readonly span?: DashboardPanelSpan;
|
|
799
805
|
readonly stats: readonly DashboardStatPanel[];
|
|
800
806
|
};
|
|
801
807
|
export type DashboardFeedPanel = DashboardPanelQueryOptions & DashboardPanelEmptyState & DashboardPanelGate & {
|
|
@@ -867,7 +873,7 @@ export type DashboardScreenDefinition = {
|
|
|
867
873
|
readonly nav?: ScreenNavSugar;
|
|
868
874
|
readonly detailFor?: string;
|
|
869
875
|
readonly description?: string;
|
|
870
|
-
readonly agent?:
|
|
876
|
+
readonly agent?: AgentScreenHints;
|
|
871
877
|
/** Screen has no nav entry by design (opened via link or navved by the
|
|
872
878
|
* app); exempts it from the nav-area boot check. */
|
|
873
879
|
readonly dormant?: boolean;
|
|
@@ -1201,7 +1207,7 @@ export type EntityEditScreenDefinition = {
|
|
|
1201
1207
|
readonly nav?: ScreenNavSugar;
|
|
1202
1208
|
readonly detailFor?: string;
|
|
1203
1209
|
readonly description?: string;
|
|
1204
|
-
readonly agent?:
|
|
1210
|
+
readonly agent?: AgentScreenHints;
|
|
1205
1211
|
/** Screen has no nav entry by design (opened via link or navved by the
|
|
1206
1212
|
* app); exempts it from the nav-area boot check. */
|
|
1207
1213
|
readonly dormant?: boolean;
|
|
@@ -1297,7 +1303,7 @@ export type ActionFormScreenDefinition = {
|
|
|
1297
1303
|
readonly nav?: ScreenNavSugar;
|
|
1298
1304
|
readonly detailFor?: string;
|
|
1299
1305
|
readonly description?: string;
|
|
1300
|
-
readonly agent?:
|
|
1306
|
+
readonly agent?: AgentScreenHints;
|
|
1301
1307
|
/** Screen has no nav entry by design (opened via link or navved by the
|
|
1302
1308
|
* app); exempts it from the nav-area boot check. */
|
|
1303
1309
|
readonly dormant?: boolean;
|
|
@@ -1465,7 +1471,7 @@ export type SecretMintScreenDefinition = {
|
|
|
1465
1471
|
readonly nav?: ScreenNavSugar;
|
|
1466
1472
|
readonly detailFor?: string;
|
|
1467
1473
|
readonly description?: string;
|
|
1468
|
-
readonly agent?:
|
|
1474
|
+
readonly agent?: AgentScreenHints;
|
|
1469
1475
|
/** Screen has no nav entry by design (opened via link or navved by the
|
|
1470
1476
|
* app); exempts it from the nav-area boot check. */
|
|
1471
1477
|
readonly dormant?: boolean;
|
|
@@ -1504,8 +1510,7 @@ export type CustomScreenDefinition = {
|
|
|
1504
1510
|
readonly nav?: ScreenNavSugar;
|
|
1505
1511
|
readonly detailFor?: string;
|
|
1506
1512
|
readonly description?: string;
|
|
1507
|
-
|
|
1508
|
-
readonly agent?: AgentHandlerHints;
|
|
1513
|
+
readonly agent?: AgentScreenHints;
|
|
1509
1514
|
readonly renderer: PlatformComponent;
|
|
1510
1515
|
readonly routes?: readonly CustomScreenRoute[];
|
|
1511
1516
|
/** Parent list screen for breadcrumb when this detail is not in nav. */
|
|
@@ -1536,7 +1541,7 @@ export type ConfigEditScreenDefinition = {
|
|
|
1536
1541
|
readonly nav?: ScreenNavSugar;
|
|
1537
1542
|
readonly detailFor?: string;
|
|
1538
1543
|
readonly description?: string;
|
|
1539
|
-
readonly agent?:
|
|
1544
|
+
readonly agent?: AgentScreenHints;
|
|
1540
1545
|
/** Screen has no nav entry by design (opened via link or navved by the
|
|
1541
1546
|
* app); exempts it from the nav-area boot check. */
|
|
1542
1547
|
readonly dormant?: boolean;
|
|
@@ -1586,7 +1591,7 @@ export type SecretsEditScreenDefinition = {
|
|
|
1586
1591
|
readonly nav?: ScreenNavSugar;
|
|
1587
1592
|
readonly detailFor?: string;
|
|
1588
1593
|
readonly description?: string;
|
|
1589
|
-
readonly agent?:
|
|
1594
|
+
readonly agent?: AgentScreenHints;
|
|
1590
1595
|
/** Screen has no nav entry by design (opened via link or navved by the
|
|
1591
1596
|
* app); exempts it from the nav-area boot check. */
|
|
1592
1597
|
readonly dormant?: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-types",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.353.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,17 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.352.0",
|
|
4
|
+
"type": "improvement",
|
|
5
|
+
"title": "SelectFieldDef.optionsAvailabilityQuery marks static select options as unavailable per tenant",
|
|
6
|
+
"detail": "The query returns { rows: { value, disabled?, hint? }[] }; the renderer merges it onto options and keeps the stored value enabled."
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"version": "0.352.0",
|
|
10
|
+
"type": "breaking",
|
|
11
|
+
"title": "Apps must import Temporal from @cosmicdrift/kumiko-types/temporal instead of temporal-polyfill (affects every app since 0.351.0)",
|
|
12
|
+
"detail": "Since 0.351.0 the native globalThis.Temporal wins over the polyfill. A Temporal imported from \"temporal-polyfill\" is a second implementation, so instanceof and z.instanceof(Temporal.Instant) reject values the framework creates. This applies whether you upgrade from before 0.351.0 or are already on it.",
|
|
13
|
+
"migration": "Replace every value import from \"temporal-polyfill\" in app code and tests, e.g. `import { Temporal } from \"temporal-polyfill\"`, with `import { Temporal } from \"@cosmicdrift/kumiko-types/temporal\"`, and drop side-effect imports of \"temporal-polyfill/global\" (importing @cosmicdrift/kumiko-types/temporal already installs the global when the runtime has none). `import type` and `/// <reference types=\"temporal-polyfill/global\" />` may stay. Then run `kumiko check`; the No-Temporal-Polyfill-Import guard lists anything left. Close the step with `kumiko-upgrade --resolve <id> --reason \"<what you changed>\"`, or add `--not-applicable` when the repo never imported temporal-polyfill."
|
|
14
|
+
},
|
|
2
15
|
{
|
|
3
16
|
"version": "0.351.0",
|
|
4
17
|
"type": "fix",
|