@cosmicdrift/kumiko-types 0.386.0 → 0.388.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/LICENSE CHANGED
@@ -1,57 +1,21 @@
1
- Business Source License 1.1
2
-
3
- Parameters
4
-
5
- Licensor: Marc Frost
6
-
7
- Licensed Work: @cosmicdrift/kumiko-types
8
- The Licensed Work is © 2026 Marc Frost.
9
-
10
- Additional Use Grant:
11
- You may use the Licensed Work in production for any purpose, including
12
- commercially, EXCEPT for the Restricted Use.
13
-
14
- "Restricted Use" is defined as using the Licensed Work to provide a platform
15
- or service to third parties that allows them to host, deploy, or run their
16
- own applications built with the Licensed Work. This includes, but is not
17
- limited to: managed hosting services, software-as-a-service (SaaS) platforms,
18
- platform-as-a-service (PaaS), developer platforms, or any multi-tenant
19
- managed offering of the Licensed Work.
20
-
21
- This restriction does not apply to the Licensor, any entity controlled by,
22
- controlling, or under common control with the Licensor ("Affiliates"), or
23
- contractors acting on their behalf. The Licensor remains free to use the
24
- Licensed Work for any purpose, including for the operation of kumiko.rocks.
25
-
26
- Change Date: 2030-05-05
27
- Change License: Apache License, Version 2.0
28
-
29
-
30
- Terms
31
-
32
- The Licensor hereby grants you the right to copy, modify, create derivative works,
33
- redistribute, and make non-production use of the Licensed Work. The Licensor may
34
- make an Additional Use Grant, above, permitting limited production use.
35
-
36
- Effective on the Change Date, or the fourth anniversary of the first publicly
37
- available distribution of the Licensed Work under this License, whichever comes
38
- first, this License will convert to the Change License.
39
-
40
- This Business Source License governs use of the Licensed Work in all cases, except
41
- as to any use that is explicitly granted in the Additional Use Grant above or
42
- under the Change License after the Change Date.
43
-
44
- If your use of the Licensed Work does not comply with the requirements of this
45
- License, you must cease use of the Licensed Work immediately.
46
-
47
- All copies of the Licensed Work, and all derivative works thereof, must include
48
- this License.
49
-
50
- This License does not grant you any right, title, or interest in any trademark,
51
- logo, or branding of the Licensor, except as required to comply with this License.
52
-
53
- TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON AN
54
- “AS IS” BASIS. LICENSOR DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
55
- WITHOUT LIMITATION WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
56
- TITLE, AND NON-INFRINGEMENT. IN NO EVENT WILL LICENSOR BE LIABLE FOR ANY DAMAGES
57
- ARISING OUT OF OR RELATED TO THIS LICENSE OR THE USE OF THE LICENSED WORK.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Marc Frost
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @cosmicdrift/kumiko-types
2
2
 
