@ai-matrx/associations 0.2.0 → 0.4.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/CHANGELOG.md +149 -0
- package/README.md +35 -5
- package/dist/core/index.cjs +74 -1
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +32 -1
- package/dist/core/index.d.ts +32 -1
- package/dist/core/index.js +74 -1
- package/dist/core/index.js.map +1 -1
- package/dist/index.cjs +6 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +50 -2
- package/dist/index.d.ts +50 -2
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +3905 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.cts +1841 -0
- package/dist/react/index.d.ts +1841 -0
- package/dist/react/index.js +3926 -0
- package/dist/react/index.js.map +1 -0
- package/package.json +24 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,154 @@
|
|
|
1
1
|
# Changelog — @ai-matrx/associations
|
|
2
2
|
|
|
3
|
+
## 0.4.0 — 2026-08-29 (unreleased; W4 completion)
|
|
4
|
+
|
|
5
|
+
The three faces STOPPED at the W3+W4 build for missing design-system
|
|
6
|
+
primitives, now built against `@ai-matrx/design-system` 0.3.0 (Command
|
|
7
|
+
family incl. CommandDialog, the Select family, the CreatablePicker
|
|
8
|
+
composite) — the optional peer floor moves to **`>=0.3.0`**. Behavior ported
|
|
9
|
+
VERBATIM from the matrx-frontend originals (each re-read in full
|
|
10
|
+
2026-08-29); only the measured seams inverted, chrome never vendored.
|
|
11
|
+
|
|
12
|
+
- **`AssociationEntitySelect` (`src/react/components/AssociationEntitySelect.tsx`)**
|
|
13
|
+
— the canonical "name dropdown" (display / inline rename / switch / add new
|
|
14
|
+
/ unlink), adapter-driven via the already-shipping
|
|
15
|
+
`AssociationEntitySelectAdapter` contract + default adapter hook. Seams:
|
|
16
|
+
`getEntityInfo` → the store's registry merge engine (`Icon: null` →
|
|
17
|
+
`DefaultEntityIcon`); `@/lib/toast` → the notifier port;
|
|
18
|
+
`EntityDoorControls` → the entityDoors port's `DoorControls` (absent → the
|
|
19
|
+
name and rows render without doors, matching the picker precedent); lucide
|
|
20
|
+
→ inlined glyphs (C19).
|
|
21
|
+
- **`CategorySelect` (`src/react/components/CategorySelect.tsx`)** — THE
|
|
22
|
+
single-value picker over one `platform.categories` dimension, the
|
|
23
|
+
CreatablePicker composite with the hierarchy parent-select in
|
|
24
|
+
`createExtra`. Seams: the Redux active-organization read
|
|
25
|
+
(`selectOrganizationId`) → the identity port's optional `ensureOrgId()`
|
|
26
|
+
(`orgId` prop wins; with neither, create refuses LOUDLY — notifier + no
|
|
27
|
+
RPC); toasts → notifier. NOTE: the origin's two-part success toast
|
|
28
|
+
(message + description) is joined into the notifier's single success
|
|
29
|
+
message (the port's `success(msg)` carries no description); content
|
|
30
|
+
preserved.
|
|
31
|
+
- **`CategoryTagPicker` (`src/react/components/CategoryTagPicker.tsx`)** —
|
|
32
|
+
THE multi-select tagger over the canonical `entity → category` edge
|
|
33
|
+
(full-role `setTargets` semantics verbatim, one write at a time). Seams:
|
|
34
|
+
the host-shaped `ensureOrgId` (`@/lib/organizations/personalOrg`) →
|
|
35
|
+
`identity.ensureOrgId` per the design's seam table, with the loud
|
|
36
|
+
`ensure_org_missing` refusal when neither the `orgId` prop nor the port
|
|
37
|
+
can answer; `console.error` → errorSink
|
|
38
|
+
(`category_tag_set_targets_failed` / `category_tag_create_failed`);
|
|
39
|
+
toasts → notifier; the `icon` prop's `LucideIcon` type → the structural
|
|
40
|
+
`TagPickerIcon`.
|
|
41
|
+
- **`buildCategoryHierarchy` → `/core`
|
|
42
|
+
(`src/core/categoryHierarchy.ts`)** — the two-level display-order util
|
|
43
|
+
both category faces consume, ported verbatim from
|
|
44
|
+
`features/scopes/utils/categoryHierarchy.ts` (pure, React-free), exported
|
|
45
|
+
from `/core`.
|
|
46
|
+
- **Four new inlined glyphs (C19)**: `ChevronDownIcon`,
|
|
47
|
+
`ChevronsUpDownIcon`, `CornerDownRightIcon`, `TagIcon`.
|
|
48
|
+
- **Token vocabulary regenerated from the live registry: 651 → 654 tokens**
|
|
49
|
+
(`platform_continued_access`, `route_manifest_entry`, `short_link` landed
|
|
50
|
+
after the 0.3.0 generation; caught by the W5 swap agent's token-parity
|
|
51
|
+
gate). `check:entity-types` green against live.
|
|
52
|
+
- 16 new jsdom behavioral tests (render + interaction + degradations against
|
|
53
|
+
fake ports) → 147 total; full gate green (`typecheck`, `test`,
|
|
54
|
+
`check:package` incl. the packed-tarball canary).
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
## 0.3.0 — 2026-08-29 (unreleased; W3 + W4 of the extraction)
|
|
58
|
+
|
|
59
|
+
Waves 3 and 4: the `/react` subpath — the seven hooks riding the /core store
|
|
60
|
+
via `useSyncExternalStore`, and the faces/pickers/capture toolbar. Behavior
|
|
61
|
+
ported VERBATIM from the matrx-frontend originals (re-read in full
|
|
62
|
+
2026-08-29); only the measured seams inverted onto the W1 ports. `/react` is
|
|
63
|
+
the package's ONE banner group: its dist chunks carry `"use client"` (tsup
|
|
64
|
+
banner + `scripts/stamp-client-boundary.mjs` belt); the root and `/core`
|
|
65
|
+
stay pure, and `verify-tarball` now proves both directions.
|
|
66
|
+
|
|
67
|
+
- **`AssociationsProvider` (`src/react/context.tsx`)** — the one React
|
|
68
|
+
binding point: the host constructs the /core store in its binding module
|
|
69
|
+
and mounts the provider with the five UI ports (notifier / windowShell /
|
|
70
|
+
capture / pickerOverrides / entityDoors). Every hook/face reaches the
|
|
71
|
+
store via `useAssociationsStore()`, which THROWS with a precise message
|
|
72
|
+
when no provider is mounted. `useNotifier()` implements the notifier
|
|
73
|
+
degradation: absent → warn ONCE via errorSink, every user-facing failure
|
|
74
|
+
still screams to the sink.
|
|
75
|
+
- **W3 hooks, signatures byte-compatible with the originals** (the W5 swap
|
|
76
|
+
is a re-export flip + Redux-fragment deletion, call sites unchanged):
|
|
77
|
+
`useAssociations` (+ `useEntityRelationships` alias + re-exported
|
|
78
|
+
`AssociationWriteResult`), `useContainerLinks` (incl. the viewer-aware
|
|
79
|
+
`conversation_files` branch, generation/stale guards verbatim),
|
|
80
|
+
`useEntityTitles` (labels never exempt the liveness read; one settled
|
|
81
|
+
round proves absence), `useCategories`, `useUniversalEntitySearch`
|
|
82
|
+
(debounce + recents via `ues_list`), `useAssociationCandidates`,
|
|
83
|
+
`useAssociationEntitySelectAdapter` (+ the
|
|
84
|
+
`AssociationEntitySelectAdapter` contract, which now lives with the
|
|
85
|
+
hook). Redux selectors/thunks → `useSyncExternalStore` over the store;
|
|
86
|
+
`@/lib/toast` → notifier; `console.error` → errorSink; the host `Json`
|
|
87
|
+
type → `unknown` (`ContainerLink.metadata`, `attach` metadata).
|
|
88
|
+
`useAssociationCandidates`' Redux `selectUserId` read became a LENIENT
|
|
89
|
+
identity-port read (null when unauthenticated): `ownerId` is a
|
|
90
|
+
candidate-read filter, not an auth gate — write paths keep the loud
|
|
91
|
+
`requireUserId` contract.
|
|
92
|
+
- **W4 faces**: `AssociationCard`, `AssociationCardGrid`, `AssociationList`
|
|
93
|
+
(+ `ContainerResourcesAdapter` + `useContainerLinksAdapter`),
|
|
94
|
+
`AssociationPicker` (+ `AssociationCandidateBody` + the
|
|
95
|
+
create-then-associate footer), `UniversalAssociationPicker`,
|
|
96
|
+
`AttachedItemsSheet`, `AssociationCaptureToolbar`, `AssociationWindow`,
|
|
97
|
+
`PrimaryEntityProvider`/`usePrimaryEntity`, plus the content-role chrome
|
|
98
|
+
(`CONTENT_ROLES`/`getContentRoleMeta` — display metadata is /react's;
|
|
99
|
+
the classification stays /core's) and the door-seam helpers
|
|
100
|
+
(`DoorRef`/`UnresolvedRef`).
|
|
101
|
+
- **Seam inversions (deliberate, per the design's Decision 2 table)**:
|
|
102
|
+
- the hardcoded `token === "file"` → FilePickerWindow branch became the
|
|
103
|
+
`pickerOverrides` port: `AssociationPicker` routes a registered token to
|
|
104
|
+
its override component (same `AssociationPickerProps` contract);
|
|
105
|
+
`UniversalAssociationPicker`'s browse mode opens the override too, so
|
|
106
|
+
"file enumeration only happens through the canonical picker" survives
|
|
107
|
+
the inversion; with no override the generic candidate list serves every
|
|
108
|
+
token (the documented degradation);
|
|
109
|
+
- `WindowPanel` → the `windowShell` port; absent → a package-internal
|
|
110
|
+
fixed centered overlay (non-draggable, same anatomy, page behind stays
|
|
111
|
+
interactive);
|
|
112
|
+
- `EntityRef`/`EntityDoorControls`/access-gate `UnresolvedEntityRef` →
|
|
113
|
+
the `entityDoors` port; absent → title text with the overlay `hrefFor`
|
|
114
|
+
anchor when present, plain text otherwise, and the package's plain
|
|
115
|
+
"Unavailable" chip for unreadable targets;
|
|
116
|
+
- the capture toolbar's `features/files` + `features/data-tables` imports
|
|
117
|
+
→ the `capture` port, PER-HANDLER optional: chips render only when
|
|
118
|
+
their handler exists, zero handlers → no toolbar and no drop zone
|
|
119
|
+
(never dead buttons, never a drop that swallows files). The original's
|
|
120
|
+
"Add document" picker (a host command palette over
|
|
121
|
+
`listAccessibleDocuments`) has no capture handler by design — hosts
|
|
122
|
+
append it via `extraActions`. "New document" collects its name with an
|
|
123
|
+
inline input row (the original's `TextInputDialog` is host chrome) and
|
|
124
|
+
opens the created document through the registry's `hrefFor` overlay
|
|
125
|
+
instead of a hardcoded `/documents/…` route;
|
|
126
|
+
- lucide icons → the package's own inlined SVGs (C19); host shadcn
|
|
127
|
+
`Input`/`Skeleton`/`Button`/`cn` → `@ai-matrx/design-system` (new
|
|
128
|
+
OPTIONAL peer at the `>=0.2.0` floor, per C18 — never vendored twins).
|
|
129
|
+
- **Store additions (additive, /core)**: `AssociationsStore` now exposes
|
|
130
|
+
the bound `errorSink` and `identity` so /react surfaces scream and read
|
|
131
|
+
identity without a second binding.
|
|
132
|
+
- **W4 gaps (deliberately NOT built — design-system 0.2.0 lacks the
|
|
133
|
+
primitives; vendoring twins is banned)**: `AssociationEntitySelect`,
|
|
134
|
+
`CategorySelect`, `CategoryTagPicker`. They need a Command/combobox
|
|
135
|
+
family (cmdk-style CommandInput/List/Item/Group/Empty + CommandDialog),
|
|
136
|
+
a Select, and the CreatablePicker composite. The
|
|
137
|
+
`AssociationEntitySelectAdapter` contract + default adapter hook (the
|
|
138
|
+
Redux-free seam) shipped anyway, so those faces are a pure-chrome build
|
|
139
|
+
once design-system grows.
|
|
140
|
+
- Tests: 131 (from 97) — jsdom behavioral suites per hook (subscription
|
|
141
|
+
updates, in-flight dedup across two consumers, error surfaces,
|
|
142
|
+
create-then-attach retry + loud outcome) and per face (render +
|
|
143
|
+
interaction against fake ports, every degradation branch: no windowShell,
|
|
144
|
+
no entityDoors, picker override routing, zero capture handlers,
|
|
145
|
+
created-but-unlinked screams).
|
|
146
|
+
- Gate: `pnpm typecheck && pnpm test && pnpm check:package` green; the
|
|
147
|
+
tarball canary installs react + react-dom + `@ai-matrx/design-system`
|
|
148
|
+
(npm, 0.2.0) into the empty project and imports AND requires `/react`,
|
|
149
|
+
proves the `"use client"` banner on both /react chunks and its absence
|
|
150
|
+
on all four pure chunks.
|
|
151
|
+
|
|
3
152
|
## 0.2.0 — 2026-08-29 (unreleased; W2 of the extraction)
|
|
4
153
|
|
|
5
154
|
Wave 2: the headless owns-persistence `/core` subpath — the service
|
package/README.md
CHANGED
|
@@ -4,11 +4,12 @@ THE one way to relate two entities on the AI Matrx platform: association edges,
|
|
|
4
4
|
categories, favorites/recents, and the generated entity-type vocabulary — shipped
|
|
5
5
|
as one package a Matrx client or enterprise app installs.
|
|
6
6
|
|
|
7
|
-
**v0.
|
|
8
|
-
chokepoint, guards, the never-throw result funnel,
|
|
9
|
-
|
|
10
|
-
list, pickers,
|
|
11
|
-
about the schema is binding — it is the package's
|
|
7
|
+
**v0.3 ships the types root, the headless `/core`, and the React binding
|
|
8
|
+
`/react`** — the service chokepoint, guards, the never-throw result funnel,
|
|
9
|
+
the registry merge engine, the subscribable cache store, the seven hooks, and
|
|
10
|
+
the association faces (cards, list, pickers, attached-items sheet, capture
|
|
11
|
+
toolbar). Everything below about the schema is binding — it is the package's
|
|
12
|
+
product.
|
|
12
13
|
|
|
13
14
|
```ts
|
|
14
15
|
import {
|
|
@@ -46,6 +47,35 @@ await store.favorites.setFavorite("note", noteId, true);
|
|
|
46
47
|
await assertDemandedSchema(supabase, { selfTest: true });
|
|
47
48
|
```
|
|
48
49
|
|
|
50
|
+
```tsx
|
|
51
|
+
// /react — the banner'd React binding (peer: react >=18 and
|
|
52
|
+
// @ai-matrx/design-system >=0.2.0 for the faces' chrome). Bind ONCE:
|
|
53
|
+
import {
|
|
54
|
+
AssociationsProvider,
|
|
55
|
+
useAssociations, // the seven hooks keep the app originals' exact signatures
|
|
56
|
+
AssociationCardGrid, // + AssociationCard / AssociationList / pickers / capture toolbar
|
|
57
|
+
PrimaryEntityProvider,
|
|
58
|
+
} from "@ai-matrx/associations/react";
|
|
59
|
+
|
|
60
|
+
<AssociationsProvider
|
|
61
|
+
store={store} // the /core store from createAssociationsStore
|
|
62
|
+
notifier={toastAdapter} // optional — absent warns once, failures still hit errorSink
|
|
63
|
+
windowShell={windowAdapter} // optional — absent falls back to a fixed overlay
|
|
64
|
+
capture={captureHandlers} // optional, per-handler — chips render only when bound
|
|
65
|
+
pickerOverrides={{ file: FilePickerWindowAdapter }} // optional per-token pickers
|
|
66
|
+
entityDoors={{ EntityRef, DoorControls, UnresolvedRef }} // optional doors
|
|
67
|
+
>
|
|
68
|
+
<PrimaryEntityProvider value={{ type: "organization", id, orgId, label }}>
|
|
69
|
+
<AssociationCardGrid />
|
|
70
|
+
</PrimaryEntityProvider>
|
|
71
|
+
</AssociationsProvider>;
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The faces style with Tailwind semantic tokens (`bg-card`,
|
|
75
|
+
`text-muted-foreground`, …): register this package as a Tailwind v4 source in
|
|
76
|
+
the consuming app (`@source "../node_modules/@ai-matrx/associations/dist"`)
|
|
77
|
+
the same way `@ai-matrx/design-system` documents.
|
|
78
|
+
|
|
49
79
|
## The demanded schema — read this first
|
|
50
80
|
|
|
51
81
|
This package is **opinionated like the Python `matrx-*` packages**: it does not
|
package/dist/core/index.cjs
CHANGED
|
@@ -26,6 +26,7 @@ __export(core_exports, {
|
|
|
26
26
|
SELF_TEST_MISSING_RPC: () => SELF_TEST_MISSING_RPC,
|
|
27
27
|
assertDemandedSchema: () => assertDemandedSchema,
|
|
28
28
|
associationsKey: () => associationsKey,
|
|
29
|
+
buildCategoryHierarchy: () => buildCategoryHierarchy,
|
|
29
30
|
createAssociationGuards: () => createAssociationGuards,
|
|
30
31
|
createAssociationHelpers: () => createAssociationHelpers,
|
|
31
32
|
createAssociationsService: () => createAssociationsService,
|
|
@@ -475,6 +476,7 @@ var ENTITY_TYPE_METADATA = {
|
|
|
475
476
|
"platform_actor_session": { token: "platform_actor_session", schema: "platform", table: "actor_session", label: "Actor session", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
|
|
476
477
|
"platform_actor_token": { token: "platform_actor_token", schema: "platform", table: "actor_token", label: "Actor token", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
|
|
477
478
|
"platform_actor_token_event": { token: "platform_actor_token_event", schema: "platform", table: "actor_token_event", label: "Actor token event", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
|
|
479
|
+
"platform_continued_access": { token: "platform_continued_access", schema: "platform", table: "continued_access", label: "Continued Access", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
|
|
478
480
|
"platform_outcome_event": { token: "platform_outcome_event", schema: "platform", table: "outcome_event", label: "Outcome Event", baseTier: 1, isComponent: false, isModule: false, isListed: true, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
|
|
479
481
|
"platform_outsider_consumer": { token: "platform_outsider_consumer", schema: "platform", table: "outsider_consumer", label: "Outsider consumer", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
|
|
480
482
|
"platform_saved_view": { token: "platform_saved_view", schema: "platform", table: "saved_view", label: "Saved view", baseTier: 1, isComponent: false, isModule: false, isListed: true, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
|
|
@@ -503,6 +505,7 @@ var ENTITY_TYPE_METADATA = {
|
|
|
503
505
|
"research_tag": { token: "research_tag", schema: "research", table: "rs_tag", label: "Research Tag", baseTier: 1, isComponent: true, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: "name", contentRole: null, referenceCategory: null },
|
|
504
506
|
"research_template": { token: "research_template", schema: "research", table: "rs_template", label: "Research Template", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: true, titleColumn: "name", contentRole: null, referenceCategory: null },
|
|
505
507
|
"research_topic": { token: "research_topic", schema: "research", table: "rs_topic", label: "Research Topic", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: true, titleColumn: "name", contentRole: null, referenceCategory: null },
|
|
508
|
+
"route_manifest_entry": { token: "route_manifest_entry", schema: "platform", table: "route_manifest", label: "Route Manifest Entry", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
|
|
506
509
|
"rulebook": { token: "rulebook", schema: "platform", table: "rulebook", label: "Rulebook", baseTier: 1, isComponent: false, isModule: false, isListed: true, scopeable: true, category: "Knowledge", referencePickable: true, titleColumn: "name", contentRole: "source", referenceCategory: null },
|
|
507
510
|
"sandbox_instance": { token: "sandbox_instance", schema: "public", table: "sandbox_instances", label: "Sandbox Instance", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
|
|
508
511
|
"sch_agent_task": { token: "sch_agent_task", schema: "scheduler", table: "sch_agent_task", label: "Agent Task Config", baseTier: 1, isComponent: true, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
|
|
@@ -581,6 +584,7 @@ var ENTITY_TYPE_METADATA = {
|
|
|
581
584
|
"seo_topic": { token: "seo_topic", schema: "seo", table: "topic", label: "SEO Topic", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: "seo", referencePickable: true, titleColumn: "name", contentRole: null, referenceCategory: null },
|
|
582
585
|
"seo_web_analytics_daily": { token: "seo_web_analytics_daily", schema: "seo", table: "web_analytics_daily", label: "Web Analytics Daily", baseTier: 1, isComponent: true, isModule: false, isListed: false, scopeable: true, category: "marketing", referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
|
|
583
586
|
"shared_canvas_item": { token: "shared_canvas_item", schema: "canvas", table: "shared_canvas_items", label: "Shared Canvas Item", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: true, titleColumn: "title", contentRole: null, referenceCategory: null },
|
|
587
|
+
"short_link": { token: "short_link", schema: "platform", table: "short_links", label: "Short Link", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
|
|
584
588
|
"skill": { token: "skill", schema: "skill", table: "definition", label: "Skill", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: "Skills", referencePickable: true, titleColumn: "label", contentRole: "utility", referenceCategory: null },
|
|
585
589
|
"skill_render_definition": { token: "skill_render_definition", schema: "skill", table: "render_definition", label: "Skill Render Definition", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: "Skills", referencePickable: true, titleColumn: "label", contentRole: null, referenceCategory: null },
|
|
586
590
|
"sms_consent": { token: "sms_consent", schema: "communication", table: "sms_consent", label: "SMS Consent", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
|
|
@@ -1128,6 +1132,7 @@ var ENTITY_TYPE_TOKENS = [
|
|
|
1128
1132
|
"platform_actor_session",
|
|
1129
1133
|
"platform_actor_token",
|
|
1130
1134
|
"platform_actor_token_event",
|
|
1135
|
+
"platform_continued_access",
|
|
1131
1136
|
"platform_outcome_event",
|
|
1132
1137
|
"platform_outsider_consumer",
|
|
1133
1138
|
"platform_saved_view",
|
|
@@ -1156,6 +1161,7 @@ var ENTITY_TYPE_TOKENS = [
|
|
|
1156
1161
|
"research_tag",
|
|
1157
1162
|
"research_template",
|
|
1158
1163
|
"research_topic",
|
|
1164
|
+
"route_manifest_entry",
|
|
1159
1165
|
"rulebook",
|
|
1160
1166
|
"sandbox_instance",
|
|
1161
1167
|
"sch_agent_task",
|
|
@@ -1234,6 +1240,7 @@ var ENTITY_TYPE_TOKENS = [
|
|
|
1234
1240
|
"seo_topic",
|
|
1235
1241
|
"seo_web_analytics_daily",
|
|
1236
1242
|
"shared_canvas_item",
|
|
1243
|
+
"short_link",
|
|
1237
1244
|
"skill",
|
|
1238
1245
|
"skill_render_definition",
|
|
1239
1246
|
"sms_consent",
|
|
@@ -3019,7 +3026,9 @@ function createAssociationsStore(config) {
|
|
|
3019
3026
|
helpers,
|
|
3020
3027
|
registry,
|
|
3021
3028
|
services: { associations, categories },
|
|
3022
|
-
registerEntityOverlay: registry.registerEntityOverlay
|
|
3029
|
+
registerEntityOverlay: registry.registerEntityOverlay,
|
|
3030
|
+
errorSink,
|
|
3031
|
+
identity: config.identity
|
|
3023
3032
|
};
|
|
3024
3033
|
}
|
|
3025
3034
|
|
|
@@ -3188,4 +3197,68 @@ function isContentSourceEdge(sourceType, metadata) {
|
|
|
3188
3197
|
if (isMembershipMetadata(metadata)) return false;
|
|
3189
3198
|
return true;
|
|
3190
3199
|
}
|
|
3200
|
+
|
|
3201
|
+
// src/core/categoryHierarchy.ts
|
|
3202
|
+
function buildCategoryHierarchy(categories) {
|
|
3203
|
+
const byId = new Map(categories.map((category) => [category.id, category]));
|
|
3204
|
+
const hasHierarchy = categories.some(
|
|
3205
|
+
(category) => category.parentId !== null && byId.has(category.parentId)
|
|
3206
|
+
);
|
|
3207
|
+
if (!hasHierarchy) {
|
|
3208
|
+
return {
|
|
3209
|
+
items: categories.map((category) => ({
|
|
3210
|
+
category,
|
|
3211
|
+
depth: 0,
|
|
3212
|
+
parent: null,
|
|
3213
|
+
displayName: category.name
|
|
3214
|
+
})),
|
|
3215
|
+
roots: categories.filter((category) => category.parentId === null),
|
|
3216
|
+
hasHierarchy: false
|
|
3217
|
+
};
|
|
3218
|
+
}
|
|
3219
|
+
const roots = categories.filter(
|
|
3220
|
+
(category) => category.parentId === null || !byId.has(category.parentId)
|
|
3221
|
+
);
|
|
3222
|
+
const childrenByParent = /* @__PURE__ */ new Map();
|
|
3223
|
+
for (const category of categories) {
|
|
3224
|
+
if (!category.parentId || !byId.has(category.parentId)) continue;
|
|
3225
|
+
const children = childrenByParent.get(category.parentId) ?? [];
|
|
3226
|
+
children.push(category);
|
|
3227
|
+
childrenByParent.set(category.parentId, children);
|
|
3228
|
+
}
|
|
3229
|
+
const items = [];
|
|
3230
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3231
|
+
for (const root of roots) {
|
|
3232
|
+
items.push({
|
|
3233
|
+
category: root,
|
|
3234
|
+
depth: 0,
|
|
3235
|
+
parent: null,
|
|
3236
|
+
displayName: root.name
|
|
3237
|
+
});
|
|
3238
|
+
seen.add(root.id);
|
|
3239
|
+
for (const child of childrenByParent.get(root.id) ?? []) {
|
|
3240
|
+
items.push({
|
|
3241
|
+
category: child,
|
|
3242
|
+
depth: 1,
|
|
3243
|
+
parent: root,
|
|
3244
|
+
displayName: `${root.name} / ${child.name}`
|
|
3245
|
+
});
|
|
3246
|
+
seen.add(child.id);
|
|
3247
|
+
}
|
|
3248
|
+
}
|
|
3249
|
+
for (const category of categories) {
|
|
3250
|
+
if (seen.has(category.id)) continue;
|
|
3251
|
+
items.push({
|
|
3252
|
+
category,
|
|
3253
|
+
depth: 0,
|
|
3254
|
+
parent: null,
|
|
3255
|
+
displayName: category.name
|
|
3256
|
+
});
|
|
3257
|
+
}
|
|
3258
|
+
return {
|
|
3259
|
+
items,
|
|
3260
|
+
roots: categories.filter((category) => category.parentId === null),
|
|
3261
|
+
hasHierarchy: true
|
|
3262
|
+
};
|
|
3263
|
+
}
|
|
3191
3264
|
//# sourceMappingURL=index.cjs.map
|