@cosmicdrift/kumiko-types 0.176.2 → 0.178.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-types",
3
- "version": "0.176.2",
3
+ "version": "0.178.1",
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/feature.ts CHANGED
@@ -64,7 +64,7 @@ import type {
64
64
  ValidationHookFn,
65
65
  } from "./hooks";
66
66
  import type { HttpRouteDefinition } from "./http-route";
67
- import type { NavDefinition } from "./nav";
67
+ import type { ContentCollectionDefinition, NavDefinition } from "./nav";
68
68
  import type {
69
69
  EntityProjectionExtension,
70
70
  MultiStreamProjectionDefinition,
@@ -356,6 +356,11 @@ export type FeatureDefinition = {
356
356
  // feature exports via setup-return — buildTarget consumes the handle,
357
357
  // not this slot. See visual-tree.md A5 + A7.
358
358
  readonly treeActions?: Readonly<Record<string, TreeActionDef>>;
359
+ // Content collections declared via r.contentCollection(). Keyed by the
360
+ // feature-local short id. Each one also produced a nav entry under the
361
+ // same id — this slot carries the `kind` the client needs to build the
362
+ // matching tree provider, which a NavDefinition has no place for.
363
+ readonly contentCollections?: Readonly<Record<string, ContentCollectionDefinition>>;
359
364
  // HTTP-Routes declared via r.httpRoute(). Index is "METHOD path"
360
365
  // (z.B. "GET /feed.xml") — eindeutig pro Feature. Die App-Server-
361
366
  // Boot-Stage iteriert getAllHttpRoutes() und mountet jede Route auf
@@ -764,6 +769,17 @@ export type FeatureRegistrar<TFeature extends string = string> = {
764
769
  // that parent chains don't contain cycles.
765
770
  nav(definition: NavDefinition): void;
766
771
 
772
+ // Register a content collection — a set of template-resources of one kind,
773
+ // navigable where it fachlich belongs (mail templates under Mail, not under
774
+ // a central "Content" section). Sugar over r.nav(): registers the nav entry
775
+ // with `provider: true` under the same id and records the kind so the client
776
+ // can wire the tree provider without repeating navId + kind.
777
+ //
778
+ // Returns the qualified nav name ("<feature>:nav:<id>") — apps that pass the
779
+ // collection to a client feature explicitly take it from here instead of
780
+ // re-typing the QN.
781
+ contentCollection(definition: ContentCollectionDefinition): string;
782
+
767
783
  // Register a workspace — a persona-/role-scoped UI surface. Pure UI
768
784
  // composition; the registry qualifies the short id to
769
785
  // "<feature>:workspace:<id>". Boot-validation checks that any nav refs
package/src/nav.ts CHANGED
@@ -65,3 +65,54 @@ export type NavDefinition = {
65
65
  // → entry belongs to no workspace).
66
66
  readonly workspaces?: readonly string[];
67
67
  };
68
+
69
+ // A feature's content collection — a set of template-resources of one `kind`,
70
+ // mounted in the nav next to the feature it belongs to rather than under a
71
+ // central "Content" section. Declared via r.contentCollection(), which
72
+ // registers the nav entry (always `provider: true`, the tree children arrive
73
+ // at runtime) and records the `kind` so the client can build the matching tree
74
+ // provider without the app repeating it.
75
+ //
76
+ // `parent` may point at another feature's nav QN; the boot validator rejects
77
+ // dangling refs, so a collection mounted under a feature that isn't mounted
78
+ // fails boot instead of silently disappearing from the sidebar.
79
+ export type ContentCollectionDefinition = {
80
+ // Feature-local short id, kebab-case. Also becomes the nav entry's id, so
81
+ // it must not collide with an r.nav()/r.screen() id in the same feature.
82
+ // Handlers take this id, not a kind — a payload can therefore only ever
83
+ // address a declared collection, with the rules that were declared for it.
84
+ readonly id: string;
85
+ // Which template-resource kind this collection lists ("mail-html",
86
+ // "document-pdf", "text-block", ...). The engine keeps it opaque —
87
+ // bundled-features owns the kind vocabulary. Two collections may share a
88
+ // kind and still differ in access and ownership.
89
+ readonly kind: string;
90
+ // Who may read and write this collection's entries. Declared at mount time
91
+ // by the app, because a bundled feature cannot know the host's role
92
+ // vocabulary — same reasoning as the `access` option on tags/folders/ledger.
93
+ // Omitted means the mounting app didn't decide; the feature's own default
94
+ // applies.
95
+ readonly access?: AccessRule;
96
+ // "tenant": one set of entries shared by everyone in the tenant (reply
97
+ // snippets an admin curates). "user": every user keeps their own (mail
98
+ // signatures). Defaults to "tenant".
99
+ readonly ownership?: "tenant" | "user";
100
+ readonly nav: {
101
+ readonly label: string;
102
+ readonly icon?: string;
103
+ readonly parent?: string;
104
+ readonly order?: number;
105
+ // Visibility of the nav node. Leave unset — it then follows the
106
+ // collection's `access`, so the sidebar never offers a node whose
107
+ // contents the handler will refuse. Set it only to hide the node from
108
+ // someone who may still reach the data another way.
109
+ readonly access?: AccessRule;
110
+ readonly workspaces?: readonly string[];
111
+ // "+" affordance on the node and hover actions on the row — same meaning
112
+ // as on NavDefinition. Without a createAction a collection can only list
113
+ // what already exists; the target is usually the owning feature's
114
+ // r.treeActions create.
115
+ readonly createAction?: TreeAction;
116
+ readonly actions?: readonly TreeAction[];
117
+ };
118
+ };