3
- [![License: BUSL-1.1](https://img.shields.io/badge/License-BUSL--1.1-blue.svg)](../../LICENSE)
3
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](../../LICENSE)
4
4
  [![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue.svg)](https://www.typescriptlang.org/)
5
5
 
6
6
  Framework type definitions for Kumiko — `FeatureDefinition`, boot-check types,
package/dist/config.d.ts CHANGED
@@ -50,7 +50,7 @@ export type ConfigKeyDefinition<T extends ConfigKeyType = ConfigKeyType> = {
50
50
  * encrypted under the DEK of the scope actually written to (tenant-row
51
51
  * → tenant subject, user-row → user subject). Only on `type: "text"`,
52
52
  * `scope !== "system"` (no subject there), and mutually exclusive with
53
- * `encrypted` (kumiko-platform#231/#459). */
53
+ * `encrypted`. */
54
54
  readonly piiEncrypted?: boolean;
55
55
  readonly options?: readonly string[];
56
56
  /** Only on `type: "select"`: loads the options from this query (QN), contract
@@ -231,6 +231,8 @@ export type NotificationTemplateMeta = {
231
231
  readonly layoutSlug?: string;
232
232
  readonly category?: "transactional" | "marketing";
233
233
  readonly sender?: string;
234
+ readonly senderName?: string;
235
+ readonly replyTo?: string;
234
236
  };
235
237
  export type NotificationTemplateBody = {
236
238
  readonly body: string;
@@ -14,6 +14,9 @@ export type WriteHandlerDefinition<TName extends string = string, TSchema extend
14
14
  readonly unsafeSkipTransitionGuard?: boolean;
15
15
  readonly rateLimit?: RateLimitDeclaration;
16
16
  readonly additionalRateLimits?: readonly PayloadRateLimitOption[];
17
+ /** Tokens each request books on every declared rateLimit bucket, computed from the validated
18
+ * payload (e.g. `(p) => p.files.length`). Replaces the options' `cost`; results below 1 count as 1. */
19
+ readonly rateLimitCost?: (payload: z.infer<TSchema>) => number;
17
20
  readonly escapeHatch?: EscapeHatchDeclaration;
18
21
  readonly reserveBeforeTransaction?: PreTransactionReservation;
19
22
  readonly beforeTransaction?: BeforeTransactionPhase<z.infer<TSchema>, TPrepared>;
@@ -31,6 +34,9 @@ export type WriteHandlerInput<TName extends string = string, TSchema extends Zod
31
34
  readonly unsafeSkipTransitionGuard?: boolean;
32
35
  readonly rateLimit?: RateLimitDeclaration;
33
36
  readonly additionalRateLimits?: readonly PayloadRateLimitOption[];
37
+ /** Tokens each request books on every declared rateLimit bucket, computed from the validated
38
+ * payload (e.g. `(p) => p.files.length`). Replaces the options' `cost`; results below 1 count as 1. */
39
+ readonly rateLimitCost?: (payload: z.infer<TSchema>) => number;
34
40
  readonly escapeHatch?: EscapeHatchDeclaration;
35
41
  readonly reserveBeforeTransaction?: PreTransactionReservation;
36
42
  readonly beforeTransaction?: BeforeTransactionPhase<z.infer<TSchema>, TPrepared>;
@@ -2,6 +2,6 @@
2
2
  // Plain-data types for EntityTableMeta — split from the runtime
3
3
  // (deriveEntityTableMeta, resolveTableName, defineUnmanagedTable) in
4
4
  // entity-table-meta.ts. Prep step for the types-only package extraction
5
- // (#1283) — this file must have ONLY `import type`, no value imports
5
+ // — this file must have ONLY `import type`, no value imports
6
6
  // (crypto/DB deps).
7
7
  export {};
@@ -3,6 +3,7 @@ import type { EntityDefinition } from "./fields.ts";
3
3
  import type { SessionUser, WriteResult } from "./handlers.ts";
4
4
  import type { DeleteContext, SaveContext } from "./hooks.ts";
5
5
  import type { EntityId, TenantId } from "./identifiers.ts";
6
+ import type { ListAggregatePayload, ListAggregateResult } from "./list-aggregate-types.ts";
6
7
  import type { SearchAdapter } from "./search-adapter.ts";
7
8
  import type { TenantDb } from "./tenant-db-types.ts";
8
9
  export type ParentVisibilityOption = {
@@ -21,6 +22,38 @@ export type LockGuardOption = {
21
22
  readonly unsafeSkipLockGuard?: boolean;
22
23
  readonly writePurpose?: WritePurpose;
23
24
  };
25
+ export type ListRuntimeOptions = {
26
+ readonly searchAdapter?: SearchAdapter;
27
+ readonly includeDeleted?: boolean;
28
+ readonly referenceSearch?: {
29
+ readonly fields: ReadonlyArray<{
30
+ readonly fieldName: string;
31
+ readonly targetEntityName: string;
32
+ readonly labelField: string;
33
+ }>;
34
+ readonly resolveEntity: (entityName: string) => EntityDefinition | undefined;
35
+ };
36
+ readonly referenceSort?: {
37
+ readonly fields: ReadonlyArray<{
38
+ readonly fieldName: string;
39
+ readonly targetEntityName: string;
40
+ readonly labelField: string;
41
+ }>;
42
+ readonly resolveEntity: (entityName: string) => EntityDefinition | undefined;
43
+ };
44
+ readonly parentVisibility?: ParentVisibilityOption;
45
+ };
46
+ type ListFilterOption = {
47
+ readonly field: string;
48
+ readonly op: "eq" | "ne" | "lt" | "gt" | "lte" | "gte" | "in";
49
+ readonly value: unknown;
50
+ };
51
+ export type ListAggregateRequest = {
52
+ readonly search?: string | undefined;
53
+ readonly filter?: ListFilterOption | undefined;
54
+ readonly filters?: readonly ListFilterOption[] | undefined;
55
+ readonly aggregate: ListAggregatePayload;
56
+ };
24
57
  export type EventStoreExecutor<Row extends Record<string, unknown> = Record<string, unknown>> = {
25
58
  create: (payload: Record<string, unknown>, user: SessionUser, db: TenantDb, options?: StreamTenantOption & {
26
59
  preSave?: PreSaveRunner;
@@ -64,36 +97,19 @@ export type EventStoreExecutor<Row extends Record<string, unknown> = Record<stri
64
97
  readonly value: unknown;
65
98
  }> | undefined;
66
99
  }, user: SessionUser, db: TenantDb,
67
- /** Tier 2.7e audit fix: per-call SearchAdapter override. When the
100
+ /** Per-call SearchAdapter override. When the
68
101
  * executor didn't get a SearchAdapter via Options at build time
69
102
  * (defaultEntityQueryHandler path), the caller (handler) can pass
70
103
  * one from ctx.searchAdapter here at runtime.
71
104
  * options.searchAdapter (build-time) wins — the runtime override
72
105
  * is the fallback for the default wrapper. */
73
- runtimeOptions?: {
74
- readonly searchAdapter?: SearchAdapter;
75
- readonly includeDeleted?: boolean;
76
- readonly referenceSearch?: {
77
- readonly fields: ReadonlyArray<{
78
- readonly fieldName: string;
79
- readonly targetEntityName: string;
80
- readonly labelField: string;
81
- }>;
82
- readonly resolveEntity: (entityName: string) => EntityDefinition | undefined;
83
- };
84
- readonly referenceSort?: {
85
- readonly fields: ReadonlyArray<{
86
- readonly fieldName: string;
87
- readonly targetEntityName: string;
88
- readonly labelField: string;
89
- }>;
90
- readonly resolveEntity: (entityName: string) => EntityDefinition | undefined;
91
- };
92
- readonly parentVisibility?: ParentVisibilityOption;
93
- }) => Promise<CursorResult<Row>>;
106
+ runtimeOptions?: ListRuntimeOptions) => Promise<CursorResult<Row>>;
107
+ /** Groups and measures over the same WHERE as `list` (filters, search, ownership, field-read gates); paging and sort are ignored. */
108
+ aggregate: (payload: ListAggregateRequest, user: SessionUser, db: TenantDb, runtimeOptions?: ListRuntimeOptions) => Promise<ListAggregateResult>;
94
109
  detail: (payload: {
95
110
  id: EntityId;
96
111
  }, user: SessionUser, db: TenantDb, options?: {
97
112
  readonly parentVisibility?: ParentVisibilityOption;
98
113
  }) => Promise<Row | null>;
99
114
  };
115
+ export {};
@@ -3,5 +3,5 @@ export function isPersonalDataGated(origin) {
3
3
  }
4
4
  // Stamped when an append runs outside any attributed scope (seed scripts,
5
5
  // tests, direct event-store use). A distinct value, not an omission —
6
- // omitted would be indistinguishable from a pre-#3043 row.
6
+ // omitted would be indistinguishable from an earlier row.
7
7
  export const UNATTRIBUTED_ORIGIN = "unknown";
@@ -1,18 +1,18 @@
1
- // Cross-Feature Compile-Time-Type-Map.
1
+ // Cross-Feature Compile-Time Type Map.
2
2
  //
3
- // Zweck: ctx.appendEvent / ctx.queryProjection / dispatcher.write gegen ein
4
- // statisch bekanntes Schema-Bild prüfen, statt erst zur Boot- oder Runtime
5
- // (zod-validate) zu scheitern. Designer/AI-Layer profitiert dadurch sofort:
6
- // Autocomplete kennt alle Event-Typen aller geladenen Features, payload-
7
- // Shape-Mismatches werden im Editor angezeigt, nicht erst beim Boot.
3
+ // Purpose: check ctx.appendEvent / ctx.queryProjection / dispatcher.write against a
4
+ // statically known schema image instead of failing only at boot or runtime
5
+ // (zod-validate). The Designer/AI layer benefits immediately: autocomplete knows all
6
+ // event types from all loaded features, and payload-shape mismatches appear in the
7
+ // editor rather than only at boot.
8
8
  //
9
- // Befüllung erfolgt per Feature über `declare module "@cosmicdrift/kumiko-framework/engine"`
10
- // — entweder hand-geschrieben (für stabile Frameworks-Internals) oder vom
11
- // Codegen-Skript erzeugt (für apps/bundled-features). Empty defaults sind
12
- // kein Bug: ein Feature ohne Augmentation ist runtime-pluggable und nutzt
13
- // die Fallback-Overload mit `unknown` payload.
9
+ // Each feature populates the map through `declare module "@cosmicdrift/kumiko-framework/engine"`
10
+ // — either manually (for stable framework internals) or through the code-generation
11
+ // script (for apps/bundled-features). Empty defaults are not a bug: a feature without
12
+ // augmentation is runtime-pluggable and uses the fallback overload with `unknown`
13
+ // payload.
14
14
  //
15
- // Pattern für hand-geschriebene Augmentation am File-Top:
15
+ // Pattern for a manually written augmentation at the top of the file:
16
16
  //
17
17
  // declare module "@cosmicdrift/kumiko-framework/engine" {
18
18
  // interface KumikoEventTypeMap {
package/dist/feature.d.ts CHANGED
@@ -79,7 +79,7 @@ export type StoreTableOptions = {
79
79
  /** Direct-write stores skip the executor, so the executor's PII
80
80
  * encryption never runs for them — a feature whose meta carries
81
81
  * piiSubjectFields must encrypt those fields itself before every
82
- * insert/update and declare that here, or boot fails (#820). */
82
+ * insert/update and declare that here, or boot fails. */
83
83
  readonly piiEncryptedOnWrite?: true;
84
84
  };
85
85
  /** Per-feature store-table registration. `meta` is the `EntityTableMeta`
@@ -152,17 +152,17 @@ export type FeatureDefinition = {
152
152
  readonly extensionSelectors: readonly ExtensionSelectorDef[];
153
153
  /**
154
154
  * Cross-feature API names this feature exposes via `r.exposesApi(name)`.
155
- * Pure Marker-Deklaration — die echte Implementation wird als
156
- * Query-/Write-Handler unter dem QN-Pattern registriert (z.B.
157
- * `compliance-profiles:query:effective-profile`). Boot-Validator prüft
158
- * dass jedes `r.usesApi(name)` einen passenden Exposer hier findet —
159
- * Tippfehler oder Drop-Refactorings werden zu Boot-Fail statt Runtime-Crash.
155
+ * Pure marker declaration — the implementation is registered separately as
156
+ * a query or write handler under the QN pattern (for example,
157
+ * `compliance-profiles:query:effective-profile`). The boot validator checks
158
+ * that every `r.usesApi(name)` finds a matching exposer, so typos or dropped
159
+ * refactors fail at boot instead of causing a runtime crash.
160
160
  */
161
161
  readonly exposedApis: ReadonlySet<string>;
162
162
  /**
163
- * Cross-feature API names this feature calls. Pflicht-Boot-Check:
164
- * jeder Eintrag muss in `exposedApis` irgendeines Features auftauchen
165
- * UND das Provider-Feature muss in requires/optionalRequires sein.
163
+ * Cross-feature API names this feature calls. The boot check requires every
164
+ * entry to appear in some feature's `exposedApis` and the provider feature
165
+ * to be listed in requires/optionalRequires.
166
166
  */
167
167
  readonly usedApis: ReadonlySet<string>;
168
168
  /**
@@ -406,30 +406,30 @@ export type FeatureRegistrar<TFeature extends string = string> = {
406
406
  readonly panels?: readonly ExtensionSelectorPanel[];
407
407
  }): void;
408
408
  /**
409
- * Marker-Deklaration: dieses Feature stellt eine Cross-Feature-API
410
- * unter dem genannten Namen bereit. Die eigentliche Implementation
411
- * wird separat als Query- oder Write-Handler unter dem QN-Pattern
412
- * registriert; `r.exposesApi` ist reine Boot-Check-Surface.
409
+ * Marker declaration: this feature provides a cross-feature API under the
410
+ * given name. The implementation is registered separately as a query or
411
+ * write handler under the QN pattern; `r.exposesApi` is only a boot-check
412
+ * surface.
413
413
  *
414
- * Boot-Validator prüft, dass jedes `r.usesApi(name)` einen passenden
415
- * Exposer findet, dass das Exposer-Feature in requires/optionalRequires
416
- * gelisted ist und dass kein API-Name doppelt exposed wird.
414
+ * The boot validator checks that every `r.usesApi(name)` finds a matching
415
+ * exposer, that the exposer feature is listed in requires/optionalRequires,
416
+ * and that no API name is exposed more than once.
417
417
  *
418
418
  * ```ts
419
419
  * defineFeature("compliance-profiles", (r) => {
420
420
  * r.exposesApi("compliance.forTenant");
421
421
  * r.queryHandler({
422
422
  * name: "compliance:query:for-tenant",
423
- * // ... echte Implementation
423
+ * // ... actual implementation
424
424
  * });
425
425
  * });
426
426
  * ```
427
427
  */
428
428
  exposesApi(apiName: string): void;
429
429
  /**
430
- * Declares that this feature calls a cross-feature API. Boot-Validator
431
- * checkt dass irgendein anderes Feature `r.exposesApi(apiName)` macht
432
- * und dass dieses Feature `r.requires/optionalRequires` darauf hat.
430
+ * Declares that this feature calls a cross-feature API. The boot validator
431
+ * checks that another feature provides `r.exposesApi(apiName)` and that
432
+ * this feature lists it in `r.requires/optionalRequires`.
433
433
  *
434
434
  * ```ts
435
435
  * defineFeature("user-data-rights", (r) => {
@@ -447,9 +447,9 @@ export type FeatureRegistrar<TFeature extends string = string> = {
447
447
  * Use for cross-feature invariants that `r.requires` can't express
448
448
  * because they're conditional (only fail when the feature has a
449
449
  * specific shape), e.g. "if this feature has PII entities, some
450
- * user-data-hook feature must be mounted" (the prompt-store trap,
451
- * kumiko-enterprise#229 — a UserData feature was written but never
452
- * mounted, and nothing caught it at boot):
450
+ * user-data-hook feature must be mounted" (the prompt-store trap —
451
+ * a UserData feature was written but never mounted, and nothing caught
452
+ * it at boot):
453
453
  *
454
454
  * ```ts
455
455
  * defineFeature("prompt-store", (r) => {