@cosmicdrift/kumiko-types 0.327.0 → 0.328.1

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.
Files changed (174) hide show
  1. package/dist/action-icon.d.ts +3 -0
  2. package/dist/action-icon.js +51 -0
  3. package/{src/agent-exposure.ts → dist/agent-exposure.d.ts} +8 -15
  4. package/dist/agent-exposure.js +16 -0
  5. package/dist/concurrency-mode.d.ts +1 -0
  6. package/dist/config-scope.d.ts +1 -0
  7. package/dist/config-scope.js +1 -0
  8. package/dist/config.d.ts +234 -0
  9. package/dist/config.js +1 -0
  10. package/dist/cursor-types.d.ts +16 -0
  11. package/dist/cursor-types.js +1 -0
  12. package/dist/db-connection.d.ts +14 -0
  13. package/dist/db-connection.js +1 -0
  14. package/dist/define-handler.d.ts +58 -0
  15. package/dist/define-handler.js +1 -0
  16. package/dist/derivatives-types.d.ts +53 -0
  17. package/dist/derivatives-types.js +3 -0
  18. package/dist/entity-cache.d.ts +16 -0
  19. package/dist/entity-cache.js +1 -0
  20. package/dist/entity-handlers.d.ts +54 -0
  21. package/dist/entity-handlers.js +1 -0
  22. package/dist/entity-table-meta-types.d.ts +44 -0
  23. package/dist/entity-table-meta-types.js +6 -0
  24. package/dist/envelope-cipher-types.d.ts +5 -0
  25. package/dist/envelope-cipher-types.js +1 -0
  26. package/dist/event-store-executor-types.d.ts +86 -0
  27. package/dist/event-store-executor-types.js +1 -0
  28. package/dist/event-store-types.d.ts +37 -0
  29. package/dist/event-store-types.js +7 -0
  30. package/dist/event-type-map.d.ts +8 -0
  31. package/{src/event-type-map.ts → dist/event-type-map.js} +1 -16
  32. package/dist/executor-brand.d.ts +8 -0
  33. package/dist/executor-brand.js +1 -0
  34. package/dist/extension-options-map.d.ts +9 -0
  35. package/dist/extension-options-map.js +4 -0
  36. package/dist/feature.d.ts +518 -0
  37. package/dist/feature.js +1 -0
  38. package/dist/field-icon.d.ts +1 -0
  39. package/dist/field-icon.js +1 -0
  40. package/dist/fields.d.ts +729 -0
  41. package/dist/fields.js +50 -0
  42. package/dist/file-handle-types.d.ts +12 -0
  43. package/dist/file-handle-types.js +1 -0
  44. package/dist/file-provider-resolver-types.d.ts +3 -0
  45. package/dist/file-provider-resolver-types.js +1 -0
  46. package/dist/file-storage-provider-types.d.ts +17 -0
  47. package/dist/file-storage-provider-types.js +1 -0
  48. package/dist/geo-tz.d.ts +17 -0
  49. package/{src/geo-tz.ts → dist/geo-tz.js} +1 -20
  50. package/dist/handlers.d.ts +493 -0
  51. package/dist/handlers.js +49 -0
  52. package/dist/hook-phase.d.ts +1 -0
  53. package/dist/hook-phase.js +1 -0
  54. package/dist/hooks.d.ts +75 -0
  55. package/dist/hooks.js +1 -0
  56. package/dist/http-route.d.ts +52 -0
  57. package/dist/http-route.js +13 -0
  58. package/dist/identifiers.d.ts +8 -0
  59. package/{src/identifiers.ts → dist/identifiers.js} +7 -24
  60. package/dist/index.d.ts +1 -0
  61. package/dist/index.js +1 -0
  62. package/dist/kms-adapter-types.d.ts +68 -0
  63. package/dist/kms-adapter-types.js +49 -0
  64. package/dist/logger.d.ts +7 -0
  65. package/dist/logger.js +1 -0
  66. package/dist/multi-stream-apply-context-types.d.ts +18 -0
  67. package/dist/multi-stream-apply-context-types.js +1 -0
  68. package/dist/nav-icon.d.ts +3 -0
  69. package/dist/nav-icon.js +100 -0
  70. package/dist/nav.d.ts +39 -0
  71. package/dist/nav.js +1 -0
  72. package/dist/observability/index.d.ts +3 -0
  73. package/dist/observability/index.js +2 -0
  74. package/dist/observability/metric.d.ts +34 -0
  75. package/dist/observability/metric.js +3 -0
  76. package/dist/observability/provider.d.ts +24 -0
  77. package/dist/observability/provider.js +4 -0
  78. package/dist/observability/span.d.ts +32 -0
  79. package/dist/observability/span.js +4 -0
  80. package/dist/ownership.d.ts +33 -0
  81. package/dist/ownership.js +5 -0
  82. package/dist/projection.d.ts +38 -0
  83. package/dist/projection.js +1 -0
  84. package/dist/rate-limit-types.d.ts +19 -0
  85. package/dist/rate-limit-types.js +1 -0
  86. package/dist/relations.d.ts +25 -0
  87. package/dist/relations.js +1 -0
  88. package/dist/schema-table-types.d.ts +15 -0
  89. package/{src/schema-table-types.ts → dist/schema-table-types.js} +0 -20
  90. package/dist/screen.d.ts +1265 -0
  91. package/dist/screen.js +3 -0
  92. package/dist/search-adapter.d.ts +32 -0
  93. package/dist/search-adapter.js +1 -0
  94. package/dist/secrets-types.d.ts +52 -0
  95. package/dist/secrets-types.js +30 -0
  96. package/dist/snapshot-types.d.ts +13 -0
  97. package/dist/snapshot-types.js +1 -0
  98. package/dist/step.d.ts +304 -0
  99. package/dist/step.js +11 -0
  100. package/dist/target-ref.d.ts +5 -0
  101. package/{src/target-ref.ts → dist/target-ref.js} +1 -6
  102. package/dist/tenancy-brand.d.ts +6 -0
  103. package/dist/tenancy-brand.js +1 -0
  104. package/dist/tenant-db-types.d.ts +67 -0
  105. package/dist/tenant-db-types.js +5 -0
  106. package/dist/tree-node.d.ts +26 -0
  107. package/dist/tree-node.js +22 -0
  108. package/dist/tz-context.d.ts +48 -0
  109. package/dist/tz-context.js +6 -0
  110. package/dist/websocket-route.d.ts +46 -0
  111. package/dist/websocket-route.js +10 -0
  112. package/dist/where-clause-types.d.ts +20 -0
  113. package/dist/where-clause-types.js +1 -0
  114. package/dist/workspace.d.ts +10 -0
  115. package/dist/workspace.js +1 -0
  116. package/dist/write-error-info-types.d.ts +12 -0
  117. package/dist/write-error-info-types.js +1 -0
  118. package/package.json +372 -124
  119. package/src/changes.json +18 -0
  120. package/src/__tests__/handlers.test.ts +0 -40
  121. package/src/__tests__/plural-forms.test.ts +0 -18
  122. package/src/action-icon.ts +0 -57
  123. package/src/concurrency-mode.ts +0 -5
  124. package/src/config-scope.ts +0 -5
  125. package/src/config.ts +0 -563
  126. package/src/cursor-types.ts +0 -18
  127. package/src/db-connection.ts +0 -25
  128. package/src/define-handler.ts +0 -138
  129. package/src/derivatives-types.ts +0 -106
  130. package/src/entity-cache.ts +0 -35
  131. package/src/entity-handlers.ts +0 -68
  132. package/src/entity-table-meta-types.ts +0 -101
  133. package/src/envelope-cipher-types.ts +0 -6
  134. package/src/event-store-executor-types.ts +0 -163
  135. package/src/event-store-types.ts +0 -85
  136. package/src/executor-brand.ts +0 -19
  137. package/src/extension-options-map.ts +0 -21
  138. package/src/feature.ts +0 -1141
  139. package/src/field-icon.ts +0 -23
  140. package/src/fields.ts +0 -1114
  141. package/src/file-handle-types.ts +0 -20
  142. package/src/file-provider-resolver-types.ts +0 -7
  143. package/src/file-storage-provider-types.ts +0 -54
  144. package/src/handlers.ts +0 -1246
  145. package/src/hook-phase.ts +0 -2
  146. package/src/hooks.ts +0 -170
  147. package/src/http-route.ts +0 -78
  148. package/src/kms-adapter-types.ts +0 -128
  149. package/src/logger.ts +0 -7
  150. package/src/multi-stream-apply-context-types.ts +0 -52
  151. package/src/nav-icon.ts +0 -105
  152. package/src/nav.ts +0 -139
  153. package/src/observability/index.ts +0 -28
  154. package/src/observability/metric.ts +0 -56
  155. package/src/observability/provider.ts +0 -32
  156. package/src/observability/span.ts +0 -58
  157. package/src/ownership.ts +0 -83
  158. package/src/projection.ts +0 -170
  159. package/src/rate-limit-types.ts +0 -32
  160. package/src/relations.ts +0 -52
  161. package/src/screen.ts +0 -1593
  162. package/src/search-adapter.ts +0 -45
  163. package/src/secrets-types.ts +0 -182
  164. package/src/snapshot-types.ts +0 -36
  165. package/src/step.ts +0 -390
  166. package/src/tenancy-brand.ts +0 -9
  167. package/src/tenant-db-types.ts +0 -116
  168. package/src/tree-node.ts +0 -134
  169. package/src/tz-context.ts +0 -63
  170. package/src/websocket-route.ts +0 -68
  171. package/src/where-clause-types.ts +0 -31
  172. package/src/workspace.ts +0 -42
  173. package/src/write-error-info-types.ts +0 -20
  174. /package/{src/index.ts → dist/concurrency-mode.js} +0 -0
package/src/hook-phase.ts DELETED
@@ -1,2 +0,0 @@
1
- // Keep in sync with HookPhases in packages/framework/src/engine/hook-helpers.ts.
2
- export type HookPhase = "inTransaction" | "afterCommit";
package/src/hooks.ts DELETED
@@ -1,170 +0,0 @@
1
- import type { StoredEvent } from "./event-store-types";
2
- import type { AppContext } from "./handlers";
3
- import type { HookPhase } from "./hook-phase";
4
- import type { EntityId } from "./identifiers";
5
-
6
- // --- Validation ---
7
-
8
- export type ValidationError = {
9
- readonly field: string;
10
- readonly error: string;
11
- };
12
-
13
- export type ValidationHookFn = (
14
- data: Readonly<Record<string, unknown>>,
15
- ) => readonly ValidationError[] | null;
16
-
17
- // --- Save/Delete Context (what hooks receive) ---
18
-
19
- export type SaveContext = {
20
- readonly kind: "save";
21
- readonly id: EntityId;
22
- readonly data: Readonly<Record<string, unknown>>;
23
- readonly changes: Readonly<Record<string, unknown>>;
24
- readonly previous: Readonly<Record<string, unknown>>;
25
- readonly isNew: boolean;
26
- readonly entityName?: string | undefined;
27
- // The event that produced this save. Populated by the event-store-executor;
28
- // the pipeline uses it to drive projections inside the same transaction.
29
- // Optional because hand-crafted SaveContexts (tests, custom executors) may
30
- // not have an event — projections just skip in that case.
31
- readonly event?: StoredEvent | undefined;
32
- };
33
-
34
- export type DeleteContext = {
35
- readonly kind: "delete";
36
- readonly id: EntityId;
37
- readonly data: Readonly<Record<string, unknown>>;
38
- readonly entityName?: string | undefined;
39
- // See SaveContext.event — same semantics.
40
- readonly event?: StoredEvent | undefined;
41
- };
42
-
43
- export type LifecycleResult = SaveContext | DeleteContext;
44
-
45
- // --- Lifecycle Hooks ---
46
-
47
- export type PreSaveHookFn = (
48
- changes: Record<string, unknown>,
49
- context: AppContext & {
50
- readonly previous: Readonly<Record<string, unknown>>;
51
- readonly isNew: boolean;
52
- },
53
- ) => Promise<Record<string, unknown>>;
54
-
55
- export type PostSaveHookFn = (result: SaveContext, context: AppContext) => Promise<void>;
56
-
57
- // Batch-variant: called once at the end of a dispatcher batch with every
58
- // successful SaveContext. The per-save PostSaveHookFn still fires for
59
- // side-effects that need per-entity semantics (SSE); PostSaveBatch exists
60
- // for adapters that can amortise work across the whole batch (e.g. search
61
- // index batch-writes, bulk webhook fanout).
62
- export type PostSaveBatchHookFn = (
63
- results: readonly SaveContext[],
64
- context: AppContext,
65
- ) => Promise<void>;
66
-
67
- export type PreDeleteHookFn = (payload: DeleteContext, context: AppContext) => Promise<void>;
68
-
69
- export type PostDeleteHookFn = (payload: DeleteContext, context: AppContext) => Promise<void>;
70
-
71
- export type PostDeleteBatchHookFn = (
72
- payloads: readonly DeleteContext[],
73
- context: AppContext,
74
- ) => Promise<void>;
75
-
76
- export type PreQueryHookFn = (
77
- payload: Record<string, unknown>,
78
- context: AppContext,
79
- ) => Promise<Record<string, unknown>>;
80
-
81
- // postQuery — fires after query-handler-execute, before field-access-read-filter.
82
- // Hook receives normalized rows + entityName + can mutate rows (e.g., merge
83
- // custom-fields, add computed-counts, attach related-data). Mutation result
84
- // replaces original rows. Hook is responsible for its own field-access-logic
85
- // on added fields (field-access-filter only knows entity's stammfields).
86
- export type PostQueryHookFn = (
87
- result: {
88
- // undefined for standalone queries (no-colon handler names like
89
- // "ns:dashboard") — those have no backing entity, but handler-keyed
90
- // postQuery hooks still fire on them.
91
- readonly entityName: string | undefined;
92
- readonly rows: ReadonlyArray<Record<string, unknown>>;
93
- },
94
- context: AppContext,
95
- ) => Promise<{ rows: ReadonlyArray<Record<string, unknown>> }>;
96
-
97
- export type LifecycleHookFn =
98
- | PreSaveHookFn
99
- | PostSaveHookFn
100
- | PreDeleteHookFn
101
- | PostDeleteHookFn
102
- | PreQueryHookFn
103
- | PostQueryHookFn;
104
-
105
- export type { HookPhase } from "./hook-phase";
106
-
107
- // Owner-tag shared across every hook structure. The lifecycle pipeline uses
108
- // it to skip hooks whose owning feature is globally disabled:
109
- // - A concrete feature name like "orders" → subject to the feature-toggle
110
- // filter (skipped when "orders" is disabled).
111
- // - "*" (star) → invariant plumbing, never filtered. Reserved for
112
- // extension-provided hooks and framework-internal hooks that belong to
113
- // the pipeline itself, not a feature.
114
- // - Omitted (undefined) → treated as "*". Supports tests that hand-build
115
- // HookMap objects without caring about ownership.
116
- export type HookOwner = { readonly featureName?: string };
117
-
118
- export type PhasedHook<TFn> = {
119
- readonly fn: TFn;
120
- readonly phase: HookPhase;
121
- } & HookOwner;
122
-
123
- // Flat (non-phased) hook — preSave, preQuery. Same owner contract, no
124
- // phase semantics because these hooks run exactly once per handler pass
125
- // before/around the DB transaction.
126
- export type OwnedFn<TFn> = {
127
- readonly fn: TFn;
128
- } & HookOwner;
129
-
130
- // --- Hook Maps ---
131
-
132
- // Slots are optional: defineFeature materializes every slot, but hand-built
133
- // FeatureDefinitions at system boundaries (test fixtures, partial boots —
134
- // see registry.test.ts "slot robustness") legitimately omit them, and the
135
- // registry merge paths tolerate undefined. The type mirrors that contract.
136
- export type HookMap = {
137
- readonly validation?: Readonly<Record<string, ValidationHookFn>>;
138
- readonly preSave?: Readonly<Record<string, readonly OwnedFn<PreSaveHookFn>[]>>;
139
- readonly postSave?: Readonly<Record<string, readonly PhasedHook<PostSaveHookFn>[]>>;
140
- readonly preDelete?: Readonly<Record<string, readonly PhasedHook<PreDeleteHookFn>[]>>;
141
- readonly postDelete?: Readonly<Record<string, readonly PhasedHook<PostDeleteHookFn>[]>>;
142
- readonly preQuery?: Readonly<Record<string, readonly OwnedFn<PreQueryHookFn>[]>>;
143
- readonly postQuery?: Readonly<Record<string, readonly OwnedFn<PostQueryHookFn>[]>>;
144
- };
145
-
146
- export type EntityHookMap = {
147
- readonly postSave?: Readonly<Record<string, readonly PhasedHook<PostSaveHookFn>[]>>;
148
- readonly preDelete?: Readonly<Record<string, readonly PhasedHook<PreDeleteHookFn>[]>>;
149
- readonly postDelete?: Readonly<Record<string, readonly PhasedHook<PostDeleteHookFn>[]>>;
150
- readonly postQuery?: Readonly<Record<string, readonly OwnedFn<PostQueryHookFn>[]>>;
151
- };
152
-
153
- // Search-Payload-Extension (F3) — contributor function that adds flat
154
- // fields to an entity's search-document. Fires synchronously during
155
- // buildSearchDocument (in `system-hooks.ts`), receives current entity
156
- // state, returns extra fields to merge into the search-index payload.
157
- //
158
- // Use-cases: custom-fields-bundle (merge customFields-jsonb-keys flat
159
- // into index), tags-bundle (project tags-array as searchable), computed-
160
- // fields (denormalize related-counts).
161
- //
162
- // IMPORTANT: contributor must be deterministic per (entityName, entityId,
163
- // state). Async-allowed for future-proofing but discouraged — the
164
- // indexing path runs once per entity-write, sync extension is
165
- // near-zero-cost.
166
- export type SearchPayloadContributorFn = (args: {
167
- readonly entityName: string;
168
- readonly entityId: EntityId;
169
- readonly state: Record<string, unknown>;
170
- }) => Record<string, unknown> | Promise<Record<string, unknown>>;
package/src/http-route.ts DELETED
@@ -1,78 +0,0 @@
1
- // HTTP route definition — feature-declared HTTP endpoints outside
2
- // the /api/write|query|batch pipeline. Use case: RSS/Atom feeds, OpenAPI
3
- // specs, OG image generators, webhook receivers — anything where the
4
- // feature author controls the wire format themselves.
5
- //
6
- // Pattern symmetric to r.queryHandler / r.writeHandler: definition as
7
- // part of the feature (not the app bootstrapping). Phase-3 multi-tenant
8
- // becomes trivial because tenant context is picked up via host resolution.
9
- //
10
- // Escape-hatch stays: runProdApp.extraRoutes (declarative list with
11
- // `entry` tier) for hand-rolled routes that have nothing to do with a
12
- // feature (e.g. platform-specific static-serving logic).
13
-
14
- import type { Context } from "hono";
15
-
16
- /** Subset von HTTP-Methoden den wir aktiv unterstützen. Hono spricht
17
- * alle, aber das hier sind die einzigen die ein Feature-Author
18
- * realistisch deklariert. */
19
- export type HttpRouteMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS";
20
-
21
- /** Dependencies die der Handler vom Framework bekommt. App-Author kann
22
- * die App selbst aufrufen (`deps.app.fetch(...)` für intern-call) oder
23
- * direkt per dispatcher Daten ziehen. Db/Redis sind die rohen Connections
24
- * — wer Tenant-Scope braucht muss durch dispatcher.query gehen.
25
- *
26
- * Hono-typing: `Context<any, any>` weil das Hono-Type-Param-Setup nur
27
- * intern relevant ist. Concrete Hono-app wird im Boot-Path zugewiesen. */
28
- export type HttpRouteHandlerDeps = {
29
- /** Die Hono-app — Handler kann via app.fetch(...) interne Routes
30
- * ansprechen (z.B. /api/query mit der vollen Auth-/Anonymous-Chain). */
31
- // biome-ignore lint/suspicious/noExplicitAny: Hono's generic-Param ist im Framework-Boundary unsichtbar
32
- readonly app: import("hono").Hono<any, any>;
33
- /** Run a query handler in-process, forcing a SPECIFIC tenant — WITHOUT
34
- * going through the public /api/query HTTP layer (no header parsing, no
35
- * anonymousAccess tenant resolution). The synthesized caller carries
36
- * anonymous-level access ONLY (same role a real anonymous request would
37
- * have, no more) — the primitive forces the tenant, not the privilege
38
- * level, so it stays safe to call from any `anonymous: true` route
39
- * without risking a field-level disclosure a real anonymous caller
40
- * couldn't already get. Use this whenever the route needs a tenant
41
- * other than the one the request resolves to (e.g. always
42
- * SYSTEM_TENANT_ID regardless of the visited host) — spoofing that via
43
- * an internal X-Tenant header on `app.fetch(...)` is indistinguishable
44
- * from an external client and gets rejected by resolverTrust:
45
- * "authoritative" anonymousAccess configs (see auth-middleware.ts). */
46
- readonly systemQuery: (
47
- type: string,
48
- payload: unknown,
49
- tenantId: import("./identifiers").TenantId,
50
- ) => Promise<unknown>;
51
- /** Caller IP resolved via the server's configured, trustedProxyHops-aware
52
- * resolver (same one requestIdMiddleware uses for `/api/*`) — a route
53
- * handler needing the caller's IP (rate limiting, audit) should read
54
- * this instead of parsing X-Forwarded-For itself, which trusts
55
- * whichever hop count the deployment actually has in front of it. */
56
- readonly clientIp: string;
57
- };
58
-
59
- export type HttpRouteHandler = (
60
- // biome-ignore lint/suspicious/noExplicitAny: Hono Context-Generics sind im Framework-Boundary unsichtbar
61
- c: Context<any, any>,
62
- deps: HttpRouteHandlerDeps,
63
- ) => Response | Promise<Response>;
64
-
65
- export type HttpRouteDefinition = {
66
- /** HTTP-Methode — bei Hono-Mount via app.{get,post,...}(path). */
67
- readonly method: HttpRouteMethod;
68
- /** URL-Pfad (Hono-Pattern, z.B. "/feed.xml" oder "/og/:tenantId.png"). */
69
- readonly path: string;
70
- /** true = public, no session required. false = mounted behind the
71
- * session auth chain (no anonymous fallthrough, PAT rate limit,
72
- * origin + CSRF guards) — a request without a session gets 401. The
73
- * handler reads the caller via getUser(c). */
74
- readonly anonymous: boolean;
75
- /** Hono-Handler. Bekommt Hono-Context + Framework-Deps; returnt
76
- * Response (sync oder async). */
77
- readonly handler: HttpRouteHandler;
78
- };
@@ -1,128 +0,0 @@
1
- import type { TenantId } from "./identifiers";
2
-
3
- // The subject a DEK belongs to. User data is shredded on user-forget,
4
- // tenant data on tenant-destroy, record data on a row-scoped forget —
5
- // three erase triggers, three subject kinds.
6
- export type SubjectId =
7
- | { readonly kind: "user"; readonly userId: string }
8
- | { readonly kind: "tenant"; readonly tenantId: TenantId }
9
- | { readonly kind: "record"; readonly entity: string; readonly id: string };
10
-
11
- // Compact storage key ("user:<uuid>" / "tenant:<uuid>" / "record:<entity>:<id>")
12
- // — primary key in adapter backends and cache key in the request-level DEK cache.
13
- export type SubjectKey = string;
14
-
15
- export function subjectKeyForUser(userId: string): SubjectKey {
16
- return `user:${userId}`;
17
- }
18
-
19
- export function subjectKeyForTenant(tenantId: TenantId): SubjectKey {
20
- return `tenant:${tenantId}`;
21
- }
22
-
23
- // Registry entity names are identifier-shaped; a free-form aggregate_type
24
- // (events-schema.ts is a plain text column) could otherwise mint a record
25
- // key that subjectIdSchema (forget-subject.write.ts) later refuses to
26
- // shred — enforced once here so minting and shredding can never disagree.
27
- export const RECORD_ENTITY_PATTERN = /^[A-Za-z][A-Za-z0-9_-]*$/;
28
-
29
- export function subjectKeyForRecord(entity: string, id: string): SubjectKey {
30
- if (!RECORD_ENTITY_PATTERN.test(entity)) {
31
- throw new Error(
32
- `Invalid record entity for subject key: "${entity}" — must match ${RECORD_ENTITY_PATTERN}`,
33
- );
34
- }
35
- if (id === "") throw new Error("Invalid record id for subject key: empty");
36
- return `record:${entity}:${id}`;
37
- }
38
-
39
- export function subjectIdToKey(subject: SubjectId): SubjectKey {
40
- switch (subject.kind) {
41
- case "user":
42
- return subjectKeyForUser(subject.userId);
43
- case "tenant":
44
- return subjectKeyForTenant(subject.tenantId);
45
- case "record":
46
- return subjectKeyForRecord(subject.entity, subject.id);
47
- }
48
- }
49
-
50
- export function subjectIdFromKey(key: SubjectKey): SubjectId {
51
- if (key.startsWith("user:")) return { kind: "user", userId: key.slice("user:".length) };
52
- if (key.startsWith("tenant:")) {
53
- return { kind: "tenant", tenantId: key.slice("tenant:".length) as TenantId }; // @cast-boundary parse of a key this module minted
54
- }
55
- if (key.startsWith("record:")) {
56
- const rest = key.slice("record:".length);
57
- const separatorIndex = rest.indexOf(":");
58
- const entity = separatorIndex === -1 ? "" : rest.slice(0, separatorIndex);
59
- const id = separatorIndex === -1 ? "" : rest.slice(separatorIndex + 1);
60
- if (entity === "" || id === "") throw new Error(`Invalid subject key: ${key}`);
61
- return { kind: "record", entity, id };
62
- }
63
- throw new Error(`Invalid subject key: ${key}`);
64
- }
65
-
66
- export interface KmsContext {
67
- readonly tenantId?: TenantId;
68
- readonly requestId: string;
69
- readonly userId?: string;
70
- readonly eraseReason?: string;
71
- }
72
-
73
- export interface KmsHealth {
74
- readonly ok: boolean;
75
- readonly latencyMs: number;
76
- readonly details?: Record<string, unknown>;
77
- }
78
-
79
- // 32-byte AES-256 data-encryption key, unwrapped and ready for local use.
80
- export type SubjectDek = Buffer;
81
-
82
- interface KmsAdapterBase {
83
- /**
84
- * Creates a fresh subject key. Throws KeyAlreadyExistsError when the
85
- * subject already has one — including an erased tombstone: a shredded
86
- * subject must never get a new key, or forget could be undone by
87
- * re-encrypting under it.
88
- */
89
- createKey(subject: SubjectId, ctx: KmsContext): Promise<void>;
90
-
91
- /**
92
- * Erases the key material immediately; the tombstone row stays for the
93
- * audit trail. Idempotent — repeat calls and unknown subjects are no-ops.
94
- */
95
- eraseKey(subject: SubjectId, ctx: KmsContext): Promise<void>;
96
-
97
- /** Probe for boot + readiness. Throws when the backend is unreachable. */
98
- health(): Promise<KmsHealth>;
99
- }
100
-
101
- // Backends that hand out the plaintext DEK (Pg, InMemory). Encrypt/decrypt
102
- // happens locally; DEKs are cacheable per request.
103
- export interface LocalKeyKmsAdapter extends KmsAdapterBase {
104
- readonly capabilities: { readonly mode: "local-key" };
105
-
106
- /**
107
- * Throws KeyErasedError after eraseKey (callers render "[[erased]]"),
108
- * KeyNotFoundError when the subject never had a key (typically a bug).
109
- */
110
- getKey(subject: SubjectId, ctx: KmsContext): Promise<SubjectDek>;
111
- }
112
-
113
- // Backends that never release key material (Vault transit, cloud KMS).
114
- // Every encrypt/decrypt is a round-trip; nothing is cacheable.
115
- export interface RemoteCryptoKmsAdapter extends KmsAdapterBase {
116
- readonly capabilities: { readonly mode: "remote-crypto" };
117
-
118
- encrypt(subject: SubjectId, plaintext: Uint8Array, ctx: KmsContext): Promise<Uint8Array>;
119
-
120
- /** Same error contract as LocalKeyKmsAdapter.getKey. */
121
- decrypt(subject: SubjectId, ciphertext: Uint8Array, ctx: KmsContext): Promise<Uint8Array>;
122
- }
123
-
124
- export type KmsAdapter = LocalKeyKmsAdapter | RemoteCryptoKmsAdapter;
125
-
126
- export function isLocalKeyKmsAdapter(adapter: KmsAdapter): adapter is LocalKeyKmsAdapter {
127
- return adapter.capabilities.mode === "local-key";
128
- }
package/src/logger.ts DELETED
@@ -1,7 +0,0 @@
1
- export type Logger = {
2
- info(msg: string, data?: Record<string, unknown>): void;
3
- warn(msg: string, data?: Record<string, unknown>): void;
4
- error(msg: string, data?: Record<string, unknown>): void;
5
- debug(msg: string, data?: Record<string, unknown>): void;
6
- child(context: Record<string, unknown>): Logger;
7
- };
@@ -1,52 +0,0 @@
1
- import type { DerivativesContext } from "./derivatives-types";
2
- import type { StoredEvent } from "./event-store-types";
3
- import type { KumikoEventTypeMap } from "./event-type-map";
4
- import type { Registry } from "./feature";
5
- import type { FileContext } from "./file-handle-types";
6
- import type { AppendEventFn, UnsafeAppendEventFn } from "./handlers";
7
- import type { SecretsContext } from "./secrets-types";
8
-
9
- // Minimal, read+write surface handed to a MultiStreamProjection's apply()
10
- // when it needs to produce follow-up events (saga / process-manager
11
- // pattern). Keeps the MSP feature-decoupled: applies don't reach into
12
- // handler-bridge (no query/write/writeAs), they just read the aggregate
13
- // stream and append new events — Marten's session scope for projections.
14
- //
15
- // TMap propagates the strict event-type-map (see HandlerContext). Default
16
- // matches the global KumikoEventTypeMap; runtime-pluggable callers route
17
- // through unsafeAppendEvent.
18
- export type MultiStreamApplyContext<TMap extends object = KumikoEventTypeMap> = {
19
- // Append a domain event onto an aggregate stream in the CURRENT tx.
20
- // Schema-validated, archive-guarded, stream-version derived. Metadata
21
- // inherits from the triggering event (correlationId) + requestContext
22
- // (causationId is already set to the triggering event.id by the
23
- // dispatcher wrap). Strict against KumikoEventTypeMap — same contract
24
- // as HandlerContext.appendEvent (compile-time-validated payload).
25
- readonly appendEvent: AppendEventFn<TMap>;
26
- // Escape hatch for runtime-pluggable events without compile-time
27
- // augmentation. Same runtime semantics; type-surface is `payload: unknown`.
28
- readonly unsafeAppendEvent: UnsafeAppendEventFn;
29
- // Read an aggregate stream — useful when a saga needs to inspect the
30
- // current state of a different aggregate before deciding what to emit.
31
- readonly loadAggregate: (
32
- aggregateId: string,
33
- options?: { readonly asOf?: Temporal.Instant },
34
- ) => Promise<readonly StoredEvent[]>;
35
- // The app registry — same instance HandlerContext/JobContext expose. Lets
36
- // an apply resolve extension-point usages (registry.getExtensionUsages),
37
- // e.g. a provider-routed MSP picking a handler by payload discriminant.
38
- readonly registry: Registry;
39
- // Binary storage handle factory, mirrors AppContext.files. Present when
40
- // the app booted with `files.storageProvider`; undefined otherwise.
41
- // Post-processing MSPs (resize, EXIF-strip, virus-scan) read bytes via
42
- // `ctx.files.ref(payload.storageKey).read()` and write derivates via
43
- // `.derive("thumb").write(...)` — binaries never ride through events.
44
- readonly files?: FileContext;
45
- // Derive-on-first-use variants, mirrors AppContext.derivatives. Present
46
- // exactly when `files` is — same file-foundation-provider precondition.
47
- readonly derivatives?: DerivativesContext;
48
- // Tenant-scoped secret reads for side-effect MSPs (e.g. step-dispatcher's
49
- // webhook auth), audited via the read's own auditCtx. Present when the
50
- // app booted with the secrets feature; undefined otherwise.
51
- readonly secrets?: SecretsContext;
52
- };
package/src/nav-icon.ts DELETED
@@ -1,105 +0,0 @@
1
- // Closed vocabulary of nav and button icon keys. NavDefinition.icon,
2
- // ScreenNavSugar.icon, ConfigMask.icon and ButtonProps.icon/iconEnd are all
3
- // typed against this union, so an unregistered key is a compile error at the
4
- // r.nav()/r.screen()/config-mask/button call site instead of a silent
5
- // missing-icon at runtime.
6
- //
7
- // The renderer-web NAV_ICONS map (packages/renderer-web/src/icons.tsx) is
8
- // checked against this same union via `satisfies`, so the two can't drift —
9
- // add a key here only together with its lucide-react entry there, and vice
10
- // versa.
11
- //
12
- // Declared as a runtime tuple (not just a type) so callers that sit outside
13
- // this repo's `tsc --build` project graph (e.g. samples, external consumers
14
- // resolving from a stale published type) still get a runtime-checkable
15
- // vocabulary — the boot-validator's validateActionHasIcon checks a declared
16
- // icon against NAV_ICON_KEYS instead of trusting "not undefined".
17
- export const NAV_ICON_KEYS = [
18
- "dashboard",
19
- "layout-grid",
20
- "book-open",
21
- "clipboard-list",
22
- "package",
23
- "gauge",
24
- "list",
25
- "table",
26
- "layers",
27
- "building",
28
- "calculator",
29
- "wallet",
30
- "coins",
31
- "credit-card",
32
- "piggy-bank",
33
- "receipt",
34
- "chart",
35
- "bar-chart",
36
- "trending",
37
- "sparkles",
38
- "wand",
39
- "calendar",
40
- "file",
41
- "folder",
42
- "folder-open",
43
- "home",
44
- "bell",
45
- "shield",
46
- "shield-check",
47
- "send",
48
- "settings",
49
- "users",
50
- "user",
51
- "search",
52
- "tag",
53
- "key",
54
- "link",
55
- "palette",
56
- "share",
57
- "server",
58
- "mail",
59
- "lock",
60
- "hash",
61
- "download",
62
- "upload",
63
- "rocket",
64
- "plus",
65
- "languages",
66
- "trash",
67
- "x",
68
- "check",
69
- "arrow-left",
70
- "arrow-right",
71
- "copy",
72
- "pencil",
73
- "eye",
74
- "eye-off",
75
- "filter",
76
- "refresh",
77
- "more-horizontal",
78
- "more-vertical",
79
- "external-link",
80
- "chevron-down",
81
- "chevron-right",
82
- "save",
83
- "undo",
84
- "archive",
85
- "star",
86
- "flag",
87
- "clock",
88
- "map-pin",
89
- "phone",
90
- "printer",
91
- "alert-triangle",
92
- "info",
93
- "check-circle",
94
- "x-circle",
95
- "loader",
96
- "mic",
97
- "circle-stop",
98
- "image",
99
- ] as const;
100
-
101
- export type NavIconKey = (typeof NAV_ICON_KEYS)[number];
102
-
103
- // Alias kept because the union stopped being nav-only — actions and fields
104
- // (added on this branch) also key their icons against it.
105
- export type IconKey = NavIconKey